-
Notifications
You must be signed in to change notification settings - Fork 275
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2670 from jku/add-conformance-workflow
Add a conformance test workflow
- Loading branch information
Showing
4 changed files
with
145 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#!/usr/bin/env python | ||
"""Conformance client for python-tuf, part of tuf-conformance""" | ||
|
||
# Copyright 2024 tuf-conformance contributors | ||
# SPDX-License-Identifier: MIT OR Apache-2.0 | ||
|
||
import argparse | ||
import os | ||
import shutil | ||
import sys | ||
from datetime import datetime, timedelta, timezone | ||
|
||
from tuf.ngclient import Updater, UpdaterConfig | ||
|
||
|
||
def init(metadata_dir: str, trusted_root: str) -> None: | ||
"""Initialize local trusted metadata""" | ||
|
||
# No need to actually run python-tuf code at this point | ||
shutil.copyfile(trusted_root, os.path.join(metadata_dir, "root.json")) | ||
print(f"python-tuf test client: Initialized repository in {metadata_dir}") | ||
|
||
|
||
def refresh( | ||
metadata_url: str, | ||
metadata_dir: str, | ||
days_in_future: str, | ||
max_root_rotations: int, | ||
) -> None: | ||
"""Refresh local metadata from remote""" | ||
|
||
updater = Updater( | ||
metadata_dir, | ||
metadata_url, | ||
config=UpdaterConfig(max_root_rotations=int(max_root_rotations)), | ||
) | ||
if days_in_future != "0": | ||
day_int = int(days_in_future) | ||
day_in_future = datetime.now(timezone.utc) + timedelta(days=day_int) | ||
updater._trusted_set.reference_time = day_in_future # noqa: SLF001 | ||
updater.refresh() | ||
print(f"python-tuf test client: Refreshed metadata in {metadata_dir}") | ||
|
||
|
||
def download_target( | ||
metadata_url: str, | ||
metadata_dir: str, | ||
target_name: str, | ||
download_dir: str, | ||
target_base_url: str, | ||
) -> None: | ||
"""Download target.""" | ||
|
||
updater = Updater( | ||
metadata_dir, | ||
metadata_url, | ||
download_dir, | ||
target_base_url, | ||
config=UpdaterConfig(prefix_targets_with_hash=False), | ||
) | ||
target_info = updater.get_targetinfo(target_name) | ||
if not target_info: | ||
raise RuntimeError(f"{target_name} not found in repository") | ||
updater.download_target(target_info) | ||
|
||
|
||
def main() -> int: | ||
"""Main TUF Client Example function""" | ||
|
||
parser = argparse.ArgumentParser(description="TUF Client Example") | ||
parser.add_argument("--metadata-url", required=False) | ||
parser.add_argument("--metadata-dir", required=True) | ||
parser.add_argument("--target-name", required=False) | ||
parser.add_argument("--target-dir", required=False) | ||
parser.add_argument("--target-base-url", required=False) | ||
parser.add_argument("--days-in-future", required=False, default="0") | ||
parser.add_argument( | ||
"--max-root-rotations", required=False, default=32, type=int | ||
) | ||
|
||
sub_command = parser.add_subparsers(dest="sub_command") | ||
init_parser = sub_command.add_parser( | ||
"init", | ||
help="Initialize client with given trusted root", | ||
) | ||
init_parser.add_argument("trusted_root") | ||
|
||
sub_command.add_parser( | ||
"refresh", | ||
help="Refresh the client metadata", | ||
) | ||
|
||
sub_command.add_parser( | ||
"download", | ||
help="Downloads a target", | ||
) | ||
|
||
command_args = parser.parse_args() | ||
|
||
# initialize the TUF Client Example infrastructure | ||
if command_args.sub_command == "init": | ||
init(command_args.metadata_dir, command_args.trusted_root) | ||
elif command_args.sub_command == "refresh": | ||
refresh( | ||
command_args.metadata_url, | ||
command_args.metadata_dir, | ||
command_args.days_in_future, | ||
command_args.max_root_rotations, | ||
) | ||
elif command_args.sub_command == "download": | ||
download_target( | ||
command_args.metadata_url, | ||
command_args.metadata_dir, | ||
command_args.target_name, | ||
command_args.target_dir, | ||
command_args.target_base_url, | ||
) | ||
else: | ||
parser.print_help() | ||
|
||
return 0 | ||
|
||
|
||
if __name__ == "__main__": | ||
sys.exit(main()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
on: | ||
# manual dispatch only while the conformance test suite is under rapid development | ||
workflow_dispatch: | ||
|
||
name: CI | ||
jobs: | ||
conformance: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Checkout conformance client | ||
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7 | ||
|
||
- name: Run test suite | ||
uses: theupdateframework/tuf-conformance@main | ||
with: | ||
entrypoint: ".github/scripts/conformance-client.py" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters