From 294cc06a6ba67ece081c983f81d92c432d257d9e Mon Sep 17 00:00:00 2001 From: Saikat Chakrabortty Date: Sun, 19 Apr 2020 13:41:50 +0530 Subject: [PATCH] ci: added ci in the process (#1) --- .circleci/config.yml | 32 +++++++ .github/workflows/release.yaml | 31 +++++++ charts/judge0/Chart.lock | 4 +- charts/judge0/Chart.yaml | 10 +-- charts/judge0/charts/.gitkeep | 0 charts/judge0/templates/deployment.yaml | 68 ++++++++++++++- charts/judge0/values.yaml | 83 +++++++++++------- test/ct.yaml | 6 ++ test/e2e-kind.sh | 74 ++++++++++++++++ test/kind-config.yaml | 5 ++ test/local-path-provisioner.yaml | 108 ++++++++++++++++++++++++ 11 files changed, 379 insertions(+), 42 deletions(-) create mode 100644 .circleci/config.yml create mode 100644 .github/workflows/release.yaml create mode 100644 charts/judge0/charts/.gitkeep create mode 100644 test/ct.yaml create mode 100755 test/e2e-kind.sh create mode 100644 test/kind-config.yaml create mode 100644 test/local-path-provisioner.yaml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..638ebe0 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,32 @@ +version: 2.1 +jobs: + lint-scripts: + docker: + - image: koalaman/shellcheck-alpine + steps: + - checkout + - run: + command: shellcheck -x test/e2e-kind.sh + + lint-charts: + docker: + - image: quay.io/helmpack/chart-testing:v3.0.0-rc.1 + steps: + - checkout + - run: + command: ct lint --config test/ct.yaml + + install-charts: + machine: true + steps: + - checkout + - run: + command: test/e2e-kind.sh + +workflows: + version: 2 + lint-install: + jobs: + - lint-scripts + - lint-charts + - install-charts \ No newline at end of file diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml new file mode 100644 index 0000000..b37d706 --- /dev/null +++ b/.github/workflows/release.yaml @@ -0,0 +1,31 @@ +name: Release Charts + +on: + push: + branches: + - master + +jobs: + release: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + + - name: Fetch history + run: git fetch --prune --unshallow + + - name: Configure Git + run: | + git config user.name "$GITHUB_ACTOR" + git config user.email "$GITHUB_ACTOR@users.noreply.github.com" + # See https://github.com/helm/chart-releaser-action/issues/6 + - name: Install Helm + run: | + curl -fsSLo get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 + chmod 700 get_helm.sh + ./get_helm.sh + - name: Run chart-releaser + uses: helm/chart-releaser-action@v1.0.0-rc.2 + env: + CR_TOKEN: "${{ secrets.CR_TOKEN }}" \ No newline at end of file diff --git a/charts/judge0/Chart.lock b/charts/judge0/Chart.lock index da67036..2029755 100644 --- a/charts/judge0/Chart.lock +++ b/charts/judge0/Chart.lock @@ -5,5 +5,5 @@ dependencies: - name: redis repository: https://kubernetes-charts.storage.googleapis.com/ version: 10.2.0 -digest: sha256:45eeef86c5f9928972242afbe1bc1defa6ad0c112e22d4616eb59d4384d1c755 -generated: "2020-01-22T21:39:59.852049+05:30" +digest: sha256:0a0e827ea174700951c8b0136b293e46a0e23b8cc0777aa1348f6a7960a46c39 +generated: "2020-04-18T20:21:42.742362+05:30" diff --git a/charts/judge0/Chart.yaml b/charts/judge0/Chart.yaml index b3ead0d..c5447f2 100644 --- a/charts/judge0/Chart.yaml +++ b/charts/judge0/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 name: judge0 -version: 1.0.0 +version: 1.0.11 appVersion: 1.5.0 -description: Helm implementation of Judge0 | Free ,robust and scalable open-source online code execution system. +description: Helm implementation of Judge0 | Free,robust and scalable open-source online code execution system. keywords: - online-judge - online-compiler @@ -22,7 +22,7 @@ dependencies: repository: https://kubernetes-charts.storage.googleapis.com/ condition: postgresql.enabled tags: - - judge0-databse + - judge0-database - name: redis version: 10.2.0 repository: https://kubernetes-charts.storage.googleapis.com/ @@ -30,6 +30,6 @@ dependencies: tags: - judge0-redis maintainers: - - name: Saikat Chakrabortty + - name: saikatharryc email: saikatchakrabortty2@gmail.com - url: https://github.com/saikatharryc/ \ No newline at end of file + url: https://github.com/saikatharryc/ diff --git a/charts/judge0/charts/.gitkeep b/charts/judge0/charts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/charts/judge0/templates/deployment.yaml b/charts/judge0/templates/deployment.yaml index bc8c84e..7a7d3ff 100644 --- a/charts/judge0/templates/deployment.yaml +++ b/charts/judge0/templates/deployment.yaml @@ -23,15 +23,55 @@ spec: spec: restartPolicy: Always {{- include "judge0.imagePullSecrets" . | indent 6 }} + initContainers: + - name: init-wait-for-dependencies + image: docker.io/saikatharryc/wait_for_dep:latest + command: ["/docker-entrypoint.sh"] + args: ["wait_for", "redis:REDIS_HOST", "postgressql:POSTGRES_HOST"] + env: + {{- if .Values.redis.enabled }} + - name: REDIS_HOST + value: {{ template "judge0.redis.fullname" . }}-master + {{- else }} + - name: REDIS_HOST + value: {{ .Values.external.redis.host | quote }} + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: POSTGRES_HOST + value: {{ template "judge0.postgresql.fullname" . }} + {{- else }} + - name: POSTGRES_HOST + value: {{ .Values.external.postgresql.host | quote }} + {{- end }} containers: - name: {{ .Chart.Name }}-api image: {{ template "judge0.image" . }} securityContext: privileged: true - imagePullPolicy: Always + imagePullPolicy: IfNotPresent ports: - name: http-port containerPort: 3000 + {{- if .Values.readinessProbe.enable }} + readinessProbe: + httpGet: + path: /system_info + port: http-port + scheme: HTTP + initialDelaySeconds: {{ .Values.readinessProbe.initialDelay }} + periodSeconds: {{ .Values.readinessProbe.interval }} + timeoutSeconds: {{ .Values.readinessProbe.timeout }} + {{- end }} + {{- if .Values.livenessProbe.enable }} + livenessProbe: + httpGet: + path: /config_info + port: http-port + scheme: HTTP + initialDelaySeconds: {{ add .Values.livenessProbe.initialDelay .Values.readinessProbe.initialDelay }} + periodSeconds: 60 + timeoutSeconds: {{ .Values.livenessProbe.timeout }} + {{- end }} env: - name: RAILS_ENV value: {{ .Values.RAILS_ENV | quote }} @@ -55,7 +95,7 @@ spec: value: {{ .Values.COUNT | quote }} {{- if .Values.redis.enabled }} - name: REDIS_HOST - value: {{ template "judge0.redis.fullname" . }} + value: {{ template "judge0.redis.fullname" . }}-master - name: REDIS_PASSWORD value: {{ .Values.redis.password | quote }} - name: REDIS_PORT @@ -169,12 +209,32 @@ spec: spec: restartPolicy: Always # {{- include "judge0.imagePullSecrets" . | indent 6 }} + initContainers: + - name: init-wait-for-dependencies + image: docker.io/saikatharryc/wait_for_dep:latest + command: ["/docker-entrypoint.sh"] + args: ["wait_for", "redis:REDIS_HOST", "postgressql:POSTGRES_HOST"] + env: + {{- if .Values.redis.enabled }} + - name: REDIS_HOST + value: {{ template "judge0.redis.fullname" . }}-master + {{- else }} + - name: REDIS_HOST + value: {{ .Values.external.redis.host | quote }} + {{- end }} + {{- if .Values.postgresql.enabled }} + - name: POSTGRES_HOST + value: {{ template "judge0.postgresql.fullname" . }} + {{- else }} + - name: POSTGRES_HOST + value: {{ .Values.external.postgresql.host | quote }} + {{- end }} containers: - name: {{ .Chart.Name }}-worker image: {{ template "judge0.image" . }} securityContext: privileged: true - imagePullPolicy: Always + imagePullPolicy: IfNotPresent args: - bash - -c @@ -202,7 +262,7 @@ spec: value: {{ .Values.COUNT | quote }} {{- if .Values.redis.enabled }} - name: REDIS_HOST - value: {{ template "judge0.redis.fullname" . }} + value: {{ template "judge0.redis.fullname" . }}-master - name: REDIS_PASSWORD value: {{ .Values.redis.password | quote }} - name: REDIS_PORT diff --git a/charts/judge0/values.yaml b/charts/judge0/values.yaml index a2e0532..2f1cef8 100644 --- a/charts/judge0/values.yaml +++ b/charts/judge0/values.yaml @@ -4,26 +4,26 @@ image: registry: docker.io repository: judge0/api - tag: 1.5.0 + tag: 1.5.0 ## Kubernetes configuration ## For minikube, set this to NodePort, elsewhere use LoadBalancer ## service: - type: LoadBalancer - # HTTP Port - port: 80 - ## loadBalancerIP: - ## - ## nodePorts: - ## http: - nodePorts: - http: "" - ## Enable client source IP preservation - ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip - ## - externalTrafficPolicy: Cluster - ## Service annotations done as key:value pairs - annotations: + type: ClusterIP + # HTTP Port + port: 80 + ## loadBalancerIP: + ## + ## nodePorts: + ## http: + nodePorts: + http: "" + ## Enable client source IP preservation + ## ref http://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#preserving-the-client-source-ip + ## + externalTrafficPolicy: Cluster + ## Service annotations done as key:value pairs + annotations: ############################################################################### # Rails Environment ############################################################################### @@ -33,7 +33,7 @@ service: # Specify maximum number of concurrent Rails threads. # Default: 5 -RAILS_MAX_THREADS: 10 +RAILS_MAX_THREADS: 10 # Maintenance mode is a mode in which clients cannot # create or delete submissions while maintenance is enabled. @@ -43,11 +43,11 @@ MAINTENANCE_MODE: false # Set custom maintenance message that will be returned to clients # who try to create or delete submisions. # Default: Judge0 API is currently in maintenance. -# MAINTENANCE_MESSAGE: +# MAINTENANCE_MESSAGE: # Secret key base for production, if not set it will be randomly generated # Default: randomly generated -# SECRET_KEY_BASE: +# SECRET_KEY_BASE: # Allow only specified origins. # If left blank, then all origins will be allowed (denoted with '*'). @@ -124,7 +124,7 @@ MAINTENANCE_MODE: false # Specify how many parallel workers to run. # Default: 1 -COUNT: 3 +COUNT: 1 # Specify maximum queue size. Represents maximum number of submissions that # can wait in the queue at once. If request for new submission comes and the @@ -132,6 +132,23 @@ COUNT: 3 # Default: 100 # MAX_QUEUE_SIZE: +readinessProbe: + # readinessProbe.enable -- Enabling Readiness Probe + enable: true + # readinessProbe.interval -- Readiness check interval + interval: 60 + # readinessProbe.timeout -- Define custom timeout + timeout: 3 + # readinessProbe.initialDelay -- Intial Delay to take in account + initialDelay: 30 + +livenessProbe: + # livenessProbe.enable -- Enabling Readiness Probe + enable: false + # livenessProbe.initialDelay -- Intial Delay to take in account + initialDelay: 30 + # livenessProbe.timeout -- Define custom timeout + timeout: 1 ############################################################################### # Database @@ -143,23 +160,28 @@ postgresql: ## if you are using enabled true, for further configuration you can look at https://github.com/helm/charts/tree/master/stable/postgresql#parameters enabled: true image: - tag: 9.6 #default version for the postgres. + tag: 9.6 # default version for the postgres. postgresqlUsername: judgemaster postgresqlPassword: uaeyjbzuyq postgresqlDatabase: judge - # service: + service: # port is defaulting to 5432 - # port: 5432 + port: 5432 + persistence: + enabled: false # if you are using enabled true, for further configuration you can look at https://github.com/helm/charts/tree/master/stable/redis#parameters redis: ## Whether to deploy a redis server to satisfy the applications requirements. To use an external redis instance set this to false and configure the external.redis parameters enabled: true cluster: - enabled: false - password: a8iuw23iuizy + enabled: false + password: a8iuw23iuizy # redisPort is bydefault set to 6379, change if needed in below line. - # redisPort: 6379 + redisPort: 6379 + master: + persistence: + enabled: false # Set this incase the above services are disabled. external: @@ -170,9 +192,9 @@ external: postgresqlDatabase: judge port: 5432 # default value is 5432 redis: - host: localhost - password: "" - port: 6379 # default value is 6379 + host: localhost + password: "" + port: 6379 # default value is 6379 ############################################################################### # Configuration ############################################################################### @@ -192,7 +214,7 @@ external: # For example, ALLOWED_LANGUAGES_FOR_COMPILER_OPTIONS:"C C++ Java" would only # allow setting compiler options for languages C, C++ and Java. # Default: empty - for every compiled language setting compiler options is allowed. -# ALLOWED_LANGUAGES_FOR_COMPILER_OPTIONS: +# ALLOWED_LANGUAGES_FOR_COMPILER_OPTIONS: # If enabled user is allowed to set custom command line arguments. # Default: true @@ -301,4 +323,3 @@ external: # Maximum number of submissions that can be created or get in a batch. # Default: 20 # MAX_SUBMISSION_BATCH_SIZE: - diff --git a/test/ct.yaml b/test/ct.yaml new file mode 100644 index 0000000..038d0ca --- /dev/null +++ b/test/ct.yaml @@ -0,0 +1,6 @@ +chart-dirs: + - charts +chart-repos: + - incubator=https://kubernetes-charts-incubator.storage.googleapis.com/ + - stable=https://kubernetes-charts.storage.googleapis.com/ +helm-extra-args: --timeout 800s \ No newline at end of file diff --git a/test/e2e-kind.sh b/test/e2e-kind.sh new file mode 100755 index 0000000..5b53a6b --- /dev/null +++ b/test/e2e-kind.sh @@ -0,0 +1,74 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +readonly CT_VERSION=v3.0.0-rc.1 +readonly KIND_VERSION=v0.7.0 +readonly CLUSTER_NAME=chart-testing +readonly K8S_VERSION=v1.17.0 + +run_ct_container() { + echo 'Running ct container...' + docker run --rm --interactive --detach --network host --name ct \ + -e KUBECONFIG="/root/.kube/config" \ + --volume "$(pwd)/test/ct.yaml:/etc/ct/ct.yaml" \ + --volume "$(pwd):/workdir" \ + --workdir /workdir \ + "quay.io/helmpack/chart-testing:$CT_VERSION" \ + cat + echo +} + +cleanup() { + echo 'Removing ct container...' + docker kill ct > /dev/null 2>&1 + + echo 'Done!' +} + +docker_exec() { + docker exec --interactive ct "$@" +} + +create_kind_cluster() { + echo 'Installing kind...' + + curl -sSLo kind "https://github.com/kubernetes-sigs/kind/releases/download/$KIND_VERSION/kind-linux-amd64" + chmod +x kind + sudo mv kind /usr/local/bin/kind + + kind create cluster --name "$CLUSTER_NAME" --config test/kind-config.yaml --image "kindest/node:$K8S_VERSION" --kubeconfig config --wait 60s + + echo 'Copying kubeconfig to container...' + # echo "$KUBECONFIG" + # cat config + docker_exec mkdir /root/.kube + docker_exec touch /root/.kube/config + sudo docker cp config ct:/root/.kube/config + docker_exec touch /root/.kube/config + docker_exec kubectl cluster-info + echo + + docker_exec kubectl get nodes + echo + + echo 'Cluster ready!' + echo +} + +install_charts() { + docker_exec ct install + echo +} + +main() { + run_ct_container + trap cleanup EXIT + + create_kind_cluster + install_charts +} + +main \ No newline at end of file diff --git a/test/kind-config.yaml b/test/kind-config.yaml new file mode 100644 index 0000000..0ebddbf --- /dev/null +++ b/test/kind-config.yaml @@ -0,0 +1,5 @@ +kind: Cluster +apiVersion: kind.sigs.k8s.io/v1alpha3 +nodes: + - role: control-plane + - role: worker \ No newline at end of file diff --git a/test/local-path-provisioner.yaml b/test/local-path-provisioner.yaml new file mode 100644 index 0000000..69f2001 --- /dev/null +++ b/test/local-path-provisioner.yaml @@ -0,0 +1,108 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: local-path-storage +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: local-path-provisioner-service-account + namespace: local-path-storage +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + name: local-path-provisioner-role + namespace: local-path-storage +rules: +- apiGroups: [""] + resources: ["nodes", "persistentvolumeclaims"] + verbs: ["get", "list", "watch"] +- apiGroups: [""] + resources: ["endpoints", "persistentvolumes", "pods"] + verbs: ["*"] +- apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- apiGroups: ["storage.k8s.io"] + resources: ["storageclasses"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + name: local-path-provisioner-bind + namespace: local-path-storage +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: local-path-provisioner-role +subjects: +- kind: ServiceAccount + name: local-path-provisioner-service-account + namespace: local-path-storage +--- +apiVersion: apps/v1beta2 +kind: Deployment +metadata: + name: local-path-provisioner + namespace: local-path-storage +spec: + replicas: 1 + selector: + matchLabels: + app: local-path-provisioner + template: + metadata: + labels: + app: local-path-provisioner + spec: + serviceAccountName: local-path-provisioner-service-account + containers: + - name: local-path-provisioner + image: rancher/local-path-provisioner:v0.0.11 + imagePullPolicy: Always + command: + - local-path-provisioner + - --debug + - start + - --config + - /etc/config/config.json + volumeMounts: + - name: config-volume + mountPath: /etc/config/ + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumes: + - name: config-volume + configMap: + name: local-path-config +--- +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: local-path + annotations: + storageclass.kubernetes.io/is-default-class: "true" +provisioner: rancher.io/local-path +volumeBindingMode: WaitForFirstConsumer +reclaimPolicy: Delete +--- +kind: ConfigMap +apiVersion: v1 +metadata: + name: local-path-config + namespace: local-path-storage +data: + config.json: |- + { + "nodePathMap":[ + { + "node":"DEFAULT_PATH_FOR_NON_LISTED_NODES", + "paths":["/opt/local-path-provisioner"] + } + ] + } \ No newline at end of file