| #!/usr/bin/env fuchsia-vendored-python |
| # Copyright 2023 The Fuchsia Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import zipfile |
| import subprocess |
| import os |
| import shutil |
| import tempfile |
| |
| |
| def zip_dir(dir, zip_file): |
| for root, _dirs, files in os.walk(dir): |
| for file in files: |
| path = os.path.join(root, file) |
| zip_file.write(path, os.path.relpath(path, dir)) |
| |
| |
| # rmtree manually removes all subdirectories and files instead of using |
| # shutil.rmtree, to avoid registering spurious reads on stale |
| # subdirectories. See https://fxbug.dev/74084. |
| def rmtree(dir): |
| if not os.path.exists(dir): |
| return |
| for root, dirs, files in os.walk(dir, topdown=False): |
| for file in files: |
| os.unlink(os.path.join(root, file)) |
| for dir in dirs: |
| full_path = os.path.join(root, dir) |
| if os.path.islink(full_path): |
| os.unlink(full_path) |
| else: |
| os.rmdir(full_path) |
| |
| |
| def prepare_dirs(repo_dir): |
| path = os.path.join(repo_dir, 'repository') |
| os.makedirs(path) |
| |
| return {'root': repo_dir, 'repository': path} |
| |
| |
| # `package-tool repository publish` expects the following inputs in its in/out directory: |
| # - `keys/{snapshot|targets|timestamp}.json` containing private metadata keys; |
| # - `repository/{{version-num}}.root.json` containing versioned root metadata; |
| # - `repository/root.json` containing default root metadata. |
| def prepare_publish(args, dirs): |
| for root_metadata_path in args.root_metadata: |
| shutil.copy(root_metadata_path, dirs['repository']) |
| shutil.copy( |
| args.default_root_metadata, |
| '{}/{}'.format(dirs['repository'], 'root.json')) |
| |
| |
| def package_tool_publish(args, dirs, depfile): |
| cmd_args = [ |
| args.package_tool, |
| 'repository', |
| 'publish', |
| '--trusted-keys', |
| args.trusted_keys, |
| '--trusted-root', |
| '{}/{}'.format(dirs['repository'], 'root.json'), |
| '--package-list', |
| args.input, |
| '--depfile', |
| args.depfile, |
| ] |
| |
| if args.delivery_blob_type: |
| cmd_args.extend(['--delivery-blob-type', args.delivery_blob_type]) |
| |
| cmd_args.append(dirs['root']) |
| |
| subprocess.run(cmd_args, check=True) |
| |
| |
| def main(args): |
| with tempfile.TemporaryDirectory( |
| dir=os.path.dirname(args.output)) as gendir: |
| dirs = prepare_dirs(gendir) |
| |
| # Prepare for `package-tool repository publish` and gather deps associated with preparations. |
| prepare_publish(args, dirs) |
| |
| depfile = os.path.join(gendir, 'deps') |
| |
| # Invoke `package-tool repository publish` and gather deps associated with invocation. |
| package_tool_publish(args, dirs, depfile) |
| |
| # Output repository directory to zip file. |
| with zipfile.ZipFile(args.output, 'w', |
| zipfile.ZIP_DEFLATED) as zip_file: |
| zip_dir(dirs['repository'], zip_file) |
| |
| |
| if __name__ == '__main__': |
| parser = argparse.ArgumentParser( |
| 'Creates a zip archive of the TUF repository output by `package-tool repository publish`' |
| ) |
| parser.add_argument( |
| '--package-tool', |
| help='path to the package-tool executable', |
| required=True) |
| parser.add_argument( |
| '--trusted-keys', |
| help= |
| 'path to a keys directory to be consumed by `package-tool repository publish`' |
| ) |
| parser.add_argument( |
| '--root-metadata', |
| help='path to a root metadata file to be used in the TUF repository', |
| action='append') |
| parser.add_argument( |
| '--default-root-metadata', |
| help='path to the default TUF root metadata file', |
| required=True) |
| parser.add_argument( |
| '--input', |
| help='path to `package-tool repository publish` file input', |
| required=True) |
| parser.add_argument( |
| '--delivery-blob-type', help='the type of delivery blob to generate') |
| parser.add_argument('--depfile', help='generate a depfile', required=True) |
| parser.add_argument('--output', help='path output zip file', required=True) |
| main(parser.parse_args()) |