From f549f95b2c677c9aa571bf51337452584d2baf1a Mon Sep 17 00:00:00 2001 From: Enola Knezevic <115070135+enola-dkfz@users.noreply.github.com> Date: Mon, 29 Jun 2026 11:16:57 +0200 Subject: [PATCH 01/10] added CQL_FLAVOUR (#391) --- bbmri/modules/eric-compose.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/bbmri/modules/eric-compose.yml b/bbmri/modules/eric-compose.yml index e6ed044..65eb6b6 100644 --- a/bbmri/modules/eric-compose.yml +++ b/bbmri/modules/eric-compose.yml @@ -12,6 +12,7 @@ services: BEAM_PROXY_URL: http://beam-proxy-eric:8081 RETRY_COUNT: ${FOCUS_RETRY_COUNT} OBFUSCATE_BBMRI_ERIC_WAY: "true" + CQL_FLAVOUR: "${FOCUS_CQL_FLAVOUR}" depends_on: - "beam-proxy-eric" - "blaze" From d7c01594de360304ebbe3f897b213e5033e30b2b Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Tue, 30 Jun 2026 15:28:25 +0200 Subject: [PATCH 02/10] Don't use wildcard in sudoers to support sudo-rs (#392) --- lib/install-bridgehead.sh | 1 - lib/update-bridgehead.sh | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/install-bridgehead.sh b/lib/install-bridgehead.sh index f712153..2e2ec69 100755 --- a/lib/install-bridgehead.sh +++ b/lib/install-bridgehead.sh @@ -21,7 +21,6 @@ Cmnd_Alias BRIDGEHEAD${PROJECT^^} = \\ /bin/systemctl start bridgehead@${PROJECT}.service, \\ /bin/systemctl stop bridgehead@${PROJECT}.service, \\ /bin/systemctl restart bridgehead@${PROJECT}.service, \\ - /bin/systemctl restart bridgehead@*.service, \\ /bin/chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead, \\ /usr/bin/chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead diff --git a/lib/update-bridgehead.sh b/lib/update-bridgehead.sh index 8ae3bde..cf846db 100755 --- a/lib/update-bridgehead.sh +++ b/lib/update-bridgehead.sh @@ -98,7 +98,7 @@ if [ $git_updated = "true" ] || [ $docker_updated = "true" ]; then RES="Updates detected, now restarting bridgehead:\n$CHANGES" log "INFO" "$RES" hc_send log "$RES" - sudo /bin/systemctl restart bridgehead@*.service + sudo /bin/systemctl restart bridgehead@${PROJECT}.service else RES="Nothing updated, nothing to restart." log "INFO" "$RES" From 65f8edcef77ae8452f4a09a2d557bdb1b1fef899 Mon Sep 17 00:00:00 2001 From: DavidCroftDKFZ <46788708+DavidCroftDKFZ@users.noreply.github.com> Date: Tue, 4 Aug 2026 12:07:08 +0200 Subject: [PATCH 03/10] Added extra information about uploading and ETL to README. (#395) --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 03a1b63..96859e4 100644 --- a/README.md +++ b/README.md @@ -359,14 +359,20 @@ https:///bbmri-localdatamanagement/fhir ``` The name of your server will generally be the full name of the VM that the Bridgehead runs on. You can alternatively supply an IP address. -The FHIR API uses basic auth. You can find the credentials in `/etc/bridgehead/.local.conf`. +For more information on how to use the FHIR API, please refer to the [Hapi FHIR tutorial](https://github.com/hapifhir/fhir-tutorial/blob/master/CRUD%20operations/lesson.md). + +The Bridgehead's FHIR API uses basic auth. You can find the credentials in `/etc/bridgehead/.local.conf`. Note that if you don't have a DNS certificate for the Bridgehead, you will need to allow an insecure connection. E.g. with curl, use the `-k` flag. -The storage space on your hard drive will depend on the number of FHIR resources that you intend to generate. This will be the sum of the number of patients/subjects, the number of samples, the number of conditions/diseases and the number of observations. As a general rule of thumb, you can assume that each resource will consume about 2 kilobytes of disk space. +As an alternative to curl, you can also use the tool [blazectl](https://github.com/samply/blazectl) for uploading data to the FHIR store. + +The storage space needed on your hard drive will depend on the number of FHIR resources that you intend to generate. This will be the sum of the number of patients/subjects, the number of samples, the number of conditions/diseases and the number of observations. As a general rule of thumb, you can assume that each resource will consume about 2 kilobytes of disk space. For more information on Blaze performance, please refer to [import performance](https://github.com/samply/blaze/blob/master/docs/performance/import.md). +If you can make your data available in tabular form (e.g. as an Excel file), then you can use the ["a small fire"](https://github.com/bbdataeng/a-small-fire) tool to convert your data into the FHIR format needed for upload to the FHIR store. + ### Clearing data The Bridgehead's FHIR store, Blaze, saves its data in a Docker volume. This means that the data will persist even if you stop the Bridgehead. You can clear existing data from the FHIR store by deleting the relevant Docker volume. From 1b4a290216633edfe7307f05976186a430852585 Mon Sep 17 00:00:00 2001 From: tm16-medma <142219207+tm16-medma@users.noreply.github.com> Date: Thu, 13 Aug 2026 18:18:52 +0200 Subject: [PATCH 04/10] Add Ovis to the CCP modules in the bridgehead (#375) This is a squash of 62 commits integrating ovis into the Bridgehead; authors see below. --------- Co-authored-by: janskiba Co-authored-by: Torben Brenner <76154651+torbrenner@users.noreply.github.com> Co-authored-by: Tobias Kussel Co-authored-by: Torben Brenner Co-authored-by: Martin Lablans --- README.md | 14 +++++ ccp/modules/ovis-compose.yml | 102 +++++++++++++++++++++++++++++++++++ ccp/modules/ovis-setup.sh | 12 +++++ versions/acceptance | 1 + versions/prod | 1 + versions/test | 1 + 6 files changed, 131 insertions(+) create mode 100644 ccp/modules/ovis-compose.yml create mode 100644 ccp/modules/ovis-setup.sh diff --git a/README.md b/README.md index 96859e4..50dc802 100644 --- a/README.md +++ b/README.md @@ -457,6 +457,20 @@ If these variables are not set, the Data Quality Agent will still run and genera Reports are accessible at `https:///bbmri-data-quality-agent` (default credentials are admin:admin, please change it after first login!!). [Official documentation](https://fdqf.bbmri-eric.eu/user/deployment.html) + +### OVis (CCP only) + +OVis visualizes your tumor documentation data at `https:///ccp-ovis`. Set in your `ccp.conf`: + +```bash +ENABLE_OVIS=true +OVIS_SUPERADMIN_EMAILS=admin@your-site.de +``` + +Users authenticate centrally with their CCP account (membership in your site's CCP group required), while their permissions are defined inside OVis -- so no duplicate user accounts are needed. The addresses in `OVIS_SUPERADMIN_EMAILS` become super admins and can grant roles to everyone else. + +Data is imported on first start into `/var/cache/bridgehead/ccp/ovis-mongodb`. Deleting that directory also resets all OVis permissions. + ## Things you should know ### Auto-Updates diff --git a/ccp/modules/ovis-compose.yml b/ccp/modules/ovis-compose.yml new file mode 100644 index 0000000..e34e094 --- /dev/null +++ b/ccp/modules/ovis-compose.yml @@ -0,0 +1,102 @@ +services: + ovis-traefik-forward-auth: + container_name: bridgehead-ccp-ovis-forward-auth + image: docker.verbis.dkfz.de/cache/oauth2-proxy/oauth2-proxy:latest + environment: + - http_proxy=http://forward_proxy:3128 + - https_proxy=http://forward_proxy:3128 + - OAUTH2_PROXY_PROVIDER=oidc + - OAUTH2_PROXY_SKIP_PROVIDER_BUTTON=true + - OAUTH2_PROXY_OIDC_ISSUER_URL=${OIDC_PRIVATE_URL} + - OAUTH2_PROXY_CLIENT_ID=${OIDC_PRIVATE_CLIENT_ID} + - OAUTH2_PROXY_CLIENT_SECRET=${OIDC_CLIENT_SECRET} + - OAUTH2_PROXY_COOKIE_SECRET=${OVIS_AUTH_COOKIE_SECRET} + - OAUTH2_PROXY_COOKIE_NAME=_BRIDGEHEAD_oauth2_ovis + - OAUTH2_PROXY_COOKIE_DOMAINS=.${HOST} + - OAUTH2_PROXY_COOKIE_REFRESH=4m + - OAUTH2_PROXY_COOKIE_EXPIRE=24h + - OAUTH2_PROXY_HTTP_ADDRESS=:4180 + - OAUTH2_PROXY_REVERSE_PROXY=true + - OAUTH2_PROXY_WHITELIST_DOMAINS=.${HOST} + - OAUTH2_PROXY_UPSTREAMS=static://202 + - OAUTH2_PROXY_EMAIL_DOMAINS=* + - OAUTH2_PROXY_SCOPE=openid profile email + - OAUTH2_PROXY_SET_AUTHORIZATION_HEADER=true + - OAUTH2_PROXY_SET_XAUTHREQUEST=true + - OAUTH2_PROXY_ALLOWED_GROUPS=${OIDC_USER_GROUP} + - OAUTH2_PROXY_OIDC_GROUPS_CLAIM=${OIDC_GROUP_CLAIM} + - OAUTH2_PROXY_PROXY_PREFIX=/oauth2-ovis + labels: + - "traefik.enable=true" + - "traefik.http.services.ovis-traefik-forward-auth.loadbalancer.server.port=4180" + - "traefik.http.routers.ovis-traefik-forward-auth.rule=Host(`${HOST}`) && PathPrefix(`/oauth2-ovis`)" + - "traefik.http.routers.ovis-traefik-forward-auth.tls=true" + - "traefik.http.middlewares.traefik-forward-auth-ovis.forwardauth.address=http://ovis-traefik-forward-auth:4180" + - "traefik.http.middlewares.traefik-forward-auth-ovis.forwardauth.authResponseHeaders=Authorization,X-Auth-Request-Email,X-Auth-Request-User,X-Auth-Request-Preferred-Username" + depends_on: + forward_proxy: + condition: service_healthy + + ovis-backend-database-mongodb: + image: docker.verbis.dkfz.de/cache/samply/ovis-backend-mongodb:${OVIS_TAG} + container_name: bridgehead-ccp-ovis-mongo + volumes: + - /var/cache/bridgehead/ccp/ovis-mongodb:/data/db + + ovis-backend-mongodb-data-preprocessing: + image: docker.verbis.dkfz.de/cache/samply/ovis-backend-preprocessor:${OVIS_TAG} + container_name: bridgehead-ccp-ovis-preprocessing + environment: + ADDRESS: mongodb://ovis-backend-database-mongodb:27017 + depends_on: + - ovis-backend-database-mongodb + healthcheck: + test: ["CMD", "curl", "-fsS", "http://localhost:9000/health"] + interval: 10s + timeout: 5s + retries: 6 + start_period: 5s + + ovis-backend-data-import: + image: docker.verbis.dkfz.de/cache/samply/ovis-backend-data-import:${OVIS_TAG} + container_name: bridgehead-ccp-ovis-import + depends_on: + ovis-backend-mongodb-data-preprocessing: + condition: service_healthy + environment: + FHIR_SERVER_URL: http://bridgehead-ccp-blaze:8080/fhir + + ovis-backend-apollo: + image: docker.verbis.dkfz.de/cache/samply/ovis-backend-apollo:${OVIS_TAG} + container_name: bridgehead-ccp-ovis-backend + environment: + ADDRESS: mongodb://ovis-backend-database-mongodb:27017 + OVIS_SUPERADMIN_EMAILS: ${OVIS_SUPERADMIN_EMAILS:-} + depends_on: + - ovis-backend-database-mongodb + - ovis-backend-mongodb-data-preprocessing + - ovis-backend-data-import + healthcheck: + test: ["CMD", "curl", "-fsS", "-X", "POST", "-H", "content-type: application/json", "-d", "{\"query\":\"{__typename}\"}", "http://localhost:4001/graphql"] + interval: 10s + timeout: 5s + retries: 5 + # Internal only - no direct Traefik exposure. GraphQL is accessed via frontend internal proxy. + + ovis-frontend: + image: docker.verbis.dkfz.de/cache/samply/ovis-frontend:${OVIS_TAG} + container_name: bridgehead-ccp-ovis-frontend + environment: + ORIGIN: https://${HOST} + depends_on: + ovis-backend-apollo: + condition: service_healthy + labels: + - "traefik.enable=true" + - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.regex=^https?://([^/]+)/ccp-ovis$" + - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.replacement=https://$${1}/ccp-ovis/" + - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.permanent=true" + - "traefik.http.routers.ovis-frontend-ccp.tls=true" + - "traefik.http.routers.ovis-frontend-ccp.rule=PathPrefix(`/ccp-ovis`)" + - "traefik.http.routers.ovis-frontend-ccp.middlewares=traefik-forward-auth-ovis,ovis-frontend-ccp-slash-redirect" + - "traefik.http.services.ovis-frontend-ccp.loadbalancer.server.port=5173" diff --git a/ccp/modules/ovis-setup.sh b/ccp/modules/ovis-setup.sh new file mode 100644 index 0000000..07e1b22 --- /dev/null +++ b/ccp/modules/ovis-setup.sh @@ -0,0 +1,12 @@ +#!/bin/bash -e + +if [ "$ENABLE_OVIS" == true ]; then + log INFO "OVIS setup detected -- will start OVIS services with local oauth2-proxy middleware." + OVERRIDE+=" -f ./$PROJECT/modules/ovis-compose.yml" + add_private_oidc_redirect_url "/oauth2-ovis/callback" + add_private_oidc_redirect_url "/ccp-ovis*" + OVIS_AUTH_COOKIE_SECRET="$(generate_simple_password 'ovisCookieSecret' | head -c 16)" + if [ -z "$OVIS_SUPERADMIN_EMAILS" ]; then + log WARN "OVIS is enabled but OVIS_SUPERADMIN_EMAILS is not set -- nobody will be able to administrate OVIS." + fi +fi diff --git a/versions/acceptance b/versions/acceptance index 648e371..aa9f5d7 100644 --- a/versions/acceptance +++ b/versions/acceptance @@ -5,3 +5,4 @@ POSTGRES_TAG=15.13-alpine TEILER_DASHBOARD_TAG=develop MTBA_TAG=develop DATA_QUALITY_AGENT_TAG=latest +OVIS_TAG=main diff --git a/versions/prod b/versions/prod index a336e12..7026c65 100644 --- a/versions/prod +++ b/versions/prod @@ -5,3 +5,4 @@ POSTGRES_TAG=15.13-alpine TEILER_DASHBOARD_TAG=main MTBA_TAG=main DATA_QUALITY_AGENT_TAG=0.1 +OVIS_TAG=main diff --git a/versions/test b/versions/test index 648e371..aa9f5d7 100644 --- a/versions/test +++ b/versions/test @@ -5,3 +5,4 @@ POSTGRES_TAG=15.13-alpine TEILER_DASHBOARD_TAG=develop MTBA_TAG=develop DATA_QUALITY_AGENT_TAG=latest +OVIS_TAG=main From 172b5544ef0f38330943e11672279d5fc3a79ba8 Mon Sep 17 00:00:00 2001 From: Jan <59206115+Threated@users.noreply.github.com> Date: Mon, 17 Aug 2026 09:34:43 +0200 Subject: [PATCH 05/10] itcc: add omics ui (#396) --- itcc/modules/itcc-omics-ingest.yaml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/itcc/modules/itcc-omics-ingest.yaml b/itcc/modules/itcc-omics-ingest.yaml index 74ae527..fbb88a1 100644 --- a/itcc/modules/itcc-omics-ingest.yaml +++ b/itcc/modules/itcc-omics-ingest.yaml @@ -1,22 +1,37 @@ services: omics-endpoint: - image: samply/itcc-omics-ingest:main + image: samply/itcc-omics-ingest:develop environment: API_KEY: ${GENERATE_API_KEY} + API_PORT: "6080" BEAM_APP_ID_LONG: omics-endpoint.${PROXY_ID} BEAM_SECRET: ${FOCUS_BEAM_SECRET_SHORT} + BEAM_URL: http://beam-proxy:8081 + BLAZE_URL: http://bridgehead-itcc-blaze:8080/fhir/ + BOX_ROOT: /var/lib/itcc-maf-box DWH_SOCKET_ID: ${DWH_SOCKET_ID} DWH_TASK_ID: ${DWH_TASK_ID} - PARTNER_ID: ${SITE_ID} + SITE_ID: ${SITE_ID} ML_API_KEY: ${GENERATE_API_KEY} + ML_URL: http://bridgehead-patientlist:8080 + UI_PORT: "3000" + volumes: + - "omics-maf-box:/var/lib/itcc-maf-box" labels: - "traefik.http.routers.omics.rule=Host(`${HOST}`) && PathPrefix(`/api/upload`)" - "traefik.enable=true" - "traefik.http.services.omics.loadbalancer.server.port=6080" + - "traefik.http.routers.omics.service=omics" - "traefik.http.routers.omics.tls=true" - "traefik.http.middlewares.omics-stripprefix.stripprefix.prefixes=/api" - "traefik.http.routers.omics.middlewares=omics-stripprefix" + - "traefik.http.routers.itcc-uploader.rule=Host(`${HOST}`) && PathPrefix(`/itcc-uploader`)" + - "traefik.http.routers.itcc-uploader.service=itcc-uploader" + - "traefik.http.routers.itcc-uploader.tls=true" + - "traefik.http.services.itcc-uploader.loadbalancer.server.port=3000" + - "traefik.http.middlewares.itcc-uploader-stripprefix.stripprefix.prefixes=/itcc-uploader" + - "traefik.http.routers.itcc-uploader.middlewares=auth,itcc-uploader-stripprefix" patientlist-db: image: postgres:${POSTGRES_TAG} @@ -60,6 +75,7 @@ services: target: /etc/resources/keys/symmetric_key.json volumes: + omics-maf-box: patientlist-db-data: secrets: mainzelliste.docker.conf: From 625ce6eebf05461be4de17f8651e341c1f550b74 Mon Sep 17 00:00:00 2001 From: tm16-medma <142219207+tm16-medma@users.noreply.github.com> Date: Fri, 25 Sep 2026 13:55:43 +0200 Subject: [PATCH 06/10] Escape OVIS redirect regex for Compose compatibility (#398) --- ccp/modules/ovis-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ccp/modules/ovis-compose.yml b/ccp/modules/ovis-compose.yml index e34e094..ac1e97a 100644 --- a/ccp/modules/ovis-compose.yml +++ b/ccp/modules/ovis-compose.yml @@ -93,7 +93,7 @@ services: condition: service_healthy labels: - "traefik.enable=true" - - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.regex=^https?://([^/]+)/ccp-ovis$" + - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.regex=^https?://([^/]+)/ccp-ovis$$" - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.replacement=https://$${1}/ccp-ovis/" - "traefik.http.middlewares.ovis-frontend-ccp-slash-redirect.redirectregex.permanent=true" - "traefik.http.routers.ovis-frontend-ccp.tls=true" From 59a9fd688e99724c640643a570ea776ddff64923 Mon Sep 17 00:00:00 2001 From: tm16-medma <142219207+tm16-medma@users.noreply.github.com> Date: Fri, 25 Sep 2026 13:56:03 +0200 Subject: [PATCH 07/10] Add internal Cox service to OVIS module (#399) --- ccp/modules/ovis-compose.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ccp/modules/ovis-compose.yml b/ccp/modules/ovis-compose.yml index ac1e97a..b9ee4b7 100644 --- a/ccp/modules/ovis-compose.yml +++ b/ccp/modules/ovis-compose.yml @@ -66,6 +66,10 @@ services: environment: FHIR_SERVER_URL: http://bridgehead-ccp-blaze:8080/fhir + ovis-backend-cox: + image: samply/ovis-backend-cox:${OVIS_TAG} + container_name: bridgehead-ccp-ovis-cox + ovis-backend-apollo: image: docker.verbis.dkfz.de/cache/samply/ovis-backend-apollo:${OVIS_TAG} container_name: bridgehead-ccp-ovis-backend @@ -76,6 +80,7 @@ services: - ovis-backend-database-mongodb - ovis-backend-mongodb-data-preprocessing - ovis-backend-data-import + - ovis-backend-cox healthcheck: test: ["CMD", "curl", "-fsS", "-X", "POST", "-H", "content-type: application/json", "-d", "{\"query\":\"{__typename}\"}", "http://localhost:4001/graphql"] interval: 10s From 00192eaefc9219c8f03fbf0a08efbeb5cfc5735d Mon Sep 17 00:00:00 2001 From: Pierre Delpy <75260699+PierreDelpy@users.noreply.github.com> Date: Thu, 8 Oct 2026 14:16:00 +0200 Subject: [PATCH 08/10] Secret Sync for the config repo token, one-time enrollment code, check output (#401) * cce: Fetch the config repository token via Secret Sync * Keep the Secret Sync GitLab token across reboots and outages * Install site configuration with a one-time enrollment code * Align the itcc and dhki cases in prepare-system.sh * Report an unreachable broker instead of a clock skew during install * Show bridgehead check results as OK, WARN or CRIT and run them during install * Refresh the config repo token before bridgehead check fetches * Skip Secret Sync until the private key and root certificate exist * Indent the case block in prepare-system.sh with tabs only * Hide the config repo URL, token and enrollment code from other local users * remove the unreachable second dhki case --------- Co-authored-by: Martin Lablans --- README.md | 33 +++----- bridgehead | 6 ++ lib/check-bridgehead.sh | 159 ++++++++++++++++++++---------------- lib/functions.sh | 163 ++++++++++++++++++++++++++++--------- lib/gitlab-token-helper.sh | 4 +- lib/install-bridgehead.sh | 10 +++ lib/prepare-system.sh | 55 +++++++++---- lib/prerequisites.sh | 1 + 8 files changed, 287 insertions(+), 144 deletions(-) diff --git a/README.md b/README.md index 50dc802..21ce84c 100644 --- a/README.md +++ b/README.md @@ -130,25 +130,29 @@ Mention: - site name (According to conventions listed above) - operator name and email -We will set the repository up for you. We will then send you: +We will set the repository up for you. We will then send you either: -- A Repository Short Name (RSN). Beware: this is distinct from your site name. -- Repository URL containing the acces token eg. https://BH_Dummy:dummy_token@git.verbis.dkfz.de/-bridgehead-configs/dummy.git +- Way A: a one-time enrollment code, or +- Way B: a repository URL including access credentials. During the installation, your Bridgehead will download your site's configuration from GitLab and you can review the details provided to us by email. ### Base Installation -First, download your site specific configuration repository: +Clone the bridgehead repository and run the installation script: ```shell -sudo mkdir -p /etc/bridgehead/ -sudo git clone /etc/bridgehead/ +sudo mkdir -p /srv/docker/ +sudo git clone -b main https://github.com/samply/bridgehead.git /srv/docker/bridgehead +cd /srv/docker/bridgehead +sudo ./bridgehead install ``` +When asked, choose Way A or Way B. For Way A, enter your one-time enrollment code and your site name; for Way B, enter your repository URL. The installation downloads your site configuration to `/etc/bridgehead`. If your server needs an HTTP proxy to reach the internet, pass it to the script, e.g. `sudo https_proxy=http://proxy.example.org:3128 ./bridgehead install `. + Review the site configuration: ```shell -sudo cat /etc/bridgehead/bbmri.conf +sudo cat /etc/bridgehead/.conf ``` Pay special attention to: @@ -159,21 +163,10 @@ Pay special attention to: - OPERATOR_LAST_NAME - OPERATOR_EMAIL -Clone the bridgehead repository: -```shell -sudo mkdir -p /srv/docker/ -sudo git clone -b main https://github.com/samply/bridgehead.git /srv/docker/bridgehead -``` - -Then, run the installation script: - -```shell -cd /srv/docker/bridgehead -sudo ./bridgehead install -``` - ### Register with Samply.Beam +If you installed with Way A, this has already been done for you; skip to the next step. + Many Bridgehead services rely on the secure, performant and flexible messaging middleware called [Samply.Beam](https://github.com/samply/beam). You will need to register ("enroll") with Samply.Beam by creating a cryptographic key pair for your bridgehead: ``` shell diff --git a/bridgehead b/bridgehead index 09b46f5..db0afa9 100755 --- a/bridgehead +++ b/bridgehead @@ -153,7 +153,13 @@ case "$ACTION" in exec ./lib/update-bridgehead.sh $PROJECT ;; check) + # Ignore the caller's environment, e.g. proxy variables, like bridgehead@.service does + if [ "$(id -u)" -eq 0 ]; then + exec systemd-run --wait --pipe --quiet --collect -p User=bridgehead -p WorkingDirectory="$BASE" "$BASE/bridgehead" check $PROJECT + fi + trap 'log "ERROR" "Unable to load the configuration of $PROJECT"; exit 3' EXIT loadVars &> /dev/null + trap - EXIT exec ./lib/check-bridgehead.sh $PROJECT ;; install) diff --git a/lib/check-bridgehead.sh b/lib/check-bridgehead.sh index 57ca537..ea6bba6 100755 --- a/lib/check-bridgehead.sh +++ b/lib/check-bridgehead.sh @@ -1,74 +1,95 @@ #!/bin/bash source lib/functions.sh -log INFO "Running Bridgehead checks..." - -# Directory ownership -log INFO "Checking directory ownership..." -OWNERSHIP_OK=true -if ! checkOwner /srv/docker/bridgehead bridgehead &> /dev/null; then - log ERROR "Wrong ownership for /srv/docker/bridgehead." - log INFO "Hint: Run 'sudo chown -R bridgehead /srv/docker/bridgehead'." - OWNERSHIP_OK=false -fi -if ! checkOwner /etc/bridgehead bridgehead &> /dev/null; then - log ERROR "Wrong ownership for /etc/bridgehead." - log INFO "Hint: Run 'sudo chown -R bridgehead /etc/bridgehead'." - OWNERSHIP_OK=false -fi - -if [ "$OWNERSHIP_OK" = true ]; then - log INFO "Directory ownership is correct." -fi - -# Git repository status -log INFO "Checking Git repository status..." -GIT_OK=true -if [ -d "/etc/bridgehead/.git" ]; then - if [ -n "$(git -C "/etc/bridgehead" status --porcelain)" ]; then - log ERROR "The config repo at /etc/bridgehead is modified.\n$(git -C /etc/bridgehead status -s)" - log INFO "Hint: Review your changes with git diff if they are already upstreamed use git stash and git pull to update the repo" - GIT_OK=false - fi -fi -if [ -n "$(git -C "$(pwd)" status --porcelain)" ]; then - log ERROR "$(pwd) is modified. \n$(git -C "$(pwd)" status -s)" - log INFO "Hint: If these are site specific changes to docker compose files consider moving them to $PROJECT/docker-compose.override.yml which is ignored by git." - log INFO " If they are already upstreamed use git stash and git pull to update the repo" - GIT_OK=false -fi - -if [ "$GIT_OK" = true ]; then - log INFO "Git repositories are clean." -fi - -# Git remote connection -log INFO "Checking Git remote connection..." -GIT_REMOTE_OK=true -if [ -d "/etc/bridgehead/.git" ]; then - if ! git -C "/etc/bridgehead" fetch --dry-run >/dev/null 2>&1; then - log ERROR "Cannot connect to the Git remote for /etc/bridgehead." - log INFO "Hint: Check your network connection and Git remote configuration for /etc/bridgehead." - GIT_REMOTE_OK=false - fi -fi -if [ -d "$(pwd)/.git" ]; then - if ! git -C "$(pwd)" fetch --dry-run >/dev/null 2>&1; then - log ERROR "Cannot connect to the Git remote for $(pwd)." - log INFO "Hint: Check your network connection and Git remote configuration for $(pwd)." - GIT_REMOTE_OK=false - fi -fi - -if [ "$GIT_REMOTE_OK" = true ]; then - log INFO "Git remote connection successful." -fi - -if [ "$OWNERSHIP_OK" = true ] && [ "$GIT_OK" = true ] && [ "$GIT_REMOTE_OK" = true ]; then - log INFO "All checks passed." - exit 0 +if [ -t 1 ]; then + GREEN=$(printf '\033[32m') + YELLOW=$(printf '\033[33m') + RED=$(printf '\033[31m') + RESET=$(printf '\033[0m') else - log ERROR "Some checks failed. Please review the hints and fix the issues." - log ERROR "Without fixing these issues bridgehead updates may not work correctly." - exit 1 + GREEN="" + YELLOW="" + RED="" + RESET="" fi + +WORST=0 + +report() { + local status=$1 message=$2 color level label + shift 2 + case "$status" in + OK) color=$GREEN; level=0; label=" OK " ;; + WARN) color=$YELLOW; level=1; label="WARN" ;; + *) color=$RED; level=2; label="CRIT" ;; + esac + printf '[%s%s%s] %s\n' "$color" "$label" "$RESET" "$message" + local hint + for hint in "$@"; do + printf '%s\n' "$hint" | sed 's/^/ /' + done + if [ $level -gt $WORST ]; then + WORST=$level + fi +} + +GIT_PROXY_ARGS=() +if [ -n "$HTTPS_PROXY_FULL_URL" ]; then + GIT_PROXY_ARGS=(-c http.proxy=$HTTPS_PROXY_FULL_URL -c https.proxy=$HTTPS_PROXY_FULL_URL) +fi + +echo "Running Bridgehead checks for project $PROJECT ..." + +if [ -n "$BROKER_URL_FOR_PREREQ" ]; then + if https_proxy=$HTTPS_PROXY_FULL_URL curl -m 10 -sS -o /dev/null "$BROKER_URL_FOR_PREREQ" 2>/dev/null; then + report OK "Network connection to $BROKER_URL_FOR_PREREQ" + else + report CRIT "Cannot connect to $BROKER_URL_FOR_PREREQ with the configured proxy \"$HTTPS_PROXY_URL\"" \ + "Hint: If your server needs a proxy, HTTPS_PROXY_URL (and, if required, HTTPS_PROXY_USERNAME and HTTPS_PROXY_PASSWORD) must be set in /etc/bridgehead/$PROJECT.conf. Please ask ${SUPPORT_EMAIL:-the support team of your project} to add it to your site configuration." + fi +fi + +for DIR in /srv/docker/bridgehead /etc/bridgehead; do + if checkOwner $DIR bridgehead &> /dev/null; then + report OK "Ownership of $DIR" + else + report CRIT "Wrong ownership for $DIR" "Hint: Run 'sudo chown -R bridgehead $DIR'." + fi +done + +if [ -d "/etc/bridgehead/.git" ]; then + if [ -z "$(git -C "/etc/bridgehead" status --porcelain)" ]; then + report OK "The config repo at /etc/bridgehead is clean" + else + report WARN "The config repo at /etc/bridgehead is modified:" \ + "$(git -C /etc/bridgehead status -s)" \ + "Hint: Review your changes with git diff if they are already upstreamed use git stash and git pull to update the repo" + fi +fi +if [ -z "$(git -C "$(pwd)" status --porcelain)" ]; then + report OK "$(pwd) is clean" +else + report WARN "$(pwd) is modified:" \ + "$(git -C "$(pwd)" status -s)" \ + "Hint: If these are site specific changes to docker compose files consider moving them to $PROJECT/docker-compose.override.yml which is ignored by git." \ + " If they are already upstreamed use git stash and git pull to update the repo" +fi + +secret_sync_gitlab_token &> /dev/null + +for DIR in /etc/bridgehead "$(pwd)"; do + if [ -d "$DIR/.git" ]; then + if git "${GIT_PROXY_ARGS[@]}" -C "$DIR" fetch --dry-run >/dev/null 2>&1; then + report OK "Git remote connection for $DIR" + else + report CRIT "Cannot connect to the Git remote for $DIR" "Hint: Check your network connection and Git remote configuration for $DIR." + fi + fi +done + +case $WORST in + 0) echo "All checks passed." ;; + 1) echo "Some checks reported warnings. Please review the hints." ;; + *) echo "Some checks failed. Please review the hints and fix the issues. Without fixing these issues bridgehead updates may not work correctly." ;; +esac +exit $WORST diff --git a/lib/functions.sh b/lib/functions.sh index 3a5cfe4..d10a2e8 100644 --- a/lib/functions.sh +++ b/lib/functions.sh @@ -336,21 +336,57 @@ function sync_secrets() { set +a # Export variables in the regular way } +# Map a GitLab URL to the prefix recognized by Secret Sync +function secret_sync_gitlab_instance() { + case "$1" in + *git.verbis.dkfz.de*) echo verbis;; + *gitlab.bbmri-eric.eu*) echo bbmri;; + *) return 1;; + esac +} + +# Use Secret Sync to validate the GitLab token in /var/cache/bridgehead/secrets/gitlab-token. +# If it is missing or expired, Secret Sync will create a new token and write it to the file. +# The git credential helper reads the token from the file during git pull. +function secret_sync_fetch_gitlab_token() { + local gitlab=$1 proxy_id=$2 broker_url=$3 broker_id=$4 privkey_file=$5 root_crt_file=$6 + if [ ! -f "$privkey_file" ] || [ ! -f "$root_crt_file" ]; then + log "WARN" "Not running Secret Sync because $privkey_file or $root_crt_file is missing" + return 1 + fi + local trusted_ca_args=() + if [ -d /etc/bridgehead/trusted-ca-certs ]; then + trusted_ca_args=(-v /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro -e TLS_CA_CERTIFICATES_DIR=/conf/trusted-ca-certs) + fi + mkdir -p /var/cache/bridgehead/secrets + chmod 700 /var/cache/bridgehead/secrets + log "INFO" "Running Secret Sync for the GitLab token (gitlab=$gitlab)" + docker pull docker.verbis.dkfz.de/cache/samply/secret-sync-local:latest # make sure we have the latest image + docker run --rm \ + -v $privkey_file:/run/secrets/privkey.pem:ro \ + -v $root_crt_file:/run/secrets/root.crt.pem:ro \ + "${trusted_ca_args[@]}" \ + -v /var/cache/bridgehead/secrets:/secret-sync/ \ + -e CACHE_PATH=/secret-sync/gitlab-token \ + -e NO_PROXY=localhost,127.0.0.1 \ + -e ALL_PROXY=$HTTPS_PROXY_FULL_URL \ + -e PROXY_ID=$proxy_id \ + -e BROKER_URL=$broker_url \ + -e GITLAB_PROJECT_ACCESS_TOKEN_PROVIDER=secret-sync-central.central-secret-sync.$broker_id \ + -e SECRET_DEFINITIONS=GitLabProjectAccessToken:BRIDGEHEAD_CONFIG_REPO_TOKEN:$gitlab \ + docker.verbis.dkfz.de/cache/samply/secret-sync-local:latest +} + function secret_sync_gitlab_token() { - if [[ "$PROJECT" != "ccp" && "$PROJECT" != "bbmri" ]]; then - log "INFO" "Not running Secret Sync for project minimal" + if [[ "$PROJECT" != "ccp" && "$PROJECT" != "bbmri" && "$PROJECT" != "cce" ]] && [ -z "$(git -C /etc/bridgehead config credential.helper)" ]; then + log "INFO" "Not running Secret Sync for project $PROJECT" return fi - # Map the origin of the git repository /etc/bridgehead to the prefix recognized by Secret Sync local gitlab - case "$(git -C /etc/bridgehead remote get-url origin)" in - *git.verbis.dkfz.de*) gitlab=verbis;; - *gitlab.bbmri-eric.eu*) gitlab=bbmri;; - *) - log "WARN" "Not running Secret Sync because the git repository /etc/bridgehead has unknown origin" - return - ;; - esac + if ! gitlab=$(secret_sync_gitlab_instance "$(git -C /etc/bridgehead remote get-url origin)"); then + log "WARN" "Not running Secret Sync because the git repository /etc/bridgehead has unknown origin" + return + fi if [ "$PROJECT" == "bbmri" ]; then # If the project is BBMRI, use the BBMRI-ERIC broker and not the GBN broker @@ -365,30 +401,7 @@ function secret_sync_gitlab_token() { root_crt_file="/srv/docker/bridgehead/$PROJECT/root.crt.pem" fi - # Create a temporary directory for Secret Sync that is valid per boot - secret_sync_tempdir="/tmp/bridgehead/secret-sync.boot-$(cat /proc/sys/kernel/random/boot_id)" - mkdir -p $secret_sync_tempdir - - # Use Secret Sync to validate the GitLab token in $secret_sync_tempdir/cache. - # If it is missing or expired, Secret Sync will create a new token and write it to the file. - # The git credential helper reads the token from the file during git pull. - log "INFO" "Running Secret Sync for the GitLab token (gitlab=$gitlab)" - docker pull docker.verbis.dkfz.de/cache/samply/secret-sync-local:latest # make sure we have the latest image - docker run --rm \ - -v $PRIVATEKEYFILENAME:/run/secrets/privkey.pem:ro \ - -v $root_crt_file:/run/secrets/root.crt.pem:ro \ - -v /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro \ - -v $secret_sync_tempdir:/secret-sync/ \ - -e CACHE_PATH=/secret-sync/gitlab-token \ - -e TLS_CA_CERTIFICATES_DIR=/conf/trusted-ca-certs \ - -e NO_PROXY=localhost,127.0.0.1 \ - -e ALL_PROXY=$HTTPS_PROXY_FULL_URL \ - -e PROXY_ID=$proxy_id \ - -e BROKER_URL=$broker_url \ - -e GITLAB_PROJECT_ACCESS_TOKEN_PROVIDER=secret-sync-central.central-secret-sync.$broker_id \ - -e SECRET_DEFINITIONS=GitLabProjectAccessToken:BRIDGEHEAD_CONFIG_REPO_TOKEN:$gitlab \ - docker.verbis.dkfz.de/cache/samply/secret-sync-local:latest - if [ $? -eq 0 ]; then + if secret_sync_fetch_gitlab_token "$gitlab" "$proxy_id" "$broker_url" "$broker_id" "$PRIVATEKEYFILENAME" "$root_crt_file"; then log "INFO" "Secret Sync was successful" # In the past we used to hardcode tokens into the repository URL. We have to remove those now for the git credential helper to become effective. CLEAN_REPO="$(git -C /etc/bridgehead remote get-url origin | sed -E 's|https://[^@]+@|https://|')" @@ -397,8 +410,6 @@ function secret_sync_gitlab_token() { git -C /etc/bridgehead config credential.helper /srv/docker/bridgehead/lib/gitlab-token-helper.sh else log "WARN" "Secret Sync failed" - # Remove the git credential helper - git -C /etc/bridgehead config --unset credential.helper fi # In the past the git credential helper was also set for /srv/docker/bridgehead but never used. @@ -407,6 +418,84 @@ function secret_sync_gitlab_token() { git -C /srv/docker/bridgehead config --unset credential.helper } +function bootstrap_site_configuration() { + local site=$1 enrollment_code=$2 repository_url=$3 + local SITE_ID=$site BROKER_ID="" BROKER_URL="" PROXY_ID="" PRIVATEKEYFILENAME="" + local HTTPS_PROXY_FULL_URL=${HTTPS_PROXY_FULL_URL:-${https_proxy:-${HTTPS_PROXY:-}}} + eval "$(grep -E '^(BROKER_ID|BROKER_URL|PROXY_ID|PRIVATEKEYFILENAME)=' "$PROJECT/vars")" + if [ -z "$BROKER_ID" ]; then + log "ERROR" "Project $PROJECT has no Samply.Beam broker to enroll with." + return 1 + fi + local gitlab + if ! gitlab=$(secret_sync_gitlab_instance "$repository_url"); then + log "ERROR" "Secret Sync does not support the GitLab server of $repository_url." + return 1 + fi + + local enroll_dir + enroll_dir=$(mktemp -d /run/bridgehead-enrollment.XXXXXX) + local key_file="$enroll_dir/$SITE_ID.priv.pem" + log "INFO" "Enrolling Beam Proxy Id $PROXY_ID" + if ! docker run --rm -v "$enroll_dir:/pki" docker.verbis.dkfz.de/cache/samply/beam-enroll:latest --output-file "/pki/$SITE_ID.priv.pem" --proxy-id "$PROXY_ID" > "$enroll_dir/enroll.out"; then + log "ERROR" "Unable to generate the private key for $PROXY_ID." + rm -rf "$enroll_dir" + return 1 + fi + local csr + csr=$(sed -n '/BEGIN CERTIFICATE REQUEST/,/END CERTIFICATE REQUEST/p' "$enroll_dir/enroll.out") + printf '%s' "$enrollment_code" > "$enroll_dir/enrollment-code" + local response + response=$(curl -sS --data-urlencode "csr=$csr" --data-urlencode "token@$enroll_dir/enrollment-code" "$BROKER_URL/csr" 2>&1) + if [[ "$response" != *"Successfully registered CSR"* ]]; then + log "ERROR" "$BROKER_URL did not accept the certificate request with your one-time enrollment code: $(echo "$response" | sed -e 's/<[^>]*>//g' | tr -s '[:space:]' ' ' | head -c 300)" + rm -rf "$enroll_dir" + return 1 + fi + + local answer + until retry 3 secret_sync_fetch_gitlab_token "$gitlab" "$PROXY_ID" "$BROKER_URL" "$BROKER_ID" "$key_file" "/srv/docker/bridgehead/$PROJECT/root.crt.pem" \ + && git -c credential.helper=/srv/docker/bridgehead/lib/gitlab-token-helper.sh clone "$repository_url" /etc/bridgehead; do + log "ERROR" "Unable to download $repository_url." + read -r -p "Fix the cause and retry? If you don't, you will need a new one-time enrollment code. [Y/n] " answer || answer=n + if [[ "$answer" == [Nn]* ]]; then + rm -rf "$enroll_dir" + return 1 + fi + done + local configured_site_id + configured_site_id=$(grep -m1 -E '^SITE_ID=' "/etc/bridgehead/$PROJECT.conf" | cut -d= -f2- | tr -d "\"'") + if [ "$configured_site_id" != "$SITE_ID" ]; then + log "ERROR" "Your configuration repository is for site '$configured_site_id', but you entered '$SITE_ID'. Ask for a one-time enrollment code for '$configured_site_id' and run the installation again." + rm -rf /etc/bridgehead "$enroll_dir" + return 1 + fi + git -C /etc/bridgehead config credential.helper /srv/docker/bridgehead/lib/gitlab-token-helper.sh + mkdir -p "$(dirname "$PRIVATEKEYFILENAME")" + mv "$key_file" "$PRIVATEKEYFILENAME" + chmod 600 "$PRIVATEKEYFILENAME" + rm -rf "$enroll_dir" +} + +function read_masked() { + local prompt=$1 char value="" + local -n read_masked_result=$2 + printf '%s' "$prompt" + while IFS= read -r -s -n1 char && [ -n "$char" ]; do + if [[ "$char" == $'\x7f' || "$char" == $'\b' ]]; then + if [ -n "$value" ]; then + value=${value%?} + printf '\b \b' + fi + else + value+=$char + printf '*' + fi + done + echo + read_masked_result=$value +} + capitalize_first_letter() { input="$1" capitalized="$(tr '[:lower:]' '[:upper:]' <<< ${input:0:1})${input:1}" diff --git a/lib/gitlab-token-helper.sh b/lib/gitlab-token-helper.sh index 1aa7a62..23680d4 100755 --- a/lib/gitlab-token-helper.sh +++ b/lib/gitlab-token-helper.sh @@ -2,10 +2,10 @@ [ "$1" = "get" ] || exit -source "/tmp/bridgehead/secret-sync.boot-$(cat /proc/sys/kernel/random/boot_id)/gitlab-token" +source /var/cache/bridgehead/secrets/gitlab-token # Any non-empty username works, only the token matters cat << EOF username=bk password=$BRIDGEHEAD_CONFIG_REPO_TOKEN -EOF \ No newline at end of file +EOF diff --git a/lib/install-bridgehead.sh b/lib/install-bridgehead.sh index 2e2ec69..7651f94 100755 --- a/lib/install-bridgehead.sh +++ b/lib/install-bridgehead.sh @@ -63,6 +63,16 @@ cp -v \ systemctl daemon-reload +fixPermissions + +log "INFO" "Checking your bridgehead ..." +CHECK_RESULT=0 +/srv/docker/bridgehead/bridgehead check "${PROJECT}" || CHECK_RESULT=$? +if [ $CHECK_RESULT -ge 2 ]; then + log "ERROR" "Some checks failed. Fix them and run the installation again." + exit 1 +fi + log INFO "Trying to update your bridgehead ..." systemctl start bridgehead-update@"${PROJECT}".service diff --git a/lib/prepare-system.sh b/lib/prepare-system.sh index 6ff4eb7..19eb7e0 100755 --- a/lib/prepare-system.sh +++ b/lib/prepare-system.sh @@ -60,16 +60,13 @@ case "$PROJECT" in ;; itcc) site_configuration_repository_middle="git.verbis.dkfz.de/itcc-sites/" - ;; - dhki) - site_configuration_repository_middle="git.verbis.dkfz.de/dhki/" - ;; - kr) - site_configuration_repository_middle="git.verbis.dkfz.de/krebsregister-sites/" ;; dhki) site_configuration_repository_middle="git.verbis.dkfz.de/dhki/" ;; + kr) + site_configuration_repository_middle="git.verbis.dkfz.de/krebsregister-sites/" + ;; nngm) site_configuration_repository_middle="git.verbis.dkfz.de/nngm/" ;; @@ -78,7 +75,7 @@ case "$PROJECT" in ;; *) log ERROR "Internal error, this should not happen." - exit 1 + exit 1 ;; esac @@ -92,16 +89,42 @@ if [ -d /etc/bridgehead ]; then fi elif [[ "$DEV_MODE" == "NODEV" ]]; then log "INFO" "Now cloning your site configuration repository for you." - if [ -z "$site" ]; then - read -p "Please enter your site: " site + if [ -z "$access_token" ] && [ -z "$enrollment_code" ]; then + echo "Way A: You received a one-time enrollment code." + echo "Way B: You received a repository URL including access credentials." + read -p "Please choose your way of installation [A/B]: " way + case "$way" in + [Aa]) + read -p "Please enter your one-time enrollment code: " enrollment_code + ;; + [Bb]) + read_masked "Please enter your repository URL: " site_configuration_repository_url + ;; + *) + log "ERROR" "Please choose A or B." + exit 1 + ;; + esac fi - if [ -z "$access_token" ]; then - read -s -p "Please enter the bridgehead's access token for your site configuration repository (will not be echoed): " access_token + if [ -z "$site_configuration_repository_url" ]; then + if [ -z "$site" ]; then + read -p "Please enter your site: " site + fi + site=$(echo $site | tr '[:upper:]' '[:lower:]') fi - site_configuration_repository_url="https://bytoken:${access_token}@${site_configuration_repository_middle}$(echo $site | tr '[:upper:]' '[:lower:]').git" - git clone $site_configuration_repository_url /etc/bridgehead - if [ $? -gt 0 ]; then - log "ERROR" "Unable to clone your configuration repository. Please obtain correct access data and try again." + if [ -z "$access_token" ] && [ -n "$enrollment_code" ]; then + if ! bootstrap_site_configuration "$site" "$enrollment_code" "https://${site_configuration_repository_middle}${site}.git"; then + log "ERROR" "Unable to set up your configuration repository with your one-time enrollment code (Way A)." + exit 1 + fi + else + if [ -n "$access_token" ]; then + site_configuration_repository_url="https://bytoken:${access_token}@${site_configuration_repository_middle}${site}.git" + fi + git clone $site_configuration_repository_url /etc/bridgehead + if [ $? -gt 0 ]; then + log "ERROR" "Unable to clone your configuration repository. Please obtain correct access data and try again." + fi fi elif [[ "$DEV_MODE" == "DEV" ]]; then log "INFO" "Now cloning your developer configuration repository for you." @@ -109,7 +132,7 @@ elif [[ "$DEV_MODE" == "DEV" ]]; then git clone "$url" /etc/bridgehead fi -chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead +fixPermissions mkdir -p /tmp/bridgehead /var/cache/bridgehead chown -R bridgehead:docker /tmp/bridgehead /var/cache/bridgehead chmod -R g+wr /var/cache/bridgehead /tmp/bridgehead diff --git a/lib/prerequisites.sh b/lib/prerequisites.sh index 2c1e186..9049f4a 100755 --- a/lib/prerequisites.sh +++ b/lib/prerequisites.sh @@ -72,6 +72,7 @@ source ${PROJECT}/vars if [ "${PROJECT}" != "minimal" ]; then set +e SERVERTIME="$(https_proxy=$HTTPS_PROXY_FULL_URL curl -m 5 -s -I $BROKER_URL_FOR_PREREQ 2>&1 | grep -i -e '^Date: ' | sed -e 's/^Date: //i')" + [ -n "$SERVERTIME" ] RET=$? set -e if [ $RET -ne 0 ]; then From 12e036753e345b8843011e4c76ce7a9c9a25407c Mon Sep 17 00:00:00 2001 From: Tobias Kussel Date: Tue, 20 Oct 2026 09:22:29 +0200 Subject: [PATCH 09/10] Explicitly set bridgehead UID:GID for data quality tool (#406) --- bbmri/modules/data-quality-agent-compose.yml | 1 + bbmri/modules/data-quality-agent-setup.sh | 2 ++ 2 files changed, 3 insertions(+) diff --git a/bbmri/modules/data-quality-agent-compose.yml b/bbmri/modules/data-quality-agent-compose.yml index 272f982..17787fb 100644 --- a/bbmri/modules/data-quality-agent-compose.yml +++ b/bbmri/modules/data-quality-agent-compose.yml @@ -4,6 +4,7 @@ services: data-quality-agent: image: ghcr.io/bbmri-cz/data-quality-agent:${DATA_QUALITY_AGENT_TAG} container_name: bridgehead-bbmri-data-quality-agent + user: "${BRIDGEHEAD_UID}:${BRIDGEHEAD_GID}" environment: APP_SETTING_FHIR_URL: http://bridgehead-bbmri-blaze:8080/fhir REPORTING_SERVER_URL: ${DATA_QUALITY_SERVER_URL} diff --git a/bbmri/modules/data-quality-agent-setup.sh b/bbmri/modules/data-quality-agent-setup.sh index f0a0e84..f12693e 100644 --- a/bbmri/modules/data-quality-agent-setup.sh +++ b/bbmri/modules/data-quality-agent-setup.sh @@ -2,6 +2,8 @@ if [ "$ENABLE_DATA_QUALITY_AGENT" == "true" ]; then log INFO "Data Quality Agent setup detected -- will start data-quality-agent service." + export BRIDGEHEAD_UID="$(id -u bridgehead)" + export BRIDGEHEAD_GID="$(id -g bridgehead)" OVERRIDE+=" -f ./$PROJECT/modules/data-quality-agent-compose.yml" fi From 0a4ee3d6a65506c023f836d3dd0b817aaa4abc64 Mon Sep 17 00:00:00 2001 From: Manoj Waikar Date: Wed, 21 Oct 2026 15:33:17 +0200 Subject: [PATCH 10/10] cce: enroll against broker.cce.dkfz.de (#400) cce: add dev and production setup --- cce/docker-compose.yml | 2 +- cce/root.crt.pem | 38 +++++++++++++++++++------------------- cce/test.root.crt.pem | 20 ++++++++++++++++++++ cce/vars | 7 ++++++- 4 files changed, 46 insertions(+), 21 deletions(-) create mode 100644 cce/test.root.crt.pem diff --git a/cce/docker-compose.yml b/cce/docker-compose.yml index 99039e7..b996738 100644 --- a/cce/docker-compose.yml +++ b/cce/docker-compose.yml @@ -57,7 +57,7 @@ services: - "forward_proxy" volumes: - /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro - - /srv/docker/bridgehead/cce/root.crt.pem:/conf/root.crt.pem:ro + - ${ROOT_CRT_FILE}:/conf/root.crt.pem:ro volumes: diff --git a/cce/root.crt.pem b/cce/root.crt.pem index 1f1265a..20fd13c 100644 --- a/cce/root.crt.pem +++ b/cce/root.crt.pem @@ -1,20 +1,20 @@ -----BEGIN CERTIFICATE----- -MIIDNTCCAh2gAwIBAgIUW34NEb7bl0+Ywx+I1VKtY5vpAOowDQYJKoZIhvcNAQEL -BQAwFjEUMBIGA1UEAxMLQnJva2VyLVJvb3QwHhcNMjQwMTIyMTMzNzEzWhcNMzQw -MTE5MTMzNzQzWjAWMRQwEgYDVQQDEwtCcm9rZXItUm9vdDCCASIwDQYJKoZIhvcN -AQEBBQADggEPADCCAQoCggEBAL5UegLXTlq3XRRj8LyFs3aF0tpRPVoW9RXp5kFI -TnBvyO6qjNbMDT/xK+4iDtEX4QQUvsxAKxfXbe9i1jpdwjgH7JHaSGm2IjAiKLqO -OXQQtguWwfNmmp96Ql13ArLj458YH08xMO/w2NFWGwB/hfARa4z/T0afFuc/tKJf -XbGCG9xzJ9tmcG45QN8NChGhVvaTweNdVxGWlpHxmi0Mn8OM9CEuB7nPtTTiBuiu -pRC2zVVmNjVp4ktkAqL7IHOz+/F5nhiz6tOika9oD3376Xj055lPznLcTQn2+4d7 -K7ZrBopCFxIQPjkgmYRLfPejbpdUjK1UVJw7hbWkqWqH7JMCAwEAAaN7MHkwDgYD -VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGjvRcaIP4HM -poIguUAK9YL2n7fbMB8GA1UdIwQYMBaAFGjvRcaIP4HMpoIguUAK9YL2n7fbMBYG -A1UdEQQPMA2CC0Jyb2tlci1Sb290MA0GCSqGSIb3DQEBCwUAA4IBAQCbzycJSaDm -AXXNJqQ88djrKs5MDXS8RIjS/cu2ayuLaYDe+BzVmUXNA0Vt9nZGdaz63SLLcjpU -fNSxBfKbwmf7s30AK8Cnfj9q4W/BlBeVizUHQsg1+RQpDIdMrRQrwkXv8mfLw+w5 -3oaXNW6W/8KpBp/H8TBZ6myl6jCbeR3T8EMXBwipMGop/1zkbF01i98Xpqmhx2+l -n+80ofPsSspOo5XmgCZym8CD/m/oFHmjcvOfpOCvDh4PZ+i37pmbSlCYoMpla3u/ -7MJMP5lugfLBYNDN2p+V4KbHP/cApCDT5UWLOeAWjgiZQtHH5ilDeYqEc1oPjyJt -Rtup0MTxSJtN ------END CERTIFICATE----- \ No newline at end of file +MIIDNTCCAh2gAwIBAgIUD8gordqfXZkBt/18/i3GL+ZHIfgwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAxMLQnJva2VyLVJvb3QwHhcNMjYwOTA3MDgzMDA0WhcNMzYw +OTA0MDgzMDM0WjAWMRQwEgYDVQQDEwtCcm9rZXItUm9vdDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAMRoq11ZV5FyDNEADhVdPxYEisVbPMMKsXlUxQEW +ibv/CgQdrgf+AVTpR9Z9qrMmHCd52bTAkck7C6WES0mGhZ/u/Kgciga+HORVf8H0 +5YthLcJRO5d5t2e2rquYTRRZzmaeUtYGP/LJe1IdBjZmbzHxzH9IALdQqmtqSMr5 +kRHd4zzLA8NtzGsJSqOcU5KfDRaA++3kEIWjGVRfzZBSQTj5A8v/98ETDt9HVqq7 +D9lPEZl9OUF3P3/wJWC/adTYyV1AXf3gET5XNZXftbmvhxO9yhNAxAXS3ogXI6EH +fXfvWbv+OKv5jDIwHyLQpBpzfCIPrulaOLpXFXaEH+CPceUCAwEAAaN7MHkwDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBddxl5dqafn +Lv7QBWkTjsFSGGB6MB8GA1UdIwQYMBaAFBddxl5dqafnLv7QBWkTjsFSGGB6MBYG +A1UdEQQPMA2CC0Jyb2tlci1Sb290MA0GCSqGSIb3DQEBCwUAA4IBAQCWfW75sCaL +Cx6JaZAWfe3Fhd7QPZmGmeOlkcdJZJ7T6jLIBMcMpAxirCXA0I1omlY0esHnljd5 +00BX03AVG0McJcclH9yCf5n+eLp0b2c8F1bvgn68I8kQg4SZIdnGL+iot74apRRx +3BvQF5IwZbnOD+MENXDzwlrCX7MZwt0/EC3t9tPnVLCZwk/mOXLlr64a+y7D0lKZ +2+LJ76Ty7RTGPN5cUgHoRodRcJ37r9Uol2dXezQTBjffLP7Kf/PPIhhjGxximadc +/kfmKu4u0e+whQV+8N260+6ScvTr8RArjIwb4vV0NolDwsoUAFaoAvZ5pNRhEnA+ +2Z8f6iL3sKOW +-----END CERTIFICATE----- diff --git a/cce/test.root.crt.pem b/cce/test.root.crt.pem new file mode 100644 index 0000000..1f1265a --- /dev/null +++ b/cce/test.root.crt.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUW34NEb7bl0+Ywx+I1VKtY5vpAOowDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAxMLQnJva2VyLVJvb3QwHhcNMjQwMTIyMTMzNzEzWhcNMzQw +MTE5MTMzNzQzWjAWMRQwEgYDVQQDEwtCcm9rZXItUm9vdDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAL5UegLXTlq3XRRj8LyFs3aF0tpRPVoW9RXp5kFI +TnBvyO6qjNbMDT/xK+4iDtEX4QQUvsxAKxfXbe9i1jpdwjgH7JHaSGm2IjAiKLqO +OXQQtguWwfNmmp96Ql13ArLj458YH08xMO/w2NFWGwB/hfARa4z/T0afFuc/tKJf +XbGCG9xzJ9tmcG45QN8NChGhVvaTweNdVxGWlpHxmi0Mn8OM9CEuB7nPtTTiBuiu +pRC2zVVmNjVp4ktkAqL7IHOz+/F5nhiz6tOika9oD3376Xj055lPznLcTQn2+4d7 +K7ZrBopCFxIQPjkgmYRLfPejbpdUjK1UVJw7hbWkqWqH7JMCAwEAAaN7MHkwDgYD +VR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFGjvRcaIP4HM +poIguUAK9YL2n7fbMB8GA1UdIwQYMBaAFGjvRcaIP4HMpoIguUAK9YL2n7fbMBYG +A1UdEQQPMA2CC0Jyb2tlci1Sb290MA0GCSqGSIb3DQEBCwUAA4IBAQCbzycJSaDm +AXXNJqQ88djrKs5MDXS8RIjS/cu2ayuLaYDe+BzVmUXNA0Vt9nZGdaz63SLLcjpU +fNSxBfKbwmf7s30AK8Cnfj9q4W/BlBeVizUHQsg1+RQpDIdMrRQrwkXv8mfLw+w5 +3oaXNW6W/8KpBp/H8TBZ6myl6jCbeR3T8EMXBwipMGop/1zkbF01i98Xpqmhx2+l +n+80ofPsSspOo5XmgCZym8CD/m/oFHmjcvOfpOCvDh4PZ+i37pmbSlCYoMpla3u/ +7MJMP5lugfLBYNDN2p+V4KbHP/cApCDT5UWLOeAWjgiZQtHH5ilDeYqEc1oPjyJt +Rtup0MTxSJtN +-----END CERTIFICATE----- \ No newline at end of file diff --git a/cce/vars b/cce/vars index 9338bd5..97b5607 100644 --- a/cce/vars +++ b/cce/vars @@ -1,4 +1,9 @@ -BROKER_ID=test-no-real-data.broker.samply.de +BROKER_ID=broker.cce.dkfz.de +ROOT_CRT_FILE=/srv/docker/bridgehead/cce/root.crt.pem +if [ "$ENVIRONMENT" == "test" ]; then + BROKER_ID=test-no-real-data.broker.samply.de + ROOT_CRT_FILE=/srv/docker/bridgehead/cce/test.root.crt.pem +fi BROKER_URL=https://${BROKER_ID} PROXY_ID=${SITE_ID}.${BROKER_ID} FOCUS_BEAM_SECRET_SHORT="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 20)"