blob: 87f1d01a913ac32e044f31bafeee6fb60495c72e [file]
#!/usr/bin/env bash
#
# Install the GitHub mirror package on the Jenkins controller.
set -euo pipefail
SCRIPT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
PACKAGE_ROOT=$(cd "${SCRIPT_DIR}/.." && pwd)
INSTALL_ROOT=${INSTALL_ROOT:-/opt/github-mirror}
MIRROR_ROOT=${MIRROR_ROOT:-/home/mirror}
MIRROR_USER=${MIRROR_USER:-gitdaemon}
MIRROR_GROUP=${MIRROR_GROUP:-nogroup}
CONFIG_DIR=${CONFIG_DIR:-${INSTALL_ROOT}/config}
ENV_FILE=${ENV_FILE:-${CONFIG_DIR}/github-mirror-webhook.env}
COMPOSE_ENV_FILE=${COMPOSE_ENV_FILE:-${INSTALL_ROOT}/.env}
APT_INSTALL=${APT_INSTALL:-1}
START_COMPOSE=${START_COMPOSE:-auto}
START_FALLBACK_TIMER=${START_FALLBACK_TIMER:-1}
INIT_MIRRORS=${INIT_MIRRORS:-1}
BUILD_IMAGES=${BUILD_IMAGES:-1}
usage() {
cat <<'EOF'
Usage:
sudo github-mirror/bin/install-controller.sh
Environment:
INSTALL_ROOT Installed package/config path. Default: /opt/github-mirror
MIRROR_ROOT Mirror root. Default: /home/mirror
MIRROR_USER Mirror owner/service user. Default: gitdaemon
MIRROR_GROUP Mirror group. Default: nogroup
CONFIG_DIR Config directory. Default: $INSTALL_ROOT/config
ENV_FILE Webhook env file. Default: $CONFIG_DIR/github-mirror-webhook.env
APT_INSTALL Install required apt packages when set to 1. Default: 1
INIT_MIRRORS Run init-mirrors.sh after install when set to 1. Default: 1
BUILD_IMAGES Build docker-compose images when set to 1. Default: 1
START_COMPOSE auto, 1, or 0. Default: auto
START_FALLBACK_TIMER
Enable/start the systemd fallback timer when set to 1. Default: 1
EOF
}
log() {
printf '%s\n' "$*" >&2
}
die() {
log "error: $*"
exit 1
}
render_template() {
local src=$1
local dst=$2
sed \
-e "s#@INSTALL_ROOT@#${INSTALL_ROOT}#g" \
-e "s#@MIRROR_ROOT@#${MIRROR_ROOT}#g" \
-e "s#@MIRROR_USER@#${MIRROR_USER}#g" \
-e "s#@MIRROR_GROUP@#${MIRROR_GROUP}#g" \
"${src}" > "${dst}"
}
secret_is_configured() {
[ -f "${ENV_FILE}" ] &&
grep -q '^GITHUB_WEBHOOK_SECRET=' "${ENV_FILE}" &&
! grep -q '^GITHUB_WEBHOOK_SECRET=CHANGE_ME' "${ENV_FILE}"
}
copy_if_present() {
local src=$1
local dst=$2
if [ -e "${src}" ] || [ -L "${src}" ]; then
cp -a "${src}" "${dst}"
return 0
fi
return 1
}
if [ $# -gt 0 ]; then
case "$1" in
-h|--help)
usage
exit 0
;;
*)
die "unknown argument: $1"
;;
esac
fi
[ "$(id -u)" -eq 0 ] || die "run as root"
if [ "${APT_INSTALL}" = "1" ]; then
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y \
git \
git-daemon-sysvinit \
docker.io \
docker-compose \
python3 \
rsync \
util-linux
fi
if ! id "${MIRROR_USER}" >/dev/null 2>&1; then
useradd --system --home-dir /home/gitdaemon --shell /usr/sbin/nologin "${MIRROR_USER}"
fi
if ! getent group "${MIRROR_GROUP}" >/dev/null 2>&1; then
die "group ${MIRROR_GROUP} does not exist"
fi
install -d -o root -g root -m 0755 "$(dirname "${INSTALL_ROOT}")"
rm -rf "${INSTALL_ROOT}.new"
install -d -o root -g root -m 0755 "${INSTALL_ROOT}.new"
cp -a "${PACKAGE_ROOT}/." "${INSTALL_ROOT}.new/"
find "${INSTALL_ROOT}.new/bin" -type f -name '*.sh' -exec chmod 0755 {} +
find "${INSTALL_ROOT}.new/bin" -type f -name '*.py' -exec chmod 0755 {} +
install -d -o root -g root -m 0700 "${INSTALL_ROOT}.new/config"
if ! copy_if_present "${ENV_FILE}" "${INSTALL_ROOT}.new/config/github-mirror-webhook.env"; then
# Migrate the pre-Compose secret location if this is an existing controller.
copy_if_present /etc/trafficserver-github-mirror/github-mirror-webhook.env \
"${INSTALL_ROOT}.new/config/github-mirror-webhook.env" || \
install -o root -g root -m 0600 \
"${INSTALL_ROOT}.new/config/github-mirror-webhook.env.example" \
"${INSTALL_ROOT}.new/config/github-mirror-webhook.env"
log "created ${INSTALL_ROOT}.new/config/github-mirror-webhook.env; set GITHUB_WEBHOOK_SECRET before starting webhook deliveries"
fi
if ! copy_if_present "${CONFIG_DIR}/git-daemon.default" "${INSTALL_ROOT}.new/config/git-daemon.default"; then
if [ -f /etc/default/git-daemon ] && [ ! -L /etc/default/git-daemon ]; then
copy_if_present /etc/default/git-daemon "${INSTALL_ROOT}.new/config/git-daemon.default" || true
fi
fi
rm -rf "${INSTALL_ROOT}"
mv "${INSTALL_ROOT}.new" "${INSTALL_ROOT}"
chown -R root:root "${INSTALL_ROOT}"
chmod 0700 "${CONFIG_DIR}"
chmod 0600 "${ENV_FILE}"
mirror_uid=$(id -u "${MIRROR_USER}")
mirror_gid=$(getent group "${MIRROR_GROUP}" | awk -F: '{ print $3 }')
cat > "${COMPOSE_ENV_FILE}" <<EOF
MIRROR_ROOT=${MIRROR_ROOT}
MIRROR_UID=${mirror_uid}
MIRROR_GID=${mirror_gid}
EOF
chmod 0644 "${COMPOSE_ENV_FILE}"
install -d -o "${MIRROR_USER}" -g "${MIRROR_GROUP}" -m 0755 "${MIRROR_ROOT}"
install -d -o "${MIRROR_USER}" -g "${MIRROR_GROUP}" -m 0755 "${MIRROR_ROOT}/.locks"
install -d -o root -g root -m 0755 /var/log/github-mirror-smart-http
ln -sfn "${INSTALL_ROOT}/config/git-daemon.default" /etc/default/git-daemon
# Remove legacy units from the pre-Compose implementation.
systemctl disable --now github-mirror-webhook.service >/dev/null 2>&1 || true
systemctl disable --now github-mirror-smart-http.service >/dev/null 2>&1 || true
rm -f /etc/systemd/system/github-mirror-webhook.service
rm -f /etc/systemd/system/github-mirror-smart-http.service
tmp_unit=$(mktemp)
render_template "${INSTALL_ROOT}/systemd/github-mirror.service" "${tmp_unit}"
install -o root -g root -m 0644 "${tmp_unit}" /etc/systemd/system/github-mirror.service
render_template "${INSTALL_ROOT}/systemd/github-mirror-fallback.service" "${tmp_unit}"
install -o root -g root -m 0644 "${tmp_unit}" /etc/systemd/system/github-mirror-fallback.service
render_template "${INSTALL_ROOT}/systemd/github-mirror-fallback.timer" "${tmp_unit}"
install -o root -g root -m 0644 "${tmp_unit}" /etc/systemd/system/github-mirror-fallback.timer
rm -f "${tmp_unit}"
systemctl daemon-reload
systemctl enable git-daemon.service >/dev/null 2>&1 || true
systemctl restart git-daemon.service >/dev/null 2>&1 || service git-daemon restart
if [ "${INIT_MIRRORS}" = "1" ]; then
MIRROR_ROOT="${MIRROR_ROOT}" MIRROR_USER="${MIRROR_USER}" MIRROR_GROUP="${MIRROR_GROUP}" \
"${INSTALL_ROOT}/bin/init-mirrors.sh"
fi
if [ "${BUILD_IMAGES}" = "1" ]; then
(cd "${INSTALL_ROOT}" && docker-compose build github-mirror github-mirror-smart-http)
fi
systemctl enable github-mirror.service
if [ "${START_FALLBACK_TIMER}" = "1" ]; then
systemctl enable --now github-mirror-fallback.timer
else
systemctl disable --now github-mirror-fallback.timer >/dev/null 2>&1 || true
fi
if [ "${START_COMPOSE}" = "1" ] ||
{ [ "${START_COMPOSE}" = "auto" ] && secret_is_configured; }; then
systemctl restart github-mirror.service
else
log "compose stack installed but not started; configure ${ENV_FILE}, then run:"
log " sudo systemctl enable --now github-mirror.service"
fi
log "install complete"