From 2b5bb570ca3c847ff3251d5b23f2f7b655afe8d3 Mon Sep 17 00:00:00 2001 From: Duan Date: Fri, 16 Oct 2026 17:26:28 +0200 Subject: [PATCH] olex2: do not preserve ownership when copying into PREFIX First build failed in install: cp -a onto /opt/psi logs 'failed to preserve ownership ... Permission denied' for every file (chown refused) and exits non-zero, which tripped the die-guard although the copy itself was fine. Use cp -r --preserve=mode,timestamps,links instead. Record the pitfall in the new-module skill guardrails. --- .claude/skills/new-module/SKILL.md | 4 ++++ olex2/build | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.claude/skills/new-module/SKILL.md b/.claude/skills/new-module/SKILL.md index 5473176..71dff26 100644 --- a/.claude/skills/new-module/SKILL.md +++ b/.claude/skills/new-module/SKILL.md @@ -102,6 +102,10 @@ There is **no `--dry-run` and no `--check-mode`** — to sanity-check config/pat `du -sh /opt/psi/MX//` from a second shell; don't kill a healthy build. - modbuild runs hooks with `pipefail` + `nounset`: `yes | cmd` fails (SIGPIPE) — use `printf 'y\ny\n' | cmd`. +- **Never `cp -a` / `cp -p` into `$PREFIX`**: chown is refused on `/opt/psi`, so every + file logs `failed to preserve ownership ... Permission denied` and cp exits non-zero + (olex2 2026-10: 12k-line log, die-guard aborted a healthy copy). Use + `cp -r --preserve=mode,timestamps,links src/. "$PREFIX"/` (or tar pipe / `install`). - modbuild has **no errexit in hooks**: a failed command scrolls by and the build still prints "done", installing the modulefile over a broken PREFIX. Guard every critical hook step with `|| std::die 42 ""` and end `install` with an diff --git a/olex2/build b/olex2/build index 193b429..b55ec68 100755 --- a/olex2/build +++ b/olex2/build @@ -38,7 +38,11 @@ pbuild::install() { local -r src="${SRC_DIR}/olex2" # 1. vendor tree, flat into $PREFIX (= BaseDir). Slow on /opt/psi: 12k files. - cp -a "${src}/." "${PREFIX}/" || std::die 42 "olex2: copying the vendor tree into ${PREFIX} failed" + # NOT `cp -a`: on /opt/psi chown is refused, so -a ends with thousands of + # "failed to preserve ownership ... Permission denied" and a non-zero exit + # (that killed the first build). Keep mode/timestamps/links only. + cp -r --preserve=mode,timestamps,links "${src}/." "${PREFIX}/" || \ + std::die 42 "olex2: copying the vendor tree into ${PREFIX} failed" # 2. zip loses nothing, but make sure the ELF binaries are executable and # everything is world-readable on the shared install