#!/bin/sh set -eu ############################################################################### # OpenSlides portable auf Ubuntu 24.04 LTS # - Binary und App unter /usr/ # - Konfiguration und Secrets unter /etc/ # - lokales HTTPS mit selbstsigniertem Zertifikat # - Mail-Konfiguration per Abfrage # - systemd-Wrapper für automatischen Start # - "latest" wird beim Download auf eine konkrete Version aufgelöst # und danach in der Konfiguration fest eingetragen ############################################################################### ############################################################################### # 1) Hilfsfunktionen ############################################################################### log() { printf '\n[%s] %s\n' "$(date '+%F %T')" "$*" } need_cmd() { command -v "$1" >/dev/null 2>&1 || { echo "Fehlt: $1" >&2 exit 1 } } ask() { prompt="$1" default="${2:-}" if [ -n "$default" ]; then printf "%s [%s]: " "$prompt" "$default" >&2 else printf "%s: " "$prompt" >&2 fi IFS= read -r value if [ -z "$value" ]; then value="$default" fi printf "%s" "$value" } ask_required() { while :; do value="$(ask "$1" "${2:-}")" if [ -n "$value" ]; then printf "%s" "$value" return 0 fi echo "Dieser Wert wird benötigt." >&2 done } ask_secret() { prompt="$1" while :; do printf "%s: " "$prompt" >&2 stty -echo IFS= read -r value stty echo printf "\n" >&2 if [ -n "$value" ]; then printf "%s" "$value" return 0 fi echo "Dieser Wert wird benötigt." >&2 done } ask_yes_no() { default="${2:-true}" while :; do reply="$(ask "$1 (true/false)" "$default")" case "$reply" in true|false) printf "%s" "$reply" return 0 ;; esac echo "Bitte true oder false eingeben." >&2 done } ############################################################################### # 2) Interaktive Abfrage ############################################################################### echo echo "OpenSlides portable – interaktive Einrichtung" echo PATH_PREFIX="$(ask_required "Pfad-Präfix unter /usr und /etc" "terruhn.it")" OS_VERSION_REQUESTED="$(ask_required "OpenSlides-Version oder latest" "latest")" INSTANCE_NAME="$(ask_required "Instanzname" "laptop-local")" OPENSLIDES_HOST="$(ask_required "Bind-Adresse" "0.0.0.0")" OPENSLIDES_PORT="$(ask_required "Port" "8000")" COMPOSE_PROJECT_NAME="$(ask_required "COMPOSE_PROJECT_NAME" "openslides")" ENABLE_LOCAL_HTTPS="$(ask_yes_no "Lokales selbstsigniertes HTTPS aktivieren" "true")" ENABLE_AUTO_HTTPS="$(ask_yes_no "Automatisches HTTPS / ACME aktivieren" "false")" USE_EMAIL="$(ask_yes_no "E-Mail-Versand konfigurieren" "true")" EMAIL_HOST="" EMAIL_PORT="" EMAIL_HOST_USER="" EMAIL_HOST_PASSWORD="" EMAIL_CONNECTION_SECURITY="" EMAIL_TIMEOUT="" EMAIL_ACCEPT_SELF_SIGNED_CERTIFICATE="" DEFAULT_FROM_EMAIL="" if [ "$USE_EMAIL" = "true" ]; then EMAIL_HOST="$(ask_required "SMTP-Host" "w014178e.kasserver.com")" EMAIL_PORT="$(ask_required "SMTP-Port" "587")" EMAIL_HOST_USER="$(ask_required "SMTP-Benutzer" "")" EMAIL_HOST_PASSWORD="$(ask_secret "SMTP-Passwort")" EMAIL_CONNECTION_SECURITY="$(ask_required "SMTP-Sicherheit (STARTTLS|SSL/TLS|NONE)" "STARTTLS")" EMAIL_TIMEOUT="$(ask_required "SMTP-Timeout in Sekunden" "5")" EMAIL_ACCEPT_SELF_SIGNED_CERTIFICATE="$(ask_yes_no "Selbstsignierte SMTP-Zertifikate akzeptieren" "false")" DEFAULT_FROM_EMAIL="$(ask_required "Absenderadresse" "")" fi ############################################################################### # 3) Abgeleitete Pfade ############################################################################### BASE_USR="/usr/${PATH_PREFIX}" BASE_ETC="/etc/${PATH_PREFIX}" BIN_DIR="${BASE_USR}/bin" SBIN_DIR="${BASE_USR}/sbin" LIB_DIR="${BASE_USR}/lib/openslides/${INSTANCE_NAME}" CONFIG_DIR="${BASE_ETC}/config" CRED_DIR="${BASE_ETC}/credentials" OPENSLIDES_BIN="${BIN_DIR}/openslides" CONFIG_FILE="${CONFIG_DIR}/openslides-${INSTANCE_NAME}.yml" ENV_FILE="${CRED_DIR}/openslides-${INSTANCE_NAME}.env" ENV_LINK="${LIB_DIR}/.env" WRAPPER_SCRIPT="${SBIN_DIR}/openslides-${INSTANCE_NAME}.sh" SYSTEMD_UNIT="/etc/systemd/system/openslides-${INSTANCE_NAME}.service" OS_VERSION="" ############################################################################### # 4) Zusammenfassung vor Ausführung ############################################################################### echo echo "Zusammenfassung" echo " Pfad-Präfix: ${PATH_PREFIX}" echo " Angefragt: ${OS_VERSION_REQUESTED}" echo " Instanzname: ${INSTANCE_NAME}" echo " Host: ${OPENSLIDES_HOST}" echo " Port: ${OPENSLIDES_PORT}" echo " Compose-Projektname: ${COMPOSE_PROJECT_NAME}" echo " Local HTTPS: ${ENABLE_LOCAL_HTTPS}" echo " Auto HTTPS: ${ENABLE_AUTO_HTTPS}" echo " E-Mail: ${USE_EMAIL}" echo echo " Binary: ${OPENSLIDES_BIN}" echo " Instanz: ${LIB_DIR}" echo " Config: ${CONFIG_FILE}" echo " Credentials: ${ENV_FILE}" echo CONFIRM="$(ask_required "Fortfahren mit diesen Werten? (ja/nein)" "ja")" case "$CONFIRM" in ja|j|yes|y) ;; *) echo "Abbruch." exit 0 ;; esac ############################################################################### # 5) Verzeichnisse vorbereiten ############################################################################### log "Verzeichnisse anlegen" mkdir -p "${BIN_DIR}" mkdir -p "${SBIN_DIR}" mkdir -p "${LIB_DIR}" mkdir -p "${CONFIG_DIR}" mkdir -p "${CRED_DIR}" chmod 700 "${CRED_DIR}" ############################################################################### # 6) Grundpakete und Docker bereitstellen ############################################################################### log "Grundpakete prüfen" apt update apt install -y ca-certificates curl gnupg lsb-release sed if ! command -v docker >/dev/null 2>&1; then log "Docker ist noch nicht installiert, Installation vorbereiten" install -m 0755 -d /etc/apt/keyrings if [ ! -f /etc/apt/keyrings/docker.asc ]; then curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc chmod a+r /etc/apt/keyrings/docker.asc fi echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ > /etc/apt/sources.list.d/docker.list apt update apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin fi log "Docker-Dienst aktivieren" systemctl enable --now docker need_cmd docker need_cmd curl need_cmd sed if ! command -v docker-compose >/dev/null 2>&1; then log "docker-compose Wrapper anlegen" cat > /usr/local/bin/docker-compose <<'EOF' #!/bin/sh exec docker compose "$@" EOF chmod 0755 /usr/local/bin/docker-compose fi need_cmd docker-compose ############################################################################### # 7) OpenSlides-Binary laden und konkrete Version ermitteln ############################################################################### log "OpenSlides-Binary herunterladen" if [ "${OS_VERSION_REQUESTED}" = "latest" ]; then EFFECTIVE_URL="$(curl -fsSL -o "${OPENSLIDES_BIN}" -w '%{url_effective}' \ "https://github.com/OpenSlides/openslides-manage-service/releases/download/latest/openslides")" OS_VERSION="$(printf '%s\n' "${EFFECTIVE_URL}" | sed -n 's#.*/releases/download/\([^/]*\)/openslides#\1#p')" if [ -z "${OS_VERSION}" ] || [ "${OS_VERSION}" = "latest" ]; then echo "Konnte konkrete OpenSlides-Version aus latest-Download nicht ermitteln." >&2 exit 1 fi else curl -fL \ "https://github.com/OpenSlides/openslides-manage-service/releases/download/${OS_VERSION_REQUESTED}/openslides" \ -o "${OPENSLIDES_BIN}" OS_VERSION="${OS_VERSION_REQUESTED}" fi chmod 0755 "${OPENSLIDES_BIN}" ln -sf "${OPENSLIDES_BIN}" /usr/local/bin/openslides need_cmd openslides ############################################################################### # 8) Config-Datei schreiben ############################################################################### log "OpenSlides-Konfiguration schreiben: ${CONFIG_FILE}" if [ "$USE_EMAIL" = "true" ]; then cat > "${CONFIG_FILE}" < "${CONFIG_FILE}" < "${ENV_FILE}" < "${ENV_FILE}" < "${WRAPPER_SCRIPT}" <&2 exit 1 ;; esac EOF chmod 0755 "${WRAPPER_SCRIPT}" ############################################################################### # 13) systemd-Unit schreiben ############################################################################### log "systemd-Unit schreiben: ${SYSTEMD_UNIT}" cat > "${SYSTEMD_UNIT}" <:${OPENSLIDES_PORT}" echo echo "Hinweis:" echo " Beim selbstsignierten Zertifikat erscheint zunächst eine Browserwarnung."