diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2f0143f0..c2523851 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -18,9 +18,11 @@ variables: .test-base: image: registry.cern.ch/docker.io/library/python:${PY_VERSION} stage: test - except: - - live/caimira-test # do not run tests on live/caimira-test branch - - tags + rules: + # do not run tests on live/caimira-test branch or tags + - if: $CI_COMMIT_BRANCH != "live/caimira-test" + - if: $CI_COMMIT_TAG + when: never .test-run: extends: @@ -65,7 +67,6 @@ test-cern-caimira-py39: .test_openshift_config: stage: test - allow_failure: true image: registry.cern.ch/docker.io/mambaorg/micromamba before_script: - micromamba create --yes -p $HOME/env python=3.9 ruamel.yaml wget -c conda-forge @@ -85,27 +86,24 @@ test-cern-caimira-py39: paths: - ./app-config/openshift/${CAIMIRA_INSTANCE}/actual - ./app-config/openshift/${CAIMIRA_INSTANCE}/expected - only: - - master - - live/caimira-test check_openshift_config_test: extends: .test_openshift_config variables: CAIMIRA_INSTANCE: 'caimira-test' - BRANCH: 'live/caimira-test' OC_SERVER: https://api.paas.okd.cern.ch OC_TOKEN: "${OPENSHIFT_CAIMIRA_TEST_CONFIG_CHECKER_TOKEN}" + rules: + - if: $CI_COMMIT_BRANCH == "live/caimira-test" -# TODO: for prod, it should ignore the different tag in the `image` field -# check_openshift_config_prod: -# extends: .test_openshift_config -# variables: -# CAIMIRA_INSTANCE: 'caimira-prod' -# BRANCH: 'master' -# OC_SERVER: https://api.paas.okd.cern.ch -# OC_TOKEN: "${OPENSHIFT_CAIMIRA_PROD_CONFIG_CHECKER_TOKEN}" - +check_openshift_config_prod: + extends: .test_openshift_config + variables: + CAIMIRA_INSTANCE: 'caimira-prod' + OC_SERVER: https://api.paas.okd.cern.ch + OC_TOKEN: "${OPENSHIFT_CAIMIRA_PROD_CONFIG_CHECKER_TOKEN}" + rules: + - if: $CI_COMMIT_BRANCH == "master" # ################################################################################################### # Build docker images @@ -119,12 +117,11 @@ check_openshift_config_test: name: gcr.io/kaniko-project/executor:debug entrypoint: [""] script: - - echo "Building image for ${CI_COMMIT_REF_NAME} branch with tag ${IMAGE_TAG}" + - echo "Building image for ${CI_COMMIT_REF_NAME} branch with tag ${IMAGE_TAG} and latest" # Prepare Kaniko configuration file - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - - echo "Building ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:latest Docker image..." # Build and push the image from the Dockerfile - - /kaniko/executor --context ${CI_PROJECT_DIR}/${DOCKER_CONTEXT_DIRECTORY} --dockerfile ${CI_PROJECT_DIR}/${DOCKERFILE_DIRECTORY}/Dockerfile --destination ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG} + - /kaniko/executor --context ${CI_PROJECT_DIR}/${DOCKER_CONTEXT_DIRECTORY} --dockerfile ${CI_PROJECT_DIR}/${DOCKERFILE_DIRECTORY}/Dockerfile --destination ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG} --destination ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:latest # Print the full registry path of the pushed image - echo "Image pushed successfully to ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}" @@ -151,15 +148,15 @@ docker-build-auth-service-test: extends: - .docker-build-test - .docker-build-auth-service - only: - - live/caimira-test + rules: + - if: $CI_COMMIT_BRANCH == "live/caimira-test" docker-build-calculator-app-test: extends: - .docker-build-test - .docker-build-calculator-app - only: - - live/caimira-test + rules: + - if: $CI_COMMIT_BRANCH == "live/caimira-test" # on release .docker-build-release: @@ -172,15 +169,15 @@ docker-build-auth-service-release: extends: - .docker-build-release - .docker-build-auth-service - only: - - tags + rules: + - if: $CI_COMMIT_TAG docker-build-calculator-app-release: extends: - .docker-build-release - .docker-build-calculator-app - only: - - tags + rules: + - if: $CI_COMMIT_TAG # ################################################################################################### # Deploy to OpenShift @@ -195,10 +192,10 @@ docker-build-calculator-app-release: - echo "Deploying ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG} to OpenShift" - oc login $OPENSHIFT_SERVER --token=$OPENSHIFT_CAIMIRA_TEST_DEPLOY_TOKEN - oc project $OPENSHIFT_PROJECT - - oc set image dc/$OPENSHIFT_DEPLOYMENT $OPENSHIFT_CONTAINER_NAME=${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG} - - oc rollout status dc/$OPENSHIFT_DEPLOYMENT - only: - - live/caimira-test + - oc set image deployment/$OPENSHIFT_DEPLOYMENT $OPENSHIFT_CONTAINER_NAME=${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG} + - oc rollout status deployment/$OPENSHIFT_DEPLOYMENT + rules: + - if: $CI_COMMIT_BRANCH == "live/caimira-test" deploy-auth-service-test: extends: .deploy diff --git a/README.md b/README.md index d8cf41f4..b603e659 100644 --- a/README.md +++ b/README.md @@ -357,9 +357,7 @@ $ cd app-config/openshift $ oc process -f configmap.yaml | oc create -f - $ oc process -f services.yaml | oc create -f - -$ oc process -f imagestreams.yaml | oc create -f - -$ oc process -f buildconfig.yaml --param GIT_BRANCH='live/caimira-test' | oc create -f - -$ oc process -f deploymentconfig.yaml --param PROJECT_NAME='caimira-test' | oc create -f - +$ oc process -f deployments.yaml | oc create -f - ``` Manually create the **route** to access the website, see `routes.example.yaml`. @@ -453,9 +451,7 @@ $ cd app-config/openshift $ oc process -f configmap.yaml | oc replace -f - $ oc process -f services.yaml | oc replace -f - -$ oc process -f imagestreams.yaml | oc replace -f - -$ oc process -f buildconfig.yaml --param GIT_BRANCH='live/caimira-test' | oc replace -f - -$ oc process -f deploymentconfig.yaml --param PROJECT_NAME='caimira-test' | oc replace -f - +$ oc process -f deployments.yaml | oc replace -f - ``` Be aware that if you create/recreate the environment you must manually create a **route** in OpenShift, diff --git a/app-config/openshift/buildconfig.yaml b/app-config/openshift/buildconfig.yaml deleted file mode 100644 index 5a72a0cd..00000000 --- a/app-config/openshift/buildconfig.yaml +++ /dev/null @@ -1,56 +0,0 @@ ---- - kind: "Template" - apiVersion: template.openshift.io/v1 - metadata: - name: "caimira-application" - creationTimestamp: null - annotations: - description: "CAiMIRA build config OpenShift template." - tags: "caimira-application" - labels: - template: "caimira-application" - objects: - - - kind: BuildConfig - apiVersion: build.openshift.io/v1 - metadata: - name: caimira-router - labels: - template: "caimira-application" - spec: - source: - type: Git - git: - ref: ${GIT_BRANCH} - uri: ${GIT_REPO} - contextDir: app-config/nginx - postCommit: {} - resources: {} - runPolicy: Serial - output: - to: - kind: ImageStreamTag - name: 'caimira-router:latest' - strategy: - sourceStrategy: - from: - kind: ImageStreamTag - name: 'nginx:1.18-ubi8' - namespace: openshift - type: Source - triggers: - - type: ImageChange - imageChange: {} - - type: ConfigChange - - generic: - secretReference: - name: gitlab-caimira-webhook-secret - type: Generic - nodeSelector: null - parameters: - - name: GIT_REPO - description: The GIT repo URL - value: 'https://gitlab.cern.ch/caimira/caimira.git' - - name: GIT_BRANCH - description: The name of the GIT branch to use when building the app, e.g. `live/caimira-test` in TEST, `master` in prod - required: true diff --git a/app-config/openshift/config-fetch.py b/app-config/openshift/config-fetch.py index ee737b0d..f3e16cd1 100644 --- a/app-config/openshift/config-fetch.py +++ b/app-config/openshift/config-fetch.py @@ -38,9 +38,7 @@ def fetch_config(output_directory: pathlib.Path): for component, name in [ ('configmap', 'auth-service'), ('services', None), - ('imagestreams', None), - ('buildconfig', None), - ('deploymentconfig', None)]: + ('deployments', None)]: with (output_directory / f'{component}.yaml').open('wt') as fh: cmd = ['oc', 'get', '-o', 'yaml', component] diff --git a/app-config/openshift/config-generate.py b/app-config/openshift/config-generate.py index e8a0eec8..cfba1b42 100644 --- a/app-config/openshift/config-generate.py +++ b/app-config/openshift/config-generate.py @@ -17,7 +17,7 @@ def configure_parser(parser: argparse.ArgumentParser) -> None: ) -def generate_config(output_directory: pathlib.Path, project_name: str, hostname: str, branch: str): +def generate_config(output_directory: pathlib.Path): output_directory.mkdir(exist_ok=True, parents=True) def oc_process(component_name: str, context: typing.Optional[dict] = None): @@ -30,24 +30,18 @@ def generate_config(output_directory: pathlib.Path, project_name: str, hostname: oc_process('configmap') oc_process('services') - oc_process('imagestreams') - oc_process('buildconfig', context={'GIT_BRANCH': branch}) - oc_process('deploymentconfig', context={'PROJECT_NAME': project_name}) + oc_process('deployments') print(f'Config in: {output_directory.absolute()}') def handler(args: argparse.ArgumentParser) -> None: if args.instance == 'caimira-prod': - project_name = 'caimira-prod' - branch = 'master' - hostname = 'caimira.web.cern.ch' + pass elif args.instance == 'caimira-test': - project_name = 'caimira-test' - branch = 'live/caimira-test' - hostname = 'caimira-test.web.cern.ch' + pass - generate_config(pathlib.Path(args.output_directory), project_name, hostname, branch) + generate_config(pathlib.Path(args.output_directory)) def main(): diff --git a/app-config/openshift/config-normalise.py b/app-config/openshift/config-normalise.py index d409aa7c..2bc6ee35 100644 --- a/app-config/openshift/config-normalise.py +++ b/app-config/openshift/config-normalise.py @@ -34,26 +34,16 @@ def clean_ephemeral_config(config: dict): item.get('spec', {}).pop('clusterIP', None) item.get('spec', {}).pop('clusterIPs', None) item.get('spec', {}).pop('revisionHistoryLimit', None) + item.get('spec', {}).pop('progressDeadlineSeconds', None) - if item['kind'] == 'BuildConfig': - for trigger in item.get('spec', {}).get('triggers', []): - trigger.get('imageChange', {}).pop('lastTriggeredImageID', None) - item.get('spec', {}).pop('failedBuildsHistoryLimit', None) - item.get('spec', {}).pop('successfulBuildsHistoryLimit', None) - - if item['kind'] == 'DeploymentConfig': + if item['kind'] == 'Deployment': + item['spec'].pop('strategy', None) item['spec'].get('template', {}).get('metadata', {}).pop('creationTimestamp', None) + item['spec'].get('template', {}).get('metadata', {}).pop('annotations', None) for container in item['spec'].get('template', {}).get('spec', {}).get('containers', []): # Drop the specific image name (and hash). container.pop('image', None) - item['spec'].get('template', {}).get('metadata', {}).pop('creationTimestamp', None) - for trigger in item['spec'].get('triggers', []): - trigger.get('imageChangeParams', {}).pop('lastTriggeredImage', None) - - # Drop the tags on ImageStream - if item['kind'] == 'ImageStream': - item['spec'].pop('tags', None) # Drop the unnecessary elements on Service if item['kind'] == 'Service': @@ -77,14 +67,14 @@ def clean_ephemeral_config(config: dict): # Fix the configmap single element data structure if config['kind'] == 'ConfigMap': config['items'] = [{ - 'apiVersion': config.get('apiVersion', {}), - 'data': config.get('data', {}), - 'kind': config.get('kind', {}), + 'apiVersion': config.get('apiVersion', {}), + 'data': config.get('data', {}), + 'kind': config.get('kind', {}), 'metadata': {'name': 'auth-service'} }] config['kind'] = 'List' config.pop('data', None) - + return config diff --git a/app-config/openshift/deploymentconfig.yaml b/app-config/openshift/deployments.yaml similarity index 72% rename from app-config/openshift/deploymentconfig.yaml rename to app-config/openshift/deployments.yaml index 61c50e72..64d570b5 100644 --- a/app-config/openshift/deploymentconfig.yaml +++ b/app-config/openshift/deployments.yaml @@ -10,8 +10,8 @@ template: "caimira-application" objects: - - apiVersion: apps.openshift.io/v1 - kind: DeploymentConfig + apiVersion: apps/v1 + kind: Deployment metadata: name: auth-service labels: @@ -22,11 +22,10 @@ metadata: labels: app: auth-service - deploymentconfig: auth-service spec: containers: - name: auth-service - image: '${PROJECT_NAME}/auth-service' + image: 'gitlab-registry.cern.ch/caimira/caimira/auth-service:latest' ports: - containerPort: 8080 protocol: TCP @@ -36,7 +35,13 @@ - secretRef: name: auth-service-secrets imagePullPolicy: Always - resources: {} + resources: + limits: + cpu: 100m + memory: 250Mi + requests: + cpu: 50m + memory: 40Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst @@ -53,24 +58,13 @@ maxUnavailable: 25% timeoutSeconds: 600 updatePeriodSeconds: 1 - type: Rolling - test: false + type: RollingUpdate selector: - deploymentconfig: auth-service - triggers: - - type: ConfigChange - - type: ImageChange - imageChangeParams: - automatic: true - containerNames: - - auth-service - from: - kind: ImageStreamTag - name: 'auth-service:latest' - namespace: ${PROJECT_NAME} + matchLabels: + app: auth-service - - apiVersion: apps.openshift.io/v1 - kind: DeploymentConfig + apiVersion: apps/v1 + kind: Deployment metadata: name: caimira-router spec: @@ -80,16 +74,42 @@ labels: app: caimira-router spec: + volumes: + - name: nginx-config + configMap: + name: router + defaultMode: 420 + - name: var-run + emptyDir: {} + - name: var-cache-nginx + emptyDir: {} + - name: var-log-nginx + emptyDir: {} containers: - name: caimira-router - image: '${PROJECT_NAME}/caimira-router' + image: 'registry.cern.ch/docker.io/library/nginx:1.23' ports: - containerPort: 8080 protocol: TCP - containerPort: 8443 protocol: TCP imagePullPolicy: Always - resources: {} + resources: + limits: + cpu: 100m + memory: 250Mi + requests: + cpu: 50m + memory: 16Mi + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/conf.d + - name: var-run + mountPath: /var/run + - name: var-cache-nginx + mountPath: /var/cache/nginx + - name: var-log-nginx + mountPath: /var/log/nginx terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst @@ -106,24 +126,13 @@ maxUnavailable: 25% timeoutSeconds: 600 updatePeriodSeconds: 1 - type: Rolling - test: false + type: RollingUpdate selector: - app: caimira-router - triggers: - - type: ImageChange - imageChangeParams: - automatic: true - containerNames: - - caimira-router - from: - kind: ImageStreamTag - name: 'caimira-router:latest' - namespace: ${PROJECT_NAME} - - type: ConfigChange + matchLabels: + app: caimira-router - - apiVersion: apps.openshift.io/v1 - kind: DeploymentConfig + apiVersion: apps/v1 + kind: Deployment metadata: name: calculator-app labels: @@ -153,7 +162,7 @@ - name: CAIMIRA_CALCULATOR_PREFIX value: /calculator-cern - name: CAIMIRA_THEME - value: caimira/apps/templates/cern + value: cern_caimira/apps/templates/cern - name: ARVE_CLIENT_ID valueFrom: secretKeyRef: @@ -173,7 +182,7 @@ value: '0' - name: CAIMIRA_PROFILER_ENABLED value: '1' - image: '${PROJECT_NAME}/calculator-app' + image: 'gitlab-registry.cern.ch/caimira/caimira/calculator-app:latest' ports: - containerPort: 8080 protocol: TCP @@ -193,8 +202,8 @@ cpu: '3' memory: 3Gi requests: - cpu: '1' - memory: 1Gi + cpu: 50m + memory: 250Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst @@ -211,24 +220,13 @@ maxUnavailable: 25% timeoutSeconds: 600 updatePeriodSeconds: 1 - type: Rolling - test: false + type: RollingUpdate selector: - app: calculator-app - triggers: - - type: ImageChange - imageChangeParams: - automatic: true - containerNames: - - calculator-app - from: - kind: ImageStreamTag - name: 'calculator-app:latest' - namespace: ${PROJECT_NAME} - - type: ConfigChange + matchLabels: + app: calculator-app - - apiVersion: apps.openshift.io/v1 - kind: DeploymentConfig + apiVersion: apps/v1 + kind: Deployment metadata: name: calculator-open-app labels: @@ -254,7 +252,7 @@ value: '0' - name: CAIMIRA_PROFILER_ENABLED value: '1' - image: '${PROJECT_NAME}/calculator-app' + image: 'gitlab-registry.cern.ch/caimira/caimira/calculator-app:latest' ports: - containerPort: 8080 protocol: TCP @@ -264,8 +262,8 @@ cpu: '3' memory: 3Gi requests: - cpu: '1' - memory: 1Gi + cpu: 50m + memory: 250Mi terminationMessagePath: /dev/termination-log terminationMessagePolicy: File dnsPolicy: ClusterFirst @@ -282,25 +280,7 @@ maxUnavailable: 25% timeoutSeconds: 600 updatePeriodSeconds: 1 - type: Rolling - test: false + type: RollingUpdate selector: - app: calculator-open-app - triggers: - - type: ConfigChange - - type: ImageChange - imageChangeParams: - automatic: true - containerNames: - - calculator-open-app - from: - kind: ImageStreamTag - name: 'calculator-app:latest' - namespace: ${PROJECT_NAME} - - type: ConfigChange - - parameters: - - name: PROJECT_NAME - description: The name of this project, e.g. caimira-test - required: true - \ No newline at end of file + matchLabels: + app: calculator-open-app diff --git a/app-config/openshift/imagestreams.yaml b/app-config/openshift/imagestreams.yaml deleted file mode 100644 index 9f6ec534..00000000 --- a/app-config/openshift/imagestreams.yaml +++ /dev/null @@ -1,44 +0,0 @@ ---- - kind: "Template" - apiVersion: template.openshift.io/v1 - metadata: - name: "caimira-imagestreams" - creationTimestamp: null - annotations: - description: "CAiMIRA imagestreams OpenShift template." - tags: "caimira-imagestreams" - labels: - template: "caimira-application" - objects: - - - kind: ImageStream - apiVersion: image.openshift.io/v1 - metadata: - name: auth-service - spec: - lookupPolicy: - local: False - - - kind: ImageStream - apiVersion: image.openshift.io/v1 - metadata: - name: caimira-router - spec: - lookupPolicy: - local: False - - - kind: ImageStream - apiVersion: image.openshift.io/v1 - metadata: - name: calculator-app - spec: - lookupPolicy: - local: False - - - kind: ImageStream - apiVersion: image.openshift.io/v1 - metadata: - name: calculator - spec: - lookupPolicy: - local: False diff --git a/app-config/openshift/services.yaml b/app-config/openshift/services.yaml index 78a05dfe..00164333 100644 --- a/app-config/openshift/services.yaml +++ b/app-config/openshift/services.yaml @@ -24,7 +24,7 @@ protocol: TCP targetPort: 8080 selector: - deploymentconfig: auth-service + app: auth-service sessionAffinity: 'None' type: 'ClusterIP' - @@ -41,7 +41,7 @@ protocol: TCP targetPort: 8080 selector: - deploymentconfig: caimira-router + app: caimira-router sessionAffinity: 'None' type: 'ClusterIP' - @@ -58,7 +58,7 @@ protocol: TCP targetPort: 8080 selector: - deploymentconfig: calculator-app + app: calculator-app sessionAffinity: 'None' type: 'ClusterIP' - @@ -75,6 +75,6 @@ protocol: TCP targetPort: 8080 selector: - deploymentconfig: calculator-open-app + app: calculator-open-app sessionAffinity: 'None' type: 'ClusterIP'