noqt commited on
Commit
f4e8387
·
1 Parent(s): de7b65d

fix: repair public 1.0 operator paths

Browse files
CHANGELOG.md CHANGED
@@ -6,6 +6,8 @@
6
  0.8.1 and 0.9 milestones.
7
  - Bind the candidate to deterministic qualification, packaged-artifact
8
  verification and the adaptive campaign evidence plan.
 
 
9
  - Keep publication, signing, tagging and external deployment as separate
10
  decisions.
11
 
 
6
  0.8.1 and 0.9 milestones.
7
  - Bind the candidate to deterministic qualification, packaged-artifact
8
  verification and the adaptive campaign evidence plan.
9
+ - Make the public first-kill path default to `v1.0.0` and make the support
10
+ helper use the installed, root-owned zipapp shipped by the verified bundle.
11
  - Keep publication, signing, tagging and external deployment as separate
12
  decisions.
13
 
README.md CHANGED
@@ -103,10 +103,11 @@ sudo /usr/bin/python3 -I -S scripts/first_kill.py \
103
 
104
  The preflight is read-only: it checks the operator, supported host features,
105
  empty installation targets, required tool availability, and that the local
106
- annotated published-release tag resolves to its qualified commit. It makes no network
107
- request and creates no workspace, GPG home, build, installation or service.
108
- It does not verify the release signature, downloaded assets, functional build,
109
- installation or containment; those checks happen only in the full run.
 
110
 
111
  ### Probe the containment primitive
112
 
@@ -245,7 +246,7 @@ candidate; names alone never trigger a kill.
245
 
246
  To make a report reproducible, create a local JSON bundle containing host
247
  compatibility, supervisor health, workload counts and redacted detection
248
- summaries:
249
 
250
  ```sh
251
  sudo /usr/bin/python3 -I -S scripts/support_bundle.py \
 
103
 
104
  The preflight is read-only: it checks the operator, supported host features,
105
  empty installation targets, required tool availability, and that the local
106
+ published-release reference is an annotated tag resolving to a commit. It makes
107
+ no network request and creates no workspace, GPG home, build, installation or
108
+ service. It does not verify the tag signature, downloaded assets, functional
109
+ build, installation or containment; the full run verifies the signature and
110
+ requires the signed tag commit to match the release manifest.
111
 
112
  ### Probe the containment primitive
113
 
 
246
 
247
  To make a report reproducible, create a local JSON bundle containing host
248
  compatibility, supervisor health, workload counts and redacted detection
249
+ summaries after Eggcracker is installed:
250
 
251
  ```sh
252
  sudo /usr/bin/python3 -I -S scripts/support_bundle.py \
RELEASE_NOTES.md CHANGED
@@ -7,6 +7,10 @@ AI profiles, direct cgroup-v2 containment, offline selected-workload and
7
  execution boundaries, watchdog recovery, and root-controlled exact relaunch
8
  lockdown.
9
 
 
 
 
 
10
  The candidate is not tagged, signed or published. Its release decision is
11
  bound to the exact commit, artifact hashes, disposable Ubuntu qualification
12
  evidence and the internal black-box/source-informed campaign. Unsupported
 
7
  execution boundaries, watchdog recovery, and root-controlled exact relaunch
8
  lockdown.
9
 
10
+ The public first-kill helper defaults to `v1.0.0`. The packaged support helper
11
+ delegates to the installed root-owned zipapp, so the documented command works
12
+ from the verified Linux release bundle without importing a mutable checkout.
13
+
14
  The candidate is not tagged, signed or published. Its release decision is
15
  bound to the exact commit, artifact hashes, disposable Ubuntu qualification
16
  evidence and the internal black-box/source-informed campaign. Unsupported
scripts/first_kill.py CHANGED
@@ -33,8 +33,7 @@ except ImportError: # pragma: no cover - first-kill is a native Linux command
33
 
34
 
35
  REPOSITORY = "noqt/Lumi-Eggcracker"
