Merge branch 'main' into checkClockSync

This commit is contained in:
Martin Lablans
2023-07-28 13:28:18 +02:00
committed by GitHub
44 changed files with 1426 additions and 963 deletions

View File

@ -1,10 +0,0 @@
#!/bin/bash -e
source lib/functions.sh
log "INFO" "This script add's a user with password to the bridghead"
read -p 'Username: ' bc_user
read -sp 'Password: ' bc_password
log "INFO" "\nPlease export the line in the your environment. Please replace the dollar signs with with \\\$"
docker run --rm -it httpd:latest htpasswd -nb $bc_user $bc_password

109
lib/functions.sh Executable file → Normal file
View File

@ -1,9 +1,26 @@
#!/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 docker.verbis.dkfz.de/cache/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"
exit 1
fail_and_report 1 "Please run as root"
fi
}
@ -16,19 +33,15 @@ checkOwner(){
return 0
}
log() {
echo -e "$(date +'%Y-%m-%d %T')" "$1:" "$2"
}
printUsage() {
echo "Usage: bridgehead start|stop|update|install|uninstall PROJECTNAME"
echo "PROJECTNAME should be one of ccp|nngm|gbn"
echo "Usage: bridgehead start|stop|is-running|update|install|uninstall|enroll PROJECTNAME"
echo "PROJECTNAME should be one of ccp|bbmri"
}
checkRequirements() {
if ! lib/prerequisites.sh; then
if ! lib/prerequisites.sh $@; then
log "ERROR" "Validating Prerequisites failed, please fix the error(s) above this line."
exit 1
fail_and_report 1 "Validating prerequisites failed."
else
return 0
fi
@ -97,10 +110,76 @@ assertVarsNotEmpty() {
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 | tr "[:upper:]" "[:lower:]")
log DEBUG "Using auto-detected hostname $HOST."
fi
}
# Takes 1) The Backup Directory Path 2) The name of the Service to be backuped
# Creates 3 Backups: 1) For the past seven days 2) For the current month and 3) for each calendar week
createEncryptedPostgresBackup(){
docker exec "$2" bash -c 'pg_dump -U $POSTGRES_USER $POSTGRES_DB --format=p --no-owner --no-privileges' | \
# TODO: Encrypt using /etc/bridgehead/pki/${SITE_ID}.priv.pem | \
tee "$1/$2/$(date +Last-%A).sql" | \
tee "$1/$2/$(date +%Y-%m).sql" > \
"$1/$2/$(date +%Y-KW%V).sql"
}
# from: https://gist.github.com/sj26/88e1c6584397bb7c13bd11108a579746
# ex. use: retry 5 /bin/false
function retry {
local retries=$1
shift
local count=0
until "$@"; do
exit=$?
wait=$((2 ** $count))
count=$(($count + 1))
if [ $count -lt $retries ]; then
echo "Retry $count/$retries exited with code $exit, retrying in $wait seconds..."
sleep $wait
else
echo "Retry $count/$retries exited with code $exit, giving up."
return $exit
fi
done
return 0
}
function bk_is_running {
detectCompose
RUNNING="$($COMPOSE -p $PROJECT -f minimal/docker-compose.yml -f ./$PROJECT/docker-compose.yml $OVERRIDE ps -q)"
NUMBEROFRUNNING=$(echo "$RUNNING" | wc -l)
if [ $NUMBEROFRUNNING -ge 2 ]; then
return 0
else
return 1
fi
}
##Setting Network properties
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}');
export HOST=$(hostname)
export PRODUCTION="false";
if [ "$(git branch --show-current)" == "main" ]; then
export PRODUCTION="true";
fi
# 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}');

View File

