mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-28 05:16:23 -06:00
fix(update): keep TUI gate user scoped
This commit is contained in:
@@ -93,14 +93,28 @@ describe("local TUI processes", () => {
|
||||
const spawnSync = vi.fn().mockReturnValue({
|
||||
status: 0,
|
||||
stdout: JSON.stringify([
|
||||
{ ProcessId: 101, CommandLine: "C:\\openclaw.exe tui" },
|
||||
{ ProcessId: 102, CommandLine: "C:\\openclaw.exe gateway" },
|
||||
{ ProcessId: 103, CommandLine: '"C:\\Program Files\\OpenClaw\\openclaw.exe" chat' },
|
||||
{ ProcessId: 101, CommandLine: "C:\\openclaw.exe tui", OwnerSid: "S-1", CurrentSid: "S-1" },
|
||||
{
|
||||
ProcessId: 102,
|
||||
CommandLine: "C:\\openclaw.exe gateway",
|
||||
OwnerSid: "S-1",
|
||||
CurrentSid: "S-1",
|
||||
},
|
||||
{
|
||||
ProcessId: 103,
|
||||
CommandLine: '"C:\\Program Files\\OpenClaw\\openclaw.exe" chat',
|
||||
OwnerSid: "S-1",
|
||||
CurrentSid: "S-1",
|
||||
},
|
||||
{
|
||||
ProcessId: 104,
|
||||
CommandLine:
|
||||
'"C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\OpenClaw\\openclaw.mjs" terminal',
|
||||
OwnerSid: "S-1",
|
||||
CurrentSid: "S-1",
|
||||
},
|
||||
{ ProcessId: 105, CommandLine: "C:\\openclaw.exe tui", OwnerSid: "S-2", CurrentSid: "S-1" },
|
||||
{ ProcessId: 106, CommandLine: "C:\\openclaw.exe tui", OwnerSid: null, CurrentSid: "S-1" },
|
||||
]),
|
||||
});
|
||||
|
||||
@@ -227,4 +241,18 @@ describe("local TUI processes", () => {
|
||||
await waitForLocalTuiUpdate(vi.fn(async () => ({ lockPath: "test", release })));
|
||||
expect(release).toHaveBeenCalledOnce();
|
||||
});
|
||||
|
||||
it("keeps waiting after the bounded lock attempt while an update is still running", async () => {
|
||||
const release = vi.fn(async () => {});
|
||||
const timeout = Object.assign(new Error("busy"), { code: "file_lock_timeout" });
|
||||
const acquireLock = vi
|
||||
.fn()
|
||||
.mockRejectedValueOnce(timeout)
|
||||
.mockResolvedValueOnce({ lockPath: "test", release });
|
||||
|
||||
await waitForLocalTuiUpdate(acquireLock);
|
||||
|
||||
expect(acquireLock).toHaveBeenCalledTimes(2);
|
||||
expect(release).toHaveBeenCalledOnce();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -119,7 +119,7 @@ export function listLocalTuiProcesses(
|
||||
[
|
||||
"-NoProfile",
|
||||
"-Command",
|
||||
"Get-CimInstance Win32_Process | Select-Object ProcessId,CreationDate,CommandLine | ConvertTo-Json -Compress",
|
||||
"$currentSid=[Security.Principal.WindowsIdentity]::GetCurrent().User.Value; Get-CimInstance Win32_Process | ForEach-Object { $ownerSid=(Invoke-CimMethod -InputObject $_ -MethodName GetOwnerSid -ErrorAction SilentlyContinue).Sid; [pscustomobject]@{ProcessId=$_.ProcessId;CommandLine=$_.CommandLine;OwnerSid=$ownerSid;CurrentSid=$currentSid} } | ConvertTo-Json -Compress",
|
||||
],
|
||||
{ encoding: "utf8", killSignal: "SIGKILL", timeout: LOCAL_TUI_PROCESS_PROBE_TIMEOUT_MS },
|
||||
);
|
||||
@@ -134,6 +134,8 @@ export function listLocalTuiProcesses(
|
||||
}
|
||||
const pidValue = Reflect.get(entry, "ProcessId");
|
||||
const commandValue = Reflect.get(entry, "CommandLine");
|
||||
const ownerSidValue = Reflect.get(entry, "OwnerSid");
|
||||
const currentSidValue = Reflect.get(entry, "CurrentSid");
|
||||
const pid = typeof pidValue === "number" ? pidValue : undefined;
|
||||
const command = typeof commandValue === "string" ? commandValue.trim() : undefined;
|
||||
const startTime = pid
|
||||
@@ -141,6 +143,8 @@ export function listLocalTuiProcesses(
|
||||
: null;
|
||||
return pid &&
|
||||
pid !== (params.currentPid ?? process.pid) &&
|
||||
typeof ownerSidValue === "string" &&
|
||||
ownerSidValue === currentSidValue &&
|
||||
command &&
|
||||
isLocalTuiCommand(command, "win32")
|
||||
? [{ pid, command, ...(startTime === null ? {} : { startTime: String(startTime) }) }]
|
||||
@@ -309,6 +313,15 @@ export async function quiesceLocalTuiProcessesBeforeUpdate(
|
||||
export async function waitForLocalTuiUpdate(
|
||||
acquireLock: typeof acquireFileLock = acquireFileLock,
|
||||
): Promise<void> {
|
||||
const lock = await acquireLock(LOCAL_TUI_UPDATE_LOCK_PATH, LOCAL_TUI_UPDATE_LOCK_OPTIONS);
|
||||
await lock.release();
|
||||
for (;;) {
|
||||
try {
|
||||
const lock = await acquireLock(LOCAL_TUI_UPDATE_LOCK_PATH, LOCAL_TUI_UPDATE_LOCK_OPTIONS);
|
||||
await lock.release();
|
||||
return;
|
||||
} catch (error) {
|
||||
if (extractErrorCode(error) !== "file_lock_timeout") {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user