| author | |
| committer | |
| log | 1f7e26d3602c2c6f5543b25dac8a20d97a9fe3b2 |
| tree | 5d1fdc4aeec6a8cd0e4ce8e8026b52a9cb8b8aea |
| parent | 76765cb2aed4394bf710c2bb4d026ec80115f593 |
| signature | Signed by SSH key SHA256:52mNGHRsVFBDED9IAX5pe+LRWUefqTbxEReunq21QvU |
Provide Nomad render output while checking that current exists before NixOS activates host units.
Assisted-by: gpt-63 files changed, 16 insertions(+), 1 deletions(-)
tools/dashboard-deploy-test.py+13| ... | @@ -173,6 +173,19 @@ class DeploymentBoundary(unittest.TestCase): | ... | @@ -173,6 +173,19 @@ class DeploymentBoundary(unittest.TestCase): |
| 173 | self.assertEqual(self.call("deploy.run", id=identity), {"lines": ["legacy", "\ufffd"], "code": 0}) | 173 | self.assertEqual(self.call("deploy.run", id=identity), {"lines": ["legacy", "\ufffd"], "code": 0}) |
| 174 | executed.assert_not_called() | 174 | executed.assert_not_called() |
| 175 | 175 | ||
| 176 | def test_first_activation_exposes_current_before_starting_host_units(self): | ||
| 177 | (self.root / "current").unlink() | ||
| 178 | |||
| 179 | def execute(argv, **kwargs): | ||
| 180 | if argv[:2] == ["nixos-rebuild", "switch"]: | ||
| 181 | self.assertEqual((self.root / "current").resolve(), self.snapshot) | ||
| 182 | output = 'job "fixture" {\n' if argv[-1] == "render" else '"leader"' | ||
| 183 | return subprocess.CompletedProcess(argv, 0, stdout=output, stderr="") | ||
| 184 | |||
| 185 | with patch.object(release.subprocess, "run", side_effect=execute): | ||
| 186 | self.assertIsNone(release.activate(self.version, initial=True)) | ||
| 187 | self.assertEqual(release.current_release(), self.version) | ||
| 188 | |||
| 176 | def test_state_reads_reject_symlinks_and_large_files(self): | 189 | def test_state_reads_reject_symlinks_and_large_files(self): |
| 177 | source = self.root / "fixture" | 190 | source = self.root / "fixture" |
| 178 | source.write_bytes(b"x" * 200) | 191 | source.write_bytes(b"x" * 200) |
tools/dashboard-run.py+1-1| ... | @@ -344,7 +344,7 @@ def handle(request): | ... | @@ -344,7 +344,7 @@ def handle(request): |
| 344 | found.append((name, 0, text)) | 344 | found.append((name, 0, text)) |
| 345 | else: | 345 | else: |
| 346 | source, version = value["source"], value["release"] | 346 | source, version = value["source"], value["release"] |
| 347 | selected = (name.endswith("-prod-" + source + ".log") or name.endswith("-prod-" + version + ".log")) or name.endswith("-rollback-" + version + ".log") | 347 | selected = name.endswith(("-prod-" + source + ".log", "-prod-" + version + ".log", "-rollback-" + version + ".log")) |
| 348 | if not selected and not re.fullmatch(r"[0-9a-f-]{36}\.log", name): | 348 | if not selected and not re.fullmatch(r"[0-9a-f-]{36}\.log", name): |
| 349 | continue | 349 | continue |
| 350 | delta = abs(path.stat().st_mtime - value["time"]) | 350 | delta = abs(path.stat().st_mtime - value["time"]) |
tools/release.py+2| ... | @@ -158,6 +158,8 @@ def activate(release, legacy=False, initial=False): | ... | @@ -158,6 +158,8 @@ def activate(release, legacy=False, initial=False): |
| 158 | print(result.stdout.strip(), flush=True) | 158 | print(result.stdout.strip(), flush=True) |
| 159 | backup = result.stdout.split("backup=", 1)[1].split()[0] | 159 | backup = result.stdout.split("backup=", 1)[1].split()[0] |
| 160 | if old_digest != digest: | 160 | if old_digest != digest: |
| 161 | if current is None: | ||
| 162 | (ROOT / "current").symlink_to(path) | ||
| 161 | subprocess.run(["nixos-rebuild", "switch", "--flake", f"path:{path}#{configuration}"], check=True) | 163 | subprocess.run(["nixos-rebuild", "switch", "--flake", f"path:{path}#{configuration}"], check=True) |
| 162 | next_link = ROOT / ("next-" + release) | 164 | next_link = ROOT / ("next-" + release) |
| 163 | next_link.unlink(missing_ok=True) | 165 | next_link.unlink(missing_ok=True) |