|
16 | 16 | ROOT = SCRIPT_DIR.parents[1] |
17 | 17 |
|
18 | 18 | from runtime_settings import ( # noqa: E402 |
| 19 | + LIVE_CONTINUITY_STATES, |
19 | 20 | SUPPORTED_PLATFORMS, |
20 | 21 | compact_json, |
21 | 22 | env_string, |
22 | 23 | platform_repository, |
| 24 | + runtime_target_fingerprint, |
23 | 25 | select_service_target_entry_index, |
24 | 26 | validate_target, |
25 | 27 | ) |
@@ -820,9 +822,35 @@ def _build_runtime_target(args: argparse.Namespace) -> dict[str, Any]: |
820 | 822 | execution_windows = _load_json_object(args.execution_windows_json, field_name="execution_windows_json") |
821 | 823 | if execution_windows: |
822 | 824 | runtime_target["execution_windows"] = execution_windows |
| 825 | + _apply_live_continuity(runtime_target, args) |
823 | 826 | return runtime_target |
824 | 827 |
|
825 | 828 |
|
| 829 | +def _apply_live_continuity(runtime_target: dict[str, Any], args: argparse.Namespace) -> None: |
| 830 | + """Attach a frozen legacy baseline without granting new live authority.""" |
| 831 | + |
| 832 | + state = str(getattr(args, "live_continuity_state", "") or "").strip().upper() |
| 833 | + if not state or state == "NONE": |
| 834 | + return |
| 835 | + if state not in LIVE_CONTINUITY_STATES: |
| 836 | + raise ValueError(f"live_continuity_state must be one of NONE, {', '.join(sorted(LIVE_CONTINUITY_STATES))}") |
| 837 | + if runtime_target.get("execution_mode") != "live" or runtime_target.get("dry_run_only") is not False: |
| 838 | + raise ValueError("live_continuity is only valid for an execution_mode=live, non-dry-run target") |
| 839 | + baseline_id = str(getattr(args, "live_continuity_baseline_id", "") or "").strip() |
| 840 | + captured_at = str(getattr(args, "live_continuity_captured_at", "") or "").strip() |
| 841 | + if not baseline_id or not captured_at: |
| 842 | + raise ValueError( |
| 843 | + "live_continuity_baseline_id and live_continuity_captured_at are required when live_continuity_state is set" |
| 844 | + ) |
| 845 | + runtime_target["live_continuity"] = { |
| 846 | + "state": state, |
| 847 | + "baseline_kind": "legacy_authorized", |
| 848 | + "baseline_id": baseline_id, |
| 849 | + "baseline_target_sha256": runtime_target_fingerprint(runtime_target), |
| 850 | + "captured_at": captured_at, |
| 851 | + } |
| 852 | + |
| 853 | + |
826 | 854 | def _build_target_entry( |
827 | 855 | *, |
828 | 856 | platform: str, |
@@ -1041,6 +1069,14 @@ def build_parser() -> argparse.ArgumentParser: |
1041 | 1069 | parser.add_argument("--account-scope", default="") |
1042 | 1070 | parser.add_argument("--service-name", default="") |
1043 | 1071 | parser.add_argument("--execution-windows-json", default="") |
| 1072 | + parser.add_argument( |
| 1073 | + "--live-continuity-state", |
| 1074 | + choices=("NONE", *sorted(LIVE_CONTINUITY_STATES)), |
| 1075 | + default="NONE", |
| 1076 | + help="Freeze an already authorised legacy baseline; does not create new live authority.", |
| 1077 | + ) |
| 1078 | + parser.add_argument("--live-continuity-baseline-id", default="") |
| 1079 | + parser.add_argument("--live-continuity-captured-at", default="") |
1044 | 1080 | parser.add_argument("--plugin-mode", choices=("auto", "none", "custom"), default="none") |
1045 | 1081 | parser.add_argument("--custom-plugin-mounts-json", default="") |
1046 | 1082 | parser.add_argument("--artifact-bucket-uri", default=DEFAULT_ARTIFACT_BUCKET_URI) |
|
0 commit comments