Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions packages/fleet-core/src/recipes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,39 @@ describe('check-updates', () => {
}, 90_000)
})

describe('no status recipe is ever silent', () => {
/*
* A status command that prints nothing is indistinguishable from a broken
* one. `who || w` shipped exactly that: `who` reads utmp, which is routinely
* empty on a systemd host with pty-less SSH sessions, and it exits 0 either
* way — so `||` never reached the fallback and the recipe reported nothing
* on a machine with users logged into it.
*/
const reporting = BUILTIN_RECIPES.filter((entry) => entry.name !== 'upgrade')

for (const entry of reporting) {
it(`${entry.name} says something`, async () => {
const binary = entry.interpreter === 'bash' ? 'bash' : '/bin/sh'
const { code, stdout } = await runScript(binary, entry.script)
expect(code).toBe(0)
expect(stdout.trim(), `${entry.name} produced no output`).not.toBe('')
}, 90_000)
}
})

describe('who', () => {
it('falls back on empty output, not on a non-zero exit', () => {
// `||` cannot see the difference, and the difference is the whole bug.
const script = findRecipe('who')!.script
expect(script).not.toMatch(/who\s*\|\|/)
expect(script).toMatch(/-z "\$found"/)
})

it('states that nobody is logged in rather than printing nothing', () => {
expect(findRecipe('who')!.script).toMatch(/no interactive logins/)
})
})

describe('reboot-required', () => {
it('succeeds when a reboot is needed but no package list exists', async () => {
// The exact case the old `[ -f pkgs ] && cat pkgs` form got wrong: its
Expand Down
22 changes: 21 additions & 1 deletion packages/fleet-core/src/recipes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,27 @@ fi`.trim(),
id: 'builtin:who',
name: 'who',
description: 'Who is logged in right now.',
script: 'who || w',
/*
* `who || w` was wrong, and wrong in a way that looked fine.
*
* `who` reads utmp, which on a systemd host with pty-less SSH sessions is
* routinely empty while people are very much logged in — and it exits 0
* either way. So `||` never reached `w`, and the recipe reported an empty
* result on a machine with users on it. The failure mode here is empty
* output, not a non-zero exit, and `||` cannot see the difference.
*
* It also ends by saying so out loud. A status command that prints
* nothing is indistinguishable from a broken one, which is exactly how
* this got reported.
*/
script: `
found=$(who 2>/dev/null)
[ -z "$found" ] && found=$(w -h 2>/dev/null)
if [ -n "$found" ]; then
printf '%s\n' "$found"
else
echo "no interactive logins on this host"
fi`.trim(),
timeoutSeconds: 30,
}),
]
Expand Down
Loading