#!/usr/bin/env python3 """Atomically switch an extension state root to its previous verified release.""" from __future__ import annotations import argparse import json import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path[:0] = [ str(ROOT / "packages" / "jwebot-sdk" / "src"), str(ROOT / "packages" / "jwebot-kernel" / "src"), ] from jwebot_kernel import ( # noqa: E402 ActivationError, ReleaseError, rollback_release, ) def main() -> int: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--state-root", type=Path, required=True) parser.add_argument("--allowed-signers", type=Path) parser.add_argument("--publisher") parser.add_argument("--allow-unsigned-local", action="store_true") args = parser.parse_args() if args.allow_unsigned_local: if args.allowed_signers is not None or args.publisher is not None: parser.error( "--allow-unsigned-local cannot include publisher trust options" ) elif args.allowed_signers is None: parser.error("signed rollback requires --allowed-signers") try: destination = rollback_release( args.state_root, allowed_signers=args.allowed_signers, expected_publisher=args.publisher, allow_unsigned=args.allow_unsigned_local, ) except (ActivationError, ReleaseError) as error: parser.error(str(error)) print( json.dumps( { "rolled_back": True, "release_dir": str(destination), "current": str(args.state_root / "current"), }, ensure_ascii=False, sort_keys=True, ) ) return 0 if __name__ == "__main__": raise SystemExit(main())