From 586198928944b070a4d9692cef874182ca3d7624 Mon Sep 17 00:00:00 2001 From: duffyduck Date: Sun, 20 Sep 2026 21:00:59 +0200 Subject: [PATCH] Restore im neu erstellten Container: fehlende Systemteile nachziehen "omd restore" brach ab mit ERROR: apache user www-data must be member of group cmk Die Ursache liegt nicht im Backup. Beim Anlegen einer Site traegt "omd create" den Apache-Benutzer in die Gruppe der Site ein - das steht in /etc/group, und das liegt im Container, nicht im Bind-Mount. Wird der Container neu erstellt, ist /etc/group wieder der Stand aus dem Abbild, waehrend die Site unveraendert weiterlebt. Der offizielle Entrypoint erkennt das und legt Gruppe und Benutzer neu an, nimmt www-data dabei aber nicht in die Gruppe auf. Im Betrieb faellt es nicht auf: die Site laeuft, die Oberflaeche antwortet. Erst user_verify beim Restore prueft es. Direkt dahinter der zweite Halt: ERROR: fstab entry for /omd/sites/cmk/tmp does not exist omd laesst einen fehlenden /etc/fstab ausdruecklich durchgehen ("seen in some containers") - das Abbild liefert aber eine Datei mit einer Kommentarzeile, also greift die Ausnahme nicht. Beides am Abbild checkmk/check-mk-raw:2.4.0-latest nachgestellt: Site im Bind-Mount anlegen, Container verwerfen, neuen Container mit demselben Mount starten - die Gruppenzugehoerigkeit ist weg und der Restore bricht mit genau dieser Meldung ab. Nach "gpasswd -a www-data cmk" und dem fstab-Eintrag laeuft er durch. container_fix_site_system stellt beides her, vor jedem restore und import (do_restore ist die gemeinsame Stelle) und nach jedem "up", damit auch ein von Hand aufgerufenes omd nicht darueber stolpert. Der Apache-Benutzer und das Kommando zum Eintragen kommen aus share/omd/distro.info - derselben Quelle, aus der omd sie liest, statt "www-data" fest zu verdrahten. Passt schon alles, bleibt die Funktion still. Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 63 ++++++++++++++++++++++++++++++++ README_en.md | 61 +++++++++++++++++++++++++++++++ scripts/cmk-manage.sh | 83 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 207 insertions(+) diff --git a/README.md b/README.md index fa0a8a6..90930db 100644 --- a/README.md +++ b/README.md @@ -2537,6 +2537,67 @@ Ablauf des Skripts: Ein rohes `omd backup`-Archiv (ohne Bundle-Hülle) wird ebenfalls akzeptiert; der Site-Name wird dann aus dem Archiv gelesen. +### 16.1 Warum ein Restore nach dem Neuerstellen des Containers scheiterte + +``` +ERROR: apache user www-data must be member of group cmk +``` + +Beim Anlegen einer Site trägt `omd create` den Apache-Benutzer in die Gruppe +der Site ein. Diese Zugehörigkeit steht in `/etc/group` – und das liegt **im +Container**, nicht im Bind-Mount. Wird der Container neu erstellt (jedes `up` +mit geändertem Image, `podman rm`, ein Update), ist `/etc/group` wieder der +Stand aus dem Abbild, während die Site im Bind-Mount unverändert weiterlebt. + +Der offizielle Entrypoint erkennt diesen Fall und legt Gruppe und Benutzer neu +an – nimmt `www-data` dabei aber **nicht** in die Gruppe auf: + +```bash +if ! getent group "$CMK_SITE_ID" >/dev/null; then + groupadd -g 1000 "$CMK_SITE_ID" +fi +if ! getent passwd "$CMK_SITE_ID" >/dev/null; then + useradd -u 1000 ... -G omd -s /bin/bash "$CMK_SITE_ID" +fi +``` + +Im Betrieb fällt das nicht auf: die Site läuft, die Oberfläche antwortet, der +Agent-Receiver nimmt Daten an. Erst `omd restore --reuse` prüft es +(`user_verify` in `omdlib/users_and_groups.py`) und bricht ab. + +Direkt dahinter wartet der zweite Stolperstein: + +``` +ERROR: fstab entry for /omd/sites/cmk/tmp does not exist +``` + +`omd` lässt einen fehlenden `/etc/fstab` ausdrücklich durchgehen +(*„In case there is no fstab (seen in some containers) assume everything is +OK"*) – im Abbild liegt aber eine Datei mit einer Kommentarzeile. Damit +existiert `/etc/fstab`, die Ausnahme greift nicht, und der Eintrag wird +vermisst. + +Beides ist Zustand des **Containers**, nicht der Daten. `cmk-manage.sh` zieht +es deshalb vor jedem `restore` und `import` nach – und seit demselben Anlass +auch nach jedem `up`, damit ein von Hand aufgerufenes `omd` nicht darüber +stolpert: + +``` +[ INFO ] Apache-Benutzer www-data -> cmk in die Gruppe aufgenommen + (nach dem Neuerstellen des Containers verloren gegangen). +[ INFO ] fstab-Eintrag fuer /omd/sites/cmk/tmp ergaenzt - ohne ihn + verweigert 'omd restore' den Dienst. +``` + +Der Apache-Benutzer und das Kommando zum Eintragen werden dabei aus +`/omd/versions/default/share/omd/distro.info` gelesen – derselben Quelle, aus +der `omd` sie nimmt. Von Hand wäre es: + +```bash +docker exec checkmk gpasswd -a www-data cmk +docker exec checkmk sh -c 'echo "tmpfs /omd/sites/cmk/tmp tmpfs noauto,user,mode=751,uid=cmk,gid=cmk 0 0" >> /etc/fstab' +``` + --- ## 17. Migration einer Direktinstallation (`migrate_creator.sh`) @@ -2778,6 +2839,8 @@ Checkmk-Werksnotizen (Werks/Release Notes) lesen. | Symptom | Ursache / Lösung | |---|---| | `ERR_SSL_UNRECOGNIZED_NAME_ALERT` beim Aufruf über `https:///` | Der Browser sendet bei einer IP kein SNI, nginx fällt auf seinen Standard-Server zurück und lehnt ab. `cmk-manage.sh proxy default --domain ` – siehe [Kapitel 10.8](#108-https-über-die-blanke-ip) | +| `omd restore`: *apache user www-data must be member of group ``* | Der Container wurde neu erstellt, die Site liegt im Bind-Mount. `cmk-manage.sh` zieht das beim Restore und beim `up` selbst nach – siehe [Kapitel 16.1](#161-warum-ein-restore-nach-dem-neuerstellen-des-containers-scheiterte) | +| `omd restore`: *fstab entry for /omd/sites/…/tmp does not exist* | gleiche Ursache, gleiche Behebung | | `Port 80/443 already in use` | Auf dem Host läuft bereits ein Webserver: `ss -tlnp \| grep ':80'` → `systemctl disable --now apache2 nginx httpd` | | Nach Reboot laufen die Container nicht (Podman) | systemd-Unit fehlt: `./install.sh --with-systemd` bzw. `--quadlet`, danach `systemctl is-enabled checkmk-stack` | | `omd restore`: *version is not installed* | passendes Image holen: `cmk-manage.sh image pull --edition --version `, dann `up` | diff --git a/README_en.md b/README_en.md index ef01a93..f8c6112 100644 --- a/README_en.md +++ b/README_en.md @@ -2529,6 +2529,65 @@ What the script does: A raw `omd backup` archive (without the bundle wrapper) is accepted as well; the site name is then read from the archive. +### 16.1 Why a restore failed after recreating the container + +``` +ERROR: apache user www-data must be member of group cmk +``` + +When a site is created, `omd create` adds the apache user to the site's group. +That membership lives in `/etc/group` – **inside the container**, not in the +bind mount. Recreate the container (every `up` with a changed image, a +`podman rm`, an update) and `/etc/group` is back to the state from the image, +while the site in the bind mount lives on unchanged. + +The official entrypoint detects this case and recreates group and user – but +does **not** add `www-data` to the group: + +```bash +if ! getent group "$CMK_SITE_ID" >/dev/null; then + groupadd -g 1000 "$CMK_SITE_ID" +fi +if ! getent passwd "$CMK_SITE_ID" >/dev/null; then + useradd -u 1000 ... -G omd -s /bin/bash "$CMK_SITE_ID" +fi +``` + +In daily operation this goes unnoticed: the site runs, the GUI answers, the +agent receiver accepts data. Only `omd restore --reuse` checks it +(`user_verify` in `omdlib/users_and_groups.py`) and aborts. + +Right behind it waits the second obstacle: + +``` +ERROR: fstab entry for /omd/sites/cmk/tmp does not exist +``` + +`omd` explicitly tolerates a missing `/etc/fstab` (*"In case there is no fstab +(seen in some containers) assume everything is OK"*) – but the image ships a +file containing a comment line. So `/etc/fstab` exists, the exception does not +apply, and the entry is found missing. + +Both are state of the **container**, not of the data. `cmk-manage.sh` +therefore restores them before every `restore` and `import` – and, for the same +reason, after every `up`, so a hand-written `omd` call does not trip over it: + +``` +[ INFO ] Apache-Benutzer www-data -> cmk in die Gruppe aufgenommen + (nach dem Neuerstellen des Containers verloren gegangen). +[ INFO ] fstab-Eintrag fuer /omd/sites/cmk/tmp ergaenzt - ohne ihn + verweigert 'omd restore' den Dienst. +``` + +The apache user and the command to add it are read from +`/omd/versions/default/share/omd/distro.info` – the same source `omd` itself +uses. By hand it would be: + +```bash +docker exec checkmk gpasswd -a www-data cmk +docker exec checkmk sh -c 'echo "tmpfs /omd/sites/cmk/tmp tmpfs noauto,user,mode=751,uid=cmk,gid=cmk 0 0" >> /etc/fstab' +``` + --- ## 17. Migrating a bare-metal installation (`migrate_creator.sh`) @@ -2770,6 +2829,8 @@ release notes beforehand. | Symptom | Cause / solution | |---|---| | `ERR_SSL_UNRECOGNIZED_NAME_ALERT` when opening `https:///` | browsers send no SNI for an IP, nginx falls back to its default server and rejects. `cmk-manage.sh proxy default --domain ` – see [chapter 10.8](#108-https-on-the-bare-ip) | +| `omd restore`: *apache user www-data must be member of group ``* | the container was recreated while the site lives in the bind mount. `cmk-manage.sh` repairs this on restore and on `up` – see [chapter 16.1](#161-why-a-restore-failed-after-recreating-the-container) | +| `omd restore`: *fstab entry for /omd/sites/…/tmp does not exist* | same cause, same fix | | `Port 80/443 already in use` | a web server is already running on the host: `ss -tlnp \| grep ':80'` → `systemctl disable --now apache2 nginx httpd` | | Containers do not run after a reboot (Podman) | systemd unit missing: `./install.sh --with-systemd` or `--quadlet`, then `systemctl is-enabled checkmk-stack` | | `omd restore`: *version is not installed* | fetch the matching image: `cmk-manage.sh image pull --edition --version `, then `up` | diff --git a/scripts/cmk-manage.sh b/scripts/cmk-manage.sh index 787cf5b..a103ef3 100755 --- a/scripts/cmk-manage.sh +++ b/scripts/cmk-manage.sh @@ -1763,6 +1763,14 @@ cmd_up() { fi npm_enabled || npm_teardown_container ok "Stack gestartet." + + # Nach dem Neuerstellen des Containers fehlen die Systemteile der + # Site (siehe container_fix_site_system). Gleich nachziehen, damit + # nicht erst ein spaeteres "omd restore" darueber stolpert. + if container_running "$CMK_CONTAINER_NAME"; then + container_fix_site_system "${CMK_SITE_ID:-cmk}" || true + fi + cmd_status } @@ -2372,6 +2380,77 @@ cmd_prune() { # ===================================================================== # Restore / Import (gemeinsame Implementierung) # ===================================================================== +# ===================================================================== +# Systemteile im Container nachziehen +# +# Beim Anlegen einer Site traegt "omd create" den Apache-Benutzer in +# die Gruppe der Site ein. Wird der Container spaeter neu erstellt - +# bei jedem "up" mit geaendertem Image etwa -, ist /etc/group wieder +# der Stand aus dem Abbild, waehrend die Site im Bind-Mount liegt und +# bleibt. Der Entrypoint legt Gruppe und Benutzer dann zwar neu an, +# nimmt www-data aber NICHT in die Gruppe auf. +# +# Im Betrieb faellt das nicht auf: die Site laeuft, die Oberflaeche +# antwortet. "omd restore" prueft es aber und bricht ab mit +# ERROR: apache user www-data must be member of group +# +# Der zweite Stolperstein: "omd restore --reuse" will einen +# fstab-Eintrag fuer das tmp-Verzeichnis sehen. Fehlt /etc/fstab ganz, +# laesst omd das durchgehen ("seen in some containers") - im Abbild +# liegt aber eine Datei mit einer Kommentarzeile, also greift die +# Ausnahme nicht. +# +# Beides ist Zustand des Containers, nicht der Daten. Es muss nach +# jedem Neuerstellen wieder hergestellt werden. +# ===================================================================== +container_fix_site_system() { # site [--quiet] + local site="$1" quiet="${2:-}" + local out + out="$(ct sh -c ' + set -e + site="'"$site"'" + info=/omd/versions/default/share/omd/distro.info + au="$(sed -n "s/^APACHE_USER[[:space:]]*=[[:space:]]*//p" "$info" 2>/dev/null | head -1)" + [ -n "$au" ] || au=www-data + getent group "$site" >/dev/null || exit 0 + + # Apache-Benutzer in die Gruppe der Site + case " $(id -nG "$au" 2>/dev/null) " in + *" $site "*) ;; + *) + add="$(sed -n "s/^ADD_USER_TO_GROUP[[:space:]]*=[[:space:]]*//p" "$info" 2>/dev/null | head -1)" + if [ -n "$add" ]; then + cmd="$(printf "%s" "$add" | sed "s/%(user)s/$au/; s/%(group)s/$site/")" + sh -c "$cmd" >/dev/null 2>&1 || usermod -aG "$site" "$au" >/dev/null 2>&1 + else + usermod -aG "$site" "$au" >/dev/null 2>&1 + fi + echo "GRUPPE $au -> $site" + ;; + esac + + # fstab-Eintrag fuer das tmp-Verzeichnis + mp="/omd/sites/$site/tmp" + if [ -f /etc/fstab ] && ! grep -q "uid=$site," /etc/fstab 2>/dev/null; then + printf "tmpfs %s tmpfs noauto,user,mode=751,uid=%s,gid=%s 0 0\n" \ + "$mp" "$site" "$site" >> /etc/fstab + echo "FSTAB $mp" + fi + ' 2>/dev/null)" || return 0 + + [ -n "$out" ] || return 0 + if [ -z "$quiet" ]; then + local l + while IFS= read -r l; do + case "$l" in + GRUPPE*) log "Apache-Benutzer ${l#GRUPPE } in die Gruppe aufgenommen (nach dem Neuerstellen des Containers verloren gegangen)." ;; + FSTAB*) log "fstab-Eintrag fuer ${l#FSTAB } ergaenzt - ohne ihn verweigert 'omd restore' den Dienst." ;; + esac + done <<<"$out" + fi + return 0 +} + do_restore() { local file="$1" as_site="$2" reuse="$3" kill_opt="$4" nostart="$5" mode="$6" @@ -2472,6 +2551,10 @@ EOF $RUNTIME cp "$tmp/payload.tar.gz" "$CMK_CONTAINER_NAME:/var/tmp/cmkrestore.tar.gz" rm -rf "$tmp" + # Die Pruefungen von "omd restore" setzen Systemteile voraus, die ein + # neu erstellter Container nicht mehr hat - vorher nachziehen. + container_fix_site_system "$target" + log "Fuehre 'omd restore ${rargs[*]-} ' aus ..." if ! ct omd restore ${rargs[@]+"${rargs[@]}"} /var/tmp/cmkrestore.tar.gz; then ct sh -c 'rm -f /var/tmp/cmkrestore.tar.gz' || true