mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-09-10 02:25:56 +00:00
Reset Podman qualification storage on teardown
This commit is contained in:
@@ -7347,10 +7347,12 @@ semantic-only report and racing the evidence assertion.
|
||||
Cleanup removes the exact fixture containers through both still-live runtime
|
||||
APIs before stopping their services or deleting storage, so Podman namespace
|
||||
and shared-memory mounts cannot outlive the state they protect. After both
|
||||
runtime services and the delegated user manager stop, cleanup waits until the
|
||||
kernel mount table contains no mount at or below any dedicated runtime state
|
||||
root before deleting that state; an empty runtime inventory or a successful
|
||||
systemd stop alone is not mount-release evidence.
|
||||
runtime services stop, Podman cleanup resets each rootless and rootful storage
|
||||
identity through the local runtime CLI before the delegated user manager is
|
||||
stopped. Cleanup then waits until the kernel mount table contains no mount at
|
||||
or below any dedicated runtime state root before deleting that state; an empty
|
||||
runtime inventory or a successful systemd stop alone is not mount-release
|
||||
evidence.
|
||||
The wrapper must compile every Go artifact with mandatory VCS stamping so a
|
||||
missing revision or unavailable clean-worktree proof fails before live evidence
|
||||
can be emitted; the receipt and validator retain the exact artifact hashes and
|
||||
|
||||
@@ -269,7 +269,9 @@ Direct recovery is complete only after the full stable telemetry digest is
|
||||
observed; the first semantic-only report cannot satisfy the qualification wait.
|
||||
Final cleanup removes the exact rootless and rootful fixture containers while
|
||||
both runtime APIs are live, then stops the services and delegated user manager.
|
||||
It deletes runtime state only after the kernel mount table proves that no mount
|
||||
After the services stop, Podman cleanup uses the local runtime CLI to reset each
|
||||
rootless and rootful storage identity before stopping the user manager. It
|
||||
deletes runtime state only after the kernel mount table proves that no mount
|
||||
remains at or below any dedicated runtime root; container inventory and unit
|
||||
state alone cannot authorize storage deletion.
|
||||
The outer wrapper forgets a tracked container only after strict labeled removal
|
||||
|
||||
@@ -429,6 +429,7 @@ func TestSecureRuntimeRootlessQualification(t *testing.T) {
|
||||
rootlessQualRemoveFixtures(t, daemon)
|
||||
rootlessQualStopUnit(t, daemon.rootlessUnit)
|
||||
rootlessQualStopUnit(t, daemon.rootfulUnit)
|
||||
rootlessQualResetRuntimeStorage(t, daemon)
|
||||
rootlessQualStopUserManager(t, daemon)
|
||||
rootlessQualWaitRuntimeMountsReleased(t, daemon, 30*time.Second)
|
||||
rootlessQualRemoveRuntimeState(t, daemon)
|
||||
@@ -1263,6 +1264,27 @@ func rootlessQualRemoveFixtures(t *testing.T, d rootlessQualDaemon) {
|
||||
rootlessQualRemoveFixtureSet(t, rootlessQualCLI(d, false))
|
||||
}
|
||||
|
||||
func rootlessQualResetRuntimeStorage(t *testing.T, d rootlessQualDaemon) {
|
||||
t.Helper()
|
||||
for _, command := range rootlessQualRuntimeResetCommands(d) {
|
||||
if len(command) == 0 {
|
||||
t.Fatal("empty runtime storage reset command")
|
||||
}
|
||||
rootlessQualCommand(t, 60*time.Second, command[0], command[1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
func rootlessQualRuntimeResetCommands(d rootlessQualDaemon) [][]string {
|
||||
if d.runtime != "podman" {
|
||||
return nil
|
||||
}
|
||||
const cleanPath = "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
return [][]string{
|
||||
{"runuser", "-u", "pulse-agent", "--", "env", "-i", "HOME=" + d.home, "XDG_RUNTIME_DIR=" + filepath.Join("/run/user", strconv.Itoa(d.uid)), cleanPath, "/usr/bin/podman", "system", "reset", "--force"},
|
||||
{"/usr/bin/env", "-i", cleanPath, "/usr/bin/podman", "system", "reset", "--force"},
|
||||
}
|
||||
}
|
||||
|
||||
func rootlessQualRemoveFixtureSet(t *testing.T, cli []string) {
|
||||
t.Helper()
|
||||
if len(cli) == 0 {
|
||||
@@ -1625,6 +1647,21 @@ func TestRootlessQualificationMountReleaseUsesExactKernelPaths(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRootlessQualificationPodmanResetsBothStorageIdentitiesLocally(t *testing.T) {
|
||||
d := rootlessQualDaemon{runtime: "podman", uid: 996, home: "/var/lib/pulse-rootless"}
|
||||
got := rootlessQualRuntimeResetCommands(d)
|
||||
want := [][]string{
|
||||
{"runuser", "-u", "pulse-agent", "--", "env", "-i", "HOME=/var/lib/pulse-rootless", "XDG_RUNTIME_DIR=/run/user/996", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "/usr/bin/podman", "system", "reset", "--force"},
|
||||
{"/usr/bin/env", "-i", "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "/usr/bin/podman", "system", "reset", "--force"},
|
||||
}
|
||||
if !slices.EqualFunc(got, want, slices.Equal[[]string]) {
|
||||
t.Fatalf("Podman reset commands = %q, want %q", got, want)
|
||||
}
|
||||
if commands := rootlessQualRuntimeResetCommands(rootlessQualDaemon{runtime: "docker"}); len(commands) != 0 {
|
||||
t.Fatalf("Docker cleanup unexpectedly gained Podman reset commands: %q", commands)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRootlessQualificationStopAcceptsCollectedTransientUnit(t *testing.T) {
|
||||
tempDir := t.TempDir()
|
||||
logPath := filepath.Join(tempDir, "systemctl.log")
|
||||
|
||||
Reference in New Issue
Block a user