don't provision rootless docker for new members

Commented out at the call site in provisionOsAccount, with the import. The code in
os-user-docker.ts stays and is now unreferenced — turning it back on is uncommenting
two blocks.

Only affects NEW accounts. Members provisioned before this keep their daemon, and
deprovisionOsAccount still tears one down, which is what those accounts need.

Verified: transpiles. tsgo has still not run in this tree (node_modules is empty).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-13 11:56:16 +00:00
co-authored by Claude Opus 5
parent cc1eab7794
commit 7b32f5bc2f
+21 -22
View File
@@ -3,7 +3,8 @@ import { ensureOsUser, osUserHome } from '@@/os-user';
import { provisionSshAccess } from '@@/os-user-ssh'; import { provisionSshAccess } from '@@/os-user-ssh';
import { seedShellConfig } from '@@/os-user-shell'; import { seedShellConfig } from '@@/os-user-shell';
import { provisionClaudeCli } from '@@/os-user-claude'; import { provisionClaudeCli } from '@@/os-user-claude';
import { provisionRootlessDocker } from '@@/os-user-docker'; // Disabled 2026-08-13 — see the commented-out step in provisionOsAccount below.
// import { provisionRootlessDocker } from '@@/os-user-docker';
import { provisionUserDirs } from '@@/data-path'; import { provisionUserDirs } from '@@/data-path';
// Giving an account its Linux side: the directory skeleton, the Linux user, the confinement, the keys. // Giving an account its Linux side: the directory skeleton, the Linux user, the confinement, the keys.
@@ -77,18 +78,24 @@ export async function provisionOsAccount(params: {
// cannot do it for them and must not try, because the alternative is lending them the owner's credential. // cannot do it for them and must not try, because the alternative is lending them the owner's credential.
const claude = await provisionClaudeCli({ email: params.email, osUser: account.osUser }); const claude = await provisionClaudeCli({ email: params.email, osUser: account.osUser });
// Their own rootless Docker daemon. Last, and the most tolerant of failure: a host without the uidmap // ── Rootless Docker: DISABLED 2026-08-13, code kept ──
// package or a kernel that will not do rootless still gets a perfectly good account, minus containers.
// //
// Provisioned for every member rather than behind a toggle, because "can I run a database to develop // Every member got their own rootless daemon, unconditionally, on the argument that "can I run a database
// against" should not be an administrative request. The cost — one daemon and one image cache per member — // to develop against" should not be an administrative request. The cost is the counter-argument and it is
// is real and is written down in os-user-docker.ts. // per member, not per install: one daemon, one image cache, one subuid range — see os-user-docker.ts.
const docker = await provisionRootlessDocker({ //
osUser: account.osUser, // Turned off at the call rather than deleted, so turning it back on is uncommenting this block and the
uid: account.uid, // import. `os-user-docker.ts` is otherwise unreferenced now; nothing else calls it.
gid: account.gid, //
home: osUserHome(params.email), // Note this only stops NEW accounts. An account provisioned before today keeps its daemon, and
}); // `deprovisionOsAccount` still cleans one up, which is what an existing member needs.
//
// const docker = await provisionRootlessDocker({
// osUser: account.osUser,
// uid: account.uid,
// gid: account.gid,
// home: osUserHome(params.email),
// });
// The Linux account is recorded either way: it exists, it is confined, and a member's terminal can run as // The Linux account is recorded either way: it exists, it is confined, and a member's terminal can run as
// it. Only the keys are missing, and that is what the error says. // it. Only the keys are missing, and that is what the error says.
@@ -98,17 +105,9 @@ export async function provisionOsAccount(params: {
// Reported in order of consequence, not in order of execution: no keys matters more than a plain prompt, // Reported in order of consequence, not in order of execution: no keys matters more than a plain prompt,
// which matters more than no containers. Only one is surfaced because the UI shows one line — the rest are // which matters more than no containers. Only one is surfaced because the UI shows one line — the rest are
// in the log. // in the log.
for (const step of [claude, shell, docker] as const) { for (const step of [claude, shell] as const) {
if (!step.ok) console.warn(`[users] ${params.email}: ${step.error}`); if (!step.ok) console.warn(`[users] ${params.email}: ${step.error}`);
} }
const error = !ssh.ok const error = !ssh.ok ? ssh.error : !claude.ok ? claude.error : !shell.ok ? shell.error : null;
? ssh.error
: !claude.ok
? claude.error
: !shell.ok
? shell.error
: !docker.ok
? docker.error
: null;
return { osUser: account.osUser, sshPublicKey, error }; return { osUser: account.osUser, sshPublicKey, error };
} }