one sudo call for both agent-status answers, not two
host's finding on 6b7aad91. claudeLoginState ran two `runAs` probes in parallel,
and each is a `sudo -n setpriv` fork/exec that writes a line to
/var/log/auth.log. It is reached from /agent-status, which sits on a grant every
role holds by default, so a polling UI would have cost two sudo spawns and two
auth-log lines per poll per member — cheap individually, unbounded in aggregate,
and the auth log is where a real sudo event has to stay visible.
One call answering both questions with markers instead of two exit codes. Did
not take his second suggestion of caching `installed`: one call per request is
cheap enough that a second mechanism with its own invalidation is the worse
trade, and that judgement is recorded in COMMS so a polling UI can revisit it.
Also carries the verify list he asked for, including the pertento host key I
accepted on first use so git could reach his remote — he can compare it against
the server, which I cannot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -111,9 +111,21 @@ export type ClaudeLoginState = {
|
||||
* saying nothing about whether the account that needs it can see it.
|
||||
*/
|
||||
export async function claudeLoginState(params: { email: string; osUser: string }): Promise<ClaudeLoginState> {
|
||||
const [installed, loggedIn] = await Promise.all([
|
||||
asMember(params.osUser, ['test', '-x', claudeBinPath(params.email)]),
|
||||
asMember(params.osUser, ['test', '-s', credentialsPath(params.email)]),
|
||||
// One `runAs` for both answers, not two. Each is a `sudo -n setpriv` fork/exec that writes a line to
|
||||
// `/var/log/auth.log`, and this is reached from `/agent-status`, which sits on a grant every role has by
|
||||
// default — so a UI that polls it would otherwise cost two sudo spawns and two auth-log lines per poll, per
|
||||
// member. Individually cheap, unbounded in aggregate, and the auth log is where a real sudo event has to
|
||||
// stay visible.
|
||||
//
|
||||
// Markers rather than an exit code because one call now answers two questions. `-x` follows symlinks, which
|
||||
// is what the installer produces: a link into a versioned directory, not a file.
|
||||
const probe = await asMember(params.osUser, [
|
||||
'sh',
|
||||
'-c',
|
||||
'test -x "$1" && printf bin; test -s "$2" && printf cred',
|
||||
'_',
|
||||
claudeBinPath(params.email),
|
||||
credentialsPath(params.email),
|
||||
]);
|
||||
return { installed: installed.ok, loggedIn: loggedIn.ok };
|
||||
return { installed: probe.out.includes('bin'), loggedIn: probe.out.includes('cred') };
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user