@ -1,116 +0,0 @@
#!/bin/bash
if [ ! -d ./landing ]
then
mkdir landing
fi
if [ ! -f ./landing/index.html ]
then
touch index.html
fi
CENTRAL_SERVICES=" <tr>
<td>CCP-IT</td>
<td><a href=\"https://monitor.vmitro.de/icingaweb2/dashboard\">Monitoring Service</td>
</tr>"
LOCAL_SERVICES=" <tr>
<td>Bridgehead</td>
<td>Reverse Proxy <a href=\"http://${HOST}:8080/\">Traefik</a></td>
</tr>"
if [ "$project" = "dktk" ] || [ "$project" = "c4" ] || [ "$project" = "dktk-fed" ]
then
CENTRAL_SERVICES+=" <tr>
<td>CCP-IT</td>
<td><a href=\"https://patientlist.ccp-it.dktk.dkfz.de\">Zentrale Patientenliste</td>
</tr>
<tr>
<td>CCP-IT</td>
<td><a href=\"https://decentralsearch.ccp-it.dktk.dkfz.de\">Dezentrale Suche</td>
</tr>
<tr>
<td>CCP-IT</td>
<td><a href=\"https://centralsearch.ccp-it.dktk.dkfz.de\">Zentrale Suche</td>
</tr>
<tr>
<td>CCP-IT</td>
<td><a href=\"https://deployment.ccp-it.dktk.dkfz.de\">Deployment-Server</td>
</tr>
<tr>
<td>CCP-IT</td>
<td><a href=\"https://dktk-kne.kgu.de\">Zentraler Kontrollnummernerzeuger</td>
</tr>
"
fi
if [ "$project" = "dktk-fed" ]
then
LOCAL_SERVICES+=" <tr>
<td>DKTK</td>
<td><a href=\"https://${HOST}/dktk-localdatamanagement/fhir/\">Blaze</a></td>
</tr>
"
fi
cat > ./landing/index.html <<EOL
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<title>Bridgehead Overview</title>
<!-- Bootstrap core CSS -->
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"
integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossorigin="anonymous"></script>
</head>
<body class="d-flex flex-column min-vh-100">
<nav class="navbar navbar-light" style="background-color: #aad7f6;">
<h2 class="pb-2 border-bottom">Bridgehead ${site_name}</h2>
</nav>
<div class="container px-4 py-5" id="featured-3">
<div>
<h2>Components</h2>
<h3>Central</h3>
<table class="table">
<thead class="thead-dark">
<tr>
<th style="width: 50%">Group</th>
<th style="width: 50%">Service</th>
</tr>
</thead>
<tbody>
${CENTRAL_SERVICES}
</tbody>
</table>
</div>
<div>
<h3>Local</h3>
<table class="table">
<thead class="thead-dark">
<tr>
<th style="width: 50%">Project</th>
<th style="width: 50%">Services</th>
</tr>
</thead>
<tbody>
${LOCAL_SERVICES}
</tbody>
</table>
</div>
<footer class="footer mt-auto py-3">
<a href="https://dktk.dkfz.de/"><img src="https://www.oncoray.de/fileadmin/files/bilder_gruppen/DKTK/Logo_DKTK_neu_2016.jpg" style="max-width: 30%; height: auto;"></a> DKTK 2022<span style="float: right;"><a href="https://github.com/samply/bridgehead"><button type="button" class="btn btn-primary">Documentaion</button></a></span>
</footer>
</body>
</html>
EOL

View File

@ -22,7 +22,7 @@ cd $BASE
source lib/functions.sh
assertVarsNotEmpty SITE_ID || exit 1
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')
@ -30,8 +30,7 @@ GITHOST=$(echo "$PARAMS" | grep "^host=" | sed 's/host=\(.*\)/\1/g')
fetchVarsFromVault GIT_PASSWORD
if [ -z "${GIT_PASSWORD}" ]; then
log ERROR "Git password not found."
exit 1
fail_and_report 1 "gitpassword.sh failed: Git password not found."
fi
cat <<EOF

66
lib/install-bridgehead.sh Executable file
View File

@ -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"

7
lib/log.sh Normal file
View File

@ -0,0 +1,7 @@
#!/bin/bash
log() {
SEVERITY="$1"
shift
echo -e "$(date +'%Y-%m-%d %T')" "$SEVERITY:" "$@"
}

54
lib/monitoring.sh Executable file
View File

@ -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 --max-time 5 -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 --max-time 5 -A "$USER_AGENT" -s -o /dev/null "$HCURL"/"$1" || log WARN "Monitoring failed: Unable to send data to $HCURL/$1"
fi
}

90
lib/prepare-system.sh Executable file
View File

