Report read-only paths after a session; known issues document
- run (on exit) and doctor scan the OpenCode log for 'Read-only file system' / EROFS, map the agent's XDG mirror back to the home directory and print a ready OCSB_RW_HOME line; writable, hidden and protected project paths are skipped - docs/known-issues.md: open gaps and planned work (Docker, blocklist egress, DNS, shared network namespace, resource limits, undo, planted repos, credentials, agents working around guards); linked from both READMEs
This commit is contained in:
@@ -34,6 +34,7 @@ ocsb_doctor() {
|
||||
ocsb_egress status
|
||||
source "${OCSB_HOME}/lib/run.sh"
|
||||
if ocsb_git_audit; then echo " ✓ no planted git metadata in the project and worktrees"; else fail=1; fi
|
||||
ocsb_erofs_report
|
||||
else
|
||||
echo "Project: none here (opencode-sandbox init)"
|
||||
fi
|
||||
|
||||
+51
-1
@@ -170,6 +170,54 @@ ocsb_git_audit() {
|
||||
return 1
|
||||
}
|
||||
|
||||
# Paths the session could not write to (tools log "Read-only file system" / EROFS): mapped
|
||||
# back from the agent's XDG mirror to the user's home and reported with a ready config line.
|
||||
# Paths already writable, deliberately hidden, or inside the project (protected) are skipped.
|
||||
# ocsb_erofs_report [byte offset into the OpenCode log]
|
||||
ocsb_erofs_report() {
|
||||
local log=${OCSB_STATE_DIR}/data/opencode/log/opencode.log from=${1:-0} s=${OCSB_STATE_DIR}
|
||||
local p rel n out=() seen=" " skip
|
||||
[[ -f ${log} ]] || return 0
|
||||
(($(stat -c %s "${log}") >= from)) || from=0
|
||||
while IFS= read -r p; do
|
||||
case ${p} in
|
||||
"${s}/data/"*) rel=.local/share/${p#"${s}/data/"} ;;
|
||||
"${s}/state/"*) rel=.local/state/${p#"${s}/state/"} ;;
|
||||
"${s}/config/"*) rel=.config/${p#"${s}/config/"} ;;
|
||||
"${s}/cache/"*) rel=.cache/${p#"${s}/cache/"} ;;
|
||||
"${OCSB_PROJECT_DIR}"/* | "${OCSB_WORKTREES_DIR}"/* | "${s}"/*) continue ;;
|
||||
"${HOME}"/*) rel=${p#"${HOME}/"} ;;
|
||||
*) rel=/${p#/} ;;
|
||||
esac
|
||||
# The directory to open: ~/.local/share/<tool>, ~/.local/bin, ~/.config/<tool>, ~/.<tool>
|
||||
case ${rel} in
|
||||
/*) rel=$(cut -d/ -f1-3 <<<"${rel}") ;;
|
||||
.local/share/* | .local/state/*) rel=$(cut -d/ -f1-3 <<<"${rel}") ;;
|
||||
.local/* | .config/*) rel=$(cut -d/ -f1-2 <<<"${rel}") ;;
|
||||
*) rel=${rel%%/*} ;;
|
||||
esac
|
||||
rel=${rel%/.tmp*}
|
||||
skip=0
|
||||
for n in "${OCSB_RW_HOME[@]}" "${OCSB_HIDE_HOME[@]}"; do
|
||||
[[ ${rel} == "${n}" || ${rel} == "${n}"/* ]] && skip=1
|
||||
done
|
||||
[[ ${skip} == 1 || ${seen} == *" ${rel} "* ]] && continue
|
||||
seen+="${rel} "
|
||||
out+=("${rel}")
|
||||
done < <(tail -c +"$((from + 1))" "${log}" | grep -E 'Read-only file system|EROFS' |
|
||||
sed -E 's/ (directory|cwd|path\.cwd)=[^ ]*//g' | grep -oE '/[A-Za-z0-9._@+/-]+' | grep -E "^(${HOME}|/opt|/usr/local|/var)/" | sort -u)
|
||||
((${#out[@]} == 0)) && return 0
|
||||
ocsb_warn "the session hit read-only paths (a tool or MCP server may have failed):"
|
||||
for rel in "${out[@]}"; do
|
||||
if [[ ${rel} == /* ]]; then
|
||||
printf ' %s → if needed: OCSB_RW+=(%s)\n' "${rel}" "${rel}" >&2
|
||||
else
|
||||
printf ' ~/%s → OCSB_RW_HOME+=(%s)\n' "${rel}" "${rel}" >&2
|
||||
fi
|
||||
done
|
||||
echo " add the line to .opencode-sandbox/sandbox.conf (or local/sandbox.conf just for you) and restart" >&2
|
||||
}
|
||||
|
||||
# bubblewrap arguments for the sandbox (variant: read-only host, writable project)
|
||||
ocsb_bwrap_args() {
|
||||
local p f uid
|
||||
@@ -310,7 +358,9 @@ ocsb_run() {
|
||||
fi
|
||||
ocsb_bwrap_args
|
||||
# On any exit (Ctrl-C too): stop the bus proxy, look for what the session planted
|
||||
trap 'kill "${OCSB_DBUS_PROXY_PID:-}" 2>/dev/null; ocsb_git_audit || true' EXIT
|
||||
# (global: the trap runs after this function has returned)
|
||||
OCSB_LOG_START=$(stat -c %s "${OCSB_STATE_DIR}/data/opencode/log/opencode.log" 2>/dev/null || echo 0)
|
||||
trap 'kill "${OCSB_DBUS_PROXY_PID:-}" 2>/dev/null; ocsb_git_audit || true; ocsb_erofs_report "${OCSB_LOG_START}"' EXIT
|
||||
cmd=(bwrap "${OCSB_BWRAP[@]}" -- "${cmd[@]}")
|
||||
# No permission prompts in the sandbox: permission rules from all configs form one
|
||||
# list, the last match wins, and OPENCODE_CONFIG_CONTENT is the last document.
|
||||
|
||||
Reference in New Issue
Block a user