| #!/usr/bin/env vpython3 |
| # Copyright 2022 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| """Implements commands for serving a TUF repository.""" |
| |
| import argparse |
| import contextlib |
| import sys |
| |
| from typing import Iterator, Optional |
| |
| from common import REPO_ALIAS, register_device_args, run_ffx_command |
| |
| _REPO_NAME = 'chromium-test-package-server' |
| |
| |
| def _stop_serving(repo_name: str, target: Optional[str]) -> None: |
| """Stop serving a repository.""" |
| |
| # Attempt to clean up. |
| run_ffx_command(['target', 'repository', 'deregister', '-r', repo_name], |
| target, |
| check=False) |
| run_ffx_command(['repository', 'remove', repo_name], check=False) |
| run_ffx_command(['repository', 'server', 'stop'], check=False) |
| |
| |
| def _start_serving(repo_dir: str, repo_name: str, |
| target: Optional[str]) -> None: |
| """Start serving a repository to a target device. |
| |
| Args: |
| repo_dir: directory the repository is served from. |
| repo_name: repository name. |
| target: Fuchsia device the repository is served to. |
| """ |
| |
| run_ffx_command(('config', 'set', 'repository.server.mode', '\"ffx\"')) |
| |
| run_ffx_command(['repository', 'server', 'start']) |
| run_ffx_command(['repository', 'add-from-pm', repo_dir, '-r', repo_name]) |
| run_ffx_command([ |
| 'target', 'repository', 'register', '-r', repo_name, '--alias', |
| REPO_ALIAS |
| ], target) |
| |
| |
| def register_serve_args(arg_parser: argparse.ArgumentParser) -> None: |
| """Register common arguments for repository serving.""" |
| |
| serve_args = arg_parser.add_argument_group('serve', |
| 'repo serving arguments') |
| serve_args.add_argument('--serve-repo', |
| dest='repo', |
| help='Directory the repository is served from.') |
| serve_args.add_argument('--repo-name', |
| default=_REPO_NAME, |
| help='Name of the repository.') |
| |
| |
| def run_serve_cmd(cmd: str, args: argparse.Namespace) -> None: |
| """Helper for running serve commands.""" |
| |
| if cmd == 'start': |
| _start_serving(args.repo, args.repo_name, args.target_id) |
| else: |
| _stop_serving(args.repo_name, args.target_id) |
| |
| |
| @contextlib.contextmanager |
| def serve_repository(args: argparse.Namespace) -> Iterator[None]: |
| """Context manager for serving a repository.""" |
| run_serve_cmd('start', args) |
| try: |
| yield None |
| finally: |
| run_serve_cmd('stop', args) |
| |
| |
| def main(): |
| """Stand-alone function for serving a repository.""" |
| |
| parser = argparse.ArgumentParser() |
| parser.add_argument('cmd', |
| choices=['start', 'stop'], |
| help='Choose to start|stop repository serving.') |
| register_device_args(parser) |
| register_serve_args(parser) |
| args = parser.parse_args() |
| if args.cmd == 'start' and not args.repo: |
| raise ValueError('Directory the repository is serving from needs ' |
| 'to be specified.') |
| run_serve_cmd(args.cmd, args) |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main()) |