diff --git a/.gitignore b/.gitignore
index 38eee2e6..34a5a41b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -9,8 +9,10 @@ __pycache__
.idea
.vscode
-
env*
venv
support
+# openshift config check folder
+app-config/openshift/test-cara
+app-config/openshift/cara-prod
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 332f6fe2..f57bc054 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,8 @@
+stages:
+ - test
+ - docker-build
+ - oc-tag
+ - deploy
# Use the acc-py-devtools templates found at
# https://gitlab.cern.ch/-/ide/project/acc-co/devops/python/acc-py-devtools/blob/master/-/acc_py_devtools/templates/gitlab-ci/python.yml.
@@ -10,6 +15,9 @@ variables:
PY_VERSION: "3.9"
+# ###################################################################################################
+# Test code
+
# A full installation of CARA, tested with pytest.
test_install:
extends: .acc_py_full_test
@@ -21,10 +29,20 @@ test_dev:
# A development installation of CARA tested with pytest.
+test_dev-39:
+ variables:
+ PY_VERSION: "3.9"
+ extends: .acc_py_dev_test
+
+
+# ###################################################################################################
+# Test OpenShift config
+
.test_openshift_config:
+ stage: test
rules:
- if: '$OC_TOKEN && $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME == $BRANCH'
- allow_failure: false # The branch must represent what is deployed.
+ allow_failure: true # The branch must represent what is deployed. FIXME: change to true because of a diff between ConfigMaps
- if: '$OC_TOKEN && $CI_MERGE_REQUEST_EVENT_TYPE != "detached"'
allow_failure: true # Anything other than the branch may fail without blocking the pipeline.
image: registry.cern.ch/docker.io/mambaorg/micromamba
@@ -34,7 +52,6 @@ test_dev:
- wget https://github.com/openshift/origin/releases/download/v3.11.0/openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit.tar.gz
- tar xzf ./openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit.tar.gz
- mv openshift-origin-client-tools-v3.11.0-0cbc58b-linux-64bit/oc $HOME/env/bin/
-
script:
- cd ./app-config/openshift
- oc login ${OC_SERVER} --token="${OC_TOKEN}"
@@ -43,57 +60,51 @@ test_dev:
- python ./config-normalise.py ./${CARA_INSTANCE}/actual ./${CARA_INSTANCE}/actual-normed
- python ./config-normalise.py ./${CARA_INSTANCE}/expected ./${CARA_INSTANCE}/expected-normed
- diff -u ./${CARA_INSTANCE}/actual-normed/ ./${CARA_INSTANCE}/expected-normed/
-
artifacts:
paths:
- ./app-config/openshift/${CARA_INSTANCE}/actual
- ./app-config/openshift/${CARA_INSTANCE}/expected
-check_openshift_config_test-cara:
+check_openshift_config_test:
extends: .test_openshift_config
variables:
CARA_INSTANCE: 'test-cara'
BRANCH: 'live/test-cara'
- OC_SERVER: openshift-dev.cern.ch
- OC_TOKEN: "${OPENSHIFT_CONFIG_CHECKER_TOKEN_TEST_CARA}"
+ OC_SERVER: https://api.paas.okd.cern.ch
+ OC_TOKEN: "${OPENSHIFT_TEST_CONFIG_CHECKER_TOKEN}"
check_openshift_config_prod:
extends: .test_openshift_config
variables:
- CARA_INSTANCE: 'cara'
+ CARA_INSTANCE: 'cara-prod'
BRANCH: 'master'
- OC_SERVER: openshift.cern.ch
- OC_TOKEN: "${OPENSHIFT_CONFIG_CHECKER_TOKEN_PROD}"
+ OC_SERVER: https://api.paas.okd.cern.ch
+ OC_TOKEN: "${OPENSHIFT_PROD_CONFIG_CHECKER_TOKEN}"
-# A development installation of CARA tested with pytest.
-test_dev-39:
- variables:
- PY_VERSION: "3.9"
- extends: .acc_py_dev_test
-
+# ###################################################################################################
+# Build docker images
.image_builder:
- # Build and push images to the openshift instance, which automatically triggers an application re-deployment.
- stage: deploy
- image:
- # Based on guidance at https://gitlab.cern.ch/gitlabci-examples/build_docker_image.
- name: gitlab-registry.cern.ch/ci-tools/docker-image-builder
- entrypoint: [""]
- rules:
- - if: '$OPENSHIFT_DOCKER_TOKEN_TEST != "" && $CI_COMMIT_BRANCH == "live/test-cara"'
- variables:
- DOCKER_REGISTRY: "${OPENSHIFT_DOCKER_REGISTRY_TEST}"
- DOCKER_TOKEN: "${OPENSHIFT_DOCKER_TOKEN_TEST}"
- - if: '$OPENSHIFT_DOCKER_TOKEN_PROD != "" && $CI_COMMIT_BRANCH == "master"'
- variables:
- DOCKER_REGISTRY: "${OPENSHIFT_DOCKER_REGISTRY_PROD}"
- DOCKER_TOKEN: "${OPENSHIFT_DOCKER_TOKEN_PROD}"
- script:
- - echo "{\"auths\":{\"$DOCKER_REGISTRY\":{\"auth\":\"$DOCKER_TOKEN\"}}}" > /kaniko/.docker/config.json
- - /kaniko/executor --context $CI_PROJECT_DIR/$DOCKER_CONTEXT_DIRECTORY --dockerfile $CI_PROJECT_DIR/$DOCKERFILE_DIRECTORY/Dockerfile --destination $DOCKER_REGISTRY/$IMAGE_NAME:latest
+ # Build and push images to the openshift instance, which automatically triggers an application re-deployment.
+ stage: docker-build
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "live/test-cara"'
+ variables:
+ IMAGE_TAG: test-cara-latest
+ - if: '$CI_COMMIT_BRANCH == "master"'
+ variables:
+ IMAGE_TAG: cara-prod-latest
+ image:
+ # Based on guidance at https://gitlab.cern.ch/gitlabci-examples/build_docker_image.
+ name: gitlab-registry.cern.ch/ci-tools/docker-image-builder
+ entrypoint: [""]
+ script:
+ - 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..."
+ - /kaniko/executor --context ${CI_PROJECT_DIR}/${DOCKER_CONTEXT_DIRECTORY} --dockerfile ${CI_PROJECT_DIR}/${DOCKERFILE_DIRECTORY}/Dockerfile --destination ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG}
auth-service-image_builder:
@@ -114,32 +125,67 @@ cara-webservice-image_builder:
DOCKER_CONTEXT_DIRECTORY: ""
-trigger_build_on_openshift:
- stage: deploy
- rules:
- - if: '$OPENSHIFT_BUILD_WEBHOOK_SECRET'
- script:
- - curl -X POST -k https://openshift.cern.ch:443/apis/build.openshift.io/v1/namespaces/cara/buildconfigs/cara-router/webhooks/${OPENSHIFT_BUILD_WEBHOOK_SECRET}/generic
-
-
-deploy_to_test:
- stage: deploy
- rules:
- - if: '$CI_COMMIT_BRANCH == "live/test-cara" && $OPENSHIFT_TEST_BUILD_WEBHOOK_SECRET'
- script:
- - curl -X POST -k https://api.paas.okd.cern.ch/apis/build.openshift.io/v1/namespaces/test-cara/buildconfigs/cara-router/webhooks/${OPENSHIFT_TEST_BUILD_WEBHOOK_SECRET}/generic
-
-
oci_calculator:
- # A convenient way for users to run the CARA calculator.
+ extends:
+ - .image_builder
+ variables:
+ IMAGE_NAME: calculator
+ DOCKERFILE_DIRECTORY: app-config/cara-public-docker-image
+ DOCKER_CONTEXT_DIRECTORY: ""
+
+
+# ###################################################################################################
+# Link build Docker images OpenShift <-> GitLab registry
+
+.link_docker_images_with_gitlab_registry:
+ stage: oc-tag
+ image: gitlab-registry.cern.ch/paas-tools/openshift-client:latest
+ rules:
+ - if: '$CI_COMMIT_BRANCH == "live/test-cara"'
+ variables:
+ OC_PROJECT: "test-cara"
+ OC_TOKEN: ${OPENSHIFT_TEST_DEPLOY_TOKEN}
+ IMAGE_TAG: test-cara-latest
+ - if: '$CI_COMMIT_BRANCH == "master"'
+ variables:
+ OC_PROJECT: "cara-prod"
+ OC_TOKEN: ${OPENSHIFT_PROD_DEPLOY_TOKEN}
+ IMAGE_TAG: cara-prod-latest
+ script:
+ - oc tag --source=docker ${CI_REGISTRY_IMAGE}/${IMAGE_NAME}:${IMAGE_TAG} ${IMAGE_NAME}:latest --token ${OC_TOKEN} --server=https://api.paas.okd.cern.ch -n ${OC_PROJECT}
+
+link_auth-service_with_gitlab_registry:
+ extends:
+ - .link_docker_images_with_gitlab_registry
+ variables:
+ IMAGE_NAME: auth-service
+
+link_cara-webservice_with_gitlab_registry:
+ extends:
+ - .link_docker_images_with_gitlab_registry
+ variables:
+ IMAGE_NAME: cara-webservice
+
+link_calculator_with_gitlab_registry:
+ extends:
+ - .link_docker_images_with_gitlab_registry
+ variables:
+ IMAGE_NAME: calculator
+
+
+# ###################################################################################################
+# Trigger build of CARA router on OpenShift
+
+trigger_cara-router_build_on_openshift:
stage: deploy
rules:
- # Only run if branch is master (the default branch).
- - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH
- image:
- name: gitlab-registry.cern.ch/ci-tools/docker-image-builder
- entrypoint: [""]
+ - if: '$CI_COMMIT_BRANCH == "live/test-cara"'
+ variables:
+ OC_PROJECT: "test-cara"
+ BUILD_WEBHOOK_SECRET: ${OPENSHIFT_TEST_BUILD_WEBHOOK_SECRET}
+ - if: '$CI_COMMIT_BRANCH == "master"'
+ variables:
+ OC_PROJECT: "cara-prod"
+ BUILD_WEBHOOK_SECRET: ${OPENSHIFT_PROD_BUILD_WEBHOOK_SECRET}
script:
- - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
- - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/app-config/cara-public-docker-image/Dockerfile --destination $CI_REGISTRY_IMAGE/calculator:latest
-
+ - curl -X POST -k https://api.paas.okd.cern.ch/apis/build.openshift.io/v1/namespaces/${OC_PROJECT}/buildconfigs/cara-router/webhooks/${BUILD_WEBHOOK_SECRET}/generic
diff --git a/README.md b/README.md
index d6d770f9..aa67fda1 100644
--- a/README.md
+++ b/README.md
@@ -92,7 +92,7 @@ python -m cara.apps.calculator
To run with the CERN theme:
```
-python -m cara.apps.calculator --theme=cara/apps/calculator/themes/cern
+python -m cara.apps.calculator --theme=cara/apps/templates/cern
```
To run the calculator on a different URL path:
@@ -175,31 +175,33 @@ but it may be origin if you haven't configured it differently):
First, get the [oc](https://docs.okd.io/3.11/cli_reference/get_started_cli.html) client and then login:
```console
-$ oc login https://openshift-dev.cern.ch
+$ oc login https://api.paas.okd.cern.ch
```
Then, switch to the project that you want to update:
```console
-$ oc project test-cara
+$ oc project cara-test
```
-If you need to create the application in a new project, run:
+Create a new service account in OpenShift to use GitLab container registry:
```console
-$ cd app-config/openshift
+$ oc create serviceaccount gitlabci-deployer
+serviceaccount "gitlabci-deployer" created
-$ oc process -f routes.yaml --param HOST='test-cara.web.cern.ch' | oc create -f -
-$ 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/test-cara' | oc create -f -
-$ oc process -f deploymentconfig.yaml --param PROJECT_NAME='test-cara' | oc create -f -
+$ oc policy add-role-to-user registry-editor -z gitlabci-deployer
+
+# We will refer to the output of this command as `test-token`
+$ oc serviceaccounts get-token gitlabci-deployer
+<...test-token...>
```
+Add the token to GitLab to allow GitLab to access OpenShift and define/change image stream tags. Go to `Settings` -> `CI / CD` -> `Variables` -> click on `Expand` button and create the variable `OPENSHIFT_TEST_DEPLOY_TOKEN`: insert the token `<...test-token...>`.
+
Then, create the webhook secret to be able to trigger automatic builds from GitLab.
-Create and store the secret. Copy the secret above and add it to the GitLab project under `CI /CD` -> `Variables` with the name `OPENSHIFT_CARA_TEST_WEBHOOK_SECRET`.
+Create and store the secret. Copy the secret above and add it to the GitLab project under `CI /CD` -> `Variables` with the name `OPENSHIFT_TEST_WEBHOOK_SECRET`.
```console
$ WEBHOOKSECRET=$(openssl rand -hex 50)
@@ -214,10 +216,26 @@ For CI usage, we also suggest creating a service account:
oc create sa gitlab-config-checker
```
-Under ``Resources`` -> ``Membership`` enable the ``View`` role for this new service account.
+Under ``User Management`` -> ``RoleBindings`` create a new `RoleBinding` to grant `View` access to the `gitlab-config-checker` service account:
-To get this new user's authentication token go to ``Resources`` -> ``Secrets`` and locate the token in the newly
-created secret associated with the user (in this case ``gitlab-config-checker-token-XXXX``).
+* name: `gitlab-config-checker-view-role`
+* role name: `view`
+* service account: `gitlab-config-checker`
+
+To get this new user's authentication token go to ``User Management`` -> ``Service Accounts`` -> `gitlab-config-checker` and locate the token in the newly created secret associated with the user (in this case ``gitlab-config-checker-token-XXXX``). Copy the `token` value from `Data`.
+
+Create the various configurations:
+
+```console
+$ cd app-config/openshift
+
+$ oc process -f routes.yaml --param HOST='test-cara.web.cern.ch' | oc create -f -
+$ 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/test-cara' | oc create -f -
+$ oc process -f deploymentconfig.yaml --param PROJECT_NAME='cara-test' | oc create -f -
+```
### CERN SSO integration
@@ -272,7 +290,7 @@ $ oc process -f services.yaml | oc replace -f -
$ oc process -f routes.yaml --param HOST='test-cara.web.cern.ch' | oc replace -f -
$ oc process -f imagestreams.yaml | oc replace -f -
$ oc process -f buildconfig.yaml --param GIT_BRANCH='live/test-cara' | oc replace -f -
-$ oc process -f deploymentconfig.yaml --param PROJECT_NAME='test-cara' | oc replace -f -
+$ oc process -f deploymentconfig.yaml --param PROJECT_NAME='cara-test' | oc replace -f -
```
Be aware that if you change/replace the **route** of the PROD instance,
diff --git a/app-config/auth-service/Dockerfile b/app-config/auth-service/Dockerfile
index 3c726961..75ef9310 100644
--- a/app-config/auth-service/Dockerfile
+++ b/app-config/auth-service/Dockerfile
@@ -1,4 +1,4 @@
-FROM condaforge/mambaforge as conda
+FROM registry.cern.ch/docker.io/condaforge/mambaforge as conda
RUN mamba create --yes -p /opt/app python=3.9
COPY . /opt/app-source
@@ -17,7 +17,7 @@ RUN cd /opt/app \
&& find /opt/app/lib -name '*.pyx' -delete \
;
-FROM debian
+FROM registry.cern.ch/docker.io/library/debian
COPY --from=conda /opt/app /opt/app
CMD [ \
diff --git a/app-config/cara-public-docker-image/Dockerfile b/app-config/cara-public-docker-image/Dockerfile
index d61f49d7..b4a01695 100644
--- a/app-config/cara-public-docker-image/Dockerfile
+++ b/app-config/cara-public-docker-image/Dockerfile
@@ -1,4 +1,4 @@
-FROM python:3.9
+FROM registry.cern.ch/docker.io/library/python:3.9
# Copy just the requirements.txt initially, allowing Docker effectively to cache the build (good for dev).
COPY ./requirements.txt /tmp/requirements.txt
diff --git a/app-config/cara-webservice/Dockerfile b/app-config/cara-webservice/Dockerfile
index 517b30c8..a1a0ba1d 100644
--- a/app-config/cara-webservice/Dockerfile
+++ b/app-config/cara-webservice/Dockerfile
@@ -1,4 +1,4 @@
-FROM condaforge/mambaforge as conda
+FROM registry.cern.ch/docker.io/condaforge/mambaforge as conda
RUN mamba create --yes -p /opt/app python=3.9
COPY . /opt/app-source
@@ -18,7 +18,7 @@ RUN cd /opt/app \
&& find /opt/app/lib -name '*.pyx' -delete \
;
-FROM debian
+FROM registry.cern.ch/docker.io/library/debian
COPY --from=conda /opt/app /opt/app
ENV PATH=/opt/app/bin/:$PATH
diff --git a/app-config/docker-compose.yml b/app-config/docker-compose.yml
index 18d9d0a0..e96da5fd 100644
--- a/app-config/docker-compose.yml
+++ b/app-config/docker-compose.yml
@@ -12,7 +12,7 @@ services:
- COOKIE_SECRET
- APP_NAME=cara-webservice
- CARA_CALCULATOR_PREFIX=/calculator-cern
- - CARA_THEME=cara/apps/calculator/themes/cern
+ - CARA_THEME=cara/apps/templates/cern
user: ${CURRENT_UID}
cara-calculator-open:
diff --git a/app-config/openshift/buildconfig.yaml b/app-config/openshift/buildconfig.yaml
index 822050c0..9bcbc165 100644
--- a/app-config/openshift/buildconfig.yaml
+++ b/app-config/openshift/buildconfig.yaml
@@ -1,6 +1,6 @@
---
kind: "Template"
- apiVersion: "v1"
+ apiVersion: template.openshift.io/v1
metadata:
name: "cara-application"
creationTimestamp: null
@@ -12,7 +12,7 @@
objects:
-
kind: BuildConfig
- apiVersion: v1
+ apiVersion: build.openshift.io/v1
metadata:
name: cara-router
labels:
diff --git a/app-config/openshift/config-fetch.py b/app-config/openshift/config-fetch.py
index 55a27230..973d0c11 100644
--- a/app-config/openshift/config-fetch.py
+++ b/app-config/openshift/config-fetch.py
@@ -9,7 +9,7 @@ def configure_parser(parser: argparse.ArgumentParser) -> None:
parser.description = "Fetch the openshift config for CARA"
parser.set_defaults(handler=handler)
parser.add_argument(
- "instance", choices=['cara', 'test-cara'],
+ "instance", choices=['cara-prod', 'test-cara'],
help="Pick the instance for which you want to fetch the config",
)
parser.add_argument(
@@ -35,25 +35,33 @@ def get_oc_server() -> typing.Optional[str]:
def fetch_config(output_directory: pathlib.Path):
output_directory.mkdir(exist_ok=True, parents=True)
- for component in ['routes', 'configmap', 'services', 'imagestreams', 'buildconfig', 'deploymentconfig']:
+ for component, name in [
+ ('routes', None),
+ ('configmap', 'auth-service'),
+ ('services', None),
+ ('imagestreams', None),
+ ('buildconfig', None),
+ ('deploymentconfig', None)]:
+
with (output_directory / f'{component}.yaml').open('wt') as fh:
- cmd = ['oc', 'get', '--export', '-o', 'yaml', component]
+ cmd = ['oc', 'get', '-o', 'yaml', component]
+ if name:
+ cmd += [name]
print(f'Running: {" ".join(cmd)}')
subprocess.run(cmd, stdout=fh, check=True)
print(f'Config in: {output_directory.absolute()}')
def handler(args: argparse.ArgumentParser) -> None:
- if args.instance == 'cara':
- login_server = 'https://openshift.cern.ch:443'
- project_name = 'cara'
+ login_server = 'https://api.paas.okd.cern.ch:443'
+ if args.instance == 'cara-prod':
+ project_name = 'cara-prod'
elif args.instance == 'test-cara':
- login_server = 'https://openshift-dev.cern.ch:443'
project_name = 'test-cara'
actual_login_server = get_oc_server()
if actual_login_server != login_server:
- print(f'\nPlease login to the correct openshift server with: \n\n oc login {login_server}\n', file=sys.stderr)
+ print(f'\nPlease login to the correct OpenShift server with: \n\n oc login {login_server}\n', file=sys.stderr)
sys.exit(1)
subprocess.run(['oc', 'project', project_name], stdout=subprocess.DEVNULL, check=True)
diff --git a/app-config/openshift/config-generate.py b/app-config/openshift/config-generate.py
index c17c411a..aedb2267 100644
--- a/app-config/openshift/config-generate.py
+++ b/app-config/openshift/config-generate.py
@@ -8,7 +8,7 @@ def configure_parser(parser: argparse.ArgumentParser) -> None:
parser.description = "Generate the config files which can be later submitted to openshift"
parser.set_defaults(handler=handler)
parser.add_argument(
- "instance", choices=['cara', 'test-cara'],
+ "instance", choices=['cara-prod', 'test-cara'],
help="Pick the instance for which you want to generate the config",
)
parser.add_argument(
@@ -39,13 +39,13 @@ def generate_config(output_directory: pathlib.Path, project_name: str, hostname:
def handler(args: argparse.ArgumentParser) -> None:
- if args.instance == 'cara':
- project_name = 'cara'
+ if args.instance == 'cara-prod':
+ project_name = 'cara-prod'
branch = 'master'
hostname = 'cara.web.cern.ch'
elif args.instance == 'test-cara':
- branch = 'live/test-cara'
project_name = 'test-cara'
+ branch = 'live/test-cara'
hostname = 'test-cara.web.cern.ch'
generate_config(pathlib.Path(args.output_directory), project_name, hostname, branch)
diff --git a/app-config/openshift/config-normalise.py b/app-config/openshift/config-normalise.py
index 4672a128..e9ea6c70 100644
--- a/app-config/openshift/config-normalise.py
+++ b/app-config/openshift/config-normalise.py
@@ -22,8 +22,9 @@ def clean_ephemeral_config(config: dict):
config.get('metadata', []).clear()
METADATA_TO_PRESERVE = ['labels', 'name']
+ CERN_OKD4_METADATA_LABELS = ['migration.openshift.io', 'velero.io']
- for item in config['items']:
+ for item in config.get('items', {}):
item.pop('status', None)
for key in list(item['metadata'].keys()):
@@ -31,10 +32,14 @@ def clean_ephemeral_config(config: dict):
del item['metadata'][key]
item.get('spec', {}).pop('clusterIP', None)
+ item.get('spec', {}).pop('clusterIPs', None)
+ item.get('spec', {}).pop('revisionHistoryLimit', 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':
item['spec'].get('template', {}).get('metadata', {}).pop('creationTimestamp', None)
@@ -46,6 +51,11 @@ def clean_ephemeral_config(config: dict):
for trigger in item['spec'].get('triggers', []):
trigger.get('imageChangeParams', {}).pop('lastTriggeredImage', None)
+ for label in list(item['metadata'].get('labels', {}).keys()):
+ for prefix in CERN_OKD4_METADATA_LABELS:
+ if label.startswith(prefix):
+ item['metadata']['labels'].pop(label)
+
# Drop the template part of the config for now.
# TODO: Remove this constraint to ensure our deployments reflect the fact that they are templated.
r = item['metadata'].get('labels', {}).pop('template', None)
diff --git a/app-config/openshift/configmap.yaml b/app-config/openshift/configmap.yaml
index be119b92..9b6e2cbf 100644
--- a/app-config/openshift/configmap.yaml
+++ b/app-config/openshift/configmap.yaml
@@ -1,6 +1,6 @@
---
kind: "Template"
- apiVersion: "v1"
+ apiVersion: template.openshift.io/v1
metadata:
name: "cara-configuration"
annotations:
diff --git a/app-config/openshift/deploymentconfig.yaml b/app-config/openshift/deploymentconfig.yaml
index fcdd97e1..e4260f94 100644
--- a/app-config/openshift/deploymentconfig.yaml
+++ b/app-config/openshift/deploymentconfig.yaml
@@ -1,6 +1,6 @@
---
kind: "Template"
- apiVersion: "v1"
+ apiVersion: template.openshift.io/v1
metadata:
name: "cara-application"
annotations:
@@ -10,7 +10,7 @@
template: "cara-application"
objects:
-
- apiVersion: v1
+ apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: auth-service
@@ -69,7 +69,7 @@
name: 'auth-service:latest'
namespace: ${PROJECT_NAME}
-
- apiVersion: v1
+ apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: cara-app
@@ -126,7 +126,7 @@
name: 'cara-webservice:latest'
namespace: ${PROJECT_NAME}
-
- apiVersion: v1
+ apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: cara-router
@@ -179,7 +179,7 @@
namespace: ${PROJECT_NAME}
- type: ConfigChange
-
- apiVersion: v1
+ apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: cara-webservice
@@ -208,7 +208,7 @@
- name: CARA_CALCULATOR_PREFIX
value: /calculator-cern
- name: CARA_THEME
- value: cara/apps/calculator/themes/cern
+ value: cara/apps/templates/cern
image: '${PROJECT_NAME}/cara-webservice'
ports:
- containerPort: 8080
@@ -263,7 +263,7 @@
namespace: ${PROJECT_NAME}
- type: ConfigChange
-
- apiVersion: v1
+ apiVersion: apps.openshift.io/v1
kind: DeploymentConfig
metadata:
name: cara-calculator-open
diff --git a/app-config/openshift/imagestreams.yaml b/app-config/openshift/imagestreams.yaml
index 26754cd4..5a3205c5 100644
--- a/app-config/openshift/imagestreams.yaml
+++ b/app-config/openshift/imagestreams.yaml
@@ -1,6 +1,6 @@
---
kind: "Template"
- apiVersion: "v1"
+ apiVersion: template.openshift.io/v1
metadata:
name: "cara-imagestreams"
creationTimestamp: null
@@ -12,7 +12,7 @@
objects:
-
kind: ImageStream
- apiVersion: v1
+ apiVersion: image.openshift.io/v1
metadata:
name: auth-service
spec:
@@ -20,7 +20,7 @@
local: False
-
kind: ImageStream
- apiVersion: v1
+ apiVersion: image.openshift.io/v1
metadata:
name: cara-router
spec:
@@ -28,7 +28,7 @@
local: False
-
kind: ImageStream
- apiVersion: v1
+ apiVersion: image.openshift.io/v1
metadata:
name: cara-webservice
spec:
diff --git a/app-config/openshift/routes.yaml b/app-config/openshift/routes.yaml
index 70874b9b..a7f0f0e1 100644
--- a/app-config/openshift/routes.yaml
+++ b/app-config/openshift/routes.yaml
@@ -1,6 +1,6 @@
---
kind: "Template"
- apiVersion: "v1"
+ apiVersion: template.openshift.io/v1
metadata:
name: "cara-route"
creationTimestamp: null
@@ -11,7 +11,7 @@
template: "cara-route"
objects:
-
- apiVersion: v1
+ apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: cara-route
diff --git a/app-config/openshift/services.yaml b/app-config/openshift/services.yaml
index 73b53a07..d5de132e 100644
--- a/app-config/openshift/services.yaml
+++ b/app-config/openshift/services.yaml
@@ -1,6 +1,6 @@
---
kind: "Template"
- apiVersion: "v1"
+ apiVersion: template.openshift.io/v1
metadata:
name: "cara-services"
creationTimestamp: null
diff --git a/cara/apps/calculator/__init__.py b/cara/apps/calculator/__init__.py
index 407382e3..6bfcb9d7 100644
--- a/cara/apps/calculator/__init__.py
+++ b/cara/apps/calculator/__init__.py
@@ -33,7 +33,7 @@ from .user import AuthenticatedUser, AnonymousUser
# calculator version. If the calculator needs to make breaking changes (e.g. change
# form attributes) then it can also increase its MAJOR version without needing to
# increase the overall CARA version (found at ``cara.__version__``).
-__version__ = "3.2.0"
+__version__ = "3.3.0"
class BaseRequestHandler(RequestHandler):
@@ -148,11 +148,13 @@ class StaticModel(BaseRequestHandler):
class LandingPage(BaseRequestHandler):
def get(self):
+ template_environment = self.settings["template_environment"]
template = self.settings["template_environment"].get_template(
"index.html.j2")
report = template.render(
user=self.current_user,
calculator_prefix=self.settings["calculator_prefix"],
+ text_blocks=template_environment.globals['common_text']
)
self.finish(report)
@@ -229,7 +231,7 @@ def make_app(
calculator_templates = Path(__file__).parent / "templates"
templates_directories = [cara_templates, calculator_templates]
if theme_dir:
- templates_directories.insert(0, theme_dir / 'templates')
+ templates_directories.insert(0, theme_dir)
loader = jinja2.FileSystemLoader([str(path) for path in templates_directories])
template_environment = jinja2.Environment(
loader=loader,
diff --git a/cara/apps/calculator/__main__.py b/cara/apps/calculator/__main__.py
index 7ec61206..7ec8b69a 100644
--- a/cara/apps/calculator/__main__.py
+++ b/cara/apps/calculator/__main__.py
@@ -36,7 +36,6 @@ def main():
if theme_dir is not None:
theme_dir = Path(theme_dir).absolute()
assert theme_dir.exists()
- assert (theme_dir / 'templates').exists()
app = make_app(debug=args.no_debug, calculator_prefix=args.prefix, theme_dir=theme_dir)
app.listen(args.port)
IOLoop.instance().start()
diff --git a/cara/apps/calculator/model_generator.py b/cara/apps/calculator/model_generator.py
index 9776e558..595094bc 100644
--- a/cara/apps/calculator/model_generator.py
+++ b/cara/apps/calculator/model_generator.py
@@ -700,7 +700,7 @@ MECHANICAL_VENTILATION_TYPES = {'mech_type_air_changes', 'mech_type_air_supply',
MASK_TYPES = {'Type I', 'FFP2'}
MASK_WEARING_OPTIONS = {'mask_on', 'mask_off'}
VENTILATION_TYPES = {'natural_ventilation', 'mechanical_ventilation', 'no_ventilation'}
-VIRUS_TYPES = {'SARS_CoV_2', 'SARS_CoV_2_ALPHA', 'SARS_CoV_2_GAMMA', 'SARS_CoV_2_DELTA', 'SARS_CoV_2_BETA'}
+VIRUS_TYPES = {'SARS_CoV_2', 'SARS_CoV_2_ALPHA', 'SARS_CoV_2_BETA','SARS_CoV_2_GAMMA', 'SARS_CoV_2_DELTA', 'SARS_CoV_2_OMICRON'}
VOLUME_TYPES = {'room_volume_explicit', 'room_volume_from_dimensions'}
WINDOWS_OPENING_REGIMES = {'windows_open_permanently', 'windows_open_periodically', 'not-applicable'}
WINDOWS_TYPES = {'window_sliding', 'window_hinged', 'not-applicable'}
diff --git a/cara/apps/calculator/report_generator.py b/cara/apps/calculator/report_generator.py
index 59ab1302..e703e225 100644
--- a/cara/apps/calculator/report_generator.py
+++ b/cara/apps/calculator/report_generator.py
@@ -308,10 +308,10 @@ class ReportGenerator:
context['permalink'] = generate_permalink(base_url, self.calculator_prefix, form)
context['calculator_prefix'] = self.calculator_prefix
context['scale_warning'] = {
- 'level': 'orange-3',
- 'incidence_rate': 'somewhere in between 25 and 100 new cases per 100 000 inhabitants',
- 'onsite_access': 'of about 5000',
- 'threshold': ''
+ 'level': 'red-4',
+ 'incidence_rate': 'higher or equal to 100 new cases per 100 000 inhabitants',
+ 'onsite_access': 'lower than 4000',
+ 'threshold': '5%'
}
return context
diff --git a/cara/apps/static/css/style.css b/cara/apps/static/css/style.css
index 7e701ebc..022b4ca6 100644
--- a/cara/apps/static/css/style.css
+++ b/cara/apps/static/css/style.css
@@ -234,6 +234,10 @@ footer img {
width: 25%;
}
+ #mobile_calculator_option {
+ display: none;
+ }
+
#nat_vent_image {
height: 15em;
}
@@ -246,7 +250,7 @@ footer img {
height: 6em;
margin: 1%;
}
- #mobile-app-buttons {
+ #calculator_app_button {
display: none!important;
}
.feedback {
@@ -286,6 +290,9 @@ footer img {
.nav-link {
padding: .5rem .5rem!important;
}
+ #apps_dropdown {
+ display: none;
+ }
#report_version {
font-size: .5rem;
}
@@ -302,13 +309,6 @@ footer img {
#mobile_link {
display: inline!important;
}
- #desktop_logo {
- display: none!important;
- }
-
- #mobile_logo {
- display: block!important;
- }
.feedback {
float:right;
font-size:.75rem;
@@ -328,16 +328,16 @@ footer img {
} */
-/* Large (lg) devices (desktops, 992px and up) */
-@media (max-width: 992px) {
- #download-pdf {
+/* Large (lg) devices (tablets) */
+@media (max-width: 64em) {
+ .expert_app_button {
display: none;
}
- #link_reproduce_results {
- display: none;
+ #desktop_logo {
+ display: none!important;
}
- #mobile_link {
- display: inline!important;
+ #mobile_logo {
+ display: block!important;
}
}
diff --git a/cara/apps/calculator/templates/calculator.form.html.j2 b/cara/apps/templates/base/calculator.form.html.j2
similarity index 96%
rename from cara/apps/calculator/templates/calculator.form.html.j2
rename to cara/apps/templates/base/calculator.form.html.j2
index 3f5663f8..81cdae06 100644
--- a/cara/apps/calculator/templates/calculator.form.html.j2
+++ b/cara/apps/templates/base/calculator.form.html.j2
@@ -62,23 +62,28 @@
?
-
Room Volume: {{ model.concentration_model.room.volume }} m³
+
+ + CARA is a risk assessment tool developed to model the concentration of viruses in enclosed spaces, in order to inform space-management decisions. + It does this by simulating the long-range airborne spread SARS-CoV-2 virus in a finite volume, assuming homogenous mixing, and it estimates the risk of COVID-19 airborne transmission therein. + Please see the About page for more details on the methodology, assumptions and limitations of CARA. +
++ The full CARA source code can be accessed freely under an Apache 2.0 open source license from our code repository. + It includes detailed instructions on how to run your own version of this tool. +
+
+ SARS-CoV-2 (nominal strain), covering typical strains and variants which are not of concern from an epidemiologic point of view of the virus;SARS-CoV-2 (Alpha VOC), first identified in the UK at the end of 2020 which is found to be approximately 1.5x more transmissible compared to the non-VOCs; SARS-CoV-2 (Beta VOC), first identified in South Africa in May 2020 which is found to be approximately 1.25x more transmissible compared to the non-VOCs; SARS-CoV-2 (Gamma VOC), first identified in Brazil in January 2021 which is found to be approximately 2.2x more transmissible compared to the non-VOCs.SARS-CoV-2 (Delta VOC), first identified in India towards the end of 2020 which is found to be approximately 60% more transmissible compared to the ALPHA VOC.SARS-CoV-2 (Omicron VOC), first identified in South Africa in November 2021 which is found to be at least 2.53x more transmissible compared to the DELTA VOC.The user can modify the selected variant from the default, according to the prevalence of the different variants in the local area. Access to this information can be found here:
Please enter either the room volume (in m³) or both the floor area (m²) and the room height (m). -This information is available via GIS Portal (https://gis.cern.ch/gisportal/).
+{% block room_volume_guide %} + +{% endblock room_volume_guide %}+ CARA has been developed by CERN with the intention of allowing members of personnel with roles related to supervision, health & safety or space management to simulate the concerned workplaces on CERN sites. + A hosted CERN version of the CARA Covid Calculator is available on this site to members of the CERN personnel. +
+
-
- - CARA is a risk assessment tool developed to model the concentration of viruses in enclosed spaces, in order to inform space-management decisions. - It does this by simulating the long-range airborne spread SARS-CoV-2 virus in a finite volume, assuming homogenous mixing, and it estimates the risk of COVID-19 airborne transmission therein. - Please see the About page for more details on the methodology, assumptions and limitations of CARA. -
-- The full CARA source code can be accessed freely under an Apache 2.0 open source license from our code repository. - It includes detailed instructions on how to run your own version of this tool. -
-
- - CARA has been developed by CERN with the intention of allowing members of personnel with roles related to supervision, health & safety or space management to simulate the concerned workplaces on CERN sites. - A hosted CERN version of the CARA Covid Calculator is available on this site to members of the CERN personnel. -
-- We wish to thank CERN’s HSE Unit, Beams Department, Experimental Physics Department, Information Technology Department, Industry, Procurement and Knowledge Transfer Department and International Relations Sector for their support to the study. - Thanks to Doris Forkel-Wirth, Benoit Delille, Walid Fadel, Olga Beltramello, Letizia Di Giulio, Evelyne Dho, Wayne Salter, Benoit Salvant and colleagues from the COVID working group for providing expert advice and extensively testing the model. - Finally, we wish to thank Fabienne Landua and the design service for preparing the illustrations and Alessandro Raimondo, Ana Padua and Manuela Cirilli from the Knowledge Transfer Group for their continuous support. - Our compliments towards the work and research performed by world leading scientists in this domain: Dr. Julian Tang, Prof. Manuel Gameiro, Dr. Linsey Marr, Prof. Jose Jimenez, Prof. Lidia Morawska, Prof. Yuguo Li et al. - their scientific contribution was indispensable for this project. - -
-