Skip to content

Commit

Permalink
actions: Add features to test-repository
Browse files Browse the repository at this point in the history
1. `update_base_url` allows testing the upgrade from one repository
   version to next: This should be great for testing
   e.g. a just published version in
   https://sigstore.github.io/root-signing-staging/ and using
   https://tuf-repo-cdn.sigstage.dev/
   as the update_base_url
2. `metadata_dir` tells test-repository to leave the metadata on disk:
   caller can then use this for e.g. deduplication purposes:
       sha256sum metadata_dir/* | shasum | cut -d " " -f 1
  • Loading branch information
jku committed Mar 30, 2024
1 parent 9d5dd3b commit 2e9f2b4
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 9 deletions.
24 changes: 23 additions & 1 deletion actions/test-repository/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ inputs:
artifact_url:
description: 'Base artifact URL the client should use'
default: ''
update_base_url:
description: 'Optional metadata URL to use as previous repository state'
default: ''
expected_artifact:
description: 'Optional artifact path that should be checked to exist in the repository'
default: ''
Expand All @@ -20,6 +23,9 @@ inputs:
offline_time:
description: 'Optional timestamp. Root and targets role validity is checked at this time'
default: ''
metadata_dir:
description: 'Optional directory name. The metadata client receives will be stored here. Useful e.g. for deduplication purpose'
default: ''

runs:
using: "composite"
Expand All @@ -38,11 +44,13 @@ runs:
- env:
METADATA_URL: ${{ inputs.metadata_url }}
ARTIFACT_URL: ${{ inputs.artifact_url }}
UPDATE_BASE_URL: ${{ inputs.update_base_url }}
EXPECTED_ARTIFACT: ${{ inputs.expected_artifact }}
OWNER_REPO: ${{ github.repository }}
COMPARE_SOURCE: ${{ inputs.compare_source }}
TIME: ${{ inputs.time }}
OFFLINE_TIME: ${{ inputs.offline_time }}
METADATA_DIR: ${{ inputs.metadata_dir }}
run: |
OWNER=${OWNER_REPO%/*}
REPO=${OWNER_REPO#*/}
Expand All @@ -55,6 +63,12 @@ runs:
ARTIFACT_URL="https://${OWNER}.github.io/${REPO}/targets/"
fi
if [ -z $UPDATE_BASE_URL ]; then
UPDATE_BASE_URL_ARG=""
else
UPDATE_BASE_URL_ARG="--update-base-url $UPDATE_BASE_URL"
fi
if [ -z $EXPECTED_ARTIFACT ]; then
ARTIFACT_ARG=""
else
Expand All @@ -79,13 +93,21 @@ runs:
OFFLINE_TIME_ARG="--offline-time $OFFLINE_TIME"
fi
if [ -z $METADATA_DIR ]; then
METADATA_DIR_ARG=""
else
METADATA_DIR_ARG="--metadata-dir $METADATA_DIR"
fi
echo "Testing repository at metadata-url $METADATA_URL, artifact-url $ARTIFACT_URL"
tuf-on-ci-test-client \
--metadata-url "$METADATA_URL" \
--artifact-url "$ARTIFACT_URL" \
$UPDATE_BASE_URL_ARG \
$ARTIFACT_ARG \
$COMPARE_SOURCE_ARG \
$TIME_ARG \
$OFFLINE_TIME_ARG
$OFFLINE_TIME_ARG \
$METADATA_DIR_ARG
shell: bash
27 changes: 19 additions & 8 deletions repo/tuf_on_ci/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,39 +29,50 @@ def expiry_check(dir: str, role: str, timestamp: int):
@click.option("-v", "--verbose", count=True, default=0)
@click.option("-m", "--metadata-url", type=str, required=True)
@click.option("-a", "--artifact-url", type=str, required=True)
@click.option("-u", "--update-base-url", type=str)
@click.option("-e", "--expected-artifact", type=str)
@click.option("--compare-source/--no-compare-source", default=True)
@click.option("-t", "--time", type=int)
@click.option("-o", "--offline-time", type=int)
@click.option("-d", "--metadata-dir", type=str)
def client(
verbose: int,
metadata_url: str,
artifact_url: str,
update_base_url: str | None,
expected_artifact: str | None,
compare_source: bool,
time: int | None,
offline_time: int | None,
metadata_dir: str | None,
) -> None:
"""Test client for tuf-on-ci
Client expects to be run in tuf-on-ci repository (current metadata
in the sources will be considered the expected expected metadata the
client should receive from remote)."""
"""Test client for tuf-on-ci"""

logging.basicConfig(level=logging.WARNING - verbose * 10)

with TemporaryDirectory() as client_dir:
metadata_dir = os.path.join(client_dir, "metadata")
if metadata_dir is None:
metadata_dir = os.path.join(client_dir, "metadata")
artifact_dir = os.path.join(client_dir, "artifacts")
os.mkdir(metadata_dir)
os.makedirs(metadata_dir, exist_ok=True)
os.mkdir(artifact_dir)

# initialize client with a root.json from metadata_url
root_url = f"{metadata_url}/1.root.json"
try:
request.urlretrieve(root_url, f"{metadata_dir}/root.json") # noqa: S310
except OSError as e:
sys.exit(f"Failed to download initial root {root_url}: {e}")

if update_base_url is not None:
# Update client to update_base_url before doing the actual update
updater = Updater(metadata_dir, metadata_url, artifact_dir, artifact_url)
try:
updater.refresh()
print(f"Client metadata update from base url {update_base_url}: OK")
except ExpiredMetadataError as e:
print(f"WARNING: update base url has expired metadata: {e}")

updater = Updater(metadata_dir, metadata_url, artifact_dir, artifact_url)
ref_time_string = ""
if time is not None:
Expand All @@ -75,7 +86,7 @@ def client(
updater.refresh()
except ExpiredMetadataError as e:
sys.exit(f"Update{ref_time_string} failed: {e}")
print(f"Client metadata update{ref_time_string}: OK")
print(f"Client metadata update from {metadata_url}{ref_time_string}: OK")

if compare_source:
# Compare received metadata versions with source metadata
Expand Down

0 comments on commit 2e9f2b4

Please sign in to comment.