systemd: serve kernel-log, the kernel's messages of one boot (issue 1975)
journalctl --dmesg --boot=N under the same escalation, window, priority, fixed-string match, 2000-line cap and redaction as the journal verb (shapeLines is the one filter both use); a boot is 0 or a negative whole number, refused otherwise before anything runs. No scope: the kernel belongs to no manager. Builds: issue 1975, the operator's request of 2026-11-12 (the lead's handover; no design line names the verb) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
@@ -241,3 +241,75 @@ func TestFailedIsOnTheSeatAndNarrowsToAScope(t *testing.T) {
|
||||
t.Fatal("a scope that is none was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
// The kernel-log verb (issue 1975): the kernel's messages of one boot, in the journal verb's window, priority,
|
||||
// match, cap and redaction, and a boot named 0, -1, and so on.
|
||||
func TestTheKernelLogIsOneBootsMessagesInTheJournalsForms(t *testing.T) {
|
||||
var calls []call
|
||||
m := journalOf([]string{"2026-11-12T10:00:00+0100 host kernel: usb 1-1: new device"}, "", &calls)
|
||||
got, err := m.KernelLog(JournalQuery{Lines: 50, Since: "-2h", Priority: "err", Boot: "-1"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
want := "--no-pager --output=short-iso --dmesg --boot=-1 --since=-2h --priority=3 --lines=50"
|
||||
if a := strings.Join(journalArgs(t, calls), " "); a != want {
|
||||
t.Fatalf("journalctl was given\n %s\nnot\n %s", a, want)
|
||||
}
|
||||
if calls[0].cmd != "sudo" || got["boot"] != "-1" || got["count"] != 1 {
|
||||
t.Fatalf("not escalated, or the answer is wrong: %+v %+v", calls[0], got)
|
||||
}
|
||||
calls = nil
|
||||
if _, err := m.KernelLog(JournalQuery{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if a := strings.Join(journalArgs(t, calls), " "); a != "--no-pager --output=short-iso --dmesg --boot=0 --lines=100" {
|
||||
t.Fatalf("the default is this boot and a hundred lines: %s", a)
|
||||
}
|
||||
// Arguments arrive as the seat's strings or as numbers.
|
||||
for _, a := range []map[string]any{{"boot": float64(-2)}, {"boot": "-2"}} {
|
||||
q, err := journalQuery(a)
|
||||
if err != nil || q.Boot != "-2" {
|
||||
t.Errorf("%v: %+v %v", a, q, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestAKernelLogBootIsRefusedBeforeAnythingRunsUnlessItIsZeroOrBefore(t *testing.T) {
|
||||
for _, bad := range []string{"1", "abc", "--user", "-1 --merge", "-10000", "0x1", "-1;id"} {
|
||||
var calls []call
|
||||
m := journalOf(nil, "", &calls)
|
||||
if _, err := m.KernelLog(JournalQuery{Boot: bad}); err == nil {
|
||||
t.Errorf("boot %q accepted", bad)
|
||||
}
|
||||
if len(calls) != 0 {
|
||||
t.Errorf("boot %q reached journalctl: %v", bad, calls)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTheKernelLogKeepsTheCapTheMatchAndTheRedaction(t *testing.T) {
|
||||
var calls []call
|
||||
m := journalOf([]string{"k one", "k password=hunter2secretvalue here", "k two"}, "", &calls)
|
||||
got, err := m.KernelLog(JournalQuery{Match: "k t", Lines: 5000})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if a := strings.Join(journalArgs(t, calls), " "); !strings.HasSuffix(a, fmt.Sprintf("--lines=%d", MatchScan)) {
|
||||
t.Errorf("a match scans the window's last %d lines: %s", MatchScan, a)
|
||||
}
|
||||
if lines := got["lines"].([]string); len(lines) != 1 || lines[0] != "k two" {
|
||||
t.Errorf("the match kept %v", lines)
|
||||
}
|
||||
calls = nil
|
||||
m = journalOf([]string{"k password=hunter2secretvalue here"}, "", &calls)
|
||||
got, err = m.KernelLog(JournalQuery{Lines: 5000})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if a := strings.Join(journalArgs(t, calls), " "); !strings.HasSuffix(a, "--lines=2000") {
|
||||
t.Errorf("the cap is 2000: %s", a)
|
||||
}
|
||||
if strings.Contains(fmt.Sprint(got["lines"]), "hunter2") || got["redacted"] == nil {
|
||||
t.Errorf("a secret in a kernel line was answered: %v", got)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user