Merge pull request #738: test(docker): give the Update-Codeman.sh smoke harness a non-root appdata owner

This commit is contained in:
Codeman maintainer committed 2026-11-04 16:47:48 +01:00
commit 457dd54825
1 file changed
+16 -1
+16 -1
View File
@@ -26,7 +26,7 @@
*/
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { readFileSync, mkdtempSync, rmSync, writeFileSync, mkdirSync } from 'node:fs';
import { readFileSync, mkdtempSync, rmSync, writeFileSync, mkdirSync, chownSync } from 'node:fs';
import { execFileSync } from 'node:child_process';
import { tmpdir } from 'node:os';
import { join } from 'node:path';
@@ -309,6 +309,21 @@ describe('Update-Codeman.sh (the scripted major-update path — docker/README.md
const casesPath = join(dir, 'cases');
const socketPath = join(dir, 'docker.sock'); // deliberately NOT a real socket — see above
mkdirSync(appdataPath);
// Both scripts derive PUID:PGID from the appdata owner and REFUSE a
// root-owned one (correctly: the container must never run as root).
// mkdirSync gives it the runner's uid, so under a root runner (a CI or
// agent container) the update path stopped at that guard before its
// build. Give it the non-root owner docker/README.md's own
// `chown -R 99:100` example sets up, as a real deployment would have.
if (process.getuid?.() === 0) {
try {
chownSync(appdataPath, 99, 100);
} catch {
// No CAP_CHOWN (root with --cap-drop ALL, as Codeman's own Docker
// case containers run) or a single-uid user namespace: leave it
// root-owned and let the scripts' own guard refuse, as before.
}
}
mkdirSync(casesPath);
writeFileSync(socketPath, '');