mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-10-23 20:25:56 +00:00
Bind demo controls without broadening unrelated release proof
Keep new source paths on their own connected proof policy after the full lookup suite exposed six broadened metadata expectations. Preserve terminal no-op cancellation evidence and the runtime file owner. Contract-Neutral: Correct connected observation and verification routing within the existing demo operations and authority. Change-source: pulse-maintainer
This commit is contained in:
@@ -275,6 +275,8 @@ class Host:
|
||||
pattern = re.compile(r"^[ \t]*" + re.escape(key) + r"=.*$", re.M)
|
||||
text = pattern.sub(key + "=" + value, text) if pattern.search(text) else text.rstrip("\n") + "\n" + key + "=" + value + "\n"
|
||||
env_file.write_text(text)
|
||||
data_owner = PATHS["data"].stat()
|
||||
os.chown(env_file, data_owner.st_uid, data_owner.st_gid)
|
||||
os.chmod(env_file, 0o600)
|
||||
billing = json.loads(billing_file.read_text())
|
||||
if not isinstance(billing, dict) or not isinstance(billing.get("capabilities", []), list):
|
||||
@@ -282,6 +284,7 @@ class Host:
|
||||
billing["capabilities"] = sorted(set(billing.get("capabilities", []) + ["demo_fixtures"]))
|
||||
billing.pop("integrity", None)
|
||||
billing_file.write_text(json.dumps(billing))
|
||||
os.chown(billing_file, data_owner.st_uid, data_owner.st_gid)
|
||||
os.chmod(billing_file, 0o600)
|
||||
if unhealthy:
|
||||
for relative in DEMO_HISTORY:
|
||||
@@ -408,14 +411,14 @@ class Transaction:
|
||||
elif self.request["mode"] == "update":
|
||||
raise Failure("update-baseline-unhealthy")
|
||||
self.receipt["healthy_baseline"] = healthy_baseline
|
||||
old_handlers = {sig: signal.getsignal(sig) for sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP)}
|
||||
for sig in old_handlers:
|
||||
signal.signal(sig, cancel)
|
||||
# The no-op is observed too; an immediate healthy sample is not success.
|
||||
if self.request["mode"] == "recover" and healthy_baseline and self.host.profile_matches(self.request):
|
||||
self.watch("forward", original_version, self.host.cursors())
|
||||
self.save("healthy_noop")
|
||||
return 0
|
||||
old_handlers = {sig: signal.getsignal(sig) for sig in (signal.SIGTERM, signal.SIGINT, signal.SIGHUP)}
|
||||
for sig in old_handlers:
|
||||
signal.signal(sig, cancel)
|
||||
self.save("capturing")
|
||||
stopped = True
|
||||
self.host.stop()
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import copy
|
||||
import hashlib
|
||||
import importlib.util
|
||||
import json
|
||||
@@ -195,6 +194,16 @@ class TransactionTest(unittest.TestCase):
|
||||
self.assertFalse(receipt["mutated"])
|
||||
self.assertEqual(self.host.stops, 0)
|
||||
|
||||
def test_noop_cancellation_retains_terminal_failure_without_stopping_service(self):
|
||||
self.host.profile(request(), False)
|
||||
self.host.cancel_at = 55
|
||||
code, receipt = self.run_transaction()
|
||||
self.assertEqual(code, 1)
|
||||
self.assertEqual(receipt["status"], "refused")
|
||||
self.assertEqual(receipt["failure"], "cancelled-forward")
|
||||
self.assertEqual(self.host.stops, 0)
|
||||
self.assertFalse(receipt["mutated"])
|
||||
|
||||
def test_update_restores_complete_changed_executable_unit_and_data_after_late_failure(self):
|
||||
self.host.fail_at = 55
|
||||
code, receipt = self.run_transaction("update", "v6.4.6")
|
||||
@@ -404,8 +413,6 @@ class DispatchLifecycleTest(unittest.TestCase):
|
||||
for uncertain in (False, True):
|
||||
with self.subTest(uncertain=uncertain), tempfile.TemporaryDirectory() as directory:
|
||||
root = Path(directory) / "state"
|
||||
source = dispatcher.BOOTSTRAP.replace("pathlib.Path('/var/lib/pulse-deploy/demo')", repr(root))
|
||||
# repr(Path) is not a Python literal: bind just the fixed path.
|
||||
source = dispatcher.BOOTSTRAP.replace("'/var/lib/pulse-deploy/demo'", repr(str(root)))
|
||||
source = source.replace("root.stat().st_uid == 0", "root.stat().st_uid == os.getuid()")
|
||||
clock = [0]
|
||||
|
||||
@@ -4751,8 +4751,6 @@
|
||||
"match_files": [
|
||||
".github/ISSUE_TEMPLATE/v6_rc_feedback.yml",
|
||||
".github/scripts/check-demo-reachability.sh",
|
||||
".github/scripts/demo-runtime-transaction.py",
|
||||
".github/scripts/dispatch-demo-runtime.py",
|
||||
".github/scripts/recover-demo-runtime.sh",
|
||||
".github/scripts/resolve-demo-runtime-profile.sh",
|
||||
".github/scripts/setup-demo-ssh.sh",
|
||||
@@ -4813,13 +4811,11 @@
|
||||
"allow_same_subsystem_tests": false,
|
||||
"test_prefixes": [],
|
||||
"exact_files": [
|
||||
".github/scripts/tests/test_demo_runtime_transaction.py",
|
||||
"frontend-modern/src/components/__tests__/whatsNewModel.test.ts",
|
||||
"frontend-modern/src/utils/__tests__/docsLinks.test.ts",
|
||||
"pulse-enterprise:scripts/validate-pro-release-line_test.sh",
|
||||
"pulse-pro:scripts/tests/test_validate_paid_runtime_distribution.py",
|
||||
"scripts/installtests/build_release_assets_test.go",
|
||||
"scripts/installtests/demo_transaction_test.go",
|
||||
"scripts/release_control/internal/record_rc_to_ga_rehearsal_test.py",
|
||||
"scripts/release_control/internal/release_preflight_test.py",
|
||||
"scripts/release_control/mobile_release_gate_test.py",
|
||||
@@ -5173,6 +5169,21 @@
|
||||
"scripts/installtests/install_sh_test.go",
|
||||
"scripts/installtests/safe_profile_migration_test.go"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "demo-runtime-transaction",
|
||||
"label": "demo shared-host transaction and retained recovery proof",
|
||||
"match_prefixes": [],
|
||||
"match_files": [
|
||||
".github/scripts/demo-runtime-transaction.py",
|
||||
".github/scripts/dispatch-demo-runtime.py"
|
||||
],
|
||||
"allow_same_subsystem_tests": false,
|
||||
"test_prefixes": [],
|
||||
"exact_files": [
|
||||
"scripts/installtests/demo_transaction_test.go",
|
||||
".github/scripts/tests/test_demo_runtime_transaction.py"
|
||||
]
|
||||
}
|
||||
],
|
||||
"match_files": null
|
||||
|
||||
@@ -25,8 +25,11 @@ func TestDemoTransactionKeepsSignedAdmissionAndVerificationOnlyReadOnly(t *testi
|
||||
}
|
||||
text := string(workflow)
|
||||
start := strings.Index(text, "- name: Apply guarded demo transaction")
|
||||
if start < 0 {
|
||||
t.Fatal("missing retained demo transaction entry")
|
||||
}
|
||||
end := strings.Index(text[start:], "- name: Retain guarded demo transaction evidence")
|
||||
if start < 0 || end < 0 {
|
||||
if end < 0 {
|
||||
t.Fatal("missing retained demo transaction entry")
|
||||
}
|
||||
entry := text[start : start+end]
|
||||
|
||||
@@ -100,6 +100,18 @@ def _contract_reference(contract_path: str, needle: str, runtime_path: str) -> d
|
||||
|
||||
|
||||
class SubsystemLookupTest(unittest.TestCase):
|
||||
|
||||
def test_demo_transaction_sources_have_connected_proof_without_widening_release_metadata(self):
|
||||
for path in (".github/scripts/demo-runtime-transaction.py", ".github/scripts/dispatch-demo-runtime.py"):
|
||||
with self.subTest(path=path):
|
||||
result = lookup_paths([path])
|
||||
subsystem = next(item for item in result["subsystems"] if item["id"] == "deployment-installability")
|
||||
self.assertEqual(subsystem["matched_verification_policies"][0]["id"], "demo-runtime-transaction")
|
||||
self.assertEqual(sorted(subsystem["required_verification"]["exact_files"]), [
|
||||
".github/scripts/tests/test_demo_runtime_transaction.py",
|
||||
"scripts/installtests/demo_transaction_test.go",
|
||||
])
|
||||
|
||||
def git(self, repo_root: Path, *args: str) -> None:
|
||||
subprocess.run(
|
||||
["git", *args],
|
||||
|
||||
Reference in New Issue
Block a user