From 7b3927dc601512d15fff030288d99d8009e91e65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Tue, 26 Nov 2024 15:05:44 +0100 Subject: [PATCH 01/50] chore: rework release note handling (#1139) #### What this PR does / why we need it reworks release note management based on github release note api It does this in the following way: 1. Creates a tag on cutoff that is annotated 2. Calls the Github Release Note API together with a release note configuration file (very similar to drafter but allows us to specify a previous tag) 3. Generates the notes for the current branch based on the last found tag. This has the advantage that we can explicitly determine which release notes are generated from when to when and also use the contributors fields. TODO: 1. Test on other repo 2. Make sure that the Merge commit in main that we used for testing disappears. #### Which issue(s) this PR fixes --- .github/config/release.yml | 28 ++++++++++ .github/release-drafter.yml | 38 ------------- .github/workflows/release-branch.yaml | 14 ++++- .github/workflows/release-drafter.yaml | 74 +++++++++++++++++++++++--- .github/workflows/release.yaml | 21 +++++++- 5 files changed, 128 insertions(+), 47 deletions(-) create mode 100644 .github/config/release.yml delete mode 100644 .github/release-drafter.yml diff --git a/.github/config/release.yml b/.github/config/release.yml new file mode 100644 index 0000000000..cf08521604 --- /dev/null +++ b/.github/config/release.yml @@ -0,0 +1,28 @@ +changelog: + exclude: + labels: + - 'kind/skip-release-notes' + - 'wontfix' + - 'triage/wont-fix' + - 'triage/invalid' + categories: + - title: '‼️ Breaking Changes' + labels: + - 'breaking-change' + - title: '🚀 Features' + labels: + - 'kind/enhancement' + - 'feature' + - 'enhancement' + - title: '🐛 Bug Fixes' + labels: + - 'kind/bug' + - 'fix' + - 'bugfix' + - 'bug' + - title: '🧰 Maintenance' + labels: + - 'chore' + - title: '⬆️ Dependencies' + labels: + - 'dependencies' \ No newline at end of file diff --git a/.github/release-drafter.yml b/.github/release-drafter.yml deleted file mode 100644 index 6827c023ff..0000000000 --- a/.github/release-drafter.yml +++ /dev/null @@ -1,38 +0,0 @@ -name-template: 'v$RESOLVED_VERSION' -tag-template: 'v$RESOLVED_VERSION' -version-template: '$COMPLETE' -change-template: '- $TITLE (#$NUMBER)' -change-title-escapes: '\<*_&#@`' -template: | - # Release v$RESOLVED_VERSION - - $CHANGES -exclude-labels: - - 'kind/skip-release-notes' - - 'wontfix' - - 'triage/wont-fix' - - 'triage/invalid' -categories: - - title: '‼️ Breaking Changes' - labels: - - 'breaking-change' - - title: '🚀 Features' - labels: - - 'kind/enhancement' - - 'feature' - - 'enhancement' - - title: '🐛 Bug Fixes' - collapse-after: 5 - labels: - - 'kind/bug' - - 'fix' - - 'bugfix' - - 'bug' - - title: '🧰 Maintenance' - collapse-after: 3 - labels: - - 'chore' - - title: '⬆️ Dependencies' - collapse-after: 3 - labels: - - 'dependencies' diff --git a/.github/workflows/release-branch.yaml b/.github/workflows/release-branch.yaml index f63d279c5f..237c8866cc 100644 --- a/.github/workflows/release-branch.yaml +++ b/.github/workflows/release-branch.yaml @@ -80,7 +80,19 @@ jobs: ref: main fetch-depth: 0 token: ${{ steps.generate_token.outputs.token }} - + - name: Setup git config + run: | + git config user.name "GitHub Actions Bot" + git config user.email "<41898282+github-actions[bot]@users.noreply.github.com>" + # tag the cutoff point in main so that it can be used for release note generation + - name: Create Cutoff Tag in Main + run: | + set -e + tag="v${{ needs.cutoff-preconditions.outputs.minor }}" + msg="Cutoff for $tag" + git tag --annotate --message "${msg}" "$tag" + git push origin "$tag" + # create a new branch - name: Create Release Branch run: | set -e diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index 607cf7613b..e066e35b6d 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -11,7 +11,7 @@ on: permissions: contents: read # The release-drafter action adds PR titles to the release notes once these are merged to main. - # A draft release is kept up-to-date listing the changes for the next minor release version. + # A draft release is kept up-to-date listing the changes for the next minor or patch release version for that branch. jobs: release-version: name: Release Version @@ -31,12 +31,72 @@ jobs: env: RELEASE_VERSION: ${{ needs.release-version.outputs.version }} steps: + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.OCMBOT_APP_ID }} + private_key: ${{ secrets.OCMBOT_PRIV_KEY }} - name: Checkout uses: actions/checkout@v4 - - name: Drafter - uses: release-drafter/release-drafter@v6 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - tag: ${{env.RELEASE_VERSION }} - version: ${{env.RELEASE_VERSION }} \ No newline at end of file + fetch-depth: 0 + fetch-tags: true + - name: Setup Release with gh + env: + REF: ${{ github.ref }} + REPO: ${{ github.repository }} + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + # generate the release notes based on the last previous tag. + # match only a valid semver tag. + # also do not match for the cutoff tag for the release branch. + # Example: If we are in releases/v0.18, we don't want to match v0.18 as the cutoff tag. + # Instead we want to match the one before that, which would be v0.17. + # That would generate us the notes from + # v0.17 to HEAD, which is what we want. + # + # Implementors Note: + # ##*\/ removes everything before the last / in the ref, + # e.g. refs/heads/releases/v0.18 -> v0.18 + previous_tag=$(git describe HEAD --abbrev=0 --tags --match "v*" --exclude "${REF##*\/}") + + if [[ -z $previous_tag ]]; then + echo "No previous tag found, cannot generate release notes" + exit 1 + fi + + echo "Generating release notes for ${{env.RELEASE_VERSION}} starting from ${previous_tag} to HEAD" + + notes=$(\ + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/${REPO}/releases/generate-notes \ + -f "tag_name=${{env.RELEASE_VERSION}}" \ + -f "target_commitish=${{ github.ref }}" \ + -f "previous_tag_name=${previous_tag}" \ + -f "configuration_file_path=.github/config/release.yml" \ + -q .body \ + ) + + echo "Release Notes generated for ${{env.RELEASE_VERSION}}:" + echo "${notes}" + + echo "Verifying if release ${{env.RELEASE_VERSION}} already exists" + if [[ -z $(gh release list -R ${REPO} --json name -q '.[] | select(.name == "${{env.RELEASE_VERSION}}")') ]]; then + echo "Release ${{env.RELEASE_VERSION}} does not exist yet, creating from scratch" + gh release create ${{env.RELEASE_VERSION}} \ + --title "${{env.RELEASE_VERSION}}" \ + --notes "${notes}" \ + --draft \ + --latest=false \ + --target ${{ github.ref }} \ + -R ${REPO} + else + echo "Release ${{env.RELEASE_VERSION}} already exists, updating existing..." + gh release edit ${{env.RELEASE_VERSION}} \ + --notes "${notes}" \ + -R ${REPO} + fi diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index f15bdb2250..b6034f388a 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -181,8 +181,27 @@ jobs: git commit -m "Release $RELEASE_VERSION" msg="Release ${{ env.RELEASE_VERSION }}" git tag --annotate --message "${msg}" ${{ env.RELEASE_VERSION }} - # push both the tag as well as a release branch with that tag. + # push the tag. git push origin ${{ env.RELEASE_VERSION }} + # If we encounter a release (i.e. NOT a candidate), we want to keep the tag in the release branch git history + # by merging it (without taking over its contents). + # This allows tools that rely on the latest tag (such as Release Note generators or git describe) + # to recognize the release as the latest version. + # We can then use this to generate release notes based on the previous tag. + # If we previously built a release candidate, the tag is not merged back. + # That results in the tag being "omitted" / not recognized while generating release notes. + # This is intended, because a candidate should never influence further release notes. + # Example: + # Branch releases/v0.19 + # - Candidate Build v0.19.0-rc.1 => no merge, release notes based on original cutoff + # - Actual Build v0.19.0 => merge, release notes based on original cutoff + # - Candidate Build v0.19.1-rc.1 => no merge, release notes based on v0.19.0 due to previous merge + - name: Merge Release Tag back into release branch if not a release candidate + if: inputs.release_candidate == false + run: | + git checkout ${{ github.ref }} + git merge --strategy ours ${{ env.RELEASE_VERSION }} + git push origin ${{ github.ref }} - name: Create GPG Token file from Secret run: | From 1b31de5579a0cc3dd49adba3a1df8ca1a7e7bb35 Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Tue, 26 Nov 2024 15:23:29 +0100 Subject: [PATCH 02/50] docs: release process - add follow up section (#1141) #### What this PR does / why we need it Once the release has been created, there are some follow up actions to keep in mind. --- .github/config/wordlist.txt | 2 ++ RELEASE_PROCESS.md | 50 ++++++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/.github/config/wordlist.txt b/.github/config/wordlist.txt index 81e7bd3d34..3bb353cc37 100644 --- a/.github/config/wordlist.txt +++ b/.github/config/wordlist.txt @@ -215,6 +215,7 @@ packageversion parameterization pendingdeprecationwarning pflag +pkgs podinfo podman pre @@ -239,6 +240,7 @@ resendbuffer resmgmt resolvers resourcereference +retrigger routings routingslips rsa diff --git a/RELEASE_PROCESS.md b/RELEASE_PROCESS.md index 181dcbbc50..262b6da560 100644 --- a/RELEASE_PROCESS.md +++ b/RELEASE_PROCESS.md @@ -18,8 +18,8 @@ created. The release branches are initially created from the `main` branch via the GitHub action [`Release Branch Creation`](./.github/workflows/release-branch.yaml). -A release is generated by calling a specific [ -`release`](./.github/workflows/release.yaml) GitHub Action. It is +A release is generated by calling a specific +[`release`](./.github/workflows/release.yaml) GitHub Action. It is executed on the branch which should be released - regardless whether it is a patch or a minor release. @@ -63,11 +63,11 @@ gitGraph TB: ### The Release Branch Creation / Cutoff -Every minor release starts with the creation of a release branch through [ -`Release Branch Creation`](./.github/workflows/release-branch.yaml). +Every minor release starts with the creation of a release branch through +[`Release Branch Creation`](./.github/workflows/release-branch.yaml). -The version / minor of the release is based on the content of the file [ -`VERSION`](./VERSION) which +The version / minor of the release is based on the content of the file +[`VERSION`](./VERSION) which is updated automatically said `release` action. During development, the content of this file is the complete release name of the release currently under development and the suffix `-dev` (e.g. `0.1.0-dev`). The content of this file @@ -93,8 +93,8 @@ This means that: the release manager - Any bug fix that is not deemed critical must be approved by the release manager -- Any bug fix must first be merged to main and then [ - `cherry-picked`](https://git-scm.com/docs/git-cherry-pick) to the release +- Any bug fix must first be merged to main and then + [`cherry-picked`](https://git-scm.com/docs/git-cherry-pick) to the release branch. At this point in time, any release targeted on this branch will have this minor @@ -143,12 +143,12 @@ and after a grace period, promote the draft release to a full release. This promotion is currently effectively a full rebuild from the release branch, with the difference that the `-rc.` suffix is removed. -After the build, instead of finishing, the [ -`release`](./.github/workflows/release.yaml) GitHub Action will also publish the +After the build, instead of finishing, the +[`release`](./.github/workflows/release.yaml) GitHub Action will also publish the release. -This publishing to package registries (such as brew) is delegated to [ -`publish-to-other-than-github`](./.github/workflows/publish-to-other-than-github.yaml) +This publishing to package registries (such as brew) is delegated to +[`publish-to-other-than-github`](./.github/workflows/publish-to-other-than-github.yaml) After the official release on a release branch was successful, the version is considered `burned`. This means that, even if bugs are found for that release in the future, a @@ -244,3 +244,29 @@ branches were created on demand. This model has now largely been replaced by the model we see in this document. However you might still encounter leftovers form the old model and you are encouraged to create issues regarding inconsistencies. + +## Follow up actions + +Review and merge open pull requests at the following locations. +See [Publish Release to other package registries than Github](https://github.com/open-component-model/ocm/actions/workflows/publish-to-other-than-github.yaml) workflow runs. +In case of error you can try to [Manually retrigger the publishing of ocm-cli to other repositories](https://github.com/open-component-model/ocm/actions/workflows/retrigger-publish-to-other.yaml). + +### ocm-website + +[Update the website](https://github.com/open-component-model/ocm-website/pulls). + +### homebrew-tap + +[Update brew tap](https://github.com/open-component-model/homebrew-tap/pulls). + +### winget-pkgs + +[Check winget-pkgs PRs for: `New version: Open-Component-Model.ocm-cli`](https://github.com/microsoft/winget-pkgs/pulls?q=is%3Apr+is%3Aopen+New+version%3A+Open-Component-Model.ocm-cli). + +### chocolatey + +[Check the `Packages in Moderation`](https://community.chocolatey.org/profiles/ocm.software#profile-moderation). + +### piper-ocm-cli + +[Update piper-ocm-cli](https://github.tools.sap/open-component-model/piper-ocm-cli/pulls). From c9a1dff3b8cc18e7f70a6247d4377a42dae96f1e Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 00:01:40 +0100 Subject: [PATCH 03/50] chore: bump VERSION to 0.20.0-dev (#1144) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update OCM Version to 0.20.0-dev This makes sure that the branch contains the next valid version. This is a minor bump, the next release will be a new minor version and signals opening of the development branch for new features. Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> Co-authored-by: Jakob Möller --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 7120f981c5..821e168310 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.19.0-dev +0.20.0-dev From 1a5ff47376bd0d99838f67c494a4c516735cd1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Wed, 27 Nov 2024 12:06:12 +0100 Subject: [PATCH 04/50] chore: autocollapse release notes (#1145) #### What this PR does / why we need it Adds a small script that autocollapses our release notes again because we no longer use release drafter #### Which issue(s) this PR fixes --------- Co-authored-by: Frederic Wilhelm --- .github/config/markdown-link-check.json | 1 + .github/config/markdownignore | 1 + .github/config/wordlist.txt | 3 +- .github/workflows/release-drafter.yaml | 11 ++ hack/collapse/.gitignore | 1 + hack/collapse/auto_collapse.sh | 115 ++++++++++++++++++ hack/collapse/test_auto_collapse.sh | 26 ++++ hack/collapse/test_example.md | 19 +++ .../test_example_expected_collapsible.md | 26 ++++ 9 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 hack/collapse/.gitignore create mode 100755 hack/collapse/auto_collapse.sh create mode 100755 hack/collapse/test_auto_collapse.sh create mode 100644 hack/collapse/test_example.md create mode 100644 hack/collapse/test_example_expected_collapsible.md diff --git a/.github/config/markdown-link-check.json b/.github/config/markdown-link-check.json index 9f14fd321d..89c303a8b9 100644 --- a/.github/config/markdown-link-check.json +++ b/.github/config/markdown-link-check.json @@ -5,5 +5,6 @@ { "pattern": "^http[s]*://localhost.*" } ,{ "pattern": "^https://.*\\.sigstore\\.dev.*" } ,{ "pattern": "^{{.*}}$" } + ,{ "pattern": "^https://github.com/**/compare/**" } ] } diff --git a/.github/config/markdownignore b/.github/config/markdownignore index 61874c2a7a..00158608b8 100644 --- a/.github/config/markdownignore +++ b/.github/config/markdownignore @@ -1,3 +1,4 @@ examples/lib/tour/0* docs/reference docs/pluginreference +hack/collapse/* \ No newline at end of file diff --git a/.github/config/wordlist.txt b/.github/config/wordlist.txt index 3bb353cc37..d38b0d4469 100644 --- a/.github/config/wordlist.txt +++ b/.github/config/wordlist.txt @@ -27,6 +27,7 @@ bool boolean buildx cas +changelog chocolateyinstall cli cliconfig @@ -307,4 +308,4 @@ xml yaml yitsushi yml -yyyy +yyyy \ No newline at end of file diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index e066e35b6d..ca8a9601cf 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -44,6 +44,7 @@ jobs: fetch-tags: true - name: Setup Release with gh env: + COLLAPSE_THRESHOLD: 5 REF: ${{ github.ref }} REPO: ${{ github.repository }} GH_TOKEN: ${{ steps.generate_token.outputs.token }} @@ -81,6 +82,16 @@ jobs: -q .body \ ) + if [[ -z $notes ]]; then + echo "No release notes generated from API, failed" + exit 1 + fi + + echo "Auto-Collapsing release notes to reduce size" + echo $notes > $RUNNER_TEMP/release_notes.md + bash hack/collapse/auto_collapse.sh $RUNNER_TEMP/release_notes.md $RUNNER_TEMP/release_notes_processed.md ${{ env.COLLAPSE_THRESHOLD }} + notes=$(cat $RUNNER_TEMP/release_notes_processed.md) + echo "Release Notes generated for ${{env.RELEASE_VERSION}}:" echo "${notes}" diff --git a/hack/collapse/.gitignore b/hack/collapse/.gitignore new file mode 100644 index 0000000000..edf5bf79b3 --- /dev/null +++ b/hack/collapse/.gitignore @@ -0,0 +1 @@ +test_example_collapsible.md \ No newline at end of file diff --git a/hack/collapse/auto_collapse.sh b/hack/collapse/auto_collapse.sh new file mode 100755 index 0000000000..6ba7eeedf2 --- /dev/null +++ b/hack/collapse/auto_collapse.sh @@ -0,0 +1,115 @@ +#!/bin/bash + +# allow > to overwrite files +set +o noclobber + +# Auto Collapse +#This is a script that takes in +# - a markdown file +# - a designated output file +# - the number of lines as a threshold on when to collapse a section. +# +# Sample +# ./auto_collapse.sh test_example.md test_example_collapsible.md 5 + +# Input and output files +INPUT_FILE=${1:-"README.md"} +OUTPUT_FILE=${2:-"README_collapsible.md"} +THRESHOLD=${3:-10} + +# Ensure output file is empty initially +true > "$OUTPUT_FILE" + +# Variables to track sections +inside_section=false +section_lines=() +section_header="" + +input="$(cat "$INPUT_FILE")" +FULL_CHANGELOG=$(grep "Full Changelog" < "$INPUT_FILE") + +if [[ -z $FULL_CHANGELOG ]]; then + echo "Full Changelog not found in the input file." +else + echo "Full Changelog found in the input file." + input=$(sed '/Full Changelog/d' <<< "${input}") +fi + +# Function to count changes (lines starting with '*') +count_changes() { + local lines=("$@") + local count=0 + for line in "${lines[@]}"; do + if [[ $line =~ ^\* ]]; then + ((count++)) + fi + done + echo "$count" +} + +# Function to process and write a section +write_section() { + local header="$1" + local lines=("${@:2}") + num_changes=$(count_changes "${lines[@]}") + + # Write the section header as is + echo "$header" >> "$OUTPUT_FILE" + + if [[ $num_changes -gt $THRESHOLD ]]; then + # Collapse only the content with a dynamic summary + { + echo "
" + echo "${num_changes} changes" + echo "" + printf "%s\n" "${lines[@]}" + echo "
" + echo "" + } >> "$OUTPUT_FILE" + else + # Write the content as is if it's below the threshold + printf "%s\n" "${lines[@]}" >> "$OUTPUT_FILE" + fi +} + +# Read the Markdown file line by line +echo "${input}" | while IFS= read -r line || [[ -n $line ]]; do + # Preserve comment blocks + if [[ $line =~ ^\ + +## What's Changed +### 🚀 Features +* feat(log): log http requests for OCI and docker based on trace level by injecting a logger by @author in https://github.com/open-component-model/ocm/pull/1118 +### 🧰 Maintenance +* chore: change guide for 0.18.0 by @author in https://github.com/open-component-model/ocm/pull/1066 +* chore: allow publishing to Brew via custom script by @author in https://github.com/open-component-model/ocm/pull/1059 +* chore: remove ocm inception during build CTF aggregation by @author in https://github.com/open-component-model/ocm/pull/1065 +* chore: release branches as `releases/vX.Y` instead of `releases/vX.Y.Z` by @author in https://github.com/open-component-model/ocm/pull/1071 +* chore: cleanup release action by @author in https://github.com/open-component-model/ocm/pull/1076 +* chore: bump version to 0.19.0-dev by @author in https://github.com/open-component-model/ocm/pull/1084 +* chore: disable mandatory period comments by @author in https://github.com/open-component-model/ocm/pull/1079 +### Some other +* chore: change guide for 0.18.0 by @author in +* chore: allow publishing to Brew via custom script by @author in + +**Full Changelog**: https://github.com/open-component-model/ocm/compare/v0.18...v0.19.0 + \ No newline at end of file diff --git a/hack/collapse/test_example_expected_collapsible.md b/hack/collapse/test_example_expected_collapsible.md new file mode 100644 index 0000000000..9ab77e97e9 --- /dev/null +++ b/hack/collapse/test_example_expected_collapsible.md @@ -0,0 +1,26 @@ + + +## What's Changed + +### 🚀 Features +* feat(log): log http requests for OCI and docker based on trace level by injecting a logger by @author in https://github.com/open-component-model/ocm/pull/1118 +### 🧰 Maintenance +
+7 changes + +* chore: change guide for 0.18.0 by @author in https://github.com/open-component-model/ocm/pull/1066 +* chore: allow publishing to Brew via custom script by @author in https://github.com/open-component-model/ocm/pull/1059 +* chore: remove ocm inception during build CTF aggregation by @author in https://github.com/open-component-model/ocm/pull/1065 +* chore: release branches as `releases/vX.Y` instead of `releases/vX.Y.Z` by @author in https://github.com/open-component-model/ocm/pull/1071 +* chore: cleanup release action by @author in https://github.com/open-component-model/ocm/pull/1076 +* chore: bump version to 0.19.0-dev by @author in https://github.com/open-component-model/ocm/pull/1084 +* chore: disable mandatory period comments by @author in https://github.com/open-component-model/ocm/pull/1079 +
+ +### Some other +* chore: change guide for 0.18.0 by @author in +* chore: allow publishing to Brew via custom script by @author in + + + +**Full Changelog**: https://github.com/open-component-model/ocm/compare/v0.18...v0.19.0 \ No newline at end of file From de4f1024e44f0ffcbfa1cd71827708aaa66ef2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Wed, 27 Nov 2024 14:08:25 +0100 Subject: [PATCH 05/50] chore: fixup release notes (#1148) #### What this PR does / why we need it the release notes that were fixed up require a small adjustment to be able to deal with properly multilined files. This is because the notes are stored in bash variables which removes newlines by default. Now they are properly formatted in again and we also fixup the script so that the line count is correct #### Which issue(s) this PR fixes Makes sure that multilined release notes are interpreted correctly and dont break out. This happened with release/v0.19 so that commit was patched up by force push to test out the notes --- .github/workflows/release-drafter.yaml | 4 +-- hack/collapse/auto_collapse.sh | 36 +++++++++++++------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/.github/workflows/release-drafter.yaml b/.github/workflows/release-drafter.yaml index ca8a9601cf..0566b2f353 100644 --- a/.github/workflows/release-drafter.yaml +++ b/.github/workflows/release-drafter.yaml @@ -82,13 +82,13 @@ jobs: -q .body \ ) - if [[ -z $notes ]]; then + if [[ -z "${notes}" ]]; then echo "No release notes generated from API, failed" exit 1 fi echo "Auto-Collapsing release notes to reduce size" - echo $notes > $RUNNER_TEMP/release_notes.md + echo "${notes}" > $RUNNER_TEMP/release_notes.md bash hack/collapse/auto_collapse.sh $RUNNER_TEMP/release_notes.md $RUNNER_TEMP/release_notes_processed.md ${{ env.COLLAPSE_THRESHOLD }} notes=$(cat $RUNNER_TEMP/release_notes_processed.md) diff --git a/hack/collapse/auto_collapse.sh b/hack/collapse/auto_collapse.sh index 6ba7eeedf2..31d7803238 100755 --- a/hack/collapse/auto_collapse.sh +++ b/hack/collapse/auto_collapse.sh @@ -24,16 +24,7 @@ true > "$OUTPUT_FILE" inside_section=false section_lines=() section_header="" - -input="$(cat "$INPUT_FILE")" -FULL_CHANGELOG=$(grep "Full Changelog" < "$INPUT_FILE") - -if [[ -z $FULL_CHANGELOG ]]; then - echo "Full Changelog not found in the input file." -else - echo "Full Changelog found in the input file." - input=$(sed '/Full Changelog/d' <<< "${input}") -fi +last_line="" # Function to count changes (lines starting with '*') count_changes() { @@ -51,6 +42,7 @@ count_changes() { write_section() { local header="$1" local lines=("${@:2}") + local num_changes num_changes=$(count_changes "${lines[@]}") # Write the section header as is @@ -73,15 +65,24 @@ write_section() { } # Read the Markdown file line by line -echo "${input}" | while IFS= read -r line || [[ -n $line ]]; do +while IFS= read -r line || [[ -n $line ]]; do + # Check if the line contains "Full Changelog" + if [[ $line =~ ^\*\*Full\ Changelog ]]; then + # Finalize any pending section + if [[ $inside_section == true ]]; then + write_section "$section_header" "${section_lines[@]:1}" # Exclude the header + inside_section=false + fi + last_line="$line" + continue + fi + # Preserve comment blocks if [[ $line =~ ^\ diff --git a/.github/ISSUE_TEMPLATE/user_story.md b/.github/ISSUE_TEMPLATE/user_story.md index 645631eefa..7778433c9d 100644 --- a/.github/ISSUE_TEMPLATE/user_story.md +++ b/.github/ISSUE_TEMPLATE/user_story.md @@ -1,7 +1,7 @@ --- name: User Story about: User Story -labels: +labels: kind/feature title: - Title --- diff --git a/.github/config/labeler.yml b/.github/config/labeler.yml index 2efa435e4a..a1177b0253 100644 --- a/.github/config/labeler.yml +++ b/.github/config/labeler.yml @@ -1,9 +1,27 @@ # see https://github.com/actions/labeler?tab=readme-ov-file#match-object to configure correctly -dependencies: +kind/dependency: - any: - head-branch: 'dependencies/*' - head-branch: 'dependabot/*' -github-actions: + - changed-files: + - any-glob-to-any-file: ['go.mod', 'go.sum'] +component/github-actions: +- any: + - changed-files: + - any-glob-to-any-file: ['.github/**'] +area/documentation: +- any: + - changed-files: + - any-glob-to-any-file: ['docs/**', 'examples/**'] +component/ocm-cli: +- any: + - changed-files: + - any-glob-to-any-file: ['components/ocmcli/**', 'cmds/ocm/**'] +component/ocm-spec: +- any: + - changed-files: + - any-glob-to-any-file: ['resources/**'] +kind/skip-release-notes: - any: - changed-files: - - any-glob-to-any-file: ['.github/**'] \ No newline at end of file + - any-glob-to-any-file: ['flake.lock', 'flake.nix'] diff --git a/.github/config/release.yml b/.github/config/release.yml index cf08521604..dcbcbc531f 100644 --- a/.github/config/release.yml +++ b/.github/config/release.yml @@ -1,28 +1,24 @@ changelog: + # ../workflows/pull_request.yaml#verify-labels one_of: kind/chore,kind/bugfix,kind/feature,kind/dependency,kind/refactor exclude: labels: - 'kind/skip-release-notes' - - 'wontfix' - - 'triage/wont-fix' - - 'triage/invalid' + - 'dev/wont-fix' + - 'dev/cant-reproduce' categories: - - title: '‼️ Breaking Changes' - labels: - - 'breaking-change' - - title: '🚀 Features' - labels: - - 'kind/enhancement' - - 'feature' - - 'enhancement' - - title: '🐛 Bug Fixes' - labels: - - 'kind/bug' - - 'fix' - - 'bugfix' - - 'bug' - - title: '🧰 Maintenance' - labels: - - 'chore' - - title: '⬆️ Dependencies' - labels: - - 'dependencies' \ No newline at end of file + - title: '‼️ Breaking Changes' + labels: + - '!BREAKING-CHANGE!' + - title: '🚀 Features' + labels: + - 'kind/feature' + - title: '🐛 Bug Fixes' + labels: + - 'kind/bugfix' + - title: '🧰 Maintenance' + labels: + - 'kind/chore' + - 'kind/refactor' + - title: '⬆️ Dependencies' + labels: + - 'kind/dependency' diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f689040921..073b795316 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -11,6 +11,11 @@ updates: schedule: interval: "weekly" day: "sunday" + labels: + - kind/dependency + - kind/chore + - kind/skip-release-notes + - component/github-actions - package-ecosystem: "gomod" directory: "/" groups: @@ -19,3 +24,6 @@ updates: schedule: interval: "weekly" day: "sunday" + labels: + - kind/dependency + - kind/chore diff --git a/.github/workflows/flake_vendorhash.yaml b/.github/workflows/flake_vendorhash.yaml index 4e4c390cb8..b1d20d21ee 100644 --- a/.github/workflows/flake_vendorhash.yaml +++ b/.github/workflows/flake_vendorhash.yaml @@ -59,6 +59,6 @@ jobs: sign-commits: true labels: | kind/skip-release-notes - chore + kind/chore body: | Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index 06785945db..cc2ad2bf8d 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -24,18 +24,18 @@ jobs: env: TYPE_TO_LABEL: | { - "feat":"kind/enhancement", - "fix":"fix", - "chore":"chore", - "docs":"kind/documentation", - "test":"kind/test", - "perf":"kind/performance" + "feat":"kind/feature", + "fix":"kind/bugfix", + "chore":"kind/chore", + "docs":"area/documentation", + "test":"area/testing", + "perf":"area/performance" } SCOPE_TO_LABEL: | { - "deps":"dependencies" + "deps":"kind/dependency" } - BREAKING_CHANGE_LABEL: "breaking" + BREAKING_CHANGE_LABEL: "!BREAKING-CHANGE!" with: script: | console.log("Verify that the PR title follows the Conventional Commit format"); @@ -158,5 +158,5 @@ jobs: - name: PRs should have at least one qualifying label uses: docker://agilepathway/pull-request-label-checker:latest with: - one_of: chore,fix,bugfix,bug,kind/bug,feature,enhancement,kind/enhancement,dependencies - repo_token: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file + one_of: kind/chore,kind/bugfix,kind/feature,kind/dependency,kind/refactor + repo_token: ${{ secrets.GITHUB_TOKEN }} From 670abc1e8c566efbddbdcf083c7a2daa33bcf409 Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Wed, 27 Nov 2024 17:29:45 +0100 Subject: [PATCH 07/50] chore: inherit from .github labels (#1150) #### What this PR does / why we need it 1. merge https://github.com/open-component-model/ocm/pull/1115 2. execute [migrate-labels.sh](https://github.com/open-component-model/.github/blob/main/labels/migrate-labels.sh) on `ocm` 3. merge this PR --- .github/settings.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/settings.yml diff --git a/.github/settings.yml b/.github/settings.yml new file mode 100644 index 0000000000..53861cbcc7 --- /dev/null +++ b/.github/settings.yml @@ -0,0 +1,8 @@ +# These settings are synced to GitHub by https://probot.github.io/apps/settings/ + +# see: https://github.com/open-component-model/.github/blob/main/.github/settings.yml +_extends: .github + +labels: +- name: repo/ocm + color: bfd4f2 From 362cb8d4a04e4f6885ab77a62637a094ff018f0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:39:15 +0000 Subject: [PATCH 08/50] chore(deps): bump the go group with 3 updates (#1151) Bumps the go group with 3 updates: [github.com/aws/aws-sdk-go-v2/feature/s3/manager](https://github.com/aws/aws-sdk-go-v2), [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) and [github.com/onsi/gomega](https://github.com/onsi/gomega). Updates `github.com/aws/aws-sdk-go-v2/feature/s3/manager` from 1.17.40 to 1.17.41
Commits

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.68.0 to 1.69.0
Commits

Updates `github.com/onsi/gomega` from 1.35.1 to 1.36.0
Release notes

Sourced from github.com/onsi/gomega's releases.

v1.36.0

1.36.0

Features

  • new: make collection-related matchers Go 1.23 iterator aware [4c964c6]

Maintenance

  • Replace min/max helpers with built-in min/max [ece6872]
  • Fix some typos in docs [8e924d7]
Changelog

Sourced from github.com/onsi/gomega's changelog.

1.36.0

Features

  • new: make collection-related matchers Go 1.23 iterator aware [4c964c6]

Maintenance

  • Replace min/max helpers with built-in min/max [ece6872]
  • Fix some typos in docs [8e924d7]
Commits
  • f1ff459 v1.36.0
  • 4c964c6 new: make collection-related matchers Go 1.23 iterator aware
  • ece6872 Replace min/max helpers with built-in min/max
  • 8e924d7 Fix some typos in docs
  • See full diff in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 6 +++--- go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index 4623b27dde..5632f9fe61 100644 --- a/go.mod +++ b/go.mod @@ -11,9 +11,9 @@ require ( github.com/aws/aws-sdk-go-v2 v1.32.5 github.com/aws/aws-sdk-go-v2/config v1.28.5 github.com/aws/aws-sdk-go-v2/credentials v1.17.46 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.40 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 - github.com/aws/aws-sdk-go-v2/service/s3 v1.68.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 github.com/cloudflare/cfssl v1.6.5 github.com/containerd/containerd v1.7.24 github.com/containerd/errdefs v1.0.0 @@ -52,7 +52,7 @@ require ( github.com/mittwald/go-helm-client v0.12.14 github.com/modern-go/reflect2 v1.0.2 github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.35.1 + github.com/onsi/gomega v1.36.0 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index e7febab052..e6fda21192 100644 --- a/go.sum +++ b/go.sum @@ -175,8 +175,8 @@ github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgb github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.40 h1:CbalQNEYQljzAJ+3beY8FQBShdLNLpJzHL4h/5LSFMc= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.40/go.mod h1:1iYVr/urNWuZ7WZ1829FSE7RRTaXvzFdwrEQV8Z40cE= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 h1:hqcxMc2g/MwwnRMod9n6Bd+t+9Nf7d5qRg7RaXKPd6o= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41/go.mod h1:d1eH0VrttvPmrCraU68LOyNdu26zFxQFjrVSb5vdhog= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o= @@ -199,8 +199,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ON github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5 h1:5dQJ6Q5QrQOqZxXjSbRXukBqU8Pgu6Ro6Qqtyd8yiz4= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5/go.mod h1:A9vfQcNHVBCE7ZZN6H+UUJpXtbH26Vv6L7Zhk5nIJAY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.68.0 h1:bFpcqdwtAEsgpZXvkTxIThFQx/EM0oV6kXmfFIGjxME= -github.com/aws/aws-sdk-go-v2/service/s3 v1.68.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow= +github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow= github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM= github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8= @@ -803,8 +803,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y= +github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9 h1:b2cJvZ8nWAVvCqvPhUaFl26Wht4nM4mqfl2ksY9lVzU= github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/open-policy-agent/opa v0.68.0 h1:Jl3U2vXRjwk7JrHmS19U3HZO5qxQRinQbJ2eCJYSqJQ= From c2434f33f4f99b84eb58a854418c9d0b88897def Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Wed, 27 Nov 2024 16:48:41 +0000 Subject: [PATCH 09/50] chore: update 'flake.nix' (#1152) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 701c062f33..b937ab5526 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-o3425Wh5uarsBFQZxciE0jDfSapzu+AjeKf4/FM5kW8="; + vendorHash = "sha256-CsGWwNrRpT5kvZgI3eTbJzgQT+FXkVRyrvILsvW+UlY="; src = ./.; From b394c3841c8d58ba36aca97cf6776ab74352bf13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 28 Nov 2024 10:07:59 +0100 Subject: [PATCH 10/50] feat: migrate to fully distroless ocm image (#1087) #### What this PR does / why we need it Migrates to Distroless which has a few advantages over alpine: 1. Smaller Base Image 2. No Package Manager or Shell that could be used to exploit vulnerabilities 3. Non-Root user by default I also remove the latest check in alpine since it only fetched a tag anyhow and we should pin by digest #### Which issue(s) this PR fixes --- Dockerfile | 22 +++++++++------------- components/ocmcli/Dockerfile | 23 +++++++++-------------- components/ocmcli/Makefile | 6 ------ components/ocmcli/ocm.sh | 20 -------------------- 4 files changed, 18 insertions(+), 53 deletions(-) delete mode 100644 components/ocmcli/ocm.sh diff --git a/Dockerfile b/Dockerfile index a7cd172537..d867203530 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,6 @@ ARG GO_VERSION="1.23" ARG ALPINE_VERSION="3.20" +ARG DISTROLESS_VERSION=debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS build @@ -20,26 +21,21 @@ RUN --mount=type=cache,target=/root/.cache/go-build \ "-s -w -X ocm.software/ocm/api/version.gitVersion=$VERSION -X ocm.software/ocm/api/version.buildDate=$NOW" \ -o /bin/ocm ./cmds/ocm/main.go -FROM alpine:${ALPINE_VERSION} +FROM gcr.io/distroless/static-${DISTROLESS_VERSION} +# pass arg from initial build +ARG DISTROLESS_VERSION -# Create group and user -ARG UID=1000 -ARG GID=1000 -RUN addgroup -g "${GID}" ocmGroup && adduser -u "${UID}" ocmUser -G ocmGroup -D - -COPY --from=build /bin/ocm /bin/ocm -COPY --chmod=0755 components/ocmcli/ocm.sh /bin/ocm.sh +COPY --from=build /bin/ocm /usr/local/bin/ocm # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.description="Open Component Model command line interface based on Alpine ${ALPINE_VERSION}" +LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless ${DISTROLESS_VERSION}" LABEL org.opencontainers.image.vendor="SAP SE" LABEL org.opencontainers.image.licenses="Apache-2.0" LABEL org.opencontainers.image.url="https://ocm.software/" LABEL org.opencontainers.image.source="https://github.com/open-component-model/ocm" LABEL org.opencontainers.image.title="ocm" LABEL org.opencontainers.image.documentation="https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm.md" -LABEL org.opencontainers.image.base.name="alpine:${ALPINE_VERSION}" +LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-${DISTROLESS_VERSION}" -USER ocmUser -ENTRYPOINT ["/bin/ocm.sh"] -CMD ["/bin/ocm"] +ENTRYPOINT ["/usr/local/bin/ocm"] +CMD ["version"] diff --git a/components/ocmcli/Dockerfile b/components/ocmcli/Dockerfile index dc5a504d7e..1cb3673bac 100644 --- a/components/ocmcli/Dockerfile +++ b/components/ocmcli/Dockerfile @@ -1,21 +1,17 @@ # This Dockerfile is used by `make` via the Makefile -ARG ALPINE_VERSION="3.20.2" -FROM --platform=$BUILDPLATFORM alpine:${ALPINE_VERSION} - -# Create group and user -ARG UID=1000 -ARG GID=1000 -RUN addgroup -g "${GID}" ocmGroup && adduser -u "${UID}" ocmUser -G ocmGroup -D +ARG DISTROLESS_VERSION=debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea +FROM --platform=$BUILDPLATFORM gcr.io/distroless/static-${DISTROLESS_VERSION} +# pass arg from initial build +ARG DISTROLESS_VERSION ARG SUFFIX ARG OCM_VERSION -COPY gen/ocmcli/ocmcli.$SUFFIX /bin/ocm -COPY --chmod=0755 components/ocmcli/ocm.sh /bin/ocm.sh +COPY gen/ocmcli/ocmcli.$SUFFIX /usr/local/bin/ocm # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.description="Open Component Model command line interface based on Alpine ${ALPINE_VERSION}" +LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless ${DISTROLESS_VERSION}" LABEL org.opencontainers.image.vendor="SAP SE" LABEL org.opencontainers.image.licenses="Apache-2.0" LABEL org.opencontainers.image.url="https://ocm.software/" @@ -24,8 +20,7 @@ LABEL org.opencontainers.image.title="ocm" LABEL org.opencontainers.image.version="${OCM_VERSION}" LABEL org.opencontainers.image.revision="${OCM_VERSION}" LABEL org.opencontainers.image.documentation="https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm.md" -LABEL org.opencontainers.image.base.name="alpine:${ALPINE_VERSION}" +LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-${DISTROLESS_VERSION}" -USER ocmUser -ENTRYPOINT ["/bin/ocm.sh"] -CMD ["/bin/ocm"] +ENTRYPOINT ["/usr/local/bin/ocm"] +CMD ["version"] diff --git a/components/ocmcli/Makefile b/components/ocmcli/Makefile index 18d955580f..20915dab42 100644 --- a/components/ocmcli/Makefile +++ b/components/ocmcli/Makefile @@ -55,8 +55,6 @@ BUILD_FLAGS := "-s -w \ -X ocm.software/ocm/api/version.gitCommit=$(COMMIT) \ -X ocm.software/ocm/api/version.buildDate=$(NOW)" -ALPINE_LATEST_VER=$(shell curl -s https://registry.hub.docker.com/v2/repositories/library/alpine/tags | jq '.results[1].name' | xargs) - .PHONY: build build: $(GEN)/build @@ -78,13 +76,11 @@ $(GEN)/image: $(GEN)/.exists Dockerfile $(GEN)/build echo; echo "Building linux instead of darwin as there's no native Docker platform for darwin"; echo; \ docker buildx build -t $(IMAGE):$(VERSION) --platform linux/$(PLATFORM_ARCH) --file Dockerfile $(REPO_ROOT) \ --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg ALPINE_VERSION=$(ALPINE_LATEST_VER) \ --build-arg SUFFIX=$$(echo linux/$(PLATFORM_ARCH) | sed -e s:/:-:g); \ else \ echo; echo "Building for $(PLATFORM_OS)/$(ARCH)"; echo; \ docker buildx build -t $(IMAGE):$(VERSION) --platform $(PLATFORM_OS)/$(PLATFORM_ARCH) --file Dockerfile $(REPO_ROOT) \ --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg ALPINE_VERSION=$(ALPINE_LATEST_VER) \ --build-arg SUFFIX=$$(echo $(PLATFORM_OS)/$(PLATFORM_ARCH) | sed -e s:/:-:g); \ fi @touch $(GEN)/image @@ -93,13 +89,11 @@ $(GEN)/image: $(GEN)/.exists Dockerfile $(GEN)/build image.multi: $(GEN)/image.multi $(GEN)/image.multi: Dockerfile $(GEN)/build - echo "Building with Alpine version: ${ALPINE_LATEST_VER}" for i in $(IMAGE_PLATFORMS); do \ tag=$$(echo $$i | sed -e s:/:-:g); \ echo building platform $$i; \ docker buildx build --load -t $(IMAGE):$(VERSION)-$$tag --platform $$i --file Dockerfile $(REPO_ROOT) \ --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg ALPINE_VERSION=$(ALPINE_LATEST_VER) \ --build-arg SUFFIX=$$tag; \ done @touch $(GEN)/image.multi diff --git a/components/ocmcli/ocm.sh b/components/ocmcli/ocm.sh deleted file mode 100644 index 0225d4c62d..0000000000 --- a/components/ocmcli/ocm.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh -set -e - -# this if will check if the first argument is a flag but only works if all arguments require a hyphenated flag -v; -SL; -f arg; etc will work, but not arg1 arg2 -if [ "$#" -eq 0 ] || [ "${1#-}" != "$1" ]; then - set -- "$@" - exec /bin/ocm "$@" - return -fi - -# this case will check if the first argument is a known OCM command -case $1 in - add | bootstrap | cache | check | clean | completion | controller | create | credentials | describe | download | execute | get | hash | help | install | oci | ocm | show | sign | toi | transfer | verify | version) - exec /bin/ocm "$@" - return - ;; -esac - -# else default to run whatever the user wanted like "bash" or "sh" -exec "$@" From 592a902497e62ed7de9806c4664ac2b0c472674d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 28 Nov 2024 11:41:58 +0100 Subject: [PATCH 11/50] chore: prioritize deps over chore (#1155) #### What this PR does / why we need it this makes it so that issues listing a dependency kind will be sorted into the correct category instead of maintenance even though they are listed as chore(deps) #### Which issue(s) this PR fixes --- .github/config/release.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/config/release.yml b/.github/config/release.yml index dcbcbc531f..e7b4feb342 100644 --- a/.github/config/release.yml +++ b/.github/config/release.yml @@ -5,6 +5,9 @@ changelog: - 'kind/skip-release-notes' - 'dev/wont-fix' - 'dev/cant-reproduce' + # if an issue matches more than one category, the first one in the list will be used + # Example: + # Labels: kind/chore, kind/dependency => Category: Dependencies categories: - title: '‼️ Breaking Changes' labels: @@ -15,10 +18,10 @@ changelog: - title: '🐛 Bug Fixes' labels: - 'kind/bugfix' + - title: '⬆️ Dependencies' + labels: + - 'kind/dependency' - title: '🧰 Maintenance' labels: - 'kind/chore' - 'kind/refactor' - - title: '⬆️ Dependencies' - labels: - - 'kind/dependency' From e96ed216d7d9983ece887ec2b665b9c83fda83dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 28 Nov 2024 12:13:14 +0100 Subject: [PATCH 12/50] chore: add catch all category for release (#1157) #### What this PR does / why we need it this adds a catch all category if none of the labels mentioned in the config didnt apply. #### Which issue(s) this PR fixes --- .github/config/release.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/config/release.yml b/.github/config/release.yml index e7b4feb342..b3eec8b0fd 100644 --- a/.github/config/release.yml +++ b/.github/config/release.yml @@ -25,3 +25,6 @@ changelog: labels: - 'kind/chore' - 'kind/refactor' + - title: 'Other Changes' + labels: + - "*" From e0d3a0bb9cb9fe60d3df6c2c706c02a3e634214c Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Thu, 28 Nov 2024 17:06:05 +0100 Subject: [PATCH 13/50] chore: missed this occurrence of `kind/bug` (#1159) --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 99fcd655f1..beb023a9ab 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,7 +1,7 @@ --- name: Bug Report about: Report a bug -labels: kind/bug +labels: kind/bugfix --- From 2585bd5e04e529541e25f4ee5273ad6fda9fee2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 28 Nov 2024 17:38:53 +0100 Subject: [PATCH 14/50] chore: make sure that dockerfiles are setup in a standard way (#1160) #### What this PR does / why we need it This simplifies the docker images update process because it runs through dependabot.yml #### Which issue(s) this PR fixes --- .github/dependabot.yml | 8 ++++++++ Dockerfile | 14 ++++---------- components/ocmcli/Dockerfile | 9 +++------ 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 073b795316..6a4c244582 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -27,3 +27,11 @@ updates: labels: - kind/dependency - kind/chore + - package-ecosystem: docker + directory: "/" + schedule: + interval: "weekly" + day: "sunday" + labels: + - kind/dependency + - kind/chore diff --git a/Dockerfile b/Dockerfile index d867203530..1a8f590786 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,4 @@ -ARG GO_VERSION="1.23" -ARG ALPINE_VERSION="3.20" -ARG DISTROLESS_VERSION=debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea - -FROM golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS build +FROM golang:1.23-alpine3.20 AS build WORKDIR /src RUN go env -w GOMODCACHE=/root/.cache/go-build @@ -21,21 +17,19 @@ RUN --mount=type=cache,target=/root/.cache/go-build \ "-s -w -X ocm.software/ocm/api/version.gitVersion=$VERSION -X ocm.software/ocm/api/version.buildDate=$NOW" \ -o /bin/ocm ./cmds/ocm/main.go -FROM gcr.io/distroless/static-${DISTROLESS_VERSION} -# pass arg from initial build -ARG DISTROLESS_VERSION +FROM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea COPY --from=build /bin/ocm /usr/local/bin/ocm # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless ${DISTROLESS_VERSION}" +LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless" LABEL org.opencontainers.image.vendor="SAP SE" LABEL org.opencontainers.image.licenses="Apache-2.0" LABEL org.opencontainers.image.url="https://ocm.software/" LABEL org.opencontainers.image.source="https://github.com/open-component-model/ocm" LABEL org.opencontainers.image.title="ocm" LABEL org.opencontainers.image.documentation="https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm.md" -LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-${DISTROLESS_VERSION}" +LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-debian12:nonroot" ENTRYPOINT ["/usr/local/bin/ocm"] CMD ["version"] diff --git a/components/ocmcli/Dockerfile b/components/ocmcli/Dockerfile index 1cb3673bac..b17ec7e741 100644 --- a/components/ocmcli/Dockerfile +++ b/components/ocmcli/Dockerfile @@ -1,9 +1,6 @@ # This Dockerfile is used by `make` via the Makefile -ARG DISTROLESS_VERSION=debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea -FROM --platform=$BUILDPLATFORM gcr.io/distroless/static-${DISTROLESS_VERSION} -# pass arg from initial build -ARG DISTROLESS_VERSION +FROM --platform=$BUILDPLATFORM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea ARG SUFFIX ARG OCM_VERSION @@ -11,7 +8,7 @@ ARG OCM_VERSION COPY gen/ocmcli/ocmcli.$SUFFIX /usr/local/bin/ocm # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless ${DISTROLESS_VERSION}" +LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless" LABEL org.opencontainers.image.vendor="SAP SE" LABEL org.opencontainers.image.licenses="Apache-2.0" LABEL org.opencontainers.image.url="https://ocm.software/" @@ -20,7 +17,7 @@ LABEL org.opencontainers.image.title="ocm" LABEL org.opencontainers.image.version="${OCM_VERSION}" LABEL org.opencontainers.image.revision="${OCM_VERSION}" LABEL org.opencontainers.image.documentation="https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm.md" -LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-${DISTROLESS_VERSION}" +LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-debian12:nonroot" ENTRYPOINT ["/usr/local/bin/ocm"] CMD ["version"] From 6aaf3fba8db4729aaf93128c066b7e4919900f8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 28 Nov 2024 18:10:27 +0100 Subject: [PATCH 15/50] chore: changes label check to any_of (#1162) #### What this PR does / why we need it Uses any_of as per https://github.com/agilepathway/label-checker?tab=readme-ov-file#checks because its technically possible that a PR fits multiple kinds (e.g. chore + dependency) #### Which issue(s) this PR fixes --- .github/workflows/pull-request.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pull-request.yaml b/.github/workflows/pull-request.yaml index cc2ad2bf8d..921f37fe87 100644 --- a/.github/workflows/pull-request.yaml +++ b/.github/workflows/pull-request.yaml @@ -158,5 +158,5 @@ jobs: - name: PRs should have at least one qualifying label uses: docker://agilepathway/pull-request-label-checker:latest with: - one_of: kind/chore,kind/bugfix,kind/feature,kind/dependency,kind/refactor + any_of: kind/chore,kind/bugfix,kind/feature,kind/dependency,kind/refactor repo_token: ${{ secrets.GITHUB_TOKEN }} From b02d33337e43662d40e706bdf89d55c033bae6b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Thu, 28 Nov 2024 18:19:19 +0100 Subject: [PATCH 16/50] chore(deps): use mergo vanity url (#1161) #### What this PR does / why we need it `In [1.0.0](https://github.com/imdario/mergo/releases/tag/1.0.0) Mergo moves to a vanity URL dario.cat/mergo. No more v1 versions will be released.` #### Which issue(s) this PR fixes see https://github.com/darccio/mergo?tab=readme-ov-file#100 --- api/utils/template/merge.go | 2 +- go.mod | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/api/utils/template/merge.go b/api/utils/template/merge.go index 7c8da61625..b349e40458 100644 --- a/api/utils/template/merge.go +++ b/api/utils/template/merge.go @@ -3,7 +3,7 @@ package template import ( "encoding/json" - "github.com/imdario/mergo" + "dario.cat/mergo" "sigs.k8s.io/yaml" ) diff --git a/go.mod b/go.mod index 5632f9fe61..ce8145cef0 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.23.2 replace github.com/spf13/cobra => github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9 require ( + dario.cat/mergo v1.0.1 github.com/DataDog/gostackparse v0.7.0 github.com/InfiniteLoopSpace/go_S-MIME v0.0.0-20181221134359-3f58f9a4b2b6 github.com/Masterminds/semver/v3 v3.3.1 @@ -37,7 +38,6 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-github/v45 v45.2.0 github.com/hashicorp/vault-client-go v0.4.3 - github.com/imdario/mergo v0.3.16 github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b github.com/klauspost/compress v1.17.11 github.com/klauspost/pgzip v1.2.6 @@ -89,7 +89,6 @@ require ( cloud.google.com/go/auth v0.10.2 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.5 // indirect cloud.google.com/go/compute/metadata v0.5.2 // indirect - dario.cat/mergo v1.0.1 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect github.com/AliyunContainerService/ack-ram-tool/pkg/credentials/provider v0.15.2 // indirect @@ -234,6 +233,7 @@ require ( github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/huandu/xstrings v1.5.0 // indirect + github.com/imdario/mergo v0.3.16 // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect @@ -368,6 +368,9 @@ require ( sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect ) +// see https://github.com/darccio/mergo?tab=readme-ov-file#100 +replace github.com/imdario/mergo => github.com/imdario/mergo v0.3.16 + retract [v0.16.0, v0.16.9] // Retract all from v0.16 due to https://github.com/open-component-model/ocm-project/issues/293 // crypto/tls: Client Hello is always sent in 2 TCP frames if GODEBUG=tlskyber=1 (default) which causes From aeaa706143eb7353fc4e5447fb3f80b0af1b92dd Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Thu, 28 Nov 2024 17:29:17 +0000 Subject: [PATCH 17/50] chore: update 'flake.nix' (#1164) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index b937ab5526..77c0e3bf98 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-CsGWwNrRpT5kvZgI3eTbJzgQT+FXkVRyrvILsvW+UlY="; + vendorHash = "sha256-dWwvxRCeY9eNqUYijpGWRE76ZQYbBgpgH96LzSn8jJ8="; src = ./.; From b07a7ffe3822366168224719f698ef37dcf7c11e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Fri, 29 Nov 2024 17:50:07 +0100 Subject: [PATCH 18/50] chore: rework default Dockerfile (#1165) #### What this PR does / why we need it uses make now to unify our build process to work exactly like we expect, everytime #### Which issue(s) this PR fixes follows up on https://github.com/open-component-model/ocm/pull/1163 as github went crazy due to me reverting to a previously detached commit --- .dockerignore | 2 ++ .github/workflows/components.yaml | 12 +++++++++ Dockerfile | 23 +++++++++-------- Makefile | 14 ++++++----- components/helminstaller/Makefile | 14 ++++++++--- components/ocmcli/Dockerfile | 23 ----------------- components/ocmcli/Makefile | 42 ++++++++++++++++--------------- 7 files changed, 68 insertions(+), 62 deletions(-) delete mode 100644 components/ocmcli/Dockerfile diff --git a/.dockerignore b/.dockerignore index ba8f5ffed7..fc54fb0a69 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,6 +22,7 @@ bin /hack /LICENSES /local +/gen /pkg/test* @@ -35,3 +36,4 @@ bin !go.* !**/*.go +!.git \ No newline at end of file diff --git a/.github/workflows/components.yaml b/.github/workflows/components.yaml index c519473c20..9cf04be0c3 100644 --- a/.github/workflows/components.yaml +++ b/.github/workflows/components.yaml @@ -33,6 +33,8 @@ env: components: '["ocmcli", "helminstaller", "helmdemo", "subchartsdemo", "ecrplugin"]' IMAGE_PLATFORMS: 'linux/amd64 linux/arm64' PLATFORMS: 'windows/amd64 darwin/arm64 darwin/amd64 linux/amd64 linux/arm64' + BUILDX_CACHE_PUSH: ${{ github.ref == 'refs/heads/main' }} + BUILDX_CACHE_REF_BASE: ghcr.io/${{ github.repository }}/buildx-cache jobs: define-matrix: @@ -66,6 +68,14 @@ jobs: with: go-version-file: '${{ github.workspace }}/go.mod' cache: false + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Docker Login + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Get go environment for use with cache run: | echo "go_cache=$(go env GOCACHE)" >> $GITHUB_ENV @@ -95,6 +105,8 @@ jobs: VERSION=${{ inputs.version }} \ PLATFORMS="${{ env.PLATFORMS }}" \ IMAGE_PLATFORMS="${{ env.IMAGE_PLATFORMS }}" \ + BUILDX_CACHE_REF=${{ env.BUILDX_CACHE_REF_BASE }}:${{ matrix.component }} \ + BUILDX_CACHE_PUSH=${{ env.BUILDX_CACHE_PUSH }} \ make \ ctf descriptor describe - name: Upload CTF diff --git a/Dockerfile b/Dockerfile index 1a8f590786..77c00ef102 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,25 +1,28 @@ -FROM golang:1.23-alpine3.20 AS build +FROM --platform=$BUILDPLATFORM golang:1.23-alpine3.20 AS build + +RUN apk add --no-cache make git WORKDIR /src -RUN go env -w GOMODCACHE=/root/.cache/go-build COPY go.mod go.sum *.go VERSION ./ ARG GO_PROXY="https://proxy.golang.org" ENV GOPROXY=${GO_PROXY} -RUN --mount=type=cache,target=/root/.cache/go-build go mod download +RUN go mod download COPY . . -RUN --mount=type=cache,target=/root/.cache/go-build \ - export VERSION=$(go run api/version/generate/release_generate.go print-rc-version) && \ - export NOW=$(date -u +%FT%T%z) && \ - go build -trimpath -ldflags \ - "-s -w -X ocm.software/ocm/api/version.gitVersion=$VERSION -X ocm.software/ocm/api/version.buildDate=$NOW" \ - -o /bin/ocm ./cmds/ocm/main.go + +ENV BUILD_FLAGS="-trimpath" + +# the GOARCH has not a default value to allow the binary be built according to the host where the command +# was called. For example, if we call make docker-build in a local env which has the Apple Silicon SO +# the docker BUILDPLATFORM arg will be linux/arm64 when for Apple x86 it will be linux/amd64. Therefore, +# by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. +RUN make bin/ocm GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} FROM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea -COPY --from=build /bin/ocm /usr/local/bin/ocm +COPY --from=build /src/bin/ocm /usr/local/bin/ocm # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless" diff --git a/Makefile b/Makefile index 726de3d3f2..87542905e6 100644 --- a/Makefile +++ b/Makefile @@ -26,12 +26,14 @@ SOURCES := $(shell go list -f '{{$$I:=.Dir}}{{range .GoFiles }}{{$$I}}/{{.}} {{e GOPATH := $(shell go env GOPATH) NOW := $(shell date -u +%FT%T%z) -BUILD_FLAGS := "-s -w \ +LD_FLAGS := "-s -w \ -X ocm.software/ocm/api/version.gitVersion=$(EFFECTIVE_VERSION) \ -X ocm.software/ocm/api/version.gitTreeState=$(GIT_TREE_STATE) \ -X ocm.software/ocm/api/version.gitCommit=$(COMMIT) \ -X ocm.software/ocm/api/version.buildDate=$(NOW)" CGO_ENABLED := 0 +GOOS := $(shell go env GOOS) +GOARCH := $(shell go env GOARCH) COMPONENTS ?= ocmcli helminstaller demoplugin ecrplugin helmdemo subchartsdemo @@ -42,19 +44,19 @@ bin: mkdir -p bin bin/ocm: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/ocm ./cmds/ocm + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ocm ./cmds/ocm bin/helminstaller: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/helminstaller ./cmds/helminstaller + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/helminstaller ./cmds/helminstaller bin/demo: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/demo ./cmds/demoplugin + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/demo ./cmds/demoplugin bin/cliplugin: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/cliplugin ./cmds/cliplugin + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/cliplugin ./cmds/cliplugin bin/ecrplugin: bin $(SOURCES) - CGO_ENABLED=$(CGO_ENABLED) go build -ldflags $(BUILD_FLAGS) -o bin/ecrplugin ./cmds/ecrplugin + CGO_ENABLED=$(CGO_ENABLED) GOOS=$(GOOS) GOARCH=$(GOARCH) go build $(BUILD_FLAGS) -ldflags $(LD_FLAGS) -o bin/ecrplugin ./cmds/ecrplugin api: $(SOURCES) go build ./api/... diff --git a/components/helminstaller/Makefile b/components/helminstaller/Makefile index e6c8d43b1c..9dafc4da79 100644 --- a/components/helminstaller/Makefile +++ b/components/helminstaller/Makefile @@ -23,6 +23,14 @@ PLATFORM := $(shell go env GOOS)/$(shell g CACHE_DIR := $(shell go env GOCACHE) MOD_CACHE_DIR := $(shell go env GOMODCACHE) + +ifneq ($(BUILDX_CACHE_REF),) + ADDITIONAL_BUILDX_ARGS += --cache-from type=registry,ref=$(BUILDX_CACHE_REF) + ifeq ($(BUILDX_CACHE_PUSH),true) + ADDITIONAL_BUILDX_ARGS += --cache-to type=registry,ref=$(BUILDX_CACHE_REF) + endif +endif + CREDS ?= # Define the path to the binary OCM_BIN = $(REPO_ROOT)/bin/ocm @@ -48,7 +56,7 @@ BUILD_FLAGS := "-s -w \ -X ocm.software/ocm/api/version.buildDate=$(NOW)" CMDSRCS=$(shell find $(REPO_ROOT)/cmds/$(NAME) -type f) -OCMSRCS=$(shell find $(REPO_ROOT)/pkg -type f) $(REPO_ROOT)/go.* +OCMSRCS=$(shell find $(REPO_ROOT)/api -type f) $(REPO_ROOT)/go.* ifeq ($(MULTI),true) FLAGSUF = .multi @@ -89,7 +97,7 @@ $(GEN)/image.$(NAME): $(GEN)/.exists Dockerfile $(CMDSRCS) $(OCMSRCS) --build-arg CACHE_DIR=$(CACHE_DIR) \ --build-arg MOD_CACHE_DIR=$(MOD_CACHE_DIR) \ --build-arg EFFECTIVE_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE); \ + --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE) $(ADDITIONAL_BUILDX_ARGS); \ @touch $(GEN)/image.$(NAME) push-image: @@ -108,7 +116,7 @@ $(GEN)/image.$(NAME).multi: $(GEN)/.exists Dockerfile $(CMDSRCS) $(OCMSRCS) --build-arg CACHE_DIR=$(CACHE_DIR) \ --build-arg MOD_CACHE_DIR=$(MOD_CACHE_DIR) \ --build-arg EFFECTIVE_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE); \ + --build-arg GIT_TREE_STATE=$(GIT_TREE_STATE) $(ADDITIONAL_BUILDX_ARGS); \ done @touch $(GEN)/image.$(NAME).multi diff --git a/components/ocmcli/Dockerfile b/components/ocmcli/Dockerfile deleted file mode 100644 index b17ec7e741..0000000000 --- a/components/ocmcli/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -# This Dockerfile is used by `make` via the Makefile - -FROM --platform=$BUILDPLATFORM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea - -ARG SUFFIX -ARG OCM_VERSION - -COPY gen/ocmcli/ocmcli.$SUFFIX /usr/local/bin/ocm - -# https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys -LABEL org.opencontainers.image.description="Open Component Model command line interface based on Distroless" -LABEL org.opencontainers.image.vendor="SAP SE" -LABEL org.opencontainers.image.licenses="Apache-2.0" -LABEL org.opencontainers.image.url="https://ocm.software/" -LABEL org.opencontainers.image.source="https://github.com/open-component-model/ocm" -LABEL org.opencontainers.image.title="ocm" -LABEL org.opencontainers.image.version="${OCM_VERSION}" -LABEL org.opencontainers.image.revision="${OCM_VERSION}" -LABEL org.opencontainers.image.documentation="https://github.com/open-component-model/ocm/blob/main/docs/reference/ocm.md" -LABEL org.opencontainers.image.base.name="gcr.io/distroless/static-debian12:nonroot" - -ENTRYPOINT ["/usr/local/bin/ocm"] -CMD ["version"] diff --git a/components/ocmcli/Makefile b/components/ocmcli/Makefile index 20915dab42..aa5174f443 100644 --- a/components/ocmcli/Makefile +++ b/components/ocmcli/Makefile @@ -31,6 +31,13 @@ ifeq ($(MULTI),true) FLAGSUF = .multi endif +ifneq ($(BUILDX_CACHE_REF),) + ADDITIONAL_BUILDX_ARGS += --cache-from type=registry,ref=$(BUILDX_CACHE_REF) + ifeq ($(BUILDX_CACHE_PUSH),true) + ADDITIONAL_BUILDX_ARGS += --cache-to type=registry,ref=$(BUILDX_CACHE_REF),mode=max + endif +endif + CREDS ?= # Define the path to the binary OCM_BIN = $(REPO_ROOT)/bin/ocm @@ -68,40 +75,35 @@ $(GEN)/build: $(GEN) $(GEN)/.exists $(CMDSRCS) $(OCMSRCS) @touch $(GEN)/build .PHONY: image -image: $(GEN)/image - -$(GEN)/image: $(GEN)/.exists Dockerfile $(GEN)/build +image: @PLATFORM_OS_OVERRIDE=$(PLATFORM_OS); \ if [ $$PLATFORM_OS_OVERRIDE == darwin ]; then \ echo; echo "Building linux instead of darwin as there's no native Docker platform for darwin"; echo; \ - docker buildx build -t $(IMAGE):$(VERSION) --platform linux/$(PLATFORM_ARCH) --file Dockerfile $(REPO_ROOT) \ - --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg SUFFIX=$$(echo linux/$(PLATFORM_ARCH) | sed -e s:/:-:g); \ + docker buildx build -t $(IMAGE):$(VERSION) --platform linux/$(PLATFORM_ARCH) --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ + --label org.opencontainers.image.version=$(VERSION) \ + --label org.opencontainers.image.revision=$(VERSION) $(ADDITIONAL_BUILDX_ARGS); \ else \ echo; echo "Building for $(PLATFORM_OS)/$(ARCH)"; echo; \ - docker buildx build -t $(IMAGE):$(VERSION) --platform $(PLATFORM_OS)/$(PLATFORM_ARCH) --file Dockerfile $(REPO_ROOT) \ - --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg SUFFIX=$$(echo $(PLATFORM_OS)/$(PLATFORM_ARCH) | sed -e s:/:-:g); \ + docker buildx build -t $(IMAGE):$(VERSION) --platform $(PLATFORM_OS)/$(PLATFORM_ARCH) --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ + --label org.opencontainers.image.version=$(VERSION) \ + --label org.opencontainers.image.revision=$(VERSION) $(ADDITIONAL_BUILDX_ARGS); \ fi - @touch $(GEN)/image .PHONY: image.multi -image.multi: $(GEN)/image.multi - -$(GEN)/image.multi: Dockerfile $(GEN)/build +image.multi: for i in $(IMAGE_PLATFORMS); do \ - tag=$$(echo $$i | sed -e s:/:-:g); \ - echo building platform $$i; \ - docker buildx build --load -t $(IMAGE):$(VERSION)-$$tag --platform $$i --file Dockerfile $(REPO_ROOT) \ - --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ - --build-arg SUFFIX=$$tag; \ + tag=$$(echo $$i | sed -e s:/:-:g); \ + echo building platform $$i; \ + docker buildx build --load -t $(IMAGE):$(VERSION)-$$tag --platform $$i --file $(REPO_ROOT)/Dockerfile $(REPO_ROOT) \ + --build-arg OCM_VERSION=$(EFFECTIVE_VERSION) \ + --label org.opencontainers.image.version=$(VERSION) \ + --label org.opencontainers.image.revision=$(VERSION) $(ADDITIONAL_BUILDX_ARGS); \ done - @touch $(GEN)/image.multi .PHONY: ctf ctf: $(GEN)/ctf -$(GEN)/ctf: $(OCM_BIN) $(GEN)/.exists $(GEN)/build $(GEN)/image$(FLAGSUF) component-constructor.yaml $(CHARTSRCS) Makefile +$(GEN)/ctf: $(OCM_BIN) $(GEN)/.exists $(GEN)/build image$(FLAGSUF) component-constructor.yaml $(CHARTSRCS) Makefile @rm -rf "$(GEN)/ctf" $(OCM) add componentversions \ --create \ From 29e4d93899b5052be2ac5779885aa122eaa44c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Fri, 29 Nov 2024 22:52:01 +0100 Subject: [PATCH 19/50] fix: allow cache push through PAT (#1166) #### What this PR does / why we need it temporarily disables the docker build cache because of token pass issues (while I locally didnt face any issues the docker login action doesnt seem to propagate correctly to the push) #### Which issue(s) this PR fixes This is to unblock main builds from failing, further investigation necessary --- .github/workflows/components.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/components.yaml b/.github/workflows/components.yaml index 9cf04be0c3..c6f8d53bde 100644 --- a/.github/workflows/components.yaml +++ b/.github/workflows/components.yaml @@ -33,7 +33,7 @@ env: components: '["ocmcli", "helminstaller", "helmdemo", "subchartsdemo", "ecrplugin"]' IMAGE_PLATFORMS: 'linux/amd64 linux/arm64' PLATFORMS: 'windows/amd64 darwin/arm64 darwin/amd64 linux/amd64 linux/arm64' - BUILDX_CACHE_PUSH: ${{ github.ref == 'refs/heads/main' }} + BUILDX_CACHE_PUSH: false BUILDX_CACHE_REF_BASE: ghcr.io/${{ github.repository }}/buildx-cache jobs: From 7ad855ba8c375d5c32e3fc1ac68f8152d4ab0ac9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 2 Dec 2024 09:14:26 +0100 Subject: [PATCH 20/50] chore(deps): bump distroless/static-debian12 from `d71f4b2` to `6cd937e` (#1169) Bumps distroless/static-debian12 from `d71f4b2` to `6cd937e`. [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=distroless/static-debian12&package-manager=docker&previous-version=nonroot&new-version=nonroot)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 77c00ef102..750585a3b6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -20,7 +20,7 @@ ENV BUILD_FLAGS="-trimpath" # by leaving it empty we can ensure that the container and binary shipped on it will have the same platform. RUN make bin/ocm GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH} -FROM gcr.io/distroless/static-debian12:nonroot@sha256:d71f4b239be2d412017b798a0a401c44c3049a3ca454838473a4c32ed076bfea +FROM gcr.io/distroless/static-debian12:nonroot@sha256:6cd937e9155bdfd805d1b94e037f9d6a899603306030936a3b11680af0c2ed58 COPY --from=build /src/bin/ocm /usr/local/bin/ocm From 28d51134bc8d37afbf4e066a03440e78f9fcaf25 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Dec 2024 13:30:40 +0100 Subject: [PATCH 21/50] chore(deps): bump the go group with 10 updates (#1177) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the go group with 10 updates: | Package | From | To | | --- | --- | --- | | [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.32.5` | `1.32.6` | | [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.28.5` | `1.28.6` | | [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.17.46` | `1.17.47` | | [github.com/aws/aws-sdk-go-v2/feature/s3/manager](https://github.com/aws/aws-sdk-go-v2) | `1.17.41` | `1.17.43` | | [github.com/aws/aws-sdk-go-v2/service/ecr](https://github.com/aws/aws-sdk-go-v2) | `1.36.6` | `1.36.7` | | [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.69.0` | `1.71.0` | | [github.com/mikefarah/yq/v4](https://github.com/mikefarah/yq) | `4.44.5` | `4.44.6` | | [golang.org/x/net](https://github.com/golang/net) | `0.31.0` | `0.32.0` | | [golang.org/x/text](https://github.com/golang/text) | `0.20.0` | `0.21.0` | | [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.19.2` | `0.19.3` | Updates `github.com/aws/aws-sdk-go-v2` from 1.32.5 to 1.32.6
Commits

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.28.5 to 1.28.6
Commits

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.17.46 to 1.17.47
Commits

Updates `github.com/aws/aws-sdk-go-v2/feature/s3/manager` from 1.17.41 to 1.17.43
Commits

Updates `github.com/aws/aws-sdk-go-v2/service/ecr` from 1.36.6 to 1.36.7
Commits

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.69.0 to 1.71.0
Commits

Updates `github.com/mikefarah/yq/v4` from 4.44.5 to 4.44.6
Release notes

Sourced from github.com/mikefarah/yq/v4's releases.

v4.44.6

Changelog

Sourced from github.com/mikefarah/yq/v4's changelog.

4.44.6:

Commits
  • 4839dbb Bumping version
  • 342efb2 Fixed panic on multipling string by very large number #2211
  • 2201381 Fixed multiply string by negative number panic #2211
  • 5273715 Fixed panic error #2211
  • e204677 Fixed no-colors regression #2218
  • f768159 Create docker image for armv7 / raspberry pi3
  • c16b180 Make sure to update the key when deleting array elements
  • 3bca3a2 Bump github.com/elliotchance/orderedmap from 1.6.0 to 1.7.0
  • 70bef5b Bump golang.org/x/net from 0.31.0 to 0.32.0
  • ea2ba18 Bump golang from 1.23.3 to 1.23.4
  • Additional commits viewable in compare view

Updates `golang.org/x/net` from 0.31.0 to 0.32.0
Commits
  • 285e1cf go.mod: update golang.org/x dependencies
  • d0a1049 route: remove unused sizeof* consts on freebsd
  • 6e41410 http2: fix benchmarks using common frame read/write functions
  • 4be1253 route: change from syscall to x/sys/unix
  • bc37675 http2: limit number of PINGs bundled with RST_STREAMs
  • e9cd716 route: fix parse of zero-length sockaddrs in RIBs
  • 9a51899 http2: add SETTINGS_ENABLE_CONNECT_PROTOCOL support
  • See full diff in compare view

Updates `golang.org/x/text` from 0.20.0 to 0.21.0
Commits

Updates `sigs.k8s.io/controller-runtime` from 0.19.2 to 0.19.3
Release notes

Sourced from sigs.k8s.io/controller-runtime's releases.

v0.19.3

What's Changed

Full Changelog: https://github.com/kubernetes-sigs/controller-runtime/compare/v0.19.2...v0.19.3

Commits
  • 3e66810 Merge pull request #3037 from kubernetes-sigs/backport019-watch
  • 2085acc add watch deprecated to certwatcher
  • 0823530 Merge pull request #3031 from k8s-infra-cherrypick-robot/cherry-pick-3028-to-...
  • e727239 [release-0.19] 🐛 Refactor certificate watcher to use polling, instead of fsno...
  • 2a0ce59 :seedling: Make using leader elector with client timeout non-breaking
  • 4bc3811 :bug: Fix RenewDeadline typo in leader election
  • 0170742 warning: Use leader elector with client timeout
  • See full diff in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 50 ++++++++++++++--------------- go.sum | 100 ++++++++++++++++++++++++++++----------------------------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/go.mod b/go.mod index ce8145cef0..f55dc0513e 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,12 @@ require ( github.com/DataDog/gostackparse v0.7.0 github.com/InfiniteLoopSpace/go_S-MIME v0.0.0-20181221134359-3f58f9a4b2b6 github.com/Masterminds/semver/v3 v3.3.1 - github.com/aws/aws-sdk-go-v2 v1.32.5 - github.com/aws/aws-sdk-go-v2/config v1.28.5 - github.com/aws/aws-sdk-go-v2/credentials v1.17.46 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 - github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 - github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 + github.com/aws/aws-sdk-go-v2 v1.32.6 + github.com/aws/aws-sdk-go-v2/config v1.28.6 + github.com/aws/aws-sdk-go-v2/credentials v1.17.47 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43 + github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 github.com/cloudflare/cfssl v1.6.5 github.com/containerd/containerd v1.7.24 github.com/containerd/errdefs v1.0.0 @@ -47,7 +47,7 @@ require ( github.com/mandelsoft/spiff v1.7.0-beta-6 github.com/mandelsoft/vfs v0.4.4 github.com/marstr/guid v1.1.0 - github.com/mikefarah/yq/v4 v4.44.5 + github.com/mikefarah/yq/v4 v4.44.6 github.com/mitchellh/copystructure v1.2.0 github.com/mittwald/go-helm-client v0.12.14 github.com/modern-go/reflect2 v1.0.2 @@ -70,9 +70,9 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 - golang.org/x/net v0.31.0 + golang.org/x/net v0.32.0 golang.org/x/oauth2 v0.24.0 - golang.org/x/text v0.20.0 + golang.org/x/text v0.21.0 gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.16.3 @@ -81,7 +81,7 @@ require ( k8s.io/apimachinery v0.31.3 k8s.io/cli-runtime v0.31.3 k8s.io/client-go v0.31.3 - sigs.k8s.io/controller-runtime v0.19.2 + sigs.k8s.io/controller-runtime v0.19.3 sigs.k8s.io/yaml v1.4.0 ) @@ -126,19 +126,19 @@ require ( github.com/aliyun/credentials-go v1.3.10 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect github.com/aws/smithy-go v1.22.1 // indirect github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20241009180534-e718692eec62 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -173,7 +173,7 @@ require ( github.com/docker/go-metrics v0.0.1 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/elliotchance/orderedmap v1.6.0 // indirect + github.com/elliotchance/orderedmap v1.7.0 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect @@ -338,11 +338,11 @@ require ( go.step.sm/crypto v0.54.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.29.0 // indirect + golang.org/x/crypto v0.30.0 // indirect golang.org/x/mod v0.22.0 // indirect - golang.org/x/sync v0.9.0 // indirect - golang.org/x/sys v0.27.0 // indirect - golang.org/x/term v0.26.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect golang.org/x/time v0.8.0 // indirect golang.org/x/tools v0.26.0 // indirect google.golang.org/api v0.206.0 // indirect diff --git a/go.sum b/go.sum index e6fda21192..a174b42f65 100644 --- a/go.sum +++ b/go.sum @@ -165,48 +165,48 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.32.5 h1:U8vdWJuY7ruAkzaOdD7guwJjD06YSKmnKCJs7s3IkIo= -github.com/aws/aws-sdk-go-v2 v1.32.5/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= +github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= -github.com/aws/aws-sdk-go-v2/config v1.28.5 h1:Za41twdCXbuyyWv9LndXxZZv3QhTG1DinqlFsSuvtI0= -github.com/aws/aws-sdk-go-v2/config v1.28.5/go.mod h1:4VsPbHP8JdcdUDmbTVgNL/8w9SqOkM5jyY8ljIxLO3o= -github.com/aws/aws-sdk-go-v2/credentials v1.17.46 h1:AU7RcriIo2lXjUfHFnFKYsLCwgbz1E7Mm95ieIRDNUg= -github.com/aws/aws-sdk-go-v2/credentials v1.17.46/go.mod h1:1FmYyLGL08KQXQ6mcTlifyFXfJVCNJTVGuQP4m0d/UA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20 h1:sDSXIrlsFSFJtWKLQS4PUWRvrT580rrnuLydJrCQ/yA= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.20/go.mod h1:WZ/c+w0ofps+/OUqMwWgnfrgzZH1DZO1RIkktICsqnY= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41 h1:hqcxMc2g/MwwnRMod9n6Bd+t+9Nf7d5qRg7RaXKPd6o= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.41/go.mod h1:d1eH0VrttvPmrCraU68LOyNdu26zFxQFjrVSb5vdhog= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24 h1:4usbeaes3yJnCFC7kfeyhkdkPtoRYPa/hTmCqMpKpLI= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.24/go.mod h1:5CI1JemjVwde8m2WG3cz23qHKPOxbpkq0HaoreEgLIY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24 h1:N1zsICrQglfzaBnrfM0Ys00860C+QFwu6u/5+LomP+o= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.24/go.mod h1:dCn9HbJ8+K31i8IQ8EWmWj0EiIk0+vKiHNMxTTYveAg= +github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= +github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw= +github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43 h1:iLdpkYZ4cXIQMO7ud+cqMWR1xK5ESbt1rvN77tRi1BY= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43/go.mod h1:OgbsKPAswXDd5kxnR4vZov69p3oYjbvUyIRBAAV0y9o= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6 h1:zg+3FGHA0PBs0KM25qE/rOf2o5zsjNa1g/Qq83+SDI0= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.6/go.mod h1:ZSq54Z9SIsOTf1Efwgw1msilSs4XVEfVQiP9nYVnKpM= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 h1:r67ps7oHCYnflpgDy2LZU0MAQtQbYIOqNNnqGO6xQkE= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25/go.mod h1:GrGY+Q4fIokYLtjCVB/aFfCVL6hhGUFl8inD18fDalE= +github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 h1:R+5XKIJga2K9Dkj0/iQ6fD/MBGo02oxGGFTc512lK/Q= +github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7/go.mod h1:fDPQV/6ONOQOjvtKhtypIy1wcGLcKYtoK/lvZ9fyDGQ= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2 h1:Zru9Iy2JPM5+uRnFnoqeOZzi8JIVIHJ0ua6JdeDHcyg= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2/go.mod h1:PtQC3XjutCYFCn1+i8+wtpDaXvEK+vXF2gyLIKAmh4A= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5 h1:wtpJ4zcwrSbwhECWQoI/g6WM9zqCcSpHDJIWSbMLOu4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.5/go.mod h1:qu/W9HXQbbQ4+1+JcZp0ZNPV31ym537ZJN+fiS7Ti8E= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 h1:HCpPsWqmYQieU7SS6E9HXfdAMSud0pteVXieJmcpIRI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6/go.mod h1:ngUiVRCco++u+soRRVBIvBZxSMMvOVMXA4PJ36JLfSw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 h1:BbGDtTi0T1DYlmjBiCr/le3wzhA37O8QTC5/Ab8+EXk= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6/go.mod h1:hLMJt7Q8ePgViKupeymbqI0la+t9/iYFBjxQCFwuAwI= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5 h1:5dQJ6Q5QrQOqZxXjSbRXukBqU8Pgu6Ro6Qqtyd8yiz4= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5/go.mod h1:A9vfQcNHVBCE7ZZN6H+UUJpXtbH26Vv6L7Zhk5nIJAY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ= -github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.6 h1:3zu537oLmsPfDMyjnUS2g+F2vITgy5pB74tHI+JBNoM= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.6/go.mod h1:WJSZH2ZvepM6t6jwu4w/Z45Eoi75lPN7DcydSRtJg6Y= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5 h1:K0OQAsDywb0ltlFrZm0JHPY3yZp/S9OaoLU33S7vPS8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.5/go.mod h1:ORITg+fyuMoeiQFiVGoqB3OydVTLkClw/ljbblMq6Cc= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.1 h1:6SZUVRQNvExYlMLbHdlKB48x0fLbc2iVROyaNEwBHbU= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.1/go.mod h1:GqWyYCwLXnlUB1lOAXQyNSPqPLQJvmo8J0DWBzp9mtg= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 h1:nyuzXooUNJexRT0Oy0UQY6AhOzxPxhtt4DcBIHyCnmw= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0/go.mod h1:sT/iQz8JK3u/5gZkT+Hmr7GzVZehUMkRZpOaAwYXeGY= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20241009180534-e718692eec62 h1:T5b8GwBFIlqQzAbqTNcyLvzcAvJ09MXrF6zyUlIic8A= @@ -365,8 +365,8 @@ github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/elliotchance/orderedmap v1.6.0 h1:xjn+kbbKXeDq6v9RVE+WYwRbYfAZKvlWfcJNxM8pvEw= -github.com/elliotchance/orderedmap v1.6.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys= +github.com/elliotchance/orderedmap v1.7.0 h1:FirjcM/NbcyudJhaIF9MG/RjIh5XHm2xb1SFquZ8k0g= +github.com/elliotchance/orderedmap v1.7.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/proto v1.12.1 h1:6n/Z2pZAnBwuhU66Gs8160B8rrrYKo7h2F2sCOnNceE= @@ -727,8 +727,8 @@ github.com/miekg/pkcs11 v1.0.2/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WT github.com/miekg/pkcs11 v1.0.3-0.20190429190417-a667d056470f/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/miekg/pkcs11 v1.1.1 h1:Ugu9pdy6vAYku5DEpVWVFPYnzV+bxB+iRdbuFSu7TvU= github.com/miekg/pkcs11 v1.1.1/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mikefarah/yq/v4 v4.44.5 h1:/Xm1dM1BfyDJMg+yIpnl2AgpmLFQg3Lcm/kuyYgHEXE= -github.com/mikefarah/yq/v4 v4.44.5/go.mod h1:rpn3xGVz+2pDuLJTlCvzatCwTmmUeHcm7MbkbtHdvkc= +github.com/mikefarah/yq/v4 v4.44.6 h1:yuu+sH3KX1R3pQCP/vsDao8uNcuiXcjvC7XtoekCV0g= +github.com/mikefarah/yq/v4 v4.44.6/go.mod h1:sva/xvSlW4mKRtRm9nwIS40A+LqNbl46ezjBHYyFtLo= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -1114,8 +1114,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.29.0 h1:L5SG1JTTXupVV3n6sUqMTeWbjAyfPwoda2DLX8J8FrQ= -golang.org/x/crypto v0.29.0/go.mod h1:+F4F4N5hv6v38hfeYwTdx20oUvLLc+QfrE9Ax9HtgRg= +golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= +golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= @@ -1159,8 +1159,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.31.0 h1:68CPQngjLL0r2AlUKiSxtQFKvzRVbnzLwMUn5SzcLHo= -golang.org/x/net v0.31.0/go.mod h1:P4fl1q7dY2hnZFxEk4pPSkDHF+QqjitcnDjUQyMM+pM= +golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= +golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -1175,8 +1175,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sync v0.9.0 h1:fEo0HyrW1GIgZdpbhCRO0PkJajUS5H9IFUztCgEo2jQ= -golang.org/x/sync v0.9.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1213,8 +1213,8 @@ golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.27.0 h1:wBqf8DvsY9Y/2P8gAfPDEYNuS30J4lPHJxXSb/nJZ+s= -golang.org/x/sys v0.27.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -1225,8 +1225,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.26.0 h1:WEQa6V3Gja/BhNxg540hBip/kkaYtRg3cxg4oXSw4AU= -golang.org/x/term v0.26.0/go.mod h1:Si5m1o57C5nBNQo5z1iq+XDijt21BDBDp2bK0QI8e3E= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1237,8 +1237,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.20.0 h1:gK/Kv2otX8gz+wn7Rmb3vT96ZwuoxnQlY+HlJVj7Qug= -golang.org/x/text v0.20.0/go.mod h1:D4IsuqiFMhST5bX19pQ9ikHC2GsaKyk/oF+pn3ducp4= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -1362,8 +1362,8 @@ k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk= oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8= -sigs.k8s.io/controller-runtime v0.19.2 h1:3sPrF58XQEPzbE8T81TN6selQIMGbtYwuaJ6eDssDF8= -sigs.k8s.io/controller-runtime v0.19.2/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4= +sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= +sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/kustomize/api v0.18.0 h1:hTzp67k+3NEVInwz5BHyzc9rGxIauoXferXyjv5lWPo= From 1ff88395dd375c60addc169784238193d55a7fd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 8 Dec 2024 12:44:51 +0000 Subject: [PATCH 22/50] chore(deps): bump github.com/fluxcd/cli-utils from 0.36.0-flux.9 to 0.36.0-flux.10 (#1178) Bumps [github.com/fluxcd/cli-utils](https://github.com/fluxcd/cli-utils) from 0.36.0-flux.9 to 0.36.0-flux.10.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/fluxcd/cli-utils&package-manager=go_modules&previous-version=0.36.0-flux.9&new-version=0.36.0-flux.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Hilmar Falkenberg --- go.mod | 8 ++++---- go.sum | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/go.mod b/go.mod index f55dc0513e..18aab08a27 100644 --- a/go.mod +++ b/go.mod @@ -26,7 +26,7 @@ require ( github.com/docker/docker v27.3.1+incompatible github.com/docker/go-connections v0.5.0 github.com/drone/envsubst v1.0.3 - github.com/fluxcd/cli-utils v0.36.0-flux.9 + github.com/fluxcd/cli-utils v0.36.0-flux.10 github.com/fluxcd/pkg/ssa v0.41.1 github.com/gertd/go-pluralize v0.2.1 github.com/ghodss/yaml v1.0.0 @@ -344,7 +344,7 @@ require ( golang.org/x/sys v0.28.0 // indirect golang.org/x/term v0.27.0 // indirect golang.org/x/time v0.8.0 // indirect - golang.org/x/tools v0.26.0 // indirect + golang.org/x/tools v0.27.0 // indirect google.golang.org/api v0.206.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect @@ -358,8 +358,8 @@ require ( k8s.io/component-base v0.31.3 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094 // indirect - k8s.io/kubectl v0.31.1 // indirect - k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 // indirect + k8s.io/kubectl v0.31.3 // indirect + k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 // indirect oras.land/oras-go v1.2.6 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/kustomize/api v0.18.0 // indirect diff --git a/go.sum b/go.sum index a174b42f65..5fb50c8b74 100644 --- a/go.sum +++ b/go.sum @@ -386,8 +386,8 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/cli-utils v0.36.0-flux.9 h1:RITKdwIAqT3EFKXl7B91mj6usVjxcy7W8PJZlxqUa84= -github.com/fluxcd/cli-utils v0.36.0-flux.9/go.mod h1:q6lXQpbAlrZmTB4Qe5oAENkv0y2kwMWcqTMDHrRo2Is= +github.com/fluxcd/cli-utils v0.36.0-flux.10 h1:kgoj1HP7KBFfIG9CHLFHpA2kCPNlfzCpbscCaAOSClE= +github.com/fluxcd/cli-utils v0.36.0-flux.10/go.mod h1:eWf+UVZmm51EmNmeGkdplVLVsFU4jETfCjoHZq7nUp4= github.com/fluxcd/pkg/ssa v0.41.1 h1:VW87zsLYAKUvCxJhuEH7VzxVh3SxaU+PyApCT6gKjTk= github.com/fluxcd/pkg/ssa v0.41.1/go.mod h1:7cbyLHqFd5FpcKvhxbHG3DkMm3cZteW45Mi78B0hg8g= github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= @@ -1256,8 +1256,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= -golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= +golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1356,10 +1356,10 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094 h1:MErs8YA0abvOqJ8gIupA1Tz6PKXYUw34XsGlA7uSL1k= k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094/go.mod h1:7ioBJr1A6igWjsR2fxq2EZ0mlMwYLejazSIc2bzMp2U= -k8s.io/kubectl v0.31.1 h1:ih4JQJHxsEggFqDJEHSOdJ69ZxZftgeZvYo7M/cpp24= -k8s.io/kubectl v0.31.1/go.mod h1:aNuQoR43W6MLAtXQ/Bu4GDmoHlbhHKuyD49lmTC8eJM= -k8s.io/utils v0.0.0-20240921022957-49e7df575cb6 h1:MDF6h2H/h4tbzmtIKTuctcwZmY0tY9mD9fNT47QO6HI= -k8s.io/utils v0.0.0-20240921022957-49e7df575cb6/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kubectl v0.31.3 h1:3r111pCjPsvnR98oLLxDMwAeM6OPGmPty6gSKaLTQes= +k8s.io/kubectl v0.31.3/go.mod h1:lhMECDCbJN8He12qcKqs2QfmVo9Pue30geovBVpH5fs= +k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= +k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk= oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8= sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= From c51453b21e14a315c9c10df1849011828ae14f23 Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Sun, 8 Dec 2024 13:54:27 +0100 Subject: [PATCH 23/50] fix: replace juju with rogpeppe go internal (#1176) #### What this PR does / why we need it Fixes https://github.com/open-component-model/ocm/issues/1174 #### Which issue(s) this PR fixes Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> --- api/utils/filelock/lock.go | 30 ++++++++++++++++-------------- go.mod | 2 +- go.sum | 2 -- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/api/utils/filelock/lock.go b/api/utils/filelock/lock.go index 4fe4ce641f..b015de5841 100644 --- a/api/utils/filelock/lock.go +++ b/api/utils/filelock/lock.go @@ -5,11 +5,10 @@ import ( "os" "sync" - "github.com/juju/fslock" "github.com/mandelsoft/filepath/pkg/filepath" - "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/vfs/pkg/osfs" "github.com/mandelsoft/vfs/pkg/vfs" + fslock "github.com/rogpeppe/go-internal/lockedfile" ) const DIRECTORY_LOCK = ".lock" @@ -25,19 +24,22 @@ const DIRECTORY_LOCK = ".lock" type Mutex struct { lock sync.Mutex path string - lockfile *fslock.Lock + lockfile *fslock.Mutex + unlock func() } func (m *Mutex) Lock() (io.Closer, error) { m.lock.Lock() if m.lockfile == nil { - m.lockfile = fslock.New(m.path) + m.lockfile = fslock.MutexAt(m.path) } - err := m.lockfile.Lock() + unlock, err := m.lockfile.Lock() if err != nil { m.lock.Unlock() return nil, err } + m.unlock = unlock + return &lock{mutex: m}, nil } @@ -46,16 +48,15 @@ func (m *Mutex) TryLock() (io.Closer, error) { return nil, nil } if m.lockfile == nil { - m.lockfile = fslock.New(m.path) + m.lockfile = fslock.MutexAt(m.path) } - err := m.lockfile.TryLock() + unlock, err := m.lockfile.Lock() if err != nil { m.lock.Unlock() - if errors.Is(err, fslock.ErrLocked) { - err = nil - } return nil, err } + m.unlock = unlock + return &lock{mutex: m}, nil } @@ -75,14 +76,15 @@ func (l *lock) Close() error { if l.mutex == nil { return os.ErrClosed } - l.mutex.lockfile.Unlock() + + l.mutex.unlock() l.mutex.lock.Unlock() l.mutex = nil return nil } var ( - _filelocks = map[string]*Mutex{} + _fileLocks = map[string]*Mutex{} _lock sync.Mutex ) @@ -121,12 +123,12 @@ func MutexFor(path string) (*Mutex, error) { _lock.Lock() defer _lock.Unlock() - mutex := _filelocks[file] + mutex := _fileLocks[file] if mutex == nil { mutex = &Mutex{ path: file, } - _filelocks[file] = mutex + _fileLocks[file] = mutex } return mutex, nil } diff --git a/go.mod b/go.mod index 18aab08a27..296f46db76 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,6 @@ require ( github.com/golang/mock v1.6.0 github.com/google/go-github/v45 v45.2.0 github.com/hashicorp/vault-client-go v0.4.3 - github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b github.com/klauspost/compress v1.17.11 github.com/klauspost/pgzip v1.2.6 github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 @@ -57,6 +56,7 @@ require ( github.com/opencontainers/image-spec v1.1.0 github.com/pkg/errors v0.9.1 github.com/redis/go-redis/v9 v9.7.0 + github.com/rogpeppe/go-internal v1.13.1 github.com/sigstore/cosign/v2 v2.4.1 github.com/sigstore/rekor v1.3.7 github.com/sigstore/sigstore v1.8.10 diff --git a/go.sum b/go.sum index 5fb50c8b74..078bbf32c3 100644 --- a/go.sum +++ b/go.sum @@ -657,8 +657,6 @@ github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b h1:FQ7+9fxhyp82ks9vAuyPzG0/vVbWwMwLJ+P6yJI5FN8= -github.com/juju/fslock v0.0.0-20160525022230-4d5c94c67b4b/go.mod h1:HMcgvsgd0Fjj4XXDkbjdmlbI505rUPBs6WBMYg2pXks= github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= From 1032698bcfe12f55cb54faeafbf6f6778ff7129f Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Mon, 9 Dec 2024 08:54:15 +0100 Subject: [PATCH 24/50] chore: update 'flake.nix' (#1179) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 77c0e3bf98..d2f84b025d 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-dWwvxRCeY9eNqUYijpGWRE76ZQYbBgpgH96LzSn8jJ8="; + vendorHash = "sha256-GgQt8YaOGaC7BjkrRQ8HzorqvY63vy4OWMEyvKHbfMs="; src = ./.; From e290d0131ff9b8f6e5c066b19e724861632f181f Mon Sep 17 00:00:00 2001 From: Gerald Morrison <67469729+morri-son@users.noreply.github.com> Date: Wed, 11 Dec 2024 12:22:12 +0100 Subject: [PATCH 25/50] fix: correct link and add notice file (#1185) #### What this PR does / why we need it correct link and add notice file --- CONTRIBUTING.md | 2 +- NOTICE | 18 ++++++++++++++++++ README.md | 3 +-- 3 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 NOTICE diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4eed9f1ae4..080a1f7920 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -2,4 +2,4 @@ We welcome many different types of contributions. -Please refer to the [Contributing Guide in the Community repository](https://github.com/open-component-model/community/blob/main/CONTRIBUTING.md) for more information on how to get support from maintainers, find work to contribute, the Pull Request checklist, the Pull Request process, and other useful information on how to contribute to OCM. +Please refer to the [Contributing Guide in the Community repository](https://github.com/open-component-model/.github/blob/main/CONTRIBUTING.md) for more information on how to get support from maintainers, find work to contribute, the Pull Request checklist, the Pull Request process, and other useful information on how to contribute to OCM. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000000..d7051158e6 --- /dev/null +++ b/NOTICE @@ -0,0 +1,18 @@ +# THIRD-PARTY LIBRARIES + +## MPL-2.0 + +This project statically links the following [Mozilla Public License 2.0 (MPL-2.0)](https://www.mozilla.org/en-US/MPL/2.0/) libraries. +The list contains the Go module path and the version of the library used. + +- github.com/hashicorp/errwrap-v1.1.0 +- github.com/hashicorp/go-cleanhttp-v0.5.2 +- github.com/hashicorp/go-multierror-v1.1.1 +- github.com/hashicorp/go-retryablehttp-v0.7.7 +- github.com/hashicorp/go-rootcerts-v1.0.2 +- github.com/hashicorp/go-secure-stdlib/strutil-configutil/v0.1.5 +- github.com/hashicorp/hcl-v1.0.1-vault-5 +- github.com/hashicorp/vault-client-go-v0.4.3 +- github.com/letsencrypt/boulder-v0.0.0-20241010192615-6692160cedfa + +Modifications to original MPL-2.0 files will be documented and made available. diff --git a/README.md b/README.md index d0025805a8..1dcc523f01 100644 --- a/README.md +++ b/README.md @@ -53,10 +53,9 @@ Install the latest release with - [Homebrew](#homebrew) - [NixOS](#nixos) - [AUR](#aur) -- [Container](#container) +- [Docker and Podman](#container) - [Chocolatey](#chocolatey) - [Winget](#winget) -- [GitHub Releases](https://github.com/open-component-model/ocm/releases/latest) ### Bash From 34064e75ca21933d70bb6fff3ec07aa49d4c1808 Mon Sep 17 00:00:00 2001 From: Fabian Burth Date: Fri, 13 Dec 2024 08:56:04 +0100 Subject: [PATCH 26/50] fix: ocm transfer ignored --enforce when --overwrite is set (#1187) #### What this PR does / why we need it Fixes a bug in the `ocm transfer` command, that caused the `--enforce` option to be ignored if `--overwrite` was set. #### Which issue(s) this PR fixes #1186 --- .../ocmcmds/common/options/overwriteoption/option.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/cmds/ocm/commands/ocmcmds/common/options/overwriteoption/option.go b/cmds/ocm/commands/ocmcmds/common/options/overwriteoption/option.go index 6cc4c32988..2073280614 100644 --- a/cmds/ocm/commands/ocmcmds/common/options/overwriteoption/option.go +++ b/cmds/ocm/commands/ocmcmds/common/options/overwriteoption/option.go @@ -50,10 +50,14 @@ versions are re-transported). func (o *Option) ApplyTransferOption(opts transferhandler.TransferOptions) error { if (o.overwrite != nil && o.overwrite.Changed) || o.Overwrite { - return standard.Overwrite(o.Overwrite).ApplyTransferOption(opts) + if err := standard.Overwrite(o.Overwrite).ApplyTransferOption(opts); err != nil { + return err + } } if (o.enforce != nil && o.enforce.Changed) || o.EnforceTransport { - return standard.EnforceTransport(o.EnforceTransport).ApplyTransferOption(opts) + if err := standard.EnforceTransport(o.EnforceTransport).ApplyTransferOption(opts); err != nil { + return err + } } return nil } From 2e9fab32cd3e414eca725031459751976a373a75 Mon Sep 17 00:00:00 2001 From: Fabian Burth Date: Fri, 13 Dec 2024 12:12:23 +0100 Subject: [PATCH 27/50] docs: adjust flags to options in cobra help and usage template (#1188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What this PR does / why we need it Renames the `Flags` section in `--help` to `Options`. The `Synopsis` currently shows `ocm [] ...`, with referring to the command line options listed under `Flags`. This might confuse users (or at least concern if something does not work). **Before:** ``` > ocm get component --help ocm get componentversions — Get Component Version Synopsis: ocm get componentversions [] {} Aliases: componentversions, componentversion, cv, components, component, comps, comp, c Flags: -c, --constraints constraints version constraint -h, --help help for componentversions --latest restrict component versions to latest --lookup stringArray repository name or spec for closure lookup fallback -o, --output string output mode (JSON, json, tree, wide, yaml) -r, --recursive follow component reference nesting --repo string repository name or spec -S, --scheme string schema version -s, --sort stringArray sort fields ``` **Now:** ``` > ocm get component --help ocm get componentversions — Get Component Version Synopsis: ocm get componentversions [] {} Aliases: componentversions, componentversion, cv, components, component, comps, comp, c Options: -c, --constraints constraints version constraint -h, --help help for componentversions --latest restrict component versions to latest --lookup stringArray repository name or spec for closure lookup fallback -o, --output string output mode (JSON, json, tree, wide, yaml) -r, --recursive follow component reference nesting --repo string repository name or spec -S, --scheme string schema version -s, --sort stringArray sort fields ``` #### Which issue(s) this PR fixes #1189 --- api/utils/cobrautils/template.go | 8 ++++---- cmds/cliplugin/cmds/cmd_test.go | 4 ++-- cmds/subcmdplugin/cmds/cmd_test.go | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/api/utils/cobrautils/template.go b/api/utils/cobrautils/template.go index 76e12ea251..76f73ab569 100644 --- a/api/utils/cobrautils/template.go +++ b/api/utils/cobrautils/template.go @@ -12,10 +12,10 @@ Aliases: Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if and .HasAvailableLocalFlags .IsAvailableCommand}} -Flags: +Options: {{ flagUsages .LocalFlags | trimTrailingWhitespaces}}{{end}}{{if and .HasAvailableInheritedFlags .IsAvailableCommand}} -Global Flags: +Global Options: {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}} Description: @@ -44,10 +44,10 @@ Examples: Available Commands:{{range .Commands}}{{if (or .IsAvailableCommand (eq .Name "help"))}} {{rpad .Name .NamePadding }} {{.Short}}{{end}}{{end}}{{end}}{{if .HasAvailableLocalFlags}} -Flags: +Options: {{ flagUsages .LocalFlags | trimTrailingWhitespaces}}{{end}}{{if .HasAvailableInheritedFlags}} -Global Flags: +Global Options: {{.InheritedFlags.FlagUsages | trimTrailingWhitespaces}}{{end}}{{if .HasHelpSubCommands}} Additional help topics:{{range .Commands}}{{if .IsAdditionalHelpTopicCommand}} diff --git a/cmds/cliplugin/cmds/cmd_test.go b/cmds/cliplugin/cmds/cmd_test.go index 50671fa3e6..6c374be6b1 100644 --- a/cmds/cliplugin/cmds/cmd_test.go +++ b/cmds/cliplugin/cmds/cmd_test.go @@ -86,7 +86,7 @@ ocm check rhubarb — Determine Whether We Are In Rhubarb Season Synopsis: ocm check rhubarb -Flags: +Options: -d, --date string the date to ask for (MM/DD) -h, --help help for check @@ -106,7 +106,7 @@ ocm check rhubarb — Determine Whether We Are In Rhubarb Season Synopsis: ocm check rhubarb -Flags: +Options: -d, --date string the date to ask for (MM/DD) -h, --help help for check diff --git a/cmds/subcmdplugin/cmds/cmd_test.go b/cmds/subcmdplugin/cmds/cmd_test.go index 240349caa6..be338733e9 100644 --- a/cmds/subcmdplugin/cmds/cmd_test.go +++ b/cmds/subcmdplugin/cmds/cmd_test.go @@ -64,7 +64,7 @@ Synopsis: Available Commands: demo a demo command -Flags: +Options: -h, --help help for group Description: @@ -83,7 +83,7 @@ ocm group demo — A Demo Command Synopsis: ocm group demo [flags] -Flags: +Options: -h, --help help for demo --version string some overloaded option @@ -107,7 +107,7 @@ Synopsis: Available Commands: demo a demo command -Flags: +Options: -h, --help help for group Description: @@ -126,7 +126,7 @@ ocm group demo — A Demo Command Synopsis: ocm group demo [flags] -Flags: +Options: -h, --help help for demo --version string some overloaded option From 12fe6422aa10695552565873cbeac47c4b23f209 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 08:30:14 +0100 Subject: [PATCH 28/50] chore(deps): bump anchore/sbom-action from 0.17.8 to 0.17.9 in the ci group (#1192) Bumps the ci group with 1 update: [anchore/sbom-action](https://github.com/anchore/sbom-action). Updates `anchore/sbom-action` from 0.17.8 to 0.17.9
Release notes

Sourced from anchore/sbom-action's releases.

v0.17.9

Changes in v0.17.9

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=anchore/sbom-action&package-manager=github_actions&previous-version=0.17.8&new-version=0.17.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index b6034f388a..676abd177e 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -122,7 +122,7 @@ jobs: token: ${{ steps.generate_token.outputs.token }} - name: Setup Syft - uses: anchore/sbom-action/download-syft@55dc4ee22412511ee8c3142cbea40418e6cec693 # v0.17.8 + uses: anchore/sbom-action/download-syft@df80a981bc6edbc4e220a492d3cbe9f5547a6e75 # v0.17.9 - name: Setup Cosign uses: sigstore/cosign-installer@v3.7.0 From 91ee457082b1ac07dfc302b2a8fe6495a6cee7e8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 07:44:43 +0000 Subject: [PATCH 29/50] chore(deps): bump the go group with 11 updates (#1190) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the go group with 11 updates: | Package | From | To | | --- | --- | --- | | [github.com/docker/cli](https://github.com/docker/cli) | `27.3.1+incompatible` | `27.4.0+incompatible` | | [github.com/docker/docker](https://github.com/docker/docker) | `27.3.1+incompatible` | `27.4.0+incompatible` | | [github.com/fluxcd/pkg/ssa](https://github.com/fluxcd/pkg) | `0.41.1` | `0.43.0` | | [github.com/mittwald/go-helm-client](https://github.com/mittwald/go-helm-client) | `0.12.14` | `0.12.15` | | [github.com/onsi/gomega](https://github.com/onsi/gomega) | `1.36.0` | `1.36.1` | | [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore) | `1.8.10` | `1.8.11` | | [k8s.io/api](https://github.com/kubernetes/api) | `0.31.3` | `0.32.0` | | [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) | `0.31.3` | `0.32.0` | | [k8s.io/apimachinery](https://github.com/kubernetes/apimachinery) | `0.31.3` | `0.32.0` | | [k8s.io/cli-runtime](https://github.com/kubernetes/cli-runtime) | `0.31.3` | `0.32.0` | | [k8s.io/client-go](https://github.com/kubernetes/client-go) | `0.31.3` | `0.32.0` | Updates `github.com/docker/cli` from 27.3.1+incompatible to 27.4.0+incompatible
Commits
  • bde2b89 Merge pull request #5669 from thaJeztah/27.x_update_go_1.22.10
  • 3284a80 update to go1.22.10
  • b7064a2 Merge pull request #5661 from thaJeztah/27.x_backport_remove_repoinfo_class
  • 67b6fe0 Merge pull request #5649 from thaJeztah/27.x_update_engine
  • 5a0508c cli/trust: GetNotaryRepository: remove uses of RepositoryInfo.Class
  • 9348385 vendor: github.com/docker/docker v27.4.0-rc.3
  • 9ea09fd Merge pull request #5652 from vvoland/5651-27.x
  • 0c9e0b4 Merge pull request #5658 from thaJeztah/27.x_backport_docs-fix-screwy-dockerd...
  • f4fec76 docs: fix janky rendering of toc on docs.docker.com
  • 6fd4825 Merge pull request #5654 from Benehiko/fix-run-ctx-27.x
  • Additional commits viewable in compare view

Updates `github.com/docker/docker` from 27.3.1+incompatible to 27.4.0+incompatible
Release notes

Sourced from github.com/docker/docker's releases.

v27.4.0

27.4.0

For a full list of pull requests and changes in this release, refer to the relevant GitHub milestones:

API

  • GET /images/json with the manifests option enabled now preserves the original order in which manifests appeared in the manifest-index. moby/moby#48712

Bug fixes and enhancements

  • When reading logs with the jsonfile or local log drivers, any errors while trying to read or parse underlying log files will cause the rest of the file to be skipped and move to the next log file (if one exists) rather than returning an error to the client and closing the stream. The errors are viewable in the Docker Daemon logs and exported to traces when tracing is configured. moby/moby#48842
  • When reading log files, compressed log files are now only decompressed when needed rather than decompressing all files before starting the log stream. moby/moby#48842
  • Fix an issue that meant published ports from one container on a bridge network were not accessible from another container on the same network with userland-proxy disabled, if the kernel's br_netfilter module was not loaded and enabled. The daemon will now attempt to load the module and enable bridge-nf-call-iptables or bridge-nf-call-ip6tables when creating a network with the userland proxy disabled. moby/moby#48685
  • Fix loading of bridge and br_netfilter kernel modules. moby/moby#48966
  • containerd image store: Fix Docker daemon failing to fully start with a "context deadline exceeded error" with containerd snapshotter and many builds/images. moby/moby#48954
  • containerd image-store: Fix partially pulled images not being garbage-collected. moby#48910, moby/moby#48957
  • containerd image store: Fix docker image inspect outputting duplicate references in RepoDigests. moby/moby#48785
  • containerd image store: Fix not being able to connect to some insecure registries in cases where the HTTPS request failed due to a non-TLS related error. moby/moby#48758
  • containerd image store: Remove a confusing warning log when tagging a non-dangling image. moby/moby#49010
  • dockerd-rootless-setuptool.sh: let --force ignore smoke test errors moby/moby#48695
  • Disable IPv6 Duplicate Address Detection (DAD) for addresses assigned to the bridges belonging to bridge networks. moby/moby#48684
  • Remove BuildKit init timeout. moby/moby#48963
  • Ignore "dataset does not exist" error when removing dataset on ZFS. moby/moby#48968
  • Client: Prevent idle connections leaking FDs. moby/moby#48764
  • Fix anonymous volumes being created through the --mount option not being marked as anonymous. moby/moby#48755
  • After a daemon restart with live-restore, ensure an iptables jump to the DOCKER-USER chain is placed before other rules. moby/moby#48714
  • Fix a possible memory leak caused by OTel meters. moby/moby#48693
  • Create distinct build history db for each store. moby/moby#48688
  • Fix an issue that caused excessive memory usage when DNS resolution was made in a tight loop. moby/moby#48840
  • containerd image store: Do not underline names in docker image ls --tree. docker/cli#5519
  • containerd image store: Change name of USED column in docker image ls --tree to IN USE. docker/cli#5518
  • Fix a bug preventing image pulls from being cancelled during docker run. docker/cli#5654
  • Port some completions from the bash completion to the new cobra based completion. docker/cli#5618
  • The docker login and docker logout command no longer update the configuration file if the credentials didn't change. docker/cli#5569
  • Optimise docker stats to reduce flickering issues. docker/cli#5588, docker/cli#5635
  • Fix inaccessible plugins paths preventing plugins from being detected. docker/cli#5652
  • Add support for events --filter in cobra generated shell completions. docker/cli#5614
  • Fix bash completion for events --filter daemon=. docker/cli#5563
  • Improve shell-completion of containers for docker rm. docker/cli#5540
  • Add shell-completion for --platform flags. docker/cli#5540
  • rootless: Make /etc/cdi and /var/run/cdi accessible by the Container Device Interface (CDI) integration. moby/moby#49027

Removed

  • Deprecate Daemon.Exists() and Daemon.IsPaused(). These functions are no longer used and will be removed in the next release. moby/moby#48719
  • Deprecate container.ErrNameReserved and container.ErrNameNotReserved. moby/moby#48697

... (truncated)

Commits
  • 92a8393 Merge pull request #49027 from thaJeztah/27.x_backport_cdi-rootless
  • 9163aa3 Merge pull request #49026 from thaJeztah/27.x_update_go_1.22.10
  • 4775621 Dockerd rootless: make {/etc,/var/run}/cdi available
  • 0176f4a Merge pull request #49024 from thaJeztah/27.x_vendor_buildkit_0.17.3
  • 0e34b39 update to go1.22.10
  • 7919b80 [27.x] vendor: github.com/moby/buildkit v0.17.3
  • a92d4c5 Merge pull request #49013 from vvoland/49006-27.x
  • 1cc1274 Merge pull request #49010 from vvoland/49009-27.x
  • 525b929 registry: deprecate RepositoryInfo.Class
  • d6d43b2 c8d/tag: Don't log a warning if the source image is not dangling
  • Additional commits viewable in compare view

Updates `github.com/fluxcd/pkg/ssa` from 0.41.1 to 0.43.0
Commits
  • 42918b3 Merge pull request #843 from fluxcd/deps-int-k8s-1.32
  • ad9c74a Update internal dependencies
  • b9b6a10 Merge pull request #842 from fluxcd/k8s-1.32.0
  • 7b6cd90 Update dependencies to Kubernetes 1.32.0 and Go 1.23.0
  • b9c338a Merge pull request #841 from fluxcd/load-vars
  • cf1915e Make the variables loading function public
  • 84013d4 Merge pull request #839 from fluxcd/workflow-tf-setup
  • b91dc11 workflows: Use setup-terraform install latest
  • 5bf9095 Merge pull request #838 from fluxcd/meta-v1.8.0
  • 05a2b81 Update apis/meta version in chartutil and runtime
  • Additional commits viewable in compare view

Updates `github.com/mittwald/go-helm-client` from 0.12.14 to 0.12.15
Release notes

Sourced from github.com/mittwald/go-helm-client's releases.

v0.12.15

What's Changed

New Contributors

Full Changelog: https://github.com/mittwald/go-helm-client/compare/v0.12.14...v0.12.15

Commits
  • 7b0ba54 Merge pull request #223 from fmontorsi-equinix/patch-1
  • bf69d23 Merge branch 'master' into patch-1
  • ff2969f Update client_test.go
  • 08a142e Merge pull request #221 from pberton/patch-1
  • 4b9c72c Merge branch 'master' into patch-1
  • c71ccfd Merge pull request #220 from tariq1890/bump-helm-gomock
  • 5e61ccb Show in docs the ChartSpec.Timeout
  • 3cc53a9 Update client.go
  • 1d8c4fc bump helm and gomock deps to the latest releases
  • See full diff in compare view

Updates `github.com/onsi/gomega` from 1.36.0 to 1.36.1
Release notes

Sourced from github.com/onsi/gomega's releases.

v1.36.1

1.36.1

Fixes

Changelog

Sourced from github.com/onsi/gomega's changelog.

1.36.1

Fixes

Commits

Updates `github.com/sigstore/sigstore` from 1.8.10 to 1.8.11
Release notes

Sourced from github.com/sigstore/sigstore's releases.

v1.8.11

What's Changed

New Contributors

Full Changelog: https://github.com/sigstore/sigstore/compare/v1.8.10...v1.8.11

Commits
  • 185deaa build(deps): Bump golang.org/x/crypto from 0.29.0 to 0.31.0 (#1903)
  • 7df71a7 build(deps): Bump cloud.google.com/go/kms (#1902)
  • f5270c4 build(deps): Bump golang.org/x/crypto in /pkg/signature/kms/azure (#1905)
  • 9bd2049 build(deps): Bump google.golang.org/api in /pkg/signature/kms/gcp (#1906)
  • 4e58ea1 build(deps): Bump actions/cache from 4.1.2 to 4.2.0 in the all group (#1907)
  • 7addd3b build(deps): Bump localstack/localstack in /test/e2e in the all group (#1899)
  • cbdd139 build(deps): Bump the gomod group across 1 directory with 3 updates (#1900)
  • 8041744 build(deps): Bump github.com/stretchr/testify in /pkg/signature/kms/aws (#1893)
  • d66b91a build(deps): Bump google.golang.org/api in /pkg/signature/kms/gcp (#1894)
  • fa4a76d build(deps): Bump github.com/stretchr/testify (#1895)
  • Additional commits viewable in compare view

Updates `k8s.io/api` from 0.31.3 to 0.32.0
Commits
  • e622342 Update dependencies to v0.32.0 tag
  • b0543a3 Merge remote-tracking branch 'origin/master' into release-1.32
  • f6bae9a Drop use of winreadlinkvolume godebug option
  • ea815d5 Merge remote-tracking branch 'origin/master' into release-1.32
  • c331a79 Revert to go1.22 windows filesystem stdlib behavior
  • f8e5e36 Merge pull request #128407 from ndixita/pod-level-resources
  • 84e0db8 Merge pull request #127857 from Jefftree/cle-v1alpha2
  • cbaf5a0 Merge pull request #128686 from thockin/take_over_pr-125233
  • a503a4f Merge pull request #128687 from tallclair/allocated-status
  • 3f43b5a Merge pull request #128240 from LionelJouin/KEP-4817
  • Additional commits viewable in compare view

Updates `k8s.io/apiextensions-apiserver` from 0.31.3 to 0.32.0
Commits
  • 7215469 Update dependencies to v0.32.0 tag
  • 887679f Merge remote-tracking branch 'origin/master' into release-1.32
  • bd027a4 Drop use of winreadlinkvolume godebug option
  • 919f42b Merge remote-tracking branch 'origin/master' into release-1.32
  • a4e1034 Revert to go1.22 windows filesystem stdlib behavior
  • 89d6021 Run codegen
  • 2a91f8a Merge pull request #127513 from tkashem/delete-undecryptable
  • 06dc95a api: run codegen
  • 19f7123 Merge pull request #128639 from jpbetz/fix-cost-test
  • 66631b6 Fix flake in CEL cost stability tests
  • Additional commits viewable in compare view

Updates `k8s.io/apimachinery` from 0.31.3 to 0.32.0
Commits
  • 59e9003 Merge remote-tracking branch 'origin/master' into release-1.32
  • 639247c Drop use of winreadlinkvolume godebug option
  • 220d7c3 Merge remote-tracking branch 'origin/master' into release-1.32
  • c199d3b Revert to go1.22 windows filesystem stdlib behavior
  • 16af2ff implement unsafe deletion, and wire it
  • 6ff8305 api: run codegen
  • ca9b8b2 api: add a new field to meta/v1 DeleteOptions
  • d941d9f Merge pull request #128503 from benluddy/cbor-codecs-featuregate
  • 3b4250f Wire serving codecs to CBOR feature gate.
  • daaad09 Merge pull request #128501 from benluddy/watch-cbor-seq
  • Additional commits viewable in compare view

Updates `k8s.io/cli-runtime` from 0.31.3 to 0.32.0
Commits
  • 49dbc54 Update dependencies to v0.32.0 tag
  • f8c45be Merge remote-tracking branch 'origin/master' into release-1.32
  • f750fa0 Drop use of winreadlinkvolume godebug option
  • 9da77ec Merge remote-tracking branch 'origin/master' into release-1.32
  • 15e0912 Revert to go1.22 windows filesystem stdlib behavior
  • 3a2a8b4 hack/pin-dependency.sh k8s.io/kube-openapi 32ad38e42d3faf1ce94eb29f4ea6d76333...
  • 8ceafc0 Merge pull request #128396 from ritazh/deprecate-EnforceMountableSecretsAnnot...
  • f78772d deprecate EnforceMountableSecretsAnnotation in 1.32
  • 44c3029 Merge pull request #128507 from dims/use-k8s.io/utils/lru-instead-of-github.c...
  • 16fbedb Use k8s.io/utils/lru instead of github.com/golang/groupcache/lru
  • Additional commits viewable in compare view

Updates `k8s.io/client-go` from 0.31.3 to 0.32.0
Commits
  • 0d55461 Update dependencies to v0.32.0 tag
  • 4765ade Merge remote-tracking branch 'origin/master' into release-1.32
  • 692a511 Drop use of winreadlinkvolume godebug option
  • 9df5099 Merge remote-tracking branch 'origin/master' into release-1.32
  • 120beb2 Revert to go1.22 windows filesystem stdlib behavior
  • 55d23e2 Align fake client-go clients with the main interface
  • 646e79b Run codegen
  • c475fe0 Generify fake clientsets
  • 955401c Merge pull request #128407 from ndixita/pod-level-resources
  • eddb107 Merge pull request #127857 from Jefftree/cle-v1alpha2
  • Additional commits viewable in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 41 ++++++++++++++--------------- go.sum | 82 ++++++++++++++++++++++++++++------------------------------ 2 files changed, 60 insertions(+), 63 deletions(-) diff --git a/go.mod b/go.mod index 296f46db76..8c3a1bf220 100644 --- a/go.mod +++ b/go.mod @@ -22,12 +22,12 @@ require ( github.com/containers/image/v5 v5.33.0 github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f github.com/distribution/reference v0.6.0 - github.com/docker/cli v27.3.1+incompatible - github.com/docker/docker v27.3.1+incompatible + github.com/docker/cli v27.4.0+incompatible + github.com/docker/docker v27.4.0+incompatible github.com/docker/go-connections v0.5.0 github.com/drone/envsubst v1.0.3 - github.com/fluxcd/cli-utils v0.36.0-flux.10 - github.com/fluxcd/pkg/ssa v0.41.1 + github.com/fluxcd/cli-utils v0.36.0-flux.11 + github.com/fluxcd/pkg/ssa v0.43.0 github.com/gertd/go-pluralize v0.2.1 github.com/ghodss/yaml v1.0.0 github.com/go-logr/logr v1.4.2 @@ -48,10 +48,10 @@ require ( github.com/marstr/guid v1.1.0 github.com/mikefarah/yq/v4 v4.44.6 github.com/mitchellh/copystructure v1.2.0 - github.com/mittwald/go-helm-client v0.12.14 + github.com/mittwald/go-helm-client v0.12.15 github.com/modern-go/reflect2 v1.0.2 github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.36.0 + github.com/onsi/gomega v1.36.1 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/pkg/errors v0.9.1 @@ -59,7 +59,7 @@ require ( github.com/rogpeppe/go-internal v1.13.1 github.com/sigstore/cosign/v2 v2.4.1 github.com/sigstore/rekor v1.3.7 - github.com/sigstore/sigstore v1.8.10 + github.com/sigstore/sigstore v1.8.11 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.1 github.com/spf13/pflag v1.0.5 @@ -76,11 +76,11 @@ require ( gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.16.3 - k8s.io/api v0.31.3 - k8s.io/apiextensions-apiserver v0.31.3 - k8s.io/apimachinery v0.31.3 - k8s.io/cli-runtime v0.31.3 - k8s.io/client-go v0.31.3 + k8s.io/api v0.32.0 + k8s.io/apiextensions-apiserver v0.32.0 + k8s.io/apimachinery v0.32.0 + k8s.io/cli-runtime v0.32.0 + k8s.io/client-go v0.32.0 sigs.k8s.io/controller-runtime v0.19.3 sigs.k8s.io/yaml v1.4.0 ) @@ -233,7 +233,6 @@ require ( github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/huandu/xstrings v1.5.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect @@ -338,13 +337,13 @@ require ( go.step.sm/crypto v0.54.2 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.30.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.22.0 // indirect golang.org/x/sync v0.10.0 // indirect golang.org/x/sys v0.28.0 // indirect golang.org/x/term v0.27.0 // indirect golang.org/x/time v0.8.0 // indirect - golang.org/x/tools v0.27.0 // indirect + golang.org/x/tools v0.28.0 // indirect google.golang.org/api v0.206.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect @@ -354,18 +353,18 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - k8s.io/apiserver v0.31.3 // indirect - k8s.io/component-base v0.31.3 // indirect + k8s.io/apiserver v0.32.0 // indirect + k8s.io/component-base v0.32.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094 // indirect - k8s.io/kubectl v0.31.3 // indirect - k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 // indirect + k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f // indirect + k8s.io/kubectl v0.32.0 // indirect + k8s.io/utils v0.0.0-20241210054802-24370beab758 // indirect oras.land/oras-go v1.2.6 // indirect sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 // indirect sigs.k8s.io/kustomize/api v0.18.0 // indirect sigs.k8s.io/kustomize/kyaml v0.18.1 // indirect sigs.k8s.io/release-utils v0.8.5 // indirect - sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.3 // indirect ) // see https://github.com/darccio/mergo?tab=readme-ov-file#100 diff --git a/go.sum b/go.sum index 078bbf32c3..cb07a1b822 100644 --- a/go.sum +++ b/go.sum @@ -337,13 +337,13 @@ github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfG github.com/distribution/distribution/v3 v3.0.0-beta.1/go.mod h1:O9O8uamhHzWWQVTjuQpyYUVm/ShPHPUDgvQMpHGVBDs= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.3.1+incompatible h1:qEGdFBF3Xu6SCvCYhc7CzaQTlBmqDuzxPDpigSyeKQQ= -github.com/docker/cli v27.3.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= +github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.3.1+incompatible h1:KttF0XoteNTicmUtBO0L2tP+J7FGRFTjaEF4k6WdhfI= -github.com/docker/docker v27.3.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.4.0+incompatible h1:I9z7sQ5qyzO0BfAb9IMOawRkAGxhYsidKiTMcm0DU+A= +github.com/docker/docker v27.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= @@ -386,10 +386,10 @@ github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/fluxcd/cli-utils v0.36.0-flux.10 h1:kgoj1HP7KBFfIG9CHLFHpA2kCPNlfzCpbscCaAOSClE= -github.com/fluxcd/cli-utils v0.36.0-flux.10/go.mod h1:eWf+UVZmm51EmNmeGkdplVLVsFU4jETfCjoHZq7nUp4= -github.com/fluxcd/pkg/ssa v0.41.1 h1:VW87zsLYAKUvCxJhuEH7VzxVh3SxaU+PyApCT6gKjTk= -github.com/fluxcd/pkg/ssa v0.41.1/go.mod h1:7cbyLHqFd5FpcKvhxbHG3DkMm3cZteW45Mi78B0hg8g= +github.com/fluxcd/cli-utils v0.36.0-flux.11 h1:W0y2uvCVkcE8bgV9jgoGSjzWbLFiNq1AjrWtuxllek8= +github.com/fluxcd/cli-utils v0.36.0-flux.11/go.mod h1:WZ7xUpZbK+O6HBxA5UWqzWTLSSltdmj4wS1LstS5Dqs= +github.com/fluxcd/pkg/ssa v0.43.0 h1:XmADD3C0erYZayKfGI0WTsMlW9TtS4bp5gy4Axo1dcA= +github.com/fluxcd/pkg/ssa v0.43.0/go.mod h1:MjkaOr4/5C8wkwsdVLMmfS64lDZOgJP4VNxmmJL0Iuc= github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= @@ -621,8 +621,6 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/in-toto/attestation v1.1.0 h1:oRWzfmZPDSctChD0VaQV7MJrywKOzyNrtpENQFq//2Q= github.com/in-toto/attestation v1.1.0/go.mod h1:DB59ytd3z7cIHgXxwpSX2SABrU6WJUKg/grpdgHVgVs= github.com/in-toto/in-toto-golang v0.9.0 h1:tHny7ac4KgtsfrG6ybU8gVOZux2H8jN05AXJ9EBM1XU= @@ -738,8 +736,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mittwald/go-helm-client v0.12.14 h1:az3GJ4kRmFK609Ic3iHXveNtg92n9jWG0YpKKTIK4oo= -github.com/mittwald/go-helm-client v0.12.14/go.mod h1:2VogAupgnV7FiuoPqtpCYKS/RrMh9fFA3/pD/OmTaLc= +github.com/mittwald/go-helm-client v0.12.15 h1:Ks7ccT3XflaCJ0/453qJLeVKlXo+K+buFehkFG0UWOE= +github.com/mittwald/go-helm-client v0.12.15/go.mod h1:LRRoErsgdw0TUVE8fXcwb1npRKibHGUQexiPhqc/UXA= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -801,8 +799,8 @@ github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoT github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.36.0 h1:Pb12RlruUtj4XUuPUqeEWc6j5DkVVVA49Uf6YLfC95Y= -github.com/onsi/gomega v1.36.0/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9 h1:b2cJvZ8nWAVvCqvPhUaFl26Wht4nM4mqfl2ksY9lVzU= github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/open-policy-agent/opa v0.68.0 h1:Jl3U2vXRjwk7JrHmS19U3HZO5qxQRinQbJ2eCJYSqJQ= @@ -911,8 +909,8 @@ github.com/sigstore/protobuf-specs v0.3.2 h1:nCVARCN+fHjlNCk3ThNXwrZRqIommIeNKWw github.com/sigstore/protobuf-specs v0.3.2/go.mod h1:RZ0uOdJR4OB3tLQeAyWoJFbNCBFrPQdcokntde4zRBA= github.com/sigstore/rekor v1.3.7 h1:Z5UW5TmqbTZnyOFkMRfi32q/CWcxK6VuzIkx+33mbq8= github.com/sigstore/rekor v1.3.7/go.mod h1:TihqJscZ6L6398x68EHY82t0AOnGYfrQ0siXe3WgbR4= -github.com/sigstore/sigstore v1.8.10 h1:r4t+TYzJlG9JdFxMy+um9GZhZ2N1hBTyTex0AHEZxFs= -github.com/sigstore/sigstore v1.8.10/go.mod h1:BekjqxS5ZtHNJC4u3Q3Stvfx2eyisbW/lUZzmPU2u4A= +github.com/sigstore/sigstore v1.8.11 h1:tEqeQqbT+awtM87ec9KEeSUxT/AFvJNawneYJyAkFrQ= +github.com/sigstore/sigstore v1.8.11/go.mod h1:fdrFQosxCQ4wTL5H1NrZcQkqQ72AQbPjtpcL2QOGKV0= github.com/sigstore/sigstore-go v0.6.1 h1:tGkkv1oDIER+QYU5MrjqlttQOVDWfSkmYwMqkJhB/cg= github.com/sigstore/sigstore-go v0.6.1/go.mod h1:Xe5GHmUeACRFbomUWzVkf/xYCn8xVifb9DgqJrV2dIw= github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.10 h1:e5GfVngPjGap/N3ODefayt7vKIPS1/v3hWLZ9+4MrN4= @@ -1112,8 +1110,8 @@ golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.30.0 h1:RwoQn3GkWiMkzlX562cLB7OxWvjH1L8xutO2WoJcRoY= -golang.org/x/crypto v0.30.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= @@ -1254,8 +1252,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.27.0 h1:qEKojBykQkQ4EynWy4S8Weg69NumxKdn40Fce3uc/8o= -golang.org/x/tools v0.27.0/go.mod h1:sUi0ZgbwW9ZPAq26Ekut+weQPR5eIM6GQLQ1Yjm1H0Q= +golang.org/x/tools v0.28.0 h1:WuB6qZ4RPCQo5aP3WdKZS7i595EdWqWR8vqJTlwTVK8= +golang.org/x/tools v0.28.0/go.mod h1:dcIOrVd3mfQKTgrDVQHqCPMWy6lnhfhtX3hLXYVLfRw= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1336,28 +1334,28 @@ helm.sh/helm/v3 v3.16.3 h1:kb8bSxMeRJ+knsK/ovvlaVPfdis0X3/ZhYCSFRP+YmY= helm.sh/helm/v3 v3.16.3/go.mod h1:zeVWGDR4JJgiRbT3AnNsjYaX8OTJlIE9zC+Q7F7iUSU= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.31.3 h1:umzm5o8lFbdN/hIXbrK9oRpOproJO62CV1zqxXrLgk8= -k8s.io/api v0.31.3/go.mod h1:UJrkIp9pnMOI9K2nlL6vwpxRzzEX5sWgn8kGQe92kCE= -k8s.io/apiextensions-apiserver v0.31.3 h1:+GFGj2qFiU7rGCsA5o+p/rul1OQIq6oYpQw4+u+nciE= -k8s.io/apiextensions-apiserver v0.31.3/go.mod h1:2DSpFhUZZJmn/cr/RweH1cEVVbzFw9YBu4T+U3mf1e4= -k8s.io/apimachinery v0.31.3 h1:6l0WhcYgasZ/wk9ktLq5vLaoXJJr5ts6lkaQzgeYPq4= -k8s.io/apimachinery v0.31.3/go.mod h1:rsPdaZJfTfLsNJSQzNHQvYoTmxhoOEofxtOsF3rtsMo= -k8s.io/apiserver v0.31.3 h1:+1oHTtCB+OheqFEz375D0IlzHZ5VeQKX1KGXnx+TTuY= -k8s.io/apiserver v0.31.3/go.mod h1:PrxVbebxrxQPFhJk4powDISIROkNMKHibTg9lTRQ0Qg= -k8s.io/cli-runtime v0.31.3 h1:fEQD9Xokir78y7pVK/fCJN090/iYNrLHpFbGU4ul9TI= -k8s.io/cli-runtime v0.31.3/go.mod h1:Q2jkyTpl+f6AtodQvgDI8io3jrfr+Z0LyQBPJJ2Btq8= -k8s.io/client-go v0.31.3 h1:CAlZuM+PH2cm+86LOBemaJI/lQ5linJ6UFxKX/SoG+4= -k8s.io/client-go v0.31.3/go.mod h1:2CgjPUTpv3fE5dNygAr2NcM8nhHzXvxB8KL5gYc3kJs= -k8s.io/component-base v0.31.3 h1:DMCXXVx546Rfvhj+3cOm2EUxhS+EyztH423j+8sOwhQ= -k8s.io/component-base v0.31.3/go.mod h1:xME6BHfUOafRgT0rGVBGl7TuSg8Z9/deT7qq6w7qjIU= +k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= +k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= +k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= +k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= +k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= +k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs= +k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag= +k8s.io/cli-runtime v0.32.0 h1:dP+OZqs7zHPpGQMCGAhectbHU2SNCuZtIimRKTv2T1c= +k8s.io/cli-runtime v0.32.0/go.mod h1:Mai8ht2+esoDRK5hr861KRy6z0zHsSTYttNVJXgP3YQ= +k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= +k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU= +k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094 h1:MErs8YA0abvOqJ8gIupA1Tz6PKXYUw34XsGlA7uSL1k= -k8s.io/kube-openapi v0.0.0-20241009091222-67ed5848f094/go.mod h1:7ioBJr1A6igWjsR2fxq2EZ0mlMwYLejazSIc2bzMp2U= -k8s.io/kubectl v0.31.3 h1:3r111pCjPsvnR98oLLxDMwAeM6OPGmPty6gSKaLTQes= -k8s.io/kubectl v0.31.3/go.mod h1:lhMECDCbJN8He12qcKqs2QfmVo9Pue30geovBVpH5fs= -k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= -k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= +k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= +k8s.io/kubectl v0.32.0 h1:rpxl+ng9qeG79YA4Em9tLSfX0G8W0vfaiPVrc/WR7Xw= +k8s.io/kubectl v0.32.0/go.mod h1:qIjSX+QgPQUgdy8ps6eKsYNF+YmFOAO3WygfucIqFiE= +k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0= +k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk= oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8= sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= @@ -1370,8 +1368,8 @@ sigs.k8s.io/kustomize/kyaml v0.18.1 h1:WvBo56Wzw3fjS+7vBjN6TeivvpbW9GmRaWZ9CIVmt sigs.k8s.io/kustomize/kyaml v0.18.1/go.mod h1:C3L2BFVU1jgcddNBE1TxuVLgS46TjObMwW5FT9FcjYo= sigs.k8s.io/release-utils v0.8.5 h1:FUtFqEAN621gSXv0L7kHyWruBeS7TUU9aWf76olX7uQ= sigs.k8s.io/release-utils v0.8.5/go.mod h1:qsm5bdxdgoHkD8HsXpgme2/c3mdsNaiV53Sz2HmKeJA= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= -sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/structured-merge-diff/v4 v4.4.3 h1:sCP7Vv3xx/CWIuTPVN38lUPx0uw0lcLfzaiDa8Ja01A= +sigs.k8s.io/structured-merge-diff/v4 v4.4.3/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= software.sslmate.com/src/go-pkcs12 v0.4.0 h1:H2g08FrTvSFKUj+D309j1DPfk5APnIdAQAB8aEykJ5k= From a6f1f3b00b01e1ee5653f9861acd2ae1719497fd Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Mon, 16 Dec 2024 08:01:10 +0000 Subject: [PATCH 30/50] chore: update 'flake.nix' (#1194) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index d2f84b025d..0f18a3344e 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-GgQt8YaOGaC7BjkrRQ8HzorqvY63vy4OWMEyvKHbfMs="; + vendorHash = "sha256-3h/k5p/simo4GtVm14mTBD5/4CG7QC8bfo48C6CuCbY="; src = ./.; From c7181af8af14a644eabfba76f7b8ec51f3b8a8eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Mon, 16 Dec 2024 12:46:27 +0300 Subject: [PATCH 31/50] chore: fixup symlink creation (#1199) #### What this PR does / why we need it this creates proper symlinks by forcing the link if it already exists. #### Which issue(s) this PR fixes --- .github/workflows/publish-to-other-than-github.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-to-other-than-github.yaml b/.github/workflows/publish-to-other-than-github.yaml index deff963c10..5828cb13d1 100644 --- a/.github/workflows/publish-to-other-than-github.yaml +++ b/.github/workflows/publish-to-other-than-github.yaml @@ -55,7 +55,7 @@ jobs: --outputDirectory ${{ github.workspace }}/tap/Formula) mkdir -p ${{ github.workspace }}/tap/Aliases cd ${{ github.workspace }}/tap/Aliases - ln -s ../Formula/$(basename $formula) ./ocm + ln -sf ../Formula/$(basename $formula) ./ocm - name: Create Pull Request uses: peter-evans/create-pull-request@v7 with: From 0db60537e82bc016665653f3c14c1aa58b3ac1e9 Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Mon, 16 Dec 2024 10:58:25 +0100 Subject: [PATCH 32/50] chore(github_action): add generate_token to push-to-website (#1198) last publish release didn't work: https://github.com/open-component-model/ocm/actions/runs/12349057328/job/34459090022 --- .github/workflows/publish-to-other-than-github.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/publish-to-other-than-github.yaml b/.github/workflows/publish-to-other-than-github.yaml index 5828cb13d1..f76b148507 100644 --- a/.github/workflows/publish-to-other-than-github.yaml +++ b/.github/workflows/publish-to-other-than-github.yaml @@ -147,6 +147,12 @@ jobs: steps: - name: Ensure proper version run: echo "RELEASE_VERSION=$(echo ${{ github.event.client_payload.version }})" >> $GITHUB_ENV + - name: Generate token + id: generate_token + uses: tibdex/github-app-token@v2 + with: + app_id: ${{ secrets.OCMBOT_APP_ID }} + private_key: ${{ secrets.OCMBOT_PRIV_KEY }} - name: Publish Release Event uses: peter-evans/repository-dispatch@v3 with: From b41f962a8ea160c544a646367e43b9cb8cebec5a Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Mon, 16 Dec 2024 14:51:51 +0100 Subject: [PATCH 33/50] fix: fix toi doc (#1196) #### What this PR does / why we need it The command doc for ocm toi-bootstrapping shows the wrong type for the reference to a TOI executor. #### Which issue(s) this PR fixes Fixes [#339](https://github.com/open-component-model/ocm-project/issues/339) --- cmds/ocm/topics/toi/bootstrapping/topic.go | 2 +- docs/reference/ocm_toi-bootstrapping.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmds/ocm/topics/toi/bootstrapping/topic.go b/cmds/ocm/topics/toi/bootstrapping/topic.go index 814c267c24..5b81157450 100644 --- a/cmds/ocm/topics/toi/bootstrapping/topic.go +++ b/cmds/ocm/topics/toi/bootstrapping/topic.go @@ -172,7 +172,7 @@ to executors. It uses the following fields: the executor will be used for all actions. The first matching executor entry will be used to execute an action by the bootstrap command -- **resourceRef** *[]ResourceReference* +- **resourceRef** *ResourceReference* An OCM resource reference describing a component version resource relative to the component version containing the package resource. diff --git a/docs/reference/ocm_toi-bootstrapping.md b/docs/reference/ocm_toi-bootstrapping.md index a128663808..87ddf03603 100644 --- a/docs/reference/ocm_toi-bootstrapping.md +++ b/docs/reference/ocm_toi-bootstrapping.md @@ -113,7 +113,7 @@ to executors. It uses the following fields: the executor will be used for all actions. The first matching executor entry will be used to execute an action by the bootstrap command -- **resourceRef** *[]ResourceReference* +- **resourceRef** *ResourceReference* An OCM resource reference describing a component version resource relative to the component version containing the package resource. From 104d27600f6c3fa0bac6c47d4a0d7f7fa7da573f Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Wed, 18 Dec 2024 10:25:01 +0100 Subject: [PATCH 34/50] feat: replace docker client code with oras - take 2 (#1184) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What this PR does / why we need it Closes https://github.com/open-component-model/ocm-project/issues/302 #### Which issue(s) this PR fixes --------- Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Co-authored-by: Jakob Möller --- .../extensions/repositories/ocireg/blobs.go | 16 +- .../repositories/ocireg/namespace.go | 12 +- .../repositories/ocireg/repository.go | 92 ++- .../extensions/repositories/ocireg/utils.go | 13 +- api/tech/docker/README.md | 4 - api/tech/docker/errors/errors.go | 58 -- api/tech/docker/fetcher.go | 202 ------ api/tech/docker/handler.go | 136 ---- api/tech/docker/httpreadseeker.go | 157 ----- api/tech/docker/lister.go | 130 ---- api/tech/docker/orig.go | 44 -- api/tech/docker/pusher.go | 433 ------------ api/tech/docker/registry.go | 234 ------- api/tech/docker/resolver.go | 656 ------------------ api/tech/oras/client.go | 201 ++++++ api/tech/oras/delayed_reader.go | 57 ++ .../{docker/resolve => oras}/interface.go | 19 +- go.mod | 2 +- go.sum | 2 + hack/generate.sh | 2 +- 20 files changed, 329 insertions(+), 2141 deletions(-) delete mode 100644 api/tech/docker/README.md delete mode 100644 api/tech/docker/errors/errors.go delete mode 100644 api/tech/docker/fetcher.go delete mode 100644 api/tech/docker/handler.go delete mode 100644 api/tech/docker/httpreadseeker.go delete mode 100644 api/tech/docker/lister.go delete mode 100644 api/tech/docker/orig.go delete mode 100644 api/tech/docker/pusher.go delete mode 100644 api/tech/docker/registry.go delete mode 100644 api/tech/docker/resolver.go create mode 100644 api/tech/oras/client.go create mode 100644 api/tech/oras/delayed_reader.go rename api/tech/{docker/resolve => oras}/interface.go (73%) diff --git a/api/oci/extensions/repositories/ocireg/blobs.go b/api/oci/extensions/repositories/ocireg/blobs.go index 0ecf1b299d..d8491c266f 100644 --- a/api/oci/extensions/repositories/ocireg/blobs.go +++ b/api/oci/extensions/repositories/ocireg/blobs.go @@ -10,7 +10,7 @@ import ( "ocm.software/ocm/api/oci/cpi" "ocm.software/ocm/api/oci/extensions/attrs/cacheattr" - "ocm.software/ocm/api/tech/docker/resolve" + "ocm.software/ocm/api/tech/oras" "ocm.software/ocm/api/utils/accessio" "ocm.software/ocm/api/utils/blobaccess/blobaccess" ) @@ -23,20 +23,20 @@ type BlobContainer interface { type blobContainer struct { accessio.StaticAllocatable - fetcher resolve.Fetcher - pusher resolve.Pusher + fetcher oras.Fetcher + pusher oras.Pusher mime string } type BlobContainers struct { lock sync.Mutex cache accessio.BlobCache - fetcher resolve.Fetcher - pusher resolve.Pusher + fetcher oras.Fetcher + pusher oras.Pusher mimes map[string]BlobContainer } -func NewBlobContainers(ctx cpi.Context, fetcher remotes.Fetcher, pusher resolve.Pusher) *BlobContainers { +func NewBlobContainers(ctx cpi.Context, fetcher remotes.Fetcher, pusher oras.Pusher) *BlobContainers { return &BlobContainers{ cache: cacheattr.Get(ctx), fetcher: fetcher, @@ -73,7 +73,7 @@ func (c *BlobContainers) Release() error { return list.Result() } -func newBlobContainer(mime string, fetcher resolve.Fetcher, pusher resolve.Pusher) *blobContainer { +func newBlobContainer(mime string, fetcher oras.Fetcher, pusher oras.Pusher) *blobContainer { return &blobContainer{ mime: mime, fetcher: fetcher, @@ -81,7 +81,7 @@ func newBlobContainer(mime string, fetcher resolve.Fetcher, pusher resolve.Pushe } } -func NewBlobContainer(cache accessio.BlobCache, mime string, fetcher resolve.Fetcher, pusher resolve.Pusher) (BlobContainer, error) { +func NewBlobContainer(cache accessio.BlobCache, mime string, fetcher oras.Fetcher, pusher oras.Pusher) (BlobContainer, error) { c := newBlobContainer(mime, fetcher, pusher) if cache == nil { diff --git a/api/oci/extensions/repositories/ocireg/namespace.go b/api/oci/extensions/repositories/ocireg/namespace.go index 9ef8239979..dd3583d7b6 100644 --- a/api/oci/extensions/repositories/ocireg/namespace.go +++ b/api/oci/extensions/repositories/ocireg/namespace.go @@ -12,7 +12,7 @@ import ( "ocm.software/ocm/api/oci/cpi" "ocm.software/ocm/api/oci/cpi/support" "ocm.software/ocm/api/oci/extensions/actions/oci-repository-prepare" - "ocm.software/ocm/api/tech/docker/resolve" + "ocm.software/ocm/api/tech/oras" "ocm.software/ocm/api/utils/accessio" "ocm.software/ocm/api/utils/blobaccess/blobaccess" "ocm.software/ocm/api/utils/logging" @@ -22,10 +22,10 @@ import ( type NamespaceContainer struct { impl support.NamespaceAccessImpl repo *RepositoryImpl - resolver resolve.Resolver - lister resolve.Lister - fetcher resolve.Fetcher - pusher resolve.Pusher + resolver oras.Resolver + lister oras.Lister + fetcher oras.Fetcher + pusher oras.Pusher blobs *BlobContainers checked bool } @@ -69,7 +69,7 @@ func (n *NamespaceContainer) SetImplementation(impl support.NamespaceAccessImpl) n.impl = impl } -func (n *NamespaceContainer) getPusher(vers string) (resolve.Pusher, error) { +func (n *NamespaceContainer) getPusher(vers string) (oras.Pusher, error) { err := n.assureCreated() if err != nil { return nil, err diff --git a/api/oci/extensions/repositories/ocireg/repository.go b/api/oci/extensions/repositories/ocireg/repository.go index bff1e51078..1f1ede981a 100644 --- a/api/oci/extensions/repositories/ocireg/repository.go +++ b/api/oci/extensions/repositories/ocireg/repository.go @@ -8,18 +8,18 @@ import ( "path" "strings" - "github.com/containerd/containerd/remotes/docker/config" "github.com/containerd/errdefs" "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/logging" + "oras.land/oras-go/v2/registry/remote/auth" + "oras.land/oras-go/v2/registry/remote/retry" "ocm.software/ocm/api/credentials" "ocm.software/ocm/api/datacontext/attrs/rootcertsattr" "ocm.software/ocm/api/oci/artdesc" "ocm.software/ocm/api/oci/cpi" - "ocm.software/ocm/api/tech/docker" - "ocm.software/ocm/api/tech/docker/resolve" "ocm.software/ocm/api/tech/oci/identity" + "ocm.software/ocm/api/tech/oras" "ocm.software/ocm/api/utils" ocmlog "ocm.software/ocm/api/utils/logging" "ocm.software/ocm/api/utils/refmgmt" @@ -114,7 +114,7 @@ func (r *RepositoryImpl) getCreds(comp string) (credentials.Credentials, error) return identity.GetCredentials(r.GetContext(), r.info.Locator, comp) } -func (r *RepositoryImpl) getResolver(comp string) (resolve.Resolver, error) { +func (r *RepositoryImpl) getResolver(comp string) (oras.Resolver, error) { creds, err := r.getCreds(comp) if err != nil { if !errors.IsErrUnknownKind(err, credentials.KIND_CONSUMER) { @@ -126,57 +126,53 @@ func (r *RepositoryImpl) getResolver(comp string) (resolve.Resolver, error) { logger.Trace("no credentials") } - opts := docker.ResolverOptions{ - Hosts: docker.ConvertHosts(config.ConfigureHosts(context.Background(), config.HostOptions{ - UpdateClient: func(client *http.Client) error { - // copy from http.DefaultTransport with a roundtripper injection - client.Transport = ocmlog.NewRoundTripper(client.Transport, logger) - return nil - }, - Credentials: func(host string) (string, string, error) { + authCreds := auth.Credential{} + if creds != nil { + pass := creds.GetProperty(credentials.ATTR_IDENTITY_TOKEN) + if pass == "" { + pass = creds.GetProperty(credentials.ATTR_PASSWORD) + } + authCreds.Username = creds.GetProperty(credentials.ATTR_USERNAME) + authCreds.Password = pass + } + + client := retry.DefaultClient + client.Transport = ocmlog.NewRoundTripper(retry.DefaultClient.Transport, logger) + if r.info.Scheme == "https" { + // set up TLS + //nolint:gosec // used like the default, there are OCI servers (quay.io) not working with min version. + conf := &tls.Config{ + // MinVersion: tls.VersionTLS13, + RootCAs: func() *x509.CertPool { + var rootCAs *x509.CertPool if creds != nil { - p := creds.GetProperty(credentials.ATTR_IDENTITY_TOKEN) - if p == "" { - p = creds.GetProperty(credentials.ATTR_PASSWORD) - } - pw := "" - if p != "" { - pw = "***" + c := creds.GetProperty(credentials.ATTR_CERTIFICATE_AUTHORITY) + if c != "" { + rootCAs = x509.NewCertPool() + rootCAs.AppendCertsFromPEM([]byte(c)) } - logger.Trace("query credentials", ocmlog.ATTR_USER, creds.GetProperty(credentials.ATTR_USERNAME), "pass", pw) - return creds.GetProperty(credentials.ATTR_USERNAME), p, nil } - logger.Trace("no credentials") - return "", "", nil - }, - DefaultScheme: r.info.Scheme, - //nolint:gosec // used like the default, there are OCI servers (quay.io) not working with min version. - DefaultTLS: func() *tls.Config { - if r.info.Scheme == "http" { - return nil - } - return &tls.Config{ - // MinVersion: tls.VersionTLS13, - RootCAs: func() *x509.CertPool { - var rootCAs *x509.CertPool - if creds != nil { - c := creds.GetProperty(credentials.ATTR_CERTIFICATE_AUTHORITY) - if c != "" { - rootCAs = x509.NewCertPool() - rootCAs.AppendCertsFromPEM([]byte(c)) - } - } - if rootCAs == nil { - rootCAs = rootcertsattr.Get(r.GetContext()).GetRootCertPool(true) - } - return rootCAs - }(), + if rootCAs == nil { + rootCAs = rootcertsattr.Get(r.GetContext()).GetRootCertPool(true) } + return rootCAs }(), - })), + } + client.Transport = ocmlog.NewRoundTripper(retry.NewTransport(&http.Transport{ + TLSClientConfig: conf, + }), logger) + } + + authClient := &auth.Client{ + Client: client, + Cache: auth.NewCache(), + Credential: auth.StaticCredential(r.info.HostPort(), authCreds), } - return docker.NewResolver(opts), nil + return oras.New(oras.ClientOptions{ + Client: authClient, + PlainHTTP: r.info.Scheme == "http", + }), nil } func (r *RepositoryImpl) GetRef(comp, vers string) string { diff --git a/api/oci/extensions/repositories/ocireg/utils.go b/api/oci/extensions/repositories/ocireg/utils.go index 17a96f040a..51f5994d17 100644 --- a/api/oci/extensions/repositories/ocireg/utils.go +++ b/api/oci/extensions/repositories/ocireg/utils.go @@ -14,7 +14,7 @@ import ( "ocm.software/ocm/api/oci/artdesc" "ocm.software/ocm/api/oci/cpi" - "ocm.software/ocm/api/tech/docker/resolve" + "ocm.software/ocm/api/tech/oras" "ocm.software/ocm/api/utils/accessio" "ocm.software/ocm/api/utils/blobaccess/blobaccess" "ocm.software/ocm/api/utils/logging" @@ -81,28 +81,29 @@ func readAll(reader io.ReadCloser, err error) ([]byte, error) { return data, nil } -func push(ctx context.Context, p resolve.Pusher, blob blobaccess.BlobAccess) error { +func push(ctx context.Context, p oras.Pusher, blob blobaccess.BlobAccess) error { desc := *artdesc.DefaultBlobDescriptor(blob) return pushData(ctx, p, desc, blob) } -func pushData(ctx context.Context, p resolve.Pusher, desc artdesc.Descriptor, data blobaccess.DataAccess) error { +func pushData(ctx context.Context, p oras.Pusher, desc artdesc.Descriptor, data blobaccess.DataAccess) error { key := remotes.MakeRefKey(ctx, desc) if desc.Size == 0 { desc.Size = -1 } logging.Logger().Debug("*** push blob", "mediatype", desc.MediaType, "digest", desc.Digest, "key", key) - req, err := p.Push(ctx, desc, data) - if err != nil { + if err := p.Push(ctx, desc, data); err != nil { if errdefs.IsAlreadyExists(err) { logging.Logger().Debug("blob already exists", "mediatype", desc.MediaType, "digest", desc.Digest) return nil } + return fmt.Errorf("failed to push: %w", err) } - return req.Commit(ctx, desc.Size, desc.Digest) + + return nil } var dummyContext = nologger() diff --git a/api/tech/docker/README.md b/api/tech/docker/README.md deleted file mode 100644 index 096a9c1e18..0000000000 --- a/api/tech/docker/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# containerd - -Taken from github.com/containerd/containerd remotes/docker to add list endpoints -Fix retry of requests with ResendBuffer diff --git a/api/tech/docker/errors/errors.go b/api/tech/docker/errors/errors.go deleted file mode 100644 index a158f75b5a..0000000000 --- a/api/tech/docker/errors/errors.go +++ /dev/null @@ -1,58 +0,0 @@ -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package errors - -import ( - "fmt" - "io" - "net/http" -) - -var _ error = ErrUnexpectedStatus{} - -// ErrUnexpectedStatus is returned if a registry API request returned with unexpected HTTP status -type ErrUnexpectedStatus struct { - Status string - StatusCode int - Body []byte - RequestURL, RequestMethod string -} - -func (e ErrUnexpectedStatus) Error() string { - if len(e.Body) > 0 { - return fmt.Sprintf("unexpected status from %s request to %s: %s: %s", e.RequestMethod, e.RequestURL, e.Status, string(e.Body)) - } - return fmt.Sprintf("unexpected status from %s request to %s: %s", e.RequestMethod, e.RequestURL, e.Status) -} - -// NewUnexpectedStatusErr creates an ErrUnexpectedStatus from HTTP response -func NewUnexpectedStatusErr(resp *http.Response) error { - var b []byte - if resp.Body != nil { - b, _ = io.ReadAll(io.LimitReader(resp.Body, 64000)) // 64KB - } - err := ErrUnexpectedStatus{ - Body: b, - Status: resp.Status, - StatusCode: resp.StatusCode, - RequestMethod: resp.Request.Method, - } - if resp.Request.URL != nil { - err.RequestURL = resp.Request.URL.String() - } - return err -} diff --git a/api/tech/docker/fetcher.go b/api/tech/docker/fetcher.go deleted file mode 100644 index 4a2eec584e..0000000000 --- a/api/tech/docker/fetcher.go +++ /dev/null @@ -1,202 +0,0 @@ -package docker - -import ( - "context" - "encoding/json" - "fmt" - "io" - "net/http" - "net/url" - "strings" - - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/images" - "github.com/containerd/containerd/log" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - - "ocm.software/ocm/api/utils/accessio" -) - -type dockerFetcher struct { - *dockerBase -} - -func (r dockerFetcher) Fetch(ctx context.Context, desc ocispec.Descriptor) (io.ReadCloser, error) { - ctx = log.WithLogger(ctx, log.G(ctx).WithField("digest", desc.Digest)) - - hosts := r.filterHosts(HostCapabilityPull) - if len(hosts) == 0 { - return nil, errors.Wrap(errdefs.ErrNotFound, "no pull hosts") - } - - ctx, err := ContextWithRepositoryScope(ctx, r.refspec, false) - if err != nil { - return nil, err - } - - return newHTTPReadSeeker(desc.Size, func(offset int64) (io.ReadCloser, error) { - // firstly try fetch via external urls - for _, us := range desc.URLs { - ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", us)) - - u, err := url.Parse(us) - if err != nil { - log.G(ctx).WithError(err).Debug("failed to parse") - continue - } - if u.Scheme != "http" && u.Scheme != "https" { - log.G(ctx).Debug("non-http(s) alternative url is unsupported") - continue - } - log.G(ctx).Debug("trying alternative url") - - // Try this first, parse it - host := RegistryHost{ - Client: http.DefaultClient, - Host: u.Host, - Scheme: u.Scheme, - Path: u.Path, - Capabilities: HostCapabilityPull, - } - req := r.request(host, http.MethodGet) - // Strip namespace from base - req.path = u.Path - if u.RawQuery != "" { - req.path = req.path + "?" + u.RawQuery - } - - rc, err := r.open(ctx, req, desc.MediaType, offset) - if err != nil { - if errdefs.IsNotFound(err) { - continue // try one of the other urls. - } - - return nil, err - } - - return rc, nil - } - - // Try manifests endpoints for manifests types - switch desc.MediaType { - case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList, - images.MediaTypeDockerSchema1Manifest, - ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex: - - var firstErr error - for _, host := range r.hosts { - req := r.request(host, http.MethodGet, "manifests", desc.Digest.String()) - if err := req.addNamespace(r.refspec.Hostname()); err != nil { - return nil, err - } - - rc, err := r.open(ctx, req, desc.MediaType, offset) - if err != nil { - // Store the error for referencing later - if firstErr == nil { - firstErr = err - } - continue // try another host - } - - return rc, nil - } - - return nil, firstErr - } - - // Finally use blobs endpoints - var firstErr error - for _, host := range r.hosts { - req := r.request(host, http.MethodGet, "blobs", desc.Digest.String()) - if err := req.addNamespace(r.refspec.Hostname()); err != nil { - return nil, err - } - - rc, err := r.open(ctx, req, desc.MediaType, offset) - if err != nil { - // Store the error for referencing later - if firstErr == nil { - firstErr = err - } - continue // try another host - } - - return rc, nil - } - - if errdefs.IsNotFound(firstErr) { - firstErr = errors.Wrapf(errdefs.ErrNotFound, - "could not fetch content descriptor %v (%v) from remote", - desc.Digest, desc.MediaType) - } - - return nil, firstErr - }) -} - -func (r dockerFetcher) open(ctx context.Context, req *request, mediatype string, offset int64) (_ io.ReadCloser, retErr error) { - mt := "*/*" - if mediatype != "" { - mt = mediatype + ", " + mt - } - req.header.Set("Accept", mt) - - if offset > 0 { - // Note: "Accept-Ranges: bytes" cannot be trusted as some endpoints - // will return the header without supporting the range. The content - // range must always be checked. - req.header.Set("Range", fmt.Sprintf("bytes=%d-", offset)) - } - - resp, err := req.doWithRetries(ctx, nil) - if err != nil { - return nil, accessio.RetriableError(err) - } - defer func() { - if retErr != nil { - resp.Body.Close() - } - }() - - if resp.StatusCode > 299 { - // TODO(stevvooe): When doing a offset specific request, we should - // really distinguish between a 206 and a 200. In the case of 200, we - // can discard the bytes, hiding the seek behavior from the - // implementation. - - if resp.StatusCode == http.StatusNotFound { - return nil, errors.Wrapf(errdefs.ErrNotFound, "content at %v not found", req.String()) - } - var registryErr Errors - if err := json.NewDecoder(resp.Body).Decode(®istryErr); err != nil || registryErr.Len() < 1 { - return nil, errors.Errorf("unexpected status code %v: %v", req.String(), resp.Status) - } - return nil, errors.Errorf("unexpected status code %v: %s - Server message: %s", req.String(), resp.Status, registryErr.Error()) - } - if offset > 0 { - cr := resp.Header.Get("content-range") - if cr != "" { - if !strings.HasPrefix(cr, fmt.Sprintf("bytes %d-", offset)) { - return nil, errors.Errorf("unhandled content range in response: %v", cr) - } - } else { - // TODO: Should any cases where use of content range - // without the proper header be considered? - // 206 responses? - - // Discard up to offset - // Could use buffer pool here but this case should be rare - n, err := io.Copy(io.Discard, io.LimitReader(resp.Body, offset)) - if err != nil { - return nil, errors.Wrap(err, "failed to discard to offset") - } - if n != offset { - return nil, errors.Errorf("unable to discard to offset") - } - } - } - - return resp.Body, nil -} diff --git a/api/tech/docker/handler.go b/api/tech/docker/handler.go deleted file mode 100644 index 0ff9959ad3..0000000000 --- a/api/tech/docker/handler.go +++ /dev/null @@ -1,136 +0,0 @@ -package docker - -import ( - "context" - "fmt" - "net/url" - "strings" - - "github.com/containerd/containerd/content" - "github.com/containerd/containerd/images" - "github.com/containerd/containerd/labels" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/reference" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" -) - -// labelDistributionSource describes the source blob comes from. -var labelDistributionSource = "containerd.io/distribution.source" - -// AppendDistributionSourceLabel updates the label of blob with distribution source. -func AppendDistributionSourceLabel(manager content.Manager, ref string) (images.HandlerFunc, error) { - refspec, err := reference.Parse(ref) - if err != nil { - return nil, err - } - - u, err := url.Parse("dummy://" + refspec.Locator) - if err != nil { - return nil, err - } - - source, repo := u.Hostname(), strings.TrimPrefix(u.Path, "/") - return func(ctx context.Context, desc ocispec.Descriptor) ([]ocispec.Descriptor, error) { - info, err := manager.Info(ctx, desc.Digest) - if err != nil { - return nil, err - } - - key := distributionSourceLabelKey(source) - - originLabel := "" - if info.Labels != nil { - originLabel = info.Labels[key] - } - value := appendDistributionSourceLabel(originLabel, repo) - - // The repo name has been limited under 256 and the distribution - // label might hit the limitation of label size, when blob data - // is used as the very, very common layer. - if err := labels.Validate(key, value); err != nil { - log.G(ctx).Warnf("skip to append distribution label: %s", err) - return nil, nil - } - - info = content.Info{ - Digest: desc.Digest, - Labels: map[string]string{ - key: value, - }, - } - _, err = manager.Update(ctx, info, fmt.Sprintf("labels.%s", key)) - return nil, err - }, nil -} - -func appendDistributionSourceLabel(originLabel, repo string) string { - repos := []string{} - if originLabel != "" { - repos = strings.Split(originLabel, ",") - } - repos = append(repos, repo) - - // use empty string to present duplicate items - for i := 1; i < len(repos); i++ { - tmp, j := repos[i], i-1 - for ; j >= 0 && repos[j] >= tmp; j-- { - if repos[j] == tmp { - tmp = "" - } - repos[j+1] = repos[j] - } - repos[j+1] = tmp - } - - i := 0 - for ; i < len(repos) && repos[i] == ""; i++ { - } - - return strings.Join(repos[i:], ",") -} - -func distributionSourceLabelKey(source string) string { - return fmt.Sprintf("%s.%s", labelDistributionSource, source) -} - -// selectRepositoryMountCandidate will select the repo which has longest -// common prefix components as the candidate. -func selectRepositoryMountCandidate(refspec reference.Spec, sources map[string]string) string { - u, err := url.Parse("dummy://" + refspec.Locator) - if err != nil { - // NOTE: basically, it won't be error here - return "" - } - - source, target := u.Hostname(), strings.TrimPrefix(u.Path, "/") - repoLabel, ok := sources[distributionSourceLabelKey(source)] - if !ok || repoLabel == "" { - return "" - } - - n, match := 0, "" - components := strings.Split(target, "/") - for _, repo := range strings.Split(repoLabel, ",") { - // the target repo is not a candidate - if repo == target { - continue - } - - if l := commonPrefixComponents(components, repo); l >= n { - n, match = l, repo - } - } - return match -} - -func commonPrefixComponents(components []string, target string) int { - targetComponents := strings.Split(target, "/") - - i := 0 - for ; i < len(components) && i < len(targetComponents); i++ { - if components[i] != targetComponents[i] { - break - } - } - return i -} diff --git a/api/tech/docker/httpreadseeker.go b/api/tech/docker/httpreadseeker.go deleted file mode 100644 index c6b803810b..0000000000 --- a/api/tech/docker/httpreadseeker.go +++ /dev/null @@ -1,157 +0,0 @@ -package docker - -import ( - "bytes" - "io" - - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/log" - "github.com/pkg/errors" -) - -const maxRetry = 3 - -type httpReadSeeker struct { - size int64 - offset int64 - rc io.ReadCloser - open func(offset int64) (io.ReadCloser, error) - closed bool - - errsWithNoProgress int -} - -func newHTTPReadSeeker(size int64, open func(offset int64) (io.ReadCloser, error)) (io.ReadCloser, error) { - return &httpReadSeeker{ - size: size, - open: open, - }, nil -} - -func (hrs *httpReadSeeker) Read(p []byte) (n int, err error) { - if hrs.closed { - return 0, io.EOF - } - - rd, err := hrs.reader() - if err != nil { - return 0, err - } - - n, err = rd.Read(p) - hrs.offset += int64(n) - if n > 0 || err == nil { - hrs.errsWithNoProgress = 0 - } - - if !errors.Is(err, io.ErrUnexpectedEOF) { - return - } - // connection closed unexpectedly. try reconnecting. - if n == 0 { - hrs.errsWithNoProgress++ - if hrs.errsWithNoProgress > maxRetry { - return // too many retries for this offset with no progress - } - } - - if hrs.rc != nil { - if clsErr := hrs.rc.Close(); clsErr != nil { - log.L.WithError(clsErr).Errorf("httpReadSeeker: failed to close ReadCloser") - } - hrs.rc = nil - } - - if _, err2 := hrs.reader(); err2 == nil { - return n, nil - } - - return n, err -} - -func (hrs *httpReadSeeker) Close() error { - if hrs.closed { - return nil - } - hrs.closed = true - if hrs.rc != nil { - return hrs.rc.Close() - } - - return nil -} - -func (hrs *httpReadSeeker) Seek(offset int64, whence int) (int64, error) { - if hrs.closed { - return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: closed") - } - - abs := hrs.offset - switch whence { - case io.SeekStart: - abs = offset - case io.SeekCurrent: - abs += offset - case io.SeekEnd: - if hrs.size == -1 { - return 0, errors.Wrap(errdefs.ErrUnavailable, "Fetcher.Seek: unknown size, cannot seek from end") - } - abs = hrs.size + offset - default: - return 0, errors.Wrap(errdefs.ErrInvalidArgument, "Fetcher.Seek: invalid whence") - } - - if abs < 0 { - return 0, errors.Wrapf(errdefs.ErrInvalidArgument, "Fetcher.Seek: negative offset") - } - - if abs != hrs.offset { - if hrs.rc != nil { - if err := hrs.rc.Close(); err != nil { - log.L.WithError(err).Errorf("Fetcher.Seek: failed to close ReadCloser") - } - - hrs.rc = nil - } - - hrs.offset = abs - } - - return hrs.offset, nil -} - -func (hrs *httpReadSeeker) reader() (io.Reader, error) { - if hrs.rc != nil { - return hrs.rc, nil - } - - if hrs.size == -1 || hrs.offset < hrs.size { - // only try to reopen the body request if we are seeking to a value - // less than the actual size. - if hrs.open == nil { - return nil, errors.Wrapf(errdefs.ErrNotImplemented, "cannot open") - } - - rc, err := hrs.open(hrs.offset) - if err != nil { - return nil, errors.Wrapf(err, "httpReadSeeker: failed open") - } - - if hrs.rc != nil { - if err := hrs.rc.Close(); err != nil { - log.L.WithError(err).Errorf("httpReadSeeker: failed to close ReadCloser") - } - } - hrs.rc = rc - } else { - // There is an edge case here where offset == size of the content. If - // we seek, we will probably get an error for content that cannot be - // sought (?). In that case, we should err on committing the content, - // as the length is already satisfied but we just return the empty - // reader instead. - - hrs.rc = io.NopCloser(bytes.NewReader([]byte{})) - } - - return hrs.rc, nil -} diff --git a/api/tech/docker/lister.go b/api/tech/docker/lister.go deleted file mode 100644 index efd3b8e1e2..0000000000 --- a/api/tech/docker/lister.go +++ /dev/null @@ -1,130 +0,0 @@ -package docker - -import ( - "context" - "encoding/json" - "io" - "net/http" - - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/log" - "github.com/pkg/errors" - - "ocm.software/ocm/api/tech/docker/resolve" -) - -var ErrObjectNotRequired = errors.New("object not required") - -type TagList struct { - Name string `json:"name"` - Tags []string `json:"tags"` -} - -type dockerLister struct { - dockerBase *dockerBase -} - -func (r *dockerResolver) Lister(ctx context.Context, ref string) (resolve.Lister, error) { - base, err := r.resolveDockerBase(ref) - if err != nil { - return nil, err - } - if base.refspec.Object != "" { - return nil, ErrObjectNotRequired - } - - return &dockerLister{ - dockerBase: base, - }, nil -} - -func (r *dockerLister) List(ctx context.Context) ([]string, error) { - refspec := r.dockerBase.refspec - base := r.dockerBase - var ( - firstErr error - paths [][]string - caps = HostCapabilityPull - ) - - // turns out, we have a valid digest, make a url. - paths = append(paths, []string{"tags/list"}) - caps |= HostCapabilityResolve - - hosts := base.filterHosts(caps) - if len(hosts) == 0 { - return nil, errors.Wrap(errdefs.ErrNotFound, "no list hosts") - } - - ctx, err := ContextWithRepositoryScope(ctx, refspec, false) - if err != nil { - return nil, err - } - - for _, u := range paths { - for _, host := range hosts { - ctxWithLogger := log.WithLogger(ctx, log.G(ctx).WithField("host", host.Host)) - - req := base.request(host, http.MethodGet, u...) - if err := req.addNamespace(base.refspec.Hostname()); err != nil { - return nil, err - } - - req.header["Accept"] = []string{"application/json"} - - log.G(ctxWithLogger).Debug("listing") - resp, err := req.doWithRetries(ctxWithLogger, nil) - if err != nil { - if errors.Is(err, ErrInvalidAuthorization) { - err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") - } - // Store the error for referencing later - if firstErr == nil { - firstErr = err - } - log.G(ctxWithLogger).WithError(err).Info("trying next host") - continue // try another host - } - - if resp.StatusCode > 299 { - resp.Body.Close() - if resp.StatusCode == http.StatusNotFound { - log.G(ctxWithLogger).Info("trying next host - response was http.StatusNotFound") - continue - } - if resp.StatusCode > 399 { - // Set firstErr when encountering the first non-404 status code. - if firstErr == nil { - firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status) - } - continue // try another host - } - return nil, errors.Errorf("taglist from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status) - } - - data, err := io.ReadAll(resp.Body) - resp.Body.Close() - if err != nil { - return nil, err - } - - tags := &TagList{} - - err = json.Unmarshal(data, tags) - if err != nil { - return nil, err - } - return tags.Tags, nil - } - } - - // If above loop terminates without return, then there was an error. - // "firstErr" contains the first non-404 error. That is, "firstErr == nil" - // means that either no registries were given or each registry returned 404. - - if firstErr == nil { - firstErr = errors.Wrap(errdefs.ErrNotFound, base.refspec.Locator) - } - - return nil, firstErr -} diff --git a/api/tech/docker/orig.go b/api/tech/docker/orig.go deleted file mode 100644 index c9b2468fba..0000000000 --- a/api/tech/docker/orig.go +++ /dev/null @@ -1,44 +0,0 @@ -package docker - -import ( - "github.com/containerd/containerd/remotes/docker" -) - -var ( - ContextWithRepositoryScope = docker.ContextWithRepositoryScope - ContextWithAppendPullRepositoryScope = docker.ContextWithAppendPullRepositoryScope - NewInMemoryTracker = docker.NewInMemoryTracker - NewDockerAuthorizer = docker.NewDockerAuthorizer - WithAuthClient = docker.WithAuthClient - WithAuthHeader = docker.WithAuthHeader - WithAuthCreds = docker.WithAuthCreds -) - -type ( - Errors = docker.Errors - StatusTracker = docker.StatusTracker - Status = docker.Status - StatusTrackLocker = docker.StatusTrackLocker -) - -func ConvertHosts(hosts docker.RegistryHosts) RegistryHosts { - return func(host string) ([]RegistryHost, error) { - list, err := hosts(host) - if err != nil { - return nil, err - } - result := make([]RegistryHost, len(list)) - for i, v := range list { - result[i] = RegistryHost{ - Client: v.Client, - Authorizer: v.Authorizer, - Host: v.Host, - Scheme: v.Scheme, - Path: v.Path, - Capabilities: HostCapabilities(v.Capabilities), - Header: v.Header, - } - } - return result, nil - } -} diff --git a/api/tech/docker/pusher.go b/api/tech/docker/pusher.go deleted file mode 100644 index 708ad0f349..0000000000 --- a/api/tech/docker/pusher.go +++ /dev/null @@ -1,433 +0,0 @@ -package docker - -import ( - "context" - "io" - "net/http" - "net/url" - "strings" - "time" - - "github.com/containerd/containerd/content" - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/images" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/remotes" - "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - - remoteserrors "ocm.software/ocm/api/tech/docker/errors" - "ocm.software/ocm/api/tech/docker/resolve" - "ocm.software/ocm/api/utils/accessio" -) - -func init() { - l := logrus.New() - l.Level = logrus.WarnLevel - log.L = logrus.NewEntry(l) -} - -type dockerPusher struct { - *dockerBase - object string - - // TODO: namespace tracker - tracker StatusTracker -} - -func (p dockerPusher) Push(ctx context.Context, desc ocispec.Descriptor, src resolve.Source) (resolve.PushRequest, error) { - return p.push(ctx, desc, src, remotes.MakeRefKey(ctx, desc), false) -} - -func (p dockerPusher) push(ctx context.Context, desc ocispec.Descriptor, src resolve.Source, ref string, unavailableOnFail bool) (resolve.PushRequest, error) { - if l, ok := p.tracker.(StatusTrackLocker); ok { - l.Lock(ref) - defer l.Unlock(ref) - } - ctx, err := ContextWithRepositoryScope(ctx, p.refspec, true) - if err != nil { - return nil, err - } - status, err := p.tracker.GetStatus(ref) - if err == nil { - if status.Committed && status.Offset == status.Total { - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "ref %v", ref) - } - if unavailableOnFail { - // Another push of this ref is happening elsewhere. The rest of function - // will continue only when `errdefs.IsNotFound(err) == true` (i.e. there - // is no actively-tracked ref already). - return nil, errors.Wrap(errdefs.ErrUnavailable, "push is on-going") - } - // TODO: Handle incomplete status - } else if !errdefs.IsNotFound(err) { - return nil, errors.Wrap(err, "failed to get status") - } - - hosts := p.filterHosts(HostCapabilityPush) - if len(hosts) == 0 { - return nil, errors.Wrap(errdefs.ErrNotFound, "no push hosts") - } - - var ( - isManifest bool - existCheck []string - host = hosts[0] - ) - - switch desc.MediaType { - case images.MediaTypeDockerSchema2Manifest, images.MediaTypeDockerSchema2ManifestList, - ocispec.MediaTypeImageManifest, ocispec.MediaTypeImageIndex: - isManifest = true - existCheck = getManifestPath(p.object, desc.Digest) - default: - existCheck = []string{"blobs", desc.Digest.String()} - } - - req := p.request(host, http.MethodHead, existCheck...) - req.header.Set("Accept", strings.Join([]string{desc.MediaType, `*/*`}, ", ")) - - log.G(ctx).WithField("url", req.String()).Debugf("checking and pushing to") - - headResp, err := req.doWithRetries(ctx, nil) - if err != nil { - if !errors.Is(err, ErrInvalidAuthorization) { - return nil, err - } - log.G(ctx).WithError(err).Debugf("Unable to check existence, continuing with push") - } else { - defer headResp.Body.Close() - - if headResp.StatusCode == http.StatusOK { - var exists bool - if isManifest && existCheck[1] != desc.Digest.String() { - dgstHeader := digest.Digest(headResp.Header.Get("Docker-Content-Digest")) - if dgstHeader == desc.Digest { - exists = true - } - } else { - exists = true - } - - if exists { - p.tracker.SetStatus(ref, Status{ - Committed: true, - Status: content.Status{ - Ref: ref, - Total: desc.Size, - Offset: desc.Size, - // TODO: Set updated time? - }, - }) - - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest) - } - } else if headResp.StatusCode != http.StatusNotFound { - err := remoteserrors.NewUnexpectedStatusErr(headResp) - - var statusError remoteserrors.ErrUnexpectedStatus - if errors.As(err, &statusError) { - log.G(ctx). - WithField("resp", headResp). - WithField("body", string(statusError.Body)). - Debug("unexpected response") - } - - return nil, accessio.RetriableError(err) - } - } - - if isManifest { - putPath := getManifestPath(p.object, desc.Digest) - req = p.request(host, http.MethodPut, putPath...) - req.header.Add("Content-Type", desc.MediaType) - } else { - // Start upload request - req = p.request(host, http.MethodPost, "blobs", "uploads/") - - var resp *http.Response - if fromRepo := selectRepositoryMountCandidate(p.refspec, desc.Annotations); fromRepo != "" { - preq := requestWithMountFrom(req, desc.Digest.String(), fromRepo) - pctx := ContextWithAppendPullRepositoryScope(ctx, fromRepo) - - // NOTE: the fromRepo might be private repo and - // auth service still can grant token without error. - // but the post request will fail because of 401. - // - // for the private repo, we should remove mount-from - // query and send the request again. - resp, err = preq.doWithRetries(pctx, nil) - if err != nil { - return nil, accessio.RetriableError(err) - } - - if resp.StatusCode == http.StatusUnauthorized { - log.G(ctx).Debugf("failed to mount from repository %s", fromRepo) - - resp.Body.Close() - resp = nil - } - } - - if resp == nil { - resp, err = req.doWithRetries(ctx, nil) - if err != nil { - return nil, accessio.RetriableError(err) - } - } - defer resp.Body.Close() - - switch resp.StatusCode { - case http.StatusOK, http.StatusAccepted, http.StatusNoContent: - case http.StatusCreated: - p.tracker.SetStatus(ref, Status{ - Committed: true, - Status: content.Status{ - Ref: ref, - Total: desc.Size, - Offset: desc.Size, - }, - }) - return nil, errors.Wrapf(errdefs.ErrAlreadyExists, "content %v on remote", desc.Digest) - default: - err := remoteserrors.NewUnexpectedStatusErr(resp) - - var statusError remoteserrors.ErrUnexpectedStatus - if errors.As(err, &statusError) { - log.G(ctx). - WithField("resp", resp). - WithField("body", string(statusError.Body)). - Debug("unexpected response") - } - - return nil, err - } - - var ( - location = resp.Header.Get("Location") - lurl *url.URL - lhost = host - ) - // Support paths without host in location - if strings.HasPrefix(location, "/") { - lurl, err = url.Parse(lhost.Scheme + "://" + lhost.Host + location) - if err != nil { - return nil, errors.Wrapf(err, "unable to parse location %v", location) - } - } else { - if !strings.Contains(location, "://") { - location = lhost.Scheme + "://" + location - } - lurl, err = url.Parse(location) - if err != nil { - return nil, errors.Wrapf(err, "unable to parse location %v", location) - } - - if lurl.Host != lhost.Host || lhost.Scheme != lurl.Scheme { - lhost.Scheme = lurl.Scheme - lhost.Host = lurl.Host - log.G(ctx).WithField("host", lhost.Host).WithField("scheme", lhost.Scheme).Debug("upload changed destination") - - // Strip authorizer if change to host or scheme - lhost.Authorizer = nil - } - } - q := lurl.Query() - q.Add("digest", desc.Digest.String()) - - req = p.request(lhost, http.MethodPut) - req.header.Set("Content-Type", "application/octet-stream") - req.path = lurl.Path + "?" + q.Encode() - } - p.tracker.SetStatus(ref, Status{ - Status: content.Status{ - Ref: ref, - Total: desc.Size, - Expected: desc.Digest, - StartedAt: time.Now(), - }, - }) - - // TODO: Support chunked upload - - respC := make(chan response, 1) - - preq := &pushRequest{ - base: p.dockerBase, - ref: ref, - responseC: respC, - source: src, - isManifest: isManifest, - expected: desc.Digest, - tracker: p.tracker, - } - - req.body = preq.Reader - req.size = desc.Size - - go func() { - defer close(respC) - resp, err := req.doWithRetries(ctx, nil) - if err != nil { - respC <- response{err: err} - return - } - - switch resp.StatusCode { - case http.StatusOK, http.StatusCreated, http.StatusNoContent: - default: - err := remoteserrors.NewUnexpectedStatusErr(resp) - - var statusError remoteserrors.ErrUnexpectedStatus - if errors.As(err, &statusError) { - log.G(ctx). - WithField("resp", resp). - WithField("body", string(statusError.Body)). - Debug("unexpected response") - } - } - respC <- response{Response: resp} - }() - - return preq, nil -} - -func getManifestPath(object string, dgst digest.Digest) []string { - if i := strings.IndexByte(object, '@'); i >= 0 { - if object[i+1:] != dgst.String() { - // use digest, not tag - object = "" - } else { - // strip @ for registry path to make tag - object = object[:i] - } - } - - if object == "" { - return []string{"manifests", dgst.String()} - } - - return []string{"manifests", object} -} - -type response struct { - *http.Response - err error -} - -type pushRequest struct { - base *dockerBase - ref string - - responseC <-chan response - source resolve.Source - isManifest bool - - expected digest.Digest - tracker StatusTracker -} - -func (pw *pushRequest) Status() (content.Status, error) { - status, err := pw.tracker.GetStatus(pw.ref) - if err != nil { - return content.Status{}, err - } - return status.Status, nil -} - -func (pw *pushRequest) Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error { - // TODO: timeout waiting for response - resp := <-pw.responseC - if resp.err != nil { - return resp.err - } - defer resp.Response.Body.Close() - - // 201 is specified return status, some registries return - // 200, 202 or 204. - switch resp.StatusCode { - case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted: - default: - return remoteserrors.NewUnexpectedStatusErr(resp.Response) - } - - status, err := pw.tracker.GetStatus(pw.ref) - if err != nil { - return errors.Wrap(err, "failed to get status") - } - - if size > 0 && size != status.Offset { - return errors.Errorf("unexpected size %d, expected %d", status.Offset, size) - } - - if expected == "" { - expected = status.Expected - } - - actual, err := digest.Parse(resp.Header.Get("Docker-Content-Digest")) - if err != nil { - return errors.Wrap(err, "invalid content digest in response") - } - - if actual != expected { - return errors.Errorf("got digest %s, expected %s", actual, expected) - } - - status.Committed = true - status.UpdatedAt = time.Now() - pw.tracker.SetStatus(pw.ref, status) - - return nil -} - -func (pw *pushRequest) Reader() (io.ReadCloser, error) { - status, err := pw.tracker.GetStatus(pw.ref) - if err != nil { - return nil, err - } - status.Offset = 0 - status.UpdatedAt = time.Now() - pw.tracker.SetStatus(pw.ref, status) - - r, err := pw.source.Reader() - if err != nil { - return nil, err - } - return &sizeTrackingReader{pw, r}, nil -} - -type sizeTrackingReader struct { - pw *pushRequest - io.ReadCloser -} - -func (t *sizeTrackingReader) Read(in []byte) (int, error) { - // fmt.Printf("reading next...\n") - n, err := t.ReadCloser.Read(in) - if n > 0 { - status, err := t.pw.tracker.GetStatus(t.pw.ref) - // fmt.Printf("read %d[%d] bytes\n", n, status.Offset) - if err != nil { - return n, err - } - status.Offset += int64(n) - status.UpdatedAt = time.Now() - t.pw.tracker.SetStatus(t.pw.ref, status) - } - return n, err -} - -func requestWithMountFrom(req *request, mount, from string) *request { - creq := *req - - sep := "?" - if strings.Contains(creq.path, sep) { - sep = "&" - } - - creq.path = creq.path + sep + "mount=" + mount + "&from=" + from - - return &creq -} diff --git a/api/tech/docker/registry.go b/api/tech/docker/registry.go deleted file mode 100644 index 795dd6e244..0000000000 --- a/api/tech/docker/registry.go +++ /dev/null @@ -1,234 +0,0 @@ -package docker - -import ( - "net" - "net/http" - - "github.com/pkg/errors" -) - -// HostCapabilities represent the capabilities of the registry -// host. This also represents the set of operations for which -// the registry host may be trusted to perform. -// -// For example pushing is a capability which should only be -// performed on an upstream source, not a mirror. -// Resolving (the process of converting a name into a digest) -// must be considered a trusted operation and only done by -// a host which is trusted (or more preferably by secure process -// which can prove the provenance of the mapping). A public -// mirror should never be trusted to do a resolve action. -// -// | Registry Type | Pull | Resolve | Push | -// |------------------|------|---------|------| -// | Public Registry | yes | yes | yes | -// | Private Registry | yes | yes | yes | -// | Public Mirror | yes | no | no | -// | Private Mirror | yes | yes | no |. -type HostCapabilities uint8 - -const ( - // HostCapabilityPull represents the capability to fetch manifests - // and blobs by digest. - HostCapabilityPull HostCapabilities = 1 << iota - - // HostCapabilityResolve represents the capability to fetch manifests - // by name. - HostCapabilityResolve - - // HostCapabilityPush represents the capability to push blobs and - // manifests. - HostCapabilityPush - - // Reserved for future capabilities (i.e. search, catalog, remove). -) - -// Has checks whether the capabilities list has the provide capability. -func (c HostCapabilities) Has(t HostCapabilities) bool { - return c&t == t -} - -// RegistryHost represents a complete configuration for a registry -// host, representing the capabilities, authorizations, connection -// configuration, and location. -type RegistryHost struct { - Client *http.Client - Authorizer Authorizer - Host string - Scheme string - Path string - Capabilities HostCapabilities - Header http.Header -} - -const ( - dockerHostname = "docker.io" - dockerRegistryHostname = "registry-1.docker.io" -) - -func (h RegistryHost) isProxy(refhost string) bool { - if refhost != h.Host { - if refhost != dockerHostname || h.Host != dockerRegistryHostname { - return true - } - } - return false -} - -// RegistryHosts fetches the registry hosts for a given namespace, -// provided by the host component of an distribution image reference. -type RegistryHosts func(string) ([]RegistryHost, error) - -// Registries joins multiple registry configuration functions, using the same -// order as provided within the arguments. When an empty registry configuration -// is returned with a nil error, the next function will be called. -// NOTE: This function will not join configurations, as soon as a non-empty -// configuration is returned from a configuration function, it will be returned -// to the caller. -func Registries(registries ...RegistryHosts) RegistryHosts { - return func(host string) ([]RegistryHost, error) { - for _, registry := range registries { - config, err := registry(host) - if err != nil { - return config, err - } - if len(config) > 0 { - return config, nil - } - } - return nil, nil - } -} - -type registryOpts struct { - authorizer Authorizer - plainHTTP func(string) (bool, error) - host func(string) (string, error) - client *http.Client -} - -// RegistryOpt defines a registry default option. -type RegistryOpt func(*registryOpts) - -// WithPlainHTTP configures registries to use plaintext http scheme -// for the provided host match function. -func WithPlainHTTP(f func(string) (bool, error)) RegistryOpt { - return func(opts *registryOpts) { - opts.plainHTTP = f - } -} - -// WithAuthorizer configures the default authorizer for a registry. -func WithAuthorizer(a Authorizer) RegistryOpt { - return func(opts *registryOpts) { - opts.authorizer = a - } -} - -// WithHostTranslator defines the default translator to use for registry hosts. -func WithHostTranslator(h func(string) (string, error)) RegistryOpt { - return func(opts *registryOpts) { - opts.host = h - } -} - -// WithClient configures the default http client for a registry. -func WithClient(c *http.Client) RegistryOpt { - return func(opts *registryOpts) { - opts.client = c - } -} - -// ConfigureDefaultRegistries is used to create a default configuration for -// registries. For more advanced configurations or per-domain setups, -// the RegistryHosts interface should be used directly. -// NOTE: This function will always return a non-empty value or error. -func ConfigureDefaultRegistries(ropts ...RegistryOpt) RegistryHosts { - var opts registryOpts - for _, opt := range ropts { - opt(&opts) - } - - return func(host string) ([]RegistryHost, error) { - config := RegistryHost{ - Client: opts.client, - Authorizer: opts.authorizer, - Host: host, - Scheme: "https", - Path: "/v2", - Capabilities: HostCapabilityPull | HostCapabilityResolve | HostCapabilityPush, - } - - if config.Client == nil { - config.Client = http.DefaultClient - } - - if opts.plainHTTP != nil { - match, err := opts.plainHTTP(host) - if err != nil { - return nil, err - } - if match { - config.Scheme = "http" - } - } - - if opts.host != nil { - var err error - config.Host, err = opts.host(config.Host) - if err != nil { - return nil, err - } - } else if host == dockerHostname { - config.Host = dockerRegistryHostname - } - - return []RegistryHost{config}, nil - } -} - -// MatchAllHosts is a host match function which is always true. -func MatchAllHosts(string) (bool, error) { - return true, nil -} - -// MatchLocalhost is a host match function which returns true for -// localhost. -// -// Note: this does not handle matching of ip addresses in octal, -// decimal or hex form. -func MatchLocalhost(host string) (bool, error) { - switch { - case host == "::1": - return true, nil - case host == "[::1]": - return true, nil - } - h, p, err := net.SplitHostPort(host) - - // addrError helps distinguish between errors of form - // "no colon in address" and "too many colons in address". - // The former is fine as the host string need not have a - // port. Latter needs to be handled. - addrError := &net.AddrError{ - Err: "missing port in address", - Addr: host, - } - if err != nil { - if err.Error() != addrError.Error() { - return false, err - } - // host string without any port specified - h = host - } else if len(p) == 0 { - return false, errors.New("invalid host name format") - } - - // use ipv4 dotted decimal for further checking - if h == "localhost" { - h = "127.0.0.1" - } - ip := net.ParseIP(h) - - return ip.IsLoopback(), nil -} diff --git a/api/tech/docker/resolver.go b/api/tech/docker/resolver.go deleted file mode 100644 index 292df03ae3..0000000000 --- a/api/tech/docker/resolver.go +++ /dev/null @@ -1,656 +0,0 @@ -package docker - -import ( - "context" - "fmt" - "io" - "net/http" - "net/url" - "path" - "strings" - - "github.com/containerd/containerd/errdefs" - "github.com/containerd/containerd/images" - "github.com/containerd/containerd/log" - "github.com/containerd/containerd/reference" - "github.com/containerd/containerd/remotes/docker/schema1" - "github.com/containerd/containerd/version" - "github.com/opencontainers/go-digest" - ocispec "github.com/opencontainers/image-spec/specs-go/v1" - "github.com/pkg/errors" - "github.com/sirupsen/logrus" - "golang.org/x/net/context/ctxhttp" - - "ocm.software/ocm/api/tech/docker/resolve" - "ocm.software/ocm/api/utils/accessio" -) - -var ( - // ErrInvalidAuthorization is used when credentials are passed to a server but - // those credentials are rejected. - ErrInvalidAuthorization = errors.New("authorization failed") - - // MaxManifestSize represents the largest size accepted from a registry - // during resolution. Larger manifests may be accepted using a - // resolution method other than the registry. - // - // NOTE: The max supported layers by some runtimes is 128 and individual - // layers will not contribute more than 256 bytes, making a - // reasonable limit for a large image manifests of 32K bytes. - // 4M bytes represents a much larger upper bound for images which may - // contain large annotations or be non-images. A proper manifest - // design puts large metadata in subobjects, as is consistent the - // intent of the manifest design. - MaxManifestSize int64 = 4 * 1048 * 1048 -) - -// Authorizer is used to authorize HTTP requests based on 401 HTTP responses. -// An Authorizer is responsible for caching tokens or credentials used by -// requests. -type Authorizer interface { - // Authorize sets the appropriate `Authorization` header on the given - // request. - // - // If no authorization is found for the request, the request remains - // unmodified. It may also add an `Authorization` header as - // "bearer " - // "basic " - Authorize(context.Context, *http.Request) error - - // AddResponses adds a 401 response for the authorizer to consider when - // authorizing requests. The last response should be unauthorized and - // the previous requests are used to consider redirects and retries - // that may have led to the 401. - // - // If response is not handled, returns `ErrNotImplemented` - AddResponses(context.Context, []*http.Response) error -} - -// ResolverOptions are used to configured a new Docker register resolver. -type ResolverOptions struct { - // Hosts returns registry host configurations for a namespace. - Hosts RegistryHosts - - // Headers are the HTTP request header fields sent by the resolver - Headers http.Header - - // Tracker is used to track uploads to the registry. This is used - // since the registry does not have upload tracking and the existing - // mechanism for getting blob upload status is expensive. - Tracker StatusTracker - - // Authorizer is used to authorize registry requests - // Deprecated: use Hosts - Authorizer Authorizer - - // Credentials provides username and secret given a host. - // If username is empty but a secret is given, that secret - // is interpreted as a long lived token. - // Deprecated: use Hosts - Credentials func(string) (string, string, error) - - // Host provides the hostname given a namespace. - // Deprecated: use Hosts - Host func(string) (string, error) - - // PlainHTTP specifies to use plain http and not https - // Deprecated: use Hosts - PlainHTTP bool - - // Client is the http client to used when making registry requests - // Deprecated: use Hosts - Client *http.Client -} - -// DefaultHost is the default host function. -func DefaultHost(ns string) (string, error) { - if ns == "docker.io" { - return "registry-1.docker.io", nil - } - return ns, nil -} - -type dockerResolver struct { - hosts RegistryHosts - header http.Header - resolveHeader http.Header - tracker StatusTracker -} - -// NewResolver returns a new resolver to a Docker registry. -func NewResolver(options ResolverOptions) resolve.Resolver { - if options.Tracker == nil { - options.Tracker = NewInMemoryTracker() - } - - if options.Headers == nil { - options.Headers = make(http.Header) - } - if _, ok := options.Headers["User-Agent"]; !ok { - options.Headers.Set("User-Agent", "containerd/"+version.Version) - } - - resolveHeader := http.Header{} - if _, ok := options.Headers["Accept"]; !ok { - // set headers for all the types we support for resolution. - resolveHeader.Set("Accept", strings.Join([]string{ - images.MediaTypeDockerSchema2Manifest, - images.MediaTypeDockerSchema2ManifestList, - ocispec.MediaTypeImageManifest, - ocispec.MediaTypeImageIndex, "*/*", - }, ", ")) - } else { - resolveHeader["Accept"] = options.Headers["Accept"] - delete(options.Headers, "Accept") - } - - if options.Hosts == nil { - opts := []RegistryOpt{} - if options.Host != nil { - opts = append(opts, WithHostTranslator(options.Host)) - } - - if options.Authorizer == nil { - options.Authorizer = NewDockerAuthorizer( - WithAuthClient(options.Client), - WithAuthHeader(options.Headers), - WithAuthCreds(options.Credentials)) - } - opts = append(opts, WithAuthorizer(options.Authorizer)) - - if options.Client != nil { - opts = append(opts, WithClient(options.Client)) - } - if options.PlainHTTP { - opts = append(opts, WithPlainHTTP(MatchAllHosts)) - } else { - opts = append(opts, WithPlainHTTP(MatchLocalhost)) - } - options.Hosts = ConfigureDefaultRegistries(opts...) - } - return &dockerResolver{ - hosts: options.Hosts, - header: options.Headers, - resolveHeader: resolveHeader, - tracker: options.Tracker, - } -} - -func getManifestMediaType(resp *http.Response) string { - // Strip encoding data (manifests should always be ascii JSON) - contentType := resp.Header.Get("Content-Type") - if sp := strings.IndexByte(contentType, ';'); sp != -1 { - contentType = contentType[0:sp] - } - - // As of Apr 30 2019 the registry.access.redhat.com registry does not specify - // the content type of any data but uses schema1 manifests. - if contentType == "text/plain" { - contentType = images.MediaTypeDockerSchema1Manifest - } - return contentType -} - -type countingReader struct { - reader io.Reader - bytesRead int64 -} - -func (r *countingReader) Read(p []byte) (int, error) { - n, err := r.reader.Read(p) - r.bytesRead += int64(n) - return n, err -} - -var _ resolve.Resolver = &dockerResolver{} - -func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocispec.Descriptor, error) { - base, err := r.resolveDockerBase(ref) - if err != nil { - return "", ocispec.Descriptor{}, err - } - refspec := base.refspec - if refspec.Object == "" { - return "", ocispec.Descriptor{}, reference.ErrObjectRequired - } - - var ( - firstErr error - paths [][]string - dgst = refspec.Digest() - caps = HostCapabilityPull - ) - - if dgst != "" { - if err := dgst.Validate(); err != nil { - // need to fail here, since we can't actually resolve the invalid - // digest. - return "", ocispec.Descriptor{}, err - } - - // turns out, we have a valid digest, make a url. - paths = append(paths, []string{"manifests", dgst.String()}) - - // fallback to blobs on not found. - paths = append(paths, []string{"blobs", dgst.String()}) - } else { - // Add - paths = append(paths, []string{"manifests", refspec.Object}) - caps |= HostCapabilityResolve - } - - hosts := base.filterHosts(caps) - if len(hosts) == 0 { - return "", ocispec.Descriptor{}, errors.Wrap(errdefs.ErrNotFound, "no resolve hosts") - } - - ctx, err = ContextWithRepositoryScope(ctx, refspec, false) - if err != nil { - return "", ocispec.Descriptor{}, err - } - - for _, u := range paths { - for _, host := range hosts { - ctxWithLogger := log.WithLogger(ctx, log.G(ctx).WithField("host", host.Host)) - - req := base.request(host, http.MethodHead, u...) - if err := req.addNamespace(base.refspec.Hostname()); err != nil { - return "", ocispec.Descriptor{}, err - } - - for key, value := range r.resolveHeader { - req.header[key] = append(req.header[key], value...) - } - - log.G(ctxWithLogger).Debug("resolving") - resp, err := req.doWithRetries(ctxWithLogger, nil) - if err != nil { - if errors.Is(err, ErrInvalidAuthorization) { - err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") - } else { - err = accessio.RetriableError(err) - } - // Store the error for referencing later - if firstErr == nil { - firstErr = err - } - log.G(ctxWithLogger).WithError(err).Info("trying next host") - continue // try another host - } - resp.Body.Close() // don't care about body contents. - - if resp.StatusCode > 299 { - if resp.StatusCode == http.StatusNotFound { - // log.G(ctxWithLogger).Info("trying next host - response was http.StatusNotFound") - continue - } - if resp.StatusCode > 399 { - // Set firstErr when encountering the first non-404 status code. - if firstErr == nil { - firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status) - } - continue // try another host - } - return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status) - } - size := resp.ContentLength - contentType := getManifestMediaType(resp) - - // if no digest was provided, then only a resolve - // trusted registry was contacted, in this case use - // the digest header (or content from GET) - if dgst == "" { - // this is the only point at which we trust the registry. we use the - // content headers to assemble a descriptor for the name. when this becomes - // more robust, we mostly get this information from a secure trust store. - dgstHeader := digest.Digest(resp.Header.Get("Docker-Content-Digest")) - - if dgstHeader != "" && size != -1 { - if err := dgstHeader.Validate(); err != nil { - return "", ocispec.Descriptor{}, errors.Wrapf(err, "%q in header not a valid digest", dgstHeader) - } - dgst = dgstHeader - } - } - if dgst == "" || size == -1 { - log.G(ctxWithLogger).Debug("no Docker-Content-Digest header, fetching manifest instead") - - req = base.request(host, http.MethodGet, u...) - if err := req.addNamespace(base.refspec.Hostname()); err != nil { - return "", ocispec.Descriptor{}, err - } - - for key, value := range r.resolveHeader { - req.header[key] = append(req.header[key], value...) - } - - resp, err := req.doWithRetries(ctxWithLogger, nil) - if err != nil { - return "", ocispec.Descriptor{}, accessio.RetriableError(err) - } - defer resp.Body.Close() - - bodyReader := countingReader{reader: resp.Body} - - contentType = getManifestMediaType(resp) - if dgst == "" { - if contentType == images.MediaTypeDockerSchema1Manifest { - b, err := schema1.ReadStripSignature(&bodyReader) - if err != nil { - return "", ocispec.Descriptor{}, accessio.RetriableError(err) - } - - dgst = digest.FromBytes(b) - } else { - dgst, err = digest.FromReader(&bodyReader) - if err != nil { - return "", ocispec.Descriptor{}, accessio.RetriableError(err) - } - } - } else if _, err := io.Copy(io.Discard, &bodyReader); err != nil { - return "", ocispec.Descriptor{}, accessio.RetriableError(err) - } - size = bodyReader.bytesRead - } - // Prevent resolving to excessively large manifests - if size > MaxManifestSize { - if firstErr == nil { - firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref) - } - continue - } - - desc := ocispec.Descriptor{ - Digest: dgst, - MediaType: contentType, - Size: size, - } - - log.G(ctxWithLogger).WithField("desc.digest", desc.Digest).Debug("resolved") - return ref, desc, nil - } - } - - // If above loop terminates without return, then there was an error. - // "firstErr" contains the first non-404 error. That is, "firstErr == nil" - // means that either no registries were given or each registry returned 404. - - if firstErr == nil { - firstErr = errors.Wrap(errdefs.ErrNotFound, ref) - } - - return "", ocispec.Descriptor{}, firstErr -} - -func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (resolve.Fetcher, error) { - base, err := r.resolveDockerBase(ref) - if err != nil { - return nil, err - } - - return dockerFetcher{ - dockerBase: base, - }, nil -} - -func (r *dockerResolver) Pusher(ctx context.Context, ref string) (resolve.Pusher, error) { - base, err := r.resolveDockerBase(ref) - if err != nil { - return nil, err - } - - return dockerPusher{ - dockerBase: base, - object: base.refspec.Object, - tracker: r.tracker, - }, nil -} - -func (r *dockerResolver) resolveDockerBase(ref string) (*dockerBase, error) { - refspec, err := reference.Parse(ref) - if err != nil { - return nil, err - } - - return r.base(refspec) -} - -type dockerBase struct { - refspec reference.Spec - repository string - hosts []RegistryHost - header http.Header -} - -func (r *dockerResolver) base(refspec reference.Spec) (*dockerBase, error) { - host := refspec.Hostname() - hosts, err := r.hosts(host) - if err != nil { - return nil, err - } - return &dockerBase{ - refspec: refspec, - repository: strings.TrimPrefix(refspec.Locator, host+"/"), - hosts: hosts, - header: r.header, - }, nil -} - -func (r *dockerBase) filterHosts(caps HostCapabilities) (hosts []RegistryHost) { - for _, host := range r.hosts { - if host.Capabilities.Has(caps) { - hosts = append(hosts, host) - } - } - return -} - -func (r *dockerBase) request(host RegistryHost, method string, ps ...string) *request { - header := r.header.Clone() - if header == nil { - header = http.Header{} - } - - for key, value := range host.Header { - header[key] = append(header[key], value...) - } - parts := append([]string{"/", host.Path, r.repository}, ps...) - p := path.Join(parts...) - // Join strips trailing slash, re-add ending "/" if included - if len(parts) > 0 && strings.HasSuffix(parts[len(parts)-1], "/") { - p += "/" - } - return &request{ - method: method, - path: p, - header: header, - host: host, - } -} - -func (r *request) authorize(ctx context.Context, req *http.Request) error { - // Check if has header for host - if r.host.Authorizer != nil { - if err := r.host.Authorizer.Authorize(ctx, req); err != nil { - return err - } - } - - return nil -} - -func (r *request) addNamespace(ns string) (err error) { - if !r.host.isProxy(ns) { - return nil - } - var q url.Values - // Parse query - if i := strings.IndexByte(r.path, '?'); i > 0 { - r.path = r.path[:i+1] - q, err = url.ParseQuery(r.path[i+1:]) - if err != nil { - return - } - } else { - r.path += "?" - q = url.Values{} - } - q.Add("ns", ns) - - r.path += q.Encode() - - return -} - -type request struct { - method string - path string - header http.Header - host RegistryHost - body func() (io.ReadCloser, error) - size int64 -} - -func (r *request) do(ctx context.Context) (*http.Response, error) { - u := r.host.Scheme + "://" + r.host.Host + r.path - req, err := http.NewRequestWithContext(ctx, r.method, u, nil) - if err != nil { - return nil, err - } - req.Header = http.Header{} // headers need to be copied to avoid concurrent map access - for k, v := range r.header { - req.Header[k] = v - } - if r.body != nil { - body, err := r.body() - if err != nil { - return nil, err - } - req.Body = body - req.GetBody = r.body - if r.size > 0 { - req.ContentLength = r.size - } - defer body.Close() - } - - ctx = log.WithLogger(ctx, log.G(ctx).WithField("url", u)) - log.G(ctx).WithFields(sanitizedRequestFields(req)).Debug("do request") - if err := r.authorize(ctx, req); err != nil { - return nil, errors.Wrap(err, "failed to authorize") - } - - client := &http.Client{} - if r.host.Client != nil { - *client = *r.host.Client - } - if client.CheckRedirect == nil { - client.CheckRedirect = func(req *http.Request, via []*http.Request) error { - if len(via) >= 10 { - return errors.New("stopped after 10 redirects") - } - return errors.Wrap(r.authorize(ctx, req), "failed to authorize redirect") - } - } - - resp, err := ctxhttp.Do(ctx, client, req) - if err != nil { - return nil, errors.Wrap(err, "failed to do request") - } - log.G(ctx).WithFields(responseFields(resp)).Debug("fetch response received") - return resp, nil -} - -func (r *request) doWithRetries(ctx context.Context, responses []*http.Response) (*http.Response, error) { - resp, err := r.do(ctx) - if err != nil { - return nil, err - } - - responses = append(responses, resp) - retry, err := r.retryRequest(ctx, responses) - if err != nil { - resp.Body.Close() - return nil, err - } - if retry { - resp.Body.Close() - return r.doWithRetries(ctx, responses) - } - return resp, err -} - -func (r *request) retryRequest(ctx context.Context, responses []*http.Response) (bool, error) { - if len(responses) > 5 { - return false, nil - } - last := responses[len(responses)-1] - switch last.StatusCode { - case http.StatusUnauthorized: - log.G(ctx).WithField("header", last.Header.Get("WWW-Authenticate")).Debug("Unauthorized") - if r.host.Authorizer != nil { - if err := r.host.Authorizer.AddResponses(ctx, responses); err == nil { - return true, nil - } else if !errdefs.IsNotImplemented(err) { - return false, err - } - } - - return false, nil - case http.StatusMethodNotAllowed: - // Support registries which have not properly implemented the HEAD method for - // manifests endpoint - if r.method == http.MethodHead && strings.Contains(r.path, "/manifests/") { - r.method = http.MethodGet - return true, nil - } - case http.StatusRequestTimeout, http.StatusTooManyRequests: - return true, nil - } - - // TODO: Handle 50x errors accounting for attempt history - return false, nil -} - -func (r *request) String() string { - return r.host.Scheme + "://" + r.host.Host + r.path -} - -func sanitizedRequestFields(req *http.Request) logrus.Fields { - fields := map[string]interface{}{ - "request.method": req.Method, - } - for k, vals := range req.Header { - k = strings.ToLower(k) - if k == "authorization" { - continue - } - for i, v := range vals { - field := "request.header." + k - if i > 0 { - field = fmt.Sprintf("%s.%d", field, i) - } - fields[field] = v - } - } - - return logrus.Fields(fields) -} - -func responseFields(resp *http.Response) logrus.Fields { - fields := map[string]interface{}{ - "response.status": resp.Status, - } - for k, vals := range resp.Header { - k = strings.ToLower(k) - for i, v := range vals { - field := "response.header." + k - if i > 0 { - field = fmt.Sprintf("%s.%d", field, i) - } - fields[field] = v - } - } - - return logrus.Fields(fields) -} diff --git a/api/tech/oras/client.go b/api/tech/oras/client.go new file mode 100644 index 0000000000..a73e0003a9 --- /dev/null +++ b/api/tech/oras/client.go @@ -0,0 +1,201 @@ +package oras + +import ( + "context" + "errors" + "fmt" + "io" + "strings" + "sync" + + "github.com/containerd/containerd/errdefs" + ociv1 "github.com/opencontainers/image-spec/specs-go/v1" + oraserr "oras.land/oras-go/v2/errdef" + "oras.land/oras-go/v2/registry/remote" + "oras.land/oras-go/v2/registry/remote/auth" +) + +type ClientOptions struct { + Client *auth.Client + PlainHTTP bool +} + +type Client struct { + client *auth.Client + plainHTTP bool + ref string + mu sync.RWMutex +} + +var ( + _ Resolver = &Client{} + _ Fetcher = &Client{} + _ Pusher = &Client{} + _ Lister = &Client{} +) + +func New(opts ClientOptions) *Client { + return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP} +} + +func (c *Client) Fetcher(ctx context.Context, ref string) (Fetcher, error) { + c.mu.Lock() + defer c.mu.Unlock() + + c.ref = ref + return c, nil +} + +func (c *Client) Pusher(ctx context.Context, ref string) (Pusher, error) { + c.mu.Lock() + defer c.mu.Unlock() + + c.ref = ref + return c, nil +} + +func (c *Client) Lister(ctx context.Context, ref string) (Lister, error) { + c.mu.Lock() + defer c.mu.Unlock() + + c.ref = ref + return c, nil +} + +func (c *Client) Resolve(ctx context.Context, ref string) (string, ociv1.Descriptor, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + src, err := c.createRepository(ref) + if err != nil { + return "", ociv1.Descriptor{}, err + } + + // We try to first resolve a manifest. + // _Note_: If there is an error like not found, but we know that the digest exists + // we can add src.Blobs().Resolve in here. If we do that, note that + // for Blobs().Resolve `not found` is actually `invalid checksum digest format`. + // Meaning it will throw that error instead of not found. + desc, err := src.Resolve(ctx, ref) + if err != nil { + if errors.Is(err, oraserr.ErrNotFound) { + return "", ociv1.Descriptor{}, errdefs.ErrNotFound + } + + return "", ociv1.Descriptor{}, fmt.Errorf("failed to resolve manifest %q: %w", ref, err) + } + + return "", desc, nil +} + +func (c *Client) Push(ctx context.Context, d ociv1.Descriptor, src Source) error { + c.mu.RLock() + defer c.mu.RUnlock() + + reader, err := src.Reader() + if err != nil { + return err + } + + repository, err := c.createRepository(c.ref) + if err != nil { + return err + } + + if split := strings.Split(c.ref, ":"); len(split) == 2 { + // Once we get a reference that contains a tag, we need to re-push that + // layer with the reference included. PushReference then will tag + // that layer resulting in the created tag pointing to the right + // blob data. + if err := repository.PushReference(ctx, d, reader, c.ref); err != nil { + return fmt.Errorf("failed to push tag: %w", err) + } + + return nil + } + + // We have a digest, so we use plain push for the digest. + // Push here decides if it's a Manifest or a Blob. + if err := repository.Push(ctx, d, reader); err != nil { + return fmt.Errorf("failed to push: %w, %s", err, c.ref) + } + + return nil +} + +func (c *Client) Fetch(ctx context.Context, desc ociv1.Descriptor) (io.ReadCloser, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + src, err := c.createRepository(c.ref) + if err != nil { + return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) + } + + // oras requires a Resolve to happen before a fetch because + // -1 is an invalid size and results in a content-length mismatch error by design. + // This is a security consideration on ORAS' side. + // manifest is not set in the descriptor + // We explicitly call resolve on manifest first because it might be + // that the mediatype is not set at this point so we don't want ORAS to try to + // select the wrong layer to fetch from. + rdesc, err := src.Manifests().Resolve(ctx, desc.Digest.String()) + if errors.Is(err, oraserr.ErrNotFound) { + rdesc, err = src.Blobs().Resolve(ctx, desc.Digest.String()) + if err != nil { + return nil, fmt.Errorf("failed to resolve fetch blob %q: %w", desc.Digest.String(), err) + } + + delayer := func() (io.ReadCloser, error) { + return src.Blobs().Fetch(ctx, rdesc) + } + + return newDelayedReader(delayer) + } + + if err != nil { + return nil, fmt.Errorf("failed to resolve fetch manifest %q: %w", desc.Digest.String(), err) + } + + // lastly, try a manifest fetch. + fetch, err := src.Fetch(ctx, rdesc) + if err != nil { + return nil, fmt.Errorf("failed to fetch manifest: %w", err) + } + + return fetch, err +} + +func (c *Client) List(ctx context.Context) ([]string, error) { + c.mu.RLock() + defer c.mu.RUnlock() + + src, err := c.createRepository(c.ref) + if err != nil { + return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) + } + + var result []string + if err := src.Tags(ctx, "", func(tags []string) error { + result = append(result, tags...) + return nil + }); err != nil { + return nil, fmt.Errorf("failed to list tags: %w", err) + } + + return result, nil +} + +// createRepository creates a new repository representation using the passed in ref. +// This is a cheap operation. +func (c *Client) createRepository(ref string) (*remote.Repository, error) { + src, err := remote.NewRepository(ref) + if err != nil { + return nil, fmt.Errorf("failed to create new repository: %w", err) + } + + src.Client = c.client // set up authenticated client. + src.PlainHTTP = c.plainHTTP + + return src, nil +} diff --git a/api/tech/oras/delayed_reader.go b/api/tech/oras/delayed_reader.go new file mode 100644 index 0000000000..d07a6f870b --- /dev/null +++ b/api/tech/oras/delayed_reader.go @@ -0,0 +1,57 @@ +package oras + +import ( + "io" +) + +// delayedReader sets up a reader that only fetches a blob +// upon explicit reading request, otherwise, it stores the +// way of getting the reader. +type delayedReader struct { + open func() (io.ReadCloser, error) + rc io.ReadCloser + closed bool +} + +func newDelayedReader(open func() (io.ReadCloser, error)) (*delayedReader, error) { + return &delayedReader{ + open: open, + }, nil +} + +func (d *delayedReader) Read(p []byte) (n int, err error) { + if d.closed { + return 0, io.EOF + } + + reader, err := d.reader() + if err != nil { + return 0, err + } + + return reader.Read(p) +} + +func (d *delayedReader) reader() (io.ReadCloser, error) { + if d.rc != nil { + return d.rc, nil + } + + rc, err := d.open() + if err != nil { + return nil, err + } + + d.rc = rc + return rc, nil +} + +func (d *delayedReader) Close() error { + if d.closed { + return nil + } + + // we close regardless of an error + d.closed = true + return d.rc.Close() +} diff --git a/api/tech/docker/resolve/interface.go b/api/tech/oras/interface.go similarity index 73% rename from api/tech/docker/resolve/interface.go rename to api/tech/oras/interface.go index 8476000012..5020f68d21 100644 --- a/api/tech/docker/resolve/interface.go +++ b/api/tech/oras/interface.go @@ -1,11 +1,9 @@ -package resolve +package oras import ( "context" "io" - "github.com/containerd/containerd/content" - "github.com/opencontainers/go-digest" ocispec "github.com/opencontainers/image-spec/specs-go/v1" ) @@ -54,22 +52,9 @@ type Fetcher interface { type Pusher interface { // Push returns a push request for the given resource identified // by the descriptor and the given data source. - Push(ctx context.Context, d ocispec.Descriptor, src Source) (PushRequest, error) + Push(ctx context.Context, d ocispec.Descriptor, src Source) error } type Lister interface { List(context.Context) ([]string, error) } - -// PushRequest handles the result of a push request -// replaces containerd content.Writer. -type PushRequest interface { - // Commit commits the blob (but no roll-back is guaranteed on an error). - // size and expected can be zero-value when unknown. - // Commit always closes the writer, even on error. - // ErrAlreadyExists aborts the writer. - Commit(ctx context.Context, size int64, expected digest.Digest, opts ...content.Opt) error - - // Status returns the current state of write - Status() (content.Status, error) -} diff --git a/go.mod b/go.mod index 8c3a1bf220..10e02fada5 100644 --- a/go.mod +++ b/go.mod @@ -81,6 +81,7 @@ require ( k8s.io/apimachinery v0.32.0 k8s.io/cli-runtime v0.32.0 k8s.io/client-go v0.32.0 + oras.land/oras-go/v2 v2.5.0 sigs.k8s.io/controller-runtime v0.19.3 sigs.k8s.io/yaml v1.4.0 ) @@ -276,7 +277,6 @@ require ( github.com/opencontainers/runtime-spec v1.2.0 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pborman/uuid v1.2.1 // indirect - github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect diff --git a/go.sum b/go.sum index cb07a1b822..cfe049224b 100644 --- a/go.sum +++ b/go.sum @@ -1358,6 +1358,8 @@ k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJ k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.6 h1:z8cmxQXBU8yZ4mkytWqXfo6tZcamPwjsuxYU81xJ8Lk= oras.land/oras-go v1.2.6/go.mod h1:OVPc1PegSEe/K8YiLfosrlqlqTN9PUyFvOw5Y9gwrT8= +oras.land/oras-go/v2 v2.5.0 h1:o8Me9kLY74Vp5uw07QXPiitjsw7qNXi8Twd+19Zf02c= +oras.land/oras-go/v2 v2.5.0/go.mod h1:z4eisnLP530vwIOUOJeBIj0aGI0L1C3d53atvCBqZHg= sigs.k8s.io/controller-runtime v0.19.3 h1:XO2GvC9OPftRst6xWCpTgBZO04S2cbp0Qqkj8bX1sPw= sigs.k8s.io/controller-runtime v0.19.3/go.mod h1:j4j87DqtsThvwTv5/Tc5NFRyyF/RF0ip4+62tbTSIUM= sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE= diff --git a/hack/generate.sh b/hack/generate.sh index d574eb5828..d2e9864987 100755 --- a/hack/generate.sh +++ b/hack/generate.sh @@ -4,4 +4,4 @@ set -e echo "> Generate" -GO111MODULE=on go generate -mod=mod $@ \ No newline at end of file +GO111MODULE=on go generate -mod=mod $@ From 206d8c1e38ce9702e2eb2bfa3c20c628f972a485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Wed, 18 Dec 2024 11:09:20 +0100 Subject: [PATCH 35/50] chore: use the pull request head to run the integration tests (#1202) #### What this PR does / why we need it This will use the Pull Request Branch Reference and Repository to checkout OCM #### Which issue(s) this PR fixes --- .github/workflows/integration-test.yaml | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 384748e96c..59082e36a0 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -16,6 +16,7 @@ permissions: jobs: test: + if: github.event_name == 'push' name: Run tests uses: open-component-model/ocm-integrationtest/.github/workflows/integrationtest.yaml@main permissions: @@ -24,4 +25,17 @@ jobs: packages: write secrets: inherit with: - ref: ${{ github.ref }} \ No newline at end of file + ref: ${{ github.ref }} + repo: ${{ github.repository }} + test-pr: + if: github.event_name == 'pull_request_target' + name: Run tests + uses: open-component-model/ocm-integrationtest/.github/workflows/integrationtest.yaml@main + permissions: + contents: write + id-token: write + packages: write + secrets: inherit + with: + ref: ${{ github.event.pull_request.head.ref }} + repo: ${{ github.event.pull_request.head.repo.name }} \ No newline at end of file From 6aea1a073cb6601adebc382333efc8264a64858d Mon Sep 17 00:00:00 2001 From: jakobmoellerdev Date: Wed, 18 Dec 2024 11:25:28 +0100 Subject: [PATCH 36/50] chore: use correct field name for pr ref --- .github/workflows/integration-test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/integration-test.yaml b/.github/workflows/integration-test.yaml index 59082e36a0..3878286ea5 100644 --- a/.github/workflows/integration-test.yaml +++ b/.github/workflows/integration-test.yaml @@ -38,4 +38,4 @@ jobs: secrets: inherit with: ref: ${{ github.event.pull_request.head.ref }} - repo: ${{ github.event.pull_request.head.repo.name }} \ No newline at end of file + repo: ${{ github.event.pull_request.head.repo.full_name }} \ No newline at end of file From f9c1e276593517250f116aec5fcedb4ac826e498 Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Thu, 19 Dec 2024 12:25:43 +0100 Subject: [PATCH 37/50] fix: deal with internal error coming from docker registry (#1203) #### What this PR does / why we need it #### Which issue(s) this PR fixes --------- Co-authored-by: jakobmoellerdev --- .../repositories/ocireg/repository.go | 13 +- api/tech/oras/client.go | 144 ++---------------- api/tech/oras/delayed_reader.go | 57 ------- api/tech/oras/fetcher.go | 64 ++++++++ api/tech/oras/lister.go | 31 ++++ api/tech/oras/pusher.go | 70 +++++++++ 6 files changed, 187 insertions(+), 192 deletions(-) delete mode 100644 api/tech/oras/delayed_reader.go create mode 100644 api/tech/oras/fetcher.go create mode 100644 api/tech/oras/lister.go create mode 100644 api/tech/oras/pusher.go diff --git a/api/oci/extensions/repositories/ocireg/repository.go b/api/oci/extensions/repositories/ocireg/repository.go index 1f1ede981a..9393cbffa7 100644 --- a/api/oci/extensions/repositories/ocireg/repository.go +++ b/api/oci/extensions/repositories/ocireg/repository.go @@ -164,14 +164,21 @@ func (r *RepositoryImpl) getResolver(comp string) (oras.Resolver, error) { } authClient := &auth.Client{ - Client: client, - Cache: auth.NewCache(), - Credential: auth.StaticCredential(r.info.HostPort(), authCreds), + Client: client, + Cache: auth.NewCache(), + Credential: auth.CredentialFunc(func(ctx context.Context, hostport string) (auth.Credential, error) { + if strings.Contains(hostport, r.info.HostPort()) { + return authCreds, nil + } + logger.Warn("no credentials for host", "host", hostport) + return auth.EmptyCredential, nil + }), } return oras.New(oras.ClientOptions{ Client: authClient, PlainHTTP: r.info.Scheme == "http", + Logger: logger, }), nil } diff --git a/api/tech/oras/client.go b/api/tech/oras/client.go index a73e0003a9..60f4fede67 100644 --- a/api/tech/oras/client.go +++ b/api/tech/oras/client.go @@ -4,11 +4,9 @@ import ( "context" "errors" "fmt" - "io" - "strings" - "sync" "github.com/containerd/containerd/errdefs" + "github.com/mandelsoft/logging" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" oraserr "oras.land/oras-go/v2/errdef" "oras.land/oras-go/v2/registry/remote" @@ -18,55 +16,35 @@ import ( type ClientOptions struct { Client *auth.Client PlainHTTP bool + Logger logging.Logger } type Client struct { client *auth.Client plainHTTP bool - ref string - mu sync.RWMutex + logger logging.Logger } -var ( - _ Resolver = &Client{} - _ Fetcher = &Client{} - _ Pusher = &Client{} - _ Lister = &Client{} -) +var _ Resolver = &Client{} func New(opts ClientOptions) *Client { - return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP} + return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP, logger: opts.Logger} } func (c *Client) Fetcher(ctx context.Context, ref string) (Fetcher, error) { - c.mu.Lock() - defer c.mu.Unlock() - - c.ref = ref - return c, nil + return &OrasFetcher{client: c.client, ref: ref, plainHTTP: c.plainHTTP}, nil } func (c *Client) Pusher(ctx context.Context, ref string) (Pusher, error) { - c.mu.Lock() - defer c.mu.Unlock() - - c.ref = ref - return c, nil + return &OrasPusher{client: c.client, ref: ref, plainHTTP: c.plainHTTP}, nil } func (c *Client) Lister(ctx context.Context, ref string) (Lister, error) { - c.mu.Lock() - defer c.mu.Unlock() - - c.ref = ref - return c, nil + return &OrasLister{client: c.client, ref: ref, plainHTTP: c.plainHTTP}, nil } func (c *Client) Resolve(ctx context.Context, ref string) (string, ociv1.Descriptor, error) { - c.mu.RLock() - defer c.mu.RUnlock() - - src, err := c.createRepository(ref) + src, err := createRepository(ref, c.client, c.plainHTTP) if err != nil { return "", ociv1.Descriptor{}, err } @@ -88,114 +66,16 @@ func (c *Client) Resolve(ctx context.Context, ref string) (string, ociv1.Descrip return "", desc, nil } -func (c *Client) Push(ctx context.Context, d ociv1.Descriptor, src Source) error { - c.mu.RLock() - defer c.mu.RUnlock() - - reader, err := src.Reader() - if err != nil { - return err - } - - repository, err := c.createRepository(c.ref) - if err != nil { - return err - } - - if split := strings.Split(c.ref, ":"); len(split) == 2 { - // Once we get a reference that contains a tag, we need to re-push that - // layer with the reference included. PushReference then will tag - // that layer resulting in the created tag pointing to the right - // blob data. - if err := repository.PushReference(ctx, d, reader, c.ref); err != nil { - return fmt.Errorf("failed to push tag: %w", err) - } - - return nil - } - - // We have a digest, so we use plain push for the digest. - // Push here decides if it's a Manifest or a Blob. - if err := repository.Push(ctx, d, reader); err != nil { - return fmt.Errorf("failed to push: %w, %s", err, c.ref) - } - - return nil -} - -func (c *Client) Fetch(ctx context.Context, desc ociv1.Descriptor) (io.ReadCloser, error) { - c.mu.RLock() - defer c.mu.RUnlock() - - src, err := c.createRepository(c.ref) - if err != nil { - return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) - } - - // oras requires a Resolve to happen before a fetch because - // -1 is an invalid size and results in a content-length mismatch error by design. - // This is a security consideration on ORAS' side. - // manifest is not set in the descriptor - // We explicitly call resolve on manifest first because it might be - // that the mediatype is not set at this point so we don't want ORAS to try to - // select the wrong layer to fetch from. - rdesc, err := src.Manifests().Resolve(ctx, desc.Digest.String()) - if errors.Is(err, oraserr.ErrNotFound) { - rdesc, err = src.Blobs().Resolve(ctx, desc.Digest.String()) - if err != nil { - return nil, fmt.Errorf("failed to resolve fetch blob %q: %w", desc.Digest.String(), err) - } - - delayer := func() (io.ReadCloser, error) { - return src.Blobs().Fetch(ctx, rdesc) - } - - return newDelayedReader(delayer) - } - - if err != nil { - return nil, fmt.Errorf("failed to resolve fetch manifest %q: %w", desc.Digest.String(), err) - } - - // lastly, try a manifest fetch. - fetch, err := src.Fetch(ctx, rdesc) - if err != nil { - return nil, fmt.Errorf("failed to fetch manifest: %w", err) - } - - return fetch, err -} - -func (c *Client) List(ctx context.Context) ([]string, error) { - c.mu.RLock() - defer c.mu.RUnlock() - - src, err := c.createRepository(c.ref) - if err != nil { - return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) - } - - var result []string - if err := src.Tags(ctx, "", func(tags []string) error { - result = append(result, tags...) - return nil - }); err != nil { - return nil, fmt.Errorf("failed to list tags: %w", err) - } - - return result, nil -} - // createRepository creates a new repository representation using the passed in ref. // This is a cheap operation. -func (c *Client) createRepository(ref string) (*remote.Repository, error) { +func createRepository(ref string, client *auth.Client, plain bool) (*remote.Repository, error) { src, err := remote.NewRepository(ref) if err != nil { return nil, fmt.Errorf("failed to create new repository: %w", err) } - src.Client = c.client // set up authenticated client. - src.PlainHTTP = c.plainHTTP + src.Client = client // set up authenticated client. + src.PlainHTTP = plain return src, nil } diff --git a/api/tech/oras/delayed_reader.go b/api/tech/oras/delayed_reader.go deleted file mode 100644 index d07a6f870b..0000000000 --- a/api/tech/oras/delayed_reader.go +++ /dev/null @@ -1,57 +0,0 @@ -package oras - -import ( - "io" -) - -// delayedReader sets up a reader that only fetches a blob -// upon explicit reading request, otherwise, it stores the -// way of getting the reader. -type delayedReader struct { - open func() (io.ReadCloser, error) - rc io.ReadCloser - closed bool -} - -func newDelayedReader(open func() (io.ReadCloser, error)) (*delayedReader, error) { - return &delayedReader{ - open: open, - }, nil -} - -func (d *delayedReader) Read(p []byte) (n int, err error) { - if d.closed { - return 0, io.EOF - } - - reader, err := d.reader() - if err != nil { - return 0, err - } - - return reader.Read(p) -} - -func (d *delayedReader) reader() (io.ReadCloser, error) { - if d.rc != nil { - return d.rc, nil - } - - rc, err := d.open() - if err != nil { - return nil, err - } - - d.rc = rc - return rc, nil -} - -func (d *delayedReader) Close() error { - if d.closed { - return nil - } - - // we close regardless of an error - d.closed = true - return d.rc.Close() -} diff --git a/api/tech/oras/fetcher.go b/api/tech/oras/fetcher.go new file mode 100644 index 0000000000..33c1bf1915 --- /dev/null +++ b/api/tech/oras/fetcher.go @@ -0,0 +1,64 @@ +package oras + +import ( + "context" + "errors" + "fmt" + "io" + + ociv1 "github.com/opencontainers/image-spec/specs-go/v1" + "oras.land/oras-go/v2/registry/remote/auth" +) + +type OrasFetcher struct { + client *auth.Client + ref string + plainHTTP bool +} + +func (c *OrasFetcher) Fetch(ctx context.Context, desc ociv1.Descriptor) (io.ReadCloser, error) { + src, err := createRepository(c.ref, c.client, c.plainHTTP) + if err != nil { + return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) + } + + // oras requires a Resolve to happen before a fetch because + // -1 or 0 are invalid sizes and result in a content-length mismatch error by design. + // This is a security consideration on ORAS' side. + // For more information (https://github.com/oras-project/oras-go/issues/822#issuecomment-2325622324) + // We explicitly call resolve on manifest first because it might be + // that the mediatype is not set at this point so we don't want ORAS to try to + // select the wrong layer to fetch from. + if desc.Size < 1 || desc.Digest == "" { + rdesc, err := src.Manifests().Resolve(ctx, desc.Digest.String()) + if err != nil { + var berr error + rdesc, berr = src.Blobs().Resolve(ctx, desc.Digest.String()) + if berr != nil { + // also display the first manifest resolve error + err = errors.Join(err, berr) + + return nil, fmt.Errorf("failed to resolve fetch blob %q: %w", desc.Digest.String(), err) + } + + reader, err := src.Blobs().Fetch(ctx, rdesc) + if err != nil { + return nil, fmt.Errorf("failed to fetch blob: %w", err) + } + + return reader, nil + } + + // no error + desc = rdesc + } + + // manifest resolve succeeded return the reader directly + // mediatype of the descriptor should now be set to the correct type. + fetch, err := src.Fetch(ctx, desc) + if err != nil { + return nil, fmt.Errorf("failed to fetch manifest: %w", err) + } + + return fetch, nil +} diff --git a/api/tech/oras/lister.go b/api/tech/oras/lister.go new file mode 100644 index 0000000000..ba74568e45 --- /dev/null +++ b/api/tech/oras/lister.go @@ -0,0 +1,31 @@ +package oras + +import ( + "context" + "fmt" + + "oras.land/oras-go/v2/registry/remote/auth" +) + +type OrasLister struct { + client *auth.Client + ref string + plainHTTP bool +} + +func (c *OrasLister) List(ctx context.Context) ([]string, error) { + src, err := createRepository(c.ref, c.client, c.plainHTTP) + if err != nil { + return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) + } + + var result []string + if err := src.Tags(ctx, "", func(tags []string) error { + result = append(result, tags...) + return nil + }); err != nil { + return nil, fmt.Errorf("failed to list tags: %w", err) + } + + return result, nil +} diff --git a/api/tech/oras/pusher.go b/api/tech/oras/pusher.go new file mode 100644 index 0000000000..784b2ae99f --- /dev/null +++ b/api/tech/oras/pusher.go @@ -0,0 +1,70 @@ +package oras + +import ( + "context" + "fmt" + + "github.com/containerd/errdefs" + ociv1 "github.com/opencontainers/image-spec/specs-go/v1" + "oras.land/oras-go/v2/registry" + "oras.land/oras-go/v2/registry/remote/auth" + + "ocm.software/ocm/api/oci/ociutils" +) + +type OrasPusher struct { + client *auth.Client + ref string + plainHTTP bool +} + +func (c *OrasPusher) Push(ctx context.Context, d ociv1.Descriptor, src Source) (retErr error) { + reader, err := src.Reader() + if err != nil { + return err + } + + repository, err := createRepository(c.ref, c.client, c.plainHTTP) + if err != nil { + return err + } + + ref, err := registry.ParseReference(c.ref) + if err != nil { + return fmt.Errorf("failed to parse reference %q: %w", c.ref, err) + } + + vers, err := ociutils.ParseVersion(ref.Reference) + if err != nil { + return fmt.Errorf("failed to parse version %q: %w", ref.Reference, err) + } + + if vers.IsTagged() { + // Once we get a reference that contains a tag, we need to re-push that + // layer with the reference included. PushReference then will tag + // that layer resulting in the created tag pointing to the right + // blob data. + if err := repository.PushReference(ctx, d, reader, c.ref); err != nil { + return fmt.Errorf("failed to push tag: %w", err) + } + + return nil + } + + ok, err := repository.Exists(ctx, d) + if err != nil { + return fmt.Errorf("failed to check if repository %q exists: %w", ref.Repository, err) + } + + if ok { + return errdefs.ErrAlreadyExists + } + + // We have a digest, so we use plain push for the digest. + // Push here decides if it's a Manifest or a Blob. + if err := repository.Push(ctx, d, reader); err != nil { + return fmt.Errorf("failed to push: %w, %s", err, c.ref) + } + + return nil +} From 285a20a66ca166fed3672998a25cdbce706ef51f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Fri, 20 Dec 2024 13:33:30 +0100 Subject: [PATCH 38/50] fix: correct fetch order for manifests and blobs with hints on media type (#1209) #### What this PR does / why we need it This PR changes the OCI fetch logic to: 1. Fetch Blobs before Manifests in case there is no media type 2. Fetch Manifests before Blobs or Blobs before Manifests if there is a media type hint #### Which issue(s) this PR fixes --------- Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> --- .../repositories/ocireg/repository.go | 2 + api/tech/oras/client.go | 7 +- api/tech/oras/fetcher.go | 78 ++++++++++++------- api/tech/oras/manifest.go | 27 +++++++ api/tech/oras/pusher.go | 10 ++- go.mod | 2 +- 6 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 api/tech/oras/manifest.go diff --git a/api/oci/extensions/repositories/ocireg/repository.go b/api/oci/extensions/repositories/ocireg/repository.go index 9393cbffa7..12fe7276de 100644 --- a/api/oci/extensions/repositories/ocireg/repository.go +++ b/api/oci/extensions/repositories/ocireg/repository.go @@ -11,6 +11,7 @@ import ( "github.com/containerd/errdefs" "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/logging" + "github.com/moby/locker" "oras.land/oras-go/v2/registry/remote/auth" "oras.land/oras-go/v2/registry/remote/retry" @@ -179,6 +180,7 @@ func (r *RepositoryImpl) getResolver(comp string) (oras.Resolver, error) { Client: authClient, PlainHTTP: r.info.Scheme == "http", Logger: logger, + Lock: locker.New(), }), nil } diff --git a/api/tech/oras/client.go b/api/tech/oras/client.go index 60f4fede67..3cde633d6a 100644 --- a/api/tech/oras/client.go +++ b/api/tech/oras/client.go @@ -7,6 +7,7 @@ import ( "github.com/containerd/containerd/errdefs" "github.com/mandelsoft/logging" + "github.com/moby/locker" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" oraserr "oras.land/oras-go/v2/errdef" "oras.land/oras-go/v2/registry/remote" @@ -17,18 +18,20 @@ type ClientOptions struct { Client *auth.Client PlainHTTP bool Logger logging.Logger + Lock *locker.Locker } type Client struct { client *auth.Client plainHTTP bool logger logging.Logger + lock *locker.Locker } var _ Resolver = &Client{} func New(opts ClientOptions) *Client { - return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP, logger: opts.Logger} + return &Client{client: opts.Client, plainHTTP: opts.PlainHTTP, logger: opts.Logger, lock: opts.Lock} } func (c *Client) Fetcher(ctx context.Context, ref string) (Fetcher, error) { @@ -36,7 +39,7 @@ func (c *Client) Fetcher(ctx context.Context, ref string) (Fetcher, error) { } func (c *Client) Pusher(ctx context.Context, ref string) (Pusher, error) { - return &OrasPusher{client: c.client, ref: ref, plainHTTP: c.plainHTTP}, nil + return &OrasPusher{client: c.client, ref: ref, plainHTTP: c.plainHTTP, lock: c.lock}, nil } func (c *Client) Lister(ctx context.Context, ref string) (Lister, error) { diff --git a/api/tech/oras/fetcher.go b/api/tech/oras/fetcher.go index 33c1bf1915..a12df685fc 100644 --- a/api/tech/oras/fetcher.go +++ b/api/tech/oras/fetcher.go @@ -5,8 +5,10 @@ import ( "errors" "fmt" "io" + "sync" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" + "oras.land/oras-go/v2/registry/remote" "oras.land/oras-go/v2/registry/remote/auth" ) @@ -14,51 +16,73 @@ type OrasFetcher struct { client *auth.Client ref string plainHTTP bool + mu sync.Mutex } func (c *OrasFetcher) Fetch(ctx context.Context, desc ociv1.Descriptor) (io.ReadCloser, error) { + c.mu.Lock() + defer c.mu.Unlock() + src, err := createRepository(c.ref, c.client, c.plainHTTP) if err != nil { return nil, fmt.Errorf("failed to resolve ref %q: %w", c.ref, err) } - // oras requires a Resolve to happen before a fetch because + // oras requires a Resolve to happen in some cases before a fetch because // -1 or 0 are invalid sizes and result in a content-length mismatch error by design. // This is a security consideration on ORAS' side. // For more information (https://github.com/oras-project/oras-go/issues/822#issuecomment-2325622324) - // We explicitly call resolve on manifest first because it might be - // that the mediatype is not set at this point so we don't want ORAS to try to - // select the wrong layer to fetch from. - if desc.Size < 1 || desc.Digest == "" { - rdesc, err := src.Manifests().Resolve(ctx, desc.Digest.String()) - if err != nil { - var berr error - rdesc, berr = src.Blobs().Resolve(ctx, desc.Digest.String()) - if berr != nil { - // also display the first manifest resolve error - err = errors.Join(err, berr) + // + // To workaround, we resolve the correct size + if desc.Size < 1 { + if desc, err = c.resolveDescriptor(ctx, desc, src); err != nil { + return nil, err + } + } - return nil, fmt.Errorf("failed to resolve fetch blob %q: %w", desc.Digest.String(), err) - } + // manifest resolve succeeded return the reader directly + // mediatype of the descriptor should now be set to the correct type. + reader, err := src.Fetch(ctx, desc) + if err != nil { + return nil, fmt.Errorf("failed to fetch blob: %w", err) + } - reader, err := src.Blobs().Fetch(ctx, rdesc) - if err != nil { - return nil, fmt.Errorf("failed to fetch blob: %w", err) - } + return reader, nil +} - return reader, nil +// resolveDescriptor resolves the descriptor by fetching the blob or manifest based on the digest as a reference. +// If the descriptor has a media type, it will be resolved directly. +// If the descriptor has no media type, it will first try to resolve the blob, then the manifest as a fallback. +func (c *OrasFetcher) resolveDescriptor(ctx context.Context, desc ociv1.Descriptor, src *remote.Repository) (ociv1.Descriptor, error) { + if desc.MediaType != "" { + var err error + // if there is a media type, resolve the descriptor directly + if isManifest(src.ManifestMediaTypes, desc) { + desc, err = src.Manifests().Resolve(ctx, desc.Digest.String()) + } else { + desc, err = src.Blobs().Resolve(ctx, desc.Digest.String()) } - - // no error - desc = rdesc + if err != nil { + return ociv1.Descriptor{}, fmt.Errorf("failed to resolve descriptor %q: %w", desc.Digest.String(), err) + } + return desc, nil } - // manifest resolve succeeded return the reader directly - // mediatype of the descriptor should now be set to the correct type. - fetch, err := src.Fetch(ctx, desc) + // if there is no media type, first try the blob, then the manifest + // To reader: DO NOT fetch manifest first, this can result in high latency calls + bdesc, err := src.Blobs().Resolve(ctx, desc.Digest.String()) if err != nil { - return nil, fmt.Errorf("failed to fetch manifest: %w", err) + mdesc, merr := src.Manifests().Resolve(ctx, desc.Digest.String()) + if merr != nil { + // also display the first manifest resolve error + err = errors.Join(err, merr) + + return ociv1.Descriptor{}, fmt.Errorf("failed to resolve manifest %q: %w", desc.Digest.String(), err) + } + desc = mdesc + } else { + desc = bdesc } - return fetch, nil + return desc, err } diff --git a/api/tech/oras/manifest.go b/api/tech/oras/manifest.go new file mode 100644 index 0000000000..cc473d87ff --- /dev/null +++ b/api/tech/oras/manifest.go @@ -0,0 +1,27 @@ +package oras + +import ( + ocispec "github.com/opencontainers/image-spec/specs-go/v1" +) + +// defaultManifestMediaTypes contains the default set of manifests media types. +var defaultManifestMediaTypes = []string{ + "application/vnd.docker.distribution.manifest.v2+json", + "application/vnd.docker.distribution.manifest.list.v2+json", + "application/vnd.oci.artifact.manifest.v1+json", + ocispec.MediaTypeImageManifest, + ocispec.MediaTypeImageIndex, +} + +// isManifest determines if the given descriptor points to a manifest. +func isManifest(manifestMediaTypes []string, desc ocispec.Descriptor) bool { + if len(manifestMediaTypes) == 0 { + manifestMediaTypes = defaultManifestMediaTypes + } + for _, mediaType := range manifestMediaTypes { + if desc.MediaType == mediaType { + return true + } + } + return false +} diff --git a/api/tech/oras/pusher.go b/api/tech/oras/pusher.go index 784b2ae99f..0372c13ebd 100644 --- a/api/tech/oras/pusher.go +++ b/api/tech/oras/pusher.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/containerd/errdefs" + "github.com/moby/locker" ociv1 "github.com/opencontainers/image-spec/specs-go/v1" "oras.land/oras-go/v2/registry" "oras.land/oras-go/v2/registry/remote/auth" @@ -16,13 +17,20 @@ type OrasPusher struct { client *auth.Client ref string plainHTTP bool + lock *locker.Locker } func (c *OrasPusher) Push(ctx context.Context, d ociv1.Descriptor, src Source) (retErr error) { + c.lock.Lock(c.ref) + defer c.lock.Unlock(c.ref) + reader, err := src.Reader() if err != nil { return err } + defer func() { + reader.Close() + }() repository, err := createRepository(c.ref, c.client, c.plainHTTP) if err != nil { @@ -60,8 +68,6 @@ func (c *OrasPusher) Push(ctx context.Context, d ociv1.Descriptor, src Source) ( return errdefs.ErrAlreadyExists } - // We have a digest, so we use plain push for the digest. - // Push here decides if it's a Manifest or a Blob. if err := repository.Push(ctx, d, reader); err != nil { return fmt.Errorf("failed to push: %w, %s", err, c.ref) } diff --git a/go.mod b/go.mod index 10e02fada5..2eab77b612 100644 --- a/go.mod +++ b/go.mod @@ -49,6 +49,7 @@ require ( github.com/mikefarah/yq/v4 v4.44.6 github.com/mitchellh/copystructure v1.2.0 github.com/mittwald/go-helm-client v0.12.15 + github.com/moby/locker v1.0.1 github.com/modern-go/reflect2 v1.0.2 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 @@ -258,7 +259,6 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect - github.com/moby/locker v1.0.1 // indirect github.com/moby/spdystream v0.5.0 // indirect github.com/moby/sys/capability v0.3.0 // indirect github.com/moby/sys/mountinfo v0.7.2 // indirect From c2605ccca2122d4eb879ed3cedc5afb727569749 Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Fri, 20 Dec 2024 13:52:09 +0100 Subject: [PATCH 39/50] chore: update 'flake.nix' (#1201) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 0f18a3344e..653312c44d 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-3h/k5p/simo4GtVm14mTBD5/4CG7QC8bfo48C6CuCbY="; + vendorHash = "sha256-hDIJjccA6G34X0AAGsPDjZuWfgW0BeiGerv6JGb4Sq8="; src = ./.; From 2cb31876cb74501608f9333bad830ad976848b17 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Fri, 20 Dec 2024 14:03:09 +0100 Subject: [PATCH 40/50] feat: support splitting blobs when stored as OCI layer (#1140) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #### What this PR does / why we need it There are OCI repositories with a layer size limitation. Because OCM potentially maps any external artifact to a single blob stored as layer on OCI registries, this could lead to problems. An obvious problematic scenario is the transport of a multi-platform OCI image. Its blob format is an archive containing all images and all layers of those images. This PR introduces the possibility to specify blob limits for OCI registries. The OCM-to-OCI mapping then splits larger blobs into multiple layers. The `localBlob` access method then uses a comma-separated list of blob layer-blob digest to remember the sequence of layers. The access then combines the layerblobs again to a single stream. #### Which issue(s) this PR fixes Fixes: https://github.com/open-component-model/ocm-project/issues/12 A follow-up issue https://github.com/open-component-model/ocm-project/issues/338 describes the provisioning of appropriate defaults for common public registries. --------- Co-authored-by: Jakob Möller --- api/credentials/identity/hostpath/identity.go | 11 ++ .../repositories/ocireg/repository.go | 1 + api/ocm/cpi/repocpi/bridge_r.go | 18 +++ .../genericocireg/accessmethod_localblob.go | 136 +++++++++++++++- .../repositories/genericocireg/bloblimits.go | 53 ++++++ .../genericocireg/componentversion.go | 118 +++++++++++--- .../repositories/genericocireg/config/type.go | 110 +++++++++++++ .../repositories/genericocireg/config_test.go | 62 +++++++ .../repositories/genericocireg/repo_test.go | 151 ++++++++++++++++++ .../repositories/genericocireg/repository.go | 58 ++++++- .../repositories/genericocireg/type.go | 26 ++- docs/reference/ocm_configfile.md | 22 +++ 12 files changed, 732 insertions(+), 34 deletions(-) create mode 100644 api/ocm/extensions/repositories/genericocireg/bloblimits.go create mode 100644 api/ocm/extensions/repositories/genericocireg/config/type.go create mode 100644 api/ocm/extensions/repositories/genericocireg/config_test.go diff --git a/api/credentials/identity/hostpath/identity.go b/api/credentials/identity/hostpath/identity.go index baa2aad8a9..968412dda6 100644 --- a/api/credentials/identity/hostpath/identity.go +++ b/api/credentials/identity/hostpath/identity.go @@ -157,3 +157,14 @@ func PathPrefix(id cpi.ConsumerIdentity) string { } return strings.TrimPrefix(id[ID_PATHPREFIX], "/") } + +func HostPort(id cpi.ConsumerIdentity) string { + if id == nil { + return "" + } + host := id[ID_HOSTNAME] + if port, ok := id[ID_PORT]; ok { + return host + ":" + port + } + return host +} diff --git a/api/oci/extensions/repositories/ocireg/repository.go b/api/oci/extensions/repositories/ocireg/repository.go index 12fe7276de..cc2c845ac0 100644 --- a/api/oci/extensions/repositories/ocireg/repository.go +++ b/api/oci/extensions/repositories/ocireg/repository.go @@ -70,6 +70,7 @@ func NewRepository(ctx cpi.Context, spec *RepositorySpec, info *RepositoryInfo) spec: spec, info: info, } + i.logger.Debug("created repository") return cpi.NewRepository(i), nil } diff --git a/api/ocm/cpi/repocpi/bridge_r.go b/api/ocm/cpi/repocpi/bridge_r.go index f7eea176fe..53ed151f5a 100644 --- a/api/ocm/cpi/repocpi/bridge_r.go +++ b/api/ocm/cpi/repocpi/bridge_r.go @@ -34,6 +34,24 @@ type RepositoryImpl interface { io.Closer } +// Chunked is an optional interface, which +// may be implemented to accept a blob limit for mapping +// local blobs to an external storage system. +type Chunked interface { + // SetBlobLimit sets the blob limit if possible. + // It returns true, if this was successful. + SetBlobLimit(s int64) bool +} + +// SetBlobLimit tries to set a blob limit for a repository +// implementation. It returns true, if this was possible. +func SetBlobLimit(i RepositoryImpl, s int64) bool { + if c, ok := i.(Chunked); ok { + return c.SetBlobLimit(s) + } + return false +} + type _repositoryBridgeBase = resource.ResourceImplBase[cpi.Repository] type repositoryBridge struct { diff --git a/api/ocm/extensions/repositories/genericocireg/accessmethod_localblob.go b/api/ocm/extensions/repositories/genericocireg/accessmethod_localblob.go index 94a0a85966..c661c9f294 100644 --- a/api/ocm/extensions/repositories/genericocireg/accessmethod_localblob.go +++ b/api/ocm/extensions/repositories/genericocireg/accessmethod_localblob.go @@ -1,10 +1,14 @@ package genericocireg import ( + "bytes" "io" + "os" + "strings" "sync" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/finalizer" "github.com/opencontainers/go-digest" "ocm.software/ocm/api/oci" @@ -88,9 +92,19 @@ func (m *localBlobAccessMethod) getBlob() (blobaccess.DataAccess, error) { return nil, errors.ErrNotImplemented("artifact blob synthesis") } } - _, data, err := m.namespace.GetBlobData(digest.Digest(m.spec.LocalReference)) - if err != nil { - return nil, err + refs := strings.Split(m.spec.LocalReference, ",") + + var ( + data blobaccess.DataAccess + err error + ) + if len(refs) < 2 { + _, data, err = m.namespace.GetBlobData(digest.Digest(m.spec.LocalReference)) + if err != nil { + return nil, err + } + } else { + data = &composedBlock{m, refs} } m.data = data return m.data, err @@ -111,3 +125,119 @@ func (m *localBlobAccessMethod) Get() ([]byte, error) { func (m *localBlobAccessMethod) MimeType() string { return m.spec.MediaType } + +//////////////////////////////////////////////////////////////////////////////// + +type composedBlock struct { + m *localBlobAccessMethod + refs []string +} + +var _ blobaccess.DataAccess = (*composedBlock)(nil) + +func (c *composedBlock) Get() ([]byte, error) { + buf := bytes.NewBuffer(nil) + for _, ref := range c.refs { + var finalize finalizer.Finalizer + + _, data, err := c.m.namespace.GetBlobData(digest.Digest(ref)) + if err != nil { + return nil, err + } + finalize.Close(data) + r, err := data.Reader() + if err != nil { + return nil, err + } + finalize.Close(r) + _, err = io.Copy(buf, r) + if err != nil { + return nil, err + } + err = finalize.Finalize() + if err != nil { + return nil, err + } + } + return buf.Bytes(), nil +} + +func (c *composedBlock) Reader() (io.ReadCloser, error) { + return &composedReader{ + m: c.m, + refs: c.refs, + }, nil +} + +func (c *composedBlock) Close() error { + return nil +} + +type composedReader struct { + lock sync.Mutex + m *localBlobAccessMethod + refs []string + reader io.ReadCloser + data blobaccess.DataAccess +} + +func (c *composedReader) Read(p []byte) (n int, err error) { + c.lock.Lock() + defer c.lock.Unlock() + + for { + if c.reader != nil { + n, err := c.reader.Read(p) + + if err == io.EOF { + c.reader.Close() + c.data.Close() + c.refs = c.refs[1:] + c.reader = nil + c.data = nil + // start new layer and return partial (>0) read before next layer is started + err = nil + } + // return partial read (even a zero read if layer is not yet finished) or error + if c.reader != nil || err != nil || n > 0 { + return n, err + } + // otherwise, we can use the given buffer for the next layer + + // now, we have to check for a next succeeding layer. + // This means to finish with the actual reader and continue + // with the next one. + } + + // If no more layers are available, report EOF. + if len(c.refs) == 0 { + return 0, io.EOF + } + + ref := strings.TrimSpace(c.refs[0]) + _, c.data, err = c.m.namespace.GetBlobData(digest.Digest(ref)) + if err != nil { + return 0, err + } + c.reader, err = c.data.Reader() + if err != nil { + return 0, err + } + } +} + +func (c *composedReader) Close() error { + c.lock.Lock() + defer c.lock.Unlock() + + if c.reader == nil && c.refs == nil { + return os.ErrClosed + } + if c.reader != nil { + c.reader.Close() + c.data.Close() + c.reader = nil + c.refs = nil + } + return nil +} diff --git a/api/ocm/extensions/repositories/genericocireg/bloblimits.go b/api/ocm/extensions/repositories/genericocireg/bloblimits.go new file mode 100644 index 0000000000..c4ecfc799a --- /dev/null +++ b/api/ocm/extensions/repositories/genericocireg/bloblimits.go @@ -0,0 +1,53 @@ +package genericocireg + +import ( + "sync" + + configctx "ocm.software/ocm/api/config" + "ocm.software/ocm/api/ocm/extensions/repositories/genericocireg/config" +) + +var ( + defaultBlobLimits config.BlobLimits + lock sync.Mutex +) + +const ( + KB = int64(1000) + MB = 1000 * KB + GB = 1000 * MB +) + +func init() { + defaultBlobLimits = config.BlobLimits{} + + // Add limits for known OCI repositories, here, + // or provide init functions in specialized packages + // by calling AddDefaultBlobLimit. + AddDefaultBlobLimit("ghcr.io", 10*GB) // https://github.com/orgs/community/discussions/77429 +} + +// AddDefaultBlobLimit can be used to set default blob limits +// for known repositories. +// Those limits will be overwritten, by blob limits +// given by a configuration object and the repository +// specification. +func AddDefaultBlobLimit(name string, limit int64) { + lock.Lock() + defer lock.Unlock() + + defaultBlobLimits[name] = limit +} + +func ConfigureBlobLimits(ctx configctx.ContextProvider, target config.Configurable) { + if target != nil { + lock.Lock() + defer lock.Unlock() + + target.ConfigureBlobLimits(defaultBlobLimits) + + if ctx != nil { + ctx.ConfigContext().ApplyTo(0, target) + } + } +} diff --git a/api/ocm/extensions/repositories/genericocireg/componentversion.go b/api/ocm/extensions/repositories/genericocireg/componentversion.go index f603fbe509..d332ca2527 100644 --- a/api/ocm/extensions/repositories/genericocireg/componentversion.go +++ b/api/ocm/extensions/repositories/genericocireg/componentversion.go @@ -2,13 +2,16 @@ package genericocireg import ( "fmt" + "io" "path" "strings" "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/set" + "github.com/mandelsoft/vfs/pkg/vfs" "github.com/opencontainers/go-digest" + "ocm.software/ocm/api/datacontext/attrs/vfsattr" "ocm.software/ocm/api/oci" "ocm.software/ocm/api/oci/artdesc" "ocm.software/ocm/api/oci/extensions/repositories/artifactset" @@ -25,7 +28,9 @@ import ( ocihdlr "ocm.software/ocm/api/ocm/extensions/blobhandler/handlers/oci" "ocm.software/ocm/api/utils/accessio" "ocm.software/ocm/api/utils/accessobj" + "ocm.software/ocm/api/utils/blobaccess" "ocm.software/ocm/api/utils/errkind" + "ocm.software/ocm/api/utils/mime" common "ocm.software/ocm/api/utils/misc" "ocm.software/ocm/api/utils/refmgmt" "ocm.software/ocm/api/utils/runtime" @@ -183,11 +188,11 @@ func (c *ComponentVersionContainer) Update() (bool, error) { layers.Add(i) } for i, r := range desc.Resources { - s, l, err := c.evalLayer(r.Access) + s, list, err := c.evalLayer(r.Access) if err != nil { return false, fmt.Errorf("failed resource layer evaluation: %w", err) } - if l > 0 { + for _, l := range list { layerAnnotations[l] = append(layerAnnotations[l], ArtifactInfo{ Kind: ARTKIND_RESOURCE, Identity: r.GetIdentity(desc.Resources), @@ -199,11 +204,11 @@ func (c *ComponentVersionContainer) Update() (bool, error) { } } for i, r := range desc.Sources { - s, l, err := c.evalLayer(r.Access) + s, list, err := c.evalLayer(r.Access) if err != nil { return false, fmt.Errorf("failed source layer evaluation: %w", err) } - if l > 0 { + for _, l := range list { layerAnnotations[l] = append(layerAnnotations[l], ArtifactInfo{ Kind: ARTKIND_SOURCE, Identity: r.GetIdentity(desc.Sources), @@ -259,32 +264,45 @@ func (c *ComponentVersionContainer) Update() (bool, error) { return false, nil } -func (c *ComponentVersionContainer) evalLayer(s compdesc.AccessSpec) (compdesc.AccessSpec, int, error) { - var d *artdesc.Descriptor +func (c *ComponentVersionContainer) evalLayer(s compdesc.AccessSpec) (compdesc.AccessSpec, []int, error) { + var ( + d *artdesc.Descriptor + layernums []int + ) spec, err := c.GetContext().AccessSpecForSpec(s) if err != nil { - return s, 0, err + return s, nil, err } if a, ok := spec.(*localblob.AccessSpec); ok { if ok, _ := artdesc.IsDigest(a.LocalReference); !ok { - return s, 0, errors.ErrInvalid("digest", a.LocalReference) + return s, nil, errors.ErrInvalid("digest", a.LocalReference) } - d = &artdesc.Descriptor{Digest: digest.Digest(a.LocalReference), MediaType: a.GetMimeType()} - } - if d != nil { - // find layer - layers := c.manifest.GetDescriptor().Layers - maxLen := len(layers) - 1 - for i := range layers { - l := layers[len(layers)-1-i] - if i < maxLen && l.Digest == d.Digest && (d.Digest == "" || d.Digest == l.Digest) { - return s, len(layers) - 1 - i, nil + refs := strings.Split(a.LocalReference, ",") + media := a.GetMimeType() + if len(refs) > 1 { + media = mime.MIME_OCTET + } + for _, ref := range refs { + d = &artdesc.Descriptor{Digest: digest.Digest(strings.TrimSpace(ref)), MediaType: media} + // find layer + layers := c.manifest.GetDescriptor().Layers + maxLen := len(layers) - 1 + found := false + for i := maxLen; i > 0; i-- { // layer 0 is the component descriptor + l := layers[i] + if l.Digest == d.Digest { + layernums = append(layernums, i) + found = true + break + } + } + if !found { + return s, nil, fmt.Errorf("resource access %s: no layer found for local blob %s[%s]", spec.Describe(c.GetContext()), d.Digest, d.MediaType) } } - return s, 0, fmt.Errorf("resource access %s: no layer found for local blob %s[%s]", spec.Describe(c.GetContext()), d.Digest, d.MediaType) } - return s, 0, nil + return s, layernums, nil } func (c *ComponentVersionContainer) GetDescriptor() *compdesc.ComponentDescriptor { @@ -299,20 +317,74 @@ func (c *ComponentVersionContainer) GetStorageContext() cpi.StorageContext { return ocihdlr.New(c.comp.GetName(), c.Repository(), c.comp.repo.ocirepo.GetSpecification().GetKind(), c.comp.repo.ocirepo, c.comp.namespace, c.manifest) } +func blobAccessForChunk(blob blobaccess.BlobAccess, fs vfs.FileSystem, r io.Reader, limit int64) (cpi.BlobAccess, bool, error) { + f, err := blobaccess.NewTempFile("", "chunk-*", fs) + if err != nil { + return nil, true, err + } + written, err := io.CopyN(f.Writer(), r, limit) + if err != nil && !errors.Is(err, io.EOF) { + f.Close() + return nil, false, err + } + if written <= 0 { + f.Close() + return nil, false, nil + } + return f.AsBlob(blob.MimeType()), written == limit, nil +} + func (c *ComponentVersionContainer) AddBlob(blob cpi.BlobAccess, refName string, global cpi.AccessSpec) (cpi.AccessSpec, error) { if blob == nil { return nil, errors.New("a resource has to be defined") } + fs := vfsattr.Get(c.GetContext()) + size := blob.Size() + limit := c.comp.repo.blobLimit + var refs []string + if limit > 0 && size != blobaccess.BLOB_UNKNOWN_SIZE && size > limit { + reader, err := blob.Reader() + if err != nil { + return nil, err + } + defer reader.Close() + + var b blobaccess.BlobAccess + cont := true + for cont { + b, cont, err = blobAccessForChunk(blob, fs, reader, limit) + if err != nil { + return nil, err + } + if b != nil { + err = c.addLayer(b, &refs) + b.Close() + if err != nil { + return nil, err + } + } + } + } else { + err := c.addLayer(blob, &refs) + if err != nil { + return nil, err + } + } + return localblob.New(strings.Join(refs, ","), refName, blob.MimeType(), global), nil +} + +func (c *ComponentVersionContainer) addLayer(blob cpi.BlobAccess, refs *[]string) error { err := c.manifest.AddBlob(blob) if err != nil { - return nil, err + return err } err = ocihdlr.AssureLayer(c.manifest.GetDescriptor(), blob) if err != nil { - return nil, err + return err } - return localblob.New(blob.Digest().String(), refName, blob.MimeType(), global), nil + *refs = append(*refs, blob.Digest().String()) + return nil } // AssureGlobalRef provides a global manifest for a local OCI Artifact. diff --git a/api/ocm/extensions/repositories/genericocireg/config/type.go b/api/ocm/extensions/repositories/genericocireg/config/type.go new file mode 100644 index 0000000000..137c1d2688 --- /dev/null +++ b/api/ocm/extensions/repositories/genericocireg/config/type.go @@ -0,0 +1,110 @@ +package config + +import ( + "net" + "strings" + + "ocm.software/ocm/api/config" + cfgcpi "ocm.software/ocm/api/config/cpi" + "ocm.software/ocm/api/utils/runtime" +) + +const ( + ConfigType = "blobLimits.ocireg.ocm" + cfgcpi.OCM_CONFIG_TYPE_SUFFIX + ConfigTypeV1 = ConfigType + runtime.VersionSeparator + "v1" +) + +func init() { + cfgcpi.RegisterConfigType(cfgcpi.NewConfigType[*Config](ConfigType, usage)) + cfgcpi.RegisterConfigType(cfgcpi.NewConfigType[*Config](ConfigTypeV1)) +} + +// Config describes a memory based config interface +// for configuring blob limits for underlying OCI manifest layers. +type Config struct { + runtime.ObjectVersionedType `json:",inline"` + // BlobLimits describe the limit setting for host:port + // entries. As a special case (for testing) it is possible + // to configure limits for CTF, also, by using "@"+filepath. + BlobLimits BlobLimits `json:"blobLimits"` +} + +type BlobLimits map[string]int64 + +func (b BlobLimits) GetLimit(hostport string) int64 { + if b == nil { + return -1 + } + l, ok := b[hostport] + if ok { + return l + } + + if !strings.HasPrefix(hostport, "@") { + host, _, err := net.SplitHostPort(hostport) + if err == nil { + l, ok = b[host] + if ok { + return l + } + } + } + return -1 +} + +type Configurable interface { + ConfigureBlobLimits(limits BlobLimits) +} + +// New creates a blob limit ConfigSpec. +func New() *Config { + return &Config{ + ObjectVersionedType: runtime.NewVersionedTypedObject(ConfigType), + } +} + +func (a *Config) GetType() string { + return ConfigType +} + +func (a *Config) AddLimit(hostport string, limit int64) { + if a.BlobLimits == nil { + a.BlobLimits = BlobLimits{} + } + a.BlobLimits[hostport] = limit +} + +func (a *Config) ApplyTo(ctx config.Context, target interface{}) error { + t, ok := target.(Configurable) + if !ok { + return config.ErrNoContext(ConfigType) + } + if a.BlobLimits != nil { + t.ConfigureBlobLimits(a.BlobLimits) + } + return nil +} + +const usage = ` +The config type ` + ConfigType + ` can be used to set some +blob layer limits for particular OCI registries used to host OCM repositories. +The blobLimits field maps a OCI registry address to the blob limit to use: + +
+    type: ` + ConfigType + `
+    blobLimits:
+        dummy.io: 65564
+        dummy.io:8443: 32768 // with :8443 specifying the port and 32768 specifying the byte limit
+
+ +If blob limits apply to a registry, local blobs with a size larger than +the configured limit will be split into several layers with a maximum +size of the given value. + +These settings can be overwritten by explicit settings in an OCM +repository specification for those repositories. + +The most specific entry will be used. If a registry with a dedicated +port is requested, but no explicit configuration is found, the +setting for the sole hostname is used (if configured). +` diff --git a/api/ocm/extensions/repositories/genericocireg/config_test.go b/api/ocm/extensions/repositories/genericocireg/config_test.go new file mode 100644 index 0000000000..2435497a81 --- /dev/null +++ b/api/ocm/extensions/repositories/genericocireg/config_test.go @@ -0,0 +1,62 @@ +package genericocireg_test + +import ( + "reflect" + + . "github.com/mandelsoft/goutils/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "ocm.software/ocm/api/datacontext" + "ocm.software/ocm/api/ocm/extensions/repositories/genericocireg/config" + + "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/mandelsoft/vfs/pkg/vfs" + "ocm.software/ocm/api/oci" + "ocm.software/ocm/api/oci/extensions/repositories/ctf" + "ocm.software/ocm/api/ocm" + "ocm.software/ocm/api/ocm/cpi/repocpi" + "ocm.software/ocm/api/ocm/extensions/repositories/genericocireg" + "ocm.software/ocm/api/utils/accessio" + "ocm.software/ocm/api/utils/accessobj" +) + +var _ = Describe("component repository mapping", func() { + var tempfs vfs.FileSystem + + var ocispec oci.RepositorySpec + var spec *genericocireg.RepositorySpec + + BeforeEach(func() { + t, err := osfs.NewTempFileSystem() + Expect(err).To(Succeed()) + tempfs = t + + // ocmlog.Context().AddRule(logging.NewConditionRule(logging.TraceLevel, accessio.ALLOC_REALM)) + + ocispec, err = ctf.NewRepositorySpec(accessobj.ACC_CREATE, "test", accessio.PathFileSystem(tempfs), accessobj.FormatDirectory) + Expect(err).To(Succeed()) + spec = genericocireg.NewRepositorySpec(ocispec, nil) + }) + + AfterEach(func() { + vfs.Cleanup(tempfs) + }) + + It("creates a dummy component with configured chunks", func() { + var finalize finalizer.Finalizer + defer Defer(finalize.Finalize) + + ctx := ocm.New(datacontext.MODE_EXTENDED) + + cfg := config.New() + cfg.AddLimit("@test", 5) + ctx.ConfigContext().ApplyConfig(cfg, "direct") + + repo := finalizer.ClosingWith(&finalize, Must(ctx.RepositoryForSpec(spec))) + impl := Must(repocpi.GetRepositoryImplementation(repo)) + Expect(reflect.TypeOf(impl).String()).To(Equal("*genericocireg.RepositoryImpl")) + + Expect(impl.(*genericocireg.RepositoryImpl).GetBlobLimit()).To(Equal(int64(5))) + }) +}) diff --git a/api/ocm/extensions/repositories/genericocireg/repo_test.go b/api/ocm/extensions/repositories/genericocireg/repo_test.go index 5ea992c69a..a892bf0f9c 100644 --- a/api/ocm/extensions/repositories/genericocireg/repo_test.go +++ b/api/ocm/extensions/repositories/genericocireg/repo_test.go @@ -2,6 +2,7 @@ package genericocireg_test import ( "fmt" + "io" "path" "reflect" @@ -123,6 +124,156 @@ var _ = Describe("component repository mapping", func() { MustBeSuccessful(finalize.Finalize()) }) + const ref4 = "sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08,sha256:3a6eb0790f39ac87c94f3856b2dd2c5d110e6811602261a9a923d3bb23adc8b7" + const ref5 = "sha256:a4853613b2a38568ed4e49196238152469097412d06d5e5fc9be8ab92cfdf2bf,sha256:977817f6f61f4dd501df3036a3e16b31452b36f4aa3edcf9a3f3242a79d7170d" + const ref8 = "sha256:" + ocmtesthelper.D_TESTDATA + + DescribeTable("creates a dummy component with chunks", func(limit int, f func(ocm.ResourceAccess), ref string) { + var finalize finalizer.Finalizer + defer Defer(finalize.Finalize) + + repo := finalizer.ClosingWith(&finalize, Must(DefaultContext.RepositoryForSpec(spec))) + impl := Must(repocpi.GetRepositoryImplementation(repo)) + Expect(reflect.TypeOf(impl).String()).To(Equal("*genericocireg.RepositoryImpl")) + repocpi.SetBlobLimit(impl, int64(limit)) + + comp := finalizer.ClosingWith(&finalize, Must(repo.LookupComponent(COMPONENT))) + vers := finalizer.ClosingWith(&finalize, Must(comp.NewVersion("v1"))) + + m1 := compdesc.NewResourceMeta("rsc1", resourcetypes.PLAIN_TEXT, metav1.LocalRelation) + blob := blobaccess.ForString(mime.MIME_TEXT, ocmtesthelper.S_TESTDATA) + MustBeSuccessful(vers.SetResourceBlob(m1, blob, "", nil)) + + MustBeSuccessful(comp.AddVersion(vers)) + + noref := vers.Repository() + Expect(noref).NotTo(BeNil()) + Expect(noref.IsClosed()).To(BeFalse()) + Expect(noref.Close()).To(Succeed()) + Expect(noref.IsClosed()).To(BeFalse()) + + MustBeSuccessful(finalize.Finalize()) + + Expect(noref.IsClosed()).To(BeTrue()) + Expect(noref.Close()).To(MatchError("closed")) + ExpectError(noref.LookupComponent("dummy")).To(MatchError("closed")) + + // access it again + repo = finalizer.ClosingWith(&finalize, Must(DefaultContext.RepositoryForSpec(spec))) + + ok := Must(repo.ExistsComponentVersion(COMPONENT, "v1")) + Expect(ok).To(BeTrue()) + + comp = finalizer.ClosingWith(&finalize, Must(repo.LookupComponent(COMPONENT))) + vers = finalizer.ClosingWith(&finalize, Must(comp.LookupVersion("v1"))) + + rsc := Must(vers.GetResourceByIndex(0)) + acc := Must(rsc.Access()) + local, ok := acc.(*localblob.AccessSpec) + Expect(ok).To(BeTrue()) + // fmt.Printf("localref: %s\n", local.LocalReference) + Expect(local.LocalReference).To(Equal(ref)) + Expect(rsc.Meta().Digest).NotTo(BeNil()) + Expect(rsc.Meta().Digest.Value).To(Equal(ocmtesthelper.D_TESTDATA)) + + f(rsc) + + MustBeSuccessful(finalize.Finalize()) + }, + Entry("get blob", 5, func(rsc ocm.ResourceAccess) { + data := Must(ocmutils.GetResourceData(rsc)) + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref5), + Entry("stream blob", 5, func(rsc ocm.ResourceAccess) { + r := Must(ocmutils.GetResourceReader(rsc)) + data := Must(io.ReadAll(r)) + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref5), + Entry("stream blob with small buffer", 5, func(rsc ocm.ResourceAccess) { + var buf [2]byte + var data []byte + + r := Must(ocmutils.GetResourceReader(rsc)) + + for { + n, err := r.Read(buf[:]) + if n > 0 { + data = append(data, buf[:n]...) + } + if err != nil { + if err == io.EOF { + break + } else { + MustBeSuccessful(err) + } + } + } + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref5), + + Entry("get blob (match limit)", len(ocmtesthelper.S_TESTDATA), func(rsc ocm.ResourceAccess) { + data := Must(ocmutils.GetResourceData(rsc)) + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref8), + Entry("stream blob (match limit)", len(ocmtesthelper.S_TESTDATA), func(rsc ocm.ResourceAccess) { + r := Must(ocmutils.GetResourceReader(rsc)) + data := Must(io.ReadAll(r)) + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref8), + Entry("stream blob with small buffer (match limit)", len(ocmtesthelper.S_TESTDATA), func(rsc ocm.ResourceAccess) { + var buf [2]byte + var data []byte + + r := Must(ocmutils.GetResourceReader(rsc)) + + for { + n, err := r.Read(buf[:]) + if n > 0 { + data = append(data, buf[:n]...) + } + if err != nil { + if err == io.EOF { + break + } else { + MustBeSuccessful(err) + } + } + } + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref8), + + Entry("get blob (match limit/2)", len(ocmtesthelper.S_TESTDATA)/2, func(rsc ocm.ResourceAccess) { + data := Must(ocmutils.GetResourceData(rsc)) + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref4), + Entry("stream blob (match limit/2)", len(ocmtesthelper.S_TESTDATA)/2, func(rsc ocm.ResourceAccess) { + r := Must(ocmutils.GetResourceReader(rsc)) + data := Must(io.ReadAll(r)) + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref4), + Entry("stream blob with small buffer (match limit/2)", len(ocmtesthelper.S_TESTDATA)/2, func(rsc ocm.ResourceAccess) { + var buf [2]byte + var data []byte + + r := Must(ocmutils.GetResourceReader(rsc)) + + for { + n, err := r.Read(buf[:]) + if n > 0 { + data = append(data, buf[:n]...) + } + if err != nil { + if err == io.EOF { + break + } else { + MustBeSuccessful(err) + } + } + } + Expect(string(data)).To(Equal(ocmtesthelper.S_TESTDATA)) + }, ref4), + ) + It("handles legacylocalociblob access method", func() { var finalize finalizer.Finalizer defer Defer(finalize.Finalize) diff --git a/api/ocm/extensions/repositories/genericocireg/repository.go b/api/ocm/extensions/repositories/genericocireg/repository.go index 70661f76f5..8773350ea5 100644 --- a/api/ocm/extensions/repositories/genericocireg/repository.go +++ b/api/ocm/extensions/repositories/genericocireg/repository.go @@ -11,12 +11,16 @@ import ( "github.com/mandelsoft/goutils/general" "ocm.software/ocm/api/credentials" + "ocm.software/ocm/api/credentials/identity/hostpath" "ocm.software/ocm/api/datacontext" "ocm.software/ocm/api/oci" ocicpi "ocm.software/ocm/api/oci/cpi" + "ocm.software/ocm/api/oci/extensions/repositories/ctf" + "ocm.software/ocm/api/oci/extensions/repositories/ocireg" "ocm.software/ocm/api/ocm/cpi" "ocm.software/ocm/api/ocm/cpi/repocpi" "ocm.software/ocm/api/ocm/extensions/repositories/genericocireg/componentmapping" + "ocm.software/ocm/api/ocm/extensions/repositories/genericocireg/config" ) type OCIBasedRepository interface { @@ -44,23 +48,69 @@ type RepositoryImpl struct { nonref cpi.Repository ocirepo oci.Repository readonly bool + // blobLimit is the size limit for layers maintained for the storage of localBlobs. + // The value -1 means an unconfigured value (a default from the blob limit configuration is used), + // a value == 0 disables the limiting and (a default from the blob limit configuration is ignored), + // a value > 0 enabled the usage of the specified size. + blobLimit int64 } var ( _ repocpi.RepositoryImpl = (*RepositoryImpl)(nil) _ credentials.ConsumerIdentityProvider = (*RepositoryImpl)(nil) + _ config.Configurable = (*RepositoryImpl)(nil) ) -func NewRepository(ctxp cpi.ContextProvider, meta *ComponentRepositoryMeta, ocirepo oci.Repository) cpi.Repository { +// NewRepository creates a new OCM repository based on any OCI abstraction from +// the OCI context type. +// The optional blobLimit is the size limit for layers maintained for the storage of localBlobs. +// The value -1 means an unconfigured value (a default from the blob limit configuration is used), +// a value == 0 disables the limiting and (a default from the blob limit configuration is ignored), +// a value > 0 enabled the usage of the specified size. +func NewRepository(ctxp cpi.ContextProvider, meta *ComponentRepositoryMeta, ocirepo oci.Repository, blobLimit ...int64) cpi.Repository { ctx := datacontext.InternalContextRef(ctxp.OCMContext()) + impl := &RepositoryImpl{ - ctx: ctx, - meta: *DefaultComponentRepositoryMeta(meta), - ocirepo: ocirepo, + ctx: ctx, + meta: *DefaultComponentRepositoryMeta(meta), + ocirepo: ocirepo, + blobLimit: general.OptionalDefaulted(-1, blobLimit...), + } + if impl.blobLimit < 0 { + ConfigureBlobLimits(ctxp.OCMContext(), impl) } return repocpi.NewRepository(impl, "OCM repo[OCI]") } +func (r *RepositoryImpl) ConfigureBlobLimits(limits config.BlobLimits) { + if len(limits) == 0 { + return + } + if spec, ok := r.ocirepo.GetSpecification().(*ocireg.RepositorySpec); ok { + id := spec.GetConsumerId() + hp := hostpath.HostPort(id) + l := limits.GetLimit(hp) + if l >= 0 { + r.blobLimit = l + } + } + if spec, ok := r.ocirepo.GetSpecification().(*ctf.RepositorySpec); ok { + l := limits.GetLimit("@" + spec.FilePath) + if l >= 0 { + r.blobLimit = l + } + } +} + +func (r *RepositoryImpl) SetBlobLimit(s int64) bool { + r.blobLimit = s + return true +} + +func (r *RepositoryImpl) GetBlobLimit() int64 { + return r.blobLimit +} + func (r *RepositoryImpl) Close() error { return r.ocirepo.Close() } diff --git a/api/ocm/extensions/repositories/genericocireg/type.go b/api/ocm/extensions/repositories/genericocireg/type.go index 809d598140..b3c4b460e5 100644 --- a/api/ocm/extensions/repositories/genericocireg/type.go +++ b/api/ocm/extensions/repositories/genericocireg/type.go @@ -91,6 +91,7 @@ func NewComponentRepositoryMeta(subPath string, mapping ComponentNameMapping) *C type RepositorySpec struct { oci.RepositorySpec ComponentRepositoryMeta + BlobLimit *int64 } var ( @@ -127,19 +128,28 @@ func (a *RepositorySpec) AsUniformSpec(cpi.Context) *cpi.UniformRepositorySpec { return &cpi.UniformRepositorySpec{Type: a.GetKind(), Scheme: spec.Scheme, Host: spec.Host, Info: spec.Info, TypeHint: spec.TypeHint, SubPath: a.SubPath} } +type meta struct { + ComponentRepositoryMeta `json:",inline"` + BlobLimit *int64 `json:"blobLimit,omitempty"` +} + func (u *RepositorySpec) UnmarshalJSON(data []byte) error { logrus.Debugf("unmarshal generic ocireg spec %s\n", string(data)) ocispec := &oci.GenericRepositorySpec{} if err := json.Unmarshal(data, ocispec); err != nil { return err } - compmeta := &ComponentRepositoryMeta{} - if err := json.Unmarshal(data, ocispec); err != nil { + + var m meta + if err := json.Unmarshal(data, &m); err != nil { return err } u.RepositorySpec = ocispec - u.ComponentRepositoryMeta = *compmeta + u.ComponentRepositoryMeta = m.ComponentRepositoryMeta + if m.BlobLimit != nil { + u.BlobLimit = m.BlobLimit + } normalizers.Normalize(u) return nil @@ -154,7 +164,12 @@ func (u RepositorySpec) MarshalJSON() ([]byte, error) { if err != nil { return nil, err } - compmeta, err := runtime.ToUnstructuredObject(u.ComponentRepositoryMeta) + + m := meta{ + ComponentRepositoryMeta: u.ComponentRepositoryMeta, + BlobLimit: u.BlobLimit, + } + compmeta, err := runtime.ToUnstructuredObject(&m) if err != nil { return nil, err } @@ -166,6 +181,9 @@ func (s *RepositorySpec) Repository(ctx cpi.Context, creds credentials.Credentia if err != nil { return nil, err } + if s.BlobLimit != nil { + return NewRepository(ctx, &s.ComponentRepositoryMeta, r, *s.BlobLimit), nil + } return NewRepository(ctx, &s.ComponentRepositoryMeta, r), nil } diff --git a/docs/reference/ocm_configfile.md b/docs/reference/ocm_configfile.md index ae9e51920d..4f5282064d 100644 --- a/docs/reference/ocm_configfile.md +++ b/docs/reference/ocm_configfile.md @@ -24,6 +24,28 @@ The following configuration types are supported: <name>: <yaml defining the attribute> ... +- blobLimits.ocireg.ocm.config.ocm.software + The config type blobLimits.ocireg.ocm.config.ocm.software can be used to set some + blob layer limits for particular OCI registries used to host OCM repositories. + The blobLimits field maps a OCI registry address to the blob limit to use: + +
+      type: blobLimits.ocireg.ocm.config.ocm.software
+      blobLimits:
+          dummy.io: 65564
+          dummy.io:8443: 32768 // with :8443 specifying the port and 32768 specifying the byte limit
+  
+ + If blob limits apply to a registry, local blobs with a size larger than + the configured limit will be split into several layers with a maximum + size of the given value. + + These settings can be overwritten by explicit settings in an OCM + repository specification for those repositories. + + The most specific entry will be used. If a registry with a dedicated + port is requested, but no explicit configuration is found, the + setting for the sole hostname is used (if configured). - cli.ocm.config.ocm.software The config type cli.ocm.config.ocm.software is used to handle the main configuration flags of the OCM command line tool. From 52ba198f2dad763cfa1e29ccda9b0172e2e16287 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 19:13:12 +0100 Subject: [PATCH 41/50] chore(deps): bump the go group across 1 directory with 13 updates (#1215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the go group with 9 updates in the / directory: | Package | From | To | | --- | --- | --- | | [github.com/aws/aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) | `1.32.6` | `1.32.7` | | [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.28.6` | `1.28.7` | | [github.com/aws/aws-sdk-go-v2/feature/s3/manager](https://github.com/aws/aws-sdk-go-v2) | `1.17.43` | `1.17.44` | | [github.com/aws/aws-sdk-go-v2/service/ecr](https://github.com/aws/aws-sdk-go-v2) | `1.36.7` | `1.38.0` | | [github.com/docker/cli](https://github.com/docker/cli) | `27.4.0+incompatible` | `27.4.1+incompatible` | | [github.com/docker/docker](https://github.com/docker/docker) | `27.4.0+incompatible` | `27.4.1+incompatible` | | [github.com/mittwald/go-helm-client](https://github.com/mittwald/go-helm-client) | `0.12.15` | `0.12.16` | | [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) | `2.22.0` | `2.22.1` | | [github.com/onsi/gomega](https://github.com/onsi/gomega) | `1.36.1` | `1.36.2` | Updates `github.com/aws/aws-sdk-go-v2` from 1.32.6 to 1.32.7
Commits

Updates `github.com/aws/aws-sdk-go-v2/config` from 1.28.6 to 1.28.7
Commits

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.17.47 to 1.17.48
Commits

Updates `github.com/aws/aws-sdk-go-v2/feature/s3/manager` from 1.17.43 to 1.17.44
Commits

Updates `github.com/aws/aws-sdk-go-v2/service/ecr` from 1.36.7 to 1.38.0
Changelog

Sourced from github.com/aws/aws-sdk-go-v2/service/ecr's changelog.

Release (2023-07-31)

General Highlights

  • Feature: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide.
  • Dependency Update: Updated to the latest SDK module versions

Module Highlights

  • github.com/aws/aws-sdk-go-v2/service/amplifyuibuilder: v1.12.0
    • Feature: Amplify Studio releases GraphQL support for codegen job action.
  • github.com/aws/aws-sdk-go-v2/service/autoscaling: v1.30.0
    • Feature: You can now configure an instance refresh to set its status to 'failed' when it detects that a specified CloudWatch alarm has gone into the ALARM state. You can also choose to roll back the instance refresh automatically when the alarm threshold is met.
  • github.com/aws/aws-sdk-go-v2/service/cleanrooms: v1.3.0
    • Feature: This release introduces custom SQL queries - an expanded set of SQL you can run. This release adds analysis templates, a new resource for storing pre-defined custom SQL queries ahead of time. This release also adds the Custom analysis rule, which lets you approve analysis templates for querying.
  • github.com/aws/aws-sdk-go-v2/service/codestarconnections: v1.15.0
    • Feature: New integration with the Gitlab provider type.
  • github.com/aws/aws-sdk-go-v2/service/drs: v1.15.0
    • Feature: Add support for in-aws right sizing
  • github.com/aws/aws-sdk-go-v2/service/inspector2: v1.16.0
    • Feature: This release adds 1 new API: BatchGetFindingDetails to retrieve enhanced vulnerability intelligence details for findings.
  • github.com/aws/aws-sdk-go-v2/service/lookoutequipment: v1.18.0
    • Feature: This release includes new import resource, model versioning and resource policy features.
  • github.com/aws/aws-sdk-go-v2/service/omics: v1.6.0
    • Feature: Add CreationType filter for ListReadSets
  • github.com/aws/aws-sdk-go-v2/service/rds: v1.49.0
    • Feature: This release adds support for Aurora MySQL local write forwarding, which allows for forwarding of write operations from reader DB instances to the writer DB instance.
  • github.com/aws/aws-sdk-go-v2/service/route53: v1.29.0
    • Feature: Amazon Route 53 now supports the Israel (Tel Aviv) Region (il-central-1) for latency records, geoproximity records, and private DNS for Amazon VPCs in that region.
  • github.com/aws/aws-sdk-go-v2/service/scheduler: v1.2.0
    • Feature: This release introduces automatic deletion of schedules in EventBridge Scheduler. If configured, EventBridge Scheduler automatically deletes a schedule after the schedule has completed its last invocation.

Release (2023-07-28.2)

Module Highlights

  • github.com/aws/aws-sdk-go-v2/service/applicationinsights: v1.18.0
    • Feature: This release enable customer to add/remove/update more than one workload for a component
  • github.com/aws/aws-sdk-go-v2/service/cloudformation: v1.33.0
    • Feature: This SDK release is for the feature launch of AWS CloudFormation RetainExceptOnCreate. It adds a new parameter retainExceptOnCreate in the following APIs: CreateStack, UpdateStack, RollbackStack, ExecuteChangeSet.
  • github.com/aws/aws-sdk-go-v2/service/cloudfront: v1.27.0
    • Feature: Add a new JavaScript runtime version for CloudFront Functions.
  • github.com/aws/aws-sdk-go-v2/service/connect: v1.62.0
    • Feature: This release adds support for new number types.
  • github.com/aws/aws-sdk-go-v2/service/kafka: v1.21.0
    • Feature: Amazon MSK has introduced new versions of ListClusterOperations and DescribeClusterOperation APIs. These v2 APIs provide information and insights into the ongoing operations of both MSK Provisioned and MSK Serverless clusters.
  • github.com/aws/aws-sdk-go-v2/service/pinpoint: v1.21.0
    • Feature: Added support for sending push notifications using the FCM v1 API with json credentials. Amazon Pinpoint customers can now deliver messages to Android devices using both FCM v1 API and the legacy FCM/GCM API

Release (2023-07-28)

General Highlights

  • Dependency Update: Updated to the latest SDK module versions

... (truncated)

Commits

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.71.0 to 1.71.1
Commits

Updates `github.com/docker/cli` from 27.4.0+incompatible to 27.4.1+incompatible
Commits
  • b9d17ea Merge pull request #5700 from thaJeztah/27.x_backport_remove_use_of_netfilter...
  • a08a120 cli/command/system: remove BridgeNfIptables, BridgeNfIp6tables in tests
  • 4870b3d Merge pull request #5699 from thaJeztah/27.x_backport_remove_system_isabs
  • d3b59fb cli/command/container: use local copy of pkg/system.IsAbs
  • ac40240 Merge pull request #5685 from thaJeztah/27.x_backport_bump_xx
  • 3fa9480 Merge pull request #5690 from thaJeztah/27.x_backport_bump_gomd2man
  • fce7c04 Merge pull request #5692 from thaJeztah/27.x_backport_remove_netfilter_warnings
  • 70815c1 cli/command/system: remove netfilter warnings from tests
  • 12d98b0 update go-md2man to v2.0.5
  • f9783ec update xx to v1.6.1 for compatibility with alpine 3.21
  • Additional commits viewable in compare view

Updates `github.com/docker/docker` from 27.4.0+incompatible to 27.4.1+incompatible
Release notes

Sourced from github.com/docker/docker's releases.

v27.4.1

27.4.1

For a full list of pull requests and changes in this release, refer to the relevant GitHub milestones:

Bug fixes and enhancements

  • Fix excessive memory allocations when OTel is not configured. moby/moby#49079
  • The docker info command and the corresponding GET /info API endpoint no longer include warnings when bridge-nf-call-iptables or bridge-nf-call-ip6tables are disabled at the daemon is started. The br_netfilter kernel module is now attempted to be loaded when needed, which made those warnings inaccurate. moby/moby#49090
  • Attempt to load kernel modules, including ip6_tables and br_netfilter when required, using a method that is likely to succeed inside a Docker-in-Docker container. moby/moby#49043
  • Fix a bug that could result in an iptables DOCKER FILTER chain not being cleaned up on failure. moby/moby#49110

Deprecations

  • pkg/system: Deprecate Lstat(), Mkdev(), Mknod(), FromStatT() and Stat() functions, and related StatT types. These were only used internally, and will be removed in the next release. moby/moby#49100
  • libnetwork/iptables: Deprecate IPV, Iptables and IP6Tables types in favor of IPVersion, IPv4, and IPv6. This type and consts will be removed in the next release. moby/moby#49093
  • libnetwork/iptables: Deprecate Passthrough. This function was only used internally, and will be removed in the next release. moby/moby#49119

Packaging updates

Commits
  • c710b88 Merge pull request #49119 from thaJeztah/27.x_backport_libnetwork_deprecate_P...
  • eda0a20 libnetwork/iptables: deprecate Passthrough
  • b51622d libnet/iptables: deprecate type IPV
  • 829ac83 Merge pull request #49104 from thaJeztah/27.x_backport_update_swagger_headers
  • bd7da11 Merge pull request #49110 from thaJeztah/27.x_backport_fix_setupIPChains_defer
  • 135b144 Merge pull request #49105 from thaJeztah/27.x_backport_testing-suse-apparmor
  • 08de719 libnetwork/drivers/bridge: setupIPChains: fix defer checking wrong err
  • 2a62319 Merge pull request #49100 from thaJeztah/27.x_backport_deprecate_pkg_system
  • 6855ca1 integration-cli: don't skip AppArmor tests on SLES
  • 224b305 docs/api: document correct case for Api-Version header
  • Additional commits viewable in compare view

Updates `github.com/mittwald/go-helm-client` from 0.12.15 to 0.12.16
Release notes

Sourced from github.com/mittwald/go-helm-client's releases.

v0.12.16

What's Changed

Full Changelog: https://github.com/mittwald/go-helm-client/compare/v0.12.15...v0.12.16

Commits

Updates `github.com/onsi/ginkgo/v2` from 2.22.0 to 2.22.1
Release notes

Sourced from github.com/onsi/ginkgo/v2's releases.

v2.22.1

2.22.1

Fixes

Fix CSV encoding

  • Update tests [aab3da6]
  • Properly encode CSV rows [c09df39]
  • Add test case for proper csv escaping [96a80fc]
  • Add meta-test [43dad69]

Maintenance

  • ensure *.test files are gitignored so we don't accidentally commit compiled tests again [c88c634]
  • remove golang.org/x/net/context in favour of stdlib context [4df44bf]
Changelog

Sourced from github.com/onsi/ginkgo/v2's changelog.

2.22.1

Fixes

Fix CSV encoding

  • Update tests [aab3da6]
  • Properly encode CSV rows [c09df39]
  • Add test case for proper csv escaping [96a80fc]
  • Add meta-test [43dad69]

Maintenance

  • ensure *.test files are gitignored so we don't accidentally commit compiled tests again [c88c634]
  • remove golang.org/x/net/context in favour of stdlib context [4df44bf]
Commits
  • a0190b7 v2.22.1
  • 4df44bf remove golang.org/x/net/context in favour of stdlib context
  • c88c634 ensure *.test files are gitignored so we don't accidentally commit compiled t...
  • aab3da6 Update tests
  • c09df39 Properly encode CSV rows
  • 96a80fc Add test case for proper csv escaping
  • 43dad69 Add meta-test
  • See full diff in compare view

Updates `github.com/onsi/gomega` from 1.36.1 to 1.36.2
Release notes

Sourced from github.com/onsi/gomega's releases.

v1.36.2

Maintenance

Changelog

Sourced from github.com/onsi/gomega's changelog.

1.36.2

Maintenance

  • Bump google.golang.org/protobuf from 1.35.1 to 1.36.1 (#810) [9a7609d]
  • Bump golang.org/x/net from 0.30.0 to 0.33.0 (#807) [b6cb028]
  • Bump github.com/onsi/ginkgo/v2 from 2.20.1 to 2.22.1 (#808) [5756529]
  • Bump nokogiri from 1.16.3 to 1.16.5 in /docs (#757) [dabc12e]
Commits

Updates `golang.org/x/net` from 0.32.0 to 0.33.0
Commits
  • dfc720d go.mod: update golang.org/x dependencies
  • 8e66b04 html: use strings.EqualFold instead of lowering ourselves
  • b935f7b html: avoid endless loop on error token
  • 9af49ef route: remove unused sizeof* consts
  • 6705db9 quic: clean up crypto streams when dropping packet protection keys
  • 4ef7588 quic: handle ACK frame in packet which drops number space
  • 552d8ac Revert "route: change from syscall to x/sys/unix"
  • 13a7c01 Revert "route: remove unused sizeof* consts on freebsd"
  • See full diff in compare view

Updates `helm.sh/helm/v3` from 3.16.3 to 3.16.4
Release notes

Sourced from helm.sh/helm/v3's releases.

Helm v3.16.4 is a patch release. Users are encouraged to upgrade for the best experience. Users are encouraged to upgrade for the best experience.

The community keeps growing, and we'd love to see you there!

  • Join the discussion in Kubernetes Slack:
    • for questions and just to hang out
    • for discussing PRs, code, and bugs
  • Hang out at the Public Developer Call: Thursday, 9:30 Pacific via Zoom
  • Test, debug, and contribute charts: ArtifactHub/packages

Installation and Upgrading

Download Helm v3.16.4. The common platform binaries are here:

This release was signed with 672C 657B E06B 4B30 969C 4A57 4614 49C2 5E36 B98E and can be found at @​mattfarina keybase account. Please use the attached signatures for verifying this release using gpg.

The Quickstart Guide will get you going from there. For upgrade instructions or detailed installation notes, check the install guide. You can also use a script to install on any system with bash.

What's Next

  • 3.17.0 is the next feature release and will be on January 15, 2025

Changelog

  • Bump golang.org/x/crypto from 0.30.0 to 0.31.0 7877b45b63f95635153b29a42c0c2f4273ec45ca (dependabot[bot])
  • Bump the k8s-io group with 7 updates 848e586c27f05d84bc19d082f395098aba0b7619 (dependabot[bot])
Commits
  • 7877b45 Bump golang.org/x/crypto from 0.30.0 to 0.31.0
  • 848e586 Bump the k8s-io group with 7 updates
  • See full diff in compare view

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 50 ++++++++++++++--------------- go.sum | 100 ++++++++++++++++++++++++++++----------------------------- 2 files changed, 75 insertions(+), 75 deletions(-) diff --git a/go.mod b/go.mod index 2eab77b612..b3cbc3eebc 100644 --- a/go.mod +++ b/go.mod @@ -9,12 +9,12 @@ require ( github.com/DataDog/gostackparse v0.7.0 github.com/InfiniteLoopSpace/go_S-MIME v0.0.0-20181221134359-3f58f9a4b2b6 github.com/Masterminds/semver/v3 v3.3.1 - github.com/aws/aws-sdk-go-v2 v1.32.6 - github.com/aws/aws-sdk-go-v2/config v1.28.6 - github.com/aws/aws-sdk-go-v2/credentials v1.17.47 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43 - github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 - github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 + github.com/aws/aws-sdk-go-v2 v1.32.7 + github.com/aws/aws-sdk-go-v2/config v1.28.7 + github.com/aws/aws-sdk-go-v2/credentials v1.17.48 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 + github.com/aws/aws-sdk-go-v2/service/ecr v1.38.0 + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 github.com/cloudflare/cfssl v1.6.5 github.com/containerd/containerd v1.7.24 github.com/containerd/errdefs v1.0.0 @@ -22,8 +22,8 @@ require ( github.com/containers/image/v5 v5.33.0 github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f github.com/distribution/reference v0.6.0 - github.com/docker/cli v27.4.0+incompatible - github.com/docker/docker v27.4.0+incompatible + github.com/docker/cli v27.4.1+incompatible + github.com/docker/docker v27.4.1+incompatible github.com/docker/go-connections v0.5.0 github.com/drone/envsubst v1.0.3 github.com/fluxcd/cli-utils v0.36.0-flux.11 @@ -48,11 +48,11 @@ require ( github.com/marstr/guid v1.1.0 github.com/mikefarah/yq/v4 v4.44.6 github.com/mitchellh/copystructure v1.2.0 - github.com/mittwald/go-helm-client v0.12.15 + github.com/mittwald/go-helm-client v0.12.16 github.com/moby/locker v1.0.1 github.com/modern-go/reflect2 v1.0.2 - github.com/onsi/ginkgo/v2 v2.22.0 - github.com/onsi/gomega v1.36.1 + github.com/onsi/ginkgo/v2 v2.22.1 + github.com/onsi/gomega v1.36.2 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 github.com/pkg/errors v0.9.1 @@ -71,12 +71,12 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 - golang.org/x/net v0.32.0 + golang.org/x/net v0.33.0 golang.org/x/oauth2 v0.24.0 golang.org/x/text v0.21.0 gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.16.3 + helm.sh/helm/v3 v3.16.4 k8s.io/api v0.32.0 k8s.io/apiextensions-apiserver v0.32.0 k8s.io/apimachinery v0.32.0 @@ -128,19 +128,19 @@ require ( github.com/aliyun/credentials-go v1.3.10 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 // indirect github.com/aws/smithy-go v1.22.1 // indirect github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20241009180534-e718692eec62 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -215,7 +215,7 @@ require ( github.com/google/go-github/v55 v55.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/gofuzz v1.2.0 // indirect - github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db // indirect + github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/s2a-go v0.1.8 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/uuid v1.6.0 // indirect @@ -348,7 +348,7 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20241104194629-dd2ea8efbc28 // indirect google.golang.org/grpc v1.68.0 // indirect - google.golang.org/protobuf v1.35.2 // indirect + google.golang.org/protobuf v1.36.1 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index cfe049224b..317846388d 100644 --- a/go.sum +++ b/go.sum @@ -165,48 +165,48 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= -github.com/aws/aws-sdk-go-v2 v1.32.6 h1:7BokKRgRPuGmKkFMhEg/jSul+tB9VvXhcViILtfG8b4= -github.com/aws/aws-sdk-go-v2 v1.32.6/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= +github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= +github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc= -github.com/aws/aws-sdk-go-v2/config v1.28.6 h1:D89IKtGrs/I3QXOLNTH93NJYtDhm8SYa9Q5CsPShmyo= -github.com/aws/aws-sdk-go-v2/config v1.28.6/go.mod h1:GDzxJ5wyyFSCoLkS+UhGB0dArhb9mI+Co4dHtoTxbko= -github.com/aws/aws-sdk-go-v2/credentials v1.17.47 h1:48bA+3/fCdi2yAwVt+3COvmatZ6jUDNkDTIsqDiMUdw= -github.com/aws/aws-sdk-go-v2/credentials v1.17.47/go.mod h1:+KdckOejLW3Ks3b0E3b5rHsr2f9yuORBum0WPnE5o5w= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 h1:AmoU1pziydclFT/xRV+xXE/Vb8fttJCLRPv8oAkprc0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21/go.mod h1:AjUdLYe4Tgs6kpH4Bv7uMZo7pottoyHMn4eTcIcneaY= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43 h1:iLdpkYZ4cXIQMO7ud+cqMWR1xK5ESbt1rvN77tRi1BY= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43/go.mod h1:OgbsKPAswXDd5kxnR4vZov69p3oYjbvUyIRBAAV0y9o= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 h1:s/fF4+yDQDoElYhfIVvSNyeCydfbuTKzhxSXDXCPasU= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25/go.mod h1:IgPfDv5jqFIzQSNbUEMoitNooSMXjRSDkhXv8jiROvU= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 h1:ZntTCl5EsYnhN/IygQEUugpdwbhdkom9uHcbCftiGgA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25/go.mod h1:DBdPrgeocww+CSl1C8cEV8PN1mHMBhuCDLpXezyvWkE= +github.com/aws/aws-sdk-go-v2/config v1.28.7 h1:GduUnoTXlhkgnxTD93g1nv4tVPILbdNQOzav+Wpg7AE= +github.com/aws/aws-sdk-go-v2/config v1.28.7/go.mod h1:vZGX6GVkIE8uECSUHB6MWAUsd4ZcG2Yq/dMa4refR3M= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4afs45mOWEI+MzZtTfQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 h1:2zxMLXLedpB4K1ilbJFxtMKsVKaexOqDttOhc0QGm3Q= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44/go.mod h1:VuLHdqwjSvgftNC7yqPWyGVhEwPmJpeRi07gOgOfHF8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvKgqdiXoTxAF4HQcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25 h1:r67ps7oHCYnflpgDy2LZU0MAQtQbYIOqNNnqGO6xQkE= -github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.25/go.mod h1:GrGY+Q4fIokYLtjCVB/aFfCVL6hhGUFl8inD18fDalE= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7 h1:R+5XKIJga2K9Dkj0/iQ6fD/MBGo02oxGGFTc512lK/Q= -github.com/aws/aws-sdk-go-v2/service/ecr v1.36.7/go.mod h1:fDPQV/6ONOQOjvtKhtypIy1wcGLcKYtoK/lvZ9fyDGQ= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo= +github.com/aws/aws-sdk-go-v2/service/ecr v1.38.0 h1:+1IqznlfeMCgFWoWAuwRqykVc6gGoUUQFGXai+77KWs= +github.com/aws/aws-sdk-go-v2/service/ecr v1.38.0/go.mod h1:NqKnlZvLl4Tp2UH/GEc/nhbjmPQhwOXmLp2eldiszLM= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2 h1:Zru9Iy2JPM5+uRnFnoqeOZzi8JIVIHJ0ua6JdeDHcyg= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2/go.mod h1:PtQC3XjutCYFCn1+i8+wtpDaXvEK+vXF2gyLIKAmh4A= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1/go.mod h1:9nu0fVANtYiAePIBh2/pFUSwtJ402hLnp854CNoDOeE= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6 h1:HCpPsWqmYQieU7SS6E9HXfdAMSud0pteVXieJmcpIRI= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.6/go.mod h1:ngUiVRCco++u+soRRVBIvBZxSMMvOVMXA4PJ36JLfSw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 h1:50+XsN70RS7dwJ2CkVNXzj7U2L1HKP8nqTd3XWEXBN4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6/go.mod h1:WqgLmwY7so32kG01zD8CPTJWVWM+TzJoOVHwTg4aPug= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6 h1:BbGDtTi0T1DYlmjBiCr/le3wzhA37O8QTC5/Ab8+EXk= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.6/go.mod h1:hLMJt7Q8ePgViKupeymbqI0la+t9/iYFBjxQCFwuAwI= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7 h1:tB4tNw83KcajNAzaIMhkhVI2Nt8fAZd5A5ro113FEMY= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.7/go.mod h1:lvpyBGkZ3tZ9iSsUIcC2EWp+0ywa7aK3BLT+FwZi+mQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7 h1:8eUsivBQzZHqe/3FE+cqwfH+0p5Jo8PFM/QYQSmeZ+M= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.7/go.mod h1:kLPQvGUmxn/fqiCrDeohwG33bq2pQpGeY62yRO6Nrh0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEHWM0bJ1QcBzxLrL/k2DHvGYhb8+W1w= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5 h1:5dQJ6Q5QrQOqZxXjSbRXukBqU8Pgu6Ro6Qqtyd8yiz4= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5/go.mod h1:A9vfQcNHVBCE7ZZN6H+UUJpXtbH26Vv6L7Zhk5nIJAY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 h1:nyuzXooUNJexRT0Oy0UQY6AhOzxPxhtt4DcBIHyCnmw= -github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0/go.mod h1:sT/iQz8JK3u/5gZkT+Hmr7GzVZehUMkRZpOaAwYXeGY= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 h1:rLnYAfXQ3YAccocshIH5mzNNwZBkBo+bP6EhIxak6Hw= -github.com/aws/aws-sdk-go-v2/service/sso v1.24.7/go.mod h1:ZHtuQJ6t9A/+YDuxOLnbryAmITtr8UysSny3qcyvJTc= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 h1:JnhTZR3PiYDNKlXy50/pNeix9aGMo6lLpXwJ1mw8MD4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6/go.mod h1:URronUEGfXZN1VpdktPSD1EkAL9mfrV+2F4sjH38qOY= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 h1:s4074ZO1Hk8qv65GqNXqDjmkf4HSQqJukaLuuW0TpDA= -github.com/aws/aws-sdk-go-v2/service/sts v1.33.2/go.mod h1:mVggCnIWoM09jP71Wh+ea7+5gAp53q+49wDFs1SW5z8= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 h1:aOVVZJgWbaH+EJYPvEgkNhCEbXXvH7+oML36oaPK3zE= +github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= +github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3 h1:Xgv/hyNgvLda/M9l9qxXc4UFSgppnRczLxlMs5Ae/QY= +github.com/aws/aws-sdk-go-v2/service/sts v1.33.3/go.mod h1:5Gn+d+VaaRgsjewpMvGazt0WfcFO+Md4wLOuBfGR9Bc= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20241009180534-e718692eec62 h1:T5b8GwBFIlqQzAbqTNcyLvzcAvJ09MXrF6zyUlIic8A= @@ -337,13 +337,13 @@ github.com/distribution/distribution/v3 v3.0.0-beta.1 h1:X+ELTxPuZ1Xe5MsD3kp2wfG github.com/distribution/distribution/v3 v3.0.0-beta.1/go.mod h1:O9O8uamhHzWWQVTjuQpyYUVm/ShPHPUDgvQMpHGVBDs= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/cli v27.4.0+incompatible h1:/nJzWkcI1MDMN+U+px/YXnQWJqnu4J+QKGTfD6ptiTc= -github.com/docker/cli v27.4.0+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/cli v27.4.1+incompatible h1:VzPiUlRJ/xh+otB75gva3r05isHMo5wXDfPRi5/b4hI= +github.com/docker/cli v27.4.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBirtxJnzDrHLEKxTAYk= github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v27.4.0+incompatible h1:I9z7sQ5qyzO0BfAb9IMOawRkAGxhYsidKiTMcm0DU+A= -github.com/docker/docker v27.4.0+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v27.4.1+incompatible h1:ZJvcY7gfwHn1JF48PfbyXg7Jyt9ZCWDW+GGXOIxEwp4= +github.com/docker/docker v27.4.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker-credential-helpers v0.8.2 h1:bX3YxiGzFP5sOXWc3bTPEXdEaZSeVMrFgOr3T+zrFAo= github.com/docker/docker-credential-helpers v0.8.2/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go v1.5.1-1.0.20160303222718-d30aec9fd63c h1:lzqkGL9b3znc+ZUgi7FlLnqjQhcXxkNM/quxIjBVMD0= @@ -546,8 +546,8 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= -github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg= +github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/s2a-go v0.1.8 h1:zZDs9gcbt9ZPLV0ndSyQk6Kacx2g/X+SKYovpnz3SMM= github.com/google/s2a-go v0.1.8/go.mod h1:6iNWHTpQ+nfNRN5E00MSdfDwVesa8hhS32PhPO8deJA= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -736,8 +736,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/mittwald/go-helm-client v0.12.15 h1:Ks7ccT3XflaCJ0/453qJLeVKlXo+K+buFehkFG0UWOE= -github.com/mittwald/go-helm-client v0.12.15/go.mod h1:LRRoErsgdw0TUVE8fXcwb1npRKibHGUQexiPhqc/UXA= +github.com/mittwald/go-helm-client v0.12.16 h1:YTyJX6L0SI/O7HNTG0qDZI2/jyGELxJOQEjvTj4mf6k= +github.com/mittwald/go-helm-client v0.12.16/go.mod h1:PDF7Ra8bmJ2YTNzoehoMMi+gW/EJBk/4TLz7j52rehY= github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= @@ -792,15 +792,15 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= -github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= +github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= -github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= -github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9 h1:b2cJvZ8nWAVvCqvPhUaFl26Wht4nM4mqfl2ksY9lVzU= github.com/open-component-model/cobra v0.0.0-20230329075350-b1fd876abfb9/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/open-policy-agent/opa v0.68.0 h1:Jl3U2vXRjwk7JrHmS19U3HZO5qxQRinQbJ2eCJYSqJQ= @@ -1155,8 +1155,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= -golang.org/x/net v0.32.0 h1:ZqPmj8Kzc+Y6e0+skZsuACbx+wzMgo5MQsJh9Qd6aYI= -golang.org/x/net v0.32.0/go.mod h1:CwU0IoeOlnQQWJ6ioyFrfRuomB8GKF6KbYXZVyeXNfs= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= @@ -1292,8 +1292,8 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.35.2 h1:8Ar7bF+apOIoThw1EdZl0p1oWvMqTHmpA2fRTyZO8io= -google.golang.org/protobuf v1.35.2/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= +google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= @@ -1330,8 +1330,8 @@ gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= -helm.sh/helm/v3 v3.16.3 h1:kb8bSxMeRJ+knsK/ovvlaVPfdis0X3/ZhYCSFRP+YmY= -helm.sh/helm/v3 v3.16.3/go.mod h1:zeVWGDR4JJgiRbT3AnNsjYaX8OTJlIE9zC+Q7F7iUSU= +helm.sh/helm/v3 v3.16.4 h1:rBn/h9MACw+QlhxQTjpl8Ifx+VTWaYsw3rguGBYBzr0= +helm.sh/helm/v3 v3.16.4/go.mod h1:k8QPotUt57wWbi90w3LNmg3/MWcLPigVv+0/X4B8BzA= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= From a6e2e9c88775716817e658907f96ad5f3da451f6 Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Sun, 29 Dec 2024 18:29:25 +0000 Subject: [PATCH 42/50] chore: update 'flake.nix' (#1216) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 653312c44d..1d55dd0504 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-hDIJjccA6G34X0AAGsPDjZuWfgW0BeiGerv6JGb4Sq8="; + vendorHash = "sha256-LazrpYWFoa2Atbh7V6q3uM+xydKIfAXPz/jiHVWPo+4="; src = ./.; From b20d02789fb3a5410e6c5633dbc84d94e5fc599c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 5 Jan 2025 17:21:50 +0100 Subject: [PATCH 43/50] chore(deps): bump the go group with 5 updates (#1219) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the go group with 5 updates: | Package | From | To | | --- | --- | --- | | [github.com/aws/aws-sdk-go-v2/feature/s3/manager](https://github.com/aws/aws-sdk-go-v2) | `1.17.44` | `1.17.45` | | [github.com/aws/aws-sdk-go-v2/service/ecr](https://github.com/aws/aws-sdk-go-v2) | `1.38.0` | `1.38.1` | | [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.71.1` | `1.72.0` | | [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) | `2.22.1` | `2.22.2` | | [golang.org/x/oauth2](https://github.com/golang/oauth2) | `0.24.0` | `0.25.0` | Updates `github.com/aws/aws-sdk-go-v2/feature/s3/manager` from 1.17.44 to 1.17.45
Commits

Updates `github.com/aws/aws-sdk-go-v2/service/ecr` from 1.38.0 to 1.38.1
Changelog

Sourced from github.com/aws/aws-sdk-go-v2/service/ecr's changelog.

Release (2023-08-01)

General Highlights

  • Dependency Update: Updated to the latest SDK module versions

Module Highlights

  • github.com/aws/aws-sdk-go-v2/service/batch: v1.26.0
    • Feature: This release adds support for price capacity optimized allocation strategy for Spot Instances.
  • github.com/aws/aws-sdk-go-v2/service/databasemigrationservice: v1.29.0
    • Feature: Adding new API describe-engine-versions which provides information about the lifecycle of a replication instance's version.
  • github.com/aws/aws-sdk-go-v2/service/internetmonitor: v1.5.0
    • Feature: This release adds a new feature for Amazon CloudWatch Internet Monitor that enables customers to set custom thresholds, for performance and availability drops, for impact limited to a single city-network to trigger creation of a health event.
  • github.com/aws/aws-sdk-go-v2/service/medialive: v1.34.0
    • Feature: AWS Elemental Link devices now report their Availability Zone. Link devices now support the ability to change their Availability Zone.
  • github.com/aws/aws-sdk-go-v2/service/polly: v1.29.0
    • Feature: Amazon Polly adds new French Belgian voice - Isabelle. Isabelle is available as Neural voice only.
  • github.com/aws/aws-sdk-go-v2/service/rds: v1.50.0
    • Feature: Added support for deleted clusters PiTR.
  • github.com/aws/aws-sdk-go-v2/service/sagemaker: v1.97.0
    • Feature: Add Stairs TrafficPattern and FlatInvocations to RecommendationJobStoppingConditions

Release (2023-07-31)

General Highlights

  • Feature: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide.
  • Dependency Update: Updated to the latest SDK module versions

Module Highlights

  • github.com/aws/aws-sdk-go-v2/service/amplifyuibuilder: v1.12.0
    • Feature: Amplify Studio releases GraphQL support for codegen job action.
  • github.com/aws/aws-sdk-go-v2/service/autoscaling: v1.30.0
    • Feature: You can now configure an instance refresh to set its status to 'failed' when it detects that a specified CloudWatch alarm has gone into the ALARM state. You can also choose to roll back the instance refresh automatically when the alarm threshold is met.
  • github.com/aws/aws-sdk-go-v2/service/cleanrooms: v1.3.0
    • Feature: This release introduces custom SQL queries - an expanded set of SQL you can run. This release adds analysis templates, a new resource for storing pre-defined custom SQL queries ahead of time. This release also adds the Custom analysis rule, which lets you approve analysis templates for querying.
  • github.com/aws/aws-sdk-go-v2/service/codestarconnections: v1.15.0
    • Feature: New integration with the Gitlab provider type.
  • github.com/aws/aws-sdk-go-v2/service/drs: v1.15.0
    • Feature: Add support for in-aws right sizing
  • github.com/aws/aws-sdk-go-v2/service/inspector2: v1.16.0
    • Feature: This release adds 1 new API: BatchGetFindingDetails to retrieve enhanced vulnerability intelligence details for findings.
  • github.com/aws/aws-sdk-go-v2/service/lookoutequipment: v1.18.0
    • Feature: This release includes new import resource, model versioning and resource policy features.
  • github.com/aws/aws-sdk-go-v2/service/omics: v1.6.0
    • Feature: Add CreationType filter for ListReadSets
  • github.com/aws/aws-sdk-go-v2/service/rds: v1.49.0
    • Feature: This release adds support for Aurora MySQL local write forwarding, which allows for forwarding of write operations from reader DB instances to the writer DB instance.
  • github.com/aws/aws-sdk-go-v2/service/route53: v1.29.0
    • Feature: Amazon Route 53 now supports the Israel (Tel Aviv) Region (il-central-1) for latency records, geoproximity records, and private DNS for Amazon VPCs in that region.
  • github.com/aws/aws-sdk-go-v2/service/scheduler: v1.2.0
    • Feature: This release introduces automatic deletion of schedules in EventBridge Scheduler. If configured, EventBridge Scheduler automatically deletes a schedule after the schedule has completed its last invocation.

... (truncated)

Commits

Updates `github.com/aws/aws-sdk-go-v2/service/s3` from 1.71.1 to 1.72.0
Commits

Updates `github.com/onsi/ginkgo/v2` from 2.22.1 to 2.22.2
Release notes

Sourced from github.com/onsi/ginkgo/v2's releases.

v2.22.2

What's Changed

Full Changelog: https://github.com/onsi/ginkgo/compare/v2.22.1...v2.22.2

Changelog

Sourced from github.com/onsi/ginkgo/v2's changelog.

2.22.2

Maintenance

  • Bump github.com/onsi/gomega from 1.36.1 to 1.36.2 (#1499) [cc553ce]
  • Bump golang.org/x/crypto (#1498) [2170370]
  • Bump golang.org/x/net from 0.32.0 to 0.33.0 (#1496) [a96c44f]
Commits

Updates `golang.org/x/oauth2` from 0.24.0 to 0.25.0
Commits

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index b3cbc3eebc..fbd7e49fce 100644 --- a/go.mod +++ b/go.mod @@ -12,9 +12,9 @@ require ( github.com/aws/aws-sdk-go-v2 v1.32.7 github.com/aws/aws-sdk-go-v2/config v1.28.7 github.com/aws/aws-sdk-go-v2/credentials v1.17.48 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 - github.com/aws/aws-sdk-go-v2/service/ecr v1.38.0 - github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.45 + github.com/aws/aws-sdk-go-v2/service/ecr v1.38.1 + github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 github.com/cloudflare/cfssl v1.6.5 github.com/containerd/containerd v1.7.24 github.com/containerd/errdefs v1.0.0 @@ -51,7 +51,7 @@ require ( github.com/mittwald/go-helm-client v0.12.16 github.com/moby/locker v1.0.1 github.com/modern-go/reflect2 v1.0.2 - github.com/onsi/ginkgo/v2 v2.22.1 + github.com/onsi/ginkgo/v2 v2.22.2 github.com/onsi/gomega v1.36.2 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 @@ -72,7 +72,7 @@ require ( golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 golang.org/x/net v0.33.0 - golang.org/x/oauth2 v0.24.0 + golang.org/x/oauth2 v0.25.0 golang.org/x/text v0.21.0 gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 diff --git a/go.sum b/go.sum index 317846388d..0dd5a350bd 100644 --- a/go.sum +++ b/go.sum @@ -175,8 +175,8 @@ github.com/aws/aws-sdk-go-v2/credentials v1.17.48 h1:IYdLD1qTJ0zanRavulofmqut4af github.com/aws/aws-sdk-go-v2/credentials v1.17.48/go.mod h1:tOscxHN3CGmuX9idQ3+qbkzrjVIx32lqDSU1/0d/qXs= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22 h1:kqOrpojG71DxJm/KDPO+Z/y1phm1JlC8/iT+5XRmAn8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.22/go.mod h1:NtSFajXVVL8TA2QNngagVZmUtXciyrHOt7xgz4faS/M= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44 h1:2zxMLXLedpB4K1ilbJFxtMKsVKaexOqDttOhc0QGm3Q= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.44/go.mod h1:VuLHdqwjSvgftNC7yqPWyGVhEwPmJpeRi07gOgOfHF8= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.45 h1:ZxB8WFVYwolhDZxuZXoesHkl+L9cXLWy0K/G0QkNATc= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.45/go.mod h1:1krrbyoFFDqaNldmltPTP+mK3sAXLHPoaFtISOw2Hkk= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= @@ -185,8 +185,8 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 h1:VaRN3TlFdd6KxX1x3ILT5ynH6HvK github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1/go.mod h1:FbtygfRFze9usAadmnGJNc8KsP346kEe+y2/oyhGAGc= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26 h1:GeNJsIFHB+WW5ap2Tec4K6dzcVTsRbsT1Lra46Hv9ME= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.26/go.mod h1:zfgMpwHDXX2WGoG84xG2H+ZlPTkJUU4YUvx2svLQYWo= -github.com/aws/aws-sdk-go-v2/service/ecr v1.38.0 h1:+1IqznlfeMCgFWoWAuwRqykVc6gGoUUQFGXai+77KWs= -github.com/aws/aws-sdk-go-v2/service/ecr v1.38.0/go.mod h1:NqKnlZvLl4Tp2UH/GEc/nhbjmPQhwOXmLp2eldiszLM= +github.com/aws/aws-sdk-go-v2/service/ecr v1.38.1 h1:pCI3RIJnZEUs0evNm+pdDzvAp+YwpabUyQTPPvxO8oY= +github.com/aws/aws-sdk-go-v2/service/ecr v1.38.1/go.mod h1:NqKnlZvLl4Tp2UH/GEc/nhbjmPQhwOXmLp2eldiszLM= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2 h1:Zru9Iy2JPM5+uRnFnoqeOZzi8JIVIHJ0ua6JdeDHcyg= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.27.2/go.mod h1:PtQC3XjutCYFCn1+i8+wtpDaXvEK+vXF2gyLIKAmh4A= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 h1:iXtILhvDxB6kPvEXgsDhGaZCSC6LQET5ZHSdJozeI0Y= @@ -199,8 +199,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7 h1:Hi0KGbrnr57bEH github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.7/go.mod h1:wKNgWgExdjjrm4qvfbTorkvocEstaoDl4WCvGfeCy9c= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5 h1:5dQJ6Q5QrQOqZxXjSbRXukBqU8Pgu6Ro6Qqtyd8yiz4= github.com/aws/aws-sdk-go-v2/service/kms v1.37.5/go.mod h1:A9vfQcNHVBCE7ZZN6H+UUJpXtbH26Vv6L7Zhk5nIJAY= -github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1 h1:aOVVZJgWbaH+EJYPvEgkNhCEbXXvH7+oML36oaPK3zE= -github.com/aws/aws-sdk-go-v2/service/s3 v1.71.1/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= +github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0 h1:SAfh4pNx5LuTafKKWR02Y+hL3A+3TX8cTKG1OIAJaBk= +github.com/aws/aws-sdk-go-v2/service/s3 v1.72.0/go.mod h1:r+xl5yzMk9083rMR+sJ5TYj9Tihvf/l1oxzZXDgGj2Q= github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= @@ -792,8 +792,8 @@ github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vv github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= -github.com/onsi/ginkgo/v2 v2.22.1 h1:QW7tbJAUDyVDVOM5dFa7qaybo+CRfR7bemlQUN6Z8aM= -github.com/onsi/ginkgo/v2 v2.22.1/go.mod h1:S6aTpoRsSq2cZOd+pssHAlKW/Q/jZt6cPrPlnj4a1xM= +github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU= +github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= @@ -1158,8 +1158,8 @@ golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.24.0 h1:KTBBxWqUa0ykRPLtV69rRto9TLXcqYkeswu48x/gvNE= -golang.org/x/oauth2 v0.24.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= +golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From d8559ce9199943bc42773e9351e42cce8fc149b3 Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 08:43:20 +0100 Subject: [PATCH 44/50] chore: update 'flake.nix' (#1220) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index 1d55dd0504..befdba47c8 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-LazrpYWFoa2Atbh7V6q3uM+xydKIfAXPz/jiHVWPo+4="; + vendorHash = "sha256-D5uEj20XEPSVXggzZsLiBM8KifkxapX9ISUQbDsgPmk="; src = ./.; From 48c3ea2b9c25509d7d8e6b454cd47ce5d62613aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Mon, 6 Jan 2025 10:33:39 +0100 Subject: [PATCH 45/50] feat: git Access, AccessMethod through BlobAccess (#869) #### What this PR does / why we need it: ~This is an extremely early (WIP) draft of implementing ctf archives in directory format tracked via git repositories, ultimately serving me as a playground to get familiar with OCM and also to play around with its feature set. So we do not need to merge this if there is no interest or disagreement on the implementation.~ This PR has developed into the development of a pure access method and input method that can be used to work with arbitrary git repositories. Examples for a component constructor could be: ``` name: test.de/x version: %s provider: name: ocm resources: - name: hello-world-access type: git version: 0.0.1 access: type: git commit: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d" ref: refs/heads/master repository: https://github.com/octocat/Hello-World.git - name: hello-world-input type: git version: 0.0.1 input: type: git ref: refs/heads/master commit: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d" repository: https://github.com/octocat/Hello-World.git ``` ~Not only does this allow using git repositories for storing blobs, it also attempts to add git downloader functionality for a generic git access method based on in memory cloning and I plan to add a OCM implementation on it as well.~ While the download is available, this is not laid out to the CLI, library only. ~Currently the implementation is written so that any modification to the CTF in the work directory also triggers a dedicated commit, and any lookup triggers a refres/pull cycle on git.~ For testing I use `file://` URLs which makes it quite easy to verify E2E in the test suites. TODO: - [X] Implement Access Credential mapping - [x] Make Git Client thread-safe, optionally in-memory and allow more customization (currently hard bount to one target ref that I am creating or syncing against, see tests for examples) - [X] Expand Git Options - Authentication support for repo and client #### Which issue(s) this PR fixes: ~As this is my own "experimentation" issue, it doesnt necessarily fix anything, it might as well be moved to a plugin for example or be scrapped alltogether~ Creates an access method for arbitrary git repositories using git-go. --------- Co-authored-by: Gergely Brautigam <182850+skarlso@users.noreply.github.com> --- api/credentials/builtin/init.go | 1 + api/oci/cpi/support/base.go | 12 +- api/oci/internal/uniform.go | 2 +- .../artifactaccess/gitaccess/options.go | 58 +++++ .../artifactaccess/gitaccess/resource.go | 25 +++ .../extensions/accessmethods/git/README.md | 93 ++++++++ api/ocm/extensions/accessmethods/git/cli.go | 43 ++++ .../extensions/accessmethods/git/method.go | 140 ++++++++++++ .../accessmethods/git/method_test.go | 167 ++++++++++++++ .../accessmethods/git/suite_test.go | 13 ++ .../git/testdata/repo/file_in_repo | 1 + api/ocm/extensions/accessmethods/init.go | 1 + api/tech/git/auth.go | 46 ++++ api/tech/git/fs.go | 177 +++++++++++++++ api/tech/git/identity/identity.go | 131 +++++++++++ api/tech/git/identity/identity_test.go | 132 +++++++++++ api/tech/git/identity/suite_test.go | 13 ++ api/tech/git/logging.go | 5 + api/tech/git/resolver.go | 212 ++++++++++++++++++ api/tech/git/resolver_test.go | 112 +++++++++ api/tech/git/suite_test.go | 13 ++ api/tech/git/testdata/repo/file_in_repo | 1 + api/utils/blobaccess/git/access.go | 136 +++++++++++ api/utils/blobaccess/git/access_test.go | 153 +++++++++++++ api/utils/blobaccess/git/digest.go | 7 + api/utils/blobaccess/git/options.go | 194 ++++++++++++++++ api/utils/blobaccess/git/suite_test.go | 13 ++ .../blobaccess/git/testdata/repo/file_in_repo | 1 + .../ocmcmds/common/inputs/types/git/cli.go | 20 ++ .../common/inputs/types/git/input_test.go | 125 +++++++++++ .../ocmcmds/common/inputs/types/git/spec.go | 77 +++++++ .../common/inputs/types/git/suite_test.go | 13 ++ .../inputs/types/git/testdata/resources1.yaml | 6 + .../ocmcmds/common/inputs/types/git/type.go | 33 +++ .../ocmcmds/common/inputs/types/init.go | 1 + .../ocm_add_resource-configuration.md | 47 ++++ docs/reference/ocm_add_resources.md | 47 ++++ .../reference/ocm_add_source-configuration.md | 47 ++++ docs/reference/ocm_add_sources.md | 47 ++++ docs/reference/ocm_credential-handling.md | 13 ++ docs/reference/ocm_get_credentials.md | 13 ++ docs/reference/ocm_logging.md | 1 + docs/reference/ocm_ocm-accessmethods.md | 24 ++ go.mod | 12 + go.sum | 39 +++- 45 files changed, 2458 insertions(+), 9 deletions(-) create mode 100644 api/ocm/elements/artifactaccess/gitaccess/options.go create mode 100644 api/ocm/elements/artifactaccess/gitaccess/resource.go create mode 100644 api/ocm/extensions/accessmethods/git/README.md create mode 100644 api/ocm/extensions/accessmethods/git/cli.go create mode 100644 api/ocm/extensions/accessmethods/git/method.go create mode 100644 api/ocm/extensions/accessmethods/git/method_test.go create mode 100644 api/ocm/extensions/accessmethods/git/suite_test.go create mode 100644 api/ocm/extensions/accessmethods/git/testdata/repo/file_in_repo create mode 100644 api/tech/git/auth.go create mode 100644 api/tech/git/fs.go create mode 100644 api/tech/git/identity/identity.go create mode 100644 api/tech/git/identity/identity_test.go create mode 100644 api/tech/git/identity/suite_test.go create mode 100644 api/tech/git/logging.go create mode 100644 api/tech/git/resolver.go create mode 100644 api/tech/git/resolver_test.go create mode 100644 api/tech/git/suite_test.go create mode 100644 api/tech/git/testdata/repo/file_in_repo create mode 100644 api/utils/blobaccess/git/access.go create mode 100644 api/utils/blobaccess/git/access_test.go create mode 100644 api/utils/blobaccess/git/digest.go create mode 100644 api/utils/blobaccess/git/options.go create mode 100644 api/utils/blobaccess/git/suite_test.go create mode 100644 api/utils/blobaccess/git/testdata/repo/file_in_repo create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/git/cli.go create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/git/input_test.go create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/git/spec.go create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/git/suite_test.go create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/git/testdata/resources1.yaml create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/git/type.go diff --git a/api/credentials/builtin/init.go b/api/credentials/builtin/init.go index 7b7cc5062d..d06d239ae2 100644 --- a/api/credentials/builtin/init.go +++ b/api/credentials/builtin/init.go @@ -2,4 +2,5 @@ package builtin import ( _ "ocm.software/ocm/api/credentials/builtin/github" + _ "ocm.software/ocm/api/tech/git/identity" ) diff --git a/api/oci/cpi/support/base.go b/api/oci/cpi/support/base.go index 60cbf0a79c..5d3568bf33 100644 --- a/api/oci/cpi/support/base.go +++ b/api/oci/cpi/support/base.go @@ -31,18 +31,18 @@ func (a *artifactBase) IsReadOnly() bool { } func (a *artifactBase) IsIndex() bool { - d := a.state.GetState().(*artdesc.Artifact) - return d.IsIndex() + d, ok := a.state.GetState().(*artdesc.Artifact) + return ok && d.IsIndex() } func (a *artifactBase) IsManifest() bool { - d := a.state.GetState().(*artdesc.Artifact) - return d.IsManifest() + d, ok := a.state.GetState().(*artdesc.Artifact) + return ok && d.IsManifest() } func (a *artifactBase) IsValid() bool { - d := a.state.GetState().(*artdesc.Artifact) - return d.IsValid() + d, ok := a.state.GetState().(*artdesc.Artifact) + return ok && d.IsValid() } func (a *artifactBase) blob() (cpi.BlobAccess, error) { diff --git a/api/oci/internal/uniform.go b/api/oci/internal/uniform.go index d35d102afb..32e3b0ef89 100644 --- a/api/oci/internal/uniform.go +++ b/api/oci/internal/uniform.go @@ -31,7 +31,7 @@ type UniformRepositorySpec struct { // Host is the hostname of an oci ref. Host string `json:"host,omitempty"` // Info is the file path used to host ctf component versions - Info string `json:"filePath,omitempty"` + Info string `json:"info,omitempty"` // CreateIfMissing indicates whether a file based or dynamic repo should be created if it does not exist CreateIfMissing bool `json:"createIfMissing,omitempty"` diff --git a/api/ocm/elements/artifactaccess/gitaccess/options.go b/api/ocm/elements/artifactaccess/gitaccess/options.go new file mode 100644 index 0000000000..5b569f1f0f --- /dev/null +++ b/api/ocm/elements/artifactaccess/gitaccess/options.go @@ -0,0 +1,58 @@ +package gitaccess + +import ( + "github.com/mandelsoft/goutils/optionutils" +) + +type Option = optionutils.Option[*Options] + +type Options struct { + URL string + Ref string + Commit string +} + +var _ Option = (*Options)(nil) + +func (o *Options) ApplyTo(opts *Options) { + if o.URL != "" { + opts.URL = o.URL + } +} + +func (o *Options) Apply(opts ...Option) { + optionutils.ApplyOptions(o, opts...) +} + +// ////////////////////////////////////////////////////////////////////////////// +// Local options + +type url string + +func (h url) ApplyTo(opts *Options) { + opts.URL = string(h) +} + +func WithURL(h string) Option { + return url(h) +} + +type ref string + +func (h ref) ApplyTo(opts *Options) { + opts.Ref = string(h) +} + +func WithRef(h string) Option { + return ref(h) +} + +type commitSpec string + +func (h commitSpec) ApplyTo(opts *Options) { + opts.Commit = string(h) +} + +func WithCommit(c string) Option { + return commitSpec(c) +} diff --git a/api/ocm/elements/artifactaccess/gitaccess/resource.go b/api/ocm/elements/artifactaccess/gitaccess/resource.go new file mode 100644 index 0000000000..24ade26b33 --- /dev/null +++ b/api/ocm/elements/artifactaccess/gitaccess/resource.go @@ -0,0 +1,25 @@ +package gitaccess + +import ( + "github.com/mandelsoft/goutils/optionutils" + + "ocm.software/ocm/api/ocm" + "ocm.software/ocm/api/ocm/compdesc" + "ocm.software/ocm/api/ocm/cpi" + "ocm.software/ocm/api/ocm/elements/artifactaccess/genericaccess" + access "ocm.software/ocm/api/ocm/extensions/accessmethods/git" + resourcetypes "ocm.software/ocm/api/ocm/extensions/artifacttypes" +) + +const TYPE = resourcetypes.DIRECTORY_TREE + +func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, opts ...Option) cpi.ArtifactAccess[M] { + eff := optionutils.EvalOptions(opts...) + if meta.GetType() == "" { + meta.SetType(TYPE) + } + + spec := access.New(eff.URL, access.WithRef(eff.Ref), access.WithCommit(eff.Commit)) + // is global access, must work, otherwise there is an error in the lib. + return genericaccess.MustAccess(ctx, meta, spec) +} diff --git a/api/ocm/extensions/accessmethods/git/README.md b/api/ocm/extensions/accessmethods/git/README.md new file mode 100644 index 0000000000..53adeffbd9 --- /dev/null +++ b/api/ocm/extensions/accessmethods/git/README.md @@ -0,0 +1,93 @@ + +# Access Method `git` - Git Commit Access + +## Synopsis + +```yaml +type: git/v1 +``` + +Provided blobs use the following media type for: `application/x-tgz` + +The artifact content is provided as gnu-zipped tar archive + +### Description + +This method implements the access of the content of a git commit stored in a +git repository. + +Supported specification version is `v1alpha1` + +### Specification Versions + +#### Version `v1alpha1` + +The type specific specification fields are: + +- **`repository`** *string* + + Repository URL with or without scheme. + +- **`ref`** (optional) *string* + + Original ref used to get the commit from + +- **`commit`** *string* + + The sha/id of the git commit + +### Go Bindings + +The go binding can be found [here](method.go) + +#### Example + +```go +package main + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "fmt" + "io" + + "ocm.software/ocm/api/ocm" + "ocm.software/ocm/api/ocm/cpi" + me "ocm.software/ocm/api/ocm/extensions/accessmethods/git" +) + +func main() { + ctx := ocm.New() + accessSpec := me.New( + "https://github.com/octocat/Hello-World.git", + me.WithRef("refs/heads/master"), + ) + method, err := accessSpec.AccessMethod(&cpi.DummyComponentVersionAccess{Context: ctx}) + if err != nil { + panic(err) + } + content, err := method.GetContent() + if err != nil { + panic(err) + } + unzippedContent, err := gzip.NewReader(bytes.NewReader(content)) + + r := tar.NewReader(unzippedContent) + + file, err := r.Next() + if err != nil { + panic(err) + } + + if file.Name != "README.md" { + panic("Expected README.md") + } + + data, err := io.ReadAll(r) + if err != nil { + panic(err) + } + fmt.Println(string(data)) +} +``` diff --git a/api/ocm/extensions/accessmethods/git/cli.go b/api/ocm/extensions/accessmethods/git/cli.go new file mode 100644 index 0000000000..fc0dce7d90 --- /dev/null +++ b/api/ocm/extensions/accessmethods/git/cli.go @@ -0,0 +1,43 @@ +package git + +import ( + "ocm.software/ocm/api/ocm/extensions/accessmethods/options" + "ocm.software/ocm/api/utils/cobrautils/flagsets" +) + +func ConfigHandler() flagsets.ConfigOptionTypeSetHandler { + return flagsets.NewConfigOptionTypeSetHandler( + Type, AddConfig, + options.RepositoryOption, + options.ReferenceOption, + options.CommitOption, + ) +} + +func AddConfig(opts flagsets.ConfigOptions, config flagsets.Config) error { + flagsets.AddFieldByOptionP(opts, options.RepositoryOption, config, "repository", "repo", "repoUrl", "repoURL") + flagsets.AddFieldByOptionP(opts, options.CommitOption, config, "commit") + flagsets.AddFieldByOptionP(opts, options.ReferenceOption, config, "ref") + return nil +} + +var usage = ` +This method implements the access of the content of a git commit stored in a +Git repository. +` + +var formatV1 = ` +The type specific specification fields are: + +- **repoUrl** *string* + + Repository URL with or without scheme. + +- **ref** (optional) *string* + + Original ref used to get the commit from + +- **commit** *string* + + The sha/id of the git commit +` diff --git a/api/ocm/extensions/accessmethods/git/method.go b/api/ocm/extensions/accessmethods/git/method.go new file mode 100644 index 0000000000..b43b96841e --- /dev/null +++ b/api/ocm/extensions/accessmethods/git/method.go @@ -0,0 +1,140 @@ +package git + +import ( + "fmt" + + "github.com/go-git/go-git/v5/plumbing" + "github.com/mandelsoft/goutils/errors" + giturls "github.com/whilp/git-urls" + + "ocm.software/ocm/api/credentials" + "ocm.software/ocm/api/datacontext/attrs/vfsattr" + "ocm.software/ocm/api/ocm/cpi/accspeccpi" + "ocm.software/ocm/api/ocm/internal" + "ocm.software/ocm/api/tech/git/identity" + "ocm.software/ocm/api/utils/blobaccess/blobaccess" + gitblob "ocm.software/ocm/api/utils/blobaccess/git" + "ocm.software/ocm/api/utils/mime" + "ocm.software/ocm/api/utils/runtime" +) + +const ( + Type = "git" + TypeV1Alpha1 = Type + runtime.VersionSeparator + "v1alpha1" +) + +func init() { + // If we remove the default registration, also the docs are gone. + // so we leave the default registration in. + accspeccpi.RegisterAccessType(accspeccpi.NewAccessSpecType[*AccessSpec](Type, accspeccpi.WithDescription(usage))) + accspeccpi.RegisterAccessType(accspeccpi.NewAccessSpecType[*AccessSpec](TypeV1Alpha1, accspeccpi.WithFormatSpec(formatV1), accspeccpi.WithConfigHandler(ConfigHandler()))) +} + +// AccessSpec describes the access for a GitHub registry. +type AccessSpec struct { + runtime.ObjectVersionedType `json:",inline"` + + // Repository is the repository URL + Repository string `json:"repository"` + + // Ref defines the hash of the commit + Ref string `json:"ref,omitempty"` + + // Commit defines the hash of the commit in string format to checkout from the Ref + Commit string `json:"commit,omitempty"` +} + +// AccessSpecOptions defines a set of options which can be applied to the access spec. +type AccessSpecOptions func(s *AccessSpec) + +func WithCommit(commit string) AccessSpecOptions { + return func(s *AccessSpec) { + s.Commit = commit + } +} + +func WithRef(ref string) AccessSpecOptions { + return func(s *AccessSpec) { + s.Ref = ref + } +} + +// New creates a new git registry access spec version v1. +func New(url string, opts ...AccessSpecOptions) *AccessSpec { + s := &AccessSpec{ + ObjectVersionedType: runtime.NewVersionedTypedObject(Type), + Repository: url, + } + for _, o := range opts { + o(s) + } + return s +} + +func (a *AccessSpec) Describe(internal.Context) string { + return fmt.Sprintf("git commit %s[%s]", a.Repository, a.Ref) +} + +func (*AccessSpec) IsLocal(internal.Context) bool { + return false +} + +func (a *AccessSpec) GlobalAccessSpec(accspeccpi.Context) accspeccpi.AccessSpec { + return a +} + +func (*AccessSpec) GetType() string { + return Type +} + +func (a *AccessSpec) AccessMethod(cva internal.ComponentVersionAccess) (internal.AccessMethod, error) { + _, err := giturls.Parse(a.Repository) + if err != nil { + return nil, errors.ErrInvalidWrap(err, "repository repoURL", a.Repository) + } + if err := plumbing.ReferenceName(a.Ref).Validate(); err != nil { + return nil, errors.ErrInvalidWrap(err, "commit hash", a.Ref) + } + creds, _, err := getCreds(a.Repository, cva.GetContext().CredentialsContext()) + if err != nil { + return nil, fmt.Errorf("failed to get credentials for repository %s: %w", a.Repository, err) + } + + octx := cva.GetContext() + + opts := []gitblob.Option{ + gitblob.WithLoggingContext(octx), + gitblob.WithCredentialContext(octx), + gitblob.WithURL(a.Repository), + gitblob.WithRef(a.Ref), + gitblob.WithCommit(a.Commit), + gitblob.WithCachingFileSystem(vfsattr.Get(octx)), + } + if creds != nil { + opts = append(opts, gitblob.WithCredentials(creds)) + } + + factory := func() (blobaccess.BlobAccess, error) { + return gitblob.BlobAccess(opts...) + } + + return accspeccpi.AccessMethodForImplementation(accspeccpi.NewDefaultMethodImpl( + cva, + a, + "", + mime.MIME_TGZ, + factory, + ), nil) +} + +func getCreds(repoURL string, cctx credentials.Context) (credentials.Credentials, credentials.ConsumerIdentity, error) { + id, err := identity.GetConsumerId(repoURL) + if err != nil { + return nil, nil, err + } + creds, err := credentials.CredentialsForConsumer(cctx.CredentialsContext(), id, identity.IdentityMatcher) + if creds == nil || err != nil { + return nil, id, err + } + return creds, id, nil +} diff --git a/api/ocm/extensions/accessmethods/git/method_test.go b/api/ocm/extensions/accessmethods/git/method_test.go new file mode 100644 index 0000000000..3a3ac663a4 --- /dev/null +++ b/api/ocm/extensions/accessmethods/git/method_test.go @@ -0,0 +1,167 @@ +package git_test + +import ( + "archive/tar" + "bytes" + "compress/gzip" + "embed" + "fmt" + "io" + "os" + "time" + + _ "embed" + + "github.com/go-git/go-git/v5/plumbing" + . "github.com/mandelsoft/goutils/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/mandelsoft/filepath/pkg/filepath" + "github.com/mandelsoft/vfs/pkg/cwdfs" + "github.com/mandelsoft/vfs/pkg/osfs" + + "ocm.software/ocm/api/datacontext/attrs/tmpcache" + "ocm.software/ocm/api/datacontext/attrs/vfsattr" + "ocm.software/ocm/api/ocm" + "ocm.software/ocm/api/ocm/cpi" + me "ocm.software/ocm/api/ocm/extensions/accessmethods/git" +) + +//go:embed testdata/repo +var testData embed.FS + +var _ = Describe("Method based on Filesystem", func() { + var ( + ctx ocm.Context + expectedBlobContent []byte + accessSpec *me.AccessSpec + ) + + ctx = ocm.New() + + BeforeEach(func() { + tempVFS, err := cwdfs.New(osfs.New(), GinkgoT().TempDir()) + Expect(err).ToNot(HaveOccurred()) + tmpcache.Set(ctx, &tmpcache.Attribute{Path: ".", Filesystem: tempVFS}) + vfsattr.Set(ctx, tempVFS) + }) + + var repoDir string + + BeforeEach(func() { + repoDir = GinkgoT().TempDir() + filepath.PathSeparatorString + "repo" + + repo := Must(git.PlainInit(repoDir, false)) + + repoBase := filepath.Join("testdata", "repo") + repoTestData := Must(testData.ReadDir(repoBase)) + + for _, entry := range repoTestData { + path := filepath.Join(repoBase, entry.Name()) + repoPath := filepath.Join(repoDir, entry.Name()) + + file := Must(testData.Open(path)) + + fileInRepo := Must(os.OpenFile( + repoPath, + os.O_CREATE|os.O_RDWR|os.O_TRUNC, + 0o600, + )) + + Must(io.Copy(fileInRepo, file)) + + Expect(fileInRepo.Close()).To(Succeed()) + Expect(file.Close()).To(Succeed()) + } + + wt := Must(repo.Worktree()) + Expect(wt.AddGlob("*")).To(Succeed()) + commit := Must(wt.Commit("OCM Test Commit", &git.CommitOptions{ + Author: &object.Signature{ + Name: "OCM Test", + Email: "dummy@ocm.software", + When: time.Now(), + }, + })) + + path := filepath.Join("testdata", "repo", "file_in_repo") + + accessSpec = me.New(fmt.Sprintf("file://%s", repoDir), + me.WithRef(plumbing.Master.String()), + me.WithCommit(commit.String()), + ) + + expectedBlobContent = Must(testData.ReadFile(path)) + }) + + It("downloads artifacts with full ref", func() { + m := Must(accessSpec.AccessMethod(&cpi.DummyComponentVersionAccess{Context: ctx})) + content := Must(m.Get()) + unzippedContent := Must(gzip.NewReader(bytes.NewReader(content))) + + r := tar.NewReader(unzippedContent) + + file := Must(r.Next()) + Expect(file.Name).To(Equal("file_in_repo")) + Expect(file.Size).To(Equal(int64(len(expectedBlobContent)))) + + data := Must(io.ReadAll(r)) + Expect(data).To(Equal(expectedBlobContent)) + }) + + It("downloads artifacts without commit because the url reference is enough", func() { + accessSpec = me.New(fmt.Sprintf("file://%s", repoDir), me.WithRef(plumbing.Master.String())) + + m := Must(accessSpec.AccessMethod(&cpi.DummyComponentVersionAccess{Context: ctx})) + content := Must(m.Get()) + unzippedContent := Must(gzip.NewReader(bytes.NewReader(content))) + + r := tar.NewReader(unzippedContent) + + file := Must(r.Next()) + Expect(file.Name).To(Equal("file_in_repo")) + Expect(file.Size).To(Equal(int64(len(expectedBlobContent)))) + + data := Must(io.ReadAll(r)) + Expect(data).To(Equal(expectedBlobContent)) + }) + + It("cannot download artifacts ref without a reference", func() { + accessSpec = me.New(fmt.Sprintf("file://%s", repoDir), me.WithCommit(accessSpec.Commit)) + + _, err := accessSpec.AccessMethod(&cpi.DummyComponentVersionAccess{Context: ctx}) + Expect(err).To(HaveOccurred()) + Expect(err.Error()).To(ContainSubstring("invalid reference name")) + }) +}) + +var _ = Describe("Method based on Real Repository", func() { + host := "github.com:443" + reachable := PingTCPServer(host, time.Second) == nil + var url string + BeforeEach(func() { + if !reachable { + Skip(fmt.Sprintf("no connection to %s, skipping test connection to remote", url)) + } + // This repo is a public repo owned by the Github Kraken Bot, so its as good of a public available + // example as any. + url = fmt.Sprintf("https://%s/octocat/Hello-World.git", host) + }) + + It("can download remote artifacts", func() { + ctx := ocm.New() + accessSpec := me.New(url, me.WithRef(plumbing.Master.String())) + + m := Must(accessSpec.AccessMethod(&cpi.DummyComponentVersionAccess{Context: ctx})) + content := Must(m.Get()) + unzippedContent := Must(gzip.NewReader(bytes.NewReader(content))) + + r := tar.NewReader(unzippedContent) + + file := Must(r.Next()) + Expect(file.Name).To(Equal("README")) + }) +}) diff --git a/api/ocm/extensions/accessmethods/git/suite_test.go b/api/ocm/extensions/accessmethods/git/suite_test.go new file mode 100644 index 0000000000..59ce0ec1fc --- /dev/null +++ b/api/ocm/extensions/accessmethods/git/suite_test.go @@ -0,0 +1,13 @@ +package git + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Github Test Suite") +} diff --git a/api/ocm/extensions/accessmethods/git/testdata/repo/file_in_repo b/api/ocm/extensions/accessmethods/git/testdata/repo/file_in_repo new file mode 100644 index 0000000000..5eced95754 --- /dev/null +++ b/api/ocm/extensions/accessmethods/git/testdata/repo/file_in_repo @@ -0,0 +1 @@ +Foobar \ No newline at end of file diff --git a/api/ocm/extensions/accessmethods/init.go b/api/ocm/extensions/accessmethods/init.go index 5f4094d3d5..08ce51bf32 100644 --- a/api/ocm/extensions/accessmethods/init.go +++ b/api/ocm/extensions/accessmethods/init.go @@ -1,6 +1,7 @@ package accessmethods import ( + _ "ocm.software/ocm/api/ocm/extensions/accessmethods/git" _ "ocm.software/ocm/api/ocm/extensions/accessmethods/github" _ "ocm.software/ocm/api/ocm/extensions/accessmethods/helm" _ "ocm.software/ocm/api/ocm/extensions/accessmethods/localblob" diff --git a/api/tech/git/auth.go b/api/tech/git/auth.go new file mode 100644 index 0000000000..276d12a962 --- /dev/null +++ b/api/tech/git/auth.go @@ -0,0 +1,46 @@ +package git + +import ( + "errors" + + "github.com/go-git/go-git/v5/plumbing/transport" + "github.com/go-git/go-git/v5/plumbing/transport/http" + gssh "github.com/go-git/go-git/v5/plumbing/transport/ssh" + + "ocm.software/ocm/api/credentials" + "ocm.software/ocm/api/tech/git/identity" +) + +var ErrNoValidGitCredentials = errors.New("no valid credentials found for git authentication") + +type AuthMethod = transport.AuthMethod + +// AuthFromCredentials creates a git authentication method from the given credentials. +// If no valid credentials are found, ErrNoValidGitCredentials is returned. +// However, one can still perform anonymous operations with the git client if the repo allows it. +func AuthFromCredentials(creds credentials.Credentials) (AuthMethod, error) { + if creds == nil { + return nil, ErrNoValidGitCredentials + } + + if creds.ExistsProperty(identity.ATTR_PRIVATE_KEY) { + return gssh.NewPublicKeysFromFile( + creds.GetProperty(identity.ATTR_USERNAME), + creds.GetProperty(identity.ATTR_PRIVATE_KEY), + creds.GetProperty(identity.ATTR_PASSWORD), + ) + } + + if creds.ExistsProperty(identity.ATTR_TOKEN) { + return &http.TokenAuth{Token: creds.GetProperty(identity.ATTR_TOKEN)}, nil + } + + if creds.ExistsProperty(identity.ATTR_USERNAME) { + return &http.BasicAuth{ + Username: creds.GetProperty(identity.ATTR_USERNAME), + Password: creds.GetProperty(identity.ATTR_PASSWORD), + }, nil + } + + return nil, ErrNoValidGitCredentials +} diff --git a/api/tech/git/fs.go b/api/tech/git/fs.go new file mode 100644 index 0000000000..bfbb4c5386 --- /dev/null +++ b/api/tech/git/fs.go @@ -0,0 +1,177 @@ +package git + +import ( + "errors" + "fmt" + "os" + "path/filepath" + "sync" + "syscall" + + "github.com/go-git/go-billy/v5" + "github.com/mandelsoft/vfs/pkg/memoryfs" + "github.com/mandelsoft/vfs/pkg/projectionfs" + "github.com/mandelsoft/vfs/pkg/vfs" +) + +func VFSBillyFS(fsToWrap vfs.FileSystem) (billy.Filesystem, error) { + if fsToWrap == nil { + fsToWrap = vfs.New(memoryfs.New()) + } + fi, err := fsToWrap.Stat(".") + if err != nil || !fi.IsDir() { + return nil, fmt.Errorf("invalid vfs for billy conversion: %w", err) + } + + return &fs{ + FileSystem: fsToWrap, + }, nil +} + +type fs struct { + vfs.FileSystem +} + +var _ billy.Filesystem = &fs{} + +// file is a wrapper around a vfs.File that implements billy.File. +// it uses a mutex to lock the file, so it can be used concurrently from the same process, but +// not across processes (like a flock). +type file struct { + vfs.File + lockMu sync.Mutex +} + +var _ billy.File = &file{} + +func (f *file) Lock() error { + f.lockMu.Lock() + return nil +} + +func (f *file) Unlock() error { + f.lockMu.Unlock() + return nil +} + +var _ billy.File = &file{} + +func (f *fs) Create(filename string) (billy.File, error) { + vfsFile, err := f.FileSystem.Create(filename) + if err != nil { + return nil, err + } + return f.vfsToBillyFileInfo(vfsFile) +} + +// vfsToBillyFileInfo converts a vfs.File to a billy.File +func (f *fs) vfsToBillyFileInfo(vf vfs.File) (billy.File, error) { + return &file{ + File: vf, + }, nil +} + +func (f *fs) Open(filename string) (billy.File, error) { + vfsFile, err := f.FileSystem.Open(filename) + if errors.Is(err, syscall.ENOENT) { + return nil, os.ErrNotExist + } + if err != nil { + return nil, err + } + return f.vfsToBillyFileInfo(vfsFile) +} + +func (f *fs) OpenFile(filename string, flag int, perm os.FileMode) (billy.File, error) { + if flag&os.O_CREATE != 0 { + if err := f.FileSystem.MkdirAll(filepath.Dir(filename), 0o755); err != nil { + return nil, err + } + } + vfsFile, err := f.FileSystem.OpenFile(filename, flag, perm) + if err != nil { + return nil, err + } + return f.vfsToBillyFileInfo(vfsFile) +} + +func (f *fs) Stat(filename string) (os.FileInfo, error) { + fi, err := f.FileSystem.Stat(filename) + if errors.Is(err, syscall.ENOENT) { + return nil, os.ErrNotExist + } + return fi, err +} + +func (f *fs) Rename(oldpath, newpath string) error { + dir := filepath.Dir(newpath) + if dir != "." { + if err := f.FileSystem.MkdirAll(dir, 0o755); err != nil { + return err + } + } + return f.FileSystem.Rename(oldpath, newpath) +} + +func (f *fs) Join(elem ...string) string { + return filepath.Join(elem...) +} + +func (f *fs) TempFile(dir, prefix string) (billy.File, error) { + vfsFile, err := vfs.TempFile(f.FileSystem, dir, prefix) + if err != nil { + return nil, err + } + return f.vfsToBillyFileInfo(vfsFile) +} + +func (f *fs) ReadDir(path string) ([]os.FileInfo, error) { + return vfs.ReadDir(f.FileSystem, path) +} + +func (f *fs) Lstat(filename string) (os.FileInfo, error) { + fi, err := f.FileSystem.Lstat(filename) + if err != nil { + if errors.Is(err, syscall.ENOENT) { + return nil, os.ErrNotExist + } + } + return fi, err +} + +func (f *fs) Chroot(path string) (billy.Filesystem, error) { + fi, err := f.FileSystem.Stat(path) + if os.IsNotExist(err) { + if err = f.FileSystem.MkdirAll(path, 0o755); err != nil { + return nil, err + } + fi, err = f.FileSystem.Stat(path) + } + + if err != nil { + return nil, err + } else if !fi.IsDir() { + return nil, fmt.Errorf("path %s is not a directory", path) + } + + chfs, err := projectionfs.New(f.FileSystem, path) + if err != nil { + return nil, err + } + + return &fs{ + FileSystem: chfs, + }, nil +} + +func (f *fs) Root() string { + if root := projectionfs.Root(f.FileSystem); root != "" { + return root + } + if canonicalRoot, err := vfs.Canonical(f.FileSystem, "/", true); err == nil { + return canonicalRoot + } + return "/" +} + +var _ billy.Filesystem = &fs{} diff --git a/api/tech/git/identity/identity.go b/api/tech/git/identity/identity.go new file mode 100644 index 0000000000..20ae3fe257 --- /dev/null +++ b/api/tech/git/identity/identity.go @@ -0,0 +1,131 @@ +package identity + +import ( + "net" + + giturls "github.com/whilp/git-urls" + + "ocm.software/ocm/api/credentials/cpi" + "ocm.software/ocm/api/credentials/identity/hostpath" + "ocm.software/ocm/api/utils/listformat" +) + +const CONSUMER_TYPE = "Git" + +var identityMatcher = hostpath.IdentityMatcher(CONSUMER_TYPE) + +func IdentityMatcher(pattern, cur, id cpi.ConsumerIdentity) bool { + return identityMatcher(pattern, cur, id) +} + +func init() { + attrs := listformat.FormatListElements("", listformat.StringElementDescriptionList{ + ATTR_USERNAME, "the basic auth user name", + ATTR_PASSWORD, "the basic auth password", + ATTR_TOKEN, "HTTP token authentication", + ATTR_PRIVATE_KEY, "Private Key authentication certificate", + }) + cpi.RegisterStandardIdentity(CONSUMER_TYPE, identityMatcher, + `Git credential matcher + +It matches the `+CONSUMER_TYPE+` consumer type and additionally acts like +the `+hostpath.IDENTITY_TYPE+` type.`, + attrs) +} + +const ( + ID_HOSTNAME = hostpath.ID_HOSTNAME + ID_PATHPREFIX = hostpath.ID_PATHPREFIX + ID_PORT = hostpath.ID_PORT + ID_SCHEME = hostpath.ID_SCHEME +) + +const ( + ATTR_TOKEN = cpi.ATTR_TOKEN + ATTR_USERNAME = cpi.ATTR_USERNAME + ATTR_PASSWORD = cpi.ATTR_PASSWORD + ATTR_PRIVATE_KEY = cpi.ATTR_PRIVATE_KEY +) + +func GetConsumerId(repoURL string) (cpi.ConsumerIdentity, error) { + host := "" + port := "" + defaultPort := "" + scheme := "" + path := "" + + if repoURL != "" { + u, err := giturls.Parse(repoURL) + if err == nil { + host = u.Host + } else { + return nil, err + } + + scheme = u.Scheme + switch scheme { + case "http": + defaultPort = "80" + case "https": + defaultPort = "443" + case "git": + defaultPort = "9418" + case "ssh": + defaultPort = "22" + case "file": + host = "localhost" + path = u.Path + } + } + + if h, p, err := net.SplitHostPort(host); err == nil { + host, port = h, p + } + + id := cpi.ConsumerIdentity{ + cpi.ID_TYPE: CONSUMER_TYPE, + ID_HOSTNAME: host, + } + + if port != "" { + id[ID_PORT] = port + } else if defaultPort != "" { + id[ID_PORT] = defaultPort + } + + if path != "" { + id[ID_PATHPREFIX] = path + } + + id[ID_SCHEME] = scheme + + return id, nil +} + +func TokenCredentials(token string) cpi.Credentials { + return cpi.DirectCredentials{ + ATTR_TOKEN: token, + } +} + +func BasicAuthCredentials(username, password string) cpi.Credentials { + return cpi.DirectCredentials{ + ATTR_USERNAME: username, + ATTR_PASSWORD: password, + } +} + +func PrivateKeyCredentials(username, privateKey string) cpi.Credentials { + return cpi.DirectCredentials{ + ATTR_USERNAME: username, + ATTR_PRIVATE_KEY: privateKey, + } +} + +func GetCredentials(ctx cpi.ContextProvider, repoURL string) (cpi.Credentials, error) { + id, err := GetConsumerId(repoURL) + if err != nil { + return nil, err + } + return cpi.CredentialsForConsumer(ctx.CredentialsContext(), id, IdentityMatcher) +} diff --git a/api/tech/git/identity/identity_test.go b/api/tech/git/identity/identity_test.go new file mode 100644 index 0000000000..13a95f4e2c --- /dev/null +++ b/api/tech/git/identity/identity_test.go @@ -0,0 +1,132 @@ +package identity_test + +import ( + "github.com/mandelsoft/goutils/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "ocm.software/ocm/api/tech/git/identity" + + "ocm.software/ocm/api/credentials" + "ocm.software/ocm/api/datacontext" + "ocm.software/ocm/api/oci" + common "ocm.software/ocm/api/utils/misc" +) + +var _ = Describe("consumer id handling", func() { + repo := "https://github.com/torvalds/linux.git" + + Context("id determination", func() { + It("handles https repos", func() { + id := testutils.Must(GetConsumerId(repo)) + Expect(id).To(Equal(credentials.NewConsumerIdentity(CONSUMER_TYPE, + "port", "443", + "hostname", "github.com", + "scheme", "https", + ))) + }) + + It("handles http repos", func() { + id := testutils.Must(GetConsumerId("http://github.com/torvalds/linux.git")) + Expect(id).To(Equal(credentials.NewConsumerIdentity(CONSUMER_TYPE, + "port", "80", + "hostname", "github.com", + "scheme", "http", + ))) + }) + + It("handles ssh standard format repos", func() { + id := testutils.Must(GetConsumerId("ssh://github.com/torvalds/linux.git")) + Expect(id).To(Equal(credentials.NewConsumerIdentity(CONSUMER_TYPE, + "port", "22", + "hostname", "github.com", + "scheme", "ssh", + ))) + }) + + It("handles ssh git @ format repos", func() { + id := testutils.Must(GetConsumerId("git@github.com:torvalds/linux.git")) + Expect(id).To(Equal(credentials.NewConsumerIdentity(CONSUMER_TYPE, + "port", "22", + "hostname", "github.com", + "scheme", "ssh", + ))) + }) + + It("handles git format repos", func() { + id := testutils.Must(GetConsumerId("git://github.com/torvalds/linux.git")) + Expect(id).To(Equal(credentials.NewConsumerIdentity(CONSUMER_TYPE, + "port", "9418", + "hostname", "github.com", + "scheme", "git", + ))) + }) + + It("handles file format repos", func() { + id := testutils.Must(GetConsumerId("file:///path/to/linux/repo")) + Expect(id).To(Equal(credentials.NewConsumerIdentity(CONSUMER_TYPE, + "scheme", "file", + "hostname", "localhost", + "pathprefix", "/path/to/linux/repo", + ))) + }) + }) + + Context("query credentials", func() { + var ctx oci.Context + var credctx credentials.Context + + BeforeEach(func() { + ctx = oci.New(datacontext.MODE_EXTENDED) + credctx = ctx.CredentialsContext() + }) + + It("Basic Auth", func() { + user, pass := "linus", "torvalds" + id := testutils.Must(GetConsumerId(repo)) + credctx.SetCredentialsForConsumer(id, + credentials.CredentialsFromList( + ATTR_USERNAME, user, + ATTR_PASSWORD, pass, + ), + ) + + creds := testutils.Must(GetCredentials(ctx, repo)) + Expect(creds).To(BeEquivalentTo(common.Properties{ + ATTR_USERNAME: user, + ATTR_PASSWORD: pass, + })) + }) + + It("Token Auth", func() { + token := "mytoken" + id := testutils.Must(GetConsumerId(repo)) + credctx.SetCredentialsForConsumer(id, + credentials.CredentialsFromList( + ATTR_TOKEN, token, + ), + ) + + creds := testutils.Must(GetCredentials(ctx, repo)) + Expect(creds).To(BeEquivalentTo(common.Properties{ + ATTR_TOKEN: token, + })) + }) + + It("Public Key Auth", func() { + user, key := "linus", "path/to/my/id_rsa" + id := testutils.Must(GetConsumerId(repo)) + credctx.SetCredentialsForConsumer(id, + credentials.CredentialsFromList( + ATTR_USERNAME, user, + ATTR_PRIVATE_KEY, key, + ), + ) + + creds := testutils.Must(GetCredentials(ctx, repo)) + Expect(creds).To(BeEquivalentTo(common.Properties{ + ATTR_USERNAME: user, + ATTR_PRIVATE_KEY: key, + })) + }) + }) +}) diff --git a/api/tech/git/identity/suite_test.go b/api/tech/git/identity/suite_test.go new file mode 100644 index 0000000000..d79c7330b1 --- /dev/null +++ b/api/tech/git/identity/suite_test.go @@ -0,0 +1,13 @@ +package identity_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Git Identity Suite") +} diff --git a/api/tech/git/logging.go b/api/tech/git/logging.go new file mode 100644 index 0000000000..1fce027755 --- /dev/null +++ b/api/tech/git/logging.go @@ -0,0 +1,5 @@ +package git + +import "ocm.software/ocm/api/utils/logging" + +var REALM = logging.DefineSubRealm("git repository", "git") diff --git a/api/tech/git/resolver.go b/api/tech/git/resolver.go new file mode 100644 index 0000000000..ef8098ee0b --- /dev/null +++ b/api/tech/git/resolver.go @@ -0,0 +1,212 @@ +package git + +import ( + "context" + "errors" + "fmt" + "net/http" + "sync" + + "github.com/go-git/go-billy/v5" + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/cache" + "github.com/go-git/go-git/v5/plumbing/transport" + gitclient "github.com/go-git/go-git/v5/plumbing/transport/client" + githttp "github.com/go-git/go-git/v5/plumbing/transport/http" + "github.com/go-git/go-git/v5/storage" + "github.com/go-git/go-git/v5/storage/filesystem" + mlog "github.com/mandelsoft/logging" + "github.com/mandelsoft/vfs/pkg/memoryfs" + "github.com/mandelsoft/vfs/pkg/vfs" + + "ocm.software/ocm/api/utils/logging" +) + +const LogAttrProtocol = "protocol" + +func init() { + // override the logging realm for http based git clients + gitclient.InstallProtocol("http", githttp.NewClient(&http.Client{ + Transport: logging.NewRoundTripper(http.DefaultTransport, logging.DynamicLogger(REALM, mlog.NewAttribute(LogAttrProtocol, "http"))), + })) + gitclient.InstallProtocol("https", githttp.NewClient(&http.Client{ + Transport: logging.NewRoundTripper(http.DefaultTransport, logging.DynamicLogger(REALM, mlog.NewAttribute(LogAttrProtocol, "https"))), + })) + // TODO Determine how we ideally log for ssh+git protocol +} + +var DefaultWorktreeBranch = plumbing.NewBranchReferenceName("ocm") + +type client struct { + opts ClientOptions + + // vfs tracks the current filesystem where the repo will be stored (at the root) + vfs vfs.FileSystem + + // repo is a reference to the git repository if it is already open + repo *git.Repository + repoMu sync.Mutex +} + +// Client is a heavy abstraction over the go git Client that opinionates the remote as git.DefaultRemoteName +// as well as access to it via high level functions that are usually required for operation within OCM CTFs that are stored +// within Git. It is not general-purpose. +type Client interface { + // Repository returns the git repository for the client initialized in the Filesystem given to Setup. + // If Setup is not called before Repository, it will an in-memory filesystem. + // Repository will attempt to initially clone the repository if it does not exist. + // If the repository is already open or cloned in the filesystem, it will attempt to open & return the existing repository. + // If the remote repository does not exist, a new repository will be created with a dummy commit and the remote + // configured to the given URL. At that point it is up to the remote to accept an initial push to the repository or not with the + // given AuthMethod. + Repository(ctx context.Context) (*git.Repository, error) + + // Setup will override the current filesystem with the given filesystem. This will be the filesystem where the repository will be stored. + // There can be only one filesystem per client. + // If the filesystem contains a repository already, it can be consumed by a subsequent call to Repository. + Setup(context.Context, vfs.FileSystem) error +} + +type ClientOptions struct { + // URL is the URL of the git repository to clone or open. + URL string + // Ref is the reference to the repository to clone or open. + // If empty, it will default to plumbing.HEAD of the remote repository. + // If the remote does not exist, it will attempt to push to the remote with DefaultWorktreeBranch on Client.Update. + // To point to a remote branch, use refs/heads/. + // To point to a tag, use refs/tags/. + Ref string + // Commit is the commit hash to checkout after cloning the repository. + // If empty, it will default to the plumbing.HEAD of the Ref. + Commit string + // AuthMethod is the authentication method to use for the repository. + AuthMethod AuthMethod +} + +var _ Client = &client{} + +func NewClient(opts ClientOptions) (Client, error) { + pref := plumbing.HEAD + if opts.Ref != "" { + pref = plumbing.ReferenceName(opts.Ref) + if err := pref.Validate(); err != nil { + return nil, fmt.Errorf("invalid reference %q: %w", opts.Ref, err) + } + } + + return &client{ + vfs: memoryfs.New(), + opts: opts, + }, nil +} + +func (c *client) Repository(ctx context.Context) (*git.Repository, error) { + c.repoMu.Lock() + defer c.repoMu.Unlock() + if c.repo != nil { + return c.repo, nil + } + + billyFS, err := VFSBillyFS(c.vfs) + if err != nil { + return nil, err + } + + strg, err := GetStorage(billyFS) + if err != nil { + return nil, err + } + + depth := 0 + if c.opts.Commit == "" { + depth = 1 // if we have no dedicated commit we can checkout HEAD, and thus a shallow clone is ok + } + + newRepo := false + repo, err := git.Open(strg, billyFS) + if errors.Is(err, git.ErrRepositoryNotExists) { + repo, err = git.CloneContext(ctx, strg, billyFS, &git.CloneOptions{ + Auth: c.opts.AuthMethod, + URL: c.opts.URL, + RemoteName: git.DefaultRemoteName, + ReferenceName: plumbing.ReferenceName(c.opts.Ref), + SingleBranch: true, + Depth: depth, + ShallowSubmodules: depth == 1, + Tags: git.AllTags, + }) + newRepo = true + } + if errors.Is(err, transport.ErrEmptyRemoteRepository) { + repo, err = git.Open(strg, billyFS) + if err != nil { + return nil, fmt.Errorf("failed to open repository based on URL %q after it was determined to be an empty clone: %w", c.opts.URL, err) + } + } + + if err != nil { + return nil, err + } + if newRepo { + if err := c.newRepository(ctx, repo); err != nil { + return nil, err + } + } + + c.repo = repo + + return repo, nil +} + +func (c *client) newRepository(ctx context.Context, repo *git.Repository) error { + if err := repo.FetchContext(ctx, &git.FetchOptions{ + Auth: c.opts.AuthMethod, + RemoteName: git.DefaultRemoteName, + Depth: 0, + Tags: git.AllTags, + Force: false, + }); err != nil && !errors.Is(err, git.NoErrAlreadyUpToDate) { + return err + } + worktree, err := repo.Worktree() + if err != nil { + return err + } + + var hash plumbing.Hash + if c.opts.Commit != "" { + hash = plumbing.NewHash(c.opts.Commit) + } + + if err := worktree.Checkout(&git.CheckoutOptions{ + Hash: hash, + Branch: DefaultWorktreeBranch, + Create: true, + Keep: true, + }); err != nil { + return err + } + + return nil +} + +func GetStorage(base billy.Filesystem) (storage.Storer, error) { + dotGit, err := base.Chroot(git.GitDirName) + if err != nil { + return nil, err + } + + return filesystem.NewStorage( + dotGit, + cache.NewObjectLRUDefault(), + ), nil +} + +func (c *client) Setup(ctx context.Context, system vfs.FileSystem) error { + c.vfs = system + if _, err := c.Repository(ctx); err != nil { + return fmt.Errorf("failed to setup repository %q: %w", c.opts.URL, err) + } + return nil +} diff --git a/api/tech/git/resolver_test.go b/api/tech/git/resolver_test.go new file mode 100644 index 0000000000..d128d07808 --- /dev/null +++ b/api/tech/git/resolver_test.go @@ -0,0 +1,112 @@ +package git_test + +import ( + "embed" + "fmt" + "io" + "os" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/mandelsoft/filepath/pkg/filepath" + . "github.com/mandelsoft/goutils/testutils" + "github.com/mandelsoft/vfs/pkg/cwdfs" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/mandelsoft/vfs/pkg/projectionfs" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "ocm.software/ocm/api/datacontext/attrs/tmpcache" + "ocm.software/ocm/api/datacontext/attrs/vfsattr" + "ocm.software/ocm/api/ocm" + self "ocm.software/ocm/api/tech/git" +) + +//go:embed testdata/repo +var testData embed.FS + +var _ = Describe("standard tests with local file repo", func() { + var ( + ctx ocm.Context + expectedBlobContent []byte + ) + + ctx = ocm.New() + + BeforeEach(func() { + tempVFS, err := cwdfs.New(osfs.New(), GinkgoT().TempDir()) + Expect(err).ToNot(HaveOccurred()) + tmpcache.Set(ctx, &tmpcache.Attribute{Path: ".", Filesystem: tempVFS}) + vfsattr.Set(ctx, tempVFS) + }) + + var repoDir string + var repoURL string + var ref string + var commit string + + BeforeEach(func() { + repoDir = GinkgoT().TempDir() + filepath.PathSeparatorString + "repo" + + repo := Must(git.PlainInit(repoDir, false)) + + repoBase := filepath.Join("testdata", "repo") + repoTestData := Must(testData.ReadDir(repoBase)) + + for _, entry := range repoTestData { + path := filepath.Join(repoBase, entry.Name()) + repoPath := filepath.Join(repoDir, entry.Name()) + + file := Must(testData.Open(path)) + + fileInRepo := Must(os.OpenFile( + repoPath, + os.O_CREATE|os.O_RDWR|os.O_TRUNC, + 0o600, + )) + + Must(io.Copy(fileInRepo, file)) + + Expect(fileInRepo.Close()).To(Succeed()) + Expect(file.Close()).To(Succeed()) + } + + wt := Must(repo.Worktree()) + Expect(wt.AddGlob("*")).To(Succeed()) + commit = Must(wt.Commit("OCM Test Commit", &git.CommitOptions{ + Author: &object.Signature{ + Name: "OCM Test", + Email: "dummy@ocm.software", + When: time.Now(), + }, + })).String() + + path := filepath.Join("testdata", "repo", "file_in_repo") + repoURL = fmt.Sprintf("file://%s", repoDir) + ref = plumbing.Master.String() + + expectedBlobContent = Must(testData.ReadFile(path)) + }) + + It("Resolver client can setup repository", func(ctx SpecContext) { + client := Must(self.NewClient(self.ClientOptions{ + URL: repoURL, + Ref: ref, + Commit: commit, + })) + + tempVFS, err := projectionfs.New(osfs.New(), GinkgoT().TempDir()) + Expect(err).ToNot(HaveOccurred()) + + Expect(client.Setup(ctx, tempVFS)).To(Succeed()) + + repo := Must(client.Repository(ctx)) + Expect(repo).ToNot(BeNil()) + + file := Must(tempVFS.Stat("file_in_repo")) + Expect(file.Size()).To(Equal(int64(len(expectedBlobContent)))) + + }) +}) diff --git a/api/tech/git/suite_test.go b/api/tech/git/suite_test.go new file mode 100644 index 0000000000..73e11ee635 --- /dev/null +++ b/api/tech/git/suite_test.go @@ -0,0 +1,13 @@ +package git_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "OCM Git Tech Test Suite") +} diff --git a/api/tech/git/testdata/repo/file_in_repo b/api/tech/git/testdata/repo/file_in_repo new file mode 100644 index 0000000000..5eced95754 --- /dev/null +++ b/api/tech/git/testdata/repo/file_in_repo @@ -0,0 +1 @@ +Foobar \ No newline at end of file diff --git a/api/utils/blobaccess/git/access.go b/api/utils/blobaccess/git/access.go new file mode 100644 index 0000000000..d9aba5b631 --- /dev/null +++ b/api/utils/blobaccess/git/access.go @@ -0,0 +1,136 @@ +package git + +import ( + "context" + + gogit "github.com/go-git/go-git/v5" + "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/goutils/optionutils" + "github.com/mandelsoft/vfs/pkg/projectionfs" + "github.com/mandelsoft/vfs/pkg/vfs" + "github.com/opencontainers/go-digest" + + "ocm.software/ocm/api/tech/git" + "ocm.software/ocm/api/utils/blobaccess/bpi" + "ocm.software/ocm/api/utils/blobaccess/file" + "ocm.software/ocm/api/utils/iotools" + "ocm.software/ocm/api/utils/mime" + "ocm.software/ocm/api/utils/tarutils" +) + +// BlobAccess clones the repository into a temporary filesystem, packs it into a tar.gz file, +// and returns a BlobAccess object for the tar.gz file. +func BlobAccess(opt ...Option) (_ bpi.BlobAccess, rerr error) { + var finalize finalizer.Finalizer + defer finalize.FinalizeWithErrorPropagation(&rerr) + + options := optionutils.EvalOptions(opt...) + if options.URL == "" { + return nil, errors.New("no URL specified") + } + log := options.Logger("RepoUrl", options.URL) + + if err := options.ConfigureAuthMethod(); err != nil { + return nil, err + } + + c, err := git.NewClient(options.ClientOptions) + if err != nil { + return nil, err + } + + tmpFS, cleanup, err := options.CachingFilesystem() + if err != nil { + return nil, err + } else if cleanup != nil { + finalize.With(cleanup) + } + + // store the repo in a temporary filesystem subfolder, so the tgz can go in the root without issues. + if err := tmpFS.MkdirAll("repository", 0o700); err != nil { + return nil, err + } + + repositoryFS, err := projectionfs.New(tmpFS, "repository") + if err != nil { + return nil, err + } + finalize.With(func() error { + return tmpFS.RemoveAll("repository") + }) + + // redirect the client to the temporary filesystem for storage of the repo, otherwise it would use memory + if err := c.Setup(context.Background(), repositoryFS); err != nil { + return nil, err + } + + // get the repository, triggering a clone if not present into the filesystem provided by setup + if _, err := c.Repository(context.Background()); err != nil { + return nil, err + } + + filteredRepositoryFS := &filteredVFS{ + FileSystem: repositoryFS, + filter: func(s string) bool { + return s != gogit.GitDirName + }, + } + + // pack all downloaded files into a tar.gz file + fs := tmpFS + tgz, err := vfs.TempFile(fs, "", "git-*.tar.gz") + if err != nil { + return nil, err + } + + dw := iotools.NewDigestWriterWith(digest.SHA256, tgz) + finalize.Close(dw) + + if err := tarutils.TgzFs(filteredRepositoryFS, dw); err != nil { + return nil, err + } + + log.Debug("created", "file", tgz.Name()) + + return file.BlobAccessForTemporaryFilePath( + mime.MIME_TGZ, + tgz.Name(), + file.WithFileSystem(fs), + file.WithDigest(dw.Digest()), + file.WithSize(dw.Size()), + ), nil +} + +type filteredVFS struct { + vfs.FileSystem + filter func(string) bool +} + +func (f *filteredVFS) Open(name string) (vfs.File, error) { + if !f.filter(name) { + return nil, vfs.SkipDir + } + return f.FileSystem.Open(name) +} + +func (f *filteredVFS) OpenFile(name string, flags int, perm vfs.FileMode) (vfs.File, error) { + if !f.filter(name) { + return nil, vfs.SkipDir + } + return f.FileSystem.OpenFile(name, flags, perm) +} + +func (f *filteredVFS) Stat(name string) (vfs.FileInfo, error) { + if !f.filter(name) { + return nil, vfs.SkipDir + } + return f.FileSystem.Stat(name) +} + +func (f *filteredVFS) Lstat(name string) (vfs.FileInfo, error) { + if !f.filter(name) { + return nil, vfs.SkipDir + } + return f.FileSystem.Lstat(name) +} diff --git a/api/utils/blobaccess/git/access_test.go b/api/utils/blobaccess/git/access_test.go new file mode 100644 index 0000000000..a35495a7aa --- /dev/null +++ b/api/utils/blobaccess/git/access_test.go @@ -0,0 +1,153 @@ +package git_test + +import ( + "embed" + _ "embed" + "fmt" + "io" + "os" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/mandelsoft/filepath/pkg/filepath" + . "github.com/mandelsoft/goutils/testutils" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/mandelsoft/vfs/pkg/projectionfs" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "ocm.software/ocm/api/datacontext/attrs/tmpcache" + "ocm.software/ocm/api/datacontext/attrs/vfsattr" + "ocm.software/ocm/api/ocm" + gitblob "ocm.software/ocm/api/utils/blobaccess/git" + "ocm.software/ocm/api/utils/tarutils" +) + +//go:embed testdata/repo +var testData embed.FS + +var _ = Describe("git Blob Access", func() { + var ( + ctx ocm.Context + url string + ) + + ctx = ocm.New() + + BeforeEach(func() { + tempVFS, err := projectionfs.New(osfs.New(), GinkgoT().TempDir()) + Expect(err).ToNot(HaveOccurred()) + tmpcache.Set(ctx, &tmpcache.Attribute{Path: ".", Filesystem: tempVFS}) + vfsattr.Set(ctx, tempVFS) + }) + + Context("git filesystem repository", func() { + BeforeEach(func() { + repoDir := GinkgoT().TempDir() + filepath.PathSeparatorString + "repo" + + repo, err := git.PlainInit(repoDir, false) + Expect(err).ToNot(HaveOccurred()) + + repoBase := filepath.Join("testdata", "repo") + repoTestData, err := testData.ReadDir(repoBase) + Expect(err).ToNot(HaveOccurred()) + + for _, entry := range repoTestData { + path := filepath.Join(repoBase, entry.Name()) + repoPath := filepath.Join(repoDir, entry.Name()) + + file, err := testData.Open(path) + Expect(err).ToNot(HaveOccurred()) + + fileInRepo, err := os.OpenFile( + repoPath, + os.O_CREATE|os.O_RDWR|os.O_TRUNC, + 0o600, + ) + Expect(err).ToNot(HaveOccurred()) + + _, err = io.Copy(fileInRepo, file) + Expect(err).ToNot(HaveOccurred()) + + Expect(fileInRepo.Close()).To(Succeed()) + Expect(file.Close()).To(Succeed()) + } + + wt, err := repo.Worktree() + Expect(err).ToNot(HaveOccurred()) + Expect(wt.AddGlob("*")).To(Succeed()) + _, err = wt.Commit("OCM Test Commit", &git.CommitOptions{ + Author: &object.Signature{ + Name: "OCM Test", + Email: "dummy@ocm.software", + When: time.Now(), + }, + }) + Expect(err).ToNot(HaveOccurred()) + + url = fmt.Sprintf("file://%s", repoDir) + }) + + It("blobaccess for simple repository", func() { + b := Must(gitblob.BlobAccess( + gitblob.WithURL(url), + gitblob.WithLoggingContext(ctx), + gitblob.WithCachingContext(ctx), + )) + defer Close(b) + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("file_in_repo")) + }) + + }) + + Context("git http repository", func() { + host := "github.com:443" + reachable := PingTCPServer(host, time.Second) == nil + BeforeEach(func() { + if !reachable { + Skip(fmt.Sprintf("no connection to %s, skipping test connection to remote", url)) + } + // This repo is a public repo owned by the Github Kraken Bot, so its as good of a public available + // example as any. + url = fmt.Sprintf("https://%s/octocat/Hello-World.git", host) + }) + + It("hello world from github without explicit branch", func() { + b := Must(gitblob.BlobAccess( + gitblob.WithURL(url), + gitblob.WithLoggingContext(ctx), + gitblob.WithCachingContext(ctx), + )) + defer Close(b) + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("README")) + }) + + It("hello world from github with master branch", func() { + b := Must(gitblob.BlobAccess( + gitblob.WithURL(url), + gitblob.WithLoggingContext(ctx), + gitblob.WithCachingContext(ctx), + gitblob.WithRef(plumbing.Master.String()), + )) + defer Close(b) + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("README")) + }) + + It("hello world from github with custom ref", func() { + b := Must(gitblob.BlobAccess( + gitblob.WithURL(url), + gitblob.WithLoggingContext(ctx), + gitblob.WithCachingContext(ctx), + gitblob.WithRef("refs/heads/test"), + )) + defer Close(b) + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("README", "CONTRIBUTING.md")) + }) + }) +}) diff --git a/api/utils/blobaccess/git/digest.go b/api/utils/blobaccess/git/digest.go new file mode 100644 index 0000000000..4d61d15310 --- /dev/null +++ b/api/utils/blobaccess/git/digest.go @@ -0,0 +1,7 @@ +package git + +import "github.com/opencontainers/go-digest" + +type Digest interface { + digest.Digest +} diff --git a/api/utils/blobaccess/git/options.go b/api/utils/blobaccess/git/options.go new file mode 100644 index 0000000000..44ebd7cd14 --- /dev/null +++ b/api/utils/blobaccess/git/options.go @@ -0,0 +1,194 @@ +package git + +import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/mandelsoft/logging" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/mandelsoft/vfs/pkg/projectionfs" + "github.com/mandelsoft/vfs/pkg/vfs" + + "ocm.software/ocm/api/credentials" + "ocm.software/ocm/api/datacontext" + "ocm.software/ocm/api/datacontext/attrs/tmpcache" + "ocm.software/ocm/api/datacontext/attrs/vfsattr" + "ocm.software/ocm/api/tech/git" + "ocm.software/ocm/api/tech/git/identity" + ocmlog "ocm.software/ocm/api/utils/logging" + "ocm.software/ocm/api/utils/stdopts" +) + +type Option = optionutils.Option[*Options] + +type Options struct { + git.ClientOptions + + stdopts.StandardContexts + stdopts.PathFileSystem +} + +func (o *Options) Logger(keyValuePairs ...interface{}) logging.Logger { + return ocmlog.LogContext(o.LoggingContext.Value, o.CredentialContext.Value).Logger(git.REALM).WithValues(keyValuePairs...) +} + +func (o *Options) Cache() *tmpcache.Attribute { + if o.CachingPath.Value != "" { + return tmpcache.New(o.CachingPath.Value, o.CachingFileSystem.Value) + } + if o.CachingContext.Value != nil { + return tmpcache.Get(o.CachingContext.Value) + } + return tmpcache.Get(o.CredentialContext.Value) +} + +func (o *Options) ApplyTo(opts *Options) { + if opts == nil { + return + } + if o.CredentialContext.Value != nil { + opts.CredentialContext = o.CredentialContext + } + if o.Credentials.Value != nil { + opts.Credentials = o.Credentials + } + if o.LoggingContext.Value != nil { + opts.LoggingContext = o.LoggingContext + } + if o.CachingFileSystem.Value != nil { + opts.CachingFileSystem = o.CachingFileSystem + } + if o.URL != "" { + opts.URL = o.URL + } + if o.Ref != "" { + opts.Ref = o.Ref + } + if o.Commit != "" { + opts.Commit = o.Commit + } +} + +func (o *Options) ConfigureAuthMethod() error { + if o.ClientOptions.AuthMethod != nil { + return nil + } + + var err error + + if o.Credentials.Value != nil { + if o.ClientOptions.AuthMethod, err = git.AuthFromCredentials(o.Credentials.Value); err != nil { + return err + } + } + + if o.CredentialContext.Value == nil { + return nil + } + + creds, err := identity.GetCredentials(o.CredentialContext.Value, o.URL) + if err != nil { + return err + } + + if creds != nil { + if o.ClientOptions.AuthMethod, err = git.AuthFromCredentials(creds); err != nil { + return err + } + } + + return nil +} + +func (o *Options) CachingFilesystem() (vfs.FileSystem, func() error, error) { + if o.PathFileSystem.Value != nil { + return o.PathFileSystem.Value, nil, nil + } + if o.CachingFileSystem.Value != nil { + return o.CachingFileSystem.Value, nil, nil + } + + if o.CachingContext.Value != nil { + if fs := vfsattr.Get(o.CachingContext.Value); fs != nil { + return fs, nil, nil + } + + if fromtmp := tmpcache.Get(o.CachingContext.Value); fromtmp != nil { + fs, err := projectionfs.New(fromtmp.Filesystem, fromtmp.Path) + if err != nil { + return nil, nil, err + } + return fs, nil, nil + } + } + tmpfs, err := osfs.NewTempFileSystem() + return tmpfs, func() error { return vfs.Cleanup(tmpfs) }, err +} + +func option[S any, T any](v T) optionutils.Option[*Options] { + return optionutils.WithGenericOption[S, *Options](v) +} + +func WithCredentialContext(ctx credentials.ContextProvider) Option { + return option[stdopts.CredentialContextOptionBag](ctx) +} + +func WithLoggingContext(ctx logging.ContextProvider) Option { + return option[stdopts.LoggingContextOptionBag](ctx) +} + +func WithCachingContext(ctx datacontext.Context) Option { + return option[stdopts.CachingContextOptionBag](ctx) +} + +func WithCachingFileSystem(fs vfs.FileSystem) Option { + return option[stdopts.CachingFileSystemOptionBag](fs) +} + +func WithPathFileSystem(fs vfs.FileSystem) Option { + return option[stdopts.PathFileSystemOptionBag](fs) +} + +func WithCredentials(c credentials.Credentials) Option { + return option[stdopts.CredentialsOptionBag](c) +} + +//////////////////////////////////////////////////////////////////////////////// + +type URLOptionBag interface { + SetURL(v string) +} + +func (o *Options) SetURL(v string) { + o.URL = v +} + +func WithURL(url string) Option { + return option[URLOptionBag](url) +} + +//////////////////////////////////////////////////////////////////////////////// + +type RefOptionBag interface { + SetRef(v string) +} + +func (o *Options) SetRef(v string) { + o.Ref = v +} + +func WithRef(ref string) Option { + return option[RefOptionBag](ref) +} + +//////////////////////////////////////////////////////////////////////////////// + +type CommitOptionBag interface { + SetCommit(v string) +} + +func (o *Options) SetCommit(v string) { + o.Commit = v +} + +func WithCommit(ref string) Option { + return option[CommitOptionBag](ref) +} diff --git a/api/utils/blobaccess/git/suite_test.go b/api/utils/blobaccess/git/suite_test.go new file mode 100644 index 0000000000..1e348d8652 --- /dev/null +++ b/api/utils/blobaccess/git/suite_test.go @@ -0,0 +1,13 @@ +package git_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "git Blob Access Test Suite") +} diff --git a/api/utils/blobaccess/git/testdata/repo/file_in_repo b/api/utils/blobaccess/git/testdata/repo/file_in_repo new file mode 100644 index 0000000000..5eced95754 --- /dev/null +++ b/api/utils/blobaccess/git/testdata/repo/file_in_repo @@ -0,0 +1 @@ +Foobar \ No newline at end of file diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/git/cli.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/cli.go new file mode 100644 index 0000000000..4d812d5c8f --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/cli.go @@ -0,0 +1,20 @@ +package git + +import ( + "ocm.software/ocm/api/utils/cobrautils/flagsets" + "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/options" +) + +func ConfigHandler() flagsets.ConfigOptionTypeSetHandler { + return flagsets.NewConfigOptionTypeSetHandler( + TYPE, AddConfig, + options.RepositoryOption, + options.VersionOption, + ) +} + +func AddConfig(opts flagsets.ConfigOptions, config flagsets.Config) error { + flagsets.AddFieldByOptionP(opts, options.RepositoryOption, config, "repository") + flagsets.AddFieldByOptionP(opts, options.VersionOption, config, "ref") + return nil +} diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/git/input_test.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/input_test.go new file mode 100644 index 0000000000..b664f261eb --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/input_test.go @@ -0,0 +1,125 @@ +package git_test + +import ( + "fmt" + "os" + + . "github.com/mandelsoft/goutils/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "ocm.software/ocm/api/datacontext/attrs/vfsattr" + "ocm.software/ocm/api/ocm" + "ocm.software/ocm/api/ocm/extensions/repositories/ctf" + "ocm.software/ocm/api/utils/accessio" + . "ocm.software/ocm/cmds/ocm/testhelper" +) + +const ( + ARCH = "test.ctf" + CONSTRUCTOR = "component-constructor.yaml" + VERSION = "v1" +) + +var _ = Describe("Test Environment", func() { + var env *TestEnv + + BeforeEach(func() { + env = NewTestEnv(TestData()) + }) + + AfterEach(func() { + Expect(env.Cleanup()).To(Succeed()) + }) + + It("add git repo described by access type specification", func() { + constructor := fmt.Sprintf(`--- +name: test.de/x +version: %s +provider: + name: ocm +resources: +- name: hello-world + type: git + version: 0.0.1 + access: + type: git + commit: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d" + ref: refs/heads/master + repository: https://github.com/octocat/Hello-World.git +`, VERSION) + Expect( + env.WriteFile(CONSTRUCTOR, []byte(constructor), os.ModePerm), + ).To(Succeed()) + + Expect(env.Execute( + "add", + "cv", + "--create", + "--file", + ARCH, + "--force", + "--type", + "directory", + CONSTRUCTOR, + )).To(Succeed()) + + ctx := ocm.New() + vfsattr.Set(ctx, env.FileSystem()) + r := Must(ctf.Open(ctx, ctf.ACC_READONLY, ARCH, 0o400, accessio.FormatDirectory, accessio.PathFileSystem(env.FileSystem()))) + DeferCleanup(r.Close) + + c := Must(r.LookupComponent("test.de/x")) + DeferCleanup(c.Close) + cv := Must(c.LookupVersion(VERSION)) + DeferCleanup(cv.Close) + cd := cv.GetDescriptor() + Expect(len(cd.Resources)).To(Equal(1)) + }) + + It("add git repo described by cli options through blob access via input described in file", func() { + + constructor := fmt.Sprintf(`--- +name: test.de/x +version: %s +provider: + name: ocm +resources: +- name: hello-world + type: git + version: 0.0.1 + input: + type: git + ref: refs/heads/master + commit: "7fd1a60b01f91b314f59955a4e4d4e80d8edf11d" + repository: https://github.com/octocat/Hello-World.git +`, VERSION) + Expect( + env.WriteFile(CONSTRUCTOR, []byte(constructor), os.ModePerm), + ).To(Succeed()) + + Expect(env.Execute( + "add", + "cv", + "--file", + ARCH, + "--create", + "--force", + "--type", + "directory", + CONSTRUCTOR, + )).To(Succeed()) + + ctx := ocm.New() + vfsattr.Set(ctx, env.FileSystem()) + r := Must(ctf.Open(ctx, ctf.ACC_READONLY, ARCH, 0o400, accessio.FormatDirectory, accessio.PathFileSystem(env.FileSystem()))) + DeferCleanup(r.Close) + + c := Must(r.LookupComponent("test.de/x")) + DeferCleanup(c.Close) + cv := Must(c.LookupVersion(VERSION)) + DeferCleanup(cv.Close) + cd := cv.GetDescriptor() + Expect(len(cd.Resources)).To(Equal(1)) + }) +}) diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/git/spec.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/spec.go new file mode 100644 index 0000000000..60b1178cc1 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/spec.go @@ -0,0 +1,77 @@ +package git + +import ( + "github.com/go-git/go-git/v5/plumbing" + giturls "github.com/whilp/git-urls" + "k8s.io/apimachinery/pkg/util/validation/field" + + "ocm.software/ocm/api/utils/blobaccess" + "ocm.software/ocm/api/utils/blobaccess/git" + "ocm.software/ocm/api/utils/runtime" + "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs" +) + +type Spec struct { + inputs.InputSpecBase `json:",inline"` + + // Repository is the Git Repository URL + Repository string `json:"repository"` + + // Ref is the Git Ref to check out. + // If empty, the default HEAD (remotes/origin/HEAD) of the remote is used. + Ref string `json:"ref,omitempty"` + + // Commit is the Git Commit to check out. + // If empty, the default HEAD of the Ref is used. + Commit string `json:"commit,omitempty"` +} + +var _ inputs.InputSpec = (*Spec)(nil) + +func New(repository, ref, commit string) *Spec { + return &Spec{ + InputSpecBase: inputs.InputSpecBase{ + ObjectVersionedType: runtime.ObjectVersionedType{ + Type: TYPE, + }, + }, + Repository: repository, + Ref: ref, + Commit: commit, + } +} + +func (s *Spec) Validate(fldPath *field.Path, _ inputs.Context, _ string) field.ErrorList { + var allErrs field.ErrorList + + if path := fldPath.Child("repository"); s.Repository == "" { + allErrs = append(allErrs, field.Invalid(path, s.Repository, "no repository")) + } else { + if _, err := giturls.Parse(s.Repository); err != nil { + allErrs = append(allErrs, field.Invalid(path, s.Repository, err.Error())) + } + } + + if ref := fldPath.Child("ref"); s.Ref != "" { + if err := plumbing.ReferenceName(s.Ref).Validate(); err != nil { + allErrs = append(allErrs, field.Invalid(ref, s.Ref, "invalid ref")) + } + } + + return allErrs +} + +func (s *Spec) GetBlob(ctx inputs.Context, info inputs.InputResourceInfo) (blobaccess.BlobAccess, string, error) { + blob, err := git.BlobAccess( + git.WithURL(s.Repository), + git.WithRef(s.Ref), + git.WithCommit(s.Commit), + git.WithCredentialContext(ctx), + git.WithLoggingContext(ctx), + git.WithCachingContext(ctx), + ) + if err != nil { + return nil, "", err + } + return blob, "", nil +} diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/git/suite_test.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/suite_test.go new file mode 100644 index 0000000000..b2afdea537 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/suite_test.go @@ -0,0 +1,13 @@ +package git_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Input Type git") +} diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/git/testdata/resources1.yaml b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/testdata/resources1.yaml new file mode 100644 index 0000000000..1ebad10285 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/testdata/resources1.yaml @@ -0,0 +1,6 @@ +name: hello-world +type: git +input: + type: git + repository: https://github.com/octocat/Hello-World.git + version: refs/heads/master \ No newline at end of file diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/git/type.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/type.go new file mode 100644 index 0000000000..f4040197ae --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/git/type.go @@ -0,0 +1,33 @@ +package git + +import ( + "ocm.software/ocm/api/oci/annotations" + "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs" +) + +const TYPE = "git" + +func init() { + inputs.DefaultInputTypeScheme.Register(inputs.NewInputType(TYPE, &Spec{}, usage, ConfigHandler())) +} + +const usage = ` +The repository type allows accessing an arbitrary git repository +using the manifest annotation ` + annotations.COMPVERS_ANNOTATION + `. +The ref can be used to further specify the branch or tag to checkout, otherwise the remote HEAD is used. + +This blob type specification supports the following fields: +- **repository** *string* + + This REQUIRED property describes the URL of the git repository to access. All git URL formats are supported. + +- **ref** *string* + + This OPTIONAL property can be used to specify the remote branch or tag to checkout (commonly called ref). + If not set, the default HEAD (remotes/origin/HEAD) of the remote is used. + +- **commit** *string* + + This OPTIONAL property can be used to specify the commit hash to checkout. + If not set, the default HEAD of the ref is used. +` diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go index a03de2fceb..a73a166973 100644 --- a/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go @@ -6,6 +6,7 @@ import ( _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/docker" _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/dockermulti" _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/file" + _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/git" _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/helm" _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/maven" _ "ocm.software/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/npm" diff --git a/docs/reference/ocm_add_resource-configuration.md b/docs/reference/ocm_add_resource-configuration.md index 2e541891bd..2d84437b48 100644 --- a/docs/reference/ocm_add_resource-configuration.md +++ b/docs/reference/ocm_add_resource-configuration.md @@ -327,6 +327,29 @@ with the field type in the input field: Options used to configure fields: --inputCompress, --inputPath, --mediaType +- Input type git + + The repository type allows accessing an arbitrary git repository + using the manifest annotation software.ocm/component-version. + The ref can be used to further specify the branch or tag to checkout, otherwise the remote HEAD is used. + + This blob type specification supports the following fields: + - **repository** *string* + + This REQUIRED property describes the URL of the git repository to access. All git URL formats are supported. + + - **ref** *string* + + This OPTIONAL property can be used to specify the remote branch or tag to checkout (commonly called ref). + If not set, the default HEAD (remotes/origin/HEAD) of the remote is used. + + - **commit** *string* + + This OPTIONAL property can be used to specify the commit hash to checkout. + If not set, the default HEAD of the ref is used. + + Options used to configure fields: --inputRepository, --inputVersion + - Input type helm The path must denote an helm chart archive or directory @@ -607,6 +630,30 @@ The access method specification can be put below the access field. If always requires the field type describing the kind and version shown below. +- Access type git + + This method implements the access of the content of a git commit stored in a + Git repository. + + The following versions are supported: + - Version v1alpha1 + + The type specific specification fields are: + + - **repoUrl** *string* + + Repository URL with or without scheme. + + - **ref** (optional) *string* + + Original ref used to get the commit from + + - **commit** *string* + + The sha/id of the git commit + + Options used to configure fields: --accessRepository, --commit, --reference + - Access type gitHub This method implements the access of the content of a git commit stored in a diff --git a/docs/reference/ocm_add_resources.md b/docs/reference/ocm_add_resources.md index 99d746c1ad..f350c6d481 100644 --- a/docs/reference/ocm_add_resources.md +++ b/docs/reference/ocm_add_resources.md @@ -339,6 +339,29 @@ with the field type in the input field: Options used to configure fields: --inputCompress, --inputPath, --mediaType +- Input type git + + The repository type allows accessing an arbitrary git repository + using the manifest annotation software.ocm/component-version. + The ref can be used to further specify the branch or tag to checkout, otherwise the remote HEAD is used. + + This blob type specification supports the following fields: + - **repository** *string* + + This REQUIRED property describes the URL of the git repository to access. All git URL formats are supported. + + - **ref** *string* + + This OPTIONAL property can be used to specify the remote branch or tag to checkout (commonly called ref). + If not set, the default HEAD (remotes/origin/HEAD) of the remote is used. + + - **commit** *string* + + This OPTIONAL property can be used to specify the commit hash to checkout. + If not set, the default HEAD of the ref is used. + + Options used to configure fields: --inputRepository, --inputVersion + - Input type helm The path must denote an helm chart archive or directory @@ -619,6 +642,30 @@ The access method specification can be put below the access field. If always requires the field type describing the kind and version shown below. +- Access type git + + This method implements the access of the content of a git commit stored in a + Git repository. + + The following versions are supported: + - Version v1alpha1 + + The type specific specification fields are: + + - **repoUrl** *string* + + Repository URL with or without scheme. + + - **ref** (optional) *string* + + Original ref used to get the commit from + + - **commit** *string* + + The sha/id of the git commit + + Options used to configure fields: --accessRepository, --commit, --reference + - Access type gitHub This method implements the access of the content of a git commit stored in a diff --git a/docs/reference/ocm_add_source-configuration.md b/docs/reference/ocm_add_source-configuration.md index 05153898b8..ecec431c58 100644 --- a/docs/reference/ocm_add_source-configuration.md +++ b/docs/reference/ocm_add_source-configuration.md @@ -327,6 +327,29 @@ with the field type in the input field: Options used to configure fields: --inputCompress, --inputPath, --mediaType +- Input type git + + The repository type allows accessing an arbitrary git repository + using the manifest annotation software.ocm/component-version. + The ref can be used to further specify the branch or tag to checkout, otherwise the remote HEAD is used. + + This blob type specification supports the following fields: + - **repository** *string* + + This REQUIRED property describes the URL of the git repository to access. All git URL formats are supported. + + - **ref** *string* + + This OPTIONAL property can be used to specify the remote branch or tag to checkout (commonly called ref). + If not set, the default HEAD (remotes/origin/HEAD) of the remote is used. + + - **commit** *string* + + This OPTIONAL property can be used to specify the commit hash to checkout. + If not set, the default HEAD of the ref is used. + + Options used to configure fields: --inputRepository, --inputVersion + - Input type helm The path must denote an helm chart archive or directory @@ -607,6 +630,30 @@ The access method specification can be put below the access field. If always requires the field type describing the kind and version shown below. +- Access type git + + This method implements the access of the content of a git commit stored in a + Git repository. + + The following versions are supported: + - Version v1alpha1 + + The type specific specification fields are: + + - **repoUrl** *string* + + Repository URL with or without scheme. + + - **ref** (optional) *string* + + Original ref used to get the commit from + + - **commit** *string* + + The sha/id of the git commit + + Options used to configure fields: --accessRepository, --commit, --reference + - Access type gitHub This method implements the access of the content of a git commit stored in a diff --git a/docs/reference/ocm_add_sources.md b/docs/reference/ocm_add_sources.md index 54f7d17b70..4434cecd57 100644 --- a/docs/reference/ocm_add_sources.md +++ b/docs/reference/ocm_add_sources.md @@ -337,6 +337,29 @@ with the field type in the input field: Options used to configure fields: --inputCompress, --inputPath, --mediaType +- Input type git + + The repository type allows accessing an arbitrary git repository + using the manifest annotation software.ocm/component-version. + The ref can be used to further specify the branch or tag to checkout, otherwise the remote HEAD is used. + + This blob type specification supports the following fields: + - **repository** *string* + + This REQUIRED property describes the URL of the git repository to access. All git URL formats are supported. + + - **ref** *string* + + This OPTIONAL property can be used to specify the remote branch or tag to checkout (commonly called ref). + If not set, the default HEAD (remotes/origin/HEAD) of the remote is used. + + - **commit** *string* + + This OPTIONAL property can be used to specify the commit hash to checkout. + If not set, the default HEAD of the ref is used. + + Options used to configure fields: --inputRepository, --inputVersion + - Input type helm The path must denote an helm chart archive or directory @@ -617,6 +640,30 @@ The access method specification can be put below the access field. If always requires the field type describing the kind and version shown below. +- Access type git + + This method implements the access of the content of a git commit stored in a + Git repository. + + The following versions are supported: + - Version v1alpha1 + + The type specific specification fields are: + + - **repoUrl** *string* + + Repository URL with or without scheme. + + - **ref** (optional) *string* + + Original ref used to get the commit from + + - **commit** *string* + + The sha/id of the git commit + + Options used to configure fields: --accessRepository, --commit, --reference + - Access type gitHub This method implements the access of the content of a git commit stored in a diff --git a/docs/reference/ocm_credential-handling.md b/docs/reference/ocm_credential-handling.md index 71e3340e28..d0ba951423 100644 --- a/docs/reference/ocm_credential-handling.md +++ b/docs/reference/ocm_credential-handling.md @@ -110,6 +110,19 @@ The following credential consumer types are used/supported: - key: secret key use to access the credential server + - Git: Git credential matcher + + It matches the Git consumer type and additionally acts like + the hostpath type. + + Credential consumers of the consumer type Git evaluate the following credential properties: + + - username: the basic auth user name + - password: the basic auth password + - token: HTTP token authentication + - privateKey: Private Key authentication certificate + + - Github: GitHub credential matcher This matcher is a hostpath matcher. diff --git a/docs/reference/ocm_get_credentials.md b/docs/reference/ocm_get_credentials.md index 55ed158abc..4ef43b318d 100644 --- a/docs/reference/ocm_get_credentials.md +++ b/docs/reference/ocm_get_credentials.md @@ -36,6 +36,19 @@ Matchers exist for the following usage contexts or consumer types: - key: secret key use to access the credential server + - Git: Git credential matcher + + It matches the Git consumer type and additionally acts like + the hostpath type. + + Credential consumers of the consumer type Git evaluate the following credential properties: + + - username: the basic auth user name + - password: the basic auth password + - token: HTTP token authentication + - privateKey: Private Key authentication certificate + + - Github: GitHub credential matcher This matcher is a hostpath matcher. diff --git a/docs/reference/ocm_logging.md b/docs/reference/ocm_logging.md index 9a1c45800b..c73dc6cc3e 100644 --- a/docs/reference/ocm_logging.md +++ b/docs/reference/ocm_logging.md @@ -27,6 +27,7 @@ The following *realms* are used by the command line tool: - ocm/credentials/dockerconfig: docker config handling as credential repository - ocm/credentials/vault: HashiCorp Vault Access - ocm/downloader: Downloaders + - ocm/git: git repository - ocm/maven: Maven repository - ocm/npm: NPM registry - ocm/oci/docker: Docker repository handling diff --git a/docs/reference/ocm_ocm-accessmethods.md b/docs/reference/ocm_ocm-accessmethods.md index 63d1ad8b44..ba86b327a5 100644 --- a/docs/reference/ocm_ocm-accessmethods.md +++ b/docs/reference/ocm_ocm-accessmethods.md @@ -15,6 +15,30 @@ The access method specification can be put below the access field. If always requires the field type describing the kind and version shown below. +- Access type git + + This method implements the access of the content of a git commit stored in a + Git repository. + + The following versions are supported: + - Version v1alpha1 + + The type specific specification fields are: + + - **repoUrl** *string* + + Repository URL with or without scheme. + + - **ref** (optional) *string* + + Original ref used to get the commit from + + - **commit** *string* + + The sha/id of the git commit + + Options used to configure fields: --accessRepository, --commit, --reference + - Access type gitHub This method implements the access of the content of a git commit stored in a diff --git a/go.mod b/go.mod index fbd7e49fce..7ee0a20f49 100644 --- a/go.mod +++ b/go.mod @@ -30,6 +30,8 @@ require ( github.com/fluxcd/pkg/ssa v0.43.0 github.com/gertd/go-pluralize v0.2.1 github.com/ghodss/yaml v1.0.0 + github.com/go-git/go-billy/v5 v5.6.0 + github.com/go-git/go-git/v5 v5.12.0 github.com/go-logr/logr v1.4.2 github.com/go-openapi/strfmt v0.23.0 github.com/go-openapi/swag v0.23.0 @@ -68,6 +70,7 @@ require ( github.com/texttheater/golang-levenshtein v1.0.1 github.com/tonglil/buflogr v1.1.1 github.com/ulikunitz/xz v0.5.12 + github.com/whilp/git-urls v1.0.0 github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 @@ -177,6 +180,7 @@ require ( github.com/dustin/go-humanize v1.0.1 // indirect github.com/elliotchance/orderedmap v1.7.0 // indirect github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/evanphx/json-patch/v5 v5.9.0 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect @@ -187,6 +191,7 @@ require ( github.com/fxamacker/cbor/v2 v2.7.0 // indirect github.com/go-chi/chi v4.1.2+incompatible // indirect github.com/go-errors/errors v1.5.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-gorp/gorp/v3 v3.1.0 // indirect github.com/go-jose/go-jose/v3 v3.0.3 // indirect github.com/go-jose/go-jose/v4 v4.0.4 // indirect @@ -237,12 +242,14 @@ require ( github.com/huandu/xstrings v1.5.0 // indirect github.com/in-toto/in-toto-golang v0.9.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 // indirect github.com/jinzhu/copier v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.1-0.20220621161143-b0104c826a24 // indirect github.com/jmoiron/sqlx v1.4.0 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 // indirect github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect github.com/letsencrypt/boulder v0.0.0-20241010192615-6692160cedfa // indirect @@ -279,6 +286,7 @@ require ( github.com/pborman/uuid v1.2.1 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/peterbourgon/diskv v2.0.1+incompatible // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/prometheus/client_golang v1.20.5 // indirect github.com/prometheus/client_model v0.6.1 // indirect @@ -293,11 +301,13 @@ require ( github.com/sassoftware/relic v7.2.1+incompatible // indirect github.com/secure-systems-lab/go-securesystemslib v0.8.0 // indirect github.com/segmentio/ksuid v1.0.4 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/shibumi/go-pathspec v1.3.0 // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sigstore/fulcio v1.6.5 // indirect github.com/sigstore/protobuf-specs v0.3.2 // indirect github.com/sigstore/timestamp-authority v1.2.3 // indirect + github.com/skeema/knownhosts v1.2.2 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect @@ -317,6 +327,7 @@ require ( github.com/vbatts/tar-split v0.11.6 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xanzy/go-gitlab v0.112.0 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xlab/treeprint v1.2.0 // indirect @@ -352,6 +363,7 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiserver v0.32.0 // indirect k8s.io/component-base v0.32.0 // indirect diff --git a/go.sum b/go.sum index 0dd5a350bd..d59e16a4e7 100644 --- a/go.sum +++ b/go.sum @@ -84,6 +84,7 @@ github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8afzqM= github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6lLg= @@ -159,6 +160,8 @@ github.com/aliyun/credentials-go v1.1.2/go.mod h1:ozcZaMR5kLM7pwtCMEpVmQ242suV6q github.com/aliyun/credentials-go v1.3.6/go.mod h1:1LxUuX7L5YrZUWzBrRyk0SwSdH4OmPrib8NVePL3fxM= github.com/aliyun/credentials-go v1.3.10 h1:45Xxrae/evfzQL9V10zL3xX31eqgLWEaIdCoPipOEQA= github.com/aliyun/credentials-go v1.3.10/go.mod h1:Jm6d+xIgwJVLVWT561vy67ZRP4lPTQxMbEYRuT2Ti1U= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= @@ -365,12 +368,16 @@ github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/elliotchance/orderedmap v1.7.0 h1:FirjcM/NbcyudJhaIF9MG/RjIh5XHm2xb1SFquZ8k0g= github.com/elliotchance/orderedmap v1.7.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emicklei/proto v1.12.1 h1:6n/Z2pZAnBwuhU66Gs8160B8rrrYKo7h2F2sCOnNceE= github.com/emicklei/proto v1.12.1/go.mod h1:rn1FgRS/FANiZdD2djyH7TMA9jdRDcYQ9IEN9yvjX0A= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -409,10 +416,20 @@ github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlL github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= +github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= +github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= +github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= @@ -628,6 +645,8 @@ github.com/in-toto/in-toto-golang v0.9.0/go.mod h1:xsBVrVsHNsB61++S6Dy2vWosKhuA3 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267 h1:TMtDYDHKYY15rFihtRfck/bfFqNfvcabqvXAFQfAUpY= github.com/jedisct1/go-minisign v0.0.0-20230811132847-661be99b8267/go.mod h1:h1nSAbGFqGVzn6Jyl1R/iCcBUHN4g+gW1u9CoBTrb9E= github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc= @@ -657,6 +676,8 @@ github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHm github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/loggo v0.0.0-20190526231331-6e530bcce5d8/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= @@ -826,6 +847,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+v github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI= github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= @@ -895,8 +918,8 @@ github.com/secure-systems-lab/go-securesystemslib v0.8.0 h1:mr5An6X45Kb2nddcFlbm github.com/secure-systems-lab/go-securesystemslib v0.8.0/go.mod h1:UH2VZVuJfCYR8WgMlCU1uFsOUU+KeyrTWcSS73NBOzU= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= -github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= -github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/shibumi/go-pathspec v1.3.0 h1:QUyMZhFo0Md5B8zV8x2tesohbb5kfbpTi9rBnKh5dkI= github.com/shibumi/go-pathspec v1.3.0/go.mod h1:Xutfslp817l2I1cZvgcfeMQJG5QnU2lh5tVaaMCl3jE= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= @@ -926,8 +949,11 @@ github.com/sigstore/timestamp-authority v1.2.3/go.mod h1:q2tJKJzP34hLIbVu3Y1A9bB github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= +github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= @@ -1006,10 +1032,14 @@ github.com/vbatts/tar-split v0.11.6 h1:4SjTW5+PU11n6fZenf2IPoV8/tz3AaYHMWjf23env github.com/vbatts/tar-split v0.11.6/go.mod h1:dqKNtesIOr2j2Qv3W/cHjnvk9I8+G7oAkFDFN6TCBEI= github.com/weppos/publicsuffix-go v0.40.3-0.20240815124645-a8ed110559c9 h1:4pH9wXOWQdW8kVMJ8P/kxbuxJKR+iNvDeC8zEVLy7eM= github.com/weppos/publicsuffix-go v0.40.3-0.20240815124645-a8ed110559c9/go.mod h1:o4XOb/pL91sSlesP+I2Xcp38P4/emRvDF6N6xUWvwzg= +github.com/whilp/git-urls v1.0.0 h1:95f6UMWN5FKW71ECsXRUd3FVYiXdrE7aX4NZKcPmIjU= +github.com/whilp/git-urls v1.0.0/go.mod h1:J16SAmobsqc3Qcy98brfl5f5+e0clUvg1krgwk/qCfE= github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= github.com/xanzy/go-gitlab v0.112.0 h1:6Z0cqEooCvBMfBIHw+CgO4AKGRV8na/9781xOb0+DKw= github.com/xanzy/go-gitlab v0.112.0/go.mod h1:wKNKh3GkYDMOsGmnfuX+ITCmDuSDWFO0G+C4AygL9RY= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1103,6 +1133,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= @@ -1190,6 +1221,7 @@ golang.org/x/sys v0.0.0-20200509044756-6aff5f38e54f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1299,6 +1331,7 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/cenkalti/backoff.v2 v2.2.1 h1:eJ9UAg01/HIHG987TwxvnzK2MgxXq97YY6rYDpY9aII= gopkg.in/cenkalti/backoff.v2 v2.2.1/go.mod h1:S0QdOvT2AlerfSBkp0O+dk+bbIMaNbEmVk876gPCthU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -1317,6 +1350,8 @@ gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1 h1:d4KQkxAaAiRY2h5Zqis161Pv91A37uZyJOx gopkg.in/rethinkdb/rethinkdb-go.v6 v6.2.1/go.mod h1:WbjuEoo1oadwzQ4apSDU+JTvmllEHtsNHS6y7vFc7iw= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= From b88e60fb7382a54123e04ef9d651b5b977b2a97c Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:54:23 +0100 Subject: [PATCH 46/50] chore: just a tiny refactor in the returning code (#1221) #### What this PR does / why we need it #### Which issue(s) this PR fixes Signed-off-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> --- api/tech/oras/fetcher.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/tech/oras/fetcher.go b/api/tech/oras/fetcher.go index a12df685fc..95b54a7cea 100644 --- a/api/tech/oras/fetcher.go +++ b/api/tech/oras/fetcher.go @@ -65,6 +65,7 @@ func (c *OrasFetcher) resolveDescriptor(ctx context.Context, desc ociv1.Descript if err != nil { return ociv1.Descriptor{}, fmt.Errorf("failed to resolve descriptor %q: %w", desc.Digest.String(), err) } + return desc, nil } @@ -79,10 +80,9 @@ func (c *OrasFetcher) resolveDescriptor(ctx context.Context, desc ociv1.Descript return ociv1.Descriptor{}, fmt.Errorf("failed to resolve manifest %q: %w", desc.Digest.String(), err) } - desc = mdesc - } else { - desc = bdesc + + return mdesc, nil } - return desc, err + return bdesc, err } From 6ac1176c9207205b4c1bbe163e29457e5f3932ef Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:07:20 +0000 Subject: [PATCH 47/50] chore: update 'flake.nix' (#1222) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index befdba47c8..ce7f2ffed1 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-D5uEj20XEPSVXggzZsLiBM8KifkxapX9ISUQbDsgPmk="; + vendorHash = "sha256-V+Uhb45+8Wa+kruXL/FpgBCAzUFfcls95FIC5PcB9zY="; src = ./.; From b9175935963addd6d81952c5aeb4c1d98c6f9f43 Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Mon, 6 Jan 2025 14:40:07 +0100 Subject: [PATCH 48/50] chore(platforms): publish for: linux/amd64 and linux/arm64 (#1225) #### What this PR does / why we need it https://github.com/open-component-model/ocm/issues/947 #### Which issue(s) this PR fixes fixes: https://github.com/open-component-model/ocm-project/issues/291 --- .github/workflows/publish-latest.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish-latest.yaml b/.github/workflows/publish-latest.yaml index 9d60f1dd52..9736db31cf 100644 --- a/.github/workflows/publish-latest.yaml +++ b/.github/workflows/publish-latest.yaml @@ -60,8 +60,8 @@ jobs: uses: docker/build-push-action@v6 with: context: . - # supported platforms of https://hub.docker.com/_/golang/tags?page=1&name=1.23-alpine3.20 - # platforms: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x + # supported platforms: https://github.com/GoogleContainerTools/distroless?tab=readme-ov-file#what-images-are-available + platforms: linux/amd64,linux/arm64 #linux/arm,linux/ppc64le,linux/s390x push: true tags: | ghcr.io/open-component-model/ocm:latest @@ -166,4 +166,4 @@ jobs: key: ${{ env.cache_name }}-${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}-${{ hashFiles('**/go.mod') }} upload-chunk-size: 256000000 # default of 32MB is not really optimal for our large cache, choose 256MB instead env: - cache_name: ocm-cli-latest-go-cache # needs to be the same key in the end as in the build step \ No newline at end of file + cache_name: ocm-cli-latest-go-cache # needs to be the same key in the end as in the build step From 22002cc084fce25cb42467618b6332b463194db7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:00:30 +0100 Subject: [PATCH 49/50] chore(deps): bump github.com/go-git/go-git/v5 from 5.12.0 to 5.13.1 in the go_modules group (#1226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps the go_modules group with 1 update: [github.com/go-git/go-git/v5](https://github.com/go-git/go-git). Updates `github.com/go-git/go-git/v5` from 5.12.0 to 5.13.1
Release notes

Sourced from github.com/go-git/go-git/v5's releases.

v5.13.1

What's Changed

Full Changelog: https://github.com/go-git/go-git/compare/v5.13.0...v5.13.1

v5.13.0

What's Changed

... (truncated)

Commits
  • b6bc0c0 Merge pull request #1346 from go-git/revert-1157-ja/knownHostsDb
  • 42f9d6b Revert "plumbing: transport/ssh, Add support for SSH @​cert-authority."
  • 88c7471 Merge pull request #1340 from go-git/dependabot/go_modules/github.com/elazarl...
  • 2fae180 build: bump github.com/elazarl/goproxy from 1.2.2 to 1.2.3
  • a0dfb09 Merge pull request #1329 from go-git/dependabot/go_modules/github.com/elazarl...
  • 05ae621 Merge pull request #1327 from go-git/dependabot/go_modules/github.com/go-git/...
  • b0d72b3 build: bump github.com/elazarl/goproxy from 1.2.1 to 1.2.2
  • b77b83a build: bump github.com/go-git/go-billy/v5 from 5.6.0 to 5.6.1
  • 94bd4af Merge pull request #1261 from BeChris/issue680
  • 8b7f5ba Merge pull request #1262 from go-git/dependabot/go_modules/github.com/elazarl...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github.com/go-git/go-git/v5&package-manager=go_modules&previous-version=5.12.0&new-version=5.13.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot show ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore major version` will close this group update PR and stop Dependabot creating any more for the specific dependency's major version (unless you unignore this specific dependency's major version or upgrade to it yourself) - `@dependabot ignore minor version` will close this group update PR and stop Dependabot creating any more for the specific dependency's minor version (unless you unignore this specific dependency's minor version or upgrade to it yourself) - `@dependabot ignore ` will close this group update PR and stop Dependabot creating any more for the specific dependency (unless you unignore this specific dependency or upgrade to it yourself) - `@dependabot unignore ` will remove all of the ignore conditions of the specified dependency - `@dependabot unignore ` will remove the ignore condition of the specified dependency and ignore conditions You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/open-component-model/ocm/network/alerts).
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 40 ++++++++++++++-------------------------- 2 files changed, 19 insertions(+), 31 deletions(-) diff --git a/go.mod b/go.mod index 7ee0a20f49..18fcc055dc 100644 --- a/go.mod +++ b/go.mod @@ -30,8 +30,8 @@ require ( github.com/fluxcd/pkg/ssa v0.43.0 github.com/gertd/go-pluralize v0.2.1 github.com/ghodss/yaml v1.0.0 - github.com/go-git/go-billy/v5 v5.6.0 - github.com/go-git/go-git/v5 v5.12.0 + github.com/go-git/go-billy/v5 v5.6.1 + github.com/go-git/go-git/v5 v5.13.1 github.com/go-logr/logr v1.4.2 github.com/go-openapi/strfmt v0.23.0 github.com/go-openapi/swag v0.23.0 @@ -113,7 +113,7 @@ require ( github.com/Masterminds/sprig/v3 v3.3.0 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/ProtonMail/go-crypto v1.0.0 // indirect + github.com/ProtonMail/go-crypto v1.1.3 // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect github.com/a8m/envsubst v1.4.2 // indirect github.com/alecthomas/participle/v2 v2.1.1 // indirect @@ -166,7 +166,7 @@ require ( github.com/containers/ocicrypt v1.2.0 // indirect github.com/containers/storage v1.56.0 // indirect github.com/coreos/go-oidc/v3 v3.11.0 // indirect - github.com/cyphar/filepath-securejoin v0.3.4 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect @@ -307,7 +307,7 @@ require ( github.com/sigstore/fulcio v1.6.5 // indirect github.com/sigstore/protobuf-specs v0.3.2 // indirect github.com/sigstore/timestamp-authority v1.2.3 // indirect - github.com/skeema/knownhosts v1.2.2 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.11.0 // indirect diff --git a/go.sum b/go.sum index d59e16a4e7..e4c920b580 100644 --- a/go.sum +++ b/go.sum @@ -91,8 +91,8 @@ github.com/Microsoft/hcsshim v0.12.9 h1:2zJy5KA+l0loz1HzEGqyNnjd3fyZA31ZBCGKacp6 github.com/Microsoft/hcsshim v0.12.9/go.mod h1:fJ0gkFAna6ukt0bLdKB8djt4XIJhF/vEPuoIWYVvZ8Y= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= -github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= +github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= +github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= github.com/Shopify/logrus-bugsnag v0.0.0-20170309145241-6dbc35f2c30d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d h1:UrqY+r/OJnIp5u0s1SbQ8dVfLCZJsnvazdBP5hS4iRs= github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= @@ -246,7 +246,6 @@ github.com/buildkite/interpolate v0.1.4 h1:qacB5WR+7+Ol1xiJ4xZajHh/CGDdhcMesXR+V github.com/buildkite/interpolate v0.1.4/go.mod h1:dHnrwHew5O8VNOAgMDpwRlFnhL5VSN6M1bHVmRZ9Ccc= github.com/buildkite/roko v1.2.0 h1:hbNURz//dQqNl6Eo9awjQOVOZwSDJ8VEbBDxSfT9rGQ= github.com/buildkite/roko v1.2.0/go.mod h1:23R9e6nHxgedznkwwfmqZ6+0VJZJZ2Sg/uVcp2cP46I= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= @@ -266,7 +265,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004/go.mod h1:yMWuSON2oQp+43nFtAV/uvKQIFpSPerB57DCt9t8sSA= github.com/cloudflare/cfssl v1.6.5 h1:46zpNkm6dlNkMZH/wMW22ejih6gIaJbzL2du6vD7ZeI= github.com/cloudflare/cfssl v1.6.5/go.mod h1:Bk1si7sq8h2+yVEDrFJiz3d7Aw+pfjjJSZVaD+Taky4= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.5.0 h1:hxIWksrX6XN5a1L2TI/h53AGPhNHoUBo+TD1ms9+pys= github.com/cloudflare/circl v1.5.0/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= github.com/cloudfoundry-incubator/candiedyaml v0.0.0-20170901234223-a41693b7b7af h1:6Cpkahw28+gcBdnXQL7LcMTX488+6jl6hfoTMRT6Hm4= @@ -316,8 +314,8 @@ github.com/creack/pty v1.1.19 h1:tUN6H7LWqNx4hQVxomd0CVsDwaDr9gaRQaI4GpSmrsA= github.com/creack/pty v1.1.19/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f h1:eHnXnuK47UlSTOQexbzxAZfekVz6i+LKRdj1CU5DPaM= github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw= -github.com/cyphar/filepath-securejoin v0.3.4 h1:VBWugsJh2ZxJmLFSM06/0qzQyiQX2Qs0ViKrUAcqdZ8= -github.com/cyphar/filepath-securejoin v0.3.4/go.mod h1:8s/MCNJREmFK0H02MF6Ihv1nakJe4L/w3WZLHNkvlYM= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/danieljoos/wincred v1.2.1 h1:dl9cBrupW8+r5250DYkYxocLeZ1Y4vB1kxgtjxw8GQs= github.com/danieljoos/wincred v1.2.1/go.mod h1:uGaFL9fDn3OLTvzCGulzE+SzjEe5NGlh5FdCcyfPwps= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -368,8 +366,8 @@ github.com/drone/envsubst v1.0.3/go.mod h1:N2jZmlMufstn1KEqvbHjw40h1KyTmnVzHcSc9 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dvsekhvalnov/jose2go v0.0.0-20170216131308-f21a8cedbbae/go.mod h1:7BvyPhdbLxMXIYTFPLsyJRFMsKmOZnQmzh6Gb+uquuM= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= -github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= +github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ= +github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64= github.com/elliotchance/orderedmap v1.7.0 h1:FirjcM/NbcyudJhaIF9MG/RjIh5XHm2xb1SFquZ8k0g= github.com/elliotchance/orderedmap v1.7.0/go.mod h1:wsDwEaX5jEoyhbs7x93zk2H/qv0zwuhg4inXhDkYqys= github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= @@ -416,20 +414,20 @@ github.com/gertd/go-pluralize v0.2.1 h1:M3uASbVjMnTsPb0PNqg+E/24Vwigyo/tvyMTtAlL github.com/gertd/go-pluralize v0.2.1/go.mod h1:rbYaKDbsXxmRfr8uygAEKhOWsjyrrqrkHVpZvoOp8zk= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gliderlabs/ssh v0.3.7 h1:iV3Bqi942d9huXnzEF2Mt+CY9gLu8DNM4Obd+8bODRE= -github.com/gliderlabs/ssh v0.3.7/go.mod h1:zpHEXBstFnQYtGnB8k8kQLol82umzn/2/snG7alWVD8= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= -github.com/go-git/go-billy/v5 v5.6.0 h1:w2hPNtoehvJIxR00Vb4xX94qHQi/ApZfX+nBE2Cjio8= -github.com/go-git/go-billy/v5 v5.6.0/go.mod h1:sFDq7xD3fn3E0GOwUSZqHo9lrkmx8xJhA0ZrfvjBRGM= +github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= +github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= -github.com/go-git/go-git/v5 v5.12.0 h1:7Md+ndsjrzZxbddRDZjF14qK+NN56sy6wkqaVrjZtys= -github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXYjuz9i5OEY= +github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= +github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= github.com/go-gorp/gorp/v3 v3.1.0 h1:ItKF/Vbuj31dmV4jxA1qblpSwkl9g1typ24xoe70IGs= github.com/go-gorp/gorp/v3 v3.1.0/go.mod h1:dLEjIyyRNiXvNZ8PSmzpt1GsWAUK8kjVhEpjH8TixEw= github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A= @@ -952,8 +950,8 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= -github.com/skeema/knownhosts v1.2.2/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smallstep/assert v0.0.0-20200723003110-82e2b9b3b262 h1:unQFBIznI+VYD1/1fApl1A+9VcBk+9dcqGfnePY87LY= @@ -1135,9 +1133,7 @@ golang.org/x/crypto v0.0.0-20201117144127-c1f2f97bffc9/go.mod h1:jdWPYTVW3xRLrWP golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= @@ -1181,9 +1177,7 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= @@ -1233,8 +1227,6 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -1246,9 +1238,7 @@ golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= golang.org/x/term v0.16.0/go.mod h1:yn7UURbUtPyrVJPGPq404EukNFxcm/foM+bV/bfcDsY= @@ -1260,9 +1250,7 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= From 1817c8728bced5ac8c1431ff3b0a65f502e0b132 Mon Sep 17 00:00:00 2001 From: "ocmbot[bot]" <125909804+ocmbot[bot]@users.noreply.github.com> Date: Mon, 6 Jan 2025 18:13:48 +0100 Subject: [PATCH 50/50] chore: update 'flake.nix' (#1227) Update OCM CLI vendor hash (see: .github/workflows/flake_vendorhash.yaml) Co-authored-by: ocmbot[bot] <125909804+ocmbot[bot]@users.noreply.github.com> --- flake.nix | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flake.nix b/flake.nix index ce7f2ffed1..e533a95ef4 100644 --- a/flake.nix +++ b/flake.nix @@ -35,7 +35,7 @@ state = if (self ? rev) then "clean" else "dirty"; # This vendorHash represents a derivative of all go.mod dependencies and needs to be adjusted with every change - vendorHash = "sha256-V+Uhb45+8Wa+kruXL/FpgBCAzUFfcls95FIC5PcB9zY="; + vendorHash = "sha256-0jxArvCync+cw/gyyKPu4AQBnCvLdA28yFzPXvg0mxQ="; src = ./.;