Merge pull request #42 from samply/develop
This commit is contained in:
commit
60b2611643
|
@ -0,0 +1,6 @@
|
|||
##Ignore site configuration
|
||||
.gitmodules
|
||||
site-config/*
|
||||
|
||||
## Ignore site configuration
|
||||
*/docker-compose.override.yml
|
183
README.md
183
README.md
|
@ -1 +1,182 @@
|
|||
# bridgehead
|
||||
# Bridgehead
|
||||
|
||||
The Bridgehead is a secure, low-effort solution to connect your research institution to a federated research network. It bundles interoperable, open-source software components into a turnkey package for installation on one of your secure servers. The Bridgehead is pre-configured with sane defaults, centrally monitored and with an absolute minimum of "moving parts" on your side, making it an extremely low-maintenance gateway to data sharing.
|
||||
|
||||
This repository is the starting point for any information and tools you will need to deploy a Bridgehead. If you have questions, please [contact us](mailto:verbis-support@dkfz-heidelberg.de).
|
||||
|
||||
1. [Requirements](#requirements)
|
||||
- [Hardware](#hardware)
|
||||
- [System](#system)
|
||||
- [Git](#git)
|
||||
- [Docker](#docker)
|
||||
2. [Deployment](#deployment)
|
||||
- [Installation](#installation)
|
||||
- [Register with Samply.Beam](#register-with-samplybeam)
|
||||
- [Starting and stopping your Bridgehead](#starting-and-stopping-your-bridgehead)
|
||||
- [Auto-starting your Bridgehead when the server starts](#auto-starting-your-bridgehead-when-the-server-starts)
|
||||
3. [Additional Services](#additional-Services)
|
||||
- [Monitoring](#monitoring)
|
||||
- [Register with a Directory](#register-with-a-Directory)
|
||||
4. [Site-specific configuration](#site-specific-configuration)
|
||||
- [HTTPS Access](#https-access)
|
||||
- [Locally Managed Secrets](#locally-managed-secrets)
|
||||
- [Git Proxy Configuration](#git-proxy-configuration)
|
||||
- [Docker Daemon Proxy Configuration](#docker-daemon-proxy-configuration)
|
||||
- [Non-Linux OS](#non-linux-os)
|
||||
5. [License](#license)
|
||||
|
||||
## Requirements
|
||||
|
||||
### Hardware
|
||||
|
||||
Hardware requirements strongly depend on the specific use-cases of your network as well as on the data it is going to serve. Most use-cases are well-served with the following configuration:
|
||||
|
||||
- 4 CPU cores
|
||||
- 32 GB RAM
|
||||
- 160GB Hard Drive, SSD recommended
|
||||
|
||||
### Software
|
||||
|
||||
You are strongly recommended to install the Bridgehead under a Linux operating system (but see the section [Non-Linux OS](#non-linux-os)). You will need root (administrator) priveleges on this machine in order to perform the deployment. We recommend the newest Ubuntu LTS server release.
|
||||
|
||||
Ensure the following software (or newer) is installed:
|
||||
|
||||
- git >= 2.0
|
||||
- docker >= 20.10.1
|
||||
- docker-compose >= 2.xx (`docker-compose` and `docker compose` are both supported).
|
||||
- systemd
|
||||
|
||||
We recommend to install Docker(-compose) from its official sources as described on the [Docker website](https://docs.docker.com).
|
||||
|
||||
Note for Ubuntu: Please note that snap versions of Docker are not supported.
|
||||
|
||||
### Network
|
||||
|
||||
Since it needs to carry sensitive patient data, Bridgeheads are intended to be deployed within your institution's secure network and behave well even in networks in strict security settings, e.g. firewall rules. The only connectivity required is an outgoing HTTPS proxy. TLS termination is supported, too (see [below](#tls-terminating-proxies))
|
||||
|
||||
Note for Ubuntu: Please note that the uncomplicated firewall (ufw) is known to conflict with Docker [here](https://github.com/chaifeng/ufw-docker).
|
||||
|
||||
## Deployment
|
||||
|
||||
### Base Installation
|
||||
|
||||
First, clone the repository to the directory `/srv/docker/bridgehead`:
|
||||
|
||||
```shell
|
||||
sudo mkdir -p /srv/docker/
|
||||
sudo git clone https://github.com/samply/bridgehead.git /srv/docker/bridgehead
|
||||
```
|
||||
|
||||
Then, run the installation script:
|
||||
|
||||
```shell
|
||||
cd /srv/docker/bridgehead
|
||||
sudo ./bridgehead install <PROJECT>
|
||||
```
|
||||
|
||||
... and follow the instructions on the screen. You should then be prompted to do the next step:
|
||||
|
||||
### Register with Samply.Beam
|
||||
|
||||
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
|
||||
cd /srv/docker/bridgehead
|
||||
sudo ./bridgehead enroll <PROJECT>
|
||||
```
|
||||
|
||||
... and follow the instructions on the screen. You should then be prompted to do the next step:
|
||||
|
||||
### Starting and stopping your Bridgehead
|
||||
|
||||
If you followed the above steps, your Bridgehead should already be configured to autostart (via systemd). If you would like to start/stop manually:
|
||||
|
||||
To start, run
|
||||
|
||||
```shell
|
||||
sudo systemctl start bridgehead@<PROJECT>.service
|
||||
```
|
||||
|
||||
To stop, run
|
||||
|
||||
```shell
|
||||
sudo systemctl stop bridgehead@<PROJECT>.service
|
||||
```
|
||||
|
||||
To enable/disable autostart, run
|
||||
|
||||
```shell
|
||||
sudo systemctl [enable|disable] bridgehead@<PROJECT>.service
|
||||
```
|
||||
|
||||
## Site-specific configuration
|
||||
|
||||
### HTTPS Access
|
||||
|
||||
Even within your internal network, the Bridgehead enforces HTTPS for all services. During the installation, a self-signed, long-lived certificate was created for you. To increase security, you can simply replace the files under `/etc/bridgehead/traefik-tls` with ones from established certification authorities such as [Let's Encrypt](https://letsencrypt.org) or [DFN-AAI](https://www.aai.dfn.de).
|
||||
|
||||
### TLS terminating proxies
|
||||
|
||||
All of the Bridgehead's outgoing connections are secured by transport encryption (TLS) and a Bridgehead will refuse to connect if certificate verification fails. If your local forward proxy server performs TLS termination, please place its CA certificate in `/etc/bridgehead/trusted-ca-certs` as a `.pem` file, e.g. `/etc/bridgehead/trusted-ca-certs/mylocalca.pem`. Then, all Bridgehead components will pick up this certificate and trust it for outgoing connections.
|
||||
|
||||
### File structure
|
||||
|
||||
- `/srv/docker/bridgehead` contains this git repository with the shell scripts and *project-specific configuration*. In here, all files are identical for all sites. You should not make any changes here.
|
||||
- `/etc/bridgehead` contains your *site-specific configuration* synchronized from your site-specific git repository as part of the [base installation](#base-installation). To change anything here, please consult your git repository (find out its URL via `git -C /etc/bridgehead remote -v`).
|
||||
- `/etc/bridgehead/<PROJECT>.conf` is your main site-specific configuration, all bundled into one concise config file. Do not change it here but via the central git repository.
|
||||
- `/etc/bridgehead/<PROJECT>.local.conf` contains site-specific parameters to be known to your Bridgehead only, e.g. local access credentials. The file is ignored via git, and you may edit it here via a text editor.
|
||||
- `/etc/bridgehead/traefik-tls` contains your Bridgehead's reverse proxies TLS certificates for [HTTPS access](#https-access).
|
||||
- `/etc/bridgehead/pki` contains your Bridgehead's private key (e.g., but not limited to Samply.Beam), generated as part of the [Samply.Beam enrollment](#register-with-samplybeam).
|
||||
- `/etc/bridgehead/trusted-ca-certs` contains third-party certificates to be trusted by the Bridgehead. For example, you want to place the certificates of your [TLS-terminating proxy](#network) here.
|
||||
|
||||
Your Bridgehead's actual data is not stored in the above directories, but in named docker volumes, see `docker volume ls` and `docker volume inspect <volume_name>`.
|
||||
|
||||
## Things you should know
|
||||
|
||||
### Auto-Updates
|
||||
|
||||
Your Bridgehead will automatically and regularly check for updates. Whenever something has been updates (e.g., one of the git repositories or one of the docker images), your Bridgehead is automatically restarted. This should happen automatically and does not need any configuration.
|
||||
|
||||
If you would like to understand what happens exactly and when, please check the systemd units deployed during the [installation](#base-installation) via `systemctl cat bridgehead-update@<PROJECT>.service` and `systemctl cat bridgehead-update@<PROJECT.timer`.
|
||||
|
||||
### Monitoring
|
||||
|
||||
To keep all Bridgeheads up and working and detect any errors before a user does, a central monitoring
|
||||
|
||||
- Your Bridgehead itself will report relevant system events, such as successful/failed updates, restarts, performance metrics or version numbers.
|
||||
- Your Bridgehead is also monitored from the outside by your network's central components. For example, the federated search will regularly perform a black-box test by sending an empty query to your Bridgehead and checking if the results make sense.
|
||||
|
||||
In all monitoring cases, obviously no sensitive information is transmitted, in particular not any patient-related data. Aggregated data, e.g. total amount of datasets, may be transmitted for diagnostic purposes.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Docker Daemon Proxy Configuration
|
||||
|
||||
Docker has a background daemon, responsible for downloading images and starting them. Sometimes, proxy configuration from your system won't carry over and it will fail to download images. In that case, configure the proxy for this daemon as described in the [official documentation](https://docs.docker.com).
|
||||
|
||||
### Non-Linux OS
|
||||
|
||||
The installation procedures described above have only been tested under Linux.
|
||||
|
||||
Below are some suggestions for getting the installation to work on other operating systems. Note that we are not able to provide support for these routes!
|
||||
|
||||
We believe that it is likely that installation would also work with FreeBSD and MacOS.
|
||||
|
||||
Under Windows, you have 2 options:
|
||||
|
||||
- Virtual machine
|
||||
- WSL
|
||||
|
||||
We have tested the installation procedure with an Ubuntu 22.04 guest system running on a VMware virtual machine. That worked flawlessly.
|
||||
|
||||
Installation under WSL ought to work, but we have not tested this.
|
||||
|
||||
## License
|
||||
|
||||
Copyright 2019 - 2022 The Samply Community
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
container_name: bridgehead-traefik
|
||||
image: traefik:latest
|
||||
command:
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --providers.docker=true
|
||||
- --providers.docker.exposedbydefault=false
|
||||
- --providers.file.directory=/configuration/
|
||||
- --api.dashboard=true
|
||||
- --accesslog=true
|
||||
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.dashboard.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
|
||||
- "traefik.http.routers.dashboard.entrypoints=websecure"
|
||||
- "traefik.http.routers.dashboard.service=api@internal"
|
||||
- "traefik.http.routers.dashboard.tls=true"
|
||||
- "traefik.http.routers.dashboard.middlewares=auth"
|
||||
- "traefik.http.middlewares.auth.basicauth.users=${LDM_LOGIN}"
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
volumes:
|
||||
- /etc/bridgehead/traefik-tls:/certs:ro
|
||||
- ../lib/traefik-configuration/:/configuration:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
|
||||
forward_proxy:
|
||||
container_name: bridgehead-forward-proxy
|
||||
image: samply/bridgehead-forward-proxy:latest
|
||||
environment:
|
||||
HTTPS_PROXY: ${HTTPS_PROXY_URL}
|
||||
USERNAME: ${HTTPS_PROXY_USERNAME}
|
||||
PASSWORD: ${HTTPS_PROXY_PASSWORD}
|
||||
volumes:
|
||||
- /etc/bridgehead/trusted-ca-certs:/docker/custom-certs/:ro
|
||||
|
||||
landing:
|
||||
container_name: bridgehead-landingpage
|
||||
image: samply/bridgehead-landingpage:master
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.landing.rule=PathPrefix(`/`)"
|
||||
- "traefik.http.services.landing.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.landing.tls=true"
|
||||
environment:
|
||||
HOST: ${HOST}
|
||||
PROJECT: ${PROJECT}
|
||||
SITE_NAME: ${SITE_NAME}
|
||||
|
||||
blaze:
|
||||
image: "samply/blaze:0.18"
|
||||
container_name: bridgehead-bbmri-blaze
|
||||
environment:
|
||||
BASE_URL: "http://bridgehead-bbmri-blaze:8080"
|
||||
JAVA_TOOL_OPTIONS: "-Xmx4g"
|
||||
LOG_LEVEL: "debug"
|
||||
ENFORCE_REFERENTIAL_INTEGRITY: "false"
|
||||
volumes:
|
||||
- "blaze-data:/app/data"
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.blaze_ccp.rule=PathPrefix(`/bbmri-localdatamanagement`)"
|
||||
- "traefik.http.middlewares.ccp_b_strip.stripprefix.prefixes=/bbmri-localdatamanagement"
|
||||
- "traefik.http.services.blaze_ccp.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.blaze_ccp.middlewares=ccp_b_strip,auth"
|
||||
- "traefik.http.routers.blaze_ccp.tls=true"
|
||||
|
||||
spot:
|
||||
image: samply/spot:latest
|
||||
container_name: bridgehead-spot
|
||||
environment:
|
||||
SECRET: ${SPOT_BEAM_SECRET_LONG}
|
||||
APPID: spot
|
||||
PROXY_ID: ${PROXY_ID}
|
||||
LDM_URL: http://bridgehead-bbmri-blaze:8080/fhir
|
||||
BEAM_PROXY: http://beam-proxy:8081
|
||||
depends_on:
|
||||
- "beam-proxy"
|
||||
- "blaze"
|
||||
|
||||
beam-proxy:
|
||||
image: "samply/beam-proxy:develop"
|
||||
container_name: bridgehead-beam-proxy
|
||||
environment:
|
||||
BROKER_URL: ${BROKER_URL}
|
||||
PROXY_ID: ${PROXY_ID}
|
||||
APP_0_ID: spot
|
||||
APP_0_KEY: ${SPOT_BEAM_SECRET_SHORT}
|
||||
PRIVKEY_FILE: /run/secrets/proxy.pem
|
||||
RUST_LOG: debug
|
||||
ALL_PROXY: http://forward_proxy:3128
|
||||
TLS_CA_CERTIFICATES_DIR: /conf/trusted-ca-certs
|
||||
secrets:
|
||||
- proxy.pem
|
||||
depends_on:
|
||||
- "forward_proxy"
|
||||
volumes:
|
||||
- /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro
|
||||
|
||||
|
||||
volumes:
|
||||
blaze-data:
|
||||
|
||||
secrets:
|
||||
proxy.pem:
|
||||
file: /etc/bridgehead/pki/${SITE_ID}.priv.pem
|
|
@ -0,0 +1,7 @@
|
|||
BROKER_ID=broker.bbmri.samply.de
|
||||
BROKER_URL=https://${BROKER_ID}
|
||||
PROXY_ID=${SITE_ID}.${BROKER_ID}
|
||||
SPOT_BEAM_SECRET_SHORT="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 20)"
|
||||
SPOT_BEAM_SECRET_LONG="ApiKey spot.${PROXY_ID} ${SPOT_BEAM_SECRET_SHORT}"
|
||||
SUPPORT_EMAIL=bridgehead@helpdesk.bbmri-eric.eu
|
||||
PRIVATEKEYFILENAME=/etc/bridgehead/pki/${SITE_ID}.priv.pem
|
|
@ -0,0 +1,107 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
baseDir() {
|
||||
# see https://stackoverflow.com/questions/59895
|
||||
SOURCE=${BASH_SOURCE[0]}
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
|
||||
SOURCE=$(readlink "$SOURCE")
|
||||
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
|
||||
echo $DIR
|
||||
}
|
||||
|
||||
BASE=$(baseDir)
|
||||
cd $BASE
|
||||
|
||||
source ./lib/functions.sh
|
||||
|
||||
ACTION=$1
|
||||
export PROJECT=$2
|
||||
|
||||
if [[ -z $1 || -z $2 ]]; then
|
||||
printUsage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$PROJECT" in
|
||||
ccp)
|
||||
#nothing extra to do
|
||||
;;
|
||||
bbmri)
|
||||
#nothing extra to do
|
||||
;;
|
||||
*)
|
||||
printUsage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
loadVars() {
|
||||
# Load variables from /etc/bridgehead and /srv/docker/bridgehead
|
||||
set -a
|
||||
source /etc/bridgehead/$PROJECT.conf || fail_and_report 1 "/etc/bridgehead/$PROJECT.conf not found"
|
||||
if [ -e /etc/bridgehead/$PROJECT.local.conf ]; then
|
||||
log INFO "Applying /etc/bridgehead/$PROJECT.local.conf"
|
||||
source /etc/bridgehead/$PROJECT.local.conf || fail_and_report 1 "Found /etc/bridgehead/$PROJECT.local.conf but failed to import"
|
||||
fi
|
||||
fetchVarsFromVaultByFile /etc/bridgehead/$PROJECT.conf || fail_and_report 1 "Unable to fetchVarsFromVaultByFile"
|
||||
[ -e ./$PROJECT/vars ] && source ./$PROJECT/vars
|
||||
set +a
|
||||
|
||||
OVERRIDE=${OVERRIDE:=""}
|
||||
if [ -f "$PROJECT/docker-compose.override.yml" ]; then
|
||||
log INFO "Applying $PROJECT/docker-compose.override.yml"
|
||||
OVERRIDE+=" -f ./$PROJECT/docker-compose.override.yml"
|
||||
fi
|
||||
detectCompose
|
||||
setHostname
|
||||
}
|
||||
|
||||
case "$ACTION" in
|
||||
start)
|
||||
loadVars
|
||||
hc_send log "Bridgehead $PROJECT startup: Checking requirements ..."
|
||||
checkRequirements
|
||||
hc_send log "Bridgehead $PROJECT startup: Requirements checked out. Now starting bridgehead ..."
|
||||
export LDM_LOGIN=$(getLdmPassword)
|
||||
exec $COMPOSE -f ./$PROJECT/docker-compose.yml $OVERRIDE up --abort-on-container-exit
|
||||
;;
|
||||
stop)
|
||||
loadVars
|
||||
exec $COMPOSE -f ./$PROJECT/docker-compose.yml $OVERRIDE down
|
||||
;;
|
||||
update)
|
||||
loadVars
|
||||
exec ./lib/update-bridgehead.sh $PROJECT
|
||||
;;
|
||||
install)
|
||||
source ./lib/prepare-system.sh
|
||||
loadVars
|
||||
exec ./lib/install-bridgehead.sh $PROJECT
|
||||
;;
|
||||
uninstall)
|
||||
exec ./lib/uninstall-bridgehead.sh $PROJECT
|
||||
;;
|
||||
enroll)
|
||||
loadVars
|
||||
if [ -e $PRIVATEKEYFILENAME ]; then
|
||||
log ERROR "Private key already exists at $PRIVATEKEYFILENAME. Please delete first to proceed."
|
||||
exit 1
|
||||
fi
|
||||
docker run --rm -ti -v /etc/bridgehead/pki:/etc/bridgehead/pki samply/beam-enroll:latest --output-file $PRIVATEKEYFILENAME --proxy-id $PROXY_ID --admin-email $SUPPORT_EMAIL
|
||||
chmod 600 $PRIVATEKEYFILENAME
|
||||
;;
|
||||
preRun | preUpdate)
|
||||
fixPermissions
|
||||
;;
|
||||
postRun | postUpdate)
|
||||
;;
|
||||
*)
|
||||
printUsage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,114 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
traefik:
|
||||
container_name: bridgehead-traefik
|
||||
image: traefik:latest
|
||||
command:
|
||||
- --entrypoints.web.address=:80
|
||||
- --entrypoints.websecure.address=:443
|
||||
- --providers.docker=true
|
||||
- --providers.docker.exposedbydefault=false
|
||||
- --providers.file.directory=/configuration/
|
||||
- --api.dashboard=true
|
||||
- --accesslog=true
|
||||
- --entrypoints.web.http.redirections.entrypoint.to=websecure
|
||||
- --entrypoints.web.http.redirections.entrypoint.scheme=https
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.dashboard.rule=PathPrefix(`/api`) || PathPrefix(`/dashboard`)"
|
||||
- "traefik.http.routers.dashboard.entrypoints=websecure"
|
||||
- "traefik.http.routers.dashboard.service=api@internal"
|
||||
- "traefik.http.routers.dashboard.tls=true"
|
||||
- "traefik.http.routers.dashboard.middlewares=auth"
|
||||
- "traefik.http.middlewares.auth.basicauth.users=${LDM_LOGIN}"
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
volumes:
|
||||
- /etc/bridgehead/traefik-tls:/certs:ro
|
||||
- ../lib/traefik-configuration/:/configuration:ro
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
|
||||
forward_proxy:
|
||||
container_name: bridgehead-forward-proxy
|
||||
image: samply/bridgehead-forward-proxy:latest
|
||||
environment:
|
||||
HTTPS_PROXY: ${HTTPS_PROXY_URL}
|
||||
USERNAME: ${HTTPS_PROXY_USERNAME}
|
||||
PASSWORD: ${HTTPS_PROXY_PASSWORD}
|
||||
volumes:
|
||||
- /etc/bridgehead/trusted-ca-certs:/docker/custom-certs/:ro
|
||||
|
||||
landing:
|
||||
container_name: bridgehead-landingpage
|
||||
image: samply/bridgehead-landingpage:master
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.landing.rule=PathPrefix(`/`)"
|
||||
- "traefik.http.services.landing.loadbalancer.server.port=80"
|
||||
- "traefik.http.routers.landing.tls=true"
|
||||
environment:
|
||||
HOST: ${HOST}
|
||||
PROJECT: ${PROJECT}
|
||||
SITE_NAME: ${SITE_NAME}
|
||||
|
||||
blaze:
|
||||
image: "samply/blaze:0.18"
|
||||
container_name: bridgehead-ccp-blaze
|
||||
environment:
|
||||
BASE_URL: "http://bridgehead-ccp-blaze:8080"
|
||||
JAVA_TOOL_OPTIONS: "-Xmx4g"
|
||||
LOG_LEVEL: "debug"
|
||||
ENFORCE_REFERENTIAL_INTEGRITY: "false"
|
||||
volumes:
|
||||
- "blaze-data:/app/data"
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.blaze_ccp.rule=PathPrefix(`/ccp-localdatamanagement`)"
|
||||
- "traefik.http.middlewares.ccp_b_strip.stripprefix.prefixes=/ccp-localdatamanagement"
|
||||
- "traefik.http.services.blaze_ccp.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.blaze_ccp.middlewares=ccp_b_strip,auth"
|
||||
- "traefik.http.routers.blaze_ccp.tls=true"
|
||||
|
||||
spot:
|
||||
image: samply/spot:latest
|
||||
container_name: bridgehead-spot
|
||||
environment:
|
||||
SECRET: ${SPOT_BEAM_SECRET_LONG}
|
||||
APPID: spot
|
||||
PROXY_ID: ${PROXY_ID}
|
||||
LDM_URL: http://bridgehead-ccp-blaze:8080/fhir
|
||||
BEAM_PROXY: http://beam-proxy:8081
|
||||
depends_on:
|
||||
- "beam-proxy"
|
||||
- "blaze"
|
||||
|
||||
beam-proxy:
|
||||
image: "samply/beam-proxy:develop"
|
||||
container_name: bridgehead-beam-proxy
|
||||
environment:
|
||||
BROKER_URL: ${BROKER_URL}
|
||||
PROXY_ID: ${PROXY_ID}
|
||||
APP_0_ID: spot
|
||||
APP_0_KEY: ${SPOT_BEAM_SECRET_SHORT}
|
||||
APP_1_ID: report-hub
|
||||
APP_1_KEY: ${REPORTHUB_BEAM_SECRET_SHORT}
|
||||
PRIVKEY_FILE: /run/secrets/proxy.pem
|
||||
RUST_LOG: debug
|
||||
ALL_PROXY: http://forward_proxy:3128
|
||||
TLS_CA_CERTIFICATES_DIR: /conf/trusted-ca-certs
|
||||
secrets:
|
||||
- proxy.pem
|
||||
depends_on:
|
||||
- "forward_proxy"
|
||||
volumes:
|
||||
- /etc/bridgehead/trusted-ca-certs:/conf/trusted-ca-certs:ro
|
||||
|
||||
|
||||
volumes:
|
||||
blaze-data:
|
||||
|
||||
secrets:
|
||||
proxy.pem:
|
||||
file: /etc/bridgehead/pki/${SITE_ID}.priv.pem
|
|
@ -0,0 +1,32 @@
|
|||
version: "3.7"
|
||||
|
||||
services:
|
||||
connector:
|
||||
container_name: bridgehead-connector
|
||||
image: docker.verbis.dkfz.de/ccp/connector:bk2
|
||||
environment:
|
||||
POSTGRES_PASSWORD: ${CONNECTOR_POSTGRES_PASSWORD}
|
||||
NNGM_MAGICPL_APIKEY: ${NNGM_MAGICPL_APIKEY}
|
||||
NNGM_MAINZELLISTE_APIKEY: ${NNGM_MAINZELLISTE_APIKEY}
|
||||
NNGM_CTS_APIKEY: ${NNGM_CTS_APIKEY}
|
||||
NNGM_CRYPTKEY: ${NNGM_CRYPTKEY}
|
||||
restart: always
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.connector.rule=PathPrefix(`/ccp-connector`)"
|
||||
- "traefik.http.services.connector.loadbalancer.server.port=8080"
|
||||
- "traefik.http.routers.connector.tls=true"
|
||||
|
||||
connector_db:
|
||||
image: postgres:9.5-alpine
|
||||
container_name: bridgehead-ccp-connector-db
|
||||
volumes:
|
||||
- "connector_db_data:/var/lib/postgresql/data"
|
||||
environment:
|
||||
POSTGRES_DB: "samplyconnector"
|
||||
POSTGRES_USER: "samplyconnector"
|
||||
POSTGRES_PASSWORD: ${CONNECTOR_POSTGRES_PASSWORD}
|
||||
restart: always
|
||||
|
||||
volumes:
|
||||
connector_db_data:
|
|
@ -0,0 +1,9 @@
|
|||
#!/bin/bash
|
||||
|
||||
function nngmSetup() {
|
||||
if [ -n "$NNGM_CTS_APIKEY" ]; then
|
||||
log INFO "nNGM setup detected -- will start nNGM Connector."
|
||||
OVERRIDE+=" -f ./$PROJECT/nngm-compose.yml"
|
||||
fi
|
||||
CONNECTOR_POSTGRES_PASSWORD="$(echo \"This is a salt string to generate one consistent password. It is not required to be secret.\" | openssl rsautl -sign -inkey /etc/bridgehead/pki/${SITE_ID}.priv.pem | base64 | head -c 30)"
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
BROKER_ID=broker.dev.ccp-it.dktk.dkfz.de
|
||||
BROKER_URL=https://${BROKER_ID}
|
||||
PROXY_ID=${SITE_ID}.${BROKER_ID}
|
||||
SPOT_BEAM_SECRET_SHORT="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 20)"
|
||||
SPOT_BEAM_SECRET_LONG="ApiKey spot.${PROXY_ID} ${SPOT_BEAM_SECRET_SHORT}"
|
||||
REPORTHUB_BEAM_SECRET_SHORT="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 20)"
|
||||
REPORTHUB_BEAM_SECRET_LONG="ApiKey report-hub.${PROXY_ID} ${REPORTHUB_BEAM_SECRET_SHORT}"
|
||||
SUPPORT_EMAIL=support-ccp@dkfz-heidelberg.de
|
||||
PRIVATEKEYFILENAME=/etc/bridgehead/pki/${SITE_ID}.priv.pem
|
||||
|
||||
# This will load nngm setup. Effective only if nngm configuration is defined.
|
||||
source $PROJECT/nngm-setup.sh
|
||||
nngmSetup
|
|
@ -0,0 +1,141 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
detectCompose() {
|
||||
if [[ "$(docker compose version 2>/dev/null)" == *"Docker Compose version"* ]]; then
|
||||
COMPOSE="docker compose"
|
||||
else
|
||||
COMPOSE="docker-compose"
|
||||
# This is intended to fail on startup in the next prereq check.
|
||||
fi
|
||||
}
|
||||
|
||||
getLdmPassword() {
|
||||
if [ -n "$LDM_PASSWORD" ]; then
|
||||
docker run --rm httpd:alpine htpasswd -nb $PROJECT $LDM_PASSWORD | tr -d '\n' | tr -d '\r'
|
||||
else
|
||||
echo -n ""
|
||||
fi
|
||||
}
|
||||
|
||||
exitIfNotRoot() {
|
||||
if [ "$EUID" -ne 0 ]; then
|
||||
log "ERROR" "Please run as root"
|
||||
fail_and_report 1 "Please run as root"
|
||||
fi
|
||||
}
|
||||
|
||||
checkOwner(){
|
||||
COUNT=$(find $1 ! -user $2 |wc -l)
|
||||
if [ $COUNT -gt 0 ]; then
|
||||
log ERROR "$COUNT files in $1 are not owned by user $2. Run find $1 ! -user $2 to see them, chown -R $2 $1 to correct this issue."
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
printUsage() {
|
||||
echo "Usage: bridgehead start|stop|update|install|uninstall|enroll PROJECTNAME"
|
||||
echo "PROJECTNAME should be one of ccp|bbmri"
|
||||
}
|
||||
|
||||
checkRequirements() {
|
||||
if ! lib/prerequisites.sh $@; then
|
||||
log "ERROR" "Validating Prerequisites failed, please fix the error(s) above this line."
|
||||
fail_and_report 1 "Validating prerequisites failed."
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
fetchVarsFromVault() {
|
||||
[ -e /etc/bridgehead/vault.conf ] && source /etc/bridgehead/vault.conf
|
||||
|
||||
if [ -z "$BW_MASTERPASS" ] || [ -z "$BW_CLIENTID" ] || [ -z "$BW_CLIENTSECRET" ]; then
|
||||
log "ERROR" "Please supply correct credentials in /etc/bridgehead/vault.conf."
|
||||
return 1
|
||||
fi
|
||||
|
||||
set +e
|
||||
|
||||
PASS=$(BW_MASTERPASS="$BW_MASTERPASS" BW_CLIENTID="$BW_CLIENTID" BW_CLIENTSECRET="$BW_CLIENTSECRET" docker run --rm -e BW_MASTERPASS -e BW_CLIENTID -e BW_CLIENTSECRET -e http_proxy samply/bridgehead-vaultfetcher $@)
|
||||
RET=$?
|
||||
|
||||
if [ $RET -ne 0 ]; then
|
||||
echo "Code: $RET"
|
||||
echo $PASS
|
||||
return $RET
|
||||
fi
|
||||
|
||||
eval $(echo -e "$PASS" | sed 's/\r//g')
|
||||
|
||||
set -e
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
fetchVarsFromVaultByFile() {
|
||||
VARS_TO_FETCH=""
|
||||
|
||||
for line in $(cat $@); do
|
||||
if [[ $line =~ .*=[\"]*\<VAULT\>[\"]*.* ]]; then
|
||||
VARS_TO_FETCH+="$(echo -n $line | sed 's/=.*//') "
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -z "$VARS_TO_FETCH" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
log INFO "Fetching $(echo $VARS_TO_FETCH | wc -w) secrets from Vault ..."
|
||||
|
||||
fetchVarsFromVault $VARS_TO_FETCH
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
assertVarsNotEmpty() {
|
||||
MISSING_VARS=""
|
||||
|
||||
for VAR in $@; do
|
||||
if [ -z "${!VAR}" ]; then
|
||||
MISSING_VARS+="$VAR "
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$MISSING_VARS" ]; then
|
||||
log "ERROR" "Mandatory variables not defined: $MISSING_VARS"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
fixPermissions() {
|
||||
CHOWN=$(which chown)
|
||||
sudo $CHOWN -R bridgehead /etc/bridgehead /srv/docker/bridgehead
|
||||
}
|
||||
|
||||
source lib/monitoring.sh
|
||||
|
||||
report_error() {
|
||||
CODE=$1
|
||||
shift
|
||||
log ERROR "$@"
|
||||
hc_send $CODE "$@"
|
||||
}
|
||||
|
||||
fail_and_report() {
|
||||
report_error $@
|
||||
exit $1
|
||||
}
|
||||
|
||||
setHostname() {
|
||||
if [ -z "$HOST" ]; then
|
||||
export HOST=$(hostname -f)
|
||||
log DEBUG "Using auto-detected hostname $HOST."
|
||||
fi
|
||||
}
|
||||
|
||||
##Setting Network properties
|
||||
# currently not needed
|
||||
#export HOSTIP=$(MSYS_NO_PATHCONV=1 docker run --rm --add-host=host.docker.internal:host-gateway ubuntu cat /etc/hosts | grep 'host.docker.internal' | awk '{print $1}');
|
|
@ -0,0 +1,41 @@
|
|||
#!/bin/bash
|
||||
|
||||
if [ "$1" != "get" ]; then
|
||||
echo "Usage: $0 get"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
baseDir() {
|
||||
# see https://stackoverflow.com/questions/59895
|
||||
SOURCE=${BASH_SOURCE[0]}
|
||||
while [ -h "$SOURCE" ]; do # resolve $SOURCE until the file is no longer a symlink
|
||||
DIR=$( cd -P "$( dirname "$SOURCE" )" >/dev/null 2>&1 && pwd )
|
||||
SOURCE=$(readlink "$SOURCE")
|
||||
[[ $SOURCE != /* ]] && SOURCE=$DIR/$SOURCE # if $SOURCE was a relative symlink, we need to resolve it relative to the path where the symlink file was located
|
||||
done
|
||||
DIR=$( cd -P "$( dirname "$SOURCE" )/.." >/dev/null 2>&1 && pwd )
|
||||
echo $DIR
|
||||
}
|
||||
|
||||
BASE=$(baseDir)
|
||||
cd $BASE
|
||||
|
||||
source lib/functions.sh
|
||||
|
||||
assertVarsNotEmpty SITE_ID || fail_and_report 1 "gitpassword.sh failed: SITE_ID is empty."
|
||||
|
||||
PARAMS="$(cat)"
|
||||
GITHOST=$(echo "$PARAMS" | grep "^host=" | sed 's/host=\(.*\)/\1/g')
|
||||
|
||||
fetchVarsFromVault GIT_PASSWORD
|
||||
|
||||
if [ -z "${GIT_PASSWORD}" ]; then
|
||||
fail_and_report 1 "gitpassword.sh failed: Git password not found."
|
||||
fi
|
||||
|
||||
cat <<EOF
|
||||
protocol=https
|
||||
host=$GITHOST
|
||||
username=bk-${SITE_ID}
|
||||
password=${GIT_PASSWORD}
|
||||
EOF
|
|
@ -0,0 +1,66 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source lib/functions.sh
|
||||
|
||||
exitIfNotRoot
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
log "ERROR" "Please provide a Project as argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export PROJECT=$1
|
||||
|
||||
checkRequirements noprivkey
|
||||
|
||||
log "INFO" "Allowing the bridgehead user to start/stop the bridgehead."
|
||||
|
||||
cat <<EOF > /etc/sudoers.d/bridgehead-"${PROJECT}"
|
||||
# This has been added by the Bridgehead installer. Remove with bridgehead uninstall.
|
||||
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
|
||||
|
||||
bridgehead ALL= NOPASSWD: BRIDGEHEAD${PROJECT^^}
|
||||
EOF
|
||||
|
||||
# TODO: Determine whether this should be located in setup-bridgehead (triggered through bridgehead install) or in update bridgehead (triggered every hour)
|
||||
if [ -z "$LDM_PASSWORD" ]; then
|
||||
log "INFO" "Now generating a password for the local data management. Please save the password for your ETL process!"
|
||||
generated_passwd="$(cat /proc/sys/kernel/random/uuid | sed 's/[-]//g' | head -c 32)"
|
||||
|
||||
log "INFO" "Your generated credentials are:\n user: $PROJECT\n password: $generated_passwd"
|
||||
echo -e "## Local Data Management Basic Authentication\n# User: $PROJECT\nLDM_PASSWORD=$generated_passwd" >> /etc/bridgehead/${PROJECT}.local.conf;
|
||||
fi
|
||||
|
||||
log "INFO" "Registering system units for bridgehead and bridgehead-update"
|
||||
cp -v \
|
||||
lib/systemd/bridgehead\@.service \
|
||||
lib/systemd/bridgehead-update\@.service \
|
||||
lib/systemd/bridgehead-update\@.timer \
|
||||
/etc/systemd/system/
|
||||
|
||||
systemctl daemon-reload
|
||||
|
||||
log INFO "Trying to update your bridgehead ..."
|
||||
|
||||
systemctl start bridgehead-update@"${PROJECT}".service
|
||||
|
||||
log "INFO" "Enabling autostart of bridgehead@${PROJECT}.service"
|
||||
systemctl enable bridgehead@"${PROJECT}".service
|
||||
|
||||
log "INFO" "Enabling auto-updates for bridgehead@${PROJECT}.service ..."
|
||||
systemctl enable --now bridgehead-update@"${PROJECT}".timer
|
||||
|
||||
STR="\n\n systemctl start bridgehead@${PROJECT}.service\n\nor by rebooting your machine."
|
||||
if [ -e /etc/bridgehead/pki/${SITE_ID}.priv.pem ]; then
|
||||
STR="Success. Next, start your bridgehead by running$STR"
|
||||
else
|
||||
STR="Success. Next, enroll into the $PROJECT broker by creating a cryptographic certificate. To do so, run\n\n /srv/docker/bridgehead/bridgehead enroll $PROJECT\n\nThen, you may start the bridgehead by running$STR"
|
||||
fi
|
||||
|
||||
log "INFO" "$STR"
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/bash
|
||||
|
||||
log() {
|
||||
SEVERITY="$1"
|
||||
shift
|
||||
echo -e "$(date +'%Y-%m-%d %T')" "$SEVERITY:" "$@"
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
#!/bin/bash
|
||||
|
||||
source lib/log.sh
|
||||
|
||||
function hc_set_uuid(){
|
||||
HCUUID="$1"
|
||||
}
|
||||
|
||||
function hc_set_service(){
|
||||
HCSERVICE="$1"
|
||||
}
|
||||
|
||||
UPTIME=
|
||||
USER_AGENT=
|
||||
|
||||
function hc_send(){
|
||||
BASEURL="https://healthchecks.verbis.dkfz.de/ping"
|
||||
if [ -n "$MONITOR_APIKEY" ]; then
|
||||
hc_set_uuid $MONITOR_APIKEY
|
||||
fi
|
||||
|
||||
if [ -n "$HCSERVICE" ]; then
|
||||
HCURL="$BASEURL/$PING_KEY/$HCSERVICE"
|
||||
fi
|
||||
if [ -n "$HCUUID" ]; then
|
||||
HCURL="$BASEURL/$HCUUID"
|
||||
fi
|
||||
if [ ! -n "$HCURL" ]; then
|
||||
log WARN "Did not report Healthcheck: Neither Healthcheck UUID nor service set. Please define MONITOR_APIKEY in /etc/bridgehead."
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "$UPTIME" ]; then
|
||||
UPTIME=$(docker ps -a --format 'table {{.Names}} \t{{.RunningFor}} \t {{.Status}} \t {{.Image}}' --filter name=bridgehead || echo "Unable to get docker statistics")
|
||||
fi
|
||||
|
||||
if [ -z "$USER_AGENT" ]; then
|
||||
if [ "$USER" != "root" ]; then
|
||||
COMMIT_ETC=$(git -C /etc/bridgehead rev-parse HEAD | cut -c -8)
|
||||
COMMIT_SRV=$(git -C /srv/docker/bridgehead rev-parse HEAD | cut -c -8)
|
||||
else
|
||||
COMMIT_ETC=$(su -c 'git -C /etc/bridgehead rev-parse HEAD' bridgehead | cut -c -8)
|
||||
COMMIT_SRV=$(su -c 'git -C /srv/docker/bridgehead rev-parse HEAD' bridgehead | cut -c -8)
|
||||
fi
|
||||
USER_AGENT="srv:$COMMIT_SRV etc:$COMMIT_ETC"
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
MSG="$2\n\nDocker stats:\n$UPTIME"
|
||||
echo -e "$MSG" | https_proxy=$HTTPS_PROXY_URL curl -A "$USER_AGENT" -s -o /dev/null -X POST --data-binary @- "$HCURL"/"$1" || log WARN "Monitoring failed: Unable to send data to $HCURL/$1"
|
||||
else
|
||||
https_proxy=$HTTPS_PROXY_URL curl -A "$USER_AGENT" -s -o /dev/null "$HCURL"/"$1" || log WARN "Monitoring failed: Unable to send data to $HCURL/$1"
|
||||
fi
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source lib/log.sh
|
||||
source lib/functions.sh
|
||||
|
||||
log "INFO" "Preparing your system for bridgehead installation ..."
|
||||
|
||||
# Create the bridgehead user
|
||||
if id bridgehead &>/dev/null; then
|
||||
log "INFO" "Existing user with id $(id -u bridgehead) will be used by the bridgehead system units."
|
||||
else
|
||||
log "INFO" "Now creating a system user to own the bridgehead's files."
|
||||
useradd -M -g docker -N bridgehead || fail_and_report ""
|
||||
fi
|
||||
|
||||
# Clone the OpenSource repository of bridgehead
|
||||
bridgehead_repository_url="https://github.com/samply/bridgehead.git"
|
||||
if [ -d "/srv/docker/bridgehead" ]; then
|
||||
current_owner=$(stat -c '%U' /srv/docker/bridgehead)
|
||||
if [ "$(su -c 'git -C /srv/docker/bridgehead remote get-url origin' $current_owner)" == "$bridgehead_repository_url" ]; then
|
||||
log "INFO" "Bridgehead's open-source repository has been found at /srv/docker/bridgehead"
|
||||
else
|
||||
log "ERROR" "The directory /srv/docker/bridgehead seems to exist, but doesn't contain a clone of $bridgehead_repository_url\nPlease delete the directory and try again."
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
log "INFO" "Cloning $bridgehead_repository_url to /srv/docker/bridgehead"
|
||||
mkdir -p /srv/docker/
|
||||
git clone bridgehead_repository_url /srv/docker/bridgehead -b feature/samplyBeam
|
||||
fi
|
||||
|
||||
case "$PROJECT" in
|
||||
ccp)
|
||||
site_configuration_repository_middle="git.verbis.dkfz.de/bridgehead-configurations/bridgehead-config-"
|
||||
;;
|
||||
bbmri)
|
||||
site_configuration_repository_middle="git.verbis.dkfz.de/bbmri-bridgehead-configs/"
|
||||
;;
|
||||
*)
|
||||
log ERROR "Internal error, this should not happen."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Clone the site-configuration
|
||||
if [ -d /etc/bridgehead ]; then
|
||||
current_owner=$(stat -c '%U' /etc/bridgehead)
|
||||
if [ "$(su -c 'git -C /etc/bridgehead remote get-url origin' $current_owner | grep $site_configuration_repository_middle)" ]; then
|
||||
log "INFO" "Your site config repository in /etc/bridgehead seems to be installed correctly."
|
||||
else
|
||||
log "WARN" "Your site configuration repository in /etc/bridgehead seems to have another origin than git.verbis.dkfz.de. Please check if the repository is correctly cloned!"
|
||||
fi
|
||||
else
|
||||
log "INFO" "Now cloning your site configuration repository for you."
|
||||
read -p "Please enter your site: " site
|
||||
read -s -p "Please enter the bridgehead's access token for your site configuration repository (will not be echoed): " access_token
|
||||
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."
|
||||
fi
|
||||
fi
|
||||
|
||||
chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead
|
||||
|
||||
log INFO "System preparation is completed and private key is present."
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
#!/bin/bash
|
||||
|
||||
source lib/functions.sh
|
||||
|
||||
detectCompose
|
||||
|
||||
if ! id "bridgehead" &>/dev/null; then
|
||||
log ERROR "User bridgehead does not exist. Please run bridgehead install $PROJECT"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
checkOwner /srv/docker/bridgehead bridgehead || exit 1
|
||||
checkOwner /etc/bridgehead bridgehead || exit 1
|
||||
|
||||
## Check if user is a su
|
||||
log INFO "Checking if all prerequisites are met ..."
|
||||
prerequisites="git docker"
|
||||
for prerequisite in $prerequisites; do
|
||||
$prerequisite --version 2>&1
|
||||
is_available=$?
|
||||
if [ $is_available -gt 0 ]; then
|
||||
fail_and_report 79 "Prerequisite not fulfilled - $prerequisite is not available!"
|
||||
fi
|
||||
# TODO: Check for specific version
|
||||
done
|
||||
|
||||
log INFO "Checking if sudo is installed ..."
|
||||
if [ ! -d /etc/sudoers.d ]; then
|
||||
fail_and_report 1 "/etc/sudoers.d does not exist. Please install sudo package."
|
||||
fi
|
||||
|
||||
log INFO "Checking configuration ..."
|
||||
|
||||
## Download submodule
|
||||
if [ ! -d "/etc/bridgehead/" ]; then
|
||||
fail_and_report 1 "Please set up the config folder at /etc/bridgehead. Instruction are in the readme."
|
||||
fi
|
||||
|
||||
# TODO: Check all required variables here in a generic loop
|
||||
|
||||
#check if project env is present
|
||||
if [ -d "/etc/bridgehead/${PROJECT}.conf" ]; then
|
||||
fail_and_report 1 "Project config not found. Please copy the template from ${PROJECT} and put it under /etc/bridgehead-config/${PROJECT}.conf."
|
||||
fi
|
||||
|
||||
# TODO: Make sure you're in the right directory, or, even better, be independent from the working directory.
|
||||
|
||||
log INFO "Checking ssl cert for accessing bridgehead via https"
|
||||
|
||||
if [ ! -d "/etc/bridgehead/traefik-tls" ]; then
|
||||
log WARN "TLS certs for accessing bridgehead via https missing, we'll now create a self-signed one. Please consider getting an officially signed one (e.g. via Let's Encrypt ...) and put into /etc/bridgehead/traefik-tls"
|
||||
mkdir -p /etc/bridgehead/traefik-tls
|
||||
fi
|
||||
|
||||
if [ ! -e "/etc/bridgehead/traefik-tls/fullchain.pem" ]; then
|
||||
openssl req -x509 -newkey rsa:4096 -nodes -keyout /etc/bridgehead/traefik-tls/privkey.pem -out /etc/bridgehead/traefik-tls/fullchain.pem -days 3650 -subj "/CN=$HOST"
|
||||
fi
|
||||
|
||||
if [ -e /etc/bridgehead/vault.conf ]; then
|
||||
if [ "$(stat -c "%a %U" /etc/bridgehead/vault.conf)" != "600 bridgehead" ]; then
|
||||
fail_and_report 1 "/etc/bridgehead/vault.conf has wrong owner/permissions. To correct this issue, run chmod 600 /etc/bridgehead/vault.conf && chown bridgehead /etc/bridgehead/vault.conf."
|
||||
fi
|
||||
fi
|
||||
|
||||
checkPrivKey() {
|
||||
if [ -e /etc/bridgehead/pki/${SITE_ID}.priv.pem ]; then
|
||||
log INFO "Success - private key found."
|
||||
else
|
||||
log ERROR "Unable to find private key at /etc/bridgehead/pki/${SITE_ID}.priv.pem. To fix, please run\n bridgehead enroll ${PROJECT}\nand follow the instructions."
|
||||
return 1
|
||||
fi
|
||||
log INFO "Success - all prerequisites are met!"
|
||||
hc_send log "Success - all prerequisites are met!"
|
||||
return 0
|
||||
}
|
||||
|
||||
if [[ "$@" =~ "noprivkey" ]]; then
|
||||
log INFO "Skipping check for private key for now."
|
||||
else
|
||||
checkPrivKey || exit 1
|
||||
fi
|
||||
|
||||
exit 0
|
|
@ -0,0 +1,12 @@
|
|||
[Unit]
|
||||
Description=Bridgehead (%i) Update Service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=bridgehead
|
||||
ExecStartPre=-/srv/docker/bridgehead/bridgehead preUpdate %i
|
||||
ExecStart=/srv/docker/bridgehead/bridgehead update %i
|
||||
ExecStopPost=-/srv/docker/bridgehead/bridgehead postUpdate %i
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,8 @@
|
|||
[Unit]
|
||||
Description=Hourly Updates of Bridgehead (%i)
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* *:00:00
|
||||
|
||||
[Install]
|
||||
WantedBy=basic.target
|
|
@ -0,0 +1,15 @@
|
|||
[Unit]
|
||||
Description=Bridgehead (%i)
|
||||
Requires=docker.service
|
||||
|
||||
[Service]
|
||||
User=bridgehead
|
||||
Restart=always
|
||||
RestartSec=30
|
||||
ExecStartPre=-/srv/docker/bridgehead/bridgehead preRun %i
|
||||
ExecStart=/srv/docker/bridgehead/bridgehead start %i
|
||||
ExecStop=/srv/docker/bridgehead/bridgehead stop %i
|
||||
ExecStopPost=-/srv/docker/bridgehead/bridgehead postRun %i
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -0,0 +1,6 @@
|
|||
tls:
|
||||
stores:
|
||||
default:
|
||||
defaultCertificate:
|
||||
certFile: /certs/fullchain.pem
|
||||
keyFile: /certs/privkey.pem
|
|
@ -0,0 +1,24 @@
|
|||
#!/bin/bash -e
|
||||
|
||||
source lib/functions.sh
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
log "ERROR" "Please provide a Project as argument"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export PROJECT=$1
|
||||
|
||||
#checkRequirements // not needed when uninstalling
|
||||
|
||||
log INFO "Removing bridgehead sudoers permissions."
|
||||
|
||||
rm -vf /etc/sudoers.d/bridgehead-${PROJECT}
|
||||
|
||||
log "INFO" "Stopping system units and removing bridgehead for ${PROJECT} ..."
|
||||
|
||||
systemctl disable --now bridgehead@${PROJECT}.service bridgehead-update@${PROJECT}.timer bridgehead-update@${PROJECT}.service
|
||||
|
||||
rm -v /etc/systemd/system/{bridgehead\@.service,bridgehead-update\@.timer,bridgehead-update\@.service}
|
||||
|
||||
log "INFO" "Successfully removed bridgehead for ${PROJECT} from your system"
|
|
@ -0,0 +1,109 @@
|
|||
#!/bin/bash
|
||||
source lib/functions.sh
|
||||
|
||||
AUTO_HOUSEKEEPING=${AUTO_HOUSEKEEPING:-true}
|
||||
|
||||
if [ "$AUTO_HOUSEKEEPING" == "true" ]; then
|
||||
A="Performing automatic maintenance: Cleaning docker images."
|
||||
hc_send log "$A"
|
||||
log INFO "$A"
|
||||
docker system prune -a -f
|
||||
else
|
||||
log WARN "Automatic housekeeping disabled (variable AUTO_HOUSEKEEPING != \"true\")"
|
||||
fi
|
||||
|
||||
hc_send log "Checking for bridgehead updates ..."
|
||||
|
||||
CONFFILE=/etc/bridgehead/$1.conf
|
||||
|
||||
if [ ! -e $CONFFILE ]; then
|
||||
fail_and_report 1 "Configuration file $CONFFILE not found."
|
||||
fi
|
||||
|
||||
source $CONFFILE
|
||||
|
||||
assertVarsNotEmpty SITE_ID || fail_and_report 1 "Update failed: SITE_ID empty"
|
||||
export SITE_ID
|
||||
|
||||
checkOwner . bridgehead || fail_and_report 1 "Update failed: Wrong permissions in $(pwd)"
|
||||
checkOwner /etc/bridgehead bridgehead || fail_and_report 1 "Update failed: Wrong permissions in /etc/bridgehead"
|
||||
|
||||
CREDHELPER="/srv/docker/bridgehead/lib/gitpassword.sh"
|
||||
|
||||
CHANGES=""
|
||||
|
||||
# Check git updates
|
||||
git_updated="false"
|
||||
for DIR in /etc/bridgehead $(pwd); do
|
||||
log "INFO" "Checking for updates to git repo $DIR ..."
|
||||
OUT="$(git -C $DIR status --porcelain)"
|
||||
if [ -n "$OUT" ]; then
|
||||
log WARN "The working directory $DIR is modified. Changed files: $OUT"
|
||||
report_error log "The working directory $DIR is modified. Changed files: $OUT"
|
||||
fi
|
||||
if [ "$(git -C $DIR config --get credential.helper)" != "$CREDHELPER" ]; then
|
||||
log "INFO" "Configuring repo to use bridgehead git credential helper."
|
||||
git -C $DIR config credential.helper "$CREDHELPER"
|
||||
fi
|
||||
old_git_hash="$(git -C $DIR rev-parse --verify HEAD)"
|
||||
if [ -z "$HTTP_PROXY_URL" ]; then
|
||||
log "INFO" "Git is using no proxy!"
|
||||
OUT=$(git -C $DIR fetch 2>&1 && git -C $DIR pull 2>&1)
|
||||
else
|
||||
log "INFO" "Git is using proxy ${HTTP_PROXY_URL} from ${CONFFILE}"
|
||||
OUT=$(git -c http.proxy=$HTTP_PROXY_URL -c https.proxy=$HTTPS_PROXY_URL -C $DIR fetch 2>&1 && git -c http.proxy=$HTTP_PROXY_URL -c https.proxy=$HTTPS_PROXY_URL -C $DIR pull 2>&1)
|
||||
fi
|
||||
if [ $? -ne 0 ]; then
|
||||
report_error log "Unable to update git $DIR: $OUT"
|
||||
fi
|
||||
|
||||
new_git_hash="$(git -C $DIR rev-parse --verify HEAD)"
|
||||
if [ "$old_git_hash" != "$new_git_hash" ]; then
|
||||
CHANGE="Updated git repository in ${DIR} from commit $old_git_hash to $new_git_hash"
|
||||
CHANGES+="- $CHANGE\n"
|
||||
log "INFO" "$CHANGE"
|
||||
# NOTE: Link generation doesn't work on repositories placed at an self-hosted instance of bitbucket.
|
||||
# See: https://community.atlassian.com/t5/Bitbucket-questions/BitBucket-4-14-diff-between-any-two-commits/qaq-p/632974
|
||||
git_repository_url="$(git -C $DIR remote get-url origin)"
|
||||
git_repository_url=${git_repository_url/.git/}
|
||||
if [ "$( echo $git_repository_url | grep "github.com")" ]; then
|
||||
# Ensure web link even if ssh is used
|
||||
git_repository_url="${git_repository_url/git@github.com/https:\/\/github.com\/}"
|
||||
log "INFO" "You can review all changes on the repository with $git_repository_url/compare/$old_git_hash...$new_git_hash"
|
||||
elif [ "$( echo $git_repository_url | grep "git.verbis.dkfz.de")" ]; then
|
||||
git_repository_url="${git_repository_url/ssh:\/\/git@git.verbis.dkfz.de/https:\/\/git.verbis.dkfz.de\/}"
|
||||
git_repository_url="https://$(echo $git_repository_url | awk -F '@' '{print $2}')"
|
||||
log "INFO" "You can review all changes on the repository with $git_repository_url/compare?from=$old_git_hash&to=$new_git_hash"
|
||||
fi
|
||||
git_updated="true"
|
||||
fi
|
||||
done
|
||||
|
||||
# Check docker updates
|
||||
log "INFO" "Checking for updates to running docker images ..."
|
||||
docker_updated="false"
|
||||
for IMAGE in $(cat $PROJECT/docker-compose.yml | grep -v "^#" | grep "image:" | sed -e 's_^.*image: \(.*\).*$_\1_g; s_\"__g'); do
|
||||
log "INFO" "Checking for Updates of Image: $IMAGE"
|
||||
if docker pull $IMAGE | grep "Downloaded newer image"; then
|
||||
CHANGE="Image $IMAGE updated."
|
||||
CHANGES+="- $CHANGE\n"
|
||||
log "INFO" "$CHANGE"
|
||||
docker_updated="true"
|
||||
fi
|
||||
done
|
||||
|
||||
# If anything is updated, restart service
|
||||
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
|
||||
else
|
||||
RES="Nothing updated, nothing to restart."
|
||||
log "INFO" "$RES"
|
||||
hc_send log "$RES"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
||||
# TODO: Print last commit explicit
|
Loading…
Reference in New Issue