diff --git a/src/main/managed-server/host-state/orcad-state-snapshot-shell.test.ts b/src/main/managed-server/host-state/orcad-state-snapshot-shell.test.ts index 565804db789..29ba3c9d81d 100644 --- a/src/main/managed-server/host-state/orcad-state-snapshot-shell.test.ts +++ b/src/main/managed-server/host-state/orcad-state-snapshot-shell.test.ts @@ -1,4 +1,5 @@ import { + chmodSync, existsSync, mkdirSync, mkdtempSync, @@ -115,6 +116,25 @@ describe.skipIf(process.platform === 'win32')('snapshot commands on a real shell expect(existsSync(join(root, '.orcad-state-restore-stage'))).toBe(false) }) + it('captures on a BusyBox before 1.30, whose timeout only takes `-t SECS`', async () => { + const bin = join(base, 'bin') + mkdirSync(bin) + // Old BusyBox reads a bare `900` as the program to run. + writeFileSync( + join(bin, 'timeout'), + '#!/bin/sh\n[ "$1" = "-t" ] || exit 127\nshift 2\n[ "$1" = "-s" ] && shift 2\nexec "$@"\n' + ) + chmodSync(join(bin, 'timeout'), 0o755) + + expect( + parseOrcadSnapshotCapture( + await sh(captureOrcadStateSnapshotCommand(posix, root, snapshot, remoteBase), { + PATH: `${bin}:${process.env.PATH ?? ''}` + }) + ) + ).toBe('captured') + }) + it('keeps live state when the archive cannot be extracted', async () => { await sh(captureOrcadStateSnapshotCommand(posix, root, snapshot, remoteBase)) writeFileSync(join(snapshot, 'state.tar'), 'not a tar archive') diff --git a/src/main/managed-server/host-state/orcad-state-snapshot.ts b/src/main/managed-server/host-state/orcad-state-snapshot.ts index f7ec816e289..fbcee78aab6 100644 --- a/src/main/managed-server/host-state/orcad-state-snapshot.ts +++ b/src/main/managed-server/host-state/orcad-state-snapshot.ts @@ -135,7 +135,9 @@ export function serializedStateMutationCommand( 'else "$@"; fi; };', // Why timeout inside the group: KILL then reaches tar and rm, not only the shell. // The deadline is a word list, so the script is sent once, not once per branch. - `orca_deadline=; command -v timeout >/dev/null 2>&1 && orca_deadline="timeout -s KILL ${ORCAD_STATE_MUTATION_DEADLINE_SECONDS}";`, + // BusyBox before 1.30 spells it `timeout -t SECS`, as the room probe found. + `orca_deadline=; if timeout 1 true 2>/dev/null; then orca_deadline="timeout -s KILL ${ORCAD_STATE_MUTATION_DEADLINE_SECONDS}";`, + `elif timeout -t 1 true 2>/dev/null; then orca_deadline="timeout -t ${ORCAD_STATE_MUTATION_DEADLINE_SECONDS} -s KILL"; fi;`, `orca_state_group $orca_deadline ${run};`, `status=$?; ${owned ? `[ "$status" -eq ${ORCAD_FENCE_LOST_EXIT} ] && exit ${ORCAD_FENCE_LOST_EXIT}; ` : ''}if [ "$status" -eq 124 ] || [ "$status" -eq 137 ]; then echo ${ORCAD_STATE_MUTATION_DEADLINE}; fi` ].join(' ')