@ -0,0 +1,90 @@
#!/bin/bash -e
DEV_MODE="${1:-NODEV}"
source lib/log.sh
source lib/functions.sh
log "INFO" "Preparing your system for bridgehead installation ..."
# Check, if running in WSL
if [[ $(grep -i Microsoft /proc/version) ]]; then
# Check, if systemd is available
if [ "$(systemctl is-system-running)" = "offline" ]; then
log "ERROR" "It seems you have no active systemd environment in your WSL environment. Please follow the guide in https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/"
exit 1
fi
fi
# 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
set +e
bridgehead_repository_url=$(git remote get-url origin)
if [ $? -ne 0 ]; then
bridgehead_repository_url="https://github.com/samply/bridgehead.git"
fi
set -e
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
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/"
;;
minimal)
site_configuration_repository_middle="git.verbis.dkfz.de/minimal-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
elif [[ "$DEV_MODE" == "NODEV" ]]; then
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
elif [[ "$DEV_MODE" == "DEV" ]]; then
log "INFO" "Now cloning your developer configuration repository for you."
read -p "Please enter your config repository URL: " url
git clone "$url" /etc/bridgehead
fi
chown -R bridgehead /etc/bridgehead /srv/docker/bridgehead
log INFO "System preparation is completed and configuration is present."

View File

@ -2,67 +2,64 @@
source lib/functions.sh
detectCompose
if ! id "bridgehead" &>/dev/null; then
log ERROR "User bridgehead does not exist. Please consult readme for installation."
log ERROR "User bridgehead does not exist. Please run bridgehead install $PROJECT"
exit 1
fi
checkOwner . bridgehead || exit 1
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 docker-compose"
prerequisites="git docker"
for prerequisite in $prerequisites; do
$prerequisite --version 2>&1
is_available=$?
if [ $is_available -gt 0 ]; then
log "ERROR" "Prerequisite not fulfilled - $prerequisite is not available!"
exit 79
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
log ERROR "/etc/sudoers.d does not exist. Please install sudo package."
exit 1
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
log ERROR "Please set up the config folder at /etc/bridgehead. Instruction are in the readme."
exit 1
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
log ERROR "Project config not found. Please copy the template from ${PROJECT} and put it under /etc/bridgehead-config/${PROJECT}.conf."
exit 1
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"
log INFO "Checking ssl cert for accessing bridgehead via https"
if [ ! -d "certs" ]; then
log WARN "TLS cert missing, we'll now create a self-signed one. Please consider getting an officially signed one (e.g. via Let's Encrypt ...)"
mkdir -p certs
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 "certs/traefik.crt" ]; then
openssl req -x509 -newkey rsa:4096 -nodes -keyout certs/traefik.key -out certs/traefik.crt -days 3650 -subj "/CN=$HOST"
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
log ERROR "/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."
exit 1
fi
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
log INFO "Checking network access ($BROKER_URL) ..."
@ -94,6 +91,24 @@ else
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
log INFO "Success - all prerequisites are met!"
exit 0

View File