36
- DEFAULT_TAG = "v0.5.0"
37
- DEFAULT_TAG_COMMIT = "eb342808f56cdc213c0861726d5309a146965bef"
38
  RELEASE_KEY_FINGERPRINT = "53786DEB001459956A2E1B86A3F29F7A27636DC7"
39
  WORKLOAD_USER = "lumi-eggcracker-workload"
40
  INSTALL_TARGETS = (
@@ -236,9 +235,12 @@ def local_release_identity(root: Path, tag: str) -> str:
236
  raise FirstKillError("could not inspect the qualified local release tag") from error
237
  if kind.returncode or kind.stdout.strip() != "tag":
238
  raise FirstKillError(f"the local {tag} reference is missing or is not an annotated tag")
239
- if resolved.returncode or resolved.stdout.strip() != DEFAULT_TAG_COMMIT:
240
- raise FirstKillError(f"the local {tag} tag does not resolve to the qualified commit")
241
- return DEFAULT_TAG_COMMIT
 
 
 
242
 
243
 
244
  def run_preflight(operator_value: str | None, tag: str) -> int:
@@ -258,9 +260,9 @@ def run_preflight(operator_value: str | None, tag: str) -> int:
258
  "local_annotated_tag_identity",
259
  ],
260
  "mode": "preflight-only",
261
- "qualified_commit": commit,
262
  "result": "PREFLIGHT_PASSED",
263
  "tag": tag,
 
264
  },
265
  indent=2,
266
  sort_keys=True,
@@ -297,7 +299,7 @@ def verify_tag(root: Path, tag: str, key: Path) -> str:
297
  def release_files(tag: str, workspace: Path) -> tuple[Path, Path]:
298
  version = tag.removeprefix("v")
299
  if not version.replace(".", "").isdigit() or version.count(".") != 2:
300
- raise FirstKillError("tag must look like v0.5.0")
301
  base = f"https://github.com/{REPOSITORY}/releases/download/{tag}"
302
  sums = workspace / "SHA256SUMS"
303
  bundle = workspace / f"lumi-eggcracker-{version}-linux.zip"
 
33
 
34
 
35
  REPOSITORY = "noqt/Lumi-Eggcracker"
36
+ DEFAULT_TAG = "v1.0.0"
 
37
  RELEASE_KEY_FINGERPRINT = "53786DEB001459956A2E1B86A3F29F7A27636DC7"
38
  WORKLOAD_USER = "lumi-eggcracker-workload"
39
  INSTALL_TARGETS = (
 
235
  raise FirstKillError("could not inspect the qualified local release tag") from error
236
  if kind.returncode or kind.stdout.strip() != "tag":
237
  raise FirstKillError(f"the local {tag} reference is missing or is not an annotated tag")
238
+ commit = resolved.stdout.strip()
239
+ if resolved.returncode or len(commit) != 40 or any(
240
+ character not in "0123456789abcdef" for character in commit.lower()
241
+ ):
242
+ raise FirstKillError(f"the local {tag} tag does not resolve to a commit")
243
+ return commit
244
 
245
 
246
  def run_preflight(operator_value: str | None, tag: str) -> int:
 
260
  "local_annotated_tag_identity",
261
  ],
262
  "mode": "preflight-only",
 
263
  "result": "PREFLIGHT_PASSED",
264
  "tag": tag,
265
+ "tag_commit": commit,
266
  },
267
  indent=2,
268
  sort_keys=True,
 
299
  def release_files(tag: str, workspace: Path) -> tuple[Path, Path]:
300
  version = tag.removeprefix("v")
301
  if not version.replace(".", "").isdigit() or version.count(".") != 2:
302
+ raise FirstKillError("tag must look like v1.0.0")
303
  base = f"https://github.com/{REPOSITORY}/releases/download/{tag}"
304
  sums = workspace / "SHA256SUMS"
305
  bundle = workspace / f"lumi-eggcracker-{version}-linux.zip"
scripts/support_bundle.py CHANGED
@@ -1,17 +1,53 @@
1
- """Write a local redacted support bundle from a source checkout."""
2
 
3
  from __future__ import annotations
4
 
5
  import argparse
6
- import sys
 
7
  from pathlib import Path
8
 
9
- ROOT = Path(__file__).resolve().parents[1]
10
- sys.path.insert(0, str(ROOT / "src"))
11
 
12
- from lumi_eggcracker.support_bundle import main
13
 
14
- parser = argparse.ArgumentParser(description="write a local redacted Eggcracker support bundle")
15
- parser.add_argument("--output", required=True, type=Path)
16
- args = parser.parse_args()
17
- raise SystemExit(main(args.output))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Write a local redacted support bundle through the installed zipapp."""
2
 
3
  from __future__ import annotations
4
 
5
  import argparse
6
+ import os
7
+ import stat
8
  from pathlib import Path
9
 
10
+ INSTALLED_APP = Path("/usr/local/lib/lumi-eggcracker/lumi-eggcracker.pyz")
 
11
 
 
12
 
13
+ def validated_installed_app(path: Path = INSTALLED_APP) -> Path:
14
+ try:
15
+ metadata = path.lstat()
16
+ except FileNotFoundError as error:
17
+ raise RuntimeError("Eggcracker is not installed") from error
18
+ if not stat.S_ISREG(metadata.st_mode) or path.is_symlink():
19
+ raise RuntimeError("installed Eggcracker zipapp is not a regular file")
20
+ if metadata.st_uid != 0 or metadata.st_mode & 0o022:
21
+ raise RuntimeError("installed Eggcracker zipapp has unsafe ownership or mode")
22
+ return path
23
+
24
+
25
+ def main(argv: list[str] | None = None) -> int:
26
+ parser = argparse.ArgumentParser(
27
+ description="write a local redacted Eggcracker support bundle"
28
+ )
29
+ parser.add_argument("--output", required=True, type=Path)
30
+ args = parser.parse_args(argv)
31
+ if os.geteuid() != 0:
32
+ parser.error("support bundle must run as root")
33
+ try:
34
+ app = validated_installed_app()
35
+ except RuntimeError as error:
36
+ parser.error(str(error))
37
+ os.execv(
38
+ "/usr/bin/python3",
39
+ [
40
+ "/usr/bin/python3",
41
+ "-I",
42
+ "-S",
43
+ str(app),
44
+ "support-bundle",
45
+ "--output",
46
+ str(args.output),
47
+ ],
48
+ )
49
+ raise RuntimeError("exec returned unexpectedly")
50
+
51
+
52
+ if __name__ == "__main__":
53
+ raise SystemExit(main())
tests/test_first_kill.py CHANGED
@@ -12,6 +12,7 @@ from pathlib import Path
12
  from unittest import mock
13
 
14
  ROOT = Path(__file__).resolve().parents[1]
 
15
  SPEC = importlib.util.spec_from_file_location("first_kill", ROOT / "scripts" / "first_kill.py")
16
  if SPEC is None or SPEC.loader is None:
17
  raise RuntimeError("cannot load first-kill script")
@@ -20,6 +21,9 @@ SPEC.loader.exec_module(first_kill)
20
 
21
 
22
  class FirstKillTests(unittest.TestCase):
 
 
 
23
  def test_preflight_exits_before_every_mutating_or_network_step(self) -> None:
24
  output = io.StringIO()
25
  with (
@@ -29,7 +33,7 @@ class FirstKillTests(unittest.TestCase):
29
  mock.patch.object(
30
  first_kill,
31
  "local_release_identity",
32
- return_value=first_kill.DEFAULT_TAG_COMMIT,
33
  ),
34
  mock.patch.object(first_kill, "prepare_workspace") as prepare_workspace,
35
  mock.patch.object(first_kill, "release_files") as release_files,
@@ -55,6 +59,8 @@ class FirstKillTests(unittest.TestCase):
55
  forbidden.assert_not_called()
56
  summary = json.loads(output.getvalue())
57
  self.assertEqual("PREFLIGHT_PASSED", summary["result"])
 
 
58
  self.assertFalse(summary["changes_made"])
59
  self.assertNotIn("/checkout", output.getvalue())
60
 
@@ -89,16 +95,25 @@ class FirstKillTests(unittest.TestCase):
89
  self.assertNotIn(canary, errors.getvalue())
90
  self.assertIn("operator account does not exist", errors.getvalue())
91
 
92
- def test_local_release_identity_requires_annotated_pinned_tag(self) -> None:
93
  annotated = mock.Mock(returncode=0, stdout="tag\n")
94
- resolved = mock.Mock(returncode=0, stdout=f"{first_kill.DEFAULT_TAG_COMMIT}\n")
95
  with mock.patch.object(first_kill, "run", side_effect=[annotated, resolved]):
96
  result = first_kill.local_release_identity(Path("/checkout"), first_kill.DEFAULT_TAG)
97
- self.assertEqual(first_kill.DEFAULT_TAG_COMMIT, result)
 
 
 
 
 
 
 
 
 
98
 
99
  def test_local_release_identity_rejects_lightweight_tag(self) -> None:
100
  lightweight = mock.Mock(returncode=0, stdout="commit\n")
101
- resolved = mock.Mock(returncode=0, stdout=f"{first_kill.DEFAULT_TAG_COMMIT}\n")
102
  with (
103
  mock.patch.object(first_kill, "run", side_effect=[lightweight, resolved]),
104
  self.assertRaisesRegex(first_kill.FirstKillError, "not an annotated tag"),
 
12
  from unittest import mock
13
 
14
  ROOT = Path(__file__).resolve().parents[1]
15
+ TAG_COMMIT = "a" * 40
16
  SPEC = importlib.util.spec_from_file_location("first_kill", ROOT / "scripts" / "first_kill.py")
17
  if SPEC is None or SPEC.loader is None:
18
  raise RuntimeError("cannot load first-kill script")
 
21
 
22
 
23
  class FirstKillTests(unittest.TestCase):
24
+ def test_default_release_identity_is_the_1_0_candidate(self) -> None:
25
+ self.assertEqual("v1.0.0", first_kill.DEFAULT_TAG)
26
+
27
  def test_preflight_exits_before_every_mutating_or_network_step(self) -> None:
28
  output = io.StringIO()
29
  with (
 
33
  mock.patch.object(
34
  first_kill,
35
  "local_release_identity",
36
+ return_value=TAG_COMMIT,
37
  ),
38
  mock.patch.object(first_kill, "prepare_workspace") as prepare_workspace,
39
  mock.patch.object(first_kill, "release_files") as release_files,
 
59
  forbidden.assert_not_called()
60
  summary = json.loads(output.getvalue())
61
  self.assertEqual("PREFLIGHT_PASSED", summary["result"])
62
+ self.assertEqual(TAG_COMMIT, summary["tag_commit"])
63
+ self.assertNotIn("qualified_commit", summary)
64
  self.assertFalse(summary["changes_made"])
65
  self.assertNotIn("/checkout", output.getvalue())
66
 
 
95
  self.assertNotIn(canary, errors.getvalue())
96
  self.assertIn("operator account does not exist", errors.getvalue())
97
 
98
+ def test_local_release_identity_requires_annotated_tag(self) -> None:
99
  annotated = mock.Mock(returncode=0, stdout="tag\n")
100
+ resolved = mock.Mock(returncode=0, stdout=f"{TAG_COMMIT}\n")
101
  with mock.patch.object(first_kill, "run", side_effect=[annotated, resolved]):
102
  result = first_kill.local_release_identity(Path("/checkout"), first_kill.DEFAULT_TAG)
103
+ self.assertEqual(TAG_COMMIT, result)
104
+
105
+ def test_local_release_identity_rejects_non_commit_output(self) -> None:
106
+ annotated = mock.Mock(returncode=0, stdout="tag\n")
107
+ malformed = mock.Mock(returncode=0, stdout="not-a-commit\n")
108
+ with (
109
+ mock.patch.object(first_kill, "run", side_effect=[annotated, malformed]),
110
+ self.assertRaisesRegex(first_kill.FirstKillError, "does not resolve"),
111
+ ):
112
+ first_kill.local_release_identity(Path("/checkout"), first_kill.DEFAULT_TAG)
113
 
114
  def test_local_release_identity_rejects_lightweight_tag(self) -> None:
115
  lightweight = mock.Mock(returncode=0, stdout="commit\n")
116
+ resolved = mock.Mock(returncode=0, stdout=f"{TAG_COMMIT}\n")
117
  with (
118
  mock.patch.object(first_kill, "run", side_effect=[lightweight, resolved]),
119
  self.assertRaisesRegex(first_kill.FirstKillError, "not an annotated tag"),
tests/test_support_bundle.py CHANGED
@@ -1,15 +1,57 @@
1
  from __future__ import annotations
2
 
 
3
  import os
4
  import tempfile
5
  import unittest
6
  from pathlib import Path
 
7
 
8
  from lumi_eggcracker import support_bundle
9
  from lumi_eggcracker.jsonio import JsonInputError
10
 
 
 
 
 
 
 
 
 
 
11
 
12
  class SupportBundleTests(unittest.TestCase):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  @staticmethod
14
  def query(action: str, **_args: object) -> dict[str, object]:
15
  if action == "doctor":
 
1
  from __future__ import annotations
2
 
3
+ import importlib.util
4
  import os
5
  import tempfile
6
  import unittest
7
  from pathlib import Path
8
+ from unittest import mock
9
 
10
  from lumi_eggcracker import support_bundle
11
  from lumi_eggcracker.jsonio import JsonInputError
12
 
13
+ ROOT = Path(__file__).resolve().parents[1]
14
+ SCRIPT_SPEC = importlib.util.spec_from_file_location(
15
+ "support_bundle_script", ROOT / "scripts" / "support_bundle.py"
16
+ )
17
+ if SCRIPT_SPEC is None or SCRIPT_SPEC.loader is None:
18
+ raise RuntimeError("cannot load support-bundle script")
19
+ support_bundle_script = importlib.util.module_from_spec(SCRIPT_SPEC)
20
+ SCRIPT_SPEC.loader.exec_module(support_bundle_script)
21
+
22
 
23
  class SupportBundleTests(unittest.TestCase):
24
+ @unittest.skipUnless(os.name == "posix", "installed helper is native-Linux behavior")
25
+ def test_release_helper_delegates_to_installed_zipapp(self) -> None:
26
+ installed = Path("/usr/local/lib/lumi-eggcracker/lumi-eggcracker.pyz")
27
+ with (
28
+ mock.patch.object(support_bundle_script.os, "geteuid", return_value=0),
29
+ mock.patch.object(
30
+ support_bundle_script,
31
+ "validated_installed_app",
32
+ return_value=installed,
33
+ ),
34
+ mock.patch.object(
35
+ support_bundle_script.os,
36
+ "execv",
37
+ side_effect=OSError("sentinel"),
38
+ ) as execute,
39
+ self.assertRaisesRegex(OSError, "sentinel"),
40
+ ):
41
+ support_bundle_script.main(["--output", "/tmp/support.json"])
42
+ execute.assert_called_once_with(
43
+ "/usr/bin/python3",
44
+ [
45
+ "/usr/bin/python3",
46
+ "-I",
47
+ "-S",
48
+ str(installed),
49
+ "support-bundle",
50
+ "--output",
51
+ "/tmp/support.json",
52
+ ],
53
+ )
54
+
55
  @staticmethod
56
  def query(action: str, **_args: object) -> dict[str, object]:
57
  if action == "doctor":