mirror of
https://github.com/moltbot/moltbot.git
synced 2026-03-07 22:44:16 +00:00
fix(podman): stop assuming /tmp is disk-backed (#38296)
* Podman: avoid hardcoding /tmp for image staging * Docs: clarify container storage paths * Podman: secure staged image import * Podman: clarify streamed image handoff
This commit is contained in:
@@ -535,6 +535,12 @@ docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789
|
||||
- Dockerfile CMD uses `--allow-unconfigured`; mounted config with `gateway.mode` not `local` will still start. Override CMD to enforce the guard.
|
||||
- The gateway container is the source of truth for sessions (`~/.openclaw/agents/<agentId>/sessions/`).
|
||||
|
||||
### Storage model
|
||||
|
||||
- **Persistent host data:** Docker Compose bind-mounts `OPENCLAW_CONFIG_DIR` to `/home/node/.openclaw` and `OPENCLAW_WORKSPACE_DIR` to `/home/node/.openclaw/workspace`, so those paths survive container replacement.
|
||||
- **Ephemeral sandbox tmpfs:** when `agents.defaults.sandbox` is enabled, the sandbox containers use `tmpfs` for `/tmp`, `/var/tmp`, and `/run`. Those mounts are separate from the top-level Compose stack and disappear with the sandbox container.
|
||||
- **Disk growth hotspots:** watch `media/`, `agents/<agentId>/sessions/sessions.json`, transcript JSONL files, `cron/runs/*.jsonl`, and rolling file logs under `/tmp/openclaw/` (or your configured `logging.file`). If you also run the macOS app outside Docker, its service logs are separate again: `~/.openclaw/logs/gateway.log`, `~/.openclaw/logs/gateway.err.log`, and `/tmp/openclaw/openclaw-gateway.log`.
|
||||
|
||||
## Agent Sandbox (host gateway + Docker tools)
|
||||
|
||||
Deep dive: [Sandboxing](/gateway/sandboxing)
|
||||
|
||||
@@ -93,6 +93,14 @@ To add quadlet **after** an initial setup that did not use it, re-run: `./setup-
|
||||
- **Gateway bind:** By default, `run-openclaw-podman.sh` starts the gateway with `--bind loopback` for safe local access. To expose on LAN, set `OPENCLAW_GATEWAY_BIND=lan` and configure `gateway.controlUi.allowedOrigins` (or explicitly enable host-header fallback) in `openclaw.json`.
|
||||
- **Paths:** Host config and workspace default to `~openclaw/.openclaw` and `~openclaw/.openclaw/workspace`. Override the host paths used by the launch script with `OPENCLAW_CONFIG_DIR` and `OPENCLAW_WORKSPACE_DIR`.
|
||||
|
||||
## Storage model
|
||||
|
||||
- **Persistent host data:** `OPENCLAW_CONFIG_DIR` and `OPENCLAW_WORKSPACE_DIR` are bind-mounted into the container and retain state on the host.
|
||||
- **Ephemeral sandbox tmpfs:** if you enable `agents.defaults.sandbox`, the tool sandbox containers mount `tmpfs` at `/tmp`, `/var/tmp`, and `/run`. Those paths are memory-backed and disappear with the sandbox container; the top-level Podman container setup does not add its own tmpfs mounts.
|
||||
- **Disk growth hotspots:** the main paths to watch are `media/`, `agents/<agentId>/sessions/sessions.json`, transcript JSONL files, `cron/runs/*.jsonl`, and rolling file logs under `/tmp/openclaw/` (or your configured `logging.file`).
|
||||
|
||||
`setup-podman.sh` now stages the image tar in a private temp directory and prints the chosen base dir during setup. For non-root runs it accepts `TMPDIR` only when that base is safe to use; otherwise it falls back to `/var/tmp`, then `/tmp`. The saved tar stays owner-only and is streamed into the target user’s `podman load`, so private caller temp dirs do not block setup.
|
||||
|
||||
## Useful commands
|
||||
|
||||
- **Logs:** With quadlet: `sudo journalctl --machine openclaw@ --user -u openclaw.service -f`. With script: `sudo -u openclaw podman logs -f openclaw`
|
||||
|
||||
@@ -27,6 +27,48 @@ require_cmd() {
|
||||
fi
|
||||
}
|
||||
|
||||
is_writable_dir() {
|
||||
local dir="$1"
|
||||
[[ -n "$dir" && -d "$dir" && ! -L "$dir" && -w "$dir" && -x "$dir" ]]
|
||||
}
|
||||
|
||||
is_safe_tmp_base() {
|
||||
local dir="$1"
|
||||
local mode=""
|
||||
local owner=""
|
||||
is_writable_dir "$dir" || return 1
|
||||
mode="$(stat -Lc '%a' "$dir" 2>/dev/null || true)"
|
||||
if [[ -n "$mode" ]]; then
|
||||
local perm=$((8#$mode))
|
||||
if (( (perm & 0022) != 0 && (perm & 01000) == 0 )); then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
if is_root; then
|
||||
owner="$(stat -Lc '%u' "$dir" 2>/dev/null || true)"
|
||||
if [[ -n "$owner" && "$owner" != "0" ]]; then
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
resolve_image_tmp_dir() {
|
||||
if ! is_root && is_safe_tmp_base "${TMPDIR:-}"; then
|
||||
printf '%s' "$TMPDIR"
|
||||
return 0
|
||||
fi
|
||||
if is_safe_tmp_base "/var/tmp"; then
|
||||
printf '%s' "/var/tmp"
|
||||
return 0
|
||||
fi
|
||||
if is_safe_tmp_base "/tmp"; then
|
||||
printf '%s' "/tmp"
|
||||
return 0
|
||||
fi
|
||||
printf '%s' "/tmp"
|
||||
}
|
||||
|
||||
is_root() { [[ "$(id -u)" -eq 0 ]]; }
|
||||
|
||||
run_root() {
|
||||
@@ -215,12 +257,18 @@ BUILD_ARGS=()
|
||||
podman build ${BUILD_ARGS[@]+"${BUILD_ARGS[@]}"} -t openclaw:local -f "$REPO_PATH/Dockerfile" "$REPO_PATH"
|
||||
|
||||
echo "Loading image into $OPENCLAW_USER's Podman store..."
|
||||
TMP_IMAGE="$(mktemp -p /tmp openclaw-image.XXXXXX.tar)"
|
||||
trap 'rm -f "$TMP_IMAGE"' EXIT
|
||||
TMP_IMAGE_DIR="$(resolve_image_tmp_dir)"
|
||||
echo "Using temporary image dir: $TMP_IMAGE_DIR"
|
||||
TMP_STAGE_DIR="$(mktemp -d -p "$TMP_IMAGE_DIR" openclaw-image.XXXXXX)"
|
||||
TMP_IMAGE="$TMP_STAGE_DIR/image.tar"
|
||||
chmod 700 "$TMP_STAGE_DIR"
|
||||
trap 'rm -rf "$TMP_STAGE_DIR"' EXIT
|
||||
podman save openclaw:local -o "$TMP_IMAGE"
|
||||
chmod 644 "$TMP_IMAGE"
|
||||
(cd /tmp && run_as_user "$OPENCLAW_USER" env HOME="$OPENCLAW_HOME" podman load -i "$TMP_IMAGE")
|
||||
rm -f "$TMP_IMAGE"
|
||||
chmod 600 "$TMP_IMAGE"
|
||||
# Stream the image into the target user's podman load so private temp directories
|
||||
# do not need to be traversable by $OPENCLAW_USER.
|
||||
cat "$TMP_IMAGE" | run_as_user "$OPENCLAW_USER" env HOME="$OPENCLAW_HOME" podman load
|
||||
rm -rf "$TMP_STAGE_DIR"
|
||||
trap - EXIT
|
||||
|
||||
echo "Copying launch script to $LAUNCH_SCRIPT_DST..."
|
||||
|
||||
Reference in New Issue
Block a user