@ -1,53 +0,0 @@
#!/bin/bash -e
source lib/functions.sh
exitIfNotRoot
if [ $# -eq 0 ]; then
log "ERROR" "Please provide a Project as argument"
exit 1
fi
if [ $1 != "ccp" ] && [ $1 != "nngm" ] && [ $1 != "gbn" ]; then
log "ERROR" "Please provide a supported project like ccp, gbn or nngm"
exit 1
fi
export PROJECT=$1
checkRequirements
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
bridgehead ALL= NOPASSWD: BRIDGEHEAD${PROJECT^^}
EOF
log "INFO" "Register 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
log "INFO" "\nSuccess - now start your bridgehead by running\n systemctl start bridgehead@${PROJECT}.service\n or by rebooting your machine."

View File

@ -4,7 +4,9 @@ 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

View File

@ -6,8 +6,10 @@ Requires=docker.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

View File

@ -1,4 +1,6 @@
tls:
certificates:
- certFile: /certs/traefik.crt
keyFile: /certs/traefik.key
stores:
default:
defaultCertificate:
certFile: /certs/fullchain.pem
keyFile: /certs/privkey.pem

View File

@ -7,11 +7,6 @@ if [ $# -eq 0 ]; then
exit 1
fi
if [ $1 != "ccp" ] && [ $1 != "nngm" ] && [ $1 != "gbn" ]; then
log "ERROR" "Please provide a supported project like ccp, gbn or nngm"
exit 1
fi
export PROJECT=$1
#checkRequirements // not needed when uninstalling

View File

@ -1,26 +1,50 @@
#!/bin/bash
source lib/functions.sh
AUTO_HOUSEKEEPING=${AUTO_HOUSEKEEPING:-true}
if [ "$AUTO_HOUSEKEEPING" == "true" ]; then
A="Performing automatic maintenance: "
if bk_is_running; then
A="$A Cleaning docker images."
docker system prune -a -f
else
A="$A Not cleaning docker images since BK is not running."
fi
hc_send log "$A"
log INFO "$A"
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
log ERROR "Configuration file $CONFFILE not found."
exit 1
fail_and_report 1 "Configuration file $CONFFILE not found."
fi
source $CONFFILE
assertVarsNotEmpty SITE_ID || exit 1
assertVarsNotEmpty SITE_ID || fail_and_report 1 "Update failed: SITE_ID empty"
export SITE_ID
checkOwner . bridgehead || exit 1
checkOwner /etc/bridgehead bridgehead || exit 1
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
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"
@ -28,17 +52,20 @@ for DIR in /etc/bridgehead $(pwd); do
old_git_hash="$(git -C $DIR rev-parse --verify HEAD)"
if [ -z "$HTTP_PROXY_URL" ]; then
log "INFO" "Git is using no proxy!"
git -C $DIR fetch 2>&1
git -C $DIR pull 2>&1
OUT=$(retry 5 git -C $DIR fetch 2>&1 && retry 5 git -C $DIR pull 2>&1)
else
log "INFO" "Git is using proxy ${HTTP_PROXY_URL} from ${CONFFILE}"
git -c http.proxy=$HTTP_PROXY_URL -c http.proxy=$HTTP_PROXY_URL -C $DIR fetch 2>&1
git -c http.proxy=$HTTP_PROXY_URL -c http.proxy=$HTTP_PROXY_URL -C $DIR pull 2>&1
OUT=$(retry 5 git -c http.proxy=$HTTP_PROXY_URL -c https.proxy=$HTTPS_PROXY_URL -C $DIR fetch 2>&1 && retry 5 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)"
git_updated="false"
if [ "$old_git_hash" != "$new_git_hash" ]; then
log "INFO" "Updated git repository in ${DIR} from commit $old_git_hash to $new_git_hash"
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)"
@ -59,20 +86,57 @@ done
# Check docker updates
log "INFO" "Checking for updates to running docker images ..."
docker_updated="false"
for IMAGE in $(docker ps --filter "name=bridgehead" --format {{.Image}}); do
for IMAGE in $(cat $PROJECT/docker-compose.yml ${OVERRIDE//-f/} minimal/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
log "INFO" "$IMAGE updated."
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
log "INFO" "Update detected, now restarting bridgehead"
RES="Updates detected, now restarting bridgehead:\n$CHANGES"
log "INFO" "$RES"
hc_send log "$RES"
sudo /bin/systemctl restart bridgehead@*.service
else
log "INFO" "Nothing updated, nothing to restart."
RES="Nothing updated, nothing to restart."
log "INFO" "$RES"
hc_send log "$RES"
fi
if [ -n "${BACKUP_DIRECTORY}" ]; then
if [ ! -d "$BACKUP_DIRECTORY" ]; then
message="Performing automatic maintenance: Attempting to create backup directory $BACKUP_DIRECTORY."
hc_send log "$message"
log INFO "$message"
mkdir -p "$BACKUP_DIRECTORY"
chown -R "$BACKUP_DIRECTORY" bridgehead;
fi
checkOwner "$BACKUP_DIRECTORY" bridgehead || fail_and_report 1 "Automatic maintenance failed: Wrong permissions for backup directory $(pwd)"
# Collect all container names that contain '-db'
BACKUP_SERVICES="$(docker ps --filter name=-db --format "{{.Names}}" | tr "\n" "\ ")"
log INFO "Performing automatic maintenance: Creating Backups for $BACKUP_SERVICES";
for service in $BACKUP_SERVICES; do
if [ ! -d "$BACKUP_DIRECTORY/$service" ]; then
message="Performing automatic maintenance: Attempting to create backup directory for $service in $BACKUP_DIRECTORY."
hc_send log "$message"
log INFO "$message"
mkdir -p "$BACKUP_DIRECTORY/$service"
fi
if createEncryptedPostgresBackup "$BACKUP_DIRECTORY" "$service"; then
message="Performing automatic maintenance: Stored encrypted backup for $service in $BACKUP_DIRECTORY."
hc_send log "$message"
log INFO "$message"
else
fail_and_report 5 "Failed to create encrypted update for $service"
fi
done
else
log WARN "Automated backups are disabled (variable AUTO_BACKUPS != \"true\")"
fi
exit 0