Handle Snap Docker home restrictions (Related to #693)

This commit is contained in:
rcourtman 2025-11-12 19:20:04 +00:00
parent 0899e36ad2
commit 305a5b17bc
2 changed files with 100 additions and 7 deletions

View file

@ -275,14 +275,24 @@ Need the alerts but at a different tone? The same Containers tab exposes global
**Symptom:** Install script completes successfully but the agent service fails with `permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock`. The install script may have shown `[WARN] docker group not found`.
**Cause:** Docker installed via Snap does not automatically create a system `docker` group, preventing the `pulse-docker` service user from accessing `/var/run/docker.sock`.
**Cause:** Docker installed via Snap does not automatically create a system `docker` group, and snapd refuses to run confined binaries for users whose home directory is outside `/home`. The legacy installer created `/var/lib/pulse-docker-agent`, so the `pulse-docker` user could not talk to the Snap-managed daemon.
**Fix:** The install script now automatically detects Snap Docker and creates the docker group when needed. If you previously installed with an older version of the script:
**Fix:** The install script now automatically detects Snap Docker, creates the `docker` group when needed, and relocates the `pulse-docker` home to `/home/pulse-docker-agent` so snapd allows socket access. If you previously installed with an older version of the script:
1. Create the docker group: `sudo addgroup --system docker`
2. Add the service user to the group: `sudo adduser pulse-docker docker`
3. Restart Snap Docker to refresh socket ACLs: `sudo snap restart docker`
4. Restart the agent service: `sudo systemctl restart pulse-docker-agent`
3. Move the service home under `/home`: `sudo usermod -d /home/pulse-docker-agent -m pulse-docker`
4. Restart Snap Docker to refresh socket ACLs: `sudo snap restart docker`
5. Restart the agent service: `sudo systemctl restart pulse-docker-agent`
If your distribution intentionally keeps system users outside `/home`, configure snapd to trust the legacy location instead:
```
sudo snap set system homedirs=/var/lib
sudo snap get system homedirs # verify
```
The snapcraft documentation at [Home directories outside of `/home`](https://snapcraft.io/docs/home-outside-home) covers additional options (bind mounts, multiple custom roots, etc.).
Verify socket access with: `sudo -u pulse-docker docker version`

View file

@ -360,6 +360,11 @@ ensure_service_user() {
else
SERVICE_GROUP_ACTUAL="$(id -gn "$SERVICE_USER")"
fi
local existing_home
existing_home=$(get_user_home_path "$SERVICE_USER")
if [[ -n "$existing_home" ]]; then
SERVICE_HOME="$existing_home"
fi
return
fi
@ -386,6 +391,11 @@ ensure_service_user() {
else
SERVICE_GROUP_ACTUAL="$(id -gn "$SERVICE_USER")"
fi
local created_home
created_home=$(get_user_home_path "$SERVICE_USER")
if [[ -n "$created_home" ]]; then
SERVICE_HOME="$created_home"
fi
if [[ "$SERVICE_USER_CREATED" == "true" ]]; then
log_success "Created service user: $SERVICE_USER"
fi
@ -415,6 +425,64 @@ ensure_service_home() {
chmod 750 "$SERVICE_HOME" >/dev/null 2>&1 || true
}
get_user_home_path() {
local user="$1"
if [[ -z "$user" ]]; then
return
fi
local entry
entry=$(getent passwd "$user" 2>/dev/null || true)
if [[ -z "$entry" ]]; then
return
fi
local home_path
home_path=$(printf '%s\n' "$entry" | awk -F: '{print $6}')
if [[ -n "$home_path" ]]; then
printf '%s\n' "$home_path"
fi
}
ensure_snap_home_compatibility() {
if [[ "$SERVICE_USER_ACTUAL" == "root" ]]; then
return
fi
detect_snap_docker
if [[ "$SNAP_DOCKER_DETECTED" != "true" ]]; then
return
fi
local current_home
current_home=$(get_user_home_path "$SERVICE_USER_ACTUAL")
if [[ -z "$current_home" ]]; then
return
fi
if [[ "$current_home" == /home/* ]]; then
SERVICE_HOME="$current_home"
return
fi
local desired_home="/home/$SERVICE_USER_ACTUAL"
if ! command -v usermod >/dev/null 2>&1; then
log_warn "Snap Docker detected but usermod is unavailable to relocate $SERVICE_USER_ACTUAL."
log_warn "Refer to https://snapcraft.io/docs/home-outside-home to allow non-/home directories."
return
fi
log_info "Snap Docker detected; relocating $SERVICE_USER_ACTUAL home to $desired_home"
if usermod -d "$desired_home" -m "$SERVICE_USER_ACTUAL" >/dev/null 2>&1; then
SERVICE_HOME="$desired_home"
log_success "Moved $SERVICE_USER_ACTUAL home to $desired_home for Snap compatibility"
return
fi
log_warn "Failed to relocate $SERVICE_USER_ACTUAL home for Snap Docker."
log_warn "See https://snapcraft.io/docs/home-outside-home for manual remediation."
}
detect_snap_docker() {
SNAP_DOCKER_DETECTED="false"
@ -652,7 +720,9 @@ validate_docker_socket_access() {
echo " 1. Ensure the docker group exists: getent group docker" >&2
echo " 2. Ensure $SERVICE_USER_ACTUAL is in the docker group: id -nG $SERVICE_USER_ACTUAL" >&2
echo " 3. Check if Snap Docker is running: snap services docker.dockerd" >&2
echo " 4. Restart Snap Docker to refresh permissions: snap restart docker" >&2
echo " 4. Confirm the $SERVICE_USER_ACTUAL home lives under /home (snapd blocks other paths)" >&2
echo " See https://snapcraft.io/docs/home-outside-home for alternate locations" >&2
echo " 5. Restart Snap Docker to refresh permissions: snap restart docker" >&2
else
echo "Common solutions:" >&2
echo " 1. Ensure $SERVICE_USER_ACTUAL is in the docker group: id -nG $SERVICE_USER_ACTUAL" >&2
@ -878,7 +948,9 @@ JOINED_TARGETS=""
ORIGINAL_ARGS=("$@")
SERVICE_USER="pulse-docker"
SERVICE_GROUP="$SERVICE_USER"
SERVICE_HOME="/var/lib/pulse-docker-agent"
SERVICE_HOME_DEFAULT="/home/pulse-docker-agent"
SERVICE_HOME_LEGACY="/var/lib/pulse-docker-agent"
SERVICE_HOME="$SERVICE_HOME_DEFAULT"
SERVICE_USER_ACTUAL="$SERVICE_USER"
SERVICE_GROUP_ACTUAL="$SERVICE_GROUP"
SERVICE_USER_CREATED="false"
@ -1179,6 +1251,11 @@ fi
if [ "$UNINSTALL" = true ]; then
log_header "Pulse Docker Agent Uninstaller"
existing_service_home=$(get_user_home_path "$SERVICE_USER")
if [[ -n "$existing_service_home" ]]; then
SERVICE_HOME="$existing_service_home"
fi
if command -v systemctl &> /dev/null; then
log_info "Stopping pulse-docker-agent service"
systemctl stop pulse-docker-agent 2>/dev/null || true
@ -1227,10 +1304,14 @@ if [ "$UNINSTALL" = true ]; then
else
log_info "Agent log file already absent: $LOG_PATH"
fi
if [[ -d "$SERVICE_HOME" ]]; then
if [[ -n "$SERVICE_HOME" && "$SERVICE_HOME" != "/" && -d "$SERVICE_HOME" ]]; then
rm -rf "$SERVICE_HOME"
log_success "Removed service home directory: $SERVICE_HOME"
fi
if [[ -n "$SERVICE_HOME_LEGACY" && "$SERVICE_HOME_LEGACY" != "$SERVICE_HOME" && -d "$SERVICE_HOME_LEGACY" ]]; then
rm -rf "$SERVICE_HOME_LEGACY"
log_success "Removed legacy service home directory: $SERVICE_HOME_LEGACY"
fi
elif [ -f "$LOG_PATH" ]; then
log_info "Preserving agent log file at $LOG_PATH (use --purge to remove)"
fi
@ -1683,6 +1764,7 @@ EOF
log_header 'Preparing service environment'
ensure_service_user
ensure_snap_home_compatibility
ensure_service_home
ensure_docker_group_membership
write_env_file
@ -1793,6 +1875,7 @@ fi
log_header 'Preparing service environment'
ensure_service_user
ensure_snap_home_compatibility
ensure_service_home
ensure_docker_group_membership
write_env_file