xref: /aosp_15_r20/external/cronet/build/fuchsia/test/serve_repo.py (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env vpython3
2*6777b538SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors
3*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be
4*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file.
5*6777b538SAndroid Build Coastguard Worker"""Implements commands for serving a TUF repository."""
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Workerimport argparse
8*6777b538SAndroid Build Coastguard Workerimport contextlib
9*6777b538SAndroid Build Coastguard Workerimport sys
10*6777b538SAndroid Build Coastguard Worker
11*6777b538SAndroid Build Coastguard Workerfrom typing import Iterator, Optional
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Workerfrom common import REPO_ALIAS, catch_sigterm, register_device_args, \
14*6777b538SAndroid Build Coastguard Worker                   run_ffx_command, wait_for_sigterm
15*6777b538SAndroid Build Coastguard Worker
16*6777b538SAndroid Build Coastguard Worker_REPO_NAME = 'chromium-test-package-server'
17*6777b538SAndroid Build Coastguard Worker
18*6777b538SAndroid Build Coastguard Worker
19*6777b538SAndroid Build Coastguard Workerdef _stop_serving(repo_name: str, target: Optional[str]) -> None:
20*6777b538SAndroid Build Coastguard Worker    """Stop serving a repository."""
21*6777b538SAndroid Build Coastguard Worker
22*6777b538SAndroid Build Coastguard Worker    # Attempt to clean up.
23*6777b538SAndroid Build Coastguard Worker    run_ffx_command(
24*6777b538SAndroid Build Coastguard Worker        cmd=['target', 'repository', 'deregister', '-r', repo_name],
25*6777b538SAndroid Build Coastguard Worker        target_id=target,
26*6777b538SAndroid Build Coastguard Worker        check=False)
27*6777b538SAndroid Build Coastguard Worker    run_ffx_command(cmd=['repository', 'remove', repo_name], check=False)
28*6777b538SAndroid Build Coastguard Worker    run_ffx_command(cmd=['repository', 'server', 'stop'], check=False)
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker
31*6777b538SAndroid Build Coastguard Workerdef _start_serving(repo_dir: str, repo_name: str,
32*6777b538SAndroid Build Coastguard Worker                   target: Optional[str]) -> None:
33*6777b538SAndroid Build Coastguard Worker    """Start serving a repository to a target device.
34*6777b538SAndroid Build Coastguard Worker
35*6777b538SAndroid Build Coastguard Worker    Args:
36*6777b538SAndroid Build Coastguard Worker        repo_dir: directory the repository is served from.
37*6777b538SAndroid Build Coastguard Worker        repo_name: repository name.
38*6777b538SAndroid Build Coastguard Worker        target: Fuchsia device the repository is served to.
39*6777b538SAndroid Build Coastguard Worker    """
40*6777b538SAndroid Build Coastguard Worker
41*6777b538SAndroid Build Coastguard Worker    run_ffx_command(cmd=('config', 'set', 'repository.server.mode', '\"ffx\"'))
42*6777b538SAndroid Build Coastguard Worker
43*6777b538SAndroid Build Coastguard Worker    run_ffx_command(cmd=['repository', 'server', 'start'])
44*6777b538SAndroid Build Coastguard Worker    run_ffx_command(
45*6777b538SAndroid Build Coastguard Worker        cmd=['repository', 'add-from-pm', repo_dir, '-r', repo_name])
46*6777b538SAndroid Build Coastguard Worker    run_ffx_command(cmd=[
47*6777b538SAndroid Build Coastguard Worker        'target', 'repository', 'register', '-r', repo_name, '--alias',
48*6777b538SAndroid Build Coastguard Worker        REPO_ALIAS
49*6777b538SAndroid Build Coastguard Worker    ],
50*6777b538SAndroid Build Coastguard Worker                    target_id=target)
51*6777b538SAndroid Build Coastguard Worker
52*6777b538SAndroid Build Coastguard Worker
53*6777b538SAndroid Build Coastguard Workerdef register_serve_args(arg_parser: argparse.ArgumentParser) -> None:
54*6777b538SAndroid Build Coastguard Worker    """Register common arguments for repository serving."""
55*6777b538SAndroid Build Coastguard Worker
56*6777b538SAndroid Build Coastguard Worker    serve_args = arg_parser.add_argument_group('serve',
57*6777b538SAndroid Build Coastguard Worker                                               'repo serving arguments')
58*6777b538SAndroid Build Coastguard Worker    serve_args.add_argument('--serve-repo',
59*6777b538SAndroid Build Coastguard Worker                            dest='repo',
60*6777b538SAndroid Build Coastguard Worker                            help='Directory the repository is served from.')
61*6777b538SAndroid Build Coastguard Worker    serve_args.add_argument('--repo-name',
62*6777b538SAndroid Build Coastguard Worker                            default=_REPO_NAME,
63*6777b538SAndroid Build Coastguard Worker                            help='Name of the repository.')
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker
66*6777b538SAndroid Build Coastguard Workerdef run_serve_cmd(cmd: str, args: argparse.Namespace) -> None:
67*6777b538SAndroid Build Coastguard Worker    """Helper for running serve commands."""
68*6777b538SAndroid Build Coastguard Worker
69*6777b538SAndroid Build Coastguard Worker    if cmd == 'start':
70*6777b538SAndroid Build Coastguard Worker        _start_serving(args.repo, args.repo_name, args.target_id)
71*6777b538SAndroid Build Coastguard Worker    elif cmd == 'stop':
72*6777b538SAndroid Build Coastguard Worker        _stop_serving(args.repo_name, args.target_id)
73*6777b538SAndroid Build Coastguard Worker    else:
74*6777b538SAndroid Build Coastguard Worker        assert cmd == 'run'
75*6777b538SAndroid Build Coastguard Worker        catch_sigterm()
76*6777b538SAndroid Build Coastguard Worker        with serve_repository(args):
77*6777b538SAndroid Build Coastguard Worker            # Clients can assume the repo is up and running once the repo-name
78*6777b538SAndroid Build Coastguard Worker            # is printed out.
79*6777b538SAndroid Build Coastguard Worker            print(args.repo_name, flush=True)
80*6777b538SAndroid Build Coastguard Worker            wait_for_sigterm('shutting down the repo server.')
81*6777b538SAndroid Build Coastguard Worker
82*6777b538SAndroid Build Coastguard Worker
83*6777b538SAndroid Build Coastguard Worker@contextlib.contextmanager
84*6777b538SAndroid Build Coastguard Workerdef serve_repository(args: argparse.Namespace) -> Iterator[None]:
85*6777b538SAndroid Build Coastguard Worker    """Context manager for serving a repository."""
86*6777b538SAndroid Build Coastguard Worker    run_serve_cmd('start', args)
87*6777b538SAndroid Build Coastguard Worker    try:
88*6777b538SAndroid Build Coastguard Worker        yield None
89*6777b538SAndroid Build Coastguard Worker    finally:
90*6777b538SAndroid Build Coastguard Worker        run_serve_cmd('stop', args)
91*6777b538SAndroid Build Coastguard Worker
92*6777b538SAndroid Build Coastguard Worker
93*6777b538SAndroid Build Coastguard Workerdef main():
94*6777b538SAndroid Build Coastguard Worker    """Stand-alone function for serving a repository."""
95*6777b538SAndroid Build Coastguard Worker
96*6777b538SAndroid Build Coastguard Worker    parser = argparse.ArgumentParser()
97*6777b538SAndroid Build Coastguard Worker    parser.add_argument('cmd',
98*6777b538SAndroid Build Coastguard Worker                        choices=['start', 'stop', 'run'],
99*6777b538SAndroid Build Coastguard Worker                        help='Choose to start|stop|run repository serving. ' \
100*6777b538SAndroid Build Coastguard Worker                             '"start" command will start the repo and exit; ' \
101*6777b538SAndroid Build Coastguard Worker                             '"run" command will start the repo and wait ' \
102*6777b538SAndroid Build Coastguard Worker                             'until ctrl-c or sigterm.')
103*6777b538SAndroid Build Coastguard Worker    register_device_args(parser)
104*6777b538SAndroid Build Coastguard Worker    register_serve_args(parser)
105*6777b538SAndroid Build Coastguard Worker    args = parser.parse_args()
106*6777b538SAndroid Build Coastguard Worker    if (args.cmd == 'start' or args.cmd == 'run') and not args.repo:
107*6777b538SAndroid Build Coastguard Worker        raise ValueError('Directory the repository is serving from needs '
108*6777b538SAndroid Build Coastguard Worker                         'to be specified.')
109*6777b538SAndroid Build Coastguard Worker
110*6777b538SAndroid Build Coastguard Worker    run_serve_cmd(args.cmd, args)
111*6777b538SAndroid Build Coastguard Worker
112*6777b538SAndroid Build Coastguard Worker
113*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__':
114*6777b538SAndroid Build Coastguard Worker    sys.exit(main())
115