diff --git a/.gitlab-ci.jsonnet b/.gitlab-ci.jsonnet index 31c24d796..bbbd4d0e0 100644 --- a/.gitlab-ci.jsonnet +++ b/.gitlab-ci.jsonnet @@ -6,13 +6,13 @@ local baseJob = (import '.gitlab-ci/base_jobs.libsonnet')(vars); local stages_list = [ // gitlab-ci stages - 'deploy', - - 'docker_build', 'docker_base', + 'docker_build', + 'deploy_preview', 'unit_tests', 'integration', 'docker_release', + 'deploy_staging', 'teardown', ]; @@ -94,12 +94,39 @@ local jobs = { 'MYSQL_USER', 'MYSQL_PASSWORD'] }), "deploy-preview": baseJob.QuayDeploy { - environment+: {on_stop: "stop-preview"}, + local _vars = self.localvars, + stage: stages.deploy_preview, + when: "manual", + environment+: { + on_stop: "stop-preview", + }, } + onlyBranch, "stop-preview": baseJob.QuayDeployStop { + when: "manual", + stage: stages.deploy_preview, + script: [ + "kubectl delete ns $K8S_NAMESPACE", + "kubectl get pods -o wide -n $K8S_NAMESPACE" + ] } + onlyBranch, + "deploy-staging": baseJob.QuayDeploy { + local _vars = self.localvars, + localvars+:: { + image: images.release, + domain: "quay-staging.k8s.devtable.com", + namespace: "ci-staging", + channels: ['master' , 'beta', 'latest'], + }, + stage: stages.deploy_staging, + script+: [], + environment+: { + name: "staging", + }, + only: ['master'] + }, + }; { diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 71d0b6796..18d564264 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -50,6 +50,10 @@ container-release: deploy-preview: before_script: - appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io + - cd deploy/quay-ci-app + - echo -n 1.0.0-${CI_COMMIT_REF_SLUG} > VERSION + - 'echo "{\"domain\": \"$QUAY_DOMAIN\", \"image\": \"quay.io/quay/quay-ci:${CI_COMMIT_REF_SLUG}\", \"tag\": \"${CI_COMMIT_REF_SLUG}\"}" > params.json' + - cat params.json environment: name: review/${CI_COMMIT_REF_SLUG} on_stop: stop-preview @@ -58,17 +62,42 @@ deploy-preview: only: - branches script: - - cd deploy/quay-demo-app - - echo -n 1.0.0-${CI_COMMIT_REF_SLUG} > VERSION - - 'echo "{\"image\": \"quay.io/quay/quay-ci:${CI_COMMIT_REF_SLUG}\", \"tag\": \"${CI_COMMIT_REF_SLUG}\"}" > params.json' - - cat params.json - - appr push quay.io/quay -f - - appr deploy quay.io/quay/quay-demo-app@1.0.0-${CI_COMMIT_REF_SLUG} --namespace ci-quay-${CI_COMMIT_REF_SLUG} -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS + - appr push quay.io/quay/quay-ci-app -f + - appr deploy quay.io/quay/quay-ci-app@1.0.0-${CI_COMMIT_REF_SLUG} --namespace ci-quay-${CI_COMMIT_REF_SLUG} -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS - kubectl get ingresses -n ci-quay-${CI_COMMIT_REF_SLUG} -o wide - stage: deploy + stage: deploy_preview tags: - kubernetes + variables: + K8S_NAMESPACE: ci-quay-${CI_COMMIT_REF_SLUG} + QUAY_DOMAIN: quay-${CI_COMMIT_REF_SLUG}.k8s.devtable.com when: manual +deploy-staging: + before_script: + - appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io + - cd deploy/quay-ci-app + - echo -n 1.0.0-${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA} > VERSION + - 'echo "{\"domain\": \"$QUAY_DOMAIN\", \"image\": \"quay.io/quay/quay:${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA}\", \"tag\": \"${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA}\"}" > params.json' + - cat params.json + environment: + name: staging + url: https://quay-staging.k8s.devtable.com + image: quay.io/appr/appr:kubectl + only: + - master + script: + - appr push quay.io/quay/quay-ci-app -f + - appr push quay.io/quay/quay-ci-app -c master + - appr push quay.io/quay/quay-ci-app -c beta + - appr push quay.io/quay/quay-ci-app -c latest + - appr deploy quay.io/quay/quay-ci-app@1.0.0-${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA} --namespace ci-staging -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS + - kubectl get ingresses -n ci-staging -o wide + stage: deploy_staging + tags: + - kubernetes + variables: + K8S_NAMESPACE: ci-staging + QUAY_DOMAIN: quay-staging.k8s.devtable.com karma-tests: before_script: - cd $QUAYDIR @@ -152,16 +181,16 @@ registry-tests: QUAYDIR: /quay-registry TEST: 'true' stages: -- deploy -- docker_build - docker_base +- docker_build +- deploy_preview - unit_tests - integration - docker_release +- deploy_staging - teardown stop-preview: - before_script: - - appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io + before_script: [] environment: action: stop name: review/${CI_COMMIT_REF_SLUG} @@ -170,15 +199,15 @@ stop-preview: only: - branches script: - - 'echo "{\"image\": \"quay.io/quay/quay-ci:${CI_COMMIT_REF_SLUG}\", \"tag\": \"${CI_COMMIT_REF_SLUG}\"}" > params.json' - - cat params.json - - appr remove quay.io/quay/quay-demo-app@1.0.0-${CI_COMMIT_REF_SLUG} --namespace ci-quay-${CI_COMMIT_REF_SLUG} -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS -x params.json - - kubectl get pods -n ci-quay-${CI_COMMIT_REF_SLUG} -o wide - stage: deploy + - kubectl delete ns $K8S_NAMESPACE + - kubectl get pods -o wide -n $K8S_NAMESPACE + stage: deploy_preview tags: - kubernetes variables: GIT_STRATEGY: none + K8S_NAMESPACE: ci-quay-${CI_COMMIT_REF_SLUG} + QUAY_DOMAIN: quay-${CI_COMMIT_REF_SLUG}.k8s.devtable.com when: manual unit-tests: before_script: diff --git a/.gitlab-ci/base_jobs.libsonnet b/.gitlab-ci/base_jobs.libsonnet index f928f45af..c4512760b 100644 --- a/.gitlab-ci/base_jobs.libsonnet +++ b/.gitlab-ci/base_jobs.libsonnet @@ -35,44 +35,70 @@ function(vars={}) ], }, - local appversion = "1.0.0-%s" % vars.images.quayci.tag, - local namespace = "ci-quay-%s" % vars.images.quayci.tag, + QuayDeploy: { + local this = self, + local _vars = self.localvars, + localvars:: { + appversion: "1.0.0-%s" % self.image.tag, + apprepo: "quay.io/quay/%s" % self.appname, + appname: "quay-ci-app", + domain: "quay-%s.k8s.devtable.com" % self.image.tag, + namespace: "ci-quay-%s" % self.image.tag, + image: vars.images.quayci, + channels: [], + pushargs: ["-f"], + + buildParams(extra_params={}):: ( + local params = {image: _vars.image.name, + tag: _vars.image.tag, + domain: "$QUAY_DOMAIN"} + extra_params; + [ + "echo -n %s > VERSION" % _vars.appversion, + 'echo %s > params.json' % std.escapeStringJson(params), + "cat params.json" + ]), + + pushApp(repo="quay.io/quay", extra_args=['-f'], channels=[]):: ( + ["appr push %s %s" % [repo, std.join(" ", extra_args)]] + + ["appr push %s -c %s" % [repo, channel] for channel in channels] + ), + }, + + variables: {K8S_NAMESPACE: _vars.namespace, + QUAY_DOMAIN: _vars.domain}, image: "quay.io/appr/appr:kubectl", - when: "manual", environment: { - name: "review/%s" % vars.images.quayci.tag, - url: "https://quay-%s.k8s.devtable.com" % vars.images.quayci.tag, + name: "review/%s" % _vars.image.tag, + url: "https://%s" % _vars.domain, }, tags: [ "kubernetes", ], - stage: "deploy", + before_script: [ - "appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io", - ], - script: [ - "cd deploy/quay-demo-app", - "echo -n %s > VERSION" % appversion, - 'echo "{\\"image\\": \\"%s\\", \\"tag\\": \\"%s\\"}" > params.json' % [vars.images.quayci.name, vars.images.quayci.tag], - "cat params.json", - "appr push quay.io/quay -f", - "appr deploy quay.io/quay/quay-demo-app@%s --namespace %s -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS" % [appversion, namespace], - "kubectl get ingresses -n %s -o wide" % namespace, + "appr login -u $DOCKER_USER -p $DOCKER_PASS quay.io", + "cd deploy/%s" % _vars.appname, + ] + _vars.buildParams(), + + script: + _vars.pushApp(_vars.apprepo, _vars.pushargs, _vars.channels) + + [ + "appr deploy %s@%s --namespace %s -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS" % [ + _vars.apprepo, + _vars.appversion, + _vars.namespace], + "kubectl get ingresses -n %s -o wide" % _vars.namespace, ], }, QuayDeployStop: self.QuayDeploy { - variables: {GIT_STRATEGY: "none"}, + variables+: {GIT_STRATEGY: "none"}, environment+: { action: "stop" }, - script: [ - 'echo "{\\"image\\": \\"%s\\", \\"tag\\": \\"%s\\"}" > params.json' % [vars.images.quayci.name, vars.images.quayci.tag], - "cat params.json", - "appr remove quay.io/quay/quay-demo-app@%s --namespace %s -x docker_user=$DOCKER_USER -x docker_pass=$DOCKER_PASS -x params.json" % [appversion, namespace], - "kubectl get pods -n %s -o wide" % namespace, - ], + before_script: [], + script: [], }, dbTest(scheme, image, env):: self.QuayTest { diff --git a/.gitlab-ci/vars.libsonnet b/.gitlab-ci/vars.libsonnet index b47e2cd9f..7a668810c 100644 --- a/.gitlab-ci/vars.libsonnet +++ b/.gitlab-ci/vars.libsonnet @@ -8,12 +8,11 @@ local utils = import "utils.libsonnet"; // internal variables images: { - // Quay initial image, used in the FROM clause + // Quay initial image, used in the Dockerfile FROM clause base: { repo: "quay.io/quay/quay-base", tag: "latest", name: utils.containerName(self.repo, self.tag), }, - // @TODO(ant31) release should use quay/quay // release is a copy of the quayci image to the 'prod' repository release: { repo: "quay.io/quay/quay", tag: "${CI_COMMIT_REF_SLUG}-${CI_COMMIT_SHA}", diff --git a/deploy/quay-app/templates/quay-dev-initdb-job.yaml b/deploy/quay-app/templates/quay-dev-initdb-job.yaml deleted file mode 100644 index ccbaef8ae..000000000 --- a/deploy/quay-app/templates/quay-dev-initdb-job.yaml +++ /dev/null @@ -1,37 +0,0 @@ ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: quay-dev-initdb -spec: - activeDeadlineSeconds: 100 - template: - metadata: - name: quay-dev-initdb - spec: - containers: - - name: quay - image: quay.io/quay/quay-ci:master - env: - - name: TEST_DATABASE_URI - value: "postgres://" - - name: SKIP_DB_SCHEMA - value: "true" - command: - - venv/bin/python - - initdb.py - volumeMounts: - - name: configvolume - readOnly: false - mountPath: /conf/stack - resources: - limits: - cpu: 500m - memory: 500Mi - imagePullSecrets: - - name: coreos-pull-secret - volumes: - - name: configvolume - secret: - secretName: quay-enterprise-config-secret - restartPolicy: Never diff --git a/deploy/quay-app/templates/quay-enterprise-secret.libsonnet b/deploy/quay-app/templates/quay-enterprise-secret.libsonnet index f867e2852..f98124c9a 100644 --- a/deploy/quay-app/templates/quay-enterprise-secret.libsonnet +++ b/deploy/quay-app/templates/quay-enterprise-secret.libsonnet @@ -12,10 +12,10 @@ local local_stack_config = ( ); # Merge all config together -# Precedence: package-config (vars.config) < local stack/config.yaml < base-config (vars.base-config) +# Precedence: local stack/config.yaml < package-config (vars.config) < base-config (vars.base-config) local config_yaml = {'config.yaml': appr.b64encode(appr.to_yaml( - vars.config + local_stack_config + + vars.config + vars.base_config))}; # Merge stack files diff --git a/deploy/quay-ci-app/manifest.jsonnet b/deploy/quay-ci-app/manifest.jsonnet index da65a523e..719643215 100644 --- a/deploy/quay-ci-app/manifest.jsonnet +++ b/deploy/quay-ci-app/manifest.jsonnet @@ -56,7 +56,8 @@ deploy: [ { name: "quay/quay-app", - variables: $.variables + variables: $.variables, + version: ":stable" }, # Deploy the initdb script diff --git a/test/data/test.db b/test/data/test.db index 7f79f6caa..2dde19399 100644 Binary files a/test/data/test.db and b/test/data/test.db differ diff --git a/util/config/provider/baseprovider.py b/util/config/provider/baseprovider.py index 6696ae88e..663c64588 100644 --- a/util/config/provider/baseprovider.py +++ b/util/config/provider/baseprovider.py @@ -109,7 +109,7 @@ class BaseProvider(object): indicating that this container requires a restart. """ raise NotImplementedError - + def get_volume_path(self, directory, filename): """ Helper for constructing file paths, which may differ between providers. For example, kubernetes can't have subfolders in configmaps """ diff --git a/util/config/provider/k8sprovider.py b/util/config/provider/k8sprovider.py index 6b959a2e5..c3965f015 100644 --- a/util/config/provider/k8sprovider.py +++ b/util/config/provider/k8sprovider.py @@ -54,20 +54,20 @@ class KubernetesConfigProvider(FileConfigProvider): self._update_secret_file(filename, contents) except IOError as ioe: raise CannotWriteConfigException(str(ioe)) - + def volume_file_exists(self, filename): secret = self._lookup_secret() if not secret or not secret.get('data'): return False return filename in secret['data'] - + def list_volume_directory(self, path): secret = self._lookup_secret() - + if not secret: return [] - + paths = [] for filename in secret.get('data', {}): if filename.startswith(path): @@ -150,4 +150,4 @@ class KubernetesConfigProvider(FileConfigProvider): return session.send(request.prepare(), verify=False, timeout=2) def get_volume_path(self, directory, filename): - return "_".join([directory.rstrip('/'), filename]) + return "_".join([directory.rstrip('/'), filename]) \ No newline at end of file