diff --git a/src/servers/api/users/provision-os.ts b/src/servers/api/users/provision-os.ts index efea4295..90bd473f 100644 --- a/src/servers/api/users/provision-os.ts +++ b/src/servers/api/users/provision-os.ts @@ -3,7 +3,8 @@ import { ensureOsUser, osUserHome } from '@@/os-user'; import { provisionSshAccess } from '@@/os-user-ssh'; import { seedShellConfig } from '@@/os-user-shell'; 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'; // 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. 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 - // package or a kernel that will not do rootless still gets a perfectly good account, minus containers. + // ── Rootless Docker: DISABLED 2026-08-13, code kept ── // - // Provisioned for every member rather than behind a toggle, because "can I run a database to develop - // against" should not be an administrative request. The cost — one daemon and one image cache per member — - // is real and is written down in os-user-docker.ts. - const docker = await provisionRootlessDocker({ - osUser: account.osUser, - uid: account.uid, - gid: account.gid, - home: osUserHome(params.email), - }); + // Every member got their own rootless daemon, unconditionally, on the argument that "can I run a database + // to develop against" should not be an administrative request. The cost is the counter-argument and it is + // per member, not per install: one daemon, one image cache, one subuid range — see os-user-docker.ts. + // + // Turned off at the call rather than deleted, so turning it back on is uncommenting this block and the + // import. `os-user-docker.ts` is otherwise unreferenced now; nothing else calls it. + // + // 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 // 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, // which matters more than no containers. Only one is surfaced because the UI shows one line — the rest are // 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}`); } - const error = !ssh.ok - ? ssh.error - : !claude.ok - ? claude.error - : !shell.ok - ? shell.error - : !docker.ok - ? docker.error - : null; + const error = !ssh.ok ? ssh.error : !claude.ok ? claude.error : !shell.ok ? shell.error : null; return { osUser: account.osUser, sshPublicKey, error }; }