import argparse from dataclasses import asdict import json from pathlib import Path from .core import ClockError from .client import Clock, FileTrust from .authority import Authority, Server def main(): parser = argparse.ArgumentParser(description='Authenticated application time; never changes OS time') commands = parser.add_subparsers(dest='command', required=True) read = commands.add_parser('read'); read.add_argument('--trust', required=True) serve = commands.add_parser('serve'); serve.add_argument('--config', required=True) health = commands.add_parser('health-export'); health.add_argument('--policy', required=True); health.add_argument('--output', required=True) args = parser.parse_args() try: if args.command == 'read': print(json.dumps(asdict(Clock(FileTrust(args.trust)).read()))) elif args.command == 'health-export': from .health import collect, write_health write_health(args.output, collect(json.loads(Path(args.policy).read_text()))) else: config = json.loads(Path(args.config).read_text()) # Private host pilot: external exposure belongs to the deployment owner. Server(('127.0.0.1', config.get('port', 8787)), Authority(config)).serve_forever() except (ClockError, OSError, ValueError, KeyError): parser.exit(1, 'Railiance time unavailable or untrusted.\n')