From 84b9231805d321cdb805cc5b5ade82af3b72a47a Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Mon, 27 May 2024 09:26:15 +0200 Subject: [PATCH 01/12] extract optionutils + fix new usages of moved packages (#775) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Please include a summary of the changes and the related issue. Please also include relevant motivation and context. List any dependencies that are required for this change. ## What type of PR is this? (check all applicable) - [ ] 🍕 Feature - [ ] 🎇 Restructuring - [ ] 🐛 Bug Fix - [ ] 📝 Documentation Update - [ ] 🎨 Style - [ ] 🧑‍💻 Code Refactor - [ ] 🔥 Performance Improvements - [ ] ✅ Test - [ ] 🤖 Build - [ ] 🔁 CI - [ ] 📦 Chore (Release) - [ ] ⏩ Revert ## Related Tickets & Documents - Related Issue # (issue) - Closes # (issue) - Fixes # (issue) > Remove if not applicable ## Screenshots ## Added tests? - [ ] 👍 yes - [ ] 🙅 no, because they aren't needed - [ ] 🙋 no, because I need help - [ ] Separate ticket for tests # (issue/pr) Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration ## Added to documentation? - [ ] 📜 README.md - [ ] 🙅 no documentation needed ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --------- Co-authored-by: Hilmar Falkenberg --- .../commands/ocmcmds/components/check/cmd.go | 2 +- .../ocmcmds/components/check/options.go | 2 +- go.mod | 2 +- go.sum | 2 ++ pkg/blobaccess/dirtree/access.go | 2 +- pkg/blobaccess/dirtree/options.go | 2 +- pkg/blobaccess/dockerdaemon/access.go | 3 +- pkg/blobaccess/dockerdaemon/options.go | 3 +- pkg/blobaccess/dockermulti/access.go | 2 +- pkg/blobaccess/dockermulti/options.go | 2 +- pkg/blobaccess/helm/options.go | 2 +- pkg/blobaccess/helm/resource.go | 2 +- pkg/blobaccess/ociartifact/options.go | 3 +- pkg/blobaccess/ociartifact/resource.go | 3 +- pkg/blobaccess/wget/access.go | 2 +- pkg/blobaccess/wget/options.go | 2 +- .../flagsets/flagsetscheme/types.go | 3 +- .../flagsets/flagsetscheme/types_options.go | 3 +- .../credentials/repositories/vault/options.go | 2 +- .../repositories/vault/repo_int_test.go | 29 ++++++++++--------- .../credentials/repositories/vault/type.go | 2 +- pkg/contexts/oci/grammar/grammar.go | 2 +- pkg/contexts/oci/grammar/grammar_test.go | 2 +- .../oci/repositories/ocireg/uniform.go | 3 +- pkg/contexts/ocm/accessmethods/mvn/method.go | 4 +-- pkg/contexts/ocm/accessmethods/wget/method.go | 3 +- .../handlers/generic/mvn/blobhandler.go | 2 +- .../handlers/generic/mvn/registration.go | 3 +- pkg/contexts/ocm/cpi/repocpi/bridge_c.go | 2 +- pkg/contexts/ocm/cpi/repocpi/bridge_cv.go | 2 +- pkg/contexts/ocm/download/download.go | 2 +- .../artifactaccess/githubaccess/options.go | 2 +- .../artifactaccess/githubaccess/resource.go | 3 +- .../artifactaccess/ociblobaccess/options.go | 2 +- .../artifactaccess/ociblobaccess/resource.go | 2 +- .../artifactaccess/s3access/options.go | 2 +- .../artifactaccess/s3access/resource.go | 3 +- .../ocm/elements/artifactblob/api/options.go | 3 +- .../elements/artifactblob/datablob/options.go | 3 +- .../artifactblob/datablob/resource.go | 2 +- .../artifactblob/dirtreeblob/options.go | 2 +- .../artifactblob/dirtreeblob/resource.go | 2 +- .../artifactblob/dockerdaemonblob/options.go | 3 +- .../artifactblob/dockerdaemonblob/resource.go | 2 +- .../artifactblob/dockermultiblob/options.go | 3 +- .../artifactblob/dockermultiblob/resource.go | 2 +- .../artifactblob/externalblob/resource.go | 2 +- .../elements/artifactblob/fileblob/options.go | 2 +- .../artifactblob/fileblob/resource.go | 2 +- .../artifactblob/genericblob/resource.go | 2 +- .../elements/artifactblob/helmblob/options.go | 2 +- .../artifactblob/helmblob/resource.go | 2 +- .../artifactblob/ociartifactblob/options.go | 3 +- .../artifactblob/ociartifactblob/resource.go | 2 +- .../artifactblob/textblob/resource.go | 3 +- .../elements/artifactblob/wgetblob/options.go | 2 +- .../artifactblob/wgetblob/resource.go | 2 +- pkg/contexts/ocm/grammar/grammar.go | 2 +- pkg/contexts/ocm/grammar/grammar_test.go | 2 +- pkg/contexts/ocm/internal/modopts.go | 3 +- .../transferhandler/standard/options.go | 2 +- pkg/contexts/ocm/utils/check/check.go | 2 +- pkg/contexts/ocm/utils/check/options.go | 3 +- pkg/iotools/hashReaderWriter.go | 2 +- pkg/optionutils/doc.go | 2 ++ pkg/runtime/descriptivetype/options.go | 3 +- pkg/utils/tarutils/pack_test.go | 7 +++-- 67 files changed, 107 insertions(+), 81 deletions(-) create mode 100644 pkg/optionutils/doc.go diff --git a/cmds/ocm/commands/ocmcmds/components/check/cmd.go b/cmds/ocm/commands/ocmcmds/components/check/cmd.go index f2bd233fbc..3fed9536b6 100644 --- a/cmds/ocm/commands/ocmcmds/components/check/cmd.go +++ b/cmds/ocm/commands/ocmcmds/components/check/cmd.go @@ -3,6 +3,7 @@ package check import ( "fmt" + "github.com/mandelsoft/goutils/optionutils" "github.com/spf13/cobra" "k8s.io/apimachinery/pkg/util/json" @@ -19,7 +20,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/clictx" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/utils/check" - "github.com/open-component-model/ocm/pkg/optionutils" utils2 "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/cmds/ocm/commands/ocmcmds/components/check/options.go b/cmds/ocm/commands/ocmcmds/components/check/options.go index 55a1c6d12f..18f8b6c1cd 100644 --- a/cmds/ocm/commands/ocmcmds/components/check/options.go +++ b/cmds/ocm/commands/ocmcmds/components/check/options.go @@ -1,11 +1,11 @@ package check import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/spf13/pflag" "github.com/open-component-model/ocm/cmds/ocm/pkg/options" "github.com/open-component-model/ocm/pkg/contexts/ocm/utils/check" - "github.com/open-component-model/ocm/pkg/optionutils" ) func From(o options.OptionSetProvider) *Option { diff --git a/go.mod b/go.mod index a2b3c429fa..b4a7f4688a 100644 --- a/go.mod +++ b/go.mod @@ -38,7 +38,7 @@ require ( github.com/klauspost/compress v1.17.8 github.com/klauspost/pgzip v1.2.6 github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 - github.com/mandelsoft/goutils v0.0.0-20240510154642-0f1a031c54cb + github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460 github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf github.com/mandelsoft/spiff v1.7.0-beta-5 github.com/mandelsoft/vfs v0.4.3 diff --git a/go.sum b/go.sum index be2792f419..e06f85114e 100644 --- a/go.sum +++ b/go.sum @@ -684,6 +684,8 @@ github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 h1:oo9nIgnyiBg github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= github.com/mandelsoft/goutils v0.0.0-20240510154642-0f1a031c54cb h1:1d3Xxk4rkdKcIFP1AcRlPxUhcBhnFCTqrMhXztB1r5E= github.com/mandelsoft/goutils v0.0.0-20240510154642-0f1a031c54cb/go.mod h1:EbNqk9JceSMq7MJuALB/vlOpoD4MAGE0TenM9TR+C0o= +github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460 h1:q44fRqo/PC3eTexd8Q3pO2BTHTABVXsW6DBXRUhC97E= +github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460/go.mod h1:EbNqk9JceSMq7MJuALB/vlOpoD4MAGE0TenM9TR+C0o= github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf h1:WEmgzeArDbp6Aw34jmziMIE5ygo2zpl/atXRq3D7lSw= github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf/go.mod h1:uO460C1lIB3IOOgrbXhAlz3AKsOv4T2K6ALBn3PwuSg= github.com/mandelsoft/spiff v1.7.0-beta-5 h1:3kC10nTviDQhL8diSxp7i4IC2iSiDg6KPbH1CAq7Lfw= diff --git a/pkg/blobaccess/dirtree/access.go b/pkg/blobaccess/dirtree/access.go index 460225f61f..9b861cbd7c 100644 --- a/pkg/blobaccess/dirtree/access.go +++ b/pkg/blobaccess/dirtree/access.go @@ -5,12 +5,12 @@ import ( "fmt" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/blobaccess/bpi" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/utils/tarutils" ) diff --git a/pkg/blobaccess/dirtree/options.go b/pkg/blobaccess/dirtree/options.go index 5793b9e60d..3eba40a116 100644 --- a/pkg/blobaccess/dirtree/options.go +++ b/pkg/blobaccess/dirtree/options.go @@ -1,10 +1,10 @@ package dirtree import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" "golang.org/x/exp/slices" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/blobaccess/dockerdaemon/access.go b/pkg/blobaccess/dockerdaemon/access.go index 8a636390c9..a832f6d084 100644 --- a/pkg/blobaccess/dockerdaemon/access.go +++ b/pkg/blobaccess/dockerdaemon/access.go @@ -3,13 +3,14 @@ package dockerdaemon import ( "fmt" + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/blobaccess/bpi" "github.com/open-component-model/ocm/pkg/contexts/oci" "github.com/open-component-model/ocm/pkg/contexts/oci/annotations" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/artifactset" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/docker" - "github.com/open-component-model/ocm/pkg/optionutils" ) func (o *Options) OCIContext() oci.Context { diff --git a/pkg/blobaccess/dockerdaemon/options.go b/pkg/blobaccess/dockerdaemon/options.go index f44bb884fa..60703913c1 100644 --- a/pkg/blobaccess/dockerdaemon/options.go +++ b/pkg/blobaccess/dockerdaemon/options.go @@ -1,9 +1,10 @@ package dockerdaemon import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/oci" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/blobaccess/dockermulti/access.go b/pkg/blobaccess/dockermulti/access.go index 59a6f8e798..6b1300c890 100644 --- a/pkg/blobaccess/dockermulti/access.go +++ b/pkg/blobaccess/dockermulti/access.go @@ -6,6 +6,7 @@ import ( . "github.com/mandelsoft/goutils/finalizer" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/optionutils" "github.com/opencontainers/go-digest" "github.com/open-component-model/ocm/pkg/blobaccess" @@ -16,7 +17,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/oci/cpi" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/artifactset" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/docker" - "github.com/open-component-model/ocm/pkg/optionutils" ) func (o *Options) OCIContext() oci.Context { diff --git a/pkg/blobaccess/dockermulti/options.go b/pkg/blobaccess/dockermulti/options.go index 309a6c507b..4b93db782e 100644 --- a/pkg/blobaccess/dockermulti/options.go +++ b/pkg/blobaccess/dockermulti/options.go @@ -1,11 +1,11 @@ package dockermulti import ( + "github.com/mandelsoft/goutils/optionutils" "golang.org/x/exp/slices" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/oci" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/blobaccess/helm/options.go b/pkg/blobaccess/helm/options.go index 39930e06d7..afb45f0c54 100644 --- a/pkg/blobaccess/helm/options.go +++ b/pkg/blobaccess/helm/options.go @@ -1,11 +1,11 @@ package helm import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/oci" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/blobaccess/helm/resource.go b/pkg/blobaccess/helm/resource.go index 16452dd3cb..4c1c40737f 100644 --- a/pkg/blobaccess/helm/resource.go +++ b/pkg/blobaccess/helm/resource.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/blobaccess" @@ -14,7 +15,6 @@ import ( ocihelm "github.com/open-component-model/ocm/pkg/contexts/oci/ociutils/helm" "github.com/open-component-model/ocm/pkg/helm" "github.com/open-component-model/ocm/pkg/helm/loader" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/blobaccess/ociartifact/options.go b/pkg/blobaccess/ociartifact/options.go index ccc0cd9c92..6e3469306e 100644 --- a/pkg/blobaccess/ociartifact/options.go +++ b/pkg/blobaccess/ociartifact/options.go @@ -1,10 +1,11 @@ package ociartifact import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/oci" "github.com/open-component-model/ocm/pkg/contexts/oci/transfer/filters" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/blobaccess/ociartifact/resource.go b/pkg/blobaccess/ociartifact/resource.go index b437c9b96e..1f468d889d 100644 --- a/pkg/blobaccess/ociartifact/resource.go +++ b/pkg/blobaccess/ociartifact/resource.go @@ -3,11 +3,12 @@ package ociartifact import ( "fmt" + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/blobaccess/bpi" "github.com/open-component-model/ocm/pkg/contexts/oci" "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/artifactset" - "github.com/open-component-model/ocm/pkg/optionutils" ) func BlobAccessForOCIArtifact(refname string, opts ...Option) (blobaccess.BlobAccess, string, error) { diff --git a/pkg/blobaccess/wget/access.go b/pkg/blobaccess/wget/access.go index fcd2b22552..c3e1666bb8 100644 --- a/pkg/blobaccess/wget/access.go +++ b/pkg/blobaccess/wget/access.go @@ -9,6 +9,7 @@ import ( "net/http" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/blobaccess/bpi" @@ -16,7 +17,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/wget/identity" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" ocmmime "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/blobaccess/wget/options.go b/pkg/blobaccess/wget/options.go index 8e6769eabe..a14fb5614f 100644 --- a/pkg/blobaccess/wget/options.go +++ b/pkg/blobaccess/wget/options.go @@ -4,12 +4,12 @@ import ( "io" "net/http" + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/logging" "github.com/open-component-model/ocm/pkg/contexts/credentials" "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/wget/identity" ocmlog "github.com/open-component-model/ocm/pkg/logging" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/cobrautils/flagsets/flagsetscheme/types.go b/pkg/cobrautils/flagsets/flagsetscheme/types.go index f69af8478b..2e9c3483d0 100644 --- a/pkg/cobrautils/flagsets/flagsetscheme/types.go +++ b/pkg/cobrautils/flagsets/flagsetscheme/types.go @@ -1,8 +1,9 @@ package flagsetscheme import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/cobrautils/flagsets" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/runtime" "github.com/open-component-model/ocm/pkg/runtime/descriptivetype" ) diff --git a/pkg/cobrautils/flagsets/flagsetscheme/types_options.go b/pkg/cobrautils/flagsets/flagsetscheme/types_options.go index a04a30f35b..1e84507b4a 100644 --- a/pkg/cobrautils/flagsets/flagsetscheme/types_options.go +++ b/pkg/cobrautils/flagsets/flagsetscheme/types_options.go @@ -1,8 +1,9 @@ package flagsetscheme import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/cobrautils/flagsets" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/runtime/descriptivetype" ) diff --git a/pkg/contexts/credentials/repositories/vault/options.go b/pkg/contexts/credentials/repositories/vault/options.go index e78cf0dfac..59d2925835 100644 --- a/pkg/contexts/credentials/repositories/vault/options.go +++ b/pkg/contexts/credentials/repositories/vault/options.go @@ -1,9 +1,9 @@ package vault import ( + "github.com/mandelsoft/goutils/optionutils" "golang.org/x/exp/slices" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/contexts/credentials/repositories/vault/repo_int_test.go b/pkg/contexts/credentials/repositories/vault/repo_int_test.go index 3001d7c65b..13456f8f36 100644 --- a/pkg/contexts/credentials/repositories/vault/repo_int_test.go +++ b/pkg/contexts/credentials/repositories/vault/repo_int_test.go @@ -12,6 +12,8 @@ import ( "github.com/hashicorp/vault-client-go" "github.com/hashicorp/vault-client-go/schema" + "github.com/mandelsoft/goutils/errors" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" @@ -20,7 +22,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/credentials/identity/hostpath" me "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault" "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault/identity" - "github.com/open-component-model/ocm/pkg/errors" "github.com/open-component-model/ocm/pkg/runtime" . "github.com/open-component-model/ocm/pkg/testutils" ) @@ -328,7 +329,7 @@ path "secret/metadata/%s/*" role := Must(vaultClient.Auth.AppRoleReadRoleId(ctx, VAULT_APP_ROLE1)) roleid := role.Data.RoleId // Unfortunately, this function is currently bugged, therefore we fall back to the generic function - //secretid := Must(client.Auth.AppRoleWriteSecretId(ctx, VAULT_APP_ROLE, schema.AppRoleWriteSecretIdRequest{})) + // secretid := Must(client.Auth.AppRoleWriteSecretId(ctx, VAULT_APP_ROLE, schema.AppRoleWriteSecretIdRequest{})) secret := Must(vaultClient.Write(ctx, fmt.Sprintf("/v1/auth/approle/role/%s/secret-id", VAULT_APP_ROLE1), map[string]interface{}{})) secretid := secret.Data["secret_id"].(string) @@ -385,18 +386,18 @@ path "secret/metadata/%s/*" Expect(c).To(YAMLEqual(data)) }) - //D(irect): + // D(irect): // - has general credentials matching parent path of P2 // - has credentials for P1 - //P1: + // P1: // - has specialized credentials for P2 - //P2: + // P2: // - has credentials for C // // - //query C: - //- D: -> nothing - //- P1: query P1 + // query C: + // - D: -> nothing + // - P1: query P1 // - D: -> found // - P1: omit (recursion) // - P2: query P2 @@ -406,7 +407,7 @@ path "secret/metadata/%s/*" // explore, whether an additional attempt with P1 BUT only with credentialless providers / direct creds // would work as a general solution. // -> select D(P2) WRONG (a1) - //- P2: query P2 + // - P2: query P2 // - D: -> found // - P1: query P1 // - D: found @@ -417,12 +418,12 @@ path "secret/metadata/%s/*" // - P2: omit (recursion) // -> select P1(P2) CORRECT (a2) // -> found - //-> select P2(C) + // -> select P2(C) // // The Problem here is, that the case a1 and case b are formally indistinguishable. While a2 and b lead to the // correct result, we would fail in a1. It("recursive authentication with overlapping credentials", func() { - //TODO + // TODO }) }) }) @@ -441,8 +442,8 @@ func StartVaultServer(mode vaultMode, rootToken, address string) (*exec.Cmd, *va } cmd := exec.CommandContext(cmdctx, "../../../../../bin/vault", "server", "-"+string(mode), fmt.Sprintf("-dev-root-token-id=%s", rootToken), fmt.Sprintf("-dev-listen-address=%s", address)) - //cmd.Stdout = os.Stdout - //cmd.Stderr = os.Stderr + // cmd.Stdout = os.Stdout + // cmd.Stderr = os.Stderr vaultClient, err := vault.New( vault.WithAddress(url), @@ -494,7 +495,7 @@ func SetUpVaultAccess(ctx context.Context, credctx credentials.Context, client * role := Must(client.Auth.AppRoleReadRoleId(ctx, VAULT_APP_ROLE)) roleid := role.Data.RoleId // Unfortunately, this function is currently bugged, therefore we fall back to the generic function - //secretid := Must(client.Auth.AppRoleWriteSecretId(ctx, VAULT_APP_ROLE, schema.AppRoleWriteSecretIdRequest{})) + // secretid := Must(client.Auth.AppRoleWriteSecretId(ctx, VAULT_APP_ROLE, schema.AppRoleWriteSecretIdRequest{})) secret := Must(client.Write(ctx, fmt.Sprintf("/v1/auth/approle/role/%s/secret-id", VAULT_APP_ROLE), map[string]interface{}{})) secretid := secret.Data["secret_id"].(string) diff --git a/pkg/contexts/credentials/repositories/vault/type.go b/pkg/contexts/credentials/repositories/vault/type.go index 2e00632427..aa78f2b933 100644 --- a/pkg/contexts/credentials/repositories/vault/type.go +++ b/pkg/contexts/credentials/repositories/vault/type.go @@ -4,12 +4,12 @@ import ( "encoding/json" "fmt" + "github.com/mandelsoft/goutils/optionutils" "golang.org/x/exp/slices" "github.com/open-component-model/ocm/pkg/contexts/credentials/cpi" "github.com/open-component-model/ocm/pkg/contexts/credentials/internal" "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault/identity" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/runtime" ) diff --git a/pkg/contexts/oci/grammar/grammar.go b/pkg/contexts/oci/grammar/grammar.go index 97e04b1d62..fa39baa2df 100644 --- a/pkg/contexts/oci/grammar/grammar.go +++ b/pkg/contexts/oci/grammar/grammar.go @@ -3,7 +3,7 @@ package grammar import ( "strings" - . "github.com/open-component-model/ocm/pkg/regex" + . "github.com/mandelsoft/goutils/regexutils" ) const ( diff --git a/pkg/contexts/oci/grammar/grammar_test.go b/pkg/contexts/oci/grammar/grammar_test.go index a6f6e9e25c..4b6172f1b2 100644 --- a/pkg/contexts/oci/grammar/grammar_test.go +++ b/pkg/contexts/oci/grammar/grammar_test.go @@ -7,7 +7,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - tool "github.com/open-component-model/ocm/pkg/regex" + tool "github.com/mandelsoft/goutils/regexutils" ) func TestConfig(t *testing.T) { diff --git a/pkg/contexts/oci/repositories/ocireg/uniform.go b/pkg/contexts/oci/repositories/ocireg/uniform.go index 49f78e9778..5a85243e39 100644 --- a/pkg/contexts/oci/repositories/ocireg/uniform.go +++ b/pkg/contexts/oci/repositories/ocireg/uniform.go @@ -1,9 +1,10 @@ package ocireg import ( + regex "github.com/mandelsoft/goutils/regexutils" + "github.com/open-component-model/ocm/pkg/contexts/oci/cpi" "github.com/open-component-model/ocm/pkg/contexts/oci/grammar" - "github.com/open-component-model/ocm/pkg/regex" ) func init() { diff --git a/pkg/contexts/ocm/accessmethods/mvn/method.go b/pkg/contexts/ocm/accessmethods/mvn/method.go index 55da45fe0b..d430b774c2 100644 --- a/pkg/contexts/ocm/accessmethods/mvn/method.go +++ b/pkg/contexts/ocm/accessmethods/mvn/method.go @@ -11,6 +11,8 @@ import ( "sort" "strings" + "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/osfs" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/opencontainers/go-digest" @@ -23,11 +25,9 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/mvn/identity" "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" - "github.com/open-component-model/ocm/pkg/errors" "github.com/open-component-model/ocm/pkg/iotools" "github.com/open-component-model/ocm/pkg/logging" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/runtime" "github.com/open-component-model/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/utils/tarutils" diff --git a/pkg/contexts/ocm/accessmethods/wget/method.go b/pkg/contexts/ocm/accessmethods/wget/method.go index 5b1602f86d..168c1baace 100644 --- a/pkg/contexts/ocm/accessmethods/wget/method.go +++ b/pkg/contexts/ocm/accessmethods/wget/method.go @@ -5,13 +5,14 @@ import ( "io" "sync" + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/blobaccess/wget" "github.com/open-component-model/ocm/pkg/contexts/credentials" "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/wget/identity" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/runtime" ) diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go b/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go index 1e27561d32..0a11fcc96f 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go @@ -9,6 +9,7 @@ import ( "net/http" "strings" + "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/mvn/identity" @@ -16,7 +17,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/errors" "github.com/open-component-model/ocm/pkg/iotools" "github.com/open-component-model/ocm/pkg/logging" "github.com/open-component-model/ocm/pkg/mime" diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go b/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go index 7fc5ffb8f9..be1436b455 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go @@ -4,9 +4,10 @@ import ( "encoding/json" "fmt" + "github.com/mandelsoft/goutils/errors" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/errors" "github.com/open-component-model/ocm/pkg/mime" "github.com/open-component-model/ocm/pkg/registrations" ) diff --git a/pkg/contexts/ocm/cpi/repocpi/bridge_c.go b/pkg/contexts/ocm/cpi/repocpi/bridge_c.go index 0a874218b4..322daef9a6 100644 --- a/pkg/contexts/ocm/cpi/repocpi/bridge_c.go +++ b/pkg/contexts/ocm/cpi/repocpi/bridge_c.go @@ -5,12 +5,12 @@ import ( "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm/attrs/compositionmodeattr" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/refmgmt" "github.com/open-component-model/ocm/pkg/refmgmt/resource" ) diff --git a/pkg/contexts/ocm/cpi/repocpi/bridge_cv.go b/pkg/contexts/ocm/cpi/repocpi/bridge_cv.go index d05e18fea1..4de83f7d4c 100644 --- a/pkg/contexts/ocm/cpi/repocpi/bridge_cv.go +++ b/pkg/contexts/ocm/cpi/repocpi/bridge_cv.go @@ -8,6 +8,7 @@ import ( "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/common" @@ -19,7 +20,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/internal" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/refmgmt" "github.com/open-component-model/ocm/pkg/refmgmt/resource" "github.com/open-component-model/ocm/pkg/runtimefinalizer" diff --git a/pkg/contexts/ocm/download/download.go b/pkg/contexts/ocm/download/download.go index 595590a66a..e536bb6460 100644 --- a/pkg/contexts/ocm/download/download.go +++ b/pkg/contexts/ocm/download/download.go @@ -1,11 +1,11 @@ package download import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/contexts/ocm/elements/artifactaccess/githubaccess/options.go b/pkg/contexts/ocm/elements/artifactaccess/githubaccess/options.go index 4b8a5ad480..12ff0a9017 100644 --- a/pkg/contexts/ocm/elements/artifactaccess/githubaccess/options.go +++ b/pkg/contexts/ocm/elements/artifactaccess/githubaccess/options.go @@ -1,7 +1,7 @@ package githubaccess import ( - "github.com/open-component-model/ocm/pkg/optionutils" + "github.com/mandelsoft/goutils/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactaccess/githubaccess/resource.go b/pkg/contexts/ocm/elements/artifactaccess/githubaccess/resource.go index 491d23ed70..4a1f7b282e 100644 --- a/pkg/contexts/ocm/elements/artifactaccess/githubaccess/resource.go +++ b/pkg/contexts/ocm/elements/artifactaccess/githubaccess/resource.go @@ -1,13 +1,14 @@ package githubaccess import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/contexts/ocm" access "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/github" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactaccess/genericaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.DIRECTORY_TREE diff --git a/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/options.go b/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/options.go index 06e1e66e0a..216c44b3f3 100644 --- a/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/options.go +++ b/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/options.go @@ -1,7 +1,7 @@ package github import ( - "github.com/open-component-model/ocm/pkg/optionutils" + "github.com/mandelsoft/goutils/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/resource.go b/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/resource.go index 53ac2d7e7c..b2b9363f81 100644 --- a/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/resource.go +++ b/pkg/contexts/ocm/elements/artifactaccess/ociblobaccess/resource.go @@ -1,6 +1,7 @@ package github import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/opencontainers/go-digest" "github.com/open-component-model/ocm/pkg/contexts/ocm" @@ -10,7 +11,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactaccess/genericaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.BLOB diff --git a/pkg/contexts/ocm/elements/artifactaccess/s3access/options.go b/pkg/contexts/ocm/elements/artifactaccess/s3access/options.go index bb7c98fe42..e52fc719cd 100644 --- a/pkg/contexts/ocm/elements/artifactaccess/s3access/options.go +++ b/pkg/contexts/ocm/elements/artifactaccess/s3access/options.go @@ -1,7 +1,7 @@ package github import ( - "github.com/open-component-model/ocm/pkg/optionutils" + "github.com/mandelsoft/goutils/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactaccess/s3access/resource.go b/pkg/contexts/ocm/elements/artifactaccess/s3access/resource.go index fcd3dc33e6..45f551bc55 100644 --- a/pkg/contexts/ocm/elements/artifactaccess/s3access/resource.go +++ b/pkg/contexts/ocm/elements/artifactaccess/s3access/resource.go @@ -1,6 +1,8 @@ package github import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/contexts/ocm" access "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/s3" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" @@ -8,7 +10,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactaccess/genericaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.BLOB diff --git a/pkg/contexts/ocm/elements/artifactblob/api/options.go b/pkg/contexts/ocm/elements/artifactblob/api/options.go index 954e07f557..245023d1c6 100644 --- a/pkg/contexts/ocm/elements/artifactblob/api/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/api/options.go @@ -1,8 +1,9 @@ package api import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/optionutils" ) type ( diff --git a/pkg/contexts/ocm/elements/artifactblob/datablob/options.go b/pkg/contexts/ocm/elements/artifactblob/datablob/options.go index 176cf5bc0c..d22d5d607b 100644 --- a/pkg/contexts/ocm/elements/artifactblob/datablob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/datablob/options.go @@ -1,9 +1,10 @@ package datablob import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/datablob/resource.go b/pkg/contexts/ocm/elements/artifactblob/datablob/resource.go index 5fa761bb64..4b0e64b2f3 100644 --- a/pkg/contexts/ocm/elements/artifactblob/datablob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/datablob/resource.go @@ -2,13 +2,13 @@ package datablob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" ) func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, blob []byte, opts ...Option) cpi.ArtifactAccess[M] { diff --git a/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/options.go b/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/options.go index 47e7479926..fdffe16d10 100644 --- a/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/options.go @@ -1,12 +1,12 @@ package dirtreeblob import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" base "github.com/open-component-model/ocm/pkg/blobaccess/dirtree" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/resource.go index fd4aa9e138..62304ff052 100644 --- a/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/dirtreeblob/resource.go @@ -2,13 +2,13 @@ package dirtreeblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess/dirtree" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.DIRECTORY_TREE diff --git a/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/options.go b/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/options.go index 98701fdabe..60c4f35d50 100644 --- a/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/options.go @@ -1,11 +1,12 @@ package dockerdaemonblob import ( + "github.com/mandelsoft/goutils/optionutils" + base "github.com/open-component-model/ocm/pkg/blobaccess/dockerdaemon" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/resource.go index fda40a0d1a..f18ae7c4b2 100644 --- a/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/dockerdaemonblob/resource.go @@ -2,6 +2,7 @@ package dockerdaemonblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess/dockerdaemon" "github.com/open-component-model/ocm/pkg/contexts/ocm" @@ -9,7 +10,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.OCI_IMAGE diff --git a/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/options.go b/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/options.go index a6412c14f1..451904c13f 100644 --- a/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/options.go @@ -1,11 +1,12 @@ package dockermultiblob import ( + "github.com/mandelsoft/goutils/optionutils" + base "github.com/open-component-model/ocm/pkg/blobaccess/dockermulti" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/resource.go index c6b5b6d4c9..b8c2b5726b 100644 --- a/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/dockermultiblob/resource.go @@ -2,13 +2,13 @@ package dockermultiblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess/dockermulti" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.OCI_IMAGE diff --git a/pkg/contexts/ocm/elements/artifactblob/externalblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/externalblob/resource.go index cb6f5813b2..47d8584402 100644 --- a/pkg/contexts/ocm/elements/artifactblob/externalblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/externalblob/resource.go @@ -3,11 +3,11 @@ package externalblob import ( "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/optionutils" ) func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, access ocm.AccessSpec, opts ...Option) (cpi.ArtifactAccess[M], error) { diff --git a/pkg/contexts/ocm/elements/artifactblob/fileblob/options.go b/pkg/contexts/ocm/elements/artifactblob/fileblob/options.go index 5a1cdc6d37..99b1faa92d 100644 --- a/pkg/contexts/ocm/elements/artifactblob/fileblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/fileblob/options.go @@ -1,11 +1,11 @@ package fileblob import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/fileblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/fileblob/resource.go index 6cacce1098..7c779e1578 100644 --- a/pkg/contexts/ocm/elements/artifactblob/fileblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/fileblob/resource.go @@ -2,13 +2,13 @@ package fileblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = "blob" diff --git a/pkg/contexts/ocm/elements/artifactblob/genericblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/genericblob/resource.go index bbd01ff01c..8c6f8fbcde 100644 --- a/pkg/contexts/ocm/elements/artifactblob/genericblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/genericblob/resource.go @@ -2,11 +2,11 @@ package genericblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/optionutils" ) func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx cpi.Context, meta P, blob blobaccess.BlobAccessProvider, opts ...Option) cpi.ArtifactAccess[M] { diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/options.go b/pkg/contexts/ocm/elements/artifactblob/helmblob/options.go index 69450c00cb..725ffb40ca 100644 --- a/pkg/contexts/ocm/elements/artifactblob/helmblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/options.go @@ -1,6 +1,7 @@ package helmblob import ( + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/vfs/pkg/vfs" base "github.com/open-component-model/ocm/pkg/blobaccess/helm" @@ -8,7 +9,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/oci" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/helmblob/resource.go index 21c1e48537..22b0be16d5 100644 --- a/pkg/contexts/ocm/elements/artifactblob/helmblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/resource.go @@ -2,13 +2,13 @@ package helmblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess/helm" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.HELM_CHART diff --git a/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/options.go b/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/options.go index 2a9a36c65a..2f03a9424a 100644 --- a/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/options.go @@ -1,12 +1,13 @@ package ociartifactblob import ( + "github.com/mandelsoft/goutils/optionutils" + base "github.com/open-component-model/ocm/pkg/blobaccess/ociartifact" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/oci" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/resource.go index 105ad0a4b7..3cb30ee21e 100644 --- a/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/ociartifactblob/resource.go @@ -2,6 +2,7 @@ package ociartifactblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" blob "github.com/open-component-model/ocm/pkg/blobaccess/ociartifact" "github.com/open-component-model/ocm/pkg/contexts/oci" @@ -9,7 +10,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.OCI_IMAGE diff --git a/pkg/contexts/ocm/elements/artifactblob/textblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/textblob/resource.go index 8683676dce..a38e26f074 100644 --- a/pkg/contexts/ocm/elements/artifactblob/textblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/textblob/resource.go @@ -1,12 +1,13 @@ package textblob import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/datablob" "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/optionutils" ) func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, blob string, opts ...Option) cpi.ArtifactAccess[M] { diff --git a/pkg/contexts/ocm/elements/artifactblob/wgetblob/options.go b/pkg/contexts/ocm/elements/artifactblob/wgetblob/options.go index ce8427ffb6..ea29ff9b1d 100644 --- a/pkg/contexts/ocm/elements/artifactblob/wgetblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/wgetblob/options.go @@ -4,6 +4,7 @@ import ( "io" "net/http" + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/logging" base "github.com/open-component-model/ocm/pkg/blobaccess/wget" @@ -11,7 +12,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/wget" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Option = optionutils.Option[*Options] diff --git a/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go index 976b4648aa..3045c59bef 100644 --- a/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go @@ -2,13 +2,13 @@ package wgetblob import ( "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/blobaccess/wget" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/optionutils" ) const TYPE = resourcetypes.BLOB diff --git a/pkg/contexts/ocm/grammar/grammar.go b/pkg/contexts/ocm/grammar/grammar.go index d92d177d14..ca5e8ddb87 100644 --- a/pkg/contexts/ocm/grammar/grammar.go +++ b/pkg/contexts/ocm/grammar/grammar.go @@ -1,7 +1,7 @@ package grammar import ( - . "github.com/open-component-model/ocm/pkg/regex" + . "github.com/mandelsoft/goutils/regexutils" "github.com/open-component-model/ocm/pkg/contexts/oci/grammar" ) diff --git a/pkg/contexts/ocm/grammar/grammar_test.go b/pkg/contexts/ocm/grammar/grammar_test.go index 22e1cf4ef0..5649bd1511 100644 --- a/pkg/contexts/ocm/grammar/grammar_test.go +++ b/pkg/contexts/ocm/grammar/grammar_test.go @@ -7,7 +7,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - gr "github.com/open-component-model/ocm/pkg/regex" + gr "github.com/mandelsoft/goutils/regexutils" ) func TestConfig(t *testing.T) { diff --git a/pkg/contexts/ocm/internal/modopts.go b/pkg/contexts/ocm/internal/modopts.go index 33ee9c0b98..268170e32a 100644 --- a/pkg/contexts/ocm/internal/modopts.go +++ b/pkg/contexts/ocm/internal/modopts.go @@ -1,7 +1,8 @@ package internal import ( - "github.com/open-component-model/ocm/pkg/optionutils" + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/contexts/ocm/transfer/transferhandler/standard/options.go b/pkg/contexts/ocm/transfer/transferhandler/standard/options.go index 080c59743a..c22a972dd3 100644 --- a/pkg/contexts/ocm/transfer/transferhandler/standard/options.go +++ b/pkg/contexts/ocm/transfer/transferhandler/standard/options.go @@ -3,13 +3,13 @@ package standard import ( "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/maputils" + "github.com/mandelsoft/goutils/optionutils" "github.com/mandelsoft/goutils/set" "github.com/mandelsoft/goutils/sliceutils" "golang.org/x/exp/slices" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer/transferhandler" - "github.com/open-component-model/ocm/pkg/optionutils" "github.com/open-component-model/ocm/pkg/runtime" ) diff --git a/pkg/contexts/ocm/utils/check/check.go b/pkg/contexts/ocm/utils/check/check.go index 989ae2a84a..7eef618a25 100644 --- a/pkg/contexts/ocm/utils/check/check.go +++ b/pkg/contexts/ocm/utils/check/check.go @@ -4,12 +4,12 @@ import ( "encoding/json" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/optionutils" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" - "github.com/open-component-model/ocm/pkg/optionutils" ) type Result struct { diff --git a/pkg/contexts/ocm/utils/check/options.go b/pkg/contexts/ocm/utils/check/options.go index d263e693e9..055ae93c43 100644 --- a/pkg/contexts/ocm/utils/check/options.go +++ b/pkg/contexts/ocm/utils/check/options.go @@ -1,7 +1,8 @@ package check import ( - "github.com/open-component-model/ocm/pkg/optionutils" + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/pkg/iotools/hashReaderWriter.go b/pkg/iotools/hashReaderWriter.go index 675cdb68c0..b74863f7e7 100644 --- a/pkg/iotools/hashReaderWriter.go +++ b/pkg/iotools/hashReaderWriter.go @@ -7,7 +7,7 @@ import ( "io" "strings" - "github.com/open-component-model/ocm/pkg/errors" + "github.com/mandelsoft/goutils/errors" ) type HashReader struct { diff --git a/pkg/optionutils/doc.go b/pkg/optionutils/doc.go new file mode 100644 index 0000000000..25ffab3e77 --- /dev/null +++ b/pkg/optionutils/doc.go @@ -0,0 +1,2 @@ +// Deprecated: use github.com/mandelsoft/goutils/optionutils +package optionutils diff --git a/pkg/runtime/descriptivetype/options.go b/pkg/runtime/descriptivetype/options.go index 7b067bd62a..42a8c637b5 100644 --- a/pkg/runtime/descriptivetype/options.go +++ b/pkg/runtime/descriptivetype/options.go @@ -1,7 +1,8 @@ package descriptivetype import ( - "github.com/open-component-model/ocm/pkg/optionutils" + "github.com/mandelsoft/goutils/optionutils" + "github.com/open-component-model/ocm/pkg/runtime" ) diff --git a/pkg/utils/tarutils/pack_test.go b/pkg/utils/tarutils/pack_test.go index 2487913a61..50b28df7d8 100644 --- a/pkg/utils/tarutils/pack_test.go +++ b/pkg/utils/tarutils/pack_test.go @@ -5,12 +5,13 @@ import ( "os" "runtime" - "github.com/mandelsoft/vfs/pkg/osfs" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - - "github.com/open-component-model/ocm/pkg/errors" . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/open-component-model/ocm/pkg/utils/tarutils" ) From 5d36b1eb6729e78943ca8704cdb5b43fdac19084 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Mon, 27 May 2024 10:18:15 +0200 Subject: [PATCH 02/12] early CD validation for AddVersion (#779) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description When adding a CV to a component, the CD validation is done deep in the call chain when updating the CV on the persistence layer. This typically happens during closing a CV which provides strange error messages. To provider a better error message the validation is now done directly in the add call. ## What type of PR is this? (check all applicable) - [x] 🍕 Feature - [ ] 🎇 Restructuring - [ ] 🐛 Bug Fix - [ ] 📝 Documentation Update - [ ] 🎨 Style - [ ] 🧑‍💻 Code Refactor - [ ] 🔥 Performance Improvements - [x] ✅ Test - [ ] 🤖 Build - [ ] 🔁 CI - [ ] 📦 Chore (Release) - [ ] ⏩ Revert ## Related Tickets & Documents - Related Issue # (issue) - Closes # (issue) - Fixes # (issue) > Remove if not applicable ## Screenshots ## Added tests? - [ ] 👍 yes - [ ] 🙅 no, because they aren't needed - [ ] 🙋 no, because I need help - [ ] Separate ticket for tests # (issue/pr) Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration ## Added to documentation? - [ ] 📜 README.md - [ ] 🙅 no documentation needed ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- pkg/contexts/ocm/cpi/repocpi/bridge_c.go | 5 +++++ .../ocm/repositories/composition/repository_test.go | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/pkg/contexts/ocm/cpi/repocpi/bridge_c.go b/pkg/contexts/ocm/cpi/repocpi/bridge_c.go index 322daef9a6..c4734c439c 100644 --- a/pkg/contexts/ocm/cpi/repocpi/bridge_c.go +++ b/pkg/contexts/ocm/cpi/repocpi/bridge_c.go @@ -134,6 +134,11 @@ func (c *componentAccessBridge) AddVersion(cv cpi.ComponentVersionAccess, opts * return err } + err = compdesc.Validate(cv.GetDescriptor()) + if err != nil { + return err + } + forcestore := c.IsOwned(cv) if !forcestore { eff, err := c.NewVersion(cv.GetVersion(), optionutils.AsValue(opts.Overwrite)) diff --git a/pkg/contexts/ocm/repositories/composition/repository_test.go b/pkg/contexts/ocm/repositories/composition/repository_test.go index 054b9c8125..9746088d6b 100644 --- a/pkg/contexts/ocm/repositories/composition/repository_test.go +++ b/pkg/contexts/ocm/repositories/composition/repository_test.go @@ -130,4 +130,10 @@ var _ = Describe("repository", func() { cv.GetDescriptor().Provider.Name = "acme.org" ExpectError(cl.Close()).To(MatchError(accessobj.ErrReadOnly)) }) + + It("provides early error", func() { + repo := me.NewRepository(ctx) + cv := me.NewComponentVersion(ctx, "a", "1.0") + ExpectError(repo.AddComponentVersion(cv)).To(MatchError("component.name: Does not match pattern '^[a-z][-a-z0-9]*([.][a-z][-a-z0-9]*)*[.][a-z]{2,}(/[a-z][-a-z0-9_]*([.][a-z][-a-z0-9_]*)*)+$'")) + }) }) From 0c499cf271c21bca7fe2c7a1c1982d2038e07edb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 08:36:19 +0000 Subject: [PATCH 03/12] Bump anchore/sbom-action from 0.15.11 to 0.16.0 in the ci group (#777) Bumps the ci group with 1 update: [anchore/sbom-action](https://github.com/anchore/sbom-action). Updates `anchore/sbom-action` from 0.15.11 to 0.16.0
Release notes

Sourced from anchore/sbom-action's releases.

v0.16

Changes in v0.16.0

  • Update Syft to v1.4.1 (#465)
  • Update GitHub artifact client (#463) [kzantow]

NOTE: if you are using this action within a matrix build and see failures attempting to upload artifacts with duplicate names, you will need to set the artifact-name to be unique based on the matrix properties (an example here). This is due to a change to use a newer GitHub API which no longer allows artifacts with duplicate names.

Commits
  • e8d2a69 chore(deps): update Syft to v1.4.1 (#465)
  • 610bea4 chore: update GitHub artifact client (#463)
  • 0445e23 chore(deps): bump actions/checkout from 4.1.4 to 4.1.5 (#464)
  • a66e2f3 chore(deps): bump actions/checkout from 4.1.2 to 4.1.4 (#461)
  • 1abd786 chore(deps): bump peter-evans/create-pull-request from 6.0.2 to 6.0.5 (#462)
  • See full diff in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=anchore/sbom-action&package-manager=github_actions&previous-version=0.15.11&new-version=0.16.0)](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> Co-authored-by: Hilmar Falkenberg --- .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 d44be89180..ad2af17518 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -142,7 +142,7 @@ jobs: go-version-file: '${{ github.workspace }}/go.mod' - name: Setup Syft - uses: anchore/sbom-action/download-syft@7ccf588e3cf3cc2611714c2eeae48550fbc17552 # v0.15.11 + uses: anchore/sbom-action/download-syft@e8d2a6937ecead383dfe75190d104edd1f9c5751 # v0.16.0 - name: Setup Cosign uses: sigstore/cosign-installer@v3.5.0 From b835e96c0b62f47b9b3f42a99f26aa32a05f4866 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 May 2024 08:45:49 +0000 Subject: [PATCH 04/12] Bump the go group with 11 updates (#778) 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/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2) | `1.27.15` | `1.27.16` | | [github.com/aws/aws-sdk-go-v2/credentials](https://github.com/aws/aws-sdk-go-v2) | `1.17.15` | `1.17.16` | | [github.com/aws/aws-sdk-go-v2/feature/s3/manager](https://github.com/aws/aws-sdk-go-v2) | `1.16.20` | `1.16.21` | | [github.com/aws/aws-sdk-go-v2/service/ecr](https://github.com/aws/aws-sdk-go-v2) | `1.28.2` | `1.28.3` | | [github.com/aws/aws-sdk-go-v2/service/s3](https://github.com/aws/aws-sdk-go-v2) | `1.54.2` | `1.54.3` | | [github.com/containers/image/v5](https://github.com/containers/image) | `5.30.1` | `5.31.0` | | [github.com/go-logr/logr](https://github.com/go-logr/logr) | `1.4.1` | `1.4.2` | | [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) | `2.17.3` | `2.19.0` | | [golang.org/x/exp](https://github.com/golang/exp) | `0.0.0-20240222234643-814bf88cf225` | `0.0.0-20240506185415-9bf2ced13842` | | [helm.sh/helm/v3](https://github.com/helm/helm) | `3.15.0` | `3.15.1` | | [sigs.k8s.io/controller-runtime](https://github.com/kubernetes-sigs/controller-runtime) | `0.18.2` | `0.18.3` | Updates `github.com/aws/aws-sdk-go-v2/config` from 1.27.15 to 1.27.16
Commits

Updates `github.com/aws/aws-sdk-go-v2/credentials` from 1.17.15 to 1.17.16
Commits

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

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

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

Updates `github.com/containers/image/v5` from 5.30.1 to 5.31.0
Release notes

Sourced from github.com/containers/image/v5's releases.

v5.31.0

What's Changed

... (truncated)

Commits
  • b5a7587 Bump c/image to v5.31.0
  • 21ac79b Merge pull request #2428 from mtrmac/als-toc-fixes
  • 45f4f23 Don't completely ignore already-computed image size if we see an ALS layer
  • 27516f3 Don't modify a storage.Layer returned by c/storage
  • c2327e4 Don't unnecessarily trust the ALS FUSE server about the TOC digest
  • db02dee Merge pull request #2426 from containers/renovate/github.com-containers-stora...
  • 6db27e1 fix(deps): update module github.com/containers/storage to v1.54.0
  • cf26b3c Merge pull request #2416 from ktock/store-tocdigest-id
  • 52101a0 getSize: allow unknown uncompressed size
  • ebbd025 Enable to pass TOCDigest to Additional Layer Store
  • Additional commits viewable in compare view

Updates `github.com/go-logr/logr` from 1.4.1 to 1.4.2
Release notes

Sourced from github.com/go-logr/logr's releases.

v1.4.2

What's Changed

Dependencies:

Full Changelog: https://github.com/go-logr/logr/compare/v1.4.1...v1.4.2

Commits
  • 1205f42 Merge pull request #295 from go-logr/dependabot/github_actions/actions/checko...
  • ccedcbd Merge pull request #294 from go-logr/dependabot/github_actions/github/codeql-...
  • bead577 build(deps): bump actions/checkout from 4.1.5 to 4.1.6
  • a492d95 build(deps): bump github/codeql-action from 3.25.4 to 3.25.5
  • 19ad07c build(deps): bump ossf/scorecard-action from 2.3.1 to 2.3.3
  • 1c97a21 build(deps): bump actions/checkout from 4.1.4 to 4.1.5
  • f70c5b5 build(deps): bump github/codeql-action from 3.25.3 to 3.25.4
  • 4ade8d3 build(deps): bump golangci/golangci-lint-action from 5.3.0 to 6.0.1
  • 88d98bd Merge pull request #289 from go-logr/dependabot/github_actions/golangci/golan...
  • 432cd86 Merge pull request #288 from go-logr/dependabot/github_actions/actions/setup-...
  • Additional commits viewable in compare view

Updates `github.com/onsi/ginkgo/v2` from 2.17.3 to 2.19.0
Release notes

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

v2.19.0

2.19.0

Features

Label Sets allow for more expressive and flexible label filtering.

v2.18.0

2.18.0

Features

  • Add --slience-skips and --force-newlines [f010b65]
  • fail when no tests were run and --fail-on-empty was set [d80eebe]

Fixes

  • Fix table entry context edge case [42013d6]

Maintenance

  • Bump golang.org/x/tools from 0.20.0 to 0.21.0 (#1406) [fcf1fd7]
  • Bump github.com/onsi/gomega from 1.33.0 to 1.33.1 (#1399) [8bb14fd]
  • Bump golang.org/x/net from 0.24.0 to 0.25.0 (#1407) [04bfad7]
Changelog

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

2.19.0

Features

Label Sets allow for more expressive and flexible label filtering.

2.18.0

Features

  • Add --slience-skips and --force-newlines [f010b65]
  • fail when no tests were run and --fail-on-empty was set [d80eebe]

Fixes

  • Fix table entry context edge case [42013d6]

Maintenance

  • Bump golang.org/x/tools from 0.20.0 to 0.21.0 (#1406) [fcf1fd7]
  • Bump github.com/onsi/gomega from 1.33.0 to 1.33.1 (#1399) [8bb14fd]
  • Bump golang.org/x/net from 0.24.0 to 0.25.0 (#1407) [04bfad7]
Commits
  • 28fb5d6 v2.19.0
  • e31f03a fix another typo
  • 966a28c Fix typos in label sets docs
  • cd231fd Label sets allow for more expressive label filtering
  • eb27ca8 v2.18.0
  • f010b65 Add --slience-skips and --force-newlines
  • 42013d6 Fix table entry context edge case
  • 9e234ea always rebuild and run ginkgo in makefile
  • 5ce8355 add --fail-on-empty to recommended CI flags in docs
  • 3ffbf8b add makefile
  • Additional commits viewable in compare view

Updates `golang.org/x/exp` from 0.0.0-20240222234643-814bf88cf225 to 0.0.0-20240506185415-9bf2ced13842
Commits

Updates `helm.sh/helm/v3` from 3.15.0 to 3.15.1
Release notes

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

Helm v3.15.1 is a patch release. The Helm application source is the same as 3.15.0. The 3.15.0 builds stated the wrong version when running helm version. Instead of the release number it had the release candidate version which pointed to the same revision of the source.

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.15.1. 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.15.2 is the next patch release and will be on June 12, 2024.
  • 3.16.0 is the next feature release and will be on September 11, 2024.

Changelog

  • Fixing build issue where wrong version is used e211f2aa62992bd72586b395de50979e31231829 (Matt Farina)
Commits

Updates `sigs.k8s.io/controller-runtime` from 0.18.2 to 0.18.3
Release notes

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

v0.18.3

What's Changed

Full Changelog: https://github.com/kubernetes-sigs/controller-runtime/compare/v0.18.2...v0.18.3

Commits
  • be2f383 Merge pull request #2840 from sbueringer/pr-bump-k8s
  • 4720d17 Bump k8s.io/* to v0.30.1
  • aa9ed14 Merge pull request #2837 from sbueringer/pr-setup-envtest-ct-rel-0.18
  • 35d7bbd default --use-deprecated-gcs to true
  • ce4e4f5 some more deprecations
  • 56dcc14 setup-envtest: allow downloading envtest binaries from controller-tools
  • 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 | 40 ++++++++++++------------- go.sum | 95 ++++++++++++++++++++++++++++------------------------------ 2 files changed, 66 insertions(+), 69 deletions(-) diff --git a/go.mod b/go.mod index b4a7f4688a..df7787db42 100644 --- a/go.mod +++ b/go.mod @@ -9,14 +9,14 @@ require ( github.com/InfiniteLoopSpace/go_S-MIME v0.0.0-20181221134359-3f58f9a4b2b6 github.com/Masterminds/semver/v3 v3.2.1 github.com/aws/aws-sdk-go-v2 v1.27.0 - github.com/aws/aws-sdk-go-v2/config v1.27.15 - github.com/aws/aws-sdk-go-v2/credentials v1.17.15 - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.20 - github.com/aws/aws-sdk-go-v2/service/ecr v1.28.2 - github.com/aws/aws-sdk-go-v2/service/s3 v1.54.2 + github.com/aws/aws-sdk-go-v2/config v1.27.16 + github.com/aws/aws-sdk-go-v2/credentials v1.17.16 + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.21 + github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3 + github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3 github.com/containerd/containerd v1.7.17 github.com/containerd/log v0.1.0 - github.com/containers/image/v5 v5.30.1 + github.com/containers/image/v5 v5.31.0 github.com/cyberphone/json-canonicalization v0.0.0-20231217050601-ba74d44ecf5f github.com/distribution/reference v0.6.0 github.com/docker/cli v26.1.3+incompatible @@ -27,7 +27,7 @@ require ( github.com/fluxcd/pkg/ssa v0.39.1 github.com/gertd/go-pluralize v0.2.1 github.com/ghodss/yaml v1.0.0 - github.com/go-logr/logr v1.4.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 github.com/go-test/deep v1.1.0 @@ -47,7 +47,7 @@ require ( github.com/mitchellh/copystructure v1.2.0 github.com/mittwald/go-helm-client v0.12.9 github.com/modern-go/reflect2 v1.0.2 - github.com/onsi/ginkgo/v2 v2.17.3 + github.com/onsi/ginkgo/v2 v2.19.0 github.com/onsi/gomega v1.33.1 github.com/opencontainers/go-digest v1.0.0 github.com/opencontainers/image-spec v1.1.0 @@ -63,20 +63,20 @@ require ( github.com/tonglil/buflogr v1.1.1 github.com/ulikunitz/xz v0.5.12 github.com/xeipuuv/gojsonschema v1.2.0 - golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 golang.org/x/net v0.25.0 golang.org/x/oauth2 v0.20.0 golang.org/x/text v0.15.0 gopkg.in/op/go-logging.v1 v1.0.0-20160211212156-b2cb9fa56473 gopkg.in/yaml.v3 v3.0.1 - helm.sh/helm/v3 v3.15.0 + helm.sh/helm/v3 v3.15.1 k8s.io/api v0.30.1 k8s.io/apiextensions-apiserver v0.30.1 k8s.io/apimachinery v0.30.1 k8s.io/cli-runtime v0.30.1 k8s.io/client-go v0.30.1 - sigs.k8s.io/controller-runtime v0.18.2 + sigs.k8s.io/controller-runtime v0.18.3 sigs.k8s.io/yaml v1.4.0 ) @@ -101,7 +101,7 @@ require ( github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Masterminds/squirrel v1.5.4 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect - github.com/Microsoft/hcsshim v0.12.0-rc.3 // indirect + github.com/Microsoft/hcsshim v0.12.3 // indirect github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c // indirect github.com/ThalesIgnite/crypto11 v1.2.5 // indirect github.com/a8m/envsubst v1.4.2 // indirect @@ -129,9 +129,9 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.3.9 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.9 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.8 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.28.9 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 // indirect github.com/aws/smithy-go v1.20.2 // indirect github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20231024185945-8841054dbdb8 // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -150,9 +150,9 @@ require ( github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 // indirect github.com/containers/ocicrypt v1.1.10 // indirect - github.com/containers/storage v1.53.0 // indirect + github.com/containers/storage v1.54.0 // indirect github.com/coreos/go-oidc/v3 v3.10.0 // indirect - github.com/cyphar/filepath-securejoin v0.2.4 // indirect + github.com/cyphar/filepath-securejoin v0.2.5 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/digitorus/pkcs7 v0.0.0-20230818184609-3a137a874352 // indirect github.com/digitorus/timestamp v0.0.0-20231217203849-220c5c2851b7 // indirect @@ -218,7 +218,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.5 // indirect + github.com/hashicorp/go-retryablehttp v0.7.6 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/hcl v1.0.1-vault-5 // indirect @@ -272,7 +272,7 @@ require ( github.com/prometheus/client_model v0.6.0 // indirect github.com/prometheus/common v0.51.1 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/rivo/uniseg v0.4.4 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/rubenv/sql-migrate v1.6.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect @@ -330,7 +330,7 @@ require ( golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/tools v0.21.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/api v0.172.0 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240311173647-c811ad7063a7 // indirect diff --git a/go.sum b/go.sum index e06f85114e..8708b4b5d7 100644 --- a/go.sum +++ b/go.sum @@ -79,8 +79,8 @@ github.com/Masterminds/squirrel v1.5.4 h1:uUcX/aBc8O7Fg9kaISIUsHXdKuqehiXAMQTYX8 github.com/Masterminds/squirrel v1.5.4/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10= 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.0-rc.3 h1:5GNGrobGs/sN/0nFO21W9k4lFn+iXXZAE8fCZbmdRak= -github.com/Microsoft/hcsshim v0.12.0-rc.3/go.mod h1:WuNfcaYNaw+KpCEsZCIM6HCEmu0c5HfXpi+dDSmveP0= +github.com/Microsoft/hcsshim v0.12.3 h1:LS9NXqXhMoqNCplK1ApmVSfB4UnVLRDWRapB6EIlxE0= +github.com/Microsoft/hcsshim v0.12.3/go.mod h1:Iyl1WVpZzr+UkzjekHZbV8o5Z9ZkxNGx6CtY2Qg/JVQ= 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 v0.0.0-20230923063757-afb1ddc0824c h1:kMFnB0vCcX7IL/m9Y5LO+KQYv+t1CQOiFe6+SV2J7bE= @@ -159,14 +159,14 @@ github.com/aws/aws-sdk-go-v2 v1.27.0 h1:7bZWKoXhzI+mMR/HjdMx8ZCC5+6fY0lS5tr0bbgi github.com/aws/aws-sdk-go-v2 v1.27.0/go.mod h1:ffIFB97e2yNsv4aTSGkqtHnppsIJzw7G7BReUZ3jCXM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2 h1:x6xsQXGSmW6frevwDA+vi/wqhp1ct18mVXYN08/93to= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.2/go.mod h1:lPprDr1e6cJdyYeGXnRaJoP4Md+cDBvi2eOj00BlGmg= -github.com/aws/aws-sdk-go-v2/config v1.27.15 h1:uNnGLZ+DutuNEkuPh6fwqK7LpEiPmzb7MIMA1mNWEUc= -github.com/aws/aws-sdk-go-v2/config v1.27.15/go.mod h1:7j7Kxx9/7kTmL7z4LlhwQe63MYEE5vkVV6nWg4ZAI8M= -github.com/aws/aws-sdk-go-v2/credentials v1.17.15 h1:YDexlvDRCA8ems2T5IP1xkMtOZ1uLJOCJdTr0igs5zo= -github.com/aws/aws-sdk-go-v2/credentials v1.17.15/go.mod h1:vxHggqW6hFNaeNC0WyXS3VdyjcV0a4KMUY4dKJ96buU= +github.com/aws/aws-sdk-go-v2/config v1.27.16 h1:knpCuH7laFVGYTNd99Ns5t+8PuRjDn4HnnZK48csipM= +github.com/aws/aws-sdk-go-v2/config v1.27.16/go.mod h1:vutqgRhDUktwSge3hrC3nkuirzkJ4E/mLj5GvI0BQas= +github.com/aws/aws-sdk-go-v2/credentials v1.17.16 h1:7d2QxY83uYl0l58ceyiSpxg9bSbStqBC6BeEeHEchwo= +github.com/aws/aws-sdk-go-v2/credentials v1.17.16/go.mod h1:Ae6li/6Yc6eMzysRL2BXlPYvnrLLBg3D11/AmOjw50k= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3 h1:dQLK4TjtnlRGb0czOht2CevZ5l6RSyRWAnKeGd7VAFE= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.3/go.mod h1:TL79f2P6+8Q7dTsILpiVST+AL9lkF6PPGI167Ny0Cjw= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.20 h1:NCM9wYaJCmlIWZSO/JwUEveKf0NCvsSgo9V9BwOAolo= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.20/go.mod h1:dmxIx3qriuepxqZgFeFMitFuftWPB94+MZv/6Btpth4= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.21 h1:1v8Ii0MRVGYB/sdhkbxrtolCA7Tp+lGh+5OJTs5vmZ8= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.21/go.mod h1:cxdd1rc8yxCjKz28hi30XN1jDXr2DxZvD44vLxTz/bg= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43/go.mod h1:auo+PiyLl0n1l8A0e8RIeR8tOzYPfZZH/JNlrJ8igTQ= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7 h1:lf/8VTF2cM+N4SLzaYJERKEWAXq8MOMpZfU6wEPWsPk= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.7/go.mod h1:4SjkU7QiqK2M9oozyMzfZ/23LmUY+h3oFqhdeP5OMiI= @@ -177,8 +177,8 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7 github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.7 h1:/FUtT3xsoHO3cfh+I/kCbcMCN98QZRsiFet/V8QkWSs= github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.7/go.mod h1:MaCAgWpGooQoCWZnMur97rGn5dp350w2+CeiV5406wE= -github.com/aws/aws-sdk-go-v2/service/ecr v1.28.2 h1:xUpMnRZonKfrHaNLC77IMpWZSUMRRXIi6IU5EhAPsrM= -github.com/aws/aws-sdk-go-v2/service/ecr v1.28.2/go.mod h1:X52zjAVRaXklEU1TE/wO8kyyJSr9cJx9ZsqliWbyRys= +github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3 h1:NsP8PA4Kw1sA6UKl3ZFRIcA9dWomePbmoRIvfOl+HKs= +github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3/go.mod h1:X52zjAVRaXklEU1TE/wO8kyyJSr9cJx9ZsqliWbyRys= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 h1:PpbXaecV3sLAS6rjQiaKw4/jyq3Z8gNzmoJupHAoBp0= github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2/go.mod h1:fUHpGXr4DrXkEDpGAjClPsviWf+Bszeb0daKE0blxv8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1xUsUr3I8cHps0G+XM3WWU16lP6yG8qu1GAZAs= @@ -191,14 +191,14 @@ github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.7 h1:uO5XR6QGBcmPyo github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.17.7/go.mod h1:feeeAYfAcwTReM6vbwjEyDmiGho+YgBhaFULuXDW8kc= github.com/aws/aws-sdk-go-v2/service/kms v1.30.0 h1:yS0JkEdV6h9JOo8sy2JSpjX+i7vsKifU8SIeHrqiDhU= github.com/aws/aws-sdk-go-v2/service/kms v1.30.0/go.mod h1:+I8VUUSVD4p5ISQtzpgSva4I8cJ4SQ4b1dcBcof7O+g= -github.com/aws/aws-sdk-go-v2/service/s3 v1.54.2 h1:gYSJhNiOF6J9xaYxu2NFNstoiNELwt0T9w29FxSfN+Y= -github.com/aws/aws-sdk-go-v2/service/s3 v1.54.2/go.mod h1:739CllldowZiPPsDFcJHNF4FXrVxaSGVnZ9Ez9Iz9hc= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.8 h1:Kv1hwNG6jHC/sxMTe5saMjH6t6ZLkgfvVxyEjfWL1ks= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.8/go.mod h1:c1qtZUWtygI6ZdvKppzCSXsDOq5I4luJPZ0Ud3juFCA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.2 h1:nWBZ1xHCF+A7vv9sDzJOq4NWIdzFYm0kH7Pr4OjHYsQ= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.2/go.mod h1:9lmoVDVLz/yUZwLaQ676TK02fhCu4+PgRSmMaKR1ozk= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.9 h1:Qp6Boy0cGDloOE3zI6XhNLNZgjNS8YmiFQFHe71SaW0= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.9/go.mod h1:0Aqn1MnEuitqfsCNyKsdKLhDUOr4txD/g19EfiUqgws= +github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3 h1:57NtjG+WLims0TxIQbjTqebZUKDM03DfM11ANAekW0s= +github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3/go.mod h1:739CllldowZiPPsDFcJHNF4FXrVxaSGVnZ9Ez9Iz9hc= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.9 h1:aD7AGQhvPuAxlSUfo0CWU7s6FpkbyykMhGYMvlqTjVs= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.9/go.mod h1:c1qtZUWtygI6ZdvKppzCSXsDOq5I4luJPZ0Ud3juFCA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3 h1:Pav5q3cA260Zqez42T9UhIlsd9QeypszRPwC9LdSSsQ= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.24.3/go.mod h1:9lmoVDVLz/yUZwLaQ676TK02fhCu4+PgRSmMaKR1ozk= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.10 h1:69tpbPED7jKPyzMcrwSvhWcJ9bPnZsZs18NT40JwM0g= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.10/go.mod h1:0Aqn1MnEuitqfsCNyKsdKLhDUOr4txD/g19EfiUqgws= github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/aws/smithy-go v1.20.2 h1:tbp628ireGtzcHDDmLT/6ADHidqnwgF57XOXZe6tp4Q= github.com/aws/smithy-go v1.20.2/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= @@ -264,8 +264,8 @@ github.com/codahale/rfc6979 v0.0.0-20141003034818-6a90f24967eb/go.mod h1:ZjrT6AX github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= -github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= -github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= +github.com/containerd/cgroups/v3 v3.0.3 h1:S5ByHZ/h9PMe5IOQoN7E+nMc2UcLEM/V48DGDJ9kip0= +github.com/containerd/cgroups/v3 v3.0.3/go.mod h1:8HBe7V3aWGLFPd/k03swSIsGjZhHI2WzJmticMgVuz0= github.com/containerd/containerd v1.7.17 h1:KjNnn0+tAVQHAoaWRjmdak9WlvnFR/8rU1CHHy8Rm2A= github.com/containerd/containerd v1.7.17/go.mod h1:vK+hhT4TIv2uejlcDlbVIc8+h/BqtKLIyNrtCZol8lI= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= @@ -276,14 +276,14 @@ github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/stargz-snapshotter/estargz v0.15.1 h1:eXJjw9RbkLFgioVaTG+G/ZW/0kEe2oEKCdS/ZxIyoCU= github.com/containerd/stargz-snapshotter/estargz v0.15.1/go.mod h1:gr2RNwukQ/S9Nv33Lt6UC7xEx58C+LHRdoqbEKjz1Kk= -github.com/containers/image/v5 v5.30.1 h1:AKrQMgOKI1oKx5FW5eoU2xoNyzACajHGx1O3qxobvFM= -github.com/containers/image/v5 v5.30.1/go.mod h1:gSD8MVOyqBspc0ynLsuiMR9qmt8UQ4jpVImjmK0uXfk= +github.com/containers/image/v5 v5.31.0 h1:eDFVlz5XaYICxe9dXpf23htEKvyosgkl62mJlIATXE4= +github.com/containers/image/v5 v5.31.0/go.mod h1:5QfOqSackPkSbF7Qxc1DnVNnPJKQ+KWLkfEfDpK590Q= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01 h1:Qzk5C6cYglewc+UyGf6lc8Mj2UaPTHy/iF2De0/77CA= github.com/containers/libtrust v0.0.0-20230121012942-c1716e8a8d01/go.mod h1:9rfv8iPl1ZP7aqh9YA68wnZv2NUDbXdcdPHVz0pFbPY= github.com/containers/ocicrypt v1.1.10 h1:r7UR6o8+lyhkEywetubUUgcKFjOWOaWz8cEBrCPX0ic= github.com/containers/ocicrypt v1.1.10/go.mod h1:YfzSSr06PTHQwSTUKqDSjish9BeW1E4HUmreluQcMd8= -github.com/containers/storage v1.53.0 h1:VSES3C/u1pxjTJIXvLrSmyP7OBtDky04oGu07UvdTEA= -github.com/containers/storage v1.53.0/go.mod h1:pujcoOSc+upx15Jirdkebhtd8uJiLwbSd/mYT6zDJK8= +github.com/containers/storage v1.54.0 h1:xwYAlf6n9OnIlURQLLg3FYHbO74fQ/2W2N6EtQEUM4I= +github.com/containers/storage v1.54.0/go.mod h1:PlMOoinRrBSnhYODLxt4EXl0nmJt+X0kjG0Xdt9fMTw= github.com/coreos/go-oidc/v3 v3.10.0 h1:tDnXHnLyiTVyT/2zLDGj09pFPkhND8Gl8lnTRhoEaJU= github.com/coreos/go-oidc/v3 v3.10.0/go.mod h1:5j11xcw0D3+SGxn6Z/WFADsgcWVMyNAlSQupk0KK3ac= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= @@ -292,8 +292,8 @@ github.com/creack/pty v1.1.21 h1:1/QdRyBaHHJP61QkWMXlOIBfsgdDeeKfK8SYVUWJKf0= github.com/creack/pty v1.1.21/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.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= -github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/cyphar/filepath-securejoin v0.2.5 h1:6iR5tXJ/e6tJZzzdMc1km3Sa7RRIVBKAK32O2s7AYfo= +github.com/cyphar/filepath-securejoin v0.2.5/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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= @@ -401,8 +401,8 @@ github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -570,13 +570,12 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= -github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= -github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.6 h1:TwRYfx2z2C4cLbXmT8I5PgP/xmuqASDyiVuGYfs9GZM= +github.com/hashicorp/go-retryablehttp v0.7.6/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-secure-stdlib/parseutil v0.1.7 h1:UpiO20jno/eV1eVZcxqWnUohyKRe1g8FPV/xH1s/2qs= @@ -682,8 +681,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 h1:oo9nIgnyiBgYPbcZslRT4y29siuL5EoNJ/t1tr0xEVQ= github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= -github.com/mandelsoft/goutils v0.0.0-20240510154642-0f1a031c54cb h1:1d3Xxk4rkdKcIFP1AcRlPxUhcBhnFCTqrMhXztB1r5E= -github.com/mandelsoft/goutils v0.0.0-20240510154642-0f1a031c54cb/go.mod h1:EbNqk9JceSMq7MJuALB/vlOpoD4MAGE0TenM9TR+C0o= github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460 h1:q44fRqo/PC3eTexd8Q3pO2BTHTABVXsW6DBXRUhC97E= github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460/go.mod h1:EbNqk9JceSMq7MJuALB/vlOpoD4MAGE0TenM9TR+C0o= github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf h1:WEmgzeArDbp6Aw34jmziMIE5ygo2zpl/atXRq3D7lSw= @@ -777,8 +774,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.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= -github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/ginkgo/v2 v2.19.0 h1:9Cnnf7UHo57Hy3k6/m5k3dRfGTMXGvxhHFvkDTCTpvA= +github.com/onsi/ginkgo/v2 v2.19.0/go.mod h1:rlwLi9PilAFJ8jCg9UE1QP6VBpd6/xj3SRC0d6TU0To= 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= @@ -850,8 +847,8 @@ github.com/protocolbuffers/txtpbfmt v0.0.0-20231025115547-084445ff1adf/go.mod h1 github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/rubenv/sql-migrate v1.6.0 h1:IZpcTlAx/VKXphWEpwWJ7BaMq05tYtE80zYz+8a5Il8= @@ -1034,8 +1031,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0 h1:9M3+rhx7kZCIQQhQRYa go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.22.0/go.mod h1:noq80iT8rrHP1SfybmPiRGc9dc5M8RPmGvtwo7Oo7tc= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0 h1:H2JFgRcGiyHg7H7bwcwaQJYrNFqCqrbTQ8K4p1OvDu8= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.22.0/go.mod h1:WfCWp1bGoYK8MeULtI15MmQVczfR+bFkk0DF3h06QmQ= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMeyr1aBvBiPVYihXIaeIZba6b8E1bYp7lbdxK8CQg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= go.opentelemetry.io/otel/metric v1.25.0 h1:LUKbS7ArpFL/I2jJHdJcqMGxkRdxpPHE0VU/D4NuEwA= go.opentelemetry.io/otel/metric v1.25.0/go.mod h1:rkDLUSd2lC5lq2dFNrX9LGAbINP5B7WBkC78RXCpH5s= go.opentelemetry.io/otel/sdk v1.25.0 h1:PDryEJPC8YJZQSyLY5eqLeafHtG+X7FWnf3aXMtxbqo= @@ -1079,8 +1076,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= -golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= @@ -1220,8 +1217,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.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= 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= @@ -1302,8 +1299,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.15.0 h1:gcLxHeFp0Hfo7lYi6KIZ84ZyvlAnfFRSJ8lTL3zvG5U= -helm.sh/helm/v3 v3.15.0/go.mod h1:fvfoRcB8UKRUV5jrIfOTaN/pG1TPhuqSb56fjYdTKXg= +helm.sh/helm/v3 v3.15.1 h1:22ztacHz4gMqhXNqCQ9NAg6BFWoRUryNLvnkz6OVyw0= +helm.sh/helm/v3 v3.15.1/go.mod h1:fvfoRcB8UKRUV5jrIfOTaN/pG1TPhuqSb56fjYdTKXg= 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.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= @@ -1330,8 +1327,8 @@ k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0g k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= oras.land/oras-go v1.2.5 h1:XpYuAwAb0DfQsunIyMfeET92emK8km3W4yEzZvUbsTo= oras.land/oras-go v1.2.5/go.mod h1:PuAwRShRZCsZb7g8Ar3jKKQR/2A/qN+pkYxIOd/FAoo= -sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLqlNpx+Q= -sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +sigs.k8s.io/controller-runtime v0.18.3 h1:B5Wmmo8WMWK7izei+2LlXLVDGzMwAHBNLX68lwtlSR4= +sigs.k8s.io/controller-runtime v0.18.3/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/kustomize/api v0.17.1 h1:MYJBOP/yQ3/5tp4/sf6HiiMfNNyO97LmtnirH9SLNr4= From ab463b22515b7829a39b2701876c58a7ad1efa46 Mon Sep 17 00:00:00 2001 From: Gergely Brautigam <182850+Skarlso@users.noreply.github.com> Date: Mon, 27 May 2024 16:48:46 +0200 Subject: [PATCH 05/12] fix: only have yaml out put on stdout if dryrun is enabled (#780) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description https://github.com/open-component-model/ocm-project/issues/67 ## What type of PR is this? (check all applicable) - [ ] 🍕 Feature - [ ] 🎇 Restructuring - [ ] 🐛 Bug Fix - [ ] 📝 Documentation Update - [ ] 🎨 Style - [ ] 🧑‍💻 Code Refactor - [ ] 🔥 Performance Improvements - [ ] ✅ Test - [ ] 🤖 Build - [ ] 🔁 CI - [ ] 📦 Chore (Release) - [ ] ⏩ Revert ## Related Tickets & Documents - Related Issue # (issue) - Closes # (issue) - Fixes # (issue) > Remove if not applicable ## Screenshots ## Added tests? - [ ] 👍 yes - [ ] 🙅 no, because they aren't needed - [ ] 🙋 no, because I need help - [ ] Separate ticket for tests # (issue/pr) Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration ## Added to documentation? - [ ] 📜 README.md - [ ] 🙅 no documentation needed ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- .../ocm/commands/controllercmds/common/log.go | 19 +++++++++++++++++++ .../controllercmds/common/manifests.go | 10 +++++----- .../commands/controllercmds/install/cmd.go | 11 +++++------ .../controllercmds/install/cmd_test.go | 11 ++--------- .../install/install_cert_manager.go | 7 +++---- .../controllercmds/uninstall/cmd_test.go | 5 ++--- 6 files changed, 36 insertions(+), 27 deletions(-) create mode 100644 cmds/ocm/commands/controllercmds/common/log.go diff --git a/cmds/ocm/commands/controllercmds/common/log.go b/cmds/ocm/commands/controllercmds/common/log.go new file mode 100644 index 0000000000..7793b26cdc --- /dev/null +++ b/cmds/ocm/commands/controllercmds/common/log.go @@ -0,0 +1,19 @@ +package common + +import ( + "fmt" + + "github.com/open-component-model/ocm/pkg/out" +) + +func Outf(ctx out.Context, dryRun bool, msg string, args ...any) (int, error) { + if dryRun { + return -1, nil + } + + if len(args) == 0 { + return fmt.Fprint(ctx.StdOut(), msg) + } + + return fmt.Fprintf(ctx.StdOut(), msg, args...) +} diff --git a/cmds/ocm/commands/controllercmds/common/manifests.go b/cmds/ocm/commands/controllercmds/common/manifests.go index 9e603e67ff..bf1a5b07d9 100644 --- a/cmds/ocm/commands/controllercmds/common/manifests.go +++ b/cmds/ocm/commands/controllercmds/common/manifests.go @@ -27,7 +27,7 @@ func Install(ctx context.Context, octx clictx.Context, sm *ssa.ResourceManager, return fmt.Errorf("✗ failed to apply manifests: %w", err) } - out.Outf(octx, "► waiting for ocm deployment to be ready\n") + Outf(octx, dryRun, "► waiting for ocm deployment to be ready\n") if err = sm.Wait(objects, ssa.DefaultWaitOptions()); err != nil { return fmt.Errorf("✗ failed to wait for objects to be ready: %w", err) } @@ -50,7 +50,7 @@ func Uninstall(ctx context.Context, octx clictx.Context, sm *ssa.ResourceManager return fmt.Errorf("✗ failed to delete manifests: %w", err) } - out.Outf(octx, "► waiting for ocm deployment to be deleted\n") + Outf(octx, dryRun, "► waiting for ocm deployment to be deleted\n") if err = sm.WaitForTermination(objects, ssa.DefaultWaitOptions()); err != nil { return fmt.Errorf("✗ failed to wait for objects to be deleted: %w", err) } @@ -64,7 +64,7 @@ func fetchObjects(ctx context.Context, octx clictx.Context, releaseURL, baseURL, if err != nil { return nil, fmt.Errorf("✗ failed to retrieve latest version for %s: %w", manifest, err) } - out.Outf(octx, "► got latest version %q\n", latest) + Outf(octx, dryRun, "► got latest version %q\n", latest) version = latest } else { exists, err := existingVersion(ctx, releaseURL, version) @@ -90,7 +90,7 @@ func fetchObjects(ctx context.Context, octx clictx.Context, releaseURL, baseURL, if _, err := os.Stat(path); os.IsNotExist(err) { return nil, fmt.Errorf("✗ failed to find %s file at location: %w", filename, err) } - out.Outf(octx, "✔ successfully fetched install file\n") + Outf(octx, dryRun, "✔ successfully fetched install file\n") if dryRun { content, err := os.ReadFile(path) if err != nil { @@ -101,7 +101,7 @@ func fetchObjects(ctx context.Context, octx clictx.Context, releaseURL, baseURL, return nil, nil } - out.Outf(octx, "► applying to cluster...\n") + Outf(octx, dryRun, "► applying to cluster...\n") objects, err := ReadObjects(path) if err != nil { diff --git a/cmds/ocm/commands/controllercmds/install/cmd.go b/cmds/ocm/commands/controllercmds/install/cmd.go index 873786f0ea..5d5a5b8bea 100644 --- a/cmds/ocm/commands/controllercmds/install/cmd.go +++ b/cmds/ocm/commands/controllercmds/install/cmd.go @@ -19,7 +19,6 @@ import ( "github.com/open-component-model/ocm/cmds/ocm/commands/verbs" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/contexts/clictx" - "github.com/open-component-model/ocm/pkg/out" ) var ( @@ -97,22 +96,22 @@ func (o *Command) Run() (err error) { ctx := context.Background() if !o.SkipPreFlightCheck { - out.Outf(o.Context, "► running pre-install check\n") + common.Outf(o.Context, o.DryRun, "► running pre-install check\n") if err := o.RunPreFlightCheck(ctx); err != nil { if o.InstallPrerequisites { - out.Outf(o.Context, "► installing prerequisites\n") + common.Outf(o.Context, o.DryRun, "► installing prerequisites\n") if err := o.installPrerequisites(ctx); err != nil { return err } - out.Outf(o.Context, "✔ successfully installed prerequisites\n") + common.Outf(o.Context, o.DryRun, "✔ successfully installed prerequisites\n") } else { return fmt.Errorf("✗ failed to run pre-flight check: %w\n", err) } } } - out.Outf(o.Context, "► installing ocm-controller with version %s\n", o.Version) + common.Outf(o.Context, o.DryRun, "► installing ocm-controller with version %s\n", o.Version) version := o.Version if err := common.Install( ctx, @@ -128,7 +127,7 @@ func (o *Command) Run() (err error) { return err } - out.Outf(o.Context, "✔ ocm-controller successfully installed\n") + common.Outf(o.Context, o.DryRun, "✔ ocm-controller successfully installed\n") return nil } diff --git a/cmds/ocm/commands/controllercmds/install/cmd_test.go b/cmds/ocm/commands/controllercmds/install/cmd_test.go index 9b8f5a31e3..dae47175a0 100644 --- a/cmds/ocm/commands/controllercmds/install/cmd_test.go +++ b/cmds/ocm/commands/controllercmds/install/cmd_test.go @@ -50,21 +50,14 @@ var _ = Describe("Test Environment", func() { It("install latest version", func() { buf := bytes.NewBuffer(nil) Expect(env.CatchOutput(buf).Execute("controller", "install", "-d", "-s", "-u", testServer.URL, "-a", testServer.URL)).To(Succeed()) - Expect(buf.String()).To(StringEqualTrimmedWithContext(`► installing ocm-controller with version latest -► got latest version "v0.0.1-test" -✔ successfully fetched install file -test: content -✔ ocm-controller successfully installed + Expect(buf.String()).To(StringEqualTrimmedWithContext(`test: content `)) }) It("install specific version", func() { buf := bytes.NewBuffer(nil) Expect(env.CatchOutput(buf).Execute("controller", "install", "-d", "-s", "-u", testServer.URL, "-a", testServer.URL, "-v", "v0.1.0-test-2")).To(Succeed()) - Expect(buf.String()).To(StringEqualTrimmedWithContext(`► installing ocm-controller with version v0.1.0-test-2 -✔ successfully fetched install file -test: content -✔ ocm-controller successfully installed + Expect(buf.String()).To(StringEqualTrimmedWithContext(`test: content `)) }) }) diff --git a/cmds/ocm/commands/controllercmds/install/install_cert_manager.go b/cmds/ocm/commands/controllercmds/install/install_cert_manager.go index 8fe2a325a1..089ec79fc0 100644 --- a/cmds/ocm/commands/controllercmds/install/install_cert_manager.go +++ b/cmds/ocm/commands/controllercmds/install/install_cert_manager.go @@ -11,26 +11,25 @@ import ( "github.com/mandelsoft/filepath/pkg/filepath" "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/common" - "github.com/open-component-model/ocm/pkg/out" ) //go:embed issuer/registry_certificate.yaml var issuer []byte func (o *Command) installPrerequisites(ctx context.Context) error { - out.Outf(o.Context, "► installing cert-manager with version %s\n", o.CertManagerVersion) + common.Outf(o.Context, o.DryRun, "► installing cert-manager with version %s\n", o.CertManagerVersion) if err := common.Install(ctx, o.Context, o.SM, o.CertManagerReleaseAPIURL, o.CertManagerBaseURL, "cert-manager", "cert-manager.yaml", o.CertManagerVersion, o.DryRun); err != nil { return err } - out.Outf(o.Context, "✔ cert-manager successfully installed\n") + common.Outf(o.Context, o.DryRun, "✔ cert-manager successfully installed\n") if o.DryRun { return nil } - out.Outf(o.Context, "► creating certificate for internal registry\n") + common.Outf(o.Context, o.DryRun, "► creating certificate for internal registry\n") if err := o.createRegistryCertificate(); err != nil { return fmt.Errorf("✗ failed to create registry certificate: %w", err) diff --git a/cmds/ocm/commands/controllercmds/uninstall/cmd_test.go b/cmds/ocm/commands/controllercmds/uninstall/cmd_test.go index a9559d69ba..d6316b5894 100644 --- a/cmds/ocm/commands/controllercmds/uninstall/cmd_test.go +++ b/cmds/ocm/commands/controllercmds/uninstall/cmd_test.go @@ -50,9 +50,8 @@ var _ = Describe("Test Environment", func() { It("uninstall latest version", func() { buf := bytes.NewBuffer(nil) Expect(env.CatchOutput(buf).Execute("controller", "uninstall", "-d", "-u", testServer.URL, "-a", testServer.URL)).To(Succeed()) + fmt.Println(buf.String()) Expect(buf.String()).To(StringEqualTrimmedWithContext(`► uninstalling ocm-controller with version latest -► got latest version "v0.0.1-test" -✔ successfully fetched install file test: content ✔ ocm-controller successfully uninstalled `)) @@ -61,8 +60,8 @@ test: content It("uninstall specific version", func() { buf := bytes.NewBuffer(nil) Expect(env.CatchOutput(buf).Execute("controller", "uninstall", "-d", "-u", testServer.URL, "-a", testServer.URL, "-v", "v0.1.0-test-2")).To(Succeed()) + fmt.Println(buf.String()) Expect(buf.String()).To(StringEqualTrimmedWithContext(`► uninstalling ocm-controller with version v0.1.0-test-2 -✔ successfully fetched install file test: content ✔ ocm-controller successfully uninstalled `)) From 509ba8913fb4ee6382226b1ce5fbe8179812f848 Mon Sep 17 00:00:00 2001 From: Fabian Burth Date: Tue, 28 May 2024 19:37:05 +0200 Subject: [PATCH 06/12] Follow Up To Maven Access (#781) ## Description This Pull Request is a follow up to the [Pull Request](https://github.com/open-component-model/ocm/pull/731) adding a Maven Access Method. This Pull Request adds a corresponding input type, a blob access and corresponding helper methods in the elements package (and therefore makes several adjustments). --- .golangci.yaml | 3 + .../controllercmds/common/manifests.go | 3 +- .../commands/controllercmds/install/cmd.go | 2 +- .../commands/controllercmds/uninstall/cmd.go | 7 +- .../uninstall/uninstall_cert_manager.go | 4 +- .../commands/misccmds/credentials/get/cmd.go | 2 +- .../commands/ocmcmds/common/addhdlrs/utils.go | 2 +- .../common/handlers/pluginhdlr/typehandler.go | 2 +- .../common/handlers/vershdlr/typehandler.go | 2 +- .../ocmcmds/common/inputs/options/standard.go | 11 +- .../ocmcmds/common/inputs/types/init.go | 1 + .../ocmcmds/common/inputs/types/maven/cli.go | 32 ++ .../common/inputs/types/maven/input_test.go | 96 ++++ .../ocmcmds/common/inputs/types/maven/spec.go | 99 ++++ .../common/inputs/types/maven}/suite_test.go | 4 +- .../types/maven/testdata/resources1.yaml | 8 + .../ocmcmds/common/inputs/types/maven/type.go | 43 ++ .../common/options/schemaoption/option.go | 2 +- cmds/ocm/commands/ocmcmds/common/resources.go | 4 +- cmds/ocm/commands/ocmcmds/common/utils.go | 2 +- .../commands/ocmcmds/components/add/cmd.go | 2 +- .../ocmcmds/components/download/cmd.go | 2 +- .../ocmcmds/components/transfer/cmd.go | 2 +- cmds/ocm/commands/ocmcmds/ctf/transfer/cmd.go | 2 +- .../commands/ocmcmds/plugins/install/cmd.go | 2 +- .../commands/toicmds/package/bootstrap/cmd.go | 2 +- .../commands/toicmds/package/describe/cmd.go | 2 +- cmds/ocm/commands/verbs/controller/cmd.go | 2 +- cmds/ocm/pkg/utils/command.go | 2 +- cmds/ocm/pkg/utils/handling.go | 1 + .../plugin_accessmethod_compose.md | 7 +- docs/pluginreference/plugin_descriptor.md | 7 +- .../plugin_valueset_compose.md | 7 +- .../ocm_add_resource-configuration.md | 65 ++- docs/reference/ocm_add_resources.md | 65 ++- .../reference/ocm_add_source-configuration.md | 65 ++- docs/reference/ocm_add_sources.md | 65 ++- docs/reference/ocm_logging.md | 3 +- docs/reference/ocm_ocm-accessmethods.md | 20 +- docs/reference/ocm_ocm-uploadhandlers.md | 8 +- .../ocm_transfer_commontransportarchive.md | 8 +- .../ocm_transfer_componentversions.md | 8 +- .../lib/tour/01-getting-started/README.md | 14 +- .../01-basic-componentversion-creation.go | 2 +- .../README.md | 2 +- .../03-working-with-credentials/common.go | 2 +- .../common.go | 2 +- .../06-signing-component-versions/common.go | 2 +- go.mod | 3 +- go.sum | 4 +- pkg/blobaccess/maven/access.go | 38 ++ pkg/blobaccess/maven/access_test.go | 125 +++++ pkg/blobaccess/maven/maven.go | 36 ++ pkg/blobaccess/maven/options.go | 204 ++++++++ pkg/blobaccess/maven/suite_test.go | 13 + pkg/blobaccess/maven/utils.go | 167 +++++++ pkg/blobaccess/standard.go | 17 + pkg/blobaccess/wget/options.go | 3 + pkg/common/accessio/retry_test.go | 1 + pkg/common/accessobj/cachedblob.go | 6 +- pkg/contexts/config/gc_test.go | 2 +- .../{mvn => maven}/identity/identity.go | 28 +- pkg/contexts/credentials/gc_test.go | 2 +- .../repositories/npm/repository_test.go | 2 +- .../repositories/vault/repo_int_test.go | 33 +- .../repositories/vault/repo_test.go | 2 +- .../datacontext/attrs/tmpcache/attr.go | 18 +- .../datacontext/attrs/vfsattr/attr.go | 2 +- pkg/contexts/oci/gc_test.go | 2 +- pkg/contexts/oci/repositories/ctf/ctf_test.go | 2 +- pkg/contexts/ocm/accessmethods/init.go | 2 +- .../accessmethods/{mvn => maven}/README.md | 0 .../ocm/accessmethods/{mvn => maven}/cli.go | 22 +- .../ocm/accessmethods/maven/method.go | 159 +++++++ .../ocm/accessmethods/maven/method_test.go | 133 ++++++ .../mvn => accessmethods/maven}/suite_test.go | 4 +- .../ocm/accessmethods/mvn/coordinates.go | 144 ------ .../ocm/accessmethods/mvn/coordinates_test.go | 55 --- .../ocm/accessmethods/mvn/integration_test.go | 98 ---- pkg/contexts/ocm/accessmethods/mvn/method.go | 444 ------------------ .../ocm/accessmethods/mvn/method_test.go | 87 ---- .../ocm/accessmethods/options/standard.go | 9 +- .../ocm/accessmethods/wget/options.go | 15 - .../handlers/generic/maven/blobhandler.go | 126 +++++ .../generic/maven/blobhandler_test.go | 101 ++++ .../generic/{mvn => maven}/registration.go | 60 ++- .../{mvn => maven}/registration_test.go | 12 +- .../handlers/generic/maven/suite_test.go | 13 + .../handlers/generic/mvn/blobhandler.go | 180 ------- .../handlers/generic/mvn/blobhandler_test.go | 43 -- .../handlers/generic/npm/registration_test.go | 2 +- pkg/contexts/ocm/blobhandler/handlers/init.go | 2 +- pkg/contexts/ocm/cpi/builder.go | 50 ++ pkg/contexts/ocm/cpi/interface.go | 4 - .../artifactaccess/mavenaccess/options.go | 20 + .../artifactaccess/mavenaccess/resource.go | 39 ++ .../artifactaccess/mvnaccess/resource.go | 30 -- .../artifactblob/helmblob/helmblob_test.go | 37 ++ .../artifactblob/helmblob/suite_test.go | 13 + .../helmblob/testdata/testchart1/.helmignore | 23 + .../testdata/testchart1/.idea/somefile | 0 .../helmblob/testdata/testchart1/Chart.yaml | 24 + .../testdata/testchart1/templates/NOTES.txt | 22 + .../testchart1/templates/_helpers.tpl | 62 +++ .../testchart1/templates/deployment.yaml | 61 +++ .../testdata/testchart1/templates/hpa.yaml | 28 ++ .../testchart1/templates/ingress.yaml | 61 +++ .../testchart1/templates/service.yaml | 15 + .../testchart1/templates/serviceaccount.yaml | 12 + .../templates/tests/test-connection.yaml | 15 + .../helmblob/testdata/testchart1/values.yaml | 81 ++++ .../helmblob/testdata/testchart2/.helmignore | 23 + .../testdata/testchart2/.idea/somefile | 0 .../helmblob/testdata/testchart2/Chart.yaml | 24 + .../testdata/testchart2/templates/NOTES.txt | 22 + .../testchart2/templates/_helpers.tpl | 62 +++ .../testchart2/templates/deployment.yaml | 61 +++ .../testdata/testchart2/templates/hpa.yaml | 28 ++ .../testchart2/templates/ingress.yaml | 61 +++ .../testchart2/templates/service.yaml | 15 + .../testchart2/templates/serviceaccount.yaml | 12 + .../templates/tests/test-connection.yaml | 15 + .../helmblob/testdata/testchart2/values.yaml | 81 ++++ .../artifactblob/mavenblob/access_test.go | 61 +++ .../artifactblob/mavenblob/options.go | 96 ++++ .../artifactblob/mavenblob/resource.go | 43 ++ .../artifactblob/mavenblob/suite_test.go | 13 + .../elements/artifactblob/textblob/options.go | 2 +- .../artifactblob/wgetblob/resource.go | 2 +- pkg/contexts/ocm/gc_test.go | 2 +- pkg/contexts/ocm/plugin/cache/updater.go | 2 +- .../repositories/genericocireg/repo_test.go | 3 +- pkg/contexts/ocm/resourcetypes/const.go | 4 +- pkg/contexts/ocm/transfer/autohandler_test.go | 1 + pkg/contexts/ocm/utils/localize/format.go | 2 +- pkg/env/env.go | 96 +++- pkg/exception/exception_test.go | 1 + pkg/iotools/hashReaderWriter.go | 140 +++--- pkg/iotools/hashReaderWriter_test.go | 49 +- pkg/maven/access.go | 407 ++++++++++++++++ pkg/maven/access_test.go | 132 ++++++ pkg/maven/coordinates.go | 218 +++++++++ pkg/maven/coordinates_test.go | 52 ++ pkg/maven/logging.go | 7 + pkg/maven/maventest/testdata.go | 9 + .../fail/test/repository/42/repository-42.pom | 0 .../test/repository/42/repository-42.pom.sha1 | 0 .../sdk-modules-bom-5.7.0-random-content.json | 1 + ...modules-bom-5.7.0-random-content.json.sha1 | 1 + .../sdk-modules-bom-5.7.0-random-content.txt | 1 + ...-modules-bom-5.7.0-random-content.txt.sha1 | 1 + .../5.7.0/sdk-modules-bom-5.7.0-sources.jar | Bin 0 -> 595 bytes .../sdk-modules-bom-5.7.0-sources.jar.sha1 | 1 + .../5.7.0/sdk-modules-bom-5.7.0.jar | Bin 0 -> 595 bytes .../5.7.0/sdk-modules-bom-5.7.0.jar.sha1 | 1 + .../5.7.0/sdk-modules-bom-5.7.0.pom | 0 .../5.7.0/sdk-modules-bom-5.7.0.pom.sha1 | 0 pkg/maven/suite_test.go | 13 + pkg/maven/utils.go | 37 ++ pkg/optionutils/utils.go | 7 + pkg/refmgmt/finalized/finalized_test.go | 2 +- pkg/testutils/tcp.go | 30 ++ pkg/utils/package.go | 44 ++ 163 files changed, 4145 insertions(+), 1458 deletions(-) create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/maven/cli.go create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/maven/spec.go rename {pkg/contexts/ocm/accessmethods/mvn => cmds/ocm/commands/ocmcmds/common/inputs/types/maven}/suite_test.go (72%) create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/maven/testdata/resources1.yaml create mode 100644 cmds/ocm/commands/ocmcmds/common/inputs/types/maven/type.go create mode 100644 pkg/blobaccess/maven/access.go create mode 100644 pkg/blobaccess/maven/access_test.go create mode 100644 pkg/blobaccess/maven/maven.go create mode 100644 pkg/blobaccess/maven/options.go create mode 100644 pkg/blobaccess/maven/suite_test.go create mode 100644 pkg/blobaccess/maven/utils.go rename pkg/contexts/credentials/builtin/{mvn => maven}/identity/identity.go (67%) rename pkg/contexts/ocm/accessmethods/{mvn => maven}/README.md (100%) rename pkg/contexts/ocm/accessmethods/{mvn => maven}/cli.go (73%) create mode 100644 pkg/contexts/ocm/accessmethods/maven/method.go create mode 100644 pkg/contexts/ocm/accessmethods/maven/method_test.go rename pkg/contexts/ocm/{blobhandler/handlers/generic/mvn => accessmethods/maven}/suite_test.go (72%) delete mode 100644 pkg/contexts/ocm/accessmethods/mvn/coordinates.go delete mode 100644 pkg/contexts/ocm/accessmethods/mvn/coordinates_test.go delete mode 100644 pkg/contexts/ocm/accessmethods/mvn/integration_test.go delete mode 100644 pkg/contexts/ocm/accessmethods/mvn/method.go delete mode 100644 pkg/contexts/ocm/accessmethods/mvn/method_test.go create mode 100644 pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler.go create mode 100644 pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler_test.go rename pkg/contexts/ocm/blobhandler/handlers/generic/{mvn => maven}/registration.go (51%) rename pkg/contexts/ocm/blobhandler/handlers/generic/{mvn => maven}/registration_test.go (58%) create mode 100644 pkg/contexts/ocm/blobhandler/handlers/generic/maven/suite_test.go delete mode 100644 pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go delete mode 100644 pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler_test.go create mode 100644 pkg/contexts/ocm/cpi/builder.go create mode 100644 pkg/contexts/ocm/elements/artifactaccess/mavenaccess/options.go create mode 100644 pkg/contexts/ocm/elements/artifactaccess/mavenaccess/resource.go delete mode 100644 pkg/contexts/ocm/elements/artifactaccess/mvnaccess/resource.go create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/helmblob_test.go create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/suite_test.go create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.helmignore create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.idea/somefile create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/Chart.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/NOTES.txt create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/_helpers.tpl create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/deployment.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/hpa.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/ingress.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/service.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/serviceaccount.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/tests/test-connection.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/values.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.helmignore create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.idea/somefile create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/Chart.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/NOTES.txt create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/_helpers.tpl create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/deployment.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/hpa.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/ingress.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/service.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/serviceaccount.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/tests/test-connection.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/values.yaml create mode 100644 pkg/contexts/ocm/elements/artifactblob/mavenblob/access_test.go create mode 100644 pkg/contexts/ocm/elements/artifactblob/mavenblob/options.go create mode 100644 pkg/contexts/ocm/elements/artifactblob/mavenblob/resource.go create mode 100644 pkg/contexts/ocm/elements/artifactblob/mavenblob/suite_test.go create mode 100644 pkg/maven/access.go create mode 100644 pkg/maven/access_test.go create mode 100644 pkg/maven/coordinates.go create mode 100644 pkg/maven/coordinates_test.go create mode 100644 pkg/maven/logging.go create mode 100644 pkg/maven/maventest/testdata.go rename pkg/{contexts/ocm/accessmethods/mvn/testdata => maven/maventest/testdata/.m2}/fail/test/repository/42/repository-42.pom (100%) rename pkg/{contexts/ocm/accessmethods/mvn/testdata => maven/maventest/testdata/.m2}/fail/test/repository/42/repository-42.pom.sha1 (100%) create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json.sha1 create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt.sha1 create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-sources.jar create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-sources.jar.sha1 create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0.jar create mode 100644 pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0.jar.sha1 rename pkg/{contexts/ocm/accessmethods/mvn => maven/maventest}/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0.pom (100%) rename pkg/{contexts/ocm/accessmethods/mvn => maven/maventest}/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0.pom.sha1 (100%) create mode 100644 pkg/maven/suite_test.go create mode 100644 pkg/maven/utils.go create mode 100644 pkg/optionutils/utils.go create mode 100644 pkg/testutils/tcp.go create mode 100644 pkg/utils/package.go diff --git a/.golangci.yaml b/.golangci.yaml index 8a105b4382..9e4ab89249 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -134,6 +134,9 @@ linters-settings: line-length: 120 gosec: exclude-generated: true + gocritic: + disabled-checks: + - elseif issues: exclude: diff --git a/cmds/ocm/commands/controllercmds/common/manifests.go b/cmds/ocm/commands/controllercmds/common/manifests.go index bf1a5b07d9..c54bc5a7c6 100644 --- a/cmds/ocm/commands/controllercmds/common/manifests.go +++ b/cmds/ocm/commands/controllercmds/common/manifests.go @@ -7,9 +7,10 @@ import ( "path/filepath" "github.com/fluxcd/pkg/ssa" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "github.com/open-component-model/ocm/pkg/contexts/clictx" "github.com/open-component-model/ocm/pkg/out" - "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) func Install(ctx context.Context, octx clictx.Context, sm *ssa.ResourceManager, releaseURL, baseURL, manifest, filename, version string, dryRun bool) error { diff --git a/cmds/ocm/commands/controllercmds/install/cmd.go b/cmds/ocm/commands/controllercmds/install/cmd.go index 5d5a5b8bea..25427a1ba5 100644 --- a/cmds/ocm/commands/controllercmds/install/cmd.go +++ b/cmds/ocm/commands/controllercmds/install/cmd.go @@ -6,7 +6,6 @@ import ( "time" "github.com/fluxcd/pkg/ssa" - "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/common" "github.com/spf13/cobra" "github.com/spf13/pflag" corev1 "k8s.io/api/core/v1" @@ -15,6 +14,7 @@ import ( "k8s.io/client-go/rest" "sigs.k8s.io/controller-runtime/pkg/client" + "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/common" "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/names" "github.com/open-component-model/ocm/cmds/ocm/commands/verbs" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" diff --git a/cmds/ocm/commands/controllercmds/uninstall/cmd.go b/cmds/ocm/commands/controllercmds/uninstall/cmd.go index 3c1e497462..47c06530c4 100644 --- a/cmds/ocm/commands/controllercmds/uninstall/cmd.go +++ b/cmds/ocm/commands/controllercmds/uninstall/cmd.go @@ -6,15 +6,16 @@ import ( "time" "github.com/fluxcd/pkg/ssa" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "k8s.io/cli-runtime/pkg/genericclioptions" + "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/common" "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/names" "github.com/open-component-model/ocm/cmds/ocm/commands/verbs" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/contexts/clictx" "github.com/open-component-model/ocm/pkg/out" - "github.com/spf13/cobra" - "github.com/spf13/pflag" - "k8s.io/cli-runtime/pkg/genericclioptions" ) var ( diff --git a/cmds/ocm/commands/controllercmds/uninstall/uninstall_cert_manager.go b/cmds/ocm/commands/controllercmds/uninstall/uninstall_cert_manager.go index 944c881eb0..e0380e264b 100644 --- a/cmds/ocm/commands/controllercmds/uninstall/uninstall_cert_manager.go +++ b/cmds/ocm/commands/controllercmds/uninstall/uninstall_cert_manager.go @@ -2,12 +2,14 @@ package uninstall import ( "context" - _ "embed" "fmt" "os" + _ "embed" + "github.com/fluxcd/pkg/ssa" "github.com/mandelsoft/filepath/pkg/filepath" + "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/common" "github.com/open-component-model/ocm/pkg/out" ) diff --git a/cmds/ocm/commands/misccmds/credentials/get/cmd.go b/cmds/ocm/commands/misccmds/credentials/get/cmd.go index 48e5f574b4..a634692cb9 100644 --- a/cmds/ocm/commands/misccmds/credentials/get/cmd.go +++ b/cmds/ocm/commands/misccmds/credentials/get/cmd.go @@ -5,7 +5,6 @@ import ( "strings" "github.com/mandelsoft/goutils/errors" - "github.com/open-component-model/ocm/pkg/listformat" "github.com/spf13/cobra" "github.com/spf13/pflag" @@ -15,6 +14,7 @@ import ( "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/contexts/clictx" "github.com/open-component-model/ocm/pkg/contexts/credentials" + "github.com/open-component-model/ocm/pkg/listformat" "github.com/open-component-model/ocm/pkg/out" ) diff --git a/cmds/ocm/commands/ocmcmds/common/addhdlrs/utils.go b/cmds/ocm/commands/ocmcmds/common/addhdlrs/utils.go index 08ee455eb0..53743e4521 100644 --- a/cmds/ocm/commands/ocmcmds/common/addhdlrs/utils.go +++ b/cmds/ocm/commands/ocmcmds/common/addhdlrs/utils.go @@ -8,7 +8,6 @@ import ( "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/vfs/pkg/vfs" - "github.com/open-component-model/ocm/pkg/errkind" "gopkg.in/yaml.v3" "k8s.io/apimachinery/pkg/util/validation/field" @@ -18,6 +17,7 @@ import ( "github.com/open-component-model/ocm/pkg/common/accessio" "github.com/open-component-model/ocm/pkg/contexts/clictx" "github.com/open-component-model/ocm/pkg/contexts/ocm" + "github.com/open-component-model/ocm/pkg/errkind" "github.com/open-component-model/ocm/pkg/runtime" utils2 "github.com/open-component-model/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/utils/template" diff --git a/cmds/ocm/commands/ocmcmds/common/handlers/pluginhdlr/typehandler.go b/cmds/ocm/commands/ocmcmds/common/handlers/pluginhdlr/typehandler.go index 4ba9f91550..b24da832ed 100644 --- a/cmds/ocm/commands/ocmcmds/common/handlers/pluginhdlr/typehandler.go +++ b/cmds/ocm/commands/ocmcmds/common/handlers/pluginhdlr/typehandler.go @@ -4,7 +4,7 @@ import ( "strings" "github.com/mandelsoft/goutils/errors" - + "github.com/open-component-model/ocm/cmds/ocm/pkg/output" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/contexts/clictx" diff --git a/cmds/ocm/commands/ocmcmds/common/handlers/vershdlr/typehandler.go b/cmds/ocm/commands/ocmcmds/common/handlers/vershdlr/typehandler.go index 875da9e575..83967edd1e 100644 --- a/cmds/ocm/commands/ocmcmds/common/handlers/vershdlr/typehandler.go +++ b/cmds/ocm/commands/ocmcmds/common/handlers/vershdlr/typehandler.go @@ -6,8 +6,8 @@ import ( "sort" "github.com/Masterminds/semver/v3" - "github.com/mandelsoft/goutils/errors" + "github.com/open-component-model/ocm/cmds/ocm/pkg/output" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/contexts/clictx" diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/options/standard.go b/cmds/ocm/commands/ocmcmds/common/inputs/options/standard.go index c43f18f318..74a22ddc28 100644 --- a/cmds/ocm/commands/ocmcmds/common/inputs/options/standard.go +++ b/cmds/ocm/commands/ocmcmds/common/inputs/options/standard.go @@ -6,13 +6,20 @@ import ( ) var ( - HintOption = options.HintOption - MediaTypeOption = options.MediatypeOption + HintOption = options.HintOption + MediaTypeOption = options.MediatypeOption + URLOption = options.URLOption HTTPHeaderOption = options.HTTPHeaderOption HTTPVerbOption = options.HTTPVerbOption HTTPBodyOption = options.HTTPBodyOption HTTPRedirectOption = options.HTTPRedirectOption + + RepositoryOption = options.RepositoryOption + GroupOption = options.GroupOption + ArtifactOption = options.ArtifactOption + ClassifierOption = options.ClassifierOption + ExtensionOption = options.ExtensionOption ) // string options diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go index ccf3c66649..8c42a5781a 100644 --- a/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/init.go @@ -7,6 +7,7 @@ import ( _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/dockermulti" _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/file" _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/helm" + _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/maven" _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/ociartifact" _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/spiff" _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types/utf8" diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/cli.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/cli.go new file mode 100644 index 0000000000..88b6fcbc63 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/cli.go @@ -0,0 +1,32 @@ +package maven + +import ( + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/options" + "github.com/open-component-model/ocm/pkg/cobrautils/flagsets" +) + +func ConfigHandler() flagsets.ConfigOptionTypeSetHandler { + return flagsets.NewConfigOptionTypeSetHandler( + TYPE, AddConfig, + options.URLOption, + options.PathOption, + options.GroupOption, + options.ArtifactOption, + options.VersionOption, + // optional + options.ClassifierOption, + options.ExtensionOption, + ) +} + +func AddConfig(opts flagsets.ConfigOptions, config flagsets.Config) error { + flagsets.AddFieldByOptionP(opts, options.URLOption, config, "repoUrl") + flagsets.AddFieldByOptionP(opts, options.PathOption, config, "path") + flagsets.AddFieldByOptionP(opts, options.GroupOption, config, "groupId") + flagsets.AddFieldByOptionP(opts, options.ArtifactOption, config, "artifactId") + flagsets.AddFieldByOptionP(opts, options.VersionOption, config, "version") + // optional + flagsets.AddFieldByOptionP(opts, options.ClassifierOption, config, "classifier") + flagsets.AddFieldByOptionP(opts, options.ExtensionOption, config, "extension") + return nil +} diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go new file mode 100644 index 0000000000..7731e45ac5 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go @@ -0,0 +1,96 @@ +package maven_test + +import ( + "crypto" + "github.com/open-component-model/ocm/pkg/maven/maventest" + + . "github.com/mandelsoft/goutils/testutils" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/cmds/ocm/testhelper" + + "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/comparch" + "github.com/open-component-model/ocm/pkg/mime" + "github.com/open-component-model/ocm/pkg/utils/tarutils" +) + +const ( + ARCH = "test.ca" + VERSION = "v1" +) + +var _ = Describe("Test Environment", func() { + var env *TestEnv + + BeforeEach(func() { + env = NewTestEnv(TestData(), maventest.TestData("/maven/testdata")) + + Expect(env.Execute("create", "ca", "-ft", "directory", "test.de/x", VERSION, "--provider", "mandelsoft", "--file", ARCH)).To(Succeed()) + }) + + AfterEach(func() { + env.Cleanup() + }) + + It("add maven from file system described by resources.yaml", func() { + Expect(env.Execute("add", "resources", "--file", ARCH, "/testdata/resources1.yaml")).To(Succeed()) + data, err := env.ReadFile(env.Join(ARCH, comparch.ComponentDescriptorFileName)) + Expect(err).To(Succeed()) + cd, err := compdesc.Decode(data) + Expect(err).To(Succeed()) + Expect(len(cd.Resources)).To(Equal(1)) + access := Must(env.Context.OCMContext().AccessSpecForSpec(cd.Resources[0].Access)).(*localblob.AccessSpec) + Expect(access.MediaType).To(Equal(mime.MIME_TGZ)) + fi := Must(env.FileSystem().Stat(env.Join(ARCH, "blobs", access.LocalReference))) + Expect(fi.Size()).To(Equal(int64(1570))) + li := Must(tarutils.ListArchiveContent(env.Join(ARCH, "blobs", access.LocalReference), env.FileSystem())) + Expect(li).To(ConsistOf( + "sdk-modules-bom-5.7.0-random-content.json", + "sdk-modules-bom-5.7.0-random-content.txt", + "sdk-modules-bom-5.7.0-sources.jar", + "sdk-modules-bom-5.7.0.jar", + "sdk-modules-bom-5.7.0.pom")) + Expect(cd.Resources[0].Digest.HashAlgorithm).To(Equal(crypto.SHA256.String())) + Expect(cd.Resources[0].Digest.Value).To(Equal("16cfb5ced0ea7688dba14aeb0d3aa76ad46e4661bfcc556ffd7287de3b2f7152")) + }) + + It("add maven from file system described by cli options", func() { + meta := ` +name: testdata +type: mavenArtifact +` + Expect(env.Execute("add", "resources", "--file", ARCH, "--resource", meta, "--inputType", "maven", + "--inputPath", "/maven/testdata/.m2/repository", "--groupId", "com.sap.cloud.sdk", "--artifactId", "sdk-modules-bom", + "--inputVersion", "5.7.0", "--classifier", "", "--extension", "pom")).To(Succeed()) + data, err := env.ReadFile(env.Join(ARCH, comparch.ComponentDescriptorFileName)) + Expect(err).To(Succeed()) + cd, err := compdesc.Decode(data) + Expect(err).To(Succeed()) + Expect(len(cd.Resources)).To(Equal(1)) + access := Must(env.Context.OCMContext().AccessSpecForSpec(cd.Resources[0].Access)).(*localblob.AccessSpec) + Expect(access.MediaType).To(Equal(mime.MIME_XML)) + fi := Must(env.FileSystem().Stat(env.Join(ARCH, "blobs", access.LocalReference))) + Expect(fi.Size()).To(Equal(int64(7153))) + }) + + It("add maven file from file system described by cli options", func() { + meta := ` +name: testdata +type: mavenArtifact +` + Expect(env.Execute("add", "resources", "--file", ARCH, "--resource", meta, "--inputType", "maven", + "--inputPath", "/maven/testdata/.m2/repository", "--groupId", "com.sap.cloud.sdk", "--artifactId", "sdk-modules-bom", + "--inputVersion", "5.7.0", "--extension", "pom")).To(Succeed()) + data, err := env.ReadFile(env.Join(ARCH, comparch.ComponentDescriptorFileName)) + Expect(err).To(Succeed()) + cd, err := compdesc.Decode(data) + Expect(err).To(Succeed()) + Expect(len(cd.Resources)).To(Equal(1)) + access := Must(env.Context.OCMContext().AccessSpecForSpec(cd.Resources[0].Access)).(*localblob.AccessSpec) + Expect(access.MediaType).To(Equal(mime.MIME_TGZ)) + fi := Must(env.FileSystem().Stat(env.Join(ARCH, "blobs", access.LocalReference))) + Expect(fi.Size()).To(Equal(int64(1109))) + }) +}) diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/spec.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/spec.go new file mode 100644 index 0000000000..b07c924979 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/spec.go @@ -0,0 +1,99 @@ +package maven + +import ( + "fmt" + + "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs" + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/cpi" + "github.com/open-component-model/ocm/pkg/blobaccess" + mavenblob "github.com/open-component-model/ocm/pkg/blobaccess/maven" + "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" + "github.com/open-component-model/ocm/pkg/maven" +) + +type Spec struct { + cpi.PathSpec `json:",inline"` + // RepoUrl defines the url from which the artifact is downloaded. + RepoUrl string `json:"repoUrl,omitempty"` + + maven.Coordinates `json:",inline"` +} + +var _ inputs.InputSpec = (*Spec)(nil) + +func New(repoUrl, groupId, artifactId, version string, classifier, extension *string) *Spec { + return &Spec{ + PathSpec: cpi.NewPathSpec(TYPE, ""), + RepoUrl: repoUrl, + Coordinates: *maven.NewCoordinates(groupId, artifactId, version, + maven.WithOptionalClassifier(classifier), + maven.WithOptionalExtension(extension)), + } +} + +func NewForFilePath(filePath, groupId, artifactId, version string, classifier, extension *string) *Spec { + return &Spec{ + PathSpec: cpi.NewPathSpec(TYPE, filePath), + RepoUrl: "", + Coordinates: *maven.NewCoordinates(groupId, artifactId, version, + maven.WithOptionalClassifier(classifier), + maven.WithOptionalExtension(extension)), + } +} + +func (s *Spec) Validate(fldPath *field.Path, ctx inputs.Context, inputFilePath string) field.ErrorList { + var allErrs field.ErrorList + if s.RepoUrl == "" { + allErrs = s.PathSpec.Validate(fldPath, ctx, inputFilePath) + } else { + if s.Path != "" { + pathField := fldPath.Child("path") + allErrs = append(allErrs, field.Forbidden(pathField, "only path or repoUrl can be specified, not both")) + } + } + if s.ArtifactId == "" { + pathField := fldPath.Child("artifactId") + allErrs = append(allErrs, field.Invalid(pathField, s.ArtifactId, "no artifact id")) + } + if s.GroupId == "" { + pathField := fldPath.Child("groupId") + allErrs = append(allErrs, field.Invalid(pathField, s.GroupId, "no group id")) + } + if s.Version == "" { + pathField := fldPath.Child("version") + allErrs = append(allErrs, field.Invalid(pathField, s.GroupId, "no group id")) + } + + return allErrs +} + +func (s *Spec) GetBlob(ctx inputs.Context, info inputs.InputResourceInfo) (blobaccess.BlobAccess, string, error) { + var repo *maven.Repository + var err error + + fs := ctx.FileSystem() + if s.Path != "" { + inputInfo, inputPath, err := inputs.FileInfo(ctx, s.Path, info.InputFilePath) + if err != nil { + return nil, "", err + } + if !inputInfo.IsDir() { + return nil, "", fmt.Errorf("maven file repository must be a directory") + } + repo = maven.NewFileRepository(inputPath, fs) + } else { + repo, err = maven.NewUrlRepository(s.RepoUrl, fs) + if err != nil { + return nil, "", err + } + } + access, err := mavenblob.BlobAccessForMavenCoords(repo, &s.Coordinates, + mavenblob.WithCredentialContext(ctx), + mavenblob.WithLoggingContext(ctx), + mavenblob.WithCachingFileSystem(vfsattr.Get(ctx)), + ) + + return access, "", err +} diff --git a/pkg/contexts/ocm/accessmethods/mvn/suite_test.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/suite_test.go similarity index 72% rename from pkg/contexts/ocm/accessmethods/mvn/suite_test.go rename to cmds/ocm/commands/ocmcmds/common/inputs/types/maven/suite_test.go index c62cadc7b0..c3662b31b0 100644 --- a/pkg/contexts/ocm/accessmethods/mvn/suite_test.go +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/suite_test.go @@ -1,4 +1,4 @@ -package mvn_test +package maven_test import ( "testing" @@ -9,5 +9,5 @@ import ( func TestConfig(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "Maven (mvn) Test Suite") + RunSpecs(t, "Input Type maven") } diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/testdata/resources1.yaml b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/testdata/resources1.yaml new file mode 100644 index 0000000000..161a29b424 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/testdata/resources1.yaml @@ -0,0 +1,8 @@ +name: myblob +type: mavenArtifact +input: + type: maven + path: ../maven/testdata/.m2/repository + groupId: com.sap.cloud.sdk + artifactId: sdk-modules-bom + version: 5.7.0 \ No newline at end of file diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/type.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/type.go new file mode 100644 index 0000000000..7c80db8e33 --- /dev/null +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/type.go @@ -0,0 +1,43 @@ +package maven + +import ( + "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs" +) + +const TYPE = "maven" + +func init() { + inputs.DefaultInputTypeScheme.Register(inputs.NewInputType(TYPE, &Spec{}, usage, ConfigHandler())) +} + +const usage = ` +The repoUrl is the url pointing either to the http endpoint of a maven +repository (e.g. https://repo.maven.apache.org/maven2/) or to a file system based +maven repository (e.g. file://local/directory). + +This blob type specification supports the following fields: +- **repoUrl** *string* + + This REQUIRED property describes the url from which the resource is to be + accessed. + +- **groupId** *string* + + This REQUIRED property describes the groupId of a maven artifact. + +- **artifactId** *string* + + This REQUIRED property describes artifactId of a maven artifact. + +- **version** *string* + + This REQUIRED property describes the version of a maven artifact. + +- **classifier** *string* + + This OPTIONAL property describes the classifier of a maven artifact. + +- **extension** *string* + + This OPTIONAL property describes the extension of a maven artifact. +` diff --git a/cmds/ocm/commands/ocmcmds/common/options/schemaoption/option.go b/cmds/ocm/commands/ocmcmds/common/options/schemaoption/option.go index 46df9fc6ab..5e463f0058 100644 --- a/cmds/ocm/commands/ocmcmds/common/options/schemaoption/option.go +++ b/cmds/ocm/commands/ocmcmds/common/options/schemaoption/option.go @@ -2,12 +2,12 @@ package schemaoption import ( "github.com/mandelsoft/goutils/errors" - "github.com/open-component-model/ocm/pkg/errkind" "github.com/spf13/pflag" "github.com/open-component-model/ocm/cmds/ocm/pkg/options" "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + "github.com/open-component-model/ocm/pkg/errkind" "github.com/open-component-model/ocm/pkg/listformat" utils2 "github.com/open-component-model/ocm/pkg/utils" ) diff --git a/cmds/ocm/commands/ocmcmds/common/resources.go b/cmds/ocm/commands/ocmcmds/common/resources.go index d64c52e427..db8b5697b6 100644 --- a/cmds/ocm/commands/ocmcmds/common/resources.go +++ b/cmds/ocm/commands/ocmcmds/common/resources.go @@ -4,11 +4,10 @@ import ( "encoding/json" "fmt" - "github.com/mandelsoft/goutils/sliceutils" _ "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/inputs/types" - utils2 "github.com/open-component-model/ocm/pkg/utils" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/sliceutils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/spf13/pflag" "golang.org/x/text/cases" @@ -33,6 +32,7 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/comparch" "github.com/open-component-model/ocm/pkg/logging" "github.com/open-component-model/ocm/pkg/mime" + utils2 "github.com/open-component-model/ocm/pkg/utils" ) const ComponentVersionTag = "" diff --git a/cmds/ocm/commands/ocmcmds/common/utils.go b/cmds/ocm/commands/ocmcmds/common/utils.go index 27df8f52f2..5985d94681 100644 --- a/cmds/ocm/commands/ocmcmds/common/utils.go +++ b/cmds/ocm/commands/ocmcmds/common/utils.go @@ -5,7 +5,7 @@ import ( "strings" "github.com/mandelsoft/goutils/errors" - + "github.com/open-component-model/ocm/cmds/ocm/pkg/options" "github.com/open-component-model/ocm/pkg/contexts/clictx" "github.com/open-component-model/ocm/pkg/contexts/ocm" diff --git a/cmds/ocm/commands/ocmcmds/components/add/cmd.go b/cmds/ocm/commands/ocmcmds/components/add/cmd.go index cce645da04..648babe18a 100644 --- a/cmds/ocm/commands/ocmcmds/components/add/cmd.go +++ b/cmds/ocm/commands/ocmcmds/components/add/cmd.go @@ -3,12 +3,12 @@ package add import ( "fmt" + "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/general" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/mandelsoft/goutils/errors" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/formatoption" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/addhdlrs" diff --git a/cmds/ocm/commands/ocmcmds/components/download/cmd.go b/cmds/ocm/commands/ocmcmds/components/download/cmd.go index 76759a6bb2..1735291dad 100644 --- a/cmds/ocm/commands/ocmcmds/components/download/cmd.go +++ b/cmds/ocm/commands/ocmcmds/components/download/cmd.go @@ -4,9 +4,9 @@ import ( "path" "strings" + "github.com/mandelsoft/goutils/errors" "github.com/spf13/cobra" - "github.com/mandelsoft/goutils/errors" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/destoption" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/formatoption" ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" diff --git a/cmds/ocm/commands/ocmcmds/components/transfer/cmd.go b/cmds/ocm/commands/ocmcmds/components/transfer/cmd.go index 81c577ae13..f91a39b22d 100644 --- a/cmds/ocm/commands/ocmcmds/components/transfer/cmd.go +++ b/cmds/ocm/commands/ocmcmds/components/transfer/cmd.go @@ -4,12 +4,12 @@ import ( "encoding/json" "fmt" + "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/maputils" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/mandelsoft/goutils/errors" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/closureoption" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/formatoption" ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" diff --git a/cmds/ocm/commands/ocmcmds/ctf/transfer/cmd.go b/cmds/ocm/commands/ocmcmds/ctf/transfer/cmd.go index beb4daa7e7..d57aefdaeb 100644 --- a/cmds/ocm/commands/ocmcmds/ctf/transfer/cmd.go +++ b/cmds/ocm/commands/ocmcmds/ctf/transfer/cmd.go @@ -1,9 +1,9 @@ package transfer import ( + "github.com/mandelsoft/goutils/errors" "github.com/spf13/cobra" - "github.com/mandelsoft/goutils/errors" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/closureoption" "github.com/open-component-model/ocm/cmds/ocm/commands/common/options/formatoption" ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" diff --git a/cmds/ocm/commands/ocmcmds/plugins/install/cmd.go b/cmds/ocm/commands/ocmcmds/plugins/install/cmd.go index d5b4182cdb..2462191b93 100644 --- a/cmds/ocm/commands/ocmcmds/plugins/install/cmd.go +++ b/cmds/ocm/commands/ocmcmds/plugins/install/cmd.go @@ -3,10 +3,10 @@ package install import ( "fmt" + "github.com/mandelsoft/goutils/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/mandelsoft/goutils/errors" ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/handlers/pluginhdlr" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/repooption" diff --git a/cmds/ocm/commands/toicmds/package/bootstrap/cmd.go b/cmds/ocm/commands/toicmds/package/bootstrap/cmd.go index 96554e0287..8555d8bdde 100644 --- a/cmds/ocm/commands/toicmds/package/bootstrap/cmd.go +++ b/cmds/ocm/commands/toicmds/package/bootstrap/cmd.go @@ -3,11 +3,11 @@ package bootstrap import ( "fmt" + "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/mandelsoft/goutils/errors" ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/handlers/comphdlr" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/lookupoption" diff --git a/cmds/ocm/commands/toicmds/package/describe/cmd.go b/cmds/ocm/commands/toicmds/package/describe/cmd.go index 994570c0c7..cccf87782c 100644 --- a/cmds/ocm/commands/toicmds/package/describe/cmd.go +++ b/cmds/ocm/commands/toicmds/package/describe/cmd.go @@ -4,9 +4,9 @@ import ( "fmt" "strings" + "github.com/mandelsoft/goutils/errors" "github.com/spf13/cobra" - "github.com/mandelsoft/goutils/errors" ocmcommon "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/handlers/comphdlr" "github.com/open-component-model/ocm/cmds/ocm/commands/ocmcmds/common/options/lookupoption" diff --git a/cmds/ocm/commands/verbs/controller/cmd.go b/cmds/ocm/commands/verbs/controller/cmd.go index 3ad8733b2c..a79e2741f7 100644 --- a/cmds/ocm/commands/verbs/controller/cmd.go +++ b/cmds/ocm/commands/verbs/controller/cmd.go @@ -1,11 +1,11 @@ package controller import ( - "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/uninstall" "github.com/spf13/cobra" "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/install" "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/names" + "github.com/open-component-model/ocm/cmds/ocm/commands/controllercmds/uninstall" "github.com/open-component-model/ocm/cmds/ocm/pkg/utils" "github.com/open-component-model/ocm/pkg/contexts/clictx" ) diff --git a/cmds/ocm/pkg/utils/command.go b/cmds/ocm/pkg/utils/command.go index aec015928b..212cd13c7d 100644 --- a/cmds/ocm/pkg/utils/command.go +++ b/cmds/ocm/pkg/utils/command.go @@ -4,10 +4,10 @@ import ( "reflect" "strings" + "github.com/mandelsoft/goutils/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" - "github.com/mandelsoft/goutils/errors" "github.com/open-component-model/ocm/cmds/ocm/pkg/options" "github.com/open-component-model/ocm/pkg/cobrautils" "github.com/open-component-model/ocm/pkg/contexts/clictx" diff --git a/cmds/ocm/pkg/utils/handling.go b/cmds/ocm/pkg/utils/handling.go index d0592950c1..ba2d2193a1 100644 --- a/cmds/ocm/pkg/utils/handling.go +++ b/cmds/ocm/pkg/utils/handling.go @@ -6,6 +6,7 @@ import ( "reflect" "github.com/mandelsoft/goutils/errors" + "github.com/open-component-model/ocm/cmds/ocm/pkg/output" ) diff --git a/docs/pluginreference/plugin_accessmethod_compose.md b/docs/pluginreference/plugin_accessmethod_compose.md index d9c0455651..e451f8f7c7 100644 --- a/docs/pluginreference/plugin_accessmethod_compose.md +++ b/docs/pluginreference/plugin_accessmethod_compose.md @@ -35,20 +35,21 @@ by the plugin name. The following predefined option types can be used: - - accessClassifier: [*string*] mvn classifier - - accessExtension: [*string*] mvn extension name - - accessGroup: [*string*] GroupID or namespace - accessHostname: [*string*] hostname used for access - accessPackage: [*string*] package or object name - accessRegistry: [*string*] registry base URL - accessRepository: [*string*] repository URL - accessVersion: [*string*] version for access specification + - artifactId: [*string*] maven artifact id - body: [*string*] body of a http request - bucket: [*string*] bucket name + - classifier: [*string*] maven classifier - comment: [*string*] comment field value - commit: [*string*] git commit id - digest: [*string*] blob digest + - extension: [*string*] maven extension name - globalAccess: [*map[string]YAML*] access specification for global access + - groupId: [*string*] maven group id - header: [*string:string,string*] http headers - hint: [*string*] (repository) hint for local artifacts - mediaType: [*string*] media type for artifact blob representation diff --git a/docs/pluginreference/plugin_descriptor.md b/docs/pluginreference/plugin_descriptor.md index c3ecbdd8a4..e2c05f2bae 100644 --- a/docs/pluginreference/plugin_descriptor.md +++ b/docs/pluginreference/plugin_descriptor.md @@ -120,20 +120,21 @@ It uses the following fields: The following predefined option types can be used: - - accessClassifier: [*string*] mvn classifier - - accessExtension: [*string*] mvn extension name - - accessGroup: [*string*] GroupID or namespace - accessHostname: [*string*] hostname used for access - accessPackage: [*string*] package or object name - accessRegistry: [*string*] registry base URL - accessRepository: [*string*] repository URL - accessVersion: [*string*] version for access specification + - artifactId: [*string*] maven artifact id - body: [*string*] body of a http request - bucket: [*string*] bucket name + - classifier: [*string*] maven classifier - comment: [*string*] comment field value - commit: [*string*] git commit id - digest: [*string*] blob digest + - extension: [*string*] maven extension name - globalAccess: [*map[string]YAML*] access specification for global access + - groupId: [*string*] maven group id - header: [*string:string,string*] http headers - hint: [*string*] (repository) hint for local artifacts - mediaType: [*string*] media type for artifact blob representation diff --git a/docs/pluginreference/plugin_valueset_compose.md b/docs/pluginreference/plugin_valueset_compose.md index 09bf007037..f7513c805b 100644 --- a/docs/pluginreference/plugin_valueset_compose.md +++ b/docs/pluginreference/plugin_valueset_compose.md @@ -35,20 +35,21 @@ by the plugin name. The following predefined option types can be used: - - accessClassifier: [*string*] mvn classifier - - accessExtension: [*string*] mvn extension name - - accessGroup: [*string*] GroupID or namespace - accessHostname: [*string*] hostname used for access - accessPackage: [*string*] package or object name - accessRegistry: [*string*] registry base URL - accessRepository: [*string*] repository URL - accessVersion: [*string*] version for access specification + - artifactId: [*string*] maven artifact id - body: [*string*] body of a http request - bucket: [*string*] bucket name + - classifier: [*string*] maven classifier - comment: [*string*] comment field value - commit: [*string*] git commit id - digest: [*string*] blob digest + - extension: [*string*] maven extension name - globalAccess: [*map[string]YAML*] access specification for global access + - groupId: [*string*] maven group id - header: [*string:string,string*] http headers - hint: [*string*] (repository) hint for local artifacts - mediaType: [*string*] media type for artifact blob representation diff --git a/docs/reference/ocm_add_resource-configuration.md b/docs/reference/ocm_add_resource-configuration.md index 679bcc2f27..533a494438 100644 --- a/docs/reference/ocm_add_resource-configuration.md +++ b/docs/reference/ocm_add_resource-configuration.md @@ -24,20 +24,21 @@ resource-configuration, resourceconfig, rsccfg, rcfg ``` --access YAML blob access specification (YAML) - --accessClassifier string mvn classifier - --accessExtension string mvn extension name - --accessGroup string GroupID or namespace --accessHostname string hostname used for access --accessPackage string package or object name --accessRegistry string registry base URL --accessRepository string repository URL --accessType string type of blob access specification --accessVersion string version for access specification + --artifactId string maven artifact id --body string body of a http request --bucket string bucket name + --classifier string maven classifier --commit string git commit id --digest string blob digest + --extension string maven extension name --globalAccess YAML access specification for global access + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --mediaType string media type for artifact blob representation @@ -53,7 +54,11 @@ resource-configuration, resourceconfig, rsccfg, rcfg #### Input Specification Options ``` + --artifactId string maven artifact id --body string body of a http request + --classifier string maven classifier + --extension string maven extension name + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --input YAML blob input specification (YAML) @@ -368,6 +373,40 @@ with the field type in the input field: Options used to configure fields: --hint, --inputCompress, --inputHelmRepository, --inputPath, --inputVersion, --mediaType +- Input type maven + + The repoUrl is the url pointing either to the http endpoint of a maven + repository (e.g. https://repo.maven.apache.org/maven2/) or to a file system based + maven repository (e.g. file://local/directory). + + This blob type specification supports the following fields: + - **repoUrl** *string* + + This REQUIRED property describes the url from which the resource is to be + accessed. + + - **groupId** *string* + + This REQUIRED property describes the groupId of a maven artifact. + + - **artifactId** *string* + + This REQUIRED property describes artifactId of a maven artifact. + + - **version** *string* + + This REQUIRED property describes the version of a maven artifact. + + - **classifier** *string* + + This OPTIONAL property describes the classifier of a maven artifact. + + - **extension** *string* + + This OPTIONAL property describes the extension of a maven artifact. + + Options used to configure fields: --artifactId, --classifier, --extension, --groupId, --inputPath, --inputVersion, --url + - Input type ociArtifact The path must denote an OCI image reference. @@ -683,40 +722,40 @@ shown below. Options used to configure fields: --globalAccess, --hint, --mediaType, --reference -- Access type mvn +- Access type maven - This method implements the access of a Maven (mvn) artifact in a Maven repository. + This method implements the access of a Maven artifact in a Maven repository. The following versions are supported: - Version v1 The type specific specification fields are: - - **repository** *string* + - **repoUrl** *string* - Base URL of the Maven (mvn) repository + URL of the Maven repository - **groupId** *string* - The groupId of the Maven (mvn) artifact + The groupId of the Maven artifact - **artifactId** *string* - The artifactId of the Maven (mvn) artifact + The artifactId of the Maven artifact - **version** *string* - The version name of the Maven (mvn) artifact + The version name of the Maven artifact - **classifier** *string* - The optional classifier of the Maven (mvn) artifact + The optional classifier of the Maven artifact - **extension** *string* - The optional extension of the Maven (mvn) artifact + The optional extension of the Maven artifact - Options used to configure fields: --accessClassifier, --accessExtension, --accessGroup, --accessPackage, --accessRepository, --accessVersion + Options used to configure fields: --accessRepository, --accessVersion, --artifactId, --classifier, --extension, --groupId - Access type none diff --git a/docs/reference/ocm_add_resources.md b/docs/reference/ocm_add_resources.md index 9e8878f8e8..944f87bf64 100644 --- a/docs/reference/ocm_add_resources.md +++ b/docs/reference/ocm_add_resources.md @@ -30,20 +30,21 @@ resources, resource, res, r ``` --access YAML blob access specification (YAML) - --accessClassifier string mvn classifier - --accessExtension string mvn extension name - --accessGroup string GroupID or namespace --accessHostname string hostname used for access --accessPackage string package or object name --accessRegistry string registry base URL --accessRepository string repository URL --accessType string type of blob access specification --accessVersion string version for access specification + --artifactId string maven artifact id --body string body of a http request --bucket string bucket name + --classifier string maven classifier --commit string git commit id --digest string blob digest + --extension string maven extension name --globalAccess YAML access specification for global access + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --mediaType string media type for artifact blob representation @@ -59,7 +60,11 @@ resources, resource, res, r #### Input Specification Options ``` + --artifactId string maven artifact id --body string body of a http request + --classifier string maven classifier + --extension string maven extension name + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --input YAML blob input specification (YAML) @@ -378,6 +383,40 @@ with the field type in the input field: Options used to configure fields: --hint, --inputCompress, --inputHelmRepository, --inputPath, --inputVersion, --mediaType +- Input type maven + + The repoUrl is the url pointing either to the http endpoint of a maven + repository (e.g. https://repo.maven.apache.org/maven2/) or to a file system based + maven repository (e.g. file://local/directory). + + This blob type specification supports the following fields: + - **repoUrl** *string* + + This REQUIRED property describes the url from which the resource is to be + accessed. + + - **groupId** *string* + + This REQUIRED property describes the groupId of a maven artifact. + + - **artifactId** *string* + + This REQUIRED property describes artifactId of a maven artifact. + + - **version** *string* + + This REQUIRED property describes the version of a maven artifact. + + - **classifier** *string* + + This OPTIONAL property describes the classifier of a maven artifact. + + - **extension** *string* + + This OPTIONAL property describes the extension of a maven artifact. + + Options used to configure fields: --artifactId, --classifier, --extension, --groupId, --inputPath, --inputVersion, --url + - Input type ociArtifact The path must denote an OCI image reference. @@ -693,40 +732,40 @@ shown below. Options used to configure fields: --globalAccess, --hint, --mediaType, --reference -- Access type mvn +- Access type maven - This method implements the access of a Maven (mvn) artifact in a Maven repository. + This method implements the access of a Maven artifact in a Maven repository. The following versions are supported: - Version v1 The type specific specification fields are: - - **repository** *string* + - **repoUrl** *string* - Base URL of the Maven (mvn) repository + URL of the Maven repository - **groupId** *string* - The groupId of the Maven (mvn) artifact + The groupId of the Maven artifact - **artifactId** *string* - The artifactId of the Maven (mvn) artifact + The artifactId of the Maven artifact - **version** *string* - The version name of the Maven (mvn) artifact + The version name of the Maven artifact - **classifier** *string* - The optional classifier of the Maven (mvn) artifact + The optional classifier of the Maven artifact - **extension** *string* - The optional extension of the Maven (mvn) artifact + The optional extension of the Maven artifact - Options used to configure fields: --accessClassifier, --accessExtension, --accessGroup, --accessPackage, --accessRepository, --accessVersion + Options used to configure fields: --accessRepository, --accessVersion, --artifactId, --classifier, --extension, --groupId - Access type none diff --git a/docs/reference/ocm_add_source-configuration.md b/docs/reference/ocm_add_source-configuration.md index f7d2b4fc32..7ebe3f1241 100644 --- a/docs/reference/ocm_add_source-configuration.md +++ b/docs/reference/ocm_add_source-configuration.md @@ -24,20 +24,21 @@ source-configuration, sourceconfig, srccfg, scfg ``` --access YAML blob access specification (YAML) - --accessClassifier string mvn classifier - --accessExtension string mvn extension name - --accessGroup string GroupID or namespace --accessHostname string hostname used for access --accessPackage string package or object name --accessRegistry string registry base URL --accessRepository string repository URL --accessType string type of blob access specification --accessVersion string version for access specification + --artifactId string maven artifact id --body string body of a http request --bucket string bucket name + --classifier string maven classifier --commit string git commit id --digest string blob digest + --extension string maven extension name --globalAccess YAML access specification for global access + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --mediaType string media type for artifact blob representation @@ -53,7 +54,11 @@ source-configuration, sourceconfig, srccfg, scfg #### Input Specification Options ``` + --artifactId string maven artifact id --body string body of a http request + --classifier string maven classifier + --extension string maven extension name + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --input YAML blob input specification (YAML) @@ -368,6 +373,40 @@ with the field type in the input field: Options used to configure fields: --hint, --inputCompress, --inputHelmRepository, --inputPath, --inputVersion, --mediaType +- Input type maven + + The repoUrl is the url pointing either to the http endpoint of a maven + repository (e.g. https://repo.maven.apache.org/maven2/) or to a file system based + maven repository (e.g. file://local/directory). + + This blob type specification supports the following fields: + - **repoUrl** *string* + + This REQUIRED property describes the url from which the resource is to be + accessed. + + - **groupId** *string* + + This REQUIRED property describes the groupId of a maven artifact. + + - **artifactId** *string* + + This REQUIRED property describes artifactId of a maven artifact. + + - **version** *string* + + This REQUIRED property describes the version of a maven artifact. + + - **classifier** *string* + + This OPTIONAL property describes the classifier of a maven artifact. + + - **extension** *string* + + This OPTIONAL property describes the extension of a maven artifact. + + Options used to configure fields: --artifactId, --classifier, --extension, --groupId, --inputPath, --inputVersion, --url + - Input type ociArtifact The path must denote an OCI image reference. @@ -683,40 +722,40 @@ shown below. Options used to configure fields: --globalAccess, --hint, --mediaType, --reference -- Access type mvn +- Access type maven - This method implements the access of a Maven (mvn) artifact in a Maven repository. + This method implements the access of a Maven artifact in a Maven repository. The following versions are supported: - Version v1 The type specific specification fields are: - - **repository** *string* + - **repoUrl** *string* - Base URL of the Maven (mvn) repository + URL of the Maven repository - **groupId** *string* - The groupId of the Maven (mvn) artifact + The groupId of the Maven artifact - **artifactId** *string* - The artifactId of the Maven (mvn) artifact + The artifactId of the Maven artifact - **version** *string* - The version name of the Maven (mvn) artifact + The version name of the Maven artifact - **classifier** *string* - The optional classifier of the Maven (mvn) artifact + The optional classifier of the Maven artifact - **extension** *string* - The optional extension of the Maven (mvn) artifact + The optional extension of the Maven artifact - Options used to configure fields: --accessClassifier, --accessExtension, --accessGroup, --accessPackage, --accessRepository, --accessVersion + Options used to configure fields: --accessRepository, --accessVersion, --artifactId, --classifier, --extension, --groupId - Access type none diff --git a/docs/reference/ocm_add_sources.md b/docs/reference/ocm_add_sources.md index 746d02c5ee..d2120df821 100644 --- a/docs/reference/ocm_add_sources.md +++ b/docs/reference/ocm_add_sources.md @@ -29,20 +29,21 @@ sources, source, src, s ``` --access YAML blob access specification (YAML) - --accessClassifier string mvn classifier - --accessExtension string mvn extension name - --accessGroup string GroupID or namespace --accessHostname string hostname used for access --accessPackage string package or object name --accessRegistry string registry base URL --accessRepository string repository URL --accessType string type of blob access specification --accessVersion string version for access specification + --artifactId string maven artifact id --body string body of a http request --bucket string bucket name + --classifier string maven classifier --commit string git commit id --digest string blob digest + --extension string maven extension name --globalAccess YAML access specification for global access + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --mediaType string media type for artifact blob representation @@ -58,7 +59,11 @@ sources, source, src, s #### Input Specification Options ``` + --artifactId string maven artifact id --body string body of a http request + --classifier string maven classifier + --extension string maven extension name + --groupId string maven group id --header :,,... http headers (default {}) --hint string (repository) hint for local artifacts --input YAML blob input specification (YAML) @@ -376,6 +381,40 @@ with the field type in the input field: Options used to configure fields: --hint, --inputCompress, --inputHelmRepository, --inputPath, --inputVersion, --mediaType +- Input type maven + + The repoUrl is the url pointing either to the http endpoint of a maven + repository (e.g. https://repo.maven.apache.org/maven2/) or to a file system based + maven repository (e.g. file://local/directory). + + This blob type specification supports the following fields: + - **repoUrl** *string* + + This REQUIRED property describes the url from which the resource is to be + accessed. + + - **groupId** *string* + + This REQUIRED property describes the groupId of a maven artifact. + + - **artifactId** *string* + + This REQUIRED property describes artifactId of a maven artifact. + + - **version** *string* + + This REQUIRED property describes the version of a maven artifact. + + - **classifier** *string* + + This OPTIONAL property describes the classifier of a maven artifact. + + - **extension** *string* + + This OPTIONAL property describes the extension of a maven artifact. + + Options used to configure fields: --artifactId, --classifier, --extension, --groupId, --inputPath, --inputVersion, --url + - Input type ociArtifact The path must denote an OCI image reference. @@ -691,40 +730,40 @@ shown below. Options used to configure fields: --globalAccess, --hint, --mediaType, --reference -- Access type mvn +- Access type maven - This method implements the access of a Maven (mvn) artifact in a Maven repository. + This method implements the access of a Maven artifact in a Maven repository. The following versions are supported: - Version v1 The type specific specification fields are: - - **repository** *string* + - **repoUrl** *string* - Base URL of the Maven (mvn) repository + URL of the Maven repository - **groupId** *string* - The groupId of the Maven (mvn) artifact + The groupId of the Maven artifact - **artifactId** *string* - The artifactId of the Maven (mvn) artifact + The artifactId of the Maven artifact - **version** *string* - The version name of the Maven (mvn) artifact + The version name of the Maven artifact - **classifier** *string* - The optional classifier of the Maven (mvn) artifact + The optional classifier of the Maven artifact - **extension** *string* - The optional extension of the Maven (mvn) artifact + The optional extension of the Maven artifact - Options used to configure fields: --accessClassifier, --accessExtension, --accessGroup, --accessPackage, --accessRepository, --accessVersion + Options used to configure fields: --accessRepository, --accessVersion, --artifactId, --classifier, --extension, --groupId - Access type none diff --git a/docs/reference/ocm_logging.md b/docs/reference/ocm_logging.md index f72d0b3fcb..1f6b89b152 100644 --- a/docs/reference/ocm_logging.md +++ b/docs/reference/ocm_logging.md @@ -24,10 +24,11 @@ The following *realms* are used by the command line tool: - ocm/compdesc: component descriptor handling - ocm/config: configuration management - ocm/context: context lifecycle + - ocm/credentials: Credentials - ocm/credentials/dockerconfig: docker config handling as credential repository - ocm/credentials/vault: HashiCorp Vault Access - ocm/downloader: Downloaders - - ocm/mvn: Maven repository + - ocm/maven: Maven repository - ocm/npm: NPM registry - ocm/oci/mapping: OCM to OCI Registry Mapping - ocm/oci/ocireg: OCI repository handling diff --git a/docs/reference/ocm_ocm-accessmethods.md b/docs/reference/ocm_ocm-accessmethods.md index 1c02801075..8ae09db829 100644 --- a/docs/reference/ocm_ocm-accessmethods.md +++ b/docs/reference/ocm_ocm-accessmethods.md @@ -183,40 +183,40 @@ shown below. Options used to configure fields: --globalAccess, --hint, --mediaType, --reference -- Access type mvn +- Access type maven - This method implements the access of a Maven (mvn) artifact in a Maven repository. + This method implements the access of a Maven artifact in a Maven repository. The following versions are supported: - Version v1 The type specific specification fields are: - - **repository** *string* + - **repoUrl** *string* - Base URL of the Maven (mvn) repository + URL of the Maven repository - **groupId** *string* - The groupId of the Maven (mvn) artifact + The groupId of the Maven artifact - **artifactId** *string* - The artifactId of the Maven (mvn) artifact + The artifactId of the Maven artifact - **version** *string* - The version name of the Maven (mvn) artifact + The version name of the Maven artifact - **classifier** *string* - The optional classifier of the Maven (mvn) artifact + The optional classifier of the Maven artifact - **extension** *string* - The optional extension of the Maven (mvn) artifact + The optional extension of the Maven artifact - Options used to configure fields: --accessClassifier, --accessExtension, --accessGroup, --accessPackage, --accessRepository, --accessVersion + Options used to configure fields: --accessRepository, --accessVersion, --artifactId, --classifier, --extension, --groupId - Access type none diff --git a/docs/reference/ocm_ocm-uploadhandlers.md b/docs/reference/ocm_ocm-uploadhandlers.md index d3b3219957..5c6ac57448 100644 --- a/docs/reference/ocm_ocm-uploadhandlers.md +++ b/docs/reference/ocm_ocm-uploadhandlers.md @@ -73,14 +73,14 @@ The following handler names are possible: sub namespace of the form <plugin name>/<handler> - - ocm/mvnArtifact: uploading mvn artifacts + - ocm/mavenArtifact: uploading maven artifacts - The ocm/mvnArtifact uploader is able to upload mvn artifacts (whole GAV only!) - as artifact archive according to the mvn artifact spec. + The ocm/mavenArtifact uploader is able to upload maven artifacts (whole GAV only!) + as artifact archive according to the maven artifact spec. If registered the default mime type is: application/x-tgz It accepts a plain string for the URL or a config with the following field: - 'url': the URL of the mvn repository. + 'url': the URL of the maven repository. diff --git a/docs/reference/ocm_transfer_commontransportarchive.md b/docs/reference/ocm_transfer_commontransportarchive.md index c3f6c2d20a..eaa4b1f1fb 100644 --- a/docs/reference/ocm_transfer_commontransportarchive.md +++ b/docs/reference/ocm_transfer_commontransportarchive.md @@ -147,14 +147,14 @@ The uploader name may be a path expression with the following possibilities: sub namespace of the form <plugin name>/<handler> - - ocm/mvnArtifact: uploading mvn artifacts + - ocm/mavenArtifact: uploading maven artifacts - The ocm/mvnArtifact uploader is able to upload mvn artifacts (whole GAV only!) - as artifact archive according to the mvn artifact spec. + The ocm/mavenArtifact uploader is able to upload maven artifacts (whole GAV only!) + as artifact archive according to the maven artifact spec. If registered the default mime type is: application/x-tgz It accepts a plain string for the URL or a config with the following field: - 'url': the URL of the mvn repository. + 'url': the URL of the maven repository. diff --git a/docs/reference/ocm_transfer_componentversions.md b/docs/reference/ocm_transfer_componentversions.md index f251617d44..b58c17b15f 100644 --- a/docs/reference/ocm_transfer_componentversions.md +++ b/docs/reference/ocm_transfer_componentversions.md @@ -204,14 +204,14 @@ The uploader name may be a path expression with the following possibilities: sub namespace of the form <plugin name>/<handler> - - ocm/mvnArtifact: uploading mvn artifacts + - ocm/mavenArtifact: uploading maven artifacts - The ocm/mvnArtifact uploader is able to upload mvn artifacts (whole GAV only!) - as artifact archive according to the mvn artifact spec. + The ocm/mavenArtifact uploader is able to upload maven artifacts (whole GAV only!) + as artifact archive according to the maven artifact spec. If registered the default mime type is: application/x-tgz It accepts a plain string for the URL or a config with the following field: - 'url': the URL of the mvn repository. + 'url': the URL of the maven repository. diff --git a/examples/lib/tour/01-getting-started/README.md b/examples/lib/tour/01-getting-started/README.md index 76423db018..5f807a67f3 100644 --- a/examples/lib/tour/01-getting-started/README.md +++ b/examples/lib/tour/01-getting-started/README.md @@ -164,32 +164,32 @@ differ, because the code always describes the latest version): ``` resources of the latest version: - version: 0.9.0 + version: 0.10.0 provider: ocm.software 1: name: ocmcli extra identity: "architecture"="amd64","os"="linux" resource type: executable - access: Local blob sha256:1de1c90f23d0a3dbb8d8646f09380f1da257f9d10796b42dc4ef85e8df93a135[] + access: Local blob sha256:e2d8f578083e9317bd199b3f374b7ea60e7f28cf989e8d39ae0ea54ac4fa8847[] 2: name: ocmcli extra identity: "architecture"="arm64","os"="linux" resource type: executable - access: Local blob sha256:ca049bb09399020ce0822fd18c0a534ae0d02c3e0180f05dd4faccf61176a267[] + access: Local blob sha256:2acef3da732a6674fb047f3d60f0dabcbb60ffeb8dd362a169df97c4dc4489a8[] 3: name: ocmcli extra identity: "architecture"="arm64","os"="darwin" resource type: executable - access: Local blob sha256:1e32b3f1a08c72e3187b247f8931ea9d0554240fd452a4df129d6036c62b0476[] + access: Local blob sha256:b05fbc5e8aaa3622e2ecc39ead7f066030fd183c625b0dc202dbac8131f06d1d[] 4: name: ocmcli extra identity: "architecture"="amd64","os"="darwin" resource type: executable - access: Local blob sha256:04708d2f9845dd6d52f2b8f94e930f3a74a1a098b7ee401e001307d4b4fcc703[] + access: Local blob sha256:aec88249f7e5a395eaa18ac6017831b275c7de90d3c10f0cd9e572027ad6c6e9[] 5: name: ocmcli extra identity: "architecture"="amd64","os"="windows" resource type: executable - access: Local blob sha256:e8cf5dfd1ab02ab982e6f1a425d426fc1f7dc83e6385d26d0477525a4a66c629[] + access: Local blob sha256:cdbac49bd004aa2a8b89fafb9e845f45bfcfaab2df402296f55b403b9b1035a2[] 6: name: ocmcli-image extra identity: resource type: ociImage - access: OCI artifact ghcr.io/open-component-model/ocm/ocm.software/ocmcli/ocmcli-image:0.9.0 + access: OCI artifact ghcr.io/open-component-model/ocm/ocm.software/ocmcli/ocmcli-image:0.10.0 ``` Resources have some metadata, like their identity and a resource type. diff --git a/examples/lib/tour/02-composing-a-component-version/01-basic-componentversion-creation.go b/examples/lib/tour/02-composing-a-component-version/01-basic-componentversion-creation.go index 7284bcc274..da13cdc0bb 100644 --- a/examples/lib/tour/02-composing-a-component-version/01-basic-componentversion-creation.go +++ b/examples/lib/tour/02-composing-a-component-version/01-basic-componentversion-creation.go @@ -173,7 +173,7 @@ data: some very important data required to understand this component // The above case could also be written as follows: // --- begin setup by access --- res := textblob.ResourceAccess(cv.GetContext(), meta, yamldata, - textblob.WithimeType(mime.MIME_YAML)) + textblob.WithMimeType(mime.MIME_YAML)) err = cv.SetResourceAccess(res) if err != nil { return errors.Wrapf(err, "cannot add yaml document") diff --git a/examples/lib/tour/02-composing-a-component-version/README.md b/examples/lib/tour/02-composing-a-component-version/README.md index 74953c7385..effd262404 100644 --- a/examples/lib/tour/02-composing-a-component-version/README.md +++ b/examples/lib/tour/02-composing-a-component-version/README.md @@ -212,7 +212,7 @@ The above case could also be written as follows: ```go res := textblob.ResourceAccess(cv.GetContext(), meta, yamldata, - textblob.WithimeType(mime.MIME_YAML)) + textblob.WithMimeType(mime.MIME_YAML)) err = cv.SetResourceAccess(res) if err != nil { return errors.Wrapf(err, "cannot add yaml document") diff --git a/examples/lib/tour/03-working-with-credentials/common.go b/examples/lib/tour/03-working-with-credentials/common.go index 27aa3149db..86151feab0 100644 --- a/examples/lib/tour/03-working-with-credentials/common.go +++ b/examples/lib/tour/03-working-with-credentials/common.go @@ -136,7 +136,7 @@ data: some very important data required to understand this component // component version. // The above case could be written as follows, also: res := textblob.ResourceAccess(cv.GetContext(), meta, yamldata, - textblob.WithimeType(mime.MIME_YAML)) + textblob.WithMimeType(mime.MIME_YAML)) err = cv.SetResourceAccess(res) if err != nil { return errors.Wrapf(err, "cannot add yaml document") diff --git a/examples/lib/tour/05-transporting-component-versions/common.go b/examples/lib/tour/05-transporting-component-versions/common.go index e170b62eec..81fdab6c30 100644 --- a/examples/lib/tour/05-transporting-component-versions/common.go +++ b/examples/lib/tour/05-transporting-component-versions/common.go @@ -135,7 +135,7 @@ data: some very important data required to understand this component // component version. // The above case could be written as follows, also: res := textblob.ResourceAccess(cv.GetContext(), meta, yamldata, - textblob.WithimeType(mime.MIME_YAML)) + textblob.WithMimeType(mime.MIME_YAML)) err = cv.SetResourceAccess(res) if err != nil { return errors.Wrapf(err, "cannot add yaml document") diff --git a/examples/lib/tour/06-signing-component-versions/common.go b/examples/lib/tour/06-signing-component-versions/common.go index 094ae6c094..f0d013f572 100644 --- a/examples/lib/tour/06-signing-component-versions/common.go +++ b/examples/lib/tour/06-signing-component-versions/common.go @@ -141,7 +141,7 @@ data: some very important data required to understand this component // component version. // The above case could be written as follows, also: res := textblob.ResourceAccess(cv.GetContext(), meta, yamldata, - textblob.WithimeType(mime.MIME_YAML)) + textblob.WithMimeType(mime.MIME_YAML)) err = cv.SetResourceAccess(res) if err != nil { return errors.Wrapf(err, "cannot add yaml document") diff --git a/go.mod b/go.mod index df7787db42..84a8c9eeed 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.21 github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3 github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3 + github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 github.com/containerd/containerd v1.7.17 github.com/containerd/log v0.1.0 github.com/containers/image/v5 v5.31.0 @@ -38,7 +39,7 @@ require ( github.com/klauspost/compress v1.17.8 github.com/klauspost/pgzip v1.2.6 github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 - github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460 + github.com/mandelsoft/goutils v0.0.0-20240527090454-525d51156f92 github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf github.com/mandelsoft/spiff v1.7.0-beta-5 github.com/mandelsoft/vfs v0.4.3 diff --git a/go.sum b/go.sum index 8708b4b5d7..f635f11af8 100644 --- a/go.sum +++ b/go.sum @@ -681,8 +681,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3 h1:oo9nIgnyiBgYPbcZslRT4y29siuL5EoNJ/t1tr0xEVQ= github.com/mandelsoft/filepath v0.0.0-20240223090642-3e2777258aa3/go.mod h1:LxhqC7khDoRENwooP6f/vWvia9ivj6TqLYrR39zqkN0= -github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460 h1:q44fRqo/PC3eTexd8Q3pO2BTHTABVXsW6DBXRUhC97E= -github.com/mandelsoft/goutils v0.0.0-20240523093855-5385ed52b460/go.mod h1:EbNqk9JceSMq7MJuALB/vlOpoD4MAGE0TenM9TR+C0o= +github.com/mandelsoft/goutils v0.0.0-20240527090454-525d51156f92 h1:JKHpPtPpkCA7AVRv5trXmqAcncjbfkjiv4x7wGSJnEc= +github.com/mandelsoft/goutils v0.0.0-20240527090454-525d51156f92/go.mod h1:EbNqk9JceSMq7MJuALB/vlOpoD4MAGE0TenM9TR+C0o= github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf h1:WEmgzeArDbp6Aw34jmziMIE5ygo2zpl/atXRq3D7lSw= github.com/mandelsoft/logging v0.0.0-20240201091719-67180059d6bf/go.mod h1:uO460C1lIB3IOOgrbXhAlz3AKsOv4T2K6ALBn3PwuSg= github.com/mandelsoft/spiff v1.7.0-beta-5 h1:3kC10nTviDQhL8diSxp7i4IC2iSiDg6KPbH1CAq7Lfw= diff --git a/pkg/blobaccess/maven/access.go b/pkg/blobaccess/maven/access.go new file mode 100644 index 0000000000..b9b963f5d9 --- /dev/null +++ b/pkg/blobaccess/maven/access.go @@ -0,0 +1,38 @@ +package maven + +import ( + "github.com/mandelsoft/goutils/optionutils" + + "github.com/open-component-model/ocm/pkg/blobaccess" + "github.com/open-component-model/ocm/pkg/blobaccess/bpi" + "github.com/open-component-model/ocm/pkg/maven" +) + +func DataAccessForMaven(repo *maven.Repository, groupId, artifactId, version string, opts ...Option) (blobaccess.DataAccess, error) { + return BlobAccessForMaven(repo, groupId, artifactId, version, opts...) +} + +func BlobAccessForMaven(repo *maven.Repository, groupId, artifactId, version string, opts ...Option) (blobaccess.BlobAccess, error) { + eff := optionutils.EvalOptions(opts...) + s := &spec{ + coords: maven.NewCoordinates(groupId, artifactId, version, maven.WithOptionalClassifier(eff.Classifier), maven.WithOptionalExtension(eff.Extension)), + repo: repo, + options: eff, + } + return s.getBlobAccess() +} + +func BlobAccessForMavenCoords(repo *maven.Repository, coords *maven.Coordinates, opts ...Option) (blobaccess.BlobAccess, error) { + return BlobAccessForMaven(repo, coords.GroupId, coords.ArtifactId, coords.Version, optionutils.WithDefaults(opts, WithOptionalClassifier(coords.Classifier), WithOptionalExtension(coords.Extension))...) +} + +func BlobAccessProviderForMaven(repo *maven.Repository, groupId, artifactId, version string, opts ...Option) bpi.BlobAccessProvider { + return bpi.BlobAccessProviderFunction(func() (bpi.BlobAccess, error) { + b, err := BlobAccessForMaven(repo, groupId, artifactId, version, opts...) + return b, err + }) +} + +func BlobAccessProviderForMavenCoords(repo *maven.Repository, coords *maven.Coordinates, opts ...Option) bpi.BlobAccessProvider { + return BlobAccessProviderForMaven(repo, coords.GroupId, coords.ArtifactId, coords.Version, optionutils.WithDefaults(opts, WithOptionalClassifier(coords.Classifier), WithOptionalExtension(coords.Extension))...) +} diff --git a/pkg/blobaccess/maven/access_test.go b/pkg/blobaccess/maven/access_test.go new file mode 100644 index 0000000000..e2e10c96df --- /dev/null +++ b/pkg/blobaccess/maven/access_test.go @@ -0,0 +1,125 @@ +package maven_test + +import ( + "github.com/open-component-model/ocm/pkg/maven/maventest" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/env/builder" + . "github.com/open-component-model/ocm/pkg/testutils" + + me "github.com/open-component-model/ocm/pkg/blobaccess/maven" + "github.com/open-component-model/ocm/pkg/maven" + "github.com/open-component-model/ocm/pkg/utils/tarutils" +) + +const ( + MAVEN_PATH = "/testdata/.m2/repository" + FAIL_PATH = "/testdata/.m2/fail" + MAVEN_CENTRAL_ADDRESS = "repo.maven.apache.org:443" + MAVEN_CENTRAL = "https://repo.maven.apache.org/maven2/" + MAVEN_GROUP_ID = "maven" + MAVEN_ARTIFACT_ID = "maven" + MAVEN_VERSION = "1.1" +) + +var _ = Describe("blobaccess for maven", func() { + + Context("maven filesystem repository", func() { + var env *Builder + var repo *maven.Repository + + BeforeEach(func() { + env = NewBuilder(maventest.TestData()) + repo = maven.NewFileRepository(MAVEN_PATH, env.FileSystem()) + }) + + AfterEach(func() { + MustBeSuccessful(env.Cleanup()) + }) + + It("blobaccess for gav", func() { + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") + + b := Must(me.BlobAccessForMaven(repo, coords.GroupId, coords.ArtifactId, coords.Version, me.WithCachingFileSystem(env.FileSystem()))) + defer Close(b, "blobaccess") + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("sdk-modules-bom-5.7.0.pom", "sdk-modules-bom-5.7.0.jar", "sdk-modules-bom-5.7.0-random-content.txt", + "sdk-modules-bom-5.7.0-random-content.json", "sdk-modules-bom-5.7.0-sources.jar")) + }) + + It("blobaccess for files with the same classifier", func() { + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", + maven.WithClassifier("random-content")) + + b := Must(me.BlobAccessForMavenCoords(repo, coords, me.WithCachingFileSystem(env.FileSystem()))) + defer Close(b, "blobaccess") + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("sdk-modules-bom-5.7.0-random-content.txt", + "sdk-modules-bom-5.7.0-random-content.json")) + }) + + It("blobaccess for files with empty classifier", func() { + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", + maven.WithClassifier("")) + + b := Must(me.BlobAccessForMavenCoords(repo, coords, me.WithCachingFileSystem(env.FileSystem()))) + defer Close(b, "blobaccess") + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("sdk-modules-bom-5.7.0.pom", + "sdk-modules-bom-5.7.0.jar")) + }) + + It("blobaccess for files with extension", func() { + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", + maven.WithExtension("jar")) + + b := Must(me.BlobAccessForMavenCoords(repo, coords, me.WithCachingFileSystem(env.FileSystem()))) + defer Close(b, "blobaccess") + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("sdk-modules-bom-5.7.0-sources.jar", + "sdk-modules-bom-5.7.0.jar")) + }) + + It("blobaccess for files with extension", func() { + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", + maven.WithExtension("txt")) + + b := Must(me.BlobAccessForMavenCoords(repo, coords, me.WithCachingFileSystem(env.FileSystem()))) + defer Close(b, "blobaccess") + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf("sdk-modules-bom-5.7.0-random-content.txt")) + }) + + It("blobaccess for a single file with classifier and extension", func() { + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", + maven.WithClassifier("random-content"), maven.WithExtension("json")) + + b := Must(me.BlobAccessForMavenCoords(repo, coords, me.WithCachingFileSystem(env.FileSystem()))) + defer Close(b, "blobaccess") + Expect(string(Must(b.Get()))).To(Equal(`{"some": "test content"}`)) + }) + }) + + Context("maven http repository", func() { + if PingTCPServer(MAVEN_CENTRAL_ADDRESS, time.Second) == nil { + var coords *maven.Coordinates + BeforeEach(func() { + coords = maven.NewCoordinates(MAVEN_GROUP_ID, MAVEN_ARTIFACT_ID, MAVEN_VERSION) + }) + It("blobaccess for gav", func() { + repo := Must(maven.NewUrlRepository(MAVEN_CENTRAL)) + b := Must(me.BlobAccessForMavenCoords(repo, coords)) + defer Close(b, "blobaccess") + files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) + Expect(files).To(ConsistOf( + "maven-1.1-RC1.javadoc.javadoc.jar", + "maven-1.1-sources.jar", + "maven-1.1.jar", + "maven-1.1.pom", + )) + }) + } + }) +}) diff --git a/pkg/blobaccess/maven/maven.go b/pkg/blobaccess/maven/maven.go new file mode 100644 index 0000000000..5d334937bb --- /dev/null +++ b/pkg/blobaccess/maven/maven.go @@ -0,0 +1,36 @@ +package maven + +import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/mandelsoft/vfs/pkg/vfs" + + "github.com/open-component-model/ocm/pkg/maven" +) + +type ( + BlobMeta = maven.FileMeta + Repository = maven.Repository + Coordinates = maven.Coordinates +) + +func NewFileRepository(path string, fss ...vfs.FileSystem) *Repository { + return maven.NewFileRepository(path, fss...) +} + +func NewUrlRepository(repoUrl string, fss ...vfs.FileSystem) (*Repository, error) { + return maven.NewUrlRepository(repoUrl, fss...) +} + +type optionwrapper struct { + options *Options +} + +func (o *optionwrapper) ApplyTo(opts *Coordinates) { + maven.WithOptionalExtension(o.options.Extension).ApplyTo(opts) + maven.WithOptionalClassifier(o.options.Classifier).ApplyTo(opts) +} + +func NewCoordinates(groupId, artifactId, version string, opts ...Option) *Coordinates { + eff := optionutils.EvalOptions(opts...) + return maven.NewCoordinates(groupId, artifactId, version, &optionwrapper{eff}) +} diff --git a/pkg/blobaccess/maven/options.go b/pkg/blobaccess/maven/options.go new file mode 100644 index 0000000000..8ceae8c2ea --- /dev/null +++ b/pkg/blobaccess/maven/options.go @@ -0,0 +1,204 @@ +package maven + +import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/mandelsoft/logging" + "github.com/mandelsoft/vfs/pkg/vfs" + + "github.com/open-component-model/ocm/pkg/contexts/credentials" + "github.com/open-component-model/ocm/pkg/contexts/datacontext" + "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/tmpcache" + ocmlog "github.com/open-component-model/ocm/pkg/logging" + "github.com/open-component-model/ocm/pkg/maven" +) + +type Option = optionutils.Option[*Options] + +type Options struct { + CredentialContext credentials.Context + LoggingContext logging.Context + CachingContext datacontext.Context + CachingFileSystem vfs.FileSystem + CachingPath string + // Credentials allows to pass credentials and certificates for the http communication + Credentials credentials.Credentials + // Classifier defines the classifier of the maven file coordinates + Classifier *string + // Extension defines the extension of the maven file coordinates + Extension *string +} + +func (o *Options) Logger(keyValuePairs ...interface{}) logging.Logger { + return ocmlog.LogContext(o.LoggingContext, o.CredentialContext).Logger(maven.REALM).WithValues(keyValuePairs...) +} + +func (o *Options) Cache() *tmpcache.Attribute { + if o.CachingPath != "" { + return tmpcache.New(o.CachingPath, o.CachingFileSystem) + } + if o.CachingContext == nil { + return tmpcache.Get(o.CredentialContext) + } + return tmpcache.Get(o.CachingContext) +} + +func (o *Options) GetCredentials(repo *maven.Repository, groupId string) (maven.Credentials, error) { + if repo.IsFileSystem() { + return nil, nil + } + + switch { + case o.Credentials != nil: + return MapCredentials(o.Credentials), nil + case o.CredentialContext != nil: + return GetCredentials(o.CredentialContext, repo, groupId) + default: + return nil, nil + } +} + +func (o *Options) ApplyTo(opts *Options) { + if opts == nil { + return + } + if o.CredentialContext != nil { + opts.CredentialContext = o.CredentialContext + } + if o.LoggingContext != nil { + opts.LoggingContext = o.LoggingContext + } + if o.CachingFileSystem != nil { + opts.CachingFileSystem = o.CachingFileSystem + } + if o.Credentials != nil { + opts.Credentials = o.Credentials + } + if o.Classifier != nil { + opts.Classifier = o.Classifier + } + if o.Extension != nil { + opts.Extension = o.Extension + } +} + +//////////////////////////////////////////////////////////////////////////////// + +type context struct { + credentials.Context +} + +func (o context) ApplyTo(opts *Options) { + opts.CredentialContext = o +} + +func WithCredentialContext(ctx credentials.ContextProvider) Option { + return context{ctx.CredentialsContext()} +} + +//////////////////////////////////////////////////////////////////////////////// + +type loggingContext struct { + logging.Context +} + +func (o loggingContext) ApplyTo(opts *Options) { + opts.LoggingContext = o +} + +func WithLoggingContext(ctx logging.ContextProvider) Option { + return loggingContext{ctx.LoggingContext()} +} + +//////////////////////////////////////////////////////////////////////////////// + +type cachingContext struct { + datacontext.Context +} + +func (o cachingContext) ApplyTo(opts *Options) { + opts.CachingContext = o +} + +func WithCachingContext(ctx datacontext.Context) Option { + return cachingContext{ctx} +} + +//////////////////////////////////////////////////////////////////////////////// + +type cachingFileSystem struct { + fs vfs.FileSystem +} + +func (o *cachingFileSystem) ApplyTo(opts *Options) { + opts.CachingFileSystem = o.fs +} + +func WithCachingFileSystem(fs vfs.FileSystem) Option { + return &cachingFileSystem{fs: fs} +} + +//////////////////////////////////////////////////////////////////////////////// + +type cachingPath string + +func (o cachingPath) ApplyTo(opts *Options) { + opts.CachingPath = string(o) +} + +func WithCachingPath(p string) Option { + return cachingPath(p) +} + +/////////////////////////////////////////////////////////////////////////////// + +type creds struct { + credentials.Credentials +} + +func (o creds) ApplyTo(opts *Options) { + opts.Credentials = o.Credentials +} + +func WithCredentials(c credentials.Credentials) Option { + return creds{c} +} + +//////////////////////////////////////////////////////////////////////////////// + +type classifier string + +func (o classifier) ApplyTo(opts *Options) { + opts.Classifier = optionutils.PointerTo(string(o)) +} + +func WithClassifier(c string) Option { + return classifier(c) +} + +func WithOptionalClassifier(c *string) Option { + if c != nil { + return WithClassifier(*c) + } + return nil +} + +//////////////////////////////////////////////////////////////////////////////// + +type extension string + +func (o extension) ApplyTo(opts *Options) { + opts.Extension = optionutils.PointerTo(string(o)) +} + +func WithExtension(e string) Option { + return extension(e) +} + +func WithOptionalExtension(e *string) Option { + if e != nil { + return WithExtension(*e) + } + return nil +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/pkg/blobaccess/maven/suite_test.go b/pkg/blobaccess/maven/suite_test.go new file mode 100644 index 0000000000..b69187676e --- /dev/null +++ b/pkg/blobaccess/maven/suite_test.go @@ -0,0 +1,13 @@ +package maven_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Maven Blob Access Test Suite") +} diff --git a/pkg/blobaccess/maven/utils.go b/pkg/blobaccess/maven/utils.go new file mode 100644 index 0000000000..b1f4d774ba --- /dev/null +++ b/pkg/blobaccess/maven/utils.go @@ -0,0 +1,167 @@ +package maven + +import ( + "io" + + "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/goutils/optionutils" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/mandelsoft/vfs/pkg/vfs" + "github.com/opencontainers/go-digest" + + "github.com/open-component-model/ocm/pkg/blobaccess" + "github.com/open-component-model/ocm/pkg/blobaccess/bpi" + "github.com/open-component-model/ocm/pkg/common/accessio" + "github.com/open-component-model/ocm/pkg/common/accessobj" + "github.com/open-component-model/ocm/pkg/contexts/credentials" + "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/maven/identity" + "github.com/open-component-model/ocm/pkg/iotools" + "github.com/open-component-model/ocm/pkg/maven" + "github.com/open-component-model/ocm/pkg/mime" + "github.com/open-component-model/ocm/pkg/utils" + "github.com/open-component-model/ocm/pkg/utils/tarutils" +) + +type coords = *maven.Coordinates + +type spec struct { + coords + repo *maven.Repository + options *Options +} + +func (s *spec) getBlobAccess() (_ bpi.BlobAccess, rerr error) { + var finalize finalizer.Finalizer + defer finalize.FinalizeWithErrorPropagation(&rerr) + + log := s.options.Logger("RepoUrl", s.repo.String()) + creds, err := s.options.GetCredentials(s.repo, s.GroupId) + if err != nil { + return nil, err + } + fileMap, err := s.repo.GavFiles(s.coords, creds) + if err != nil { + return nil, err + } + + fileMap = s.coords.FilterFileMap(fileMap) + + switch l := len(fileMap); { + case l <= 0: + return nil, errors.New("no maven artifact files found") + case l == 1 && optionutils.AsValue(s.Extension) != "" && s.Classifier != nil: + for file, hash := range fileMap { + metadata, err := s.repo.GetFileMeta(s.coords, file, hash, creds) + if err != nil { + return nil, err + } + return blobAccessForRepositoryAccess(metadata, creds, s.options) + } + // default: continue below with: create tmpfs where all files can be downloaded to and packed together as tar.gz + } + + tmpfs, err := osfs.NewTempFileSystem() + if err != nil { + return nil, err + } + finalize.With(func() error { + return vfs.Cleanup(tmpfs) + }) + + for file, hash := range fileMap { + loop := finalize.Nested() + metadata, err := s.repo.GetFileMeta(s.coords, file, hash, creds) + if err != nil { + return nil, err + } + + // download the artifact into the temporary file system + out, err := tmpfs.Create(file) + if err != nil { + return nil, err + } + loop.Close(out) + + reader, err := metadata.Location.GetReader(creds) + if err != nil { + return nil, err + } + loop.Close(reader) + if hash > 0 { + dreader := iotools.NewDigestReaderWithHash(hash, reader) + _, err = io.Copy(out, dreader) + if err != nil { + return nil, err + } + sum := dreader.Digest().Encoded() + if metadata.Hash != sum { + return nil, errors.Newf("%s digest mismatch: expected %s, found %s", metadata.HashType, metadata.Hash, sum) + } + } else { + _, err = io.Copy(out, reader) + return nil, err + } + err = loop.Finalize() + if err != nil { + return nil, err + } + } + + // pack all downloaded files into a tar.gz file + fs := utils.FileSystem(s.options.CachingFileSystem) + tgz, err := vfs.TempFile(fs, "", "maven-"+s.coords.FileNamePrefix()+"-*.tar.gz") + if err != nil { + return nil, err + } + + dw := iotools.NewDigestWriterWith(digest.SHA256, tgz) + finalize.Close(dw) + + err = tarutils.TgzFs(tmpfs, dw) + if err != nil { + return nil, err + } + log.Debug("created", "file", tgz.Name()) + return blobaccess.ForTemporaryFilePathWithMeta(mime.MIME_TGZ, dw.Digest(), dw.Size(), tgz.Name(), fs), nil +} + +func blobAccessForRepositoryAccess(meta *BlobMeta, creds maven.Credentials, opts *Options) (bpi.BlobAccess, error) { + reader := func() (io.ReadCloser, error) { + return meta.Location.GetReader(creds) + } + if meta.Hash != "" { + getreader := reader + reader = func() (io.ReadCloser, error) { + readCloser, err := getreader() + if err != nil { + return nil, err + } + return iotools.VerifyingReaderWithHash(readCloser, meta.HashType, meta.Hash), nil + } + } + acc := blobaccess.DataAccessForReaderFunction(reader, meta.Location.String()) + return accessobj.CachedBlobAccessForWriterWithCache(opts.Cache(), meta.MimeType, accessio.NewDataAccessWriter(acc)), nil +} + +func MapCredentials(creds credentials.Credentials) maven.Credentials { + if creds == nil || (!creds.ExistsProperty(identity.ATTR_USERNAME) && !creds.ExistsProperty(identity.ATTR_PASSWORD)) { + return nil + } + return &maven.BasicAuthCredentials{ + Username: creds.GetProperty(identity.ATTR_USERNAME), + Password: creds.GetProperty(identity.ATTR_PASSWORD), + } +} + +func GetCredentials(ctx credentials.ContextProvider, repo *Repository, groupId string) (maven.Credentials, error) { + consumerid, err := identity.GetConsumerId(repo.String(), groupId) + if err != nil { + return nil, err + } + creds, err := credentials.CredentialsForConsumer(ctx, consumerid, identity.IdentityMatcher) + if err != nil { + return nil, err + } + return MapCredentials(creds), nil +} diff --git a/pkg/blobaccess/standard.go b/pkg/blobaccess/standard.go index ea8379cdf6..7555ac3114 100644 --- a/pkg/blobaccess/standard.go +++ b/pkg/blobaccess/standard.go @@ -321,6 +321,15 @@ func ForTemporaryFile(mime string, temp vfs.File, fss ...vfs.FileSystem) BlobAcc }) } +func ForTemporaryFileWithMeta(mime string, digest digest.Digest, size int64, temp vfs.File, fss ...vfs.FileSystem) BlobAccess { + return bpi.NewBlobAccessForBase(bpi.BaseAccessForDataAccessAndMeta(mime, &temporaryFileBlob{ + _blobAccess: ForFile(mime, temp.Name(), fss...), + filesystem: utils.FileSystem(fss...), + path: temp.Name(), + file: temp, + }, digest, size)) +} + func ForTemporaryFilePath(mime string, temp string, fss ...vfs.FileSystem) BlobAccess { return bpi.NewBlobAccessForBase(&temporaryFileBlob{ _blobAccess: ForFile(mime, temp, fss...), @@ -329,6 +338,14 @@ func ForTemporaryFilePath(mime string, temp string, fss ...vfs.FileSystem) BlobA }) } +func ForTemporaryFilePathWithMeta(mime string, digest digest.Digest, size int64, temp string, fss ...vfs.FileSystem) BlobAccess { + return bpi.NewBlobAccessForBase(bpi.BaseAccessForDataAccessAndMeta(mime, &temporaryFileBlob{ + _blobAccess: ForFile(mime, temp, fss...), + filesystem: utils.FileSystem(fss...), + path: temp, + }, digest, size)) +} + //////////////////////////////////////////////////////////////////////////////// type mimeBlob struct { diff --git a/pkg/blobaccess/wget/options.go b/pkg/blobaccess/wget/options.go index a14fb5614f..a808e4545c 100644 --- a/pkg/blobaccess/wget/options.go +++ b/pkg/blobaccess/wget/options.go @@ -64,6 +64,9 @@ func (o *Options) ApplyTo(opts *Options) { if o.LoggingContext != nil { opts.LoggingContext = o.LoggingContext } + if o.Credentials != nil { + opts.Credentials = o.Credentials + } if o.Header != nil { opts.Header = o.Header } diff --git a/pkg/common/accessio/retry_test.go b/pkg/common/accessio/retry_test.go index 73d764ff19..e67df7cf49 100644 --- a/pkg/common/accessio/retry_test.go +++ b/pkg/common/accessio/retry_test.go @@ -9,6 +9,7 @@ import ( . "github.com/open-component-model/ocm/pkg/testutils" "github.com/mandelsoft/goutils/errors" + "github.com/open-component-model/ocm/pkg/common/accessio" ) diff --git a/pkg/common/accessobj/cachedblob.go b/pkg/common/accessobj/cachedblob.go index 5ca6cfbab8..4e08c175ef 100644 --- a/pkg/common/accessobj/cachedblob.go +++ b/pkg/common/accessobj/cachedblob.go @@ -29,10 +29,14 @@ type CachedBlobAccess struct { var _ bpi.BlobAccessBase = (*CachedBlobAccess)(nil) func CachedBlobAccessForWriter(ctx datacontext.Context, mime string, src accessio.DataWriter) blobaccess.BlobAccess { + return CachedBlobAccessForWriterWithCache(tmpcache.Get(ctx), mime, src) +} + +func CachedBlobAccessForWriterWithCache(cache *tmpcache.Attribute, mime string, src accessio.DataWriter) blobaccess.BlobAccess { return bpi.NewBlobAccessForBase(&CachedBlobAccess{ source: src, mime: mime, - cache: tmpcache.Get(ctx), + cache: cache, }) } diff --git a/pkg/contexts/config/gc_test.go b/pkg/contexts/config/gc_test.go index 79e38c2974..996cb23388 100644 --- a/pkg/contexts/config/gc_test.go +++ b/pkg/contexts/config/gc_test.go @@ -6,9 +6,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/open-component-model/ocm/pkg/runtimefinalizer" me "github.com/open-component-model/ocm/pkg/contexts/config" + "github.com/open-component-model/ocm/pkg/runtimefinalizer" ) var _ = Describe("area test", func() { diff --git a/pkg/contexts/credentials/builtin/mvn/identity/identity.go b/pkg/contexts/credentials/builtin/maven/identity/identity.go similarity index 67% rename from pkg/contexts/credentials/builtin/mvn/identity/identity.go rename to pkg/contexts/credentials/builtin/maven/identity/identity.go index 0a5bf6fc74..491e38b453 100644 --- a/pkg/contexts/credentials/builtin/mvn/identity/identity.go +++ b/pkg/contexts/credentials/builtin/maven/identity/identity.go @@ -1,30 +1,26 @@ package identity import ( - "errors" - "net/http" - . "net/url" "github.com/open-component-model/ocm/pkg/contexts/credentials/cpi" "github.com/open-component-model/ocm/pkg/contexts/credentials/identity/hostpath" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" "github.com/open-component-model/ocm/pkg/listformat" "github.com/open-component-model/ocm/pkg/logging" ) const ( - // CONSUMER_TYPE is the mvn repository type. + // CONSUMER_TYPE is the maven repository type. CONSUMER_TYPE = "MavenRepository" - // ATTR_USERNAME is the username attribute. Required for login at any mvn registry. + // ATTR_USERNAME is the username attribute. Required for login at any maven registry. ATTR_USERNAME = cpi.ATTR_USERNAME - // ATTR_PASSWORD is the password attribute. Required for login at any mvn registry. + // ATTR_PASSWORD is the password attribute. Required for login at any maven registry. ATTR_PASSWORD = cpi.ATTR_PASSWORD ) // REALM the logging realm / prefix. -var REALM = logging.DefineSubRealm("Maven repository", "mvn") +var REALM = logging.DefineSubRealm("Maven repository", "maven") func init() { attrs := listformat.FormatListElements("", listformat.StringElementDescriptionList{ @@ -64,19 +60,3 @@ func GetCredentials(ctx cpi.ContextProvider, repoUrl, groupId string) (cpi.Crede } return cpi.CredentialsForConsumer(ctx.CredentialsContext(), id) } - -func BasicAuth(req *http.Request, ctx accspeccpi.Context, repoUrl, groupId string) (err error) { - credentials, err := GetCredentials(ctx, repoUrl, groupId) - if err != nil { - return err - } - if credentials == nil { - logging.DynamicLogger(REALM).Debug("No credentials found. BasicAuth not required?", "url", repoUrl, "groupId", groupId) - return nil - } - if !credentials.ExistsProperty(ATTR_USERNAME) || !credentials.ExistsProperty(ATTR_PASSWORD) { - return errors.New("missing username or password in credentials") - } - req.SetBasicAuth(credentials.GetProperty(ATTR_USERNAME), credentials.GetProperty(ATTR_PASSWORD)) - return -} diff --git a/pkg/contexts/credentials/gc_test.go b/pkg/contexts/credentials/gc_test.go index 648e9a9e9c..c96f94c418 100644 --- a/pkg/contexts/credentials/gc_test.go +++ b/pkg/contexts/credentials/gc_test.go @@ -6,9 +6,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/open-component-model/ocm/pkg/runtimefinalizer" me "github.com/open-component-model/ocm/pkg/contexts/credentials" + "github.com/open-component-model/ocm/pkg/runtimefinalizer" ) var _ = Describe("area test", func() { diff --git a/pkg/contexts/credentials/repositories/npm/repository_test.go b/pkg/contexts/credentials/repositories/npm/repository_test.go index e7fd29cfa6..82694bcc48 100644 --- a/pkg/contexts/credentials/repositories/npm/repository_test.go +++ b/pkg/contexts/credentials/repositories/npm/repository_test.go @@ -6,7 +6,6 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/open-component-model/ocm/pkg/runtimefinalizer" . "github.com/open-component-model/ocm/pkg/testutils" "github.com/open-component-model/ocm/pkg/common" @@ -14,6 +13,7 @@ import ( npmCredentials "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/npm/identity" "github.com/open-component-model/ocm/pkg/contexts/credentials/cpi" local "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/npm" + "github.com/open-component-model/ocm/pkg/runtimefinalizer" ) var _ = Describe("NPM config - .npmrc", func() { diff --git a/pkg/contexts/credentials/repositories/vault/repo_int_test.go b/pkg/contexts/credentials/repositories/vault/repo_int_test.go index 13456f8f36..3109660a3e 100644 --- a/pkg/contexts/credentials/repositories/vault/repo_int_test.go +++ b/pkg/contexts/credentials/repositories/vault/repo_int_test.go @@ -5,17 +5,16 @@ package vault_test import ( "context" "fmt" - "net" "os" "os/exec" "time" - "github.com/hashicorp/vault-client-go" - "github.com/hashicorp/vault-client-go/schema" - "github.com/mandelsoft/goutils/errors" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/hashicorp/vault-client-go" + "github.com/hashicorp/vault-client-go/schema" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/credentials" @@ -23,7 +22,6 @@ import ( me "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault" "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault/identity" "github.com/open-component-model/ocm/pkg/runtime" - . "github.com/open-component-model/ocm/pkg/testutils" ) type vaultMode string @@ -461,32 +459,11 @@ func StartVaultServer(mode vaultMode, rootToken, address string) (*exec.Cmd, *va err = cmd.Start() if err == nil { - err = WaitForTCPServer(address, time.Minute) + err = PingTCPServer(address, time.Minute) } return cmd, vaultClient, cancelFunc, err } -func WaitForTCPServer(address string, dur time.Duration) error { - var conn net.Conn - var d net.Dialer - - ctx, cancel := context.WithTimeout(context.Background(), time.Minute) - defer cancel() - - end := time.Now().Add(dur) - err := errors.New("timed out waiting for server to start") - for time.Now().Before(end) { - conn, err = d.DialContext(ctx, "tcp", address) - if err != nil { - time.Sleep(time.Second) - continue - } - conn.Close() - break - } - return err -} - func SetUpVaultAccess(ctx context.Context, credctx credentials.Context, client *vault.Client, policy string) { _ = Must(client.System.AuthEnableMethod(ctx, "approle", schema.AuthEnableMethodRequest{Type: "approle"})) _ = Must(client.System.PoliciesWriteAclPolicy(ctx, VAULT_POLICY_NAME, schema.PoliciesWriteAclPolicyRequest{Policy: policy})) diff --git a/pkg/contexts/credentials/repositories/vault/repo_test.go b/pkg/contexts/credentials/repositories/vault/repo_test.go index 5eb7bdc748..72e3ee2d5c 100644 --- a/pkg/contexts/credentials/repositories/vault/repo_test.go +++ b/pkg/contexts/credentials/repositories/vault/repo_test.go @@ -7,12 +7,12 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/testutils" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/credentials" me "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault" "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/vault/identity" - . "github.com/open-component-model/ocm/pkg/testutils" ) const ( diff --git a/pkg/contexts/datacontext/attrs/tmpcache/attr.go b/pkg/contexts/datacontext/attrs/tmpcache/attr.go index b71abfe230..bbe00a818f 100644 --- a/pkg/contexts/datacontext/attrs/tmpcache/attr.go +++ b/pkg/contexts/datacontext/attrs/tmpcache/attr.go @@ -62,6 +62,13 @@ type Attribute struct { Filesystem vfs.FileSystem } +func New(path string, fss ...vfs.FileSystem) *Attribute { + return &Attribute{ + Path: path, + Filesystem: utils.FileSystem(fss...), + } +} + func (a *Attribute) CreateTempFile(pat string) (vfs.File, error) { err := a.Filesystem.MkdirAll(a.Path, 0o777) if err != nil { @@ -73,8 +80,15 @@ func (a *Attribute) CreateTempFile(pat string) (vfs.File, error) { //////////////////////////////////////////////////////////////////////////////// func Get(ctx datacontext.Context) *Attribute { - v := ctx.GetAttributes().GetAttribute(ATTR_KEY) - fs := utils.FileSystem(vfsattr.Get(ctx)) + var v interface{} + var fs vfs.FileSystem + + if ctx != nil { + v = ctx.GetAttributes().GetAttribute(ATTR_KEY) + fs = utils.FileSystem(vfsattr.Get(ctx)) + } + fs = utils.FileSystem(fs) + if v != nil { a := v.(*Attribute) if a.Filesystem == nil { diff --git a/pkg/contexts/datacontext/attrs/vfsattr/attr.go b/pkg/contexts/datacontext/attrs/vfsattr/attr.go index c0b8858d23..5ba3ef9645 100644 --- a/pkg/contexts/datacontext/attrs/vfsattr/attr.go +++ b/pkg/contexts/datacontext/attrs/vfsattr/attr.go @@ -35,7 +35,7 @@ Virtual filesystem to use for command line context. func (a AttributeType) Encode(v interface{}, marshaller runtime.Marshaler) ([]byte, error) { if _, ok := v.(vfs.FileSystem); !ok { - return nil, fmt.Errorf("vfs.FileSystem required") + return nil, fmt.Errorf("vfs.CachingFileSystem required") } return nil, nil } diff --git a/pkg/contexts/oci/gc_test.go b/pkg/contexts/oci/gc_test.go index 404dbad31e..bc48501b92 100644 --- a/pkg/contexts/oci/gc_test.go +++ b/pkg/contexts/oci/gc_test.go @@ -6,9 +6,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/open-component-model/ocm/pkg/runtimefinalizer" me "github.com/open-component-model/ocm/pkg/contexts/oci" + "github.com/open-component-model/ocm/pkg/runtimefinalizer" ) var _ = Describe("area test", func() { diff --git a/pkg/contexts/oci/repositories/ctf/ctf_test.go b/pkg/contexts/oci/repositories/ctf/ctf_test.go index 34aa84669f..5ca0cd470c 100644 --- a/pkg/contexts/oci/repositories/ctf/ctf_test.go +++ b/pkg/contexts/oci/repositories/ctf/ctf_test.go @@ -10,13 +10,13 @@ import ( . "github.com/open-component-model/ocm/pkg/contexts/oci/repositories/ctf/testhelper" . "github.com/open-component-model/ocm/pkg/testutils" + "github.com/mandelsoft/goutils/errors" "github.com/mandelsoft/goutils/finalizer" "github.com/mandelsoft/logging" "github.com/mandelsoft/vfs/pkg/osfs" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/opencontainers/go-digest" - "github.com/mandelsoft/goutils/errors" "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/common/accessio" "github.com/open-component-model/ocm/pkg/common/accessobj" diff --git a/pkg/contexts/ocm/accessmethods/init.go b/pkg/contexts/ocm/accessmethods/init.go index f0a70ce7dd..55ffe41be8 100644 --- a/pkg/contexts/ocm/accessmethods/init.go +++ b/pkg/contexts/ocm/accessmethods/init.go @@ -6,7 +6,7 @@ import ( _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localblob" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localfsblob" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/localociblob" - _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/mvn" + _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/maven" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/none" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/npm" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/ociartifact" diff --git a/pkg/contexts/ocm/accessmethods/mvn/README.md b/pkg/contexts/ocm/accessmethods/maven/README.md similarity index 100% rename from pkg/contexts/ocm/accessmethods/mvn/README.md rename to pkg/contexts/ocm/accessmethods/maven/README.md diff --git a/pkg/contexts/ocm/accessmethods/mvn/cli.go b/pkg/contexts/ocm/accessmethods/maven/cli.go similarity index 73% rename from pkg/contexts/ocm/accessmethods/mvn/cli.go rename to pkg/contexts/ocm/accessmethods/maven/cli.go index dd81479a6b..db82b8a8b9 100644 --- a/pkg/contexts/ocm/accessmethods/mvn/cli.go +++ b/pkg/contexts/ocm/accessmethods/maven/cli.go @@ -1,4 +1,4 @@ -package mvn +package maven import ( "github.com/open-component-model/ocm/pkg/cobrautils/flagsets" @@ -10,7 +10,7 @@ func ConfigHandler() flagsets.ConfigOptionTypeSetHandler { Type, AddConfig, options.RepositoryOption, options.GroupOption, - options.PackageOption, + options.ArtifactOption, options.VersionOption, // optional options.ClassifierOption, @@ -19,7 +19,7 @@ func ConfigHandler() flagsets.ConfigOptionTypeSetHandler { } func AddConfig(opts flagsets.ConfigOptions, config flagsets.Config) error { - flagsets.AddFieldByOptionP(opts, options.RepositoryOption, config, "repository") + flagsets.AddFieldByOptionP(opts, options.RepositoryOption, config, "repoUrl") flagsets.AddFieldByOptionP(opts, options.GroupOption, config, "groupId") flagsets.AddFieldByOptionP(opts, options.PackageOption, config, "artifactId") flagsets.AddFieldByOptionP(opts, options.VersionOption, config, "version") @@ -30,33 +30,33 @@ func AddConfig(opts flagsets.ConfigOptions, config flagsets.Config) error { } var usage = ` -This method implements the access of a Maven (mvn) artifact in a Maven repository. +This method implements the access of a Maven artifact in a Maven repository. ` var formatV1 = ` The type specific specification fields are: -- **repository** *string* +- **repoUrl** *string* - Base URL of the Maven (mvn) repository + URL of the Maven repository - **groupId** *string* - The groupId of the Maven (mvn) artifact + The groupId of the Maven artifact - **artifactId** *string* - The artifactId of the Maven (mvn) artifact + The artifactId of the Maven artifact - **version** *string* - The version name of the Maven (mvn) artifact + The version name of the Maven artifact - **classifier** *string* - The optional classifier of the Maven (mvn) artifact + The optional classifier of the Maven artifact - **extension** *string* - The optional extension of the Maven (mvn) artifact + The optional extension of the Maven artifact ` diff --git a/pkg/contexts/ocm/accessmethods/maven/method.go b/pkg/contexts/ocm/accessmethods/maven/method.go new file mode 100644 index 0000000000..d377c884fd --- /dev/null +++ b/pkg/contexts/ocm/accessmethods/maven/method.go @@ -0,0 +1,159 @@ +package maven + +import ( + "fmt" + + "github.com/mandelsoft/goutils/optionutils" + + "github.com/open-component-model/ocm/pkg/blobaccess" + mavenblob "github.com/open-component-model/ocm/pkg/blobaccess/maven" + "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/maven/identity" + "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" + "github.com/open-component-model/ocm/pkg/maven" + "github.com/open-component-model/ocm/pkg/runtime" +) + +// Type is the access type of Maven repository. +const ( + Type = "maven" + TypeV1 = Type + runtime.VersionSeparator + "v1" +) + +func init() { + accspeccpi.RegisterAccessType(accspeccpi.NewAccessSpecType[*AccessSpec](Type, accspeccpi.WithDescription(usage))) + accspeccpi.RegisterAccessType(accspeccpi.NewAccessSpecType[*AccessSpec](TypeV1, accspeccpi.WithFormatSpec(formatV1), accspeccpi.WithConfigHandler(ConfigHandler()))) +} + +// AccessSpec describes the access for a Maven artifact. +type AccessSpec struct { + runtime.ObjectVersionedType `json:",inline"` + + // RepoUrl is the base URL of the Maven repository. + RepoUrl string `json:"repoUrl"` + + maven.Coordinates `json:",inline"` +} + +// Option defines the interface function "ApplyTo()". +type Option = maven.CoordinateOption + +type WithClassifier = maven.WithClassifier + +func WithOptionalClassifier(c *string) Option { + return maven.WithOptionalClassifier(c) +} + +type WithExtension = maven.WithExtension + +func WithOptionalExtension(e *string) Option { + return maven.WithOptionalExtension(e) +} + +/////////////////////////////////////////////////////////////////////////////// + +var _ accspeccpi.AccessSpec = (*AccessSpec)(nil) + +// New creates a new Maven repository access spec version v1. +func New(repository, groupId, artifactId, version string, opts ...Option) *AccessSpec { + accessSpec := &AccessSpec{ + ObjectVersionedType: runtime.NewVersionedTypedObject(Type), + RepoUrl: repository, + Coordinates: *maven.NewCoordinates(groupId, artifactId, version, opts...), + } + return accessSpec +} + +// NewForCoordinates creates a new Maven repository access spec version v1. +func NewForCoordinates(repository string, coords *maven.Coordinates, opts ...Option) *AccessSpec { + optionutils.ApplyOptions(coords, opts...) + accessSpec := &AccessSpec{ + ObjectVersionedType: runtime.NewVersionedTypedObject(Type), + RepoUrl: repository, + Coordinates: *coords, + } + return accessSpec +} + +func (a *AccessSpec) Describe(_ accspeccpi.Context) string { + return fmt.Sprintf("Maven package '%s' in repository '%s' path '%s'", a.Coordinates.String(), a.RepoUrl, a.Coordinates.FilePath()) +} + +func (_ *AccessSpec) IsLocal(accspeccpi.Context) bool { + return false +} + +func (a *AccessSpec) GlobalAccessSpec(_ accspeccpi.Context) accspeccpi.AccessSpec { + return a +} + +// GetReferenceHint returns the reference hint for the Maven (mvn) artifact. +func (a *AccessSpec) GetReferenceHint(_ accspeccpi.ComponentVersionAccess) string { + return a.String() +} + +func (_ *AccessSpec) GetType() string { + return Type +} + +func (a *AccessSpec) AccessMethod(cv accspeccpi.ComponentVersionAccess) (accspeccpi.AccessMethod, error) { + octx := cv.GetContext() + + repo, err := maven.NewUrlRepository(a.RepoUrl, vfsattr.Get(cv.GetContext())) + if err != nil { + return nil, err + } + + factory := func() (blobaccess.BlobAccess, error) { + return mavenblob.BlobAccessForMavenCoords(repo, &a.Coordinates, + mavenblob.WithCredentialContext(octx), + mavenblob.WithLoggingContext(octx), + mavenblob.WithCachingFileSystem(vfsattr.Get(octx))) + } + return accspeccpi.AccessMethodForImplementation(accspeccpi.NewDefaultMethodImpl(cv, a, "", a.MimeType(), factory), nil) +} + +func (a *AccessSpec) GetInexpensiveContentVersionIdentity(cv accspeccpi.ComponentVersionAccess) string { + creds, err := identity.GetCredentials(cv.GetContext(), a.RepoUrl, a.GroupId) + if err != nil { + return "" + } + mvncreds := mavenblob.MapCredentials(creds) + fs := vfsattr.Get(cv.GetContext()) + repo, err := maven.NewUrlRepository(a.RepoUrl, fs) + if err != nil { + return "" + } + files, err := repo.GavFiles(&a.Coordinates, mvncreds) + if err != nil { + return "" + } + files = a.Coordinates.FilterFileMap(files) + if len(files) != 1 { + return "" + } + if optionutils.AsValue(a.Extension) == "" { + return "" + } + for _, h := range files { + id, _ := a.Location(repo).GetHash(mvncreds, h) + return id + } + return "" +} + +func (a *AccessSpec) BaseUrl() string { + return a.RepoUrl + "/" + a.GavPath() +} + +func (a *AccessSpec) ArtifactUrl() string { + repo, err := maven.NewUrlRepository(a.RepoUrl) + if err != nil { + return "" + } + return a.Location(repo).String() +} + +func (a *AccessSpec) GetCoordinates() *maven.Coordinates { + return a.Coordinates.Copy() +} diff --git a/pkg/contexts/ocm/accessmethods/maven/method_test.go b/pkg/contexts/ocm/accessmethods/maven/method_test.go new file mode 100644 index 0000000000..20310c92d0 --- /dev/null +++ b/pkg/contexts/ocm/accessmethods/maven/method_test.go @@ -0,0 +1,133 @@ +package maven_test + +import ( + "crypto" + "github.com/open-component-model/ocm/pkg/maven/maventest" + "time" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/env/builder" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/open-component-model/ocm/pkg/contexts/ocm" + me "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/maven" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + "github.com/open-component-model/ocm/pkg/iotools" + "github.com/open-component-model/ocm/pkg/mime" + "github.com/open-component-model/ocm/pkg/utils/tarutils" +) + +const ( + MAVEN_PATH = "/testdata/.m2/repository" + FAILPATH = "/testdata/.m2/fail" + MAVEN_CENTRAL = "https://repo.maven.apache.org/maven2/" + MAVEN_CENTRAL_ADDRESS = "repo.maven.apache.org:443" + MAVEN_GROUP_ID = "maven" + MAVEN_ARTIFACT_ID = "maven" + MAVEN_VERSION = "1.1" +) + +var _ = Describe("local accessmethods.maven.AccessSpec tests", func() { + var env *Builder + var cv ocm.ComponentVersionAccess + + BeforeEach(func() { + env = NewBuilder(maventest.TestData()) + cv = &cpi.DummyComponentVersionAccess{env.OCMContext()} + }) + + AfterEach(func() { + env.Cleanup() + }) + + It("accesses local artifact", func() { + acc := me.New("file://"+MAVEN_PATH, "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") + m := Must(acc.AccessMethod(cv)) + defer Close(m) + Expect(m.MimeType()).To(Equal(mime.MIME_TGZ)) + r := Must(m.Reader()) + defer Close(r) + dr := iotools.NewDigestReaderWithHash(crypto.SHA1, r) + for { + var buf [8096]byte + _, err := dr.Read(buf[:]) + if err != nil { + break + } + } + Expect(dr.Size()).To(Equal(int64(1570))) + Expect(dr.Digest().String()).To(Equal("SHA-1:359d02795bcc737e81c7f2f0ac32f49351d41867")) + }) + + It("accesses local artifact with empty classifier and with extension", func() { + acc := me.New("file://"+MAVEN_PATH, "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", me.WithClassifier(""), me.WithExtension("pom")) + m := Must(acc.AccessMethod(cv)) + defer Close(m) + Expect(m.MimeType()).To(Equal(mime.MIME_XML)) + r := Must(m.Reader()) + defer Close(r) + + dr := iotools.NewDigestReaderWithHash(crypto.SHA1, r) + for { + var buf [8096]byte + _, err := dr.Read(buf[:]) + if err != nil { + break + } + } + + Expect(dr.Size()).To(Equal(int64(7153))) + Expect(dr.Digest().String()).To(Equal("SHA-1:34ccdeb9c008f8aaef90873fc636b09d3ae5c709")) + }) + + It("accesses local artifact with extension", func() { + acc := me.New("file://"+MAVEN_PATH, "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", me.WithExtension("pom")) + m := Must(acc.AccessMethod(cv)) + defer Close(m) + Expect(m.MimeType()).To(Equal(mime.MIME_TGZ)) + r := Must(m.Reader()) + defer Close(r) + dr := iotools.NewDigestReaderWithHash(crypto.SHA1, r) + list := Must(tarutils.ListArchiveContentFromReader(dr)) + Expect(list).To(ConsistOf("sdk-modules-bom-5.7.0.pom")) + + Expect(dr.Size()).To(Equal(int64(1109))) + Expect(dr.Digest().String()).To(Equal("SHA-1:4ee125ffe4f7690588833f1217a13cc741e4df5f")) + }) + + It("Describe", func() { + acc := me.New("file://"+FAILPATH, "test", "repository", "42", me.WithExtension("pom")) + Expect(acc.Describe(nil)).To(Equal("Maven package 'test:repository:42::pom' in repository 'file:///testdata/.m2/fail' path 'test/repository/42/repository-42.pom'")) + }) + + It("detects digests mismatch", func() { + acc := me.New("file://"+FAILPATH, "test", "repository", "42", me.WithExtension("pom")) + m := Must(acc.AccessMethod(cv)) + defer Close(m) + _, err := m.Reader() + Expect(err).To(MatchError(ContainSubstring("SHA-1 digest mismatch: expected 44a77645201d1a8fc5213ace787c220eabbd0967, found b3242b8c31f8ce14f729b8fd132ac77bc4bc5bf7"))) + }) + + Context("me http repository", func() { + if PingTCPServer(MAVEN_CENTRAL_ADDRESS, time.Second) == nil { + It("blobaccess for gav", func() { + acc := me.New(MAVEN_CENTRAL, MAVEN_GROUP_ID, MAVEN_ARTIFACT_ID, MAVEN_VERSION) + m := Must(acc.AccessMethod(cv)) + defer Close(m) + files := Must(tarutils.ListArchiveContentFromReader(Must(m.Reader()))) + Expect(files).To(ConsistOf( + "maven-1.1-RC1.javadoc.javadoc.jar", + "maven-1.1-sources.jar", + "maven-1.1.jar", + "maven-1.1.pom", + )) + }) + + It("inexpensive id", func() { + acc := me.New(MAVEN_CENTRAL, MAVEN_GROUP_ID, MAVEN_ARTIFACT_ID, MAVEN_VERSION, me.WithClassifier(""), me.WithExtension("pom")) + Expect(acc.GetInexpensiveContentVersionIdentity(cv)).To(Equal("4fb753e1a4ab7acebc39557f1aa292052775b0d8")) + }) + } + }) +}) diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/suite_test.go b/pkg/contexts/ocm/accessmethods/maven/suite_test.go similarity index 72% rename from pkg/contexts/ocm/blobhandler/handlers/generic/mvn/suite_test.go rename to pkg/contexts/ocm/accessmethods/maven/suite_test.go index c62cadc7b0..d43b2dbd6b 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/suite_test.go +++ b/pkg/contexts/ocm/accessmethods/maven/suite_test.go @@ -1,4 +1,4 @@ -package mvn_test +package maven_test import ( "testing" @@ -9,5 +9,5 @@ import ( func TestConfig(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "Maven (mvn) Test Suite") + RunSpecs(t, "Maven Test Suite") } diff --git a/pkg/contexts/ocm/accessmethods/mvn/coordinates.go b/pkg/contexts/ocm/accessmethods/mvn/coordinates.go deleted file mode 100644 index d39e09c2e5..0000000000 --- a/pkg/contexts/ocm/accessmethods/mvn/coordinates.go +++ /dev/null @@ -1,144 +0,0 @@ -package mvn - -import ( - "fmt" - "mime" - "path" - "path/filepath" - "strings" - - ocmmime "github.com/open-component-model/ocm/pkg/mime" -) - -// Coordinates holds the typical Maven coordinates groupId, artifactId, version. Optional also classifier and extension. -// https://maven.apache.org/ref/3.9.6/maven-core/artifact-handlers.html -type Coordinates struct { - // GroupId of the Maven (mvn) artifact. - GroupId string `json:"groupId"` - // ArtifactId of the Maven (mvn) artifact. - ArtifactId string `json:"artifactId"` - // Version of the Maven (mvn) artifact. - Version string `json:"version"` - // Classifier of the Maven (mvn) artifact. - Classifier string `json:"classifier"` - // Extension of the Maven (mvn) artifact. - Extension string `json:"extension"` -} - -// GAV returns the GAV coordinates of the Maven Coordinates. -func (c *Coordinates) GAV() string { - return c.GroupId + ":" + c.ArtifactId + ":" + c.Version -} - -// String returns the Coordinates as a string (GroupId:ArtifactId:Version:Classifier:Extension). -func (c *Coordinates) String() string { - return c.GroupId + ":" + c.ArtifactId + ":" + c.Version + ":" + c.Classifier + ":" + c.Extension -} - -// GavPath returns the Maven repository path. -func (c *Coordinates) GavPath() string { - return c.GroupPath() + "/" + c.ArtifactId + "/" + c.Version -} - -// FilePath returns the Maven Coordinates's GAV-name with classifier and extension. -// Which is equal to the URL-path of the artifact in the repository. -// Default extension is jar. -func (c *Coordinates) FilePath() string { - path := c.GavPath() + "/" + c.FileNamePrefix() - if c.Classifier != "" { - path += "-" + c.Classifier - } - if c.Extension != "" { - path += "." + c.Extension - } else { - path += ".jar" - } - return path -} - -func (c *Coordinates) Url(baseUrl string) string { - return baseUrl + "/" + c.FilePath() -} - -// GroupPath returns GroupId with `/` instead of `.`. -func (c *Coordinates) GroupPath() string { - return strings.ReplaceAll(c.GroupId, ".", "/") -} - -func (c *Coordinates) FileNamePrefix() string { - return c.ArtifactId + "-" + c.Version -} - -// Purl returns the Package URL of the Maven Coordinates. -func (c *Coordinates) Purl() string { - return "pkg:maven/" + c.GroupId + "/" + c.ArtifactId + "@" + c.Version -} - -// SetClassifierExtensionBy extracts the classifier and extension from the filename (without any path prefix). -func (c *Coordinates) SetClassifierExtensionBy(filename string) error { - s := strings.TrimPrefix(path.Base(filename), c.FileNamePrefix()) - if strings.HasPrefix(s, "-") { - s = strings.TrimPrefix(s, "-") - i := strings.Index(s, ".") - if i < 0 { - return fmt.Errorf("no extension after classifier found in filename: %s", filename) - } - c.Classifier = s[:i] - s = strings.TrimPrefix(s, c.Classifier) - } else { - c.Classifier = "" - } - c.Extension = strings.TrimPrefix(s, ".") - return nil -} - -// MimeType returns the MIME type of the Maven Coordinates based on the file extension. -// Default is application/x-tgz. -func (c *Coordinates) MimeType() string { - m := mime.TypeByExtension("." + c.Extension) - if m != "" { - return m - } - return ocmmime.MIME_TGZ -} - -// Copy creates a new Coordinates with the same values. -func (c *Coordinates) Copy() *Coordinates { - return &Coordinates{ - GroupId: c.GroupId, - ArtifactId: c.ArtifactId, - Version: c.Version, - Classifier: c.Classifier, - Extension: c.Extension, - } -} - -// Parse creates an Coordinates from it's serialized form (see Coordinates.String). -func Parse(serializedArtifact string) (*Coordinates, error) { - parts := strings.Split(serializedArtifact, ":") - if len(parts) < 3 { - return nil, fmt.Errorf("invalid artifact string: %s", serializedArtifact) - } - artifact := &Coordinates{ - GroupId: parts[0], - ArtifactId: parts[1], - Version: parts[2], - } - if len(parts) >= 4 { - artifact.Classifier = parts[3] - } - if len(parts) >= 5 { - artifact.Extension = parts[4] - } - return artifact, nil -} - -// IsResource returns true if the filename is not a checksum or signature file. -func IsResource(fileName string) bool { - switch filepath.Ext(fileName) { - case ".asc", ".md5", ".sha1", ".sha256", ".sha512": - return false - default: - return true - } -} diff --git a/pkg/contexts/ocm/accessmethods/mvn/coordinates_test.go b/pkg/contexts/ocm/accessmethods/mvn/coordinates_test.go deleted file mode 100644 index 63df1268ae..0000000000 --- a/pkg/contexts/ocm/accessmethods/mvn/coordinates_test.go +++ /dev/null @@ -1,55 +0,0 @@ -package mvn - -import ( - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -var _ = Describe("Maven Test Environment", func() { - - It("GAV, GroupPath, FilePath", func() { - artifact := &Coordinates{ - GroupId: "ocm.software", - ArtifactId: "hello-ocm", - Version: "0.0.1", - Extension: "jar", - } - Expect(artifact.GAV()).To(Equal("ocm.software:hello-ocm:0.0.1")) - Expect(artifact.GroupPath()).To(Equal("ocm/software")) - Expect(artifact.FilePath()).To(Equal("ocm/software/hello-ocm/0.0.1/hello-ocm-0.0.1.jar")) - }) - - It("SetClassifierExtensionBy", func() { - artifact := &Coordinates{ - GroupId: "ocm.software", - ArtifactId: "hello-ocm", - Version: "0.0.1", - } - artifact.SetClassifierExtensionBy("hello-ocm-0.0.1.pom") - Expect(artifact.Classifier).To(Equal("")) - Expect(artifact.Extension).To(Equal("pom")) - - artifact.SetClassifierExtensionBy("hello-ocm-0.0.1-tests.jar") - Expect(artifact.Classifier).To(Equal("tests")) - Expect(artifact.Extension).To(Equal("jar")) - - artifact.ArtifactId = "apache-maven" - artifact.Version = "3.9.6" - artifact.SetClassifierExtensionBy("apache-maven-3.9.6-bin.tar.gz") - Expect(artifact.Classifier).To(Equal("bin")) - Expect(artifact.Extension).To(Equal("tar.gz")) - }) - - It("parse GAV", func() { - gav := "org.apache.commons:commons-compress:1.26.1:cyclonedx:xml" - artifact, err := Parse(gav) - Expect(err).To(BeNil()) - Expect(artifact.String()).To(Equal(gav)) - Expect(artifact.GroupId).To(Equal("org.apache.commons")) - Expect(artifact.ArtifactId).To(Equal("commons-compress")) - Expect(artifact.Version).To(Equal("1.26.1")) - Expect(artifact.Classifier).To(Equal("cyclonedx")) - Expect(artifact.Extension).To(Equal("xml")) - Expect(artifact.FilePath()).To(Equal("org/apache/commons/commons-compress/1.26.1/commons-compress-1.26.1-cyclonedx.xml")) - }) -}) diff --git a/pkg/contexts/ocm/accessmethods/mvn/integration_test.go b/pkg/contexts/ocm/accessmethods/mvn/integration_test.go deleted file mode 100644 index b2eca2b1d0..0000000000 --- a/pkg/contexts/ocm/accessmethods/mvn/integration_test.go +++ /dev/null @@ -1,98 +0,0 @@ -//go:build integration - -package mvn_test - -import ( - "crypto" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/open-component-model/ocm/pkg/contexts/ocm" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/mvn" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - . "github.com/open-component-model/ocm/pkg/env" - . "github.com/open-component-model/ocm/pkg/env/builder" - "github.com/open-component-model/ocm/pkg/mime" - . "github.com/open-component-model/ocm/pkg/testutils" - "github.com/open-component-model/ocm/pkg/utils/tarutils" -) - -var _ = Describe("online accessmethods.mvn.AccessSpec integration tests", func() { - var env *Builder - var cv ocm.ComponentVersionAccess - - BeforeEach(func() { - env = NewBuilder(TestData()) - cv = &cpi.DummyComponentVersionAccess{env.OCMContext()} - }) - - AfterEach(func() { - env.Cleanup() - }) - - // https://repo1.maven.org/maven2/com/sap/cloud/sdk/sdk-modules-bom/5.7.0 - It("one single pom only", func() { - acc := mvn.New("https://repo1.maven.org/maven2", "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") - files, err := acc.GavFiles(cv.GetContext()) - Expect(err).ToNot(HaveOccurred()) - Expect(files).To(HaveLen(1)) - Expect(files["sdk-modules-bom-5.7.0.pom"]).To(Equal(crypto.SHA1)) - }) - It("GetPackageMeta - com.sap.cloud.sdk", func() { - acc := mvn.New("https://repo1.maven.org/maven2", "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") - meta, err := acc.GetPackageMeta(ocm.DefaultContext()) - Expect(err).ToNot(HaveOccurred()) - Expect(meta.Bin).To(HavePrefix("file://")) - Expect(meta.Bin).To(ContainSubstring("mvn-sdk-modules-bom-5.7.0-")) - Expect(meta.Bin).To(HaveSuffix(".tar.gz")) - Expect(meta.Hash).To(Equal("345fe2e640663c3cd6ac87b7afb92e1c934f665f75ddcb9555bc33e1813ef00b")) - Expect(meta.HashType).To(Equal(crypto.SHA256)) - }) - - // https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6 - It("apache-maven, with bin + tar.gz etc.", func() { - acc := mvn.New("https://repo1.maven.org/maven2", "org.apache.maven", "apache-maven", "3.9.6") - Expect(acc).ToNot(BeNil()) - Expect(acc.BaseUrl()).To(Equal("https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6")) - files, err := acc.GavFiles(cv.GetContext()) - Expect(err).ToNot(HaveOccurred()) - Expect(files).To(HaveLen(8)) - Expect(files["apache-maven-3.9.6-src.zip"]).To(Equal(crypto.SHA512)) - Expect(files["apache-maven-3.9.6.pom"]).To(Equal(crypto.SHA1)) - }) - - // https://repo1.maven.org/maven2/com/sap/cloud/environment/servicebinding/java-sap-vcap-services/0.10.4 - It("accesses local artifact", func() { - acc := mvn.New("https://repo1.maven.org/maven2", "com.sap.cloud.environment.servicebinding", "java-sap-vcap-services", "0.10.4") - meta, err := acc.GetPackageMeta(ocm.DefaultContext()) - Expect(err).ToNot(HaveOccurred()) - Expect(meta.Bin).To(HavePrefix("file://")) - m := Must(acc.AccessMethod(cv)) - defer m.Close() - Expect(m.MimeType()).To(Equal(mime.MIME_TGZ)) - /* manually also tested with repos: - - https://repo1.maven.org/maven2/org/apache/commons/commons-compress/1.26.1/ // cyclonedx - - https://repo1.maven.org/maven2/cn/afternode/commons/commons/1.6/ // gradle module! - */ - }) - - // https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6 - It("apache-maven, 'bin' zip + tar.gz only!", func() { - acc := mvn.New("https://repo1.maven.org/maven2", "org.apache.maven", "apache-maven", "3.9.6", mvn.WithClassifier("bin")) - Expect(acc).ToNot(BeNil()) - Expect(acc.BaseUrl()).To(Equal("https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.9.6")) - files, err := acc.GavFiles(cv.GetContext()) - Expect(err).ToNot(HaveOccurred()) - Expect(files).To(HaveLen(8)) // the repo contains 8 files... - m := Must(acc.AccessMethod(cv)) - defer m.Close() - Expect(err).ToNot(HaveOccurred()) - Expect(m.MimeType()).To(Equal(mime.MIME_TGZ)) - r := Must(m.Reader()) - defer r.Close() - list, err := tarutils.ListArchiveContentFromReader(r) - Expect(err).ToNot(HaveOccurred()) - Expect(list).To(HaveLen(2)) // ...but with the classifier set, we're interested only in two! - }) -}) diff --git a/pkg/contexts/ocm/accessmethods/mvn/method.go b/pkg/contexts/ocm/accessmethods/mvn/method.go deleted file mode 100644 index d430b774c2..0000000000 --- a/pkg/contexts/ocm/accessmethods/mvn/method.go +++ /dev/null @@ -1,444 +0,0 @@ -package mvn - -import ( - "bytes" - "context" - "crypto" - "fmt" - "io" - "net/http" - "path" - "sort" - "strings" - - "github.com/mandelsoft/goutils/errors" - "github.com/mandelsoft/goutils/optionutils" - "github.com/mandelsoft/vfs/pkg/osfs" - "github.com/mandelsoft/vfs/pkg/vfs" - "github.com/opencontainers/go-digest" - "golang.org/x/exp/slices" - "golang.org/x/net/html" - - "github.com/open-component-model/ocm/pkg/blobaccess" - "github.com/open-component-model/ocm/pkg/common/accessio" - "github.com/open-component-model/ocm/pkg/common/accessobj" - "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/mvn/identity" - "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" - "github.com/open-component-model/ocm/pkg/iotools" - "github.com/open-component-model/ocm/pkg/logging" - "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/runtime" - "github.com/open-component-model/ocm/pkg/utils" - "github.com/open-component-model/ocm/pkg/utils/tarutils" -) - -// Type is the access type of Maven (mvn) repository. -const ( - Type = "mvn" - TypeV1 = Type + runtime.VersionSeparator + "v1" -) - -func init() { - accspeccpi.RegisterAccessType(accspeccpi.NewAccessSpecType[*AccessSpec](Type, accspeccpi.WithDescription(usage))) - accspeccpi.RegisterAccessType(accspeccpi.NewAccessSpecType[*AccessSpec](TypeV1, accspeccpi.WithFormatSpec(formatV1), accspeccpi.WithConfigHandler(ConfigHandler()))) -} - -// AccessSpec describes the access for a Maven (mvn) artifact. -type AccessSpec struct { - runtime.ObjectVersionedType `json:",inline"` - - // Repository is the base URL of the Maven (mvn) repository. - Repository string `json:"repository"` - - Coordinates `json:",inline"` -} - -// Option defines the interface function "ApplyTo()". -type Option = optionutils.Option[*AccessSpec] - -var _ accspeccpi.AccessSpec = (*AccessSpec)(nil) - -var log = logging.DynamicLogger(identity.REALM) - -// New creates a new Maven (mvn) repository access spec version v1. -func New(repository, groupId, artifactId, version string, options ...Option) *AccessSpec { - accessSpec := &AccessSpec{ - ObjectVersionedType: runtime.NewVersionedTypedObject(Type), - Repository: repository, - Coordinates: Coordinates{ - GroupId: groupId, - ArtifactId: artifactId, - Version: version, - Classifier: "", - Extension: "", - }, - } - optionutils.ApplyOptions(accessSpec, options...) - return accessSpec -} - -// classifier Option for Maven (mvn) Coordinates. -type classifier string - -func (c classifier) ApplyTo(a *AccessSpec) { - a.Classifier = string(c) -} - -// WithClassifier sets the classifier of the Maven (mvn) artifact. -func WithClassifier(c string) Option { - return classifier(c) -} - -// extension Option for Maven (mvn) Coordinates. -type extension string - -func (e extension) ApplyTo(a *AccessSpec) { - a.Extension = string(e) -} - -// WithExtension sets the extension of the Maven (mvn) artifact. -func WithExtension(e string) Option { - return extension(e) -} - -func (a *AccessSpec) Describe(_ accspeccpi.Context) string { - return fmt.Sprintf("Maven (mvn) package '%s' in repository '%s' path '%s'", a.Coordinates.String(), a.Repository, a.Coordinates.FilePath()) -} - -func (_ *AccessSpec) IsLocal(accspeccpi.Context) bool { - return false -} - -func (a *AccessSpec) GlobalAccessSpec(_ accspeccpi.Context) accspeccpi.AccessSpec { - return a -} - -// GetReferenceHint returns the reference hint for the Maven (mvn) artifact. -func (a *AccessSpec) GetReferenceHint(_ accspeccpi.ComponentVersionAccess) string { - return a.String() -} - -func (_ *AccessSpec) GetType() string { - return Type -} - -func (a *AccessSpec) AccessMethod(c accspeccpi.ComponentVersionAccess) (accspeccpi.AccessMethod, error) { - return accspeccpi.AccessMethodForImplementation(newMethod(c, a)) -} - -func (a *AccessSpec) GetInexpensiveContentVersionIdentity(access accspeccpi.ComponentVersionAccess) string { - meta, _ := a.GetPackageMeta(access.GetContext()) - if meta != nil { - return meta.Hash - } - return "" -} - -func (a *AccessSpec) BaseUrl() string { - return a.Repository + "/" + a.GavPath() -} - -func (a *AccessSpec) ArtifactUrl() string { - return a.Url(a.Repository) -} - -func (a *AccessSpec) NewArtifact() *Coordinates { - return a.Coordinates.Copy() -} - -type meta struct { - MimeType string `json:"packaging"` - HashType crypto.Hash `json:"hashType"` - Hash string `json:"hash"` - Bin string `json:"bin"` -} - -func update(a *AccessSpec, file string, hash crypto.Hash, metadata *meta, ctx accspeccpi.Context, fs vfs.FileSystem) error { - artifact := a.NewArtifact() - err := artifact.SetClassifierExtensionBy(file) - if err != nil { - return err - } - metadata.Bin = artifact.Url(a.Repository) - log := log.WithValues("file", metadata.Bin) - log.Debug("processing") - metadata.MimeType = artifact.MimeType() - if hash > 0 { - metadata.HashType = hash - metadata.Hash, err = getStringData(ctx, metadata.Bin+hashUrlExt(hash), fs) - if err != nil { - return errors.Wrapf(err, "cannot read %s digest of: %s", hash, metadata.Bin) - } - } else { - log.Warn("no digest available") - } - return nil -} - -func (a *AccessSpec) GetPackageMeta(ctx accspeccpi.Context) (*meta, error) { - fs := vfsattr.Get(ctx) - - log := log.WithValues("BaseUrl", a.BaseUrl()) - fileMap, err := a.GavFiles(ctx, fs) - if err != nil { - return nil, err - } - - if a.Classifier != "" { - fileMap = filterByClassifier(fileMap, a.Classifier) - } - - switch l := len(fileMap); { - case l <= 0: - return nil, errors.New("no maven artifact files found") - case l == 1 && (a.Extension != "" || a.Classifier != ""): - metadata := meta{} - for file, hash := range fileMap { - update(a, file, hash, &metadata, ctx, fs) - } - return &metadata, nil - // default: continue below with: create tempFs where all files can be downloaded to and packed together as tar.gz - } - - if (a.Extension == "") != (a.Classifier == "") { // XOR - log.Warn("Either classifier or extension have been specified, which results in an incomplete GAV!") - } - tempFs, err := osfs.NewTempFileSystem() - if err != nil { - return nil, err - } - defer vfs.Cleanup(tempFs) - - metadata := meta{} - for file, hash := range fileMap { - update(a, file, hash, &metadata, ctx, fs) - - // download the artifact into the temporary file system - e := func() error { - out, err := tempFs.Create(file) - if err != nil { - return err - } - defer out.Close() - reader, err := getReader(ctx, metadata.Bin, fs) - if err != nil { - return err - } - defer reader.Close() - if hash > 0 { - dreader := iotools.NewDigestReaderWithHash(hash, reader) - _, err = io.Copy(out, dreader) - if err != nil { - return err - } - sum := dreader.Digest().Encoded() - if metadata.Hash != sum { - return errors.Newf("%s digest mismatch: expected %s, found %s", metadata.HashType, metadata.Hash, sum) - } - } else { - _, err = io.Copy(out, reader) - return err - } - return err - }() - if e != nil { - return nil, e - } - } - - // pack all downloaded files into a tar.gz file - tgz, err := vfs.TempFile(fs, "", Type+"-"+a.NewArtifact().FileNamePrefix()+"-*.tar.gz") - if err != nil { - return nil, err - } - defer tgz.Close() - - dw := iotools.NewDigestWriterWith(digest.SHA256, tgz) - defer dw.Close() - err = tarutils.TgzFs(tempFs, dw) - if err != nil { - return nil, err - } - - metadata.Bin = "file://" + tgz.Name() - metadata.MimeType = mime.MIME_TGZ - metadata.Hash = dw.Digest().Encoded() - metadata.HashType = crypto.SHA256 - log.Debug("created", "file", metadata.Bin) - - return &metadata, nil -} - -func filterByClassifier(fileMap map[string]crypto.Hash, classifier string) map[string]crypto.Hash { - for file := range fileMap { - if !strings.Contains(file, "-"+classifier+".") { - delete(fileMap, file) - } - } - return fileMap -} - -func (a *AccessSpec) GavFiles(ctx accspeccpi.Context, fs ...vfs.FileSystem) (map[string]crypto.Hash, error) { - if strings.HasPrefix(a.Repository, "file://") { - dir := path.Join(a.Repository[7:], a.GavPath()) - return gavFilesFromDisk(utils.FileSystem(fs...), dir) - } - return a.gavOnlineFiles(ctx) -} - -func gavFilesFromDisk(fs vfs.FileSystem, dir string) (map[string]crypto.Hash, error) { - files, err := tarutils.ListSortedFilesInDir(fs, dir, true) - if err != nil { - return nil, err - } - return filesAndHashes(files), nil -} - -// gavOnlineFiles returns the files of the Maven (mvn) artifact in the repository and their available digests. -func (a *AccessSpec) gavOnlineFiles(ctx accspeccpi.Context) (map[string]crypto.Hash, error) { - log := log.WithValues("BaseUrl", a.BaseUrl()) - log.Debug("gavOnlineFiles") - - reader, err := getReader(ctx, a.BaseUrl(), nil) - if err != nil { - return nil, err - } - defer reader.Close() - - // Which files are listed in the repository? - log.Debug("parse-html") - htmlDoc, err := html.Parse(reader) - if err != nil { - return nil, err - } - var fileList []string - var process func(*html.Node) - prefix := a.FileNamePrefix() - process = func(node *html.Node) { - // check if the node is an element node and the tag is "" - if node.Type == html.ElementNode && node.Data == "a" { - for _, attribute := range node.Attr { - if attribute.Key == "href" { - // check if the href starts with artifactId-version - if strings.HasPrefix(attribute.Val, prefix) { - fileList = append(fileList, attribute.Val) - } - } - } - } - for nextChild := node.FirstChild; nextChild != nil; nextChild = nextChild.NextSibling { - process(nextChild) // recursive call! - } - } - process(htmlDoc) - - return filesAndHashes(fileList), nil -} - -func filesAndHashes(fileList []string) map[string]crypto.Hash { - // Sort the list of files, to ensure always the same results for e.g. identical tar.gz files. - sort.Strings(fileList) - - // Which hash files are available? - result := make(map[string]crypto.Hash, len(fileList)/2) - for _, file := range fileList { - if IsResource(file) { - result[file] = bestAvailableHash(fileList, file) - log.Debug("found", "file", file) - } - } - return result -} - -// bestAvailableHash returns the best available hash for the given file. -// It first checks for SHA-512, then SHA-256, SHA-1, and finally MD5. If nothing is found, it returns 0. -func bestAvailableHash(list []string, filename string) crypto.Hash { - hashes := [5]crypto.Hash{crypto.SHA512, crypto.SHA256, crypto.SHA1, crypto.MD5} - for _, hash := range hashes { - if slices.Contains(list, filename+hashUrlExt(hash)) { - return hash - } - } - return 0 -} - -//////////////////////////////////////////////////////////////////////////////// - -// getStringData reads all data from the given URL and returns it as a string. -func getStringData(ctx accspeccpi.Context, url string, fs vfs.FileSystem) (string, error) { - r, err := getReader(ctx, url, fs) - if err != nil { - return "", err - } - defer r.Close() - b, err := io.ReadAll(r) - if err != nil { - return "", err - } - return string(b), nil -} - -// hashUrlExt returns the 'maven' hash extension for the given hash. -// Maven usually uses sha1, sha256, sha512, md5 instead of SHA-1, SHA-256, SHA-512, MD5. -func hashUrlExt(h crypto.Hash) string { - return "." + strings.ReplaceAll(strings.ToLower(h.String()), "-", "") -} - -func newMethod(c accspeccpi.ComponentVersionAccess, a *AccessSpec) (accspeccpi.AccessMethodImpl, error) { - factory := func() (blobaccess.BlobAccess, error) { - meta, err := a.GetPackageMeta(c.GetContext()) - if err != nil { - return nil, err - } - - reader := func() (io.ReadCloser, error) { - return getReader(c.GetContext(), meta.Bin, vfsattr.Get(c.GetContext())) - } - if meta.Hash != "" { - getreader := reader - reader = func() (io.ReadCloser, error) { - readCloser, err := getreader() - if err != nil { - return nil, err - } - return iotools.VerifyingReaderWithHash(readCloser, meta.HashType, meta.Hash), nil - } - } - acc := blobaccess.DataAccessForReaderFunction(reader, meta.Bin) - return accessobj.CachedBlobAccessForWriter(c.GetContext(), a.MimeType(), accessio.NewDataAccessWriter(acc)), nil - } - // FIXME add Digest! - return accspeccpi.NewDefaultMethodImpl(c, a, "", a.MimeType(), factory), nil -} - -func getReader(ctx accspeccpi.Context, url string, fs vfs.FileSystem) (io.ReadCloser, error) { - if strings.HasPrefix(url, "file://") { - path := url[7:] - return fs.OpenFile(path, vfs.O_RDONLY, 0o600) - } - - req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil) - if err != nil { - return nil, err - } - err = identity.BasicAuth(req, ctx, url, "") - if err != nil { - return nil, err - } - httpClient := &http.Client{} - resp, err := httpClient.Do(req) - if err != nil { - return nil, err - } - if resp.StatusCode != http.StatusOK { - defer resp.Body.Close() - buf := &bytes.Buffer{} - _, err = io.Copy(buf, io.LimitReader(resp.Body, 2000)) - if err == nil { - log.Error("http", "code", resp.Status, "url", url, "body", buf.String()) - } - return nil, errors.Newf("http %s error - %s", resp.Status, url) - } - return resp.Body, nil -} diff --git a/pkg/contexts/ocm/accessmethods/mvn/method_test.go b/pkg/contexts/ocm/accessmethods/mvn/method_test.go deleted file mode 100644 index 7b4ca85a80..0000000000 --- a/pkg/contexts/ocm/accessmethods/mvn/method_test.go +++ /dev/null @@ -1,87 +0,0 @@ -package mvn_test - -import ( - "crypto" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/open-component-model/ocm/pkg/contexts/ocm" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/mvn" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - . "github.com/open-component-model/ocm/pkg/env" - . "github.com/open-component-model/ocm/pkg/env/builder" - "github.com/open-component-model/ocm/pkg/iotools" - "github.com/open-component-model/ocm/pkg/mime" - . "github.com/open-component-model/ocm/pkg/testutils" -) - -const ( - mvnPATH = "/testdata/.m2/repository" - FAILPATH = "/testdata/fail" -) - -var _ = Describe("local accessmethods.mvn.AccessSpec tests", func() { - var env *Builder - var cv ocm.ComponentVersionAccess - - BeforeEach(func() { - env = NewBuilder(TestData()) - cv = &cpi.DummyComponentVersionAccess{env.OCMContext()} - }) - - AfterEach(func() { - env.Cleanup() - }) - - It("accesses local artifact", func() { - acc := mvn.New("file://"+mvnPATH, "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") - m := Must(acc.AccessMethod(cv)) - defer m.Close() - Expect(m.MimeType()).To(Equal(mime.MIME_TGZ)) - r := Must(m.Reader()) - defer r.Close() - dr := iotools.NewDigestReaderWithHash(crypto.SHA1, r) - for { - var buf [8096]byte - _, err := dr.Read(buf[:]) - if err != nil { - break - } - } - Expect(dr.Size()).To(Equal(int64(1109))) - Expect(dr.Digest().String()).To(Equal("SHA-1:4ee125ffe4f7690588833f1217a13cc741e4df5f")) - }) - - It("accesses local artifact with extension", func() { - acc := mvn.New("file://"+mvnPATH, "com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", mvn.WithExtension("pom")) - m := Must(acc.AccessMethod(cv)) - defer m.Close() - Expect(m.MimeType()).To(Equal(mime.MIME_XML)) - r := Must(m.Reader()) - defer r.Close() - dr := iotools.NewDigestReaderWithHash(crypto.SHA1, r) - for { - var buf [8096]byte - _, err := dr.Read(buf[:]) - if err != nil { - break - } - } - Expect(dr.Size()).To(Equal(int64(7153))) - Expect(dr.Digest().String()).To(Equal("SHA-1:34ccdeb9c008f8aaef90873fc636b09d3ae5c709")) - }) - - It("Describe", func() { - acc := mvn.New("file://"+FAILPATH, "test", "repository", "42", mvn.WithExtension("pom")) - Expect(acc.Describe(nil)).To(Equal("Maven (mvn) package 'test:repository:42::pom' in repository 'file:///testdata/fail' path 'test/repository/42/repository-42.pom'")) - }) - - It("detects digests mismatch", func() { - acc := mvn.New("file://"+FAILPATH, "test", "repository", "42", mvn.WithExtension("pom")) - m := Must(acc.AccessMethod(cv)) - defer m.Close() - _, err := m.Reader() - Expect(err).To(MatchError(ContainSubstring("SHA-1 digest mismatch: expected 44a77645201d1a8fc5213ace787c220eabbd0967, found b3242b8c31f8ce14f729b8fd132ac77bc4bc5bf7"))) - }) -}) diff --git a/pkg/contexts/ocm/accessmethods/options/standard.go b/pkg/contexts/ocm/accessmethods/options/standard.go index 7e8680f12b..cc666b3ecc 100644 --- a/pkg/contexts/ocm/accessmethods/options/standard.go +++ b/pkg/contexts/ocm/accessmethods/options/standard.go @@ -18,8 +18,11 @@ var ReferenceOption = RegisterOption(NewStringOptionType("reference", "reference // PackageOption. var PackageOption = RegisterOption(NewStringOptionType("accessPackage", "package or object name")) +// ArtifactOption. +var ArtifactOption = RegisterOption(NewStringOptionType("artifactId", "maven artifact id")) + // GroupOption. -var GroupOption = RegisterOption(NewStringOptionType("accessGroup", "GroupID or namespace")) +var GroupOption = RegisterOption(NewStringOptionType("groupId", "maven group id")) // RepositoryOption. var RepositoryOption = RegisterOption(NewStringOptionType("accessRepository", "repository URL")) @@ -60,7 +63,7 @@ var HTTPRedirectOption = RegisterOption(NewBoolOptionType("noredirect", "http re var CommentOption = RegisterOption(NewStringOptionType("comment", "comment field value")) // ClassifierOption the optional classifier of a maven resource. -var ClassifierOption = RegisterOption(NewStringOptionType("accessClassifier", "mvn classifier")) +var ClassifierOption = RegisterOption(NewStringOptionType("classifier", "maven classifier")) // ExtensionOption the optional extension of a maven resource. -var ExtensionOption = RegisterOption(NewStringOptionType("accessExtension", "mvn extension name")) +var ExtensionOption = RegisterOption(NewStringOptionType("extension", "maven extension name")) diff --git a/pkg/contexts/ocm/accessmethods/wget/options.go b/pkg/contexts/ocm/accessmethods/wget/options.go index 4693d6c697..fcf667661f 100644 --- a/pkg/contexts/ocm/accessmethods/wget/options.go +++ b/pkg/contexts/ocm/accessmethods/wget/options.go @@ -4,10 +4,7 @@ import ( "io" "net/http" - "github.com/mandelsoft/logging" - "github.com/open-component-model/ocm/pkg/blobaccess/wget" - "github.com/open-component-model/ocm/pkg/contexts/credentials" ) type ( @@ -15,22 +12,10 @@ type ( Option = wget.Option ) -func WithCredentialContext(ctx credentials.ContextProvider) Option { - return wget.WithCredentialContext(ctx) -} - -func WithLoggingContext(ctx logging.ContextProvider) Option { - return wget.WithLoggingContext(ctx) -} - func WithMimeType(mime string) Option { return wget.WithMimeType(mime) } -func WithCredentials(c credentials.Credentials) Option { - return wget.WithCredentials(c) -} - func WithHeader(h http.Header) Option { return wget.WithHeader(h) } diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler.go b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler.go new file mode 100644 index 0000000000..76dd8689bc --- /dev/null +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler.go @@ -0,0 +1,126 @@ +package maven + +import ( + "crypto" + + "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/vfs/pkg/vfs" + + mavenblob "github.com/open-component-model/ocm/pkg/blobaccess/maven" + "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/maven/identity" + access "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/maven" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" + "github.com/open-component-model/ocm/pkg/iotools" + "github.com/open-component-model/ocm/pkg/logging" + "github.com/open-component-model/ocm/pkg/maven" + "github.com/open-component-model/ocm/pkg/mime" + "github.com/open-component-model/ocm/pkg/utils/tarutils" +) + +const BlobHandlerName = "ocm/" + resourcetypes.MAVEN_ARTIFACT + +type artifactHandler struct { + spec *Config +} + +func NewArtifactHandler(repospec *Config) cpi.BlobHandler { + return &artifactHandler{repospec} +} + +var log = logging.DynamicLogger(identity.REALM) + +func (b *artifactHandler) StoreBlob(blob cpi.BlobAccess, resourceType string, hint string, _ cpi.AccessSpec, ctx cpi.StorageContext) (_ cpi.AccessSpec, rerr error) { + var finalize finalizer.Finalizer + defer finalize.FinalizeWithErrorPropagation(&rerr) + + // check conditions + if b.spec == nil { + return nil, nil + } + mimeType := blob.MimeType() + if resourcetypes.MAVEN_ARTIFACT != resourceType { + log.Debug("not a MVN artifact", "resourceType", resourceType) + return nil, nil + } + if mime.MIME_TGZ != mimeType { + log.Debug("not a tarball, can't be a complete maven GAV", "mimeType", mimeType) + return nil, nil + } + + repo, err := b.spec.GetRepository(ctx.GetContext()) + if err != nil { + return nil, err + } + + // setup logger + log := log.WithValues("repository", repo.String()) + // identify artifact + coords, err := maven.Parse(hint) + if err != nil { + return nil, err + } + if coords.Classifier != nil || coords.Extension != nil { + return nil, nil + } + log = log.WithValues("groupId", coords.GroupId, "artifactId", coords.ArtifactId, "version", coords.Version) + log.Debug("identified") + + blobReader, err := blob.Reader() + if err != nil { + return nil, err + } + finalize.Close(blobReader) + tempFs, err := tarutils.ExtractTgzToTempFs(blobReader) + if err != nil { + return nil, err + } + finalize.With(func() error { return vfs.Cleanup(tempFs) }) + files, err := tarutils.ListSortedFilesInDir(tempFs, "", false) + if err != nil { + return nil, err + } + for _, file := range files { + loop := finalize.Nested() + log.Debug("uploading", "file", file) + err := coords.SetClassifierExtensionBy(file) + if err != nil { + return nil, err + } + readHash, err := tempFs.Open(file) + if err != nil { + return nil, err + } + loop.Close(readHash) + // MD5 + SHA1 are still the most used ones in the maven context + hr := iotools.NewHashReader(readHash, crypto.SHA256, crypto.SHA1, crypto.MD5) + _, err = hr.CalcHashes() + if err != nil { + return nil, err + } + reader, err := tempFs.Open(file) + if err != nil { + return nil, err + } + loop.Close(reader) + creds, err := mavenblob.GetCredentials(ctx.GetContext(), repo, coords.GroupId) + if err != nil { + return nil, err + } + err = repo.Upload(coords, reader, creds, hr.Hashes()) + if err != nil { + return nil, err + } + err = loop.Finalize() + if err != nil { + return nil, err + } + } + + log.Debug("done", "artifact", coords) + url, err := repo.Url() + if err != nil { + return nil, err + } + return access.New(url, coords.GroupId, coords.ArtifactId, coords.Version), nil +} diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler_test.go b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler_test.go new file mode 100644 index 0000000000..76532ed6bf --- /dev/null +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/blobhandler_test.go @@ -0,0 +1,101 @@ +package maven_test + +import ( + "encoding/json" + "github.com/open-component-model/ocm/pkg/maven/maventest" + "os" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/env/builder" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/mandelsoft/goutils/sliceutils" + "github.com/mandelsoft/vfs/pkg/vfs" + + mavenblob "github.com/open-component-model/ocm/pkg/blobaccess/maven" + me "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/maven" + "github.com/open-component-model/ocm/pkg/contexts/ocm/elements" + "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/composition" + "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" + "github.com/open-component-model/ocm/pkg/maven" +) + +const MAVEN_PATH = "/testdata/.m2/repository" + +var _ = Describe("blobhandler generic maven tests", func() { + var env *Builder + var repo *maven.Repository + + BeforeEach(func() { + env = NewBuilder(maventest.TestData()) + repo = maven.NewFileRepository(MAVEN_PATH, env.FileSystem()) + }) + + It("Unmarshal upload response Body", func() { + resp := `{ "repo" : "ocm-mvn-test", + "path" : "/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar", + "created" : "2024-04-11T15:09:28.920Z", + "createdBy" : "john.doe", + "downloadUri" : "https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar", + "mimeType" : "application/java-archive", + "size" : "1792", + "checksums" : { + "sha1" : "99d9acac1ff93ac3d52229edec910091af1bc40a", + "md5" : "6cb7520b65d820b3b35773a8daa8368e", + "sha256" : "b19dcd275f72a0cbdead1e5abacb0ef25a0cb55ff36252ef44b1178eeedf9c30" }, + "originalChecksums" : { + "sha256" : "b19dcd275f72a0cbdead1e5abacb0ef25a0cb55ff36252ef44b1178eeedf9c30" }, + "uri" : "https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar" }` + var body maven.Body + err := json.Unmarshal([]byte(resp), &body) + Expect(err).To(BeNil()) + Expect(body.Repo).To(Equal("ocm-mvn-test")) + Expect(body.DownloadUri).To(Equal("https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar")) + Expect(body.Uri).To(Equal("https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar")) + Expect(body.MimeType).To(Equal("application/java-archive")) + Expect(body.Size).To(Equal("1792")) + Expect(body.Checksums["md5"]).To(Equal("6cb7520b65d820b3b35773a8daa8368e")) + Expect(body.Checksums["sha1"]).To(Equal("99d9acac1ff93ac3d52229edec910091af1bc40a")) + Expect(body.Checksums["sha256"]).To(Equal("b19dcd275f72a0cbdead1e5abacb0ef25a0cb55ff36252ef44b1178eeedf9c30")) + Expect(body.Checksums["sha512"]).To(Equal("")) + }) + + It("Upload artifact to file system", func() { + env.OCMContext().BlobHandlers().Register(me.NewArtifactHandler(me.NewFileConfig("target", env.FileSystem()))) + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") + bacc := Must(mavenblob.BlobAccessForMavenCoords(repo, coords, mavenblob.WithCachingFileSystem(env.FileSystem()))) + defer Close(bacc) + ocmrepo := composition.NewRepository(env) + defer Close(ocmrepo) + cv := composition.NewComponentVersion(env, "acme.org/test", "1.0.0") + MustBeSuccessful(cv.SetResourceBlob(Must(elements.ResourceMeta("test", resourcetypes.MAVEN_ARTIFACT)), bacc, coords.GAV(), nil)) + MustBeSuccessful(ocmrepo.AddComponentVersion(cv)) + l := sliceutils.Transform(Must(vfs.ReadDir(env.FileSystem(), "target/com/sap/cloud/sdk/sdk-modules-bom/5.7.0")), + func(info os.FileInfo) string { + return info.Name() + }) + Expect(l).To(ConsistOf( + "sdk-modules-bom-5.7.0-random-content.json", + "sdk-modules-bom-5.7.0-random-content.json.md5", + "sdk-modules-bom-5.7.0-random-content.json.sha1", + "sdk-modules-bom-5.7.0-random-content.json.sha256", + "sdk-modules-bom-5.7.0-random-content.txt", + "sdk-modules-bom-5.7.0-random-content.txt.md5", + "sdk-modules-bom-5.7.0-random-content.txt.sha1", + "sdk-modules-bom-5.7.0-random-content.txt.sha256", + "sdk-modules-bom-5.7.0-sources.jar", + "sdk-modules-bom-5.7.0-sources.jar.md5", + "sdk-modules-bom-5.7.0-sources.jar.sha1", + "sdk-modules-bom-5.7.0-sources.jar.sha256", + "sdk-modules-bom-5.7.0.jar", + "sdk-modules-bom-5.7.0.jar.md5", + "sdk-modules-bom-5.7.0.jar.sha1", + "sdk-modules-bom-5.7.0.jar.sha256", + "sdk-modules-bom-5.7.0.pom", + "sdk-modules-bom-5.7.0.pom.md5", + "sdk-modules-bom-5.7.0.pom.sha1", + "sdk-modules-bom-5.7.0.pom.sha256")) + }) + +}) diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/registration.go similarity index 51% rename from pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go rename to pkg/contexts/ocm/blobhandler/handlers/generic/maven/registration.go index be1436b455..f6024503c2 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration.go +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/registration.go @@ -1,23 +1,61 @@ -package mvn +package maven import ( "encoding/json" "fmt" "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/general" + "github.com/mandelsoft/vfs/pkg/vfs" + "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" + "github.com/open-component-model/ocm/pkg/maven" "github.com/open-component-model/ocm/pkg/mime" "github.com/open-component-model/ocm/pkg/registrations" + "github.com/open-component-model/ocm/pkg/utils" ) +func init() { + cpi.RegisterBlobHandlerRegistrationHandler(BlobHandlerName, &RegistrationHandler{}) +} + type Config struct { - Url string `json:"url"` + Url string `json:"url"` + Path string `json:"path"` + FileSystem vfs.FileSystem `json:"-"` +} + +func NewFileConfig(path string, fss ...vfs.FileSystem) *Config { + return &Config{ + Path: path, + FileSystem: utils.FileSystem(fss...), + } +} + +func NewUrlConfig(url string, fss ...vfs.FileSystem) *Config { + return &Config{ + Url: url, + FileSystem: utils.FileSystem(fss...), + } } type rawConfig Config +func (c *Config) GetRepository(ctx cpi.ContextProvider) (*maven.Repository, error) { + if c.Url != "" && c.Path != "" { + return nil, fmt.Errorf("cannot specify both url and path") + } + if c.Url != "" { + return maven.NewUrlRepository(c.Url, general.OptionalDefaulted(vfsattr.Get(ctx.OCMContext()), c.FileSystem)) + } + if c.Path != "" { + return maven.NewFileRepository(c.Path, general.OptionalDefaulted(vfsattr.Get(ctx.OCMContext()), c.FileSystem)), nil + } + return nil, fmt.Errorf("must specify either url or path") +} + func (c *Config) UnmarshalJSON(data []byte) error { err := json.Unmarshal(data, &c.Url) if err == nil { @@ -33,20 +71,16 @@ func (c *Config) UnmarshalJSON(data []byte) error { return nil } -func init() { - cpi.RegisterBlobHandlerRegistrationHandler(BlobHandlerName, &RegistrationHandler{}) -} - type RegistrationHandler struct{} var _ cpi.BlobHandlerRegistrationHandler = (*RegistrationHandler)(nil) func (r *RegistrationHandler) RegisterByName(handler string, ctx cpi.Context, config cpi.BlobHandlerConfig, olist ...cpi.BlobHandlerOption) (bool, error) { if handler != "" { - return true, fmt.Errorf("invalid %s handler %q", resourcetypes.MVN_ARTIFACT, handler) + return true, fmt.Errorf("invalid %s handler %q", resourcetypes.MAVEN_ARTIFACT, handler) } if config == nil { - return true, fmt.Errorf("mvn target specification required") + return true, fmt.Errorf("maven target specification required") } cfg, err := registrations.DecodeConfig[Config](config) if err != nil { @@ -54,7 +88,7 @@ func (r *RegistrationHandler) RegisterByName(handler string, ctx cpi.Context, co } ctx.BlobHandlers().Register(NewArtifactHandler(cfg), - cpi.ForArtifactType(resourcetypes.MVN_ARTIFACT), + cpi.ForArtifactType(resourcetypes.MAVEN_ARTIFACT), cpi.ForMimeType(mime.MIME_TGZ), cpi.NewBlobHandlerOptions(olist...), ) @@ -63,13 +97,13 @@ func (r *RegistrationHandler) RegisterByName(handler string, ctx cpi.Context, co } func (r *RegistrationHandler) GetHandlers(_ cpi.Context) registrations.HandlerInfos { - return registrations.NewLeafHandlerInfo("uploading mvn artifacts", ` -The `+BlobHandlerName+` uploader is able to upload mvn artifacts (whole GAV only!) -as artifact archive according to the mvn artifact spec. + return registrations.NewLeafHandlerInfo("uploading maven artifacts", ` +The `+BlobHandlerName+` uploader is able to upload maven artifacts (whole GAV only!) +as artifact archive according to the maven artifact spec. If registered the default mime type is: `+mime.MIME_TGZ+` It accepts a plain string for the URL or a config with the following field: -'url': the URL of the mvn repository. +'url': the URL of the maven repository. `, ) } diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration_test.go b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/registration_test.go similarity index 58% rename from pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration_test.go rename to pkg/contexts/ocm/blobhandler/handlers/generic/maven/registration_test.go index c64b3e13bb..e64514fbc6 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/registration_test.go +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/registration_test.go @@ -1,23 +1,23 @@ -package mvn_test +package maven_test import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/open-component-model/ocm/pkg/testutils" - "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/mvn" + "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/maven" "github.com/open-component-model/ocm/pkg/registrations" ) var _ = Describe("Config deserialization Test Environment", func() { It("deserializes string", func() { - cfg := Must(registrations.DecodeConfig[mvn.Config]("test")) - Expect(cfg).To(Equal(&mvn.Config{Url: "test"})) + cfg := Must(registrations.DecodeConfig[maven.Config]("test")) + Expect(cfg).To(Equal(&maven.Config{Url: "test"})) }) It("deserializes struct", func() { - cfg := Must(registrations.DecodeConfig[mvn.Config](`{"Url":"test"}`)) - Expect(cfg).To(Equal(&mvn.Config{Url: "test"})) + cfg := Must(registrations.DecodeConfig[maven.Config](`{"url":"test"}`)) + Expect(cfg).To(Equal(&maven.Config{Url: "test"})) }) }) diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/maven/suite_test.go b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/suite_test.go new file mode 100644 index 0000000000..d43b2dbd6b --- /dev/null +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/maven/suite_test.go @@ -0,0 +1,13 @@ +package maven_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Maven Test Suite") +} diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go b/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go deleted file mode 100644 index 0a11fcc96f..0000000000 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler.go +++ /dev/null @@ -1,180 +0,0 @@ -package mvn - -import ( - "context" - "crypto" - "encoding/json" - "fmt" - "io" - "net/http" - "strings" - - "github.com/mandelsoft/goutils/errors" - "github.com/mandelsoft/vfs/pkg/vfs" - - "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/mvn/identity" - "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/mvn" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi/accspeccpi" - "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - "github.com/open-component-model/ocm/pkg/iotools" - "github.com/open-component-model/ocm/pkg/logging" - "github.com/open-component-model/ocm/pkg/mime" - "github.com/open-component-model/ocm/pkg/utils/tarutils" -) - -const BlobHandlerName = "ocm/" + resourcetypes.MVN_ARTIFACT - -type artifactHandler struct { - spec *Config -} - -func NewArtifactHandler(repospec *Config) cpi.BlobHandler { - return &artifactHandler{repospec} -} - -var log = logging.DynamicLogger(identity.REALM) - -func (b *artifactHandler) StoreBlob(blob cpi.BlobAccess, resourceType string, hint string, _ cpi.AccessSpec, ctx cpi.StorageContext) (cpi.AccessSpec, error) { - // check conditions - if b.spec == nil { - return nil, nil - } - mimeType := blob.MimeType() - if resourcetypes.MVN_ARTIFACT != resourceType { - log.Debug("not a MVN artifact", "resourceType", resourceType) - return nil, nil - } - if mime.MIME_TGZ != mimeType { - log.Debug("not a tarball, can't be a complete mvn GAV", "mimeType", mimeType) - return nil, nil - } - if b.spec.Url == "" { - return nil, errors.New("MVN repository url not provided") - } - - // setup logger - log := log.WithValues("repository", b.spec.Url) - // identify artifact - artifact, err := mvn.Parse(hint) - if err != nil { - return nil, err - } - log = log.WithValues("groupId", artifact.GroupId, "artifactId", artifact.ArtifactId, "version", artifact.Version) - log.Debug("identified") - - blobReader, err := blob.Reader() - if err != nil { - return nil, err - } - defer blobReader.Close() - tempFs, err := tarutils.ExtractTgzToTempFs(blobReader) - if err != nil { - return nil, err - } - defer vfs.Cleanup(tempFs) - files, err := tarutils.ListSortedFilesInDir(tempFs, "", false) - if err != nil { - return nil, err - } - for _, file := range files { - e := func() (err error) { - log.Debug("uploading", "file", file) - err = artifact.SetClassifierExtensionBy(file) - if err != nil { - return - } - readHash, err := tempFs.Open(file) - if err != nil { - return - } - defer readHash.Close() - // MD5 + SHA1 are still the most used ones in the mvn context - hr := iotools.NewHashReader(readHash, crypto.SHA256, crypto.SHA1, crypto.MD5) - _, err = hr.CalcHashes() - if err != nil { - return - } - reader, err := tempFs.Open(file) - if err != nil { - return - } - defer reader.Close() - err = deploy(artifact, b.spec.Url, reader, ctx.GetContext(), hr) - return - }() - if e != nil { - return nil, e - } - } - - log.Debug("done", "artifact", artifact) - return mvn.New(b.spec.Url, artifact.GroupId, artifact.ArtifactId, artifact.Version, mvn.WithClassifier(artifact.Classifier), mvn.WithExtension(artifact.Extension)), nil -} - -// deploy an artifact to the specified destination. See https://jfrog.com/help/r/jfrog-rest-apis/deploy-artifact -func deploy(artifact *mvn.Coordinates, url string, reader io.ReadCloser, ctx accspeccpi.Context, hashes *iotools.HashReader) (err error) { - req, err := http.NewRequestWithContext(context.Background(), http.MethodPut, artifact.Url(url), reader) - if err != nil { - return - } - err = identity.BasicAuth(req, ctx, url, artifact.GroupPath()) - if err != nil { - return - } - // give the remote server a chance to decide based upon the checksum policy - for k, v := range hashes.HttpHeader() { - req.Header.Set(k, v) - } - - // Execute the request - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - return - } - defer resp.Body.Close() - - // Check the response - if resp.StatusCode != http.StatusCreated { - all, e := io.ReadAll(resp.Body) - if e != nil { - return e - } - return fmt.Errorf("http (%d) - failed to upload artifact: %s", resp.StatusCode, string(all)) - } - log.Debug("uploaded", "artifact", artifact, "extension", artifact.Extension, "classifier", artifact.Classifier) - - // Validate the response - especially the hash values with the ones we've tried to send - respBody, err := io.ReadAll(resp.Body) - if err != nil { - return - } - var artifactBody Body - err = json.Unmarshal(respBody, &artifactBody) - if err != nil { - return - } - - // let's check only SHA256 for now - digest := hashes.GetString(crypto.SHA256) - remoteDigest := artifactBody.Checksums[strings.ReplaceAll(strings.ToLower(crypto.SHA256.String()), "-", "")] - if remoteDigest == "" { - log.Warn("no checksum found for algorithm, we can't guarantee that the artifact has been uploaded correctly", "algorithm", crypto.SHA256) - } else if remoteDigest != digest { - return errors.New("failed to upload artifact: checksums do not match") - } - log.Debug("digests are ok", "remoteDigest", remoteDigest, "digest", digest) - return -} - -// Body is the response struct of a deployment from the MVN repository (JFrog Artifactory). -type Body struct { - Repo string `json:"repo"` - Path string `json:"path"` - DownloadUri string `json:"downloadUri"` - Uri string `json:"uri"` - MimeType string `json:"mimeType"` - Size string `json:"size"` - Checksums map[string]string `json:"checksums"` -} diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler_test.go b/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler_test.go deleted file mode 100644 index a632ace444..0000000000 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/mvn/blobhandler_test.go +++ /dev/null @@ -1,43 +0,0 @@ -package mvn_test - -import ( - "encoding/json" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - - "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/mvn" -) - -var _ = Describe("blobhandler generic mvn tests", func() { - - It("Unmarshal deploy response Body", func() { - resp := `{ "repo" : "ocm-mvn-test", - "path" : "/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar", - "created" : "2024-04-11T15:09:28.920Z", - "createdBy" : "john.doe", - "downloadUri" : "https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar", - "mimeType" : "application/java-archive", - "size" : "1792", - "checksums" : { - "sha1" : "99d9acac1ff93ac3d52229edec910091af1bc40a", - "md5" : "6cb7520b65d820b3b35773a8daa8368e", - "sha256" : "b19dcd275f72a0cbdead1e5abacb0ef25a0cb55ff36252ef44b1178eeedf9c30" }, - "originalChecksums" : { - "sha256" : "b19dcd275f72a0cbdead1e5abacb0ef25a0cb55ff36252ef44b1178eeedf9c30" }, - "uri" : "https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar" }` - var body mvn.Body - err := json.Unmarshal([]byte(resp), &body) - Expect(err).To(BeNil()) - Expect(body.Repo).To(Equal("ocm-mvn-test")) - Expect(body.DownloadUri).To(Equal("https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar")) - Expect(body.Uri).To(Equal("https://ocm.sofware/repository/ocm-mvn-test/open-component-model/hello-ocm/0.0.2/hello-ocm-0.0.2.jar")) - Expect(body.MimeType).To(Equal("application/java-archive")) - Expect(body.Size).To(Equal("1792")) - Expect(body.Checksums["md5"]).To(Equal("6cb7520b65d820b3b35773a8daa8368e")) - Expect(body.Checksums["sha1"]).To(Equal("99d9acac1ff93ac3d52229edec910091af1bc40a")) - Expect(body.Checksums["sha256"]).To(Equal("b19dcd275f72a0cbdead1e5abacb0ef25a0cb55ff36252ef44b1178eeedf9c30")) - Expect(body.Checksums["sha512"]).To(Equal("")) - }) - -}) diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/npm/registration_test.go b/pkg/contexts/ocm/blobhandler/handlers/generic/npm/registration_test.go index 89aae1d6e9..e254dd1ede 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/npm/registration_test.go +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/npm/registration_test.go @@ -17,7 +17,7 @@ var _ = Describe("Config deserialization Test Environment", func() { }) It("deserializes struct", func() { - cfg := Must(registrations.DecodeConfig[npm.Config](`{"Url":"test"}`)) + cfg := Must(registrations.DecodeConfig[npm.Config](`{"url":"test"}`)) Expect(cfg).To(Equal(&npm.Config{Url: "test"})) }) }) diff --git a/pkg/contexts/ocm/blobhandler/handlers/init.go b/pkg/contexts/ocm/blobhandler/handlers/init.go index b318fe2c9e..3fd4df2811 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/init.go +++ b/pkg/contexts/ocm/blobhandler/handlers/init.go @@ -1,7 +1,7 @@ package handlers import ( - _ "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/mvn" + _ "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/maven" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/npm" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/generic/ocirepo" _ "github.com/open-component-model/ocm/pkg/contexts/ocm/blobhandler/handlers/oci/ocirepo" diff --git a/pkg/contexts/ocm/cpi/builder.go b/pkg/contexts/ocm/cpi/builder.go new file mode 100644 index 0000000000..ea045d4983 --- /dev/null +++ b/pkg/contexts/ocm/cpi/builder.go @@ -0,0 +1,50 @@ +package cpi + +import ( + "context" + + "github.com/open-component-model/ocm/pkg/contexts/credentials" + "github.com/open-component-model/ocm/pkg/contexts/datacontext" + "github.com/open-component-model/ocm/pkg/contexts/oci" + "github.com/open-component-model/ocm/pkg/contexts/ocm/internal" +) + +func WithContext(ctx context.Context) internal.Builder { + return internal.Builder{}.WithContext(ctx) +} + +func WithCredentials(ctx credentials.Context) internal.Builder { + return internal.Builder{}.WithCredentials(ctx) +} + +func WithOCIRepositories(ctx oci.Context) internal.Builder { + return internal.Builder{}.WithOCIRepositories(ctx) +} + +func WithRepositoyTypeScheme(scheme RepositoryTypeScheme) internal.Builder { + return internal.Builder{}.WithRepositoyTypeScheme(scheme) +} + +func WithRepositoryDelegation(reg RepositoryDelegationRegistry) internal.Builder { + return internal.Builder{}.WithRepositoryDelegation(reg) +} + +func WithAccessypeScheme(scheme AccessTypeScheme) internal.Builder { + return internal.Builder{}.WithAccessTypeScheme(scheme) +} + +func WithRepositorySpecHandlers(reg RepositorySpecHandlers) internal.Builder { + return internal.Builder{}.WithRepositorySpecHandlers(reg) +} + +func WithBlobHandlers(reg BlobHandlerRegistry) internal.Builder { + return internal.Builder{}.WithBlobHandlers(reg) +} + +func WithBlobDigesters(reg BlobDigesterRegistry) internal.Builder { + return internal.Builder{}.WithBlobDigesters(reg) +} + +func New(mode ...datacontext.BuilderMode) Context { + return internal.Builder{}.New(mode...) +} diff --git a/pkg/contexts/ocm/cpi/interface.go b/pkg/contexts/ocm/cpi/interface.go index 1e62109d1b..8b605836ea 100644 --- a/pkg/contexts/ocm/cpi/interface.go +++ b/pkg/contexts/ocm/cpi/interface.go @@ -110,10 +110,6 @@ func DefaultBlobHandlerProvider(ctx Context) BlobHandlerProvider { return internal.DefaultBlobHandlerProvider(ctx) } -func New() Context { - return internal.Builder{}.New() -} - func NewResourceMeta(name string, typ string, relation metav1.ResourceRelation) *ResourceMeta { return compdesc.NewResourceMeta(name, typ, relation) } diff --git a/pkg/contexts/ocm/elements/artifactaccess/mavenaccess/options.go b/pkg/contexts/ocm/elements/artifactaccess/mavenaccess/options.go new file mode 100644 index 0000000000..8a965b6958 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactaccess/mavenaccess/options.go @@ -0,0 +1,20 @@ +package mavenaccess + +import "github.com/open-component-model/ocm/pkg/maven" + +type ( + Options = maven.Coordinates + Option = maven.CoordinateOption +) + +type WithClassifier = maven.WithClassifier + +func WithOptionalClassifier(c *string) Option { + return maven.WithOptionalClassifier(c) +} + +type WithExtension = maven.WithExtension + +func WithOptionalExtension(e *string) Option { + return maven.WithOptionalExtension(e) +} diff --git a/pkg/contexts/ocm/elements/artifactaccess/mavenaccess/resource.go b/pkg/contexts/ocm/elements/artifactaccess/mavenaccess/resource.go new file mode 100644 index 0000000000..d2a1d2b21e --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactaccess/mavenaccess/resource.go @@ -0,0 +1,39 @@ +package mavenaccess + +import ( + "github.com/open-component-model/ocm/pkg/contexts/ocm" + access "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/maven" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactaccess/genericaccess" + "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" + "github.com/open-component-model/ocm/pkg/maven" +) + +const TYPE = resourcetypes.MAVEN_ARTIFACT + +func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, repoUrl, groupId, artifactId, version string, opts ...Option) cpi.ArtifactAccess[M] { + if meta.GetType() == "" { + meta.SetType(TYPE) + } + + spec := access.New(repoUrl, groupId, artifactId, version, opts...) + // is global access, must work, otherwise there is an error in the lib. + return genericaccess.MustAccess(ctx, meta, spec) +} + +func ResourceAccess(ctx ocm.Context, meta *cpi.ResourceMeta, repoUrl, groupId, artifactId, version string, opts ...Option) cpi.ResourceAccess { + return Access(ctx, meta, repoUrl, groupId, artifactId, version, opts...) +} + +func ResourceAccessForMavenCoords(ctx ocm.Context, meta *cpi.ResourceMeta, repoUrl string, coords *maven.Coordinates) cpi.ResourceAccess { + return Access(ctx, meta, repoUrl, coords.GroupId, coords.ArtifactId, coords.Version, WithOptionalClassifier(coords.Classifier), WithOptionalExtension(coords.Extension)) +} + +func SourceAccess(ctx ocm.Context, meta *cpi.SourceMeta, repoUrl, groupId, artifactId, version string, opts ...Option) cpi.SourceAccess { + return Access(ctx, meta, repoUrl, groupId, artifactId, version, opts...) +} + +func SourceAccessForMavenCoords(ctx ocm.Context, meta *cpi.SourceMeta, repoUrl string, coords *maven.Coordinates) cpi.SourceAccess { + return Access(ctx, meta, repoUrl, coords.GroupId, coords.ArtifactId, coords.Version, WithOptionalClassifier(coords.Classifier), WithOptionalExtension(coords.Extension)) +} diff --git a/pkg/contexts/ocm/elements/artifactaccess/mvnaccess/resource.go b/pkg/contexts/ocm/elements/artifactaccess/mvnaccess/resource.go deleted file mode 100644 index 6c90b396a9..0000000000 --- a/pkg/contexts/ocm/elements/artifactaccess/mvnaccess/resource.go +++ /dev/null @@ -1,30 +0,0 @@ -package mvnaccess - -import ( - "github.com/open-component-model/ocm/pkg/contexts/ocm" - access "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/mvn" - "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" - "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" - "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactaccess/genericaccess" - "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" -) - -const TYPE = resourcetypes.MVN_ARTIFACT - -func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, repository, groupId, artifactId, version string) cpi.ArtifactAccess[M] { - if meta.GetType() == "" { - meta.SetType(TYPE) - } - - spec := access.New(repository, groupId, artifactId, version) - // is global access, must work, otherwise there is an error in the lib. - return genericaccess.MustAccess(ctx, meta, spec) -} - -func ResourceAccess(ctx ocm.Context, meta *cpi.ResourceMeta, repository, groupId, artifactId, version string) cpi.ResourceAccess { - return Access(ctx, meta, repository, groupId, artifactId, version) -} - -func SourceAccess(ctx ocm.Context, meta *cpi.SourceMeta, repository, groupId, artifactId, version string) cpi.SourceAccess { - return Access(ctx, meta, repository, groupId, artifactId, version) -} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/helmblob_test.go b/pkg/contexts/ocm/elements/artifactblob/helmblob/helmblob_test.go new file mode 100644 index 0000000000..1889da3ee4 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/helmblob_test.go @@ -0,0 +1,37 @@ +package helmblob_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/open-component-model/ocm/pkg/env/builder" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/open-component-model/ocm/pkg/common/accessobj" + metav1 "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc/meta/v1" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + me "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/helmblob" + ctfocm "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ctf" + "github.com/open-component-model/ocm/pkg/env" +) + +var _ = Describe("", func() { + var e *Builder + + BeforeEach(func() { + e = NewBuilder(env.TestData()) + + }) + + AfterEach(func() { + MustBeSuccessful(e.Cleanup()) + }) + + It("", func() { + ctf := Must(ctfocm.Open(e, accessobj.ACC_CREATE, "/repo", 0o700, e, ctfocm.FormatDirectory)) + defer Close(ctf) + cv := Must(ctf.NewComponentVersion("ocm.software/test-component", "1.0.0")) + defer Close(cv) + MustBeSuccessful(cv.SetResourceAccess(me.ResourceAccess(e.OCMContext(), cpi.NewResourceMeta("helm1", "blob", metav1.LocalRelation), "/testdata/testchart1", me.WithFileSystem(e.FileSystem())))) + MustBeSuccessful(cv.SetResourceAccess(me.ResourceAccess(e.OCMContext(), cpi.NewResourceMeta("helm2", "blob", metav1.LocalRelation), "/testdata/testchart2", me.WithFileSystem(e.FileSystem())))) + MustBeSuccessful(ctf.AddComponentVersion(cv, true)) + }) +}) diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/suite_test.go b/pkg/contexts/ocm/elements/artifactblob/helmblob/suite_test.go new file mode 100644 index 0000000000..451b4150bc --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/suite_test.go @@ -0,0 +1,13 @@ +package helmblob_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Helm Blob Test Suite") +} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.helmignore b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.idea/somefile b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/.idea/somefile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/Chart.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/Chart.yaml new file mode 100644 index 0000000000..01328a81ce --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: testchart1 +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/NOTES.txt b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/NOTES.txt new file mode 100644 index 0000000000..45e51670a8 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "testchart.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "testchart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "testchart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "testchart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/_helpers.tpl b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/_helpers.tpl new file mode 100644 index 0000000000..4b0db05bf5 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "testchart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "testchart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "testchart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "testchart.labels" -}} +helm.sh/chart: {{ include "testchart.chart" . }} +{{ include "testchart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "testchart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "testchart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "testchart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "testchart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/deployment.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/deployment.yaml new file mode 100644 index 0000000000..69b8e08feb --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "testchart.fullname" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "testchart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "testchart.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "testchart.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/hpa.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/hpa.yaml new file mode 100644 index 0000000000..51734471d4 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "testchart.fullname" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "testchart.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/ingress.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/ingress.yaml new file mode 100644 index 0000000000..9732d2a24a --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "testchart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "testchart.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/service.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/service.yaml new file mode 100644 index 0000000000..86baf14821 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "testchart.fullname" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "testchart.selectorLabels" . | nindent 4 }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/serviceaccount.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/serviceaccount.yaml new file mode 100644 index 0000000000..f728deb2a6 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "testchart.serviceAccountName" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/tests/test-connection.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/tests/test-connection.yaml new file mode 100644 index 0000000000..a391ef1c46 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "testchart.fullname" . }}-test-connection" + labels: + {{- include "testchart.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "testchart.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/values.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/values.yaml new file mode 100644 index 0000000000..b598adba92 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart1/values.yaml @@ -0,0 +1,81 @@ +# Default values for testchart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: gcr.io/google_containers/echoserver + pullPolicy: IfNotPresent + tag: "1.0" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.helmignore b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.helmignore new file mode 100644 index 0000000000..0e8a0eb36f --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.idea/somefile b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/.idea/somefile new file mode 100644 index 0000000000..e69de29bb2 diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/Chart.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/Chart.yaml new file mode 100644 index 0000000000..8f4b7146ce --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: testchart2 +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/NOTES.txt b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/NOTES.txt new file mode 100644 index 0000000000..45e51670a8 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "testchart.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "testchart.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "testchart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "testchart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/_helpers.tpl b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/_helpers.tpl new file mode 100644 index 0000000000..4b0db05bf5 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "testchart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "testchart.fullname" -}} +{{- if .Values.fullnameOverride }} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- $name := default .Chart.Name .Values.nameOverride }} +{{- if contains $name .Release.Name }} +{{- .Release.Name | trunc 63 | trimSuffix "-" }} +{{- else }} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} +{{- end }} +{{- end }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "testchart.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "testchart.labels" -}} +helm.sh/chart: {{ include "testchart.chart" . }} +{{ include "testchart.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "testchart.selectorLabels" -}} +app.kubernetes.io/name: {{ include "testchart.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "testchart.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "testchart.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/deployment.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/deployment.yaml new file mode 100644 index 0000000000..69b8e08feb --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "testchart.fullname" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "testchart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "testchart.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "testchart.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 8080 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/hpa.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/hpa.yaml new file mode 100644 index 0000000000..51734471d4 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/hpa.yaml @@ -0,0 +1,28 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "testchart.fullname" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "testchart.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/ingress.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/ingress.yaml new file mode 100644 index 0000000000..9732d2a24a --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/ingress.yaml @@ -0,0 +1,61 @@ +{{- if .Values.ingress.enabled -}} +{{- $fullName := include "testchart.fullname" . -}} +{{- $svcPort := .Values.service.port -}} +{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} + {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} + {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} + {{- end }} +{{- end }} +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1 +{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} +apiVersion: networking.k8s.io/v1beta1 +{{- else -}} +apiVersion: extensions/v1beta1 +{{- end }} +kind: Ingress +metadata: + name: {{ $fullName }} + labels: + {{- include "testchart.labels" . | nindent 4 }} + {{- with .Values.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + {{- if .Values.ingress.tls }} + tls: + {{- range .Values.ingress.tls }} + - hosts: + {{- range .hosts }} + - {{ . | quote }} + {{- end }} + secretName: {{ .secretName }} + {{- end }} + {{- end }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ .host | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path }} + {{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} + pathType: {{ .pathType }} + {{- end }} + backend: + {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} + service: + name: {{ $fullName }} + port: + number: {{ $svcPort }} + {{- else }} + serviceName: {{ $fullName }} + servicePort: {{ $svcPort }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/service.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/service.yaml new file mode 100644 index 0000000000..86baf14821 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "testchart.fullname" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: http + protocol: TCP + name: http + selector: + {{- include "testchart.selectorLabels" . | nindent 4 }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/serviceaccount.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/serviceaccount.yaml new file mode 100644 index 0000000000..f728deb2a6 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "testchart.serviceAccountName" . }} + labels: + {{- include "testchart.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/tests/test-connection.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/tests/test-connection.yaml new file mode 100644 index 0000000000..a391ef1c46 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "testchart.fullname" . }}-test-connection" + labels: + {{- include "testchart.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "testchart.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/values.yaml b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/values.yaml new file mode 100644 index 0000000000..b598adba92 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/helmblob/testdata/testchart2/values.yaml @@ -0,0 +1,81 @@ +# Default values for testchart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: gcr.io/google_containers/echoserver + pullPolicy: IfNotPresent + tag: "1.0" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + className: "" + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/pkg/contexts/ocm/elements/artifactblob/mavenblob/access_test.go b/pkg/contexts/ocm/elements/artifactblob/mavenblob/access_test.go new file mode 100644 index 0000000000..8bf2b4fdd9 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/mavenblob/access_test.go @@ -0,0 +1,61 @@ +package mavenblob_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/env/builder" + "github.com/open-component-model/ocm/pkg/maven/maventest" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/open-component-model/ocm/pkg/contexts/ocm/elements" + me "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/mavenblob" + "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/composition" + "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" + "github.com/open-component-model/ocm/pkg/maven" +) + +const ( + MAVEN_PATH = "/testdata/.m2/repository" + FAIL_PATH = "/testdata/.m2/fail" + MAVEN_CENTRAL_ADDRESS = "repo.maven.apache.org:443" + MAVEN_CENTRAL = "https://repo.maven.apache.org/maven2/" + MAVEN_GROUP_ID = "maven" + MAVEN_ARTIFACT_ID = "maven" + MAVEN_VERSION = "1.1" +) + +var _ = Describe("blobaccess for maven", func() { + + Context("maven filesystem repository", func() { + var env *Builder + var repo *maven.Repository + + BeforeEach(func() { + env = NewBuilder(maventest.TestData()) + repo = maven.NewFileRepository(MAVEN_PATH, env.FileSystem()) + }) + + AfterEach(func() { + MustBeSuccessful(env.Cleanup()) + }) + + It("blobaccess for a single file with classifier and extension", func() { + cv := composition.NewComponentVersion(env.OCMContext(), "acme.org/test", "1.0.0") + defer Close(cv) + + coords := maven.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", + maven.WithClassifier("random-content"), maven.WithExtension("json")) + + a := me.ResourceAccessForMavenCoords(env.OCMContext(), Must(elements.ResourceMeta("mavenblob", resourcetypes.OCM_JSON, elements.WithLocalRelation())), repo, coords, me.WithCachingFileSystem(env.FileSystem())) + b := Must(a.BlobAccess()) + defer Close(b) + Expect(string(Must(b.Get()))).To(Equal(`{"some": "test content"}`)) + + MustBeSuccessful(cv.SetResourceAccess(a)) + r := Must(cv.GetResourceByIndex(0)) + m := Must(r.AccessMethod()) + defer Close(m) + Expect(string(Must(m.Get()))).To(Equal(`{"some": "test content"}`)) + }) + }) +}) diff --git a/pkg/contexts/ocm/elements/artifactblob/mavenblob/options.go b/pkg/contexts/ocm/elements/artifactblob/mavenblob/options.go new file mode 100644 index 0000000000..6bc448da74 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/mavenblob/options.go @@ -0,0 +1,96 @@ +package mavenblob + +import ( + "github.com/mandelsoft/goutils/optionutils" + "github.com/mandelsoft/logging" + "github.com/mandelsoft/vfs/pkg/vfs" + + base "github.com/open-component-model/ocm/pkg/blobaccess/maven" + "github.com/open-component-model/ocm/pkg/contexts/credentials" + "github.com/open-component-model/ocm/pkg/contexts/datacontext" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + "github.com/open-component-model/ocm/pkg/contexts/ocm/elements/artifactblob/api" +) + +type Option = optionutils.Option[*Options] + +type Options struct { + api.Options + Blob base.Options +} + +var ( + _ api.GeneralOptionsProvider = (*Options)(nil) + _ Option = (*Options)(nil) +) + +func (o *Options) ApplyTo(opts *Options) { + o.Options.ApplyTo(&opts.Options) + o.Blob.ApplyTo(&opts.Blob) +} + +func (o *Options) Apply(opts ...Option) { + optionutils.ApplyOptions(o, opts...) +} + +//////////////////////////////////////////////////////////////////////////////// +// General Options + +func WithHint(h string) Option { + return api.WrapHint[Options](h) +} + +func WithGlobalAccess(a cpi.AccessSpec) Option { + return api.WrapGlobalAccess[Options](a) +} + +//////////////////////////////////////////////////////////////////////////////// +// Local Options + +func mapBaseOption(opts *Options) *base.Options { + return &opts.Blob +} + +func wrapBase(o base.Option) Option { + return optionutils.OptionWrapperFunc[*base.Options, *Options](o, mapBaseOption) +} + +func WithCredentialContext(credctx credentials.ContextProvider) Option { + return wrapBase(base.WithCredentialContext(credctx)) +} + +func WithLoggingContext(logctx logging.ContextProvider) Option { + return wrapBase(base.WithLoggingContext(logctx)) +} + +func WithCachingContext(cachectx datacontext.Context) Option { + return wrapBase(base.WithCachingContext(cachectx)) +} + +func WithCachingFileSystem(fs vfs.FileSystem) Option { + return wrapBase(base.WithCachingFileSystem(fs)) +} + +func WithCachingPath(p string) Option { + return wrapBase(base.WithCachingPath(p)) +} + +func WithCredentials(c credentials.Credentials) Option { + return wrapBase(base.WithCredentials(c)) +} + +func WithClassifier(c string) Option { + return wrapBase(base.WithClassifier(c)) +} + +func WithOptionalClassifier(c *string) Option { + return wrapBase(base.WithOptionalClassifier(c)) +} + +func WithExtension(e string) Option { + return wrapBase(base.WithExtension(e)) +} + +func WithOptionalExtension(e *string) Option { + return wrapBase(base.WithOptionalExtension(e)) +} diff --git a/pkg/contexts/ocm/elements/artifactblob/mavenblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/mavenblob/resource.go new file mode 100644 index 0000000000..c977c55ad0 --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/mavenblob/resource.go @@ -0,0 +1,43 @@ +package mavenblob + +import ( + "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" + + "github.com/open-component-model/ocm/pkg/blobaccess/maven" + "github.com/open-component-model/ocm/pkg/contexts/ocm" + "github.com/open-component-model/ocm/pkg/contexts/ocm/compdesc" + "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" +) + +const TYPE = resourcetypes.MAVEN_ARTIFACT + +func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, repo *maven.Repository, groupId, artifactId, version string, opts ...Option) cpi.ArtifactAccess[M] { + eff := optionutils.EvalOptions(optionutils.WithDefaults(opts, WithCredentialContext(ctx))...) + + if meta.GetType() == "" { + meta.SetType(TYPE) + } + + blobprov := maven.BlobAccessProviderForMaven(repo, groupId, artifactId, version, &eff.Blob) + accprov := cpi.NewAccessProviderForBlobAccessProvider(ctx, blobprov, eff.Hint, eff.Global) + // strange type cast is required by Go compiler, meta has the correct type. + return cpi.NewArtifactAccessForProvider(generics.Cast[*M](meta), accprov) +} + +func ResourceAccess(ctx ocm.Context, meta *ocm.ResourceMeta, repo *maven.Repository, groupId, artifactId, version string, opts ...Option) cpi.ResourceAccess { + return Access(ctx, meta, repo, groupId, artifactId, version, opts...) +} + +func ResourceAccessForMavenCoords(ctx ocm.Context, meta *ocm.ResourceMeta, repo *maven.Repository, coords *maven.Coordinates, opts ...Option) cpi.ResourceAccess { + return Access(ctx, meta, repo, coords.GroupId, coords.ArtifactId, coords.Version, optionutils.WithDefaults(opts, WithOptionalClassifier(coords.Classifier), WithOptionalExtension(coords.Extension))...) +} + +func SourceAccess(ctx ocm.Context, meta *ocm.SourceMeta, repo *maven.Repository, groupId, artifactId, version string, opts ...Option) cpi.SourceAccess { + return Access(ctx, meta, repo, groupId, artifactId, version, opts...) +} + +func SourceAccessForMavenCoords(ctx ocm.Context, meta *ocm.SourceMeta, repo *maven.Repository, coords *maven.Coordinates, opts ...Option) cpi.SourceAccess { + return Access(ctx, meta, repo, coords.GroupId, coords.ArtifactId, coords.Version, optionutils.WithDefaults(opts, WithOptionalClassifier(coords.Classifier), WithOptionalExtension(coords.Extension))...) +} diff --git a/pkg/contexts/ocm/elements/artifactblob/mavenblob/suite_test.go b/pkg/contexts/ocm/elements/artifactblob/mavenblob/suite_test.go new file mode 100644 index 0000000000..a083b2234c --- /dev/null +++ b/pkg/contexts/ocm/elements/artifactblob/mavenblob/suite_test.go @@ -0,0 +1,13 @@ +package mavenblob_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Maven Blob Access Test Suite") +} diff --git a/pkg/contexts/ocm/elements/artifactblob/textblob/options.go b/pkg/contexts/ocm/elements/artifactblob/textblob/options.go index 46e99a0035..ab1d01c966 100644 --- a/pkg/contexts/ocm/elements/artifactblob/textblob/options.go +++ b/pkg/contexts/ocm/elements/artifactblob/textblob/options.go @@ -30,7 +30,7 @@ func WithGlobalAccess(a cpi.AccessSpec) Option { //////////////////////////////////////////////////////////////////////////////// // Local Options -func WithimeType(mime string) Option { +func WithMimeType(mime string) Option { return datablob.WithMimeType(mime) } diff --git a/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go b/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go index 3045c59bef..ef9273b23a 100644 --- a/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go +++ b/pkg/contexts/ocm/elements/artifactblob/wgetblob/resource.go @@ -14,7 +14,7 @@ import ( const TYPE = resourcetypes.BLOB func Access[M any, P compdesc.ArtifactMetaPointer[M]](ctx ocm.Context, meta P, url string, opts ...Option) cpi.ArtifactAccess[M] { - eff := optionutils.EvalOptions(append([]Option{WithCredentialContext(ctx), WithLoggingContext(ctx)}, opts...)...) + eff := optionutils.EvalOptions(optionutils.WithDefaults(opts, WithCredentialContext(ctx))...) if meta.GetType() == "" { meta.SetType(TYPE) diff --git a/pkg/contexts/ocm/gc_test.go b/pkg/contexts/ocm/gc_test.go index 2896ae9406..a4ad5f81a7 100644 --- a/pkg/contexts/ocm/gc_test.go +++ b/pkg/contexts/ocm/gc_test.go @@ -6,9 +6,9 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - "github.com/open-component-model/ocm/pkg/runtimefinalizer" me "github.com/open-component-model/ocm/pkg/contexts/ocm" + "github.com/open-component-model/ocm/pkg/runtimefinalizer" ) var _ = Describe("area test", func() { diff --git a/pkg/contexts/ocm/plugin/cache/updater.go b/pkg/contexts/ocm/plugin/cache/updater.go index 0f28269d02..cde2925a3a 100644 --- a/pkg/contexts/ocm/plugin/cache/updater.go +++ b/pkg/contexts/ocm/plugin/cache/updater.go @@ -194,7 +194,7 @@ func (o *PluginUpdater) download(session ocm.Session, cv ocm.ComponentVersionAcc break } wrong = r - } else { //nolint: gocritic // yes + } else { if name != "" { wrong = r } diff --git a/pkg/contexts/ocm/repositories/genericocireg/repo_test.go b/pkg/contexts/ocm/repositories/genericocireg/repo_test.go index 29347bb13c..206e0d8464 100644 --- a/pkg/contexts/ocm/repositories/genericocireg/repo_test.go +++ b/pkg/contexts/ocm/repositories/genericocireg/repo_test.go @@ -9,12 +9,11 @@ import ( . "github.com/onsi/gomega" . "github.com/open-component-model/ocm/pkg/testutils" + "github.com/mandelsoft/goutils/finalizer" "github.com/mandelsoft/vfs/pkg/osfs" "github.com/mandelsoft/vfs/pkg/vfs" "github.com/opencontainers/go-digest" - "github.com/mandelsoft/goutils/finalizer" - "github.com/open-component-model/ocm/pkg/blobaccess" "github.com/open-component-model/ocm/pkg/common/accessio" "github.com/open-component-model/ocm/pkg/common/accessobj" diff --git a/pkg/contexts/ocm/resourcetypes/const.go b/pkg/contexts/ocm/resourcetypes/const.go index 6c0dc78650..40ee9453e8 100644 --- a/pkg/contexts/ocm/resourcetypes/const.go +++ b/pkg/contexts/ocm/resourcetypes/const.go @@ -16,8 +16,8 @@ const ( HELM_CHART = "helmChart" // NPM_PACKAGE describes a Node.js (npm) package. NPM_PACKAGE = "npmPackage" - // MVN_ARTIFACT describes a Maven artifact (jar). - MVN_ARTIFACT = "mvnArtifact" + // MAVEN_ARTIFACT describes a Maven artifact (jar). + MAVEN_ARTIFACT = "mavenArtifact" // BLUEPRINT describes a Gardener Landscaper blueprint which is an artifact used in its installations describing // how to deploy a software component. BLUEPRINT = "landscaper.gardener.cloud/blueprint" diff --git a/pkg/contexts/ocm/transfer/autohandler_test.go b/pkg/contexts/ocm/transfer/autohandler_test.go index 2370e26828..92bdcea68c 100644 --- a/pkg/contexts/ocm/transfer/autohandler_test.go +++ b/pkg/contexts/ocm/transfer/autohandler_test.go @@ -6,6 +6,7 @@ import ( . "github.com/open-component-model/ocm/pkg/testutils" "github.com/mandelsoft/goutils/errors" + "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer" "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer/transferhandler" "github.com/open-component-model/ocm/pkg/contexts/ocm/transfer/transferhandler/spiff" diff --git a/pkg/contexts/ocm/utils/localize/format.go b/pkg/contexts/ocm/utils/localize/format.go index 5f2a487d13..da1018ad3e 100644 --- a/pkg/contexts/ocm/utils/localize/format.go +++ b/pkg/contexts/ocm/utils/localize/format.go @@ -48,7 +48,7 @@ func (m *ImageMapping) Evaluate(idx int, cv ocm.ComponentVersionAccess, resolver name := "image mapping" if m.Name != "" { name = fmt.Sprintf("%s %q", name, m.Name) - } else { //nolint: gocritic // yes + } else { if idx >= 0 { name = fmt.Sprintf("%s %d", name, idx+1) } diff --git a/pkg/env/env.go b/pkg/env/env.go index ffbabb5de9..2f4da4b7e3 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -3,11 +3,14 @@ package env import ( "bytes" "fmt" + "runtime" "runtime/debug" "strings" "github.com/DataDog/gostackparse" + "github.com/mandelsoft/filepath/pkg/filepath" "github.com/mandelsoft/goutils/exception" + "github.com/mandelsoft/goutils/general" "github.com/mandelsoft/vfs/pkg/composefs" "github.com/mandelsoft/vfs/pkg/layerfs" "github.com/mandelsoft/vfs/pkg/memoryfs" @@ -21,7 +24,7 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/credentials" "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" "github.com/open-component-model/ocm/pkg/contexts/oci" - "github.com/open-component-model/ocm/pkg/contexts/ocm" + ocm "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/utils" ) @@ -199,7 +202,7 @@ type tdOpt struct { modifiable bool } -func TestData(paths ...string) tdOpt { +func testData(modifiable bool, paths ...string) tdOpt { path := "/testdata" source := "testdata" @@ -214,30 +217,85 @@ func TestData(paths ...string) tdOpt { panic("invalid number of arguments") } return tdOpt{ - path: path, - source: source, + path: path, + source: source, + modifiable: modifiable, } } +func TestData(paths ...string) tdOpt { + return testData(false, paths...) +} + func ModifiableTestData(paths ...string) tdOpt { - path := "/testdata" - source := "testdata" + return testData(true, paths...) +} + +func projectTestData(modifiable bool, source string, dest ...string) Option { + path := "." + for count := 0; count < 20; count++ { + if ok, err := vfs.FileExists(osfs.OsFs, filepath.Join(path, "go.mod")); err != nil || ok { + if err != nil { + panic(err) + } + path = filepath.Join(path, source) + break + } + if count == 19 { + panic("could not find go.mod (within 20 steps)") + } - switch len(paths) { - case 0: - case 1: - source = paths[0] - case 2: - source = paths[0] - path = paths[1] - default: - panic("invalid number of arguments") + path = filepath.Join(path, "..") } - return tdOpt{ - path: path, - source: source, - modifiable: true, + + return testData(modifiable, path, general.OptionalDefaulted("/testdata", dest...)) +} + +func ProjectTestData(source string, dest ...string) Option { + return projectTestData(false, source, dest...) +} + +func ModifiableProjectTestData(source string, dest ...string) Option { + return projectTestData(true, source, dest...) +} + +func projectTestDataForCaller(modifiable bool, dest ...string) Option { + pc, _, _, ok := runtime.Caller(2) + if !ok { + panic("unable to find caller") + } + + // Get the function details from the program counter + caller := runtime.FuncForPC(pc) + if caller == nil { + panic("unable to find caller") } + + fullFuncName := caller.Name() + + // Split the name to extract the package path + // Assuming the format: "package/path.functionName" + lastSlashIndex := strings.LastIndex(fullFuncName, "/") + if lastSlashIndex == -1 { + panic("unable to find package name") + } + + funcIndex := strings.Index(fullFuncName[lastSlashIndex:], ".") + packagePath := fullFuncName[:lastSlashIndex+funcIndex] + path, ok := strings.CutPrefix(packagePath, "github.com/open-component-model/ocm/") + if !ok { + panic("unable to find package name") + } + + return projectTestData(modifiable, filepath.Join(path, "testdata"), dest...) +} + +func ProjectTestDataForCaller(dest ...string) Option { + return projectTestDataForCaller(false, dest...) +} + +func ModifiableProjectTestDataForCaller(dest ...string) Option { + return projectTestDataForCaller(true, dest...) } func (o tdOpt) OptionHandler() OptionHandler { diff --git a/pkg/exception/exception_test.go b/pkg/exception/exception_test.go index 33e95ccda5..b6bdf5e9d0 100644 --- a/pkg/exception/exception_test.go +++ b/pkg/exception/exception_test.go @@ -7,6 +7,7 @@ import ( . "github.com/onsi/gomega" "github.com/mandelsoft/goutils/errors" + "github.com/open-component-model/ocm/pkg/exception" ) diff --git a/pkg/iotools/hashReaderWriter.go b/pkg/iotools/hashReaderWriter.go index b74863f7e7..f36d74b58d 100644 --- a/pkg/iotools/hashReaderWriter.go +++ b/pkg/iotools/hashReaderWriter.go @@ -5,42 +5,79 @@ import ( "fmt" "hash" "io" + "net/http" "strings" "github.com/mandelsoft/goutils/errors" ) +type Hashes map[crypto.Hash]hash.Hash + +func NewHashes(algorithms ...crypto.Hash) Hashes { + hashMap := make(Hashes, len(algorithms)) + for _, algorithm := range algorithms { + hashMap[algorithm] = algorithm.New() + } + return hashMap +} + +func (h Hashes) Write(c int, buf []byte) { + if c > 0 { + for _, hash := range h { + hash.Write(buf[:c]) + } + } +} + +func (h Hashes) AsHttpHeader() http.Header { + headers := make(http.Header, len(h)) + for algorithm := range h { + headers.Set(headerName(algorithm), h.GetString(algorithm)) + } + return headers +} + +func (h Hashes) GetBytes(algorithm crypto.Hash) []byte { + hash := h[algorithm] + if hash != nil { + return hash.Sum(nil) + } + return nil +} + +func (h Hashes) GetString(algorithm crypto.Hash) string { + return fmt.Sprintf("%x", h.GetBytes(algorithm)) +} + +func headerName(algorithm crypto.Hash) string { + a := strings.ReplaceAll(algorithm.String(), "-", "") + return "X-Checksum-" + a[:1] + strings.ToLower(a[1:]) +} + +//////////////////////////////////////////////////////////////////////////////// + type HashReader struct { reader io.Reader - hashMap map[crypto.Hash]hash.Hash + hashMap Hashes } func NewHashReader(delegate io.Reader, algorithms ...crypto.Hash) *HashReader { newInstance := HashReader{ reader: delegate, - hashMap: initMap(algorithms), + hashMap: NewHashes(algorithms...), } return &newInstance } func (h *HashReader) Read(buf []byte) (int, error) { c, err := h.reader.Read(buf) - return write(h, c, buf, err) -} - -func (h *HashReader) GetString(algorithm crypto.Hash) string { - return getString(h, algorithm) -} - -func (h *HashReader) GetBytes(algorithm crypto.Hash) []byte { - return getBytes(h, algorithm) -} - -func (h *HashReader) HttpHeader() map[string]string { - return httpHeader(h) + if err == nil { + h.hashMap.Write(c, buf) + } + return c, err } -func (h *HashReader) hashes() map[crypto.Hash]hash.Hash { +func (h *HashReader) Hashes() Hashes { return h.hashMap } @@ -69,84 +106,25 @@ func (h *HashReader) CalcHashes() (int64, error) { type HashWriter struct { writer io.Writer - hashMap map[crypto.Hash]hash.Hash + hashMap Hashes } func NewHashWriter(w io.Writer, algorithms ...crypto.Hash) *HashWriter { newInstance := HashWriter{ writer: w, - hashMap: initMap(algorithms), + hashMap: NewHashes(algorithms...), } return &newInstance } func (h *HashWriter) Write(buf []byte) (int, error) { c, err := h.writer.Write(buf) - return write(h, c, buf, err) -} - -func (h *HashWriter) GetString(algorithm crypto.Hash) string { - return getString(h, algorithm) -} - -func (h *HashWriter) GetBytes(algorithm crypto.Hash) []byte { - return getBytes(h, algorithm) -} - -func (h *HashWriter) HttpHeader() map[string]string { - return httpHeader(h) -} - -func (h *HashWriter) hashes() map[crypto.Hash]hash.Hash { - return h.hashMap -} - -//////////////////////////////////////////////////////////////////////////////// - -type hashes interface { - hashes() map[crypto.Hash]hash.Hash -} - -func getString(h hashes, algorithm crypto.Hash) string { - return fmt.Sprintf("%x", getBytes(h, algorithm)) -} - -func getBytes(h hashes, algorithm crypto.Hash) []byte { - hash := h.hashes()[algorithm] - if hash != nil { - return hash.Sum(nil) - } - return nil -} - -func httpHeader(h hashes) map[string]string { - headers := make(map[string]string, len(h.hashes())) - for algorithm := range h.hashes() { - headers[headerName(algorithm)] = getString(h, algorithm) - } - return headers -} - -func initMap(algorithms []crypto.Hash) map[crypto.Hash]hash.Hash { - hashMap := make(map[crypto.Hash]hash.Hash, len(algorithms)) - for _, algorithm := range algorithms { - hashMap[algorithm] = algorithm.New() - } - return hashMap -} - -func write(h hashes, c int, buf []byte, err error) (int, error) { - if err == nil && c > 0 { - for _, hash := range h.hashes() { - hash.Write(buf[:c]) - } + if err == nil { + h.hashMap.Write(c, buf) } return c, err } -//////////////////////////////////////////////////////////////////////////////// - -func headerName(hash crypto.Hash) string { - a := strings.ReplaceAll(hash.String(), "-", "") - return "X-Checksum-" + a[:1] + strings.ToLower(a[1:]) +func (h *HashWriter) Hashes() Hashes { + return h.hashMap } diff --git a/pkg/iotools/hashReaderWriter_test.go b/pkg/iotools/hashReaderWriter_test.go index bda2a6fc3d..457fa15342 100644 --- a/pkg/iotools/hashReaderWriter_test.go +++ b/pkg/iotools/hashReaderWriter_test.go @@ -26,26 +26,29 @@ var _ = Describe("Hash Reader Writer tests", func() { It("test HashWriter", func() { s := "Hello Hash!" var b bytes.Buffer - hr := iotools.NewHashWriter(io.Writer(&b)) - hr.Write([]byte(s)) + hw := iotools.NewHashWriter(io.Writer(&b)) + hw.Write([]byte(s)) + hashes := hw.Hashes() Expect(b.String()).To(Equal(s)) - Expect(hr.GetBytes(0)).To(BeNil()) + Expect(hashes.GetBytes(0)).To(BeNil()) b.Reset() w := io.Writer(&b) - hr = iotools.NewHashWriter(w, crypto.SHA1) - hr.Write([]byte(s)) + hw = iotools.NewHashWriter(w, crypto.SHA1) + hw.Write([]byte(s)) + hashes = hw.Hashes() Expect(b.String()).To(Equal(s)) - Expect(hr.GetBytes(0)).To(BeNil()) - Expect(hr.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) + Expect(hashes.GetBytes(0)).To(BeNil()) + Expect(hashes.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) b.Reset() - hr = iotools.NewHashWriter(io.Writer(&b), crypto.SHA1, crypto.MD5) - hr.Write([]byte(s)) + hw = iotools.NewHashWriter(io.Writer(&b), crypto.SHA1, crypto.MD5) + hw.Write([]byte(s)) + hashes = hw.Hashes() Expect(b.String()).To(Equal(s)) - Expect(hr.GetBytes(0)).To(BeNil()) - Expect(hr.GetString(crypto.MD5)).To(Equal("c10e8df2e378a1584359b0e546cf0149")) - Expect(hr.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) + Expect(hashes.GetBytes(0)).To(BeNil()) + Expect(hashes.GetString(crypto.MD5)).To(Equal("c10e8df2e378a1584359b0e546cf0149")) + Expect(hashes.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) }) It("test HashReader", func() { @@ -53,27 +56,29 @@ var _ = Describe("Hash Reader Writer tests", func() { hr := iotools.NewHashReader(strings.NewReader(s)) buf := make([]byte, len(s)) hr.Read(buf) - Expect(hr.GetBytes(0)).To(BeNil()) + hashes := hr.Hashes() + Expect(hashes.GetBytes(0)).To(BeNil()) Expect(string(buf)).To(Equal(s)) hr = iotools.NewHashReader(strings.NewReader(s), crypto.SHA1) hr.Read(buf) - Expect(hr.GetBytes(0)).To(BeNil()) - Expect(hr.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) + hashes = hr.Hashes() + Expect(hashes.GetBytes(0)).To(BeNil()) + Expect(hashes.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) hr = iotools.NewHashReader(strings.NewReader(s), crypto.SHA1) cnt, err := hr.CalcHashes() + hashes = hr.Hashes() Expect(err).To(BeNil()) Expect(cnt).To(Equal(int64(len(s)))) - Expect(hr.GetBytes(0)).To(BeNil()) - Expect(hr.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) + Expect(hashes.GetBytes(0)).To(BeNil()) + Expect(hashes.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) hr = iotools.NewHashReader(strings.NewReader(s), crypto.SHA1, crypto.MD5) hr.Read(buf) - Expect(hr.GetBytes(crypto.SHA256)).To(BeNil()) - Expect(hr.GetString(crypto.MD5)).To(Equal("c10e8df2e378a1584359b0e546cf0149")) - Expect(hr.GetString(crypto.MD5)).To(Equal("c10e8df2e378a1584359b0e546cf0149")) - Expect(hr.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) - Expect(hr.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) + hashes = hr.Hashes() + Expect(hashes.GetBytes(crypto.SHA256)).To(BeNil()) + Expect(hashes.GetString(crypto.MD5)).To(Equal("c10e8df2e378a1584359b0e546cf0149")) + Expect(hashes.GetString(crypto.SHA1)).To(Equal("5c075ed604db0adc524edd3516e8f0258ca6e58d")) }) }) diff --git a/pkg/maven/access.go b/pkg/maven/access.go new file mode 100644 index 0000000000..3fc972b83e --- /dev/null +++ b/pkg/maven/access.go @@ -0,0 +1,407 @@ +package maven + +import ( + "bytes" + "context" + "crypto" + "encoding/json" + "fmt" + "io" + "net/http" + "net/url" + "strings" + + "github.com/cloudflare/cfssl/log" + "github.com/mandelsoft/goutils/errors" + "github.com/mandelsoft/goutils/finalizer" + "github.com/mandelsoft/goutils/general" + "github.com/mandelsoft/vfs/pkg/vfs" + "golang.org/x/exp/maps" + "golang.org/x/net/html" + + "github.com/open-component-model/ocm/pkg/iotools" + "github.com/open-component-model/ocm/pkg/utils" + "github.com/open-component-model/ocm/pkg/utils/tarutils" +) + +type FileMeta struct { + MimeType string + HashType crypto.Hash + Hash string + Location *Location +} + +type Repository struct { + Location +} + +func NewFileRepository(path string, fss ...vfs.FileSystem) *Repository { + return &Repository{Location{ + path: path, + fs: utils.FileSystem(fss...), + }} +} + +func NewUrlRepository(repoUrl string, fss ...vfs.FileSystem) (*Repository, error) { + u, err := url.Parse(repoUrl) + if err != nil { + return nil, err + } + if u.Scheme == "file" { + if u.Host != "" && u.Host != "localhost" { + return nil, errors.Newf("named host not supported for url file scheme: %q", repoUrl) + } + return NewFileRepository(u.Path, fss...), nil + } + return &Repository{Location{ + url: repoUrl, + }}, nil +} + +func (r *Repository) Url() (string, error) { + if r.url != "" { + return r.url, nil + } + p, err := vfs.Canonical(r.fs, r.path, false) + if err != nil { + return "", err + } + return "file://localhost" + p, nil +} + +// Body is the response struct of a deployment from the MVN repository (JFrog Artifactory). +type Body struct { + Repo string `json:"repo"` + Path string `json:"path"` + DownloadUri string `json:"downloadUri"` + Uri string `json:"uri"` + MimeType string `json:"mimeType"` + Size string `json:"size"` + Checksums map[string]string `json:"checksums"` +} + +func (r *Repository) Download(coords *Coordinates, creds Credentials, enforceVerification ...bool) (io.ReadCloser, error) { + files, err := r.GavFiles(coords, creds) + if err != nil { + return nil, err + } + algorithm, ok := files[coords.FileName()] + if !ok { + return nil, errors.ErrNotFound("file", coords.FileName(), coords.GAV()) + } + + var digest string + loc := coords.Location(r) + if algorithm != 0 { + digestFile := loc.AddExtension(HashExt(algorithm)) + reader, err := digestFile.GetReader(creds) + if err != nil { + return nil, err + } + digestData, err := io.ReadAll(reader) + if err != nil { + return nil, err + } + digest = string(digestData) + } else { + if general.Optional(enforceVerification...) { + return nil, fmt.Errorf("unable to verify, no digest available in target repository") + } + } + + reader, err := loc.GetReader(creds) + if err != nil { + return nil, err + } + if algorithm != 0 { + reader = iotools.VerifyingReaderWithHash(reader, algorithm, digest) + } + return reader, nil +} + +func (r *Repository) Upload(coords *Coordinates, reader io.ReadCloser, creds Credentials, hashes iotools.Hashes) (rerr error) { + finalize := finalizer.Finalizer{} + defer finalize.FinalizeWithErrorPropagation(&rerr) + + loc := coords.Location(r) + if r.IsFileSystem() { + err := loc.fs.MkdirAll(vfs.Dir(loc.fs, loc.path), 0o755) + if err != nil { + return err + } + f, err := loc.fs.OpenFile(loc.path, vfs.O_WRONLY|vfs.O_CREATE|vfs.O_TRUNC, 0o644) + if err != nil { + return err + } + finalize.Close(f) + + _, err = io.Copy(f, reader) + if err != nil { + return err + } + + for algorithm := range hashes { + digest := hashes.GetString(algorithm) + p := loc.path + "." + HashExt(algorithm) + err = vfs.WriteFile(loc.fs, p, []byte(digest), 0o644) + if err != nil { + return err + } + } + return nil + } + + req, err := http.NewRequestWithContext(context.Background(), http.MethodPut, loc.String(), reader) + if err != nil { + return err + } + if creds != nil { + err = creds.SetForRequest(req) + if err != nil { + return err + } + } + // give the remote server a chance to decide based upon the checksum policy + for k, v := range hashes.AsHttpHeader() { + req.Header[k] = v + } + + // Execute the request + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return err + } + finalize.Close(resp.Body) + + // Check the response + if resp.StatusCode != http.StatusCreated { + all, e := io.ReadAll(resp.Body) + if e != nil { + return e + } + return fmt.Errorf("http (%d) - failed to upload coords: %s", resp.StatusCode, string(all)) + } + Log.Debug("uploaded", "coords", coords, "extension", coords.Extension, "classifier", coords.Classifier) + + // Validate the response - especially the hash values with the ones we've tried to send + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + var artifactBody Body + err = json.Unmarshal(respBody, &artifactBody) + if err != nil { + return err + } + + algorithm := bestAvailableHash(maps.Keys(hashes)) + digest := hashes.GetString(algorithm) + remoteDigest := artifactBody.Checksums[strings.ReplaceAll(strings.ToLower(algorithm.String()), "-", "")] + if remoteDigest == "" { + Log.Warn("no checksum found for algorithm, we can't guarantee that the coords has been uploaded correctly", "algorithm", algorithm.String()) + } else if remoteDigest != digest { + return errors.New("failed to upload coords: checksums do not match") + } + Log.Debug("digests are ok", "remoteDigest", remoteDigest, "digest", digest) + return err +} + +func (r *Repository) GetFileMeta(c *Coordinates, file string, hash crypto.Hash, creds Credentials) (*FileMeta, error) { + coords := c.Copy() + err := coords.SetClassifierExtensionBy(file) + if err != nil { + return nil, err + } + metadata := &FileMeta{ + Location: coords.Location(r), + MimeType: coords.MimeType(), + } + log := Log.WithValues("file", metadata.Location.String()) + log.Debug("processing") + if hash > 0 { + metadata.HashType = hash + metadata.Hash, err = metadata.Location.GetHash(creds, hash) + if err != nil { + return nil, errors.Wrapf(err, "cannot read %s digest of: %s", hash, metadata.Location) + } + } else { + log.Warn("no digest available") + } + return metadata, nil +} + +func (r *Repository) GavFiles(coords *Coordinates, creds Credentials) (map[string]crypto.Hash, error) { + if r.path != "" { + return gavFilesFromDisk(r.fs, coords.GavLocation(r).path) + } + return gavOnlineFiles(r, coords, creds) +} + +func gavFilesFromDisk(fs vfs.FileSystem, dir string) (map[string]crypto.Hash, error) { + files, err := tarutils.ListSortedFilesInDir(fs, dir, true) + if err != nil { + return nil, err + } + return filesAndHashes(files), nil +} + +// gavOnlineFiles returns the files of the Maven artifact in the repository and their available digests. +func gavOnlineFiles(repo *Repository, coords *Coordinates, creds Credentials) (map[string]crypto.Hash, error) { + log := Log.WithValues("RepoUrl", repo.String(), "GAV", coords.GavPath()) + log.Debug("gavOnlineFiles") + + reader, err := coords.GavLocation(repo).GetReader(creds) + if err != nil { + return nil, err + } + defer reader.Close() + + // Which files are listed in the repository? + log.Debug("parse-html") + htmlDoc, err := html.Parse(reader) + if err != nil { + return nil, err + } + var fileList []string + var process func(*html.Node) + prefix := coords.FileNamePrefix() + process = func(node *html.Node) { + // check if the node is an element node and the tag is "" + if node.Type == html.ElementNode && node.Data == "a" { + for _, attribute := range node.Attr { + if attribute.Key == "href" { + // check if the href starts with artifactId-version + if strings.HasPrefix(attribute.Val, prefix) { + fileList = append(fileList, attribute.Val) + } + } + } + } + for nextChild := node.FirstChild; nextChild != nil; nextChild = nextChild.NextSibling { + process(nextChild) // recursive call! + } + } + process(htmlDoc) + + return filesAndHashes(fileList), nil +} + +func filesAndHashes(fileList []string) map[string]crypto.Hash { + // Which hash files are available? + result := make(map[string]crypto.Hash, len(fileList)/2) + for _, file := range fileList { + if IsResource(file) { + result[file] = bestAvailableHashForFile(fileList, file) + log.Debug("found", "file", file) + } + } + return result +} + +type Location struct { + url string + path string + fs vfs.FileSystem +} + +func (l *Location) MarshalJSON() ([]byte, error) { + return json.Marshal(l.String()) +} + +func (l *Location) IsFileSystem() bool { + return l.path != "" +} + +func (l *Location) AddPath(path string) *Location { + result := *l + var p *string + if result.url != "" { + p = &result.url + } else { + p = &result.path + } + + if !strings.HasSuffix(*p, "/") { + *p += "/" + } + *p += path + return &result +} + +func (l *Location) AddExtension(ext string) *Location { + result := *l + var p *string + if result.url != "" { + p = &result.url + } else { + p = &result.path + } + + *p += "." + ext + return &result +} + +func (l *Location) String() string { + return general.Conditional(l.path != "", l.path, l.url) +} + +func (l *Location) GetHash(creds Credentials, hash crypto.Hash) (string, error) { + // getStringData reads all data from the given URL and returns it as a string. + r, err := l.AddExtension(HashExt(hash)).GetReader(creds) + if err != nil { + return "", err + } + defer r.Close() + b, err := io.ReadAll(r) + if err != nil { + return "", err + } + return string(b), nil +} + +func (l *Location) GetReader(creds Credentials) (io.ReadCloser, error) { + if l.path != "" { + return l.fs.OpenFile(l.path, vfs.O_RDONLY, 0o600) + } + + req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, l.url, nil) + if err != nil { + return nil, err + } + if creds != nil { + err = creds.SetForRequest(req) + if err != nil { + return nil, err + } + } + httpClient := &http.Client{} + resp, err := httpClient.Do(req) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + defer resp.Body.Close() + buf := &bytes.Buffer{} + _, err = io.Copy(buf, io.LimitReader(resp.Body, 2000)) + if err == nil { + Log.Error("http", "code", resp.Status, "repo", l.url, "body", buf.String()) + } + return nil, errors.Newf("http %s error - %s", resp.Status, l.url) + } + return resp.Body, nil +} + +type Credentials interface { + SetForRequest(req *http.Request) error +} + +type BasicAuthCredentials struct { + Username string + Password string +} + +func (b *BasicAuthCredentials) SetForRequest(req *http.Request) error { + req.SetBasicAuth(b.Username, b.Password) + return nil +} diff --git a/pkg/maven/access_test.go b/pkg/maven/access_test.go new file mode 100644 index 0000000000..4696286597 --- /dev/null +++ b/pkg/maven/access_test.go @@ -0,0 +1,132 @@ +package maven_test + +import ( + "crypto" + "io" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/env/builder" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/mandelsoft/goutils/optionutils" + + me "github.com/open-component-model/ocm/pkg/maven" + "github.com/open-component-model/ocm/pkg/maven/maventest" +) + +const ( + MAVEN_PATH = "/testdata/.m2/repository" + FAIL_PATH = "/testdata/.m2/fail" +) + +var _ = Describe("local accessmethods.me.AccessSpec tests", func() { + var env *Builder + var repo *me.Repository + + BeforeEach(func() { + env = NewBuilder(maventest.TestData()) + repo = me.NewFileRepository(MAVEN_PATH, env.FileSystem()) + }) + + AfterEach(func() { + env.Cleanup() + }) + + It("accesses local artifact file", func() { + coords := me.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") + files := Must(repo.GavFiles(coords, nil)) + Expect(files).To(YAMLEqual(` +sdk-modules-bom-5.7.0-random-content.json: 3 +sdk-modules-bom-5.7.0-random-content.txt: 3 +sdk-modules-bom-5.7.0-sources.jar: 3 +sdk-modules-bom-5.7.0.jar: 3 +sdk-modules-bom-5.7.0.pom: 3 +`)) + }) + + It("accesses local artifact file with extension", func() { + coords := me.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", me.WithClassifier(""), me.WithExtension("pom")) + hash := Must(coords.Location(repo).GetHash(nil, crypto.SHA1)) + Expect(hash).To(Equal("34ccdeb9c008f8aaef90873fc636b09d3ae5c709")) + }) + + It("access dedicated file", func() { + coords := me.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", me.WithClassifier(""), me.WithExtension("pom")) + meta := Must(repo.GetFileMeta(coords, "sdk-modules-bom-5.7.0.pom", crypto.SHA1, nil)) + Expect(meta).To(YAMLEqual(` + Hash: 34ccdeb9c008f8aaef90873fc636b09d3ae5c709 + HashType: 3 + MimeType: application/xml + Location: /testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0.pom +`)) + }) + + Context("filtering", func() { + var ( + files map[string]crypto.Hash + coords *me.Coordinates + ) + BeforeEach(func() { + coords = me.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0") + files = Must(repo.GavFiles(coords, nil)) + }) + + It("filters nothing", func() { + Expect(coords.FilterFileMap(files)).To(Equal(files)) + }) + It("filter by empty classifier", func() { + coords.Classifier = optionutils.PointerTo("") + Expect(coords.FilterFileMap(files)).To(YAMLEqual(` +sdk-modules-bom-5.7.0.jar: 3 +sdk-modules-bom-5.7.0.pom: 3 +`)) + }) + It("filter by non-empty classifier", func() { + coords.Classifier = optionutils.PointerTo("random-content") + Expect(coords.FilterFileMap(files)).To(YAMLEqual(` +sdk-modules-bom-5.7.0-random-content.json: 3 +sdk-modules-bom-5.7.0-random-content.txt: 3 +`)) + }) + It("filter by extension", func() { + coords.Extension = optionutils.PointerTo("jar") + Expect(coords.FilterFileMap(files)).To(YAMLEqual(` +sdk-modules-bom-5.7.0-sources.jar: 3 +sdk-modules-bom-5.7.0.jar: 3 +`)) + }) + + It("filter by empty classifier and extension", func() { + coords.Classifier = optionutils.PointerTo("") + coords.Extension = optionutils.PointerTo("jar") + Expect(coords.FilterFileMap(files)).To(YAMLEqual(` +sdk-modules-bom-5.7.0.jar: 3 +`)) + }) + + It("filter by non-empty classifier and extension", func() { + coords.Classifier = optionutils.PointerTo("sources") + coords.Extension = optionutils.PointerTo("jar") + Expect(coords.FilterFileMap(files)).To(YAMLEqual(` +sdk-modules-bom-5.7.0-sources.jar: 3 +`)) + }) + + It("download dedicated file", func() { + coords := me.NewCoordinates("com.sap.cloud.sdk", "sdk-modules-bom", "5.7.0", me.WithClassifier(""), me.WithExtension("pom")) + reader := Must(repo.Download(coords, nil, true)) + data := Must(io.ReadAll(reader)) + Expect(len(data)).To(Equal(7153)) + MustBeSuccessful(reader.Close()) + }) + + It("download dedicated file with filed digest verification", func() { + coords := me.NewCoordinates("test", "repository", "42", me.WithClassifier(""), me.WithExtension("pom")) + repo := me.NewFileRepository(FAIL_PATH, env) + reader := Must(repo.Download(coords, nil, true)) + _ = Must(io.ReadAll(reader)) + Expect(reader.Close()).To(MatchError("SHA-1 digest mismatch: expected 44a77645201d1a8fc5213ace787c220eabbd0967, found b3242b8c31f8ce14f729b8fd132ac77bc4bc5bf7")) + }) + }) +}) diff --git a/pkg/maven/coordinates.go b/pkg/maven/coordinates.go new file mode 100644 index 0000000000..fa1767ba4e --- /dev/null +++ b/pkg/maven/coordinates.go @@ -0,0 +1,218 @@ +package maven + +import ( + "crypto" + "fmt" + "mime" + "path" + "path/filepath" + "strings" + + . "github.com/mandelsoft/goutils/regexutils" + + "github.com/mandelsoft/goutils/generics" + "github.com/mandelsoft/goutils/optionutils" + + ocmmime "github.com/open-component-model/ocm/pkg/mime" +) + +type CoordinateOption = optionutils.Option[*Coordinates] + +type WithClassifier string + +func WithOptionalClassifier(c *string) CoordinateOption { + if c != nil { + return WithClassifier(*c) + } + return nil +} + +func (o WithClassifier) ApplyTo(c *Coordinates) { + c.Classifier = optionutils.PointerTo(string(o)) +} + +type WithExtension string + +func WithOptionalExtension(e *string) CoordinateOption { + if e != nil { + return WithExtension(*e) + } + return nil +} + +func (o WithExtension) ApplyTo(c *Coordinates) { + c.Extension = optionutils.PointerTo(string(o)) +} + +// Coordinates holds the typical Maven coordinates groupId, artifactId, version. Optional also classifier and extension. +// https://maven.apache.org/ref/3.9.6/maven-core/artifact-handlers.html +type Coordinates struct { + // GroupId of the Maven artifact. + GroupId string `json:"groupId"` + // ArtifactId of the Maven artifact. + ArtifactId string `json:"artifactId"` + // Version of the Maven artifact. + Version string `json:"version"` + // Classifier of the Maven artifact. + Classifier *string `json:"classifier,omitempty"` + // Extension of the Maven artifact. + Extension *string `json:"extension,omitempty"` +} + +func NewCoordinates(groupId, artifactId, version string, opts ...CoordinateOption) *Coordinates { + c := &Coordinates{ + GroupId: groupId, + ArtifactId: artifactId, + Version: version, + } + optionutils.ApplyOptions(c, opts...) + return c +} + +// GAV returns the GAV coordinates of the Maven Coordinates. +func (c *Coordinates) GAV() string { + return c.GroupId + ":" + c.ArtifactId + ":" + c.Version +} + +// String returns the Coordinates as a string (GroupId:ArtifactId:Version:WithClassifier:WithExtension). +func (c *Coordinates) String() string { + return c.GroupId + ":" + c.ArtifactId + ":" + c.Version + ":" + optionutils.AsValue(c.Classifier) + ":" + optionutils.AsValue(c.Extension) +} + +// GavPath returns the Maven repository path. +func (c *Coordinates) GavPath() string { + return c.GroupPath() + "/" + c.ArtifactId + "/" + c.Version +} + +func (c *Coordinates) GavLocation(repo *Repository) *Location { + return repo.AddPath(c.GavPath()) +} + +func (c *Coordinates) FileName() string { + file := c.FileNamePrefix() + if optionutils.AsValue(c.Classifier) != "" { + file += "-" + *c.Classifier + } + if optionutils.AsValue(c.Extension) != "" { + file += "." + *c.Extension + } else { + file += ".jar" + } + return file +} + +// FilePath returns the Maven Coordinates's GAV-name with classifier and extension. +// Which is equal to the URL-path of the artifact in the repository. +// Default extension is jar. +func (c *Coordinates) FilePath() string { + return c.GavPath() + "/" + c.FileName() +} + +func (c *Coordinates) Location(repo *Repository) *Location { + return repo.AddPath(c.FilePath()) +} + +// GroupPath returns GroupId with `/` instead of `.`. +func (c *Coordinates) GroupPath() string { + return strings.ReplaceAll(c.GroupId, ".", "/") +} + +func (c *Coordinates) FileNamePrefix() string { + return c.ArtifactId + "-" + c.Version +} + +// Purl returns the Package URL of the Maven Coordinates. +func (c *Coordinates) Purl() string { + return "pkg:maven/" + c.GroupId + "/" + c.ArtifactId + "@" + c.Version +} + +// SetClassifierExtensionBy extracts the classifier and extension from the filename (without any path prefix). +func (c *Coordinates) SetClassifierExtensionBy(filename string) error { + s := strings.TrimPrefix(path.Base(filename), c.FileNamePrefix()) + if strings.HasPrefix(s, "-") { + s = strings.TrimPrefix(s, "-") + i := strings.Index(s, ".") + if i < 0 { + return fmt.Errorf("no extension after classifier found in filename: %s", filename) + } + c.Classifier = optionutils.PointerTo(s[:i]) + s = strings.TrimPrefix(s, optionutils.AsValue(c.Classifier)) + } else { + c.Classifier = optionutils.PointerTo("") + } + c.Extension = optionutils.PointerTo(strings.TrimPrefix(s, ".")) + return nil +} + +// MimeType returns the MIME type of the Maven Coordinates based on the file extension. +// Default is application/x-tgz. +func (c *Coordinates) MimeType() string { + if c.Extension != nil && c.Classifier != nil { + m := mime.TypeByExtension("." + optionutils.AsValue(c.Extension)) + if m != "" { + return m + } + return ocmmime.MIME_OCTET + } + return ocmmime.MIME_TGZ +} + +// Copy creates a new Coordinates with the same values. +func (c *Coordinates) Copy() *Coordinates { + return generics.Pointer(*c) +} + +func (c *Coordinates) FilterFileMap(fileMap map[string]crypto.Hash) map[string]crypto.Hash { + if c.Classifier == nil && c.Extension == nil { + return fileMap + } + exp := Literal(c.ArtifactId + "-" + c.Version) + if optionutils.AsValue(c.Classifier) != "" { + exp = Sequence(exp, Literal("-"+*c.Classifier)) + } + if optionutils.AsValue(c.Extension) != "" { + if c.Classifier == nil { + exp = Sequence(exp, Optional(Literal("-"), Match(".+"))) + } + exp = Sequence(exp, Literal("."+*c.Extension)) + } else { + exp = Sequence(exp, Literal("."), Match(".*")) + } + exp = Anchored(exp) + for file := range fileMap { + if !exp.MatchString(file) { + delete(fileMap, file) + } + } + return fileMap +} + +// Parse creates a Coordinates from it's serialized form (see Coordinates.String). +func Parse(serializedArtifact string) (*Coordinates, error) { + parts := strings.Split(serializedArtifact, ":") + if len(parts) < 3 { + return nil, fmt.Errorf("invalid coordination string: %s", serializedArtifact) + } + coords := &Coordinates{ + GroupId: parts[0], + ArtifactId: parts[1], + Version: parts[2], + } + if len(parts) >= 4 { + coords.Classifier = optionutils.PointerTo(parts[3]) + } + if len(parts) >= 5 { + coords.Extension = optionutils.PointerTo(parts[4]) + } + return coords, nil +} + +// IsResource returns true if the filename is not a checksum or signature file. +func IsResource(fileName string) bool { + switch filepath.Ext(fileName) { + case ".asc", ".md5", ".sha1", ".sha256", ".sha512": + return false + default: + return true + } +} diff --git a/pkg/maven/coordinates_test.go b/pkg/maven/coordinates_test.go new file mode 100644 index 0000000000..9a7aa6300a --- /dev/null +++ b/pkg/maven/coordinates_test.go @@ -0,0 +1,52 @@ +package maven_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/testutils" + + "github.com/mandelsoft/goutils/optionutils" + + me "github.com/open-component-model/ocm/pkg/maven" +) + +var _ = Describe("Maven Test Environment", func() { + + It("GAV, GroupPath, FilePath", func() { + coords := me.NewCoordinates("ocm.software", "hello-ocm", "0.0.1", me.WithExtension("jar")) + Expect(coords.GAV()).To(Equal("ocm.software:hello-ocm:0.0.1")) + Expect(coords.GroupPath()).To(Equal("ocm/software")) + Expect(coords.FilePath()).To(Equal("ocm/software/hello-ocm/0.0.1/hello-ocm-0.0.1.jar")) + }) + + It("SetClassifierExtensionBy", func() { + coords := me.NewCoordinates("ocm.software", "hello-ocm", "0.0.1") + MustBeSuccessful(coords.SetClassifierExtensionBy("hello-ocm-0.0.1.pom")) + Expect(coords.Classifier).ToNot(BeNil()) + Expect(optionutils.AsValue(coords.Classifier)).To(Equal("")) + Expect(optionutils.AsValue(coords.Extension)).To(Equal("pom")) + + MustBeSuccessful(coords.SetClassifierExtensionBy("hello-ocm-0.0.1-tests.jar")) + Expect(optionutils.AsValue(coords.Classifier)).To(Equal("tests")) + Expect(optionutils.AsValue(coords.Extension)).To(Equal("jar")) + + coords.ArtifactId = "apache-me" + coords.Version = "3.9.6" + MustBeSuccessful(coords.SetClassifierExtensionBy("apache-me-3.9.6-bin.tar.gz")) + Expect(optionutils.AsValue(coords.Classifier)).To(Equal("bin")) + Expect(optionutils.AsValue(coords.Extension)).To(Equal("tar.gz")) + }) + + It("parse GAV", func() { + gav := "org.apache.commons:commons-compress:1.26.1:cyclonedx:xml" + coords, err := me.Parse(gav) + Expect(err).To(BeNil()) + Expect(coords.String()).To(Equal(gav)) + Expect(coords.GroupId).To(Equal("org.apache.commons")) + Expect(coords.ArtifactId).To(Equal("commons-compress")) + Expect(coords.Version).To(Equal("1.26.1")) + Expect(optionutils.AsValue(coords.Classifier)).To(Equal("cyclonedx")) + Expect(optionutils.AsValue(coords.Extension)).To(Equal("xml")) + Expect(coords.FilePath()).To(Equal("org/apache/commons/commons-compress/1.26.1/commons-compress-1.26.1-cyclonedx.xml")) + }) +}) diff --git a/pkg/maven/logging.go b/pkg/maven/logging.go new file mode 100644 index 0000000000..17bfd5df54 --- /dev/null +++ b/pkg/maven/logging.go @@ -0,0 +1,7 @@ +package maven + +import "github.com/open-component-model/ocm/pkg/logging" + +var REALM = logging.DefineSubRealm("Maven repository", "maven") + +var Log = logging.DynamicLogger(REALM) diff --git a/pkg/maven/maventest/testdata.go b/pkg/maven/maventest/testdata.go new file mode 100644 index 0000000000..64f0c103e8 --- /dev/null +++ b/pkg/maven/maventest/testdata.go @@ -0,0 +1,9 @@ +package maventest + +import ( + "github.com/open-component-model/ocm/pkg/env" +) + +func TestData(dest ...string) env.Option { + return env.ProjectTestDataForCaller(dest...) +} diff --git a/pkg/contexts/ocm/accessmethods/mvn/testdata/fail/test/repository/42/repository-42.pom b/pkg/maven/maventest/testdata/.m2/fail/test/repository/42/repository-42.pom similarity index 100% rename from pkg/contexts/ocm/accessmethods/mvn/testdata/fail/test/repository/42/repository-42.pom rename to pkg/maven/maventest/testdata/.m2/fail/test/repository/42/repository-42.pom diff --git a/pkg/contexts/ocm/accessmethods/mvn/testdata/fail/test/repository/42/repository-42.pom.sha1 b/pkg/maven/maventest/testdata/.m2/fail/test/repository/42/repository-42.pom.sha1 similarity index 100% rename from pkg/contexts/ocm/accessmethods/mvn/testdata/fail/test/repository/42/repository-42.pom.sha1 rename to pkg/maven/maventest/testdata/.m2/fail/test/repository/42/repository-42.pom.sha1 diff --git a/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json new file mode 100644 index 0000000000..2f1fc35fdc --- /dev/null +++ b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json @@ -0,0 +1 @@ +{"some": "test content"} \ No newline at end of file diff --git a/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json.sha1 b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json.sha1 new file mode 100644 index 0000000000..d6836aeaa0 --- /dev/null +++ b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.json.sha1 @@ -0,0 +1 @@ +f0763ff4add043560aa3827cea06bf9335b87f73 \ No newline at end of file diff --git a/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt new file mode 100644 index 0000000000..b4af84697f --- /dev/null +++ b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt @@ -0,0 +1 @@ +some test content \ No newline at end of file diff --git a/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt.sha1 b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt.sha1 new file mode 100644 index 0000000000..55eceeb992 --- /dev/null +++ b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-random-content.txt.sha1 @@ -0,0 +1 @@ +dbabd43828eccd27e3a109b58454e4ff43c8673e \ No newline at end of file diff --git a/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-sources.jar b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-sources.jar new file mode 100644 index 0000000000000000000000000000000000000000..8564f0addae8de5525417df8294d13c0c2a3a7c0 GIT binary patch literal 595 zcmWIWW@h1HVBlb2I6ZY+1OpP_WME~0p0C?y-!rFuymj?1@_OrPojY@WbCAIm;|EWR^t^m^Jbf>guG$i0z|{3Z zQZu9C$@67uqD!Y`e=7P|#0a#Cor7naNwg)65ZVVl++yk z{N!Byg6wqtq@4Vu#N_1E;$r>W#In>p{gTw;l9a@fME%s^D&0A%HfJ3D=4gl*pE23j>4+%YaO}g$OGf$YN$76k=px&<0`# F1^|3_lo~0p0C?y-!rFuymj?1@_OrPojY@WbCAIm;|EWR^t^m^Jbf>guG$i0z|{3Z zQZu9C$@67uqD!Y`e=7P|#0a#Cor7naNwg)65ZVVl++yk z{N!Byg6wqtq@4Vu#N_1E;$r>W#In>p{gTw;l9a@fME%s^D&0A%HfJ3D=4gl*pE23j>4+%YaO}g$OGf$YN$76k=px&<0`# F1^|3_lo Date: Wed, 29 May 2024 14:47:50 +0200 Subject: [PATCH 07/12] utility function to get module name (#783) ## Description This Pull Request provides a utility function to get the module's name. --- pkg/env/env.go | 50 +++------- pkg/testutils/package.go | 78 +++++++++++++++ pkg/testutils/package_test.go | 15 +++ pkg/utils/package.go | 44 --------- pkg/utils/pkgutils/package.go | 102 ++++++++++++++++++++ pkg/utils/pkgutils/package_test.go | 32 ++++++ pkg/utils/pkgutils/suite_test.go | 13 +++ pkg/utils/pkgutils/testpackage/testtypes.go | 21 ++++ 8 files changed, 275 insertions(+), 80 deletions(-) create mode 100644 pkg/testutils/package.go create mode 100644 pkg/testutils/package_test.go delete mode 100644 pkg/utils/package.go create mode 100644 pkg/utils/pkgutils/package.go create mode 100644 pkg/utils/pkgutils/package_test.go create mode 100644 pkg/utils/pkgutils/suite_test.go create mode 100644 pkg/utils/pkgutils/testpackage/testtypes.go diff --git a/pkg/env/env.go b/pkg/env/env.go index 2f4da4b7e3..431b44e174 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -3,7 +3,6 @@ package env import ( "bytes" "fmt" - "runtime" "runtime/debug" "strings" @@ -25,7 +24,9 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/datacontext/attrs/vfsattr" "github.com/open-component-model/ocm/pkg/contexts/oci" ocm "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + "github.com/open-component-model/ocm/pkg/testutils" "github.com/open-component-model/ocm/pkg/utils" + "github.com/open-component-model/ocm/pkg/utils/pkgutils" ) //////////////////////////////////////////////////////////////////////////////// @@ -232,23 +233,13 @@ func ModifiableTestData(paths ...string) tdOpt { } func projectTestData(modifiable bool, source string, dest ...string) Option { - path := "." - for count := 0; count < 20; count++ { - if ok, err := vfs.FileExists(osfs.OsFs, filepath.Join(path, "go.mod")); err != nil || ok { - if err != nil { - panic(err) - } - path = filepath.Join(path, source) - break - } - if count == 19 { - panic("could not find go.mod (within 20 steps)") - } - - path = filepath.Join(path, "..") + pathToRoot, err := testutils.GetRelativePathToProjectRoot() + if err != nil { + panic(err) } + pathToTestdata := filepath.Join(pathToRoot, source) - return testData(modifiable, path, general.OptionalDefaulted("/testdata", dest...)) + return testData(modifiable, pathToTestdata, general.OptionalDefaulted("/testdata", dest...)) } func ProjectTestData(source string, dest ...string) Option { @@ -260,29 +251,16 @@ func ModifiableProjectTestData(source string, dest ...string) Option { } func projectTestDataForCaller(modifiable bool, dest ...string) Option { - pc, _, _, ok := runtime.Caller(2) - if !ok { - panic("unable to find caller") - } - - // Get the function details from the program counter - caller := runtime.FuncForPC(pc) - if caller == nil { - panic("unable to find caller") + packagePath, err := pkgutils.GetPackageName(2) + if err != nil { + panic(err) } - fullFuncName := caller.Name() - - // Split the name to extract the package path - // Assuming the format: "package/path.functionName" - lastSlashIndex := strings.LastIndex(fullFuncName, "/") - if lastSlashIndex == -1 { - panic("unable to find package name") + moduleName, err := testutils.GetModuleName() + if err != nil { + panic(err) } - - funcIndex := strings.Index(fullFuncName[lastSlashIndex:], ".") - packagePath := fullFuncName[:lastSlashIndex+funcIndex] - path, ok := strings.CutPrefix(packagePath, "github.com/open-component-model/ocm/") + path, ok := strings.CutPrefix(packagePath, moduleName+"/") if !ok { panic("unable to find package name") } diff --git a/pkg/testutils/package.go b/pkg/testutils/package.go new file mode 100644 index 0000000000..2e2925195d --- /dev/null +++ b/pkg/testutils/package.go @@ -0,0 +1,78 @@ +package testutils + +import ( + "fmt" + "strings" + + "github.com/mandelsoft/filepath/pkg/filepath" + "github.com/mandelsoft/goutils/general" + "github.com/mandelsoft/vfs/pkg/osfs" + "github.com/mandelsoft/vfs/pkg/vfs" + "golang.org/x/mod/modfile" + + "github.com/open-component-model/ocm/pkg/utils/pkgutils" +) + +const GO_MOD = "go.mod" + +func GetPackagePathFromProjectRoot(i ...interface{}) (string, error) { + pkg, err := pkgutils.GetPackageName(i...) + if err != nil { + return "", err + } + mod, err := GetModuleName() + if err != nil { + return "", err + } + path, ok := strings.CutPrefix(pkg, mod+"/") + if !ok { + return "", fmt.Errorf("prefix %q not found in %q", mod, pkg) + } + return path, nil +} + +// GetModuleName returns a go modules module name by finding and parsing the go.mod file. +func GetModuleName() (string, error) { + pathToRoot, err := GetRelativePathToProjectRoot() + if err != nil { + return "", err + } + pathToGoMod := filepath.Join(pathToRoot, GO_MOD) + // Read the content of the go.mod file + data, err := vfs.ReadFile(osfs.OsFs, pathToGoMod) + if err != nil { + return "", err + } + + // Parse the go.mod file + modFile, err := modfile.Parse(GO_MOD, data, nil) + if err != nil { + return "", fmt.Errorf("error parsing %s file: %w", GO_MOD, err) + } + + // Print the module path + return modFile.Module.Mod.Path, nil +} + +// GetRelativePathToProjectRoot calculates the relative path to a go projects root directory. +// It therefore assumes that the project root is the directory containing the go.mod file. +// The optional parameter i determines how many directories the function will step up through, attempting to find a +// go.mod file. If it cannot find a directory with a go.mod file within i iterations, the function throws an error. +func GetRelativePathToProjectRoot(i ...int) (string, error) { + iterations := general.OptionalDefaulted(20, i...) + + path := "." + for count := 0; count < iterations; count++ { + if ok, err := vfs.FileExists(osfs.OsFs, filepath.Join(path, GO_MOD)); err != nil || ok { + if err != nil { + return "", fmt.Errorf("failed to check if %s exists: %w", GO_MOD, err) + } + return path, nil + } + if count == iterations { + return "", fmt.Errorf("could not find %s (within %d steps)", GO_MOD, iterations) + } + path = filepath.Join(path, "..") + } + return "", nil +} diff --git a/pkg/testutils/package_test.go b/pkg/testutils/package_test.go new file mode 100644 index 0000000000..8e5805c70a --- /dev/null +++ b/pkg/testutils/package_test.go @@ -0,0 +1,15 @@ +package testutils_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + me "github.com/open-component-model/ocm/pkg/testutils" +) + +var _ = Describe("package tests", func() { + It("go module name", func() { + mod := me.Must(me.GetModuleName()) + Expect(mod).To(Equal("github.com/open-component-model/ocm")) + }) +}) diff --git a/pkg/utils/package.go b/pkg/utils/package.go deleted file mode 100644 index 932a765982..0000000000 --- a/pkg/utils/package.go +++ /dev/null @@ -1,44 +0,0 @@ -package utils - -import ( - "fmt" - "reflect" - "runtime" - "strings" -) - -const MODULE_PATH = "github.com/open-component-model/ocm" - -func GetPackageNameForFunc(i interface{}) (string, error) { - // Get the function's pointer - ptr := reflect.ValueOf(i).Pointer() - // Retrieve the function's runtime information - funcForPC := runtime.FuncForPC(ptr) - if funcForPC == nil { - return "", fmt.Errorf("could not determine package name") - } - // Get the full name of the function, including the package path - fullFuncName := funcForPC.Name() - - // Split the name to extract the package path - // Assuming the format: "package/path.functionName" - lastSlashIndex := strings.LastIndex(fullFuncName, "/") - if lastSlashIndex == -1 { - return "", fmt.Errorf("could not determine package name") - } - - packagePath := fullFuncName[:lastSlashIndex] - return packagePath, nil -} - -func GetPackagePathFromProjectRootForFunc(i interface{}) (string, error) { - pkg, err := GetPackageNameForFunc(i) - if err != nil { - return "", err - } - path, ok := strings.CutPrefix(pkg, "github.com/open-component-model/ocm/") - if !ok { - return "", fmt.Errorf("prefix %q not found in %q", MODULE_PATH, pkg) - } - return path, nil -} diff --git a/pkg/utils/pkgutils/package.go b/pkg/utils/pkgutils/package.go new file mode 100644 index 0000000000..857ca195f5 --- /dev/null +++ b/pkg/utils/pkgutils/package.go @@ -0,0 +1,102 @@ +package pkgutils + +import ( + "fmt" + "reflect" + "runtime" + "strings" +) + +// GetPackageName gets the package name for an object, a type, a function or a caller offset. +// +// Examples: +// +// GetPackageName(1) +// GetPackageName(&MyStruct{}) +// GetPackageName(GetPackageName) +// GetPackageName(generics.TypeOf[MyStruct]()) +func GetPackageName(i ...interface{}) (string, error) { + if len(i) == 0 { + i = []interface{}{0} + } + if t, ok := i[0].(reflect.Type); ok { + pkgpath := t.PkgPath() + if pkgpath == "" { + return "", fmt.Errorf("unable to determine package name") + } + return pkgpath, nil + } + v := reflect.ValueOf(i[0]) + for v.Kind() == reflect.Ptr { + v = v.Elem() + } + switch v.Kind() { + case reflect.Func: + return getPackageNameForFuncPC(v.Pointer()) + case reflect.Struct, reflect.Chan, reflect.Map, reflect.Slice, reflect.Array: + pkgpath := v.Type().PkgPath() + if pkgpath == "" { + return "", fmt.Errorf("unable to determine package name") + } + return pkgpath, nil + default: + offset, err := CastInt(v.Interface()) + if err != nil { + return "", err + } + pc, _, _, ok := runtime.Caller(offset + 1) + if !ok { + return "", fmt.Errorf("unable to find caller") + } + return getPackageNameForFuncPC(pc) + } +} + +func getPackageNameForFuncPC(pc uintptr) (string, error) { + // Retrieve the function's runtime information + funcForPC := runtime.FuncForPC(pc) + if funcForPC == nil { + return "", fmt.Errorf("could not determine package name") + } + // Get the full name of the function, including the package path + fullFuncName := funcForPC.Name() + + // Split the name to extract the package path + // Assuming the format: "package/path.functionName" + lastSlashIndex := strings.LastIndex(fullFuncName, "/") + if lastSlashIndex == -1 { + panic("unable to find package name") + } + + funcIndex := strings.Index(fullFuncName[lastSlashIndex:], ".") + packagePath := fullFuncName[:lastSlashIndex+funcIndex] + + return packagePath, nil +} + +func CastInt(i interface{}) (int, error) { + switch v := i.(type) { + case int: + return v, nil + case int8: + return int(v), nil + case int16: + return int(v), nil + case int32: + return int(v), nil + case int64: + return int(v), nil + case uint: + return int(v), nil + case uint8: + return int(v), nil + case uint16: + return int(v), nil + case uint32: + return int(v), nil + case uint64: + return int(v), nil + default: + return 0, fmt.Errorf("unable to cast %T into int", i) + } +} diff --git a/pkg/utils/pkgutils/package_test.go b/pkg/utils/pkgutils/package_test.go new file mode 100644 index 0000000000..b7ed7f1331 --- /dev/null +++ b/pkg/utils/pkgutils/package_test.go @@ -0,0 +1,32 @@ +package pkgutils_test + +import ( + "github.com/mandelsoft/goutils/generics" + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + . "github.com/open-component-model/ocm/pkg/testutils" + me "github.com/open-component-model/ocm/pkg/utils/pkgutils" + "github.com/open-component-model/ocm/pkg/utils/pkgutils/testpackage" + "reflect" +) + +type typ struct{} + +var _ = Describe("package tests", func() { + DescribeTable("determine package type for ", func(typ interface{}) { + Expect(Must(me.GetPackageName(typ))).To(Equal(reflect.TypeOf(testpackage.MyStruct{}).PkgPath())) + }, + Entry("struct", &testpackage.MyStruct{}), + Entry("array", &testpackage.MyArray{}), + Entry("list", &testpackage.MyList{}), + Entry("map", &testpackage.MyMap{}), + Entry("chan", make(testpackage.MyChan)), + Entry("func", testpackage.MyFunc), + Entry("func type", generics.TypeOf[testpackage.MyFuncType]()), + Entry("struct type", generics.TypeOf[testpackage.MyStruct]()), + ) + It("determine package for caller func", func() { + Expect(Must(testpackage.MyFunc())).To(Equal(reflect.TypeOf(testpackage.MyStruct{}).PkgPath())) + Expect(Must(testpackage.MyFunc(1))).To(Equal(reflect.TypeOf(typ{}).PkgPath())) + }) +}) diff --git a/pkg/utils/pkgutils/suite_test.go b/pkg/utils/pkgutils/suite_test.go new file mode 100644 index 0000000000..2946fa4d3b --- /dev/null +++ b/pkg/utils/pkgutils/suite_test.go @@ -0,0 +1,13 @@ +package pkgutils_test + +import ( + "testing" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +func TestConfig(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Package Utils Test Suite") +} diff --git a/pkg/utils/pkgutils/testpackage/testtypes.go b/pkg/utils/pkgutils/testpackage/testtypes.go new file mode 100644 index 0000000000..057497e57a --- /dev/null +++ b/pkg/utils/pkgutils/testpackage/testtypes.go @@ -0,0 +1,21 @@ +package testpackage + +import ( + "github.com/mandelsoft/goutils/sliceutils" + + "github.com/open-component-model/ocm/pkg/utils/pkgutils" +) + +type ( + MyStruct struct{} + + MyList []int + MyArray [3]int + MyMap map[int]int + MyChan chan int + MyFuncType func() +) + +func MyFunc(i ...int) (string, error) { + return pkgutils.GetPackageName(sliceutils.Convert[interface{}](i)...) +} From 862458c1dc8b515770b0ca6004fcff94bee93322 Mon Sep 17 00:00:00 2001 From: Hilmar Falkenberg Date: Wed, 29 May 2024 15:26:59 +0200 Subject: [PATCH 08/12] sonatype nexus - quirks modes (#782) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Two step token auth doesn't work with Nexus and the REST endpoint for a dedicated version doesn't exist. With this PR, Read-Access is done only via Basic-Auth and in case the specified version endpoint is not found, it will now try to load the complete package description from one level above. That should contain ALL existing versions, incl. the requested one. ## What type of PR is this? (check all applicable) - [ ] 🍕 Feature - [ ] 🎇 Restructuring - [ ] 🐛 Bug Fix - [ ] 📝 Documentation Update - [ ] 🎨 Style - [ ] 🧑‍💻 Code Refactor - [ ] 🔥 Performance Improvements - [ ] ✅ Test - [ ] 🤖 Build - [ ] 🔁 CI - [ ] 📦 Chore (Release) - [ ] ⏩ Revert ## Related Tickets & Documents - Fixes #753 and #769 ## Added tests? - [ ] 👍 yes - [ ] 🙅 no, because they aren't needed - [ ] 🙋 no, because I need help - [ ] Separate ticket for tests # (issue/pr) Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration ## Added to documentation? - [ ] 📜 README.md - [ ] 🙅 no documentation needed ## Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- docs/reference/ocm_credential-handling.md | 2 +- docs/reference/ocm_get_credentials.md | 2 +- .../builtin/npm/identity/identity.go | 39 +++---- .../repositories/npm/config_test.go | 9 +- .../credentials/repositories/npm/provider.go | 8 +- .../repositories/npm/repository.go | 2 +- pkg/contexts/ocm/accessmethods/npm/method.go | 100 +++++++++++++----- .../ocm/accessmethods/npm/method_test.go | 22 +++- .../handlers/generic/npm/blobhandler.go | 23 ++-- pkg/iotools/digests.go | 21 ++++ pkg/iotools/digests_test.go | 39 +++++++ pkg/npm/login.go | 53 +++++++--- pkg/npm/structs.go | 18 ++++ 13 files changed, 254 insertions(+), 84 deletions(-) create mode 100644 pkg/iotools/digests.go create mode 100644 pkg/iotools/digests_test.go create mode 100644 pkg/npm/structs.go diff --git a/docs/reference/ocm_credential-handling.md b/docs/reference/ocm_credential-handling.md index 28e70c6c12..32dc2e39f8 100644 --- a/docs/reference/ocm_credential-handling.md +++ b/docs/reference/ocm_credential-handling.md @@ -167,7 +167,7 @@ The following credential consumer types are used/supported: - password: the basic auth password - - NpmRegistry: NPM repository + - NpmRegistry: NPM registry It matches the NpmRegistry consumer type and additionally acts like the hostpath type. diff --git a/docs/reference/ocm_get_credentials.md b/docs/reference/ocm_get_credentials.md index c97d24bb06..1a7205d394 100644 --- a/docs/reference/ocm_get_credentials.md +++ b/docs/reference/ocm_get_credentials.md @@ -93,7 +93,7 @@ Matchers exist for the following usage contexts or consumer types: - password: the basic auth password - - NpmRegistry: NPM repository + - NpmRegistry: NPM registry It matches the NpmRegistry consumer type and additionally acts like the hostpath type. diff --git a/pkg/contexts/credentials/builtin/npm/identity/identity.go b/pkg/contexts/credentials/builtin/npm/identity/identity.go index 308cf8d299..dd90ef107d 100644 --- a/pkg/contexts/credentials/builtin/npm/identity/identity.go +++ b/pkg/contexts/credentials/builtin/npm/identity/identity.go @@ -1,11 +1,8 @@ package identity import ( - "path" + "net/url" - . "net/url" - - "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/credentials/cpi" "github.com/open-component-model/ocm/pkg/contexts/credentials/identity/hostpath" "github.com/open-component-model/ocm/pkg/listformat" @@ -37,31 +34,35 @@ func init() { ATTR_TOKEN, "the token attribute. May exist after login at any npm registry. Check your .npmrc file!", }) - cpi.RegisterStandardIdentity(CONSUMER_TYPE, hostpath.IdentityMatcher(CONSUMER_TYPE), `NPM repository + cpi.RegisterStandardIdentity(CONSUMER_TYPE, hostpath.IdentityMatcher(CONSUMER_TYPE), `NPM registry It matches the `+CONSUMER_TYPE+` consumer type and additionally acts like the `+hostpath.IDENTITY_TYPE+` type.`, attrs) } -func GetConsumerId(rawURL string, pkgName string) cpi.ConsumerIdentity { - url, err := Parse(rawURL) +var identityMatcher = hostpath.IdentityMatcher(CONSUMER_TYPE) + +func IdentityMatcher(pattern, cur, id cpi.ConsumerIdentity) bool { + return identityMatcher(pattern, cur, id) +} + +func GetConsumerId(rawURL, groupId string) (cpi.ConsumerIdentity, error) { + _url, err := url.JoinPath(rawURL, groupId) if err != nil { - return nil + return nil, err } - - url.Path = path.Join(url.Path, pkgName) - return hostpath.GetConsumerIdentity(CONSUMER_TYPE, url.String()) + return hostpath.GetConsumerIdentity(CONSUMER_TYPE, _url), nil } -func GetCredentials(ctx cpi.ContextProvider, repoUrl string, pkgName string) common.Properties { - id := GetConsumerId(repoUrl, pkgName) - if id == nil { - return nil +func GetCredentials(ctx cpi.ContextProvider, repoUrl string, pkgName string) (cpi.Credentials, error) { + id, err := GetConsumerId(repoUrl, pkgName) + if err != nil { + return nil, err } - credentials, err := cpi.CredentialsForConsumer(ctx.CredentialsContext(), id) - if credentials == nil || err != nil { - return nil + if id == nil { + logging.DynamicLogger(REALM).Debug("No consumer identity found.", "url", repoUrl, "groupId", pkgName) + return nil, nil } - return credentials.Properties() + return cpi.CredentialsForConsumer(ctx.CredentialsContext(), id) } diff --git a/pkg/contexts/credentials/repositories/npm/config_test.go b/pkg/contexts/credentials/repositories/npm/config_test.go index e2c2fcfea9..d0ed58df86 100644 --- a/pkg/contexts/credentials/repositories/npm/config_test.go +++ b/pkg/contexts/credentials/repositories/npm/config_test.go @@ -3,18 +3,17 @@ package npm_test import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - . "github.com/open-component-model/ocm/pkg/testutils" "github.com/open-component-model/ocm/pkg/common" "github.com/open-component-model/ocm/pkg/contexts/credentials" "github.com/open-component-model/ocm/pkg/contexts/credentials/builtin/npm/identity" "github.com/open-component-model/ocm/pkg/contexts/credentials/repositories/npm" + . "github.com/open-component-model/ocm/pkg/testutils" ) var _ = Describe("Config deserialization Test Environment", func() { It("read .npmrc", func() { ctx := credentials.New() - repo := Must(npm.NewRepository(ctx, "testdata/.npmrc")) Expect(Must(repo.LookupCredentials("registry.npmjs.org")).Properties()).To(Equal(common.Properties{identity.ATTR_TOKEN: "npm_TOKEN"})) Expect(Must(repo.LookupCredentials("npm.registry.acme.com/api/npm")).Properties()).To(Equal(common.Properties{identity.ATTR_TOKEN: "bearer_TOKEN"})) @@ -22,12 +21,9 @@ var _ = Describe("Config deserialization Test Environment", func() { It("propagates credentials", func() { ctx := credentials.New() - spec := npm.NewRepositorySpec("testdata/.npmrc") - _ = Must(ctx.RepositoryForSpec(spec)) - id := identity.GetConsumerId("registry.npmjs.org", "pkg") - + id := Must(identity.GetConsumerId("registry.npmjs.org", "pkg")) creds := Must(credentials.CredentialsForConsumer(ctx, id)) Expect(creds).NotTo(BeNil()) Expect(creds.GetProperty(identity.ATTR_TOKEN)).To(Equal("npm_TOKEN")) @@ -39,5 +35,4 @@ var _ = Describe("Config deserialization Test Environment", func() { Expect(t).NotTo(BeNil()) Expect(t.Description()).NotTo(Equal("")) }) - }) diff --git a/pkg/contexts/credentials/repositories/npm/provider.go b/pkg/contexts/credentials/repositories/npm/provider.go index 2268ff5faf..a605204371 100644 --- a/pkg/contexts/credentials/repositories/npm/provider.go +++ b/pkg/contexts/credentials/repositories/npm/provider.go @@ -35,8 +35,12 @@ func (p *ConsumerProvider) get(requested cpi.ConsumerIdentity, currentFound cpi. var creds cpi.CredentialsSource for key, value := range all { - id := npm.GetConsumerId("https://"+key, "") - + id, err := npm.GetConsumerId("https://"+key, "") + if err != nil { + log := logging.Context().Logger(npm.REALM) + log.LogError(err, "Failed to get consumer id", "key", key, "value", value) + return nil, nil + } if m(requested, currentFound, id) { creds = newCredentials(value) currentFound = id diff --git a/pkg/contexts/credentials/repositories/npm/repository.go b/pkg/contexts/credentials/repositories/npm/repository.go index 87c4d326c5..0cd48ffa4f 100644 --- a/pkg/contexts/credentials/repositories/npm/repository.go +++ b/pkg/contexts/credentials/repositories/npm/repository.go @@ -65,7 +65,7 @@ func (r *Repository) Read(force bool) error { } if r.path == "" { - return fmt.Errorf("npmrc path not provided") + return errors.New("npmrc path not provided") } cfg, path, err := readNpmConfigFile(r.path) if err != nil { diff --git a/pkg/contexts/ocm/accessmethods/npm/method.go b/pkg/contexts/ocm/accessmethods/npm/method.go index fcf60cc67b..7d70ecb217 100644 --- a/pkg/contexts/ocm/accessmethods/npm/method.go +++ b/pkg/contexts/ocm/accessmethods/npm/method.go @@ -86,7 +86,7 @@ func (a *AccessSpec) AccessMethod(c accspeccpi.ComponentVersionAccess) (accspecc } func (a *AccessSpec) GetInexpensiveContentVersionIdentity(access accspeccpi.ComponentVersionAccess) string { - meta, err := a.getPackageMeta(access.GetContext()) + meta, err := a.GetPackageVersion(access.GetContext()) if err != nil { return "" } @@ -96,36 +96,49 @@ func (a *AccessSpec) GetInexpensiveContentVersionIdentity(access accspeccpi.Comp return "" } -// PackageUrl returns the URL of the NPM package (Registry/Package/Version). +// PackageUrl returns the URL of the NPM package (Registry/Package). func (a *AccessSpec) PackageUrl() string { - return a.Registry + path.Join("/", a.Package, a.Version) + return strings.TrimSuffix(a.Registry, "/") + path.Join("/", a.Package) } -func (a *AccessSpec) getPackageMeta(ctx accspeccpi.Context) (*meta, error) { +// PackageVersionUrl returns the URL of the NPM package-version (Registry/Package/Version). +func (a *AccessSpec) PackageVersionUrl() string { + return strings.TrimSuffix(a.Registry, "/") + path.Join("/", a.Package, a.Version) +} + +func (a *AccessSpec) GetPackageVersion(ctx accspeccpi.Context) (*npm.Version, error) { r, err := reader(a, vfsattr.Get(ctx), ctx) if err != nil { return nil, err } - buf := &bytes.Buffer{} - _, err = io.Copy(buf, io.LimitReader(r, 200000)) + defer r.Close() + buf, err := io.ReadAll(r) if err != nil { - return nil, errors.Wrapf(err, "cannot get version metadata for %s", a.PackageUrl()) + return nil, errors.Wrapf(err, "cannot get version metadata for %s", a.PackageVersionUrl()) } - - var metadata meta - - err = json.Unmarshal(buf.Bytes(), &metadata) - if err != nil { - return nil, errors.Wrapf(err, "cannot unmarshal version metadata for %s", a.PackageUrl()) + var version npm.Version + err = json.Unmarshal(buf, &version) + if err != nil || version.Dist.Tarball == "" { + // ugly fallback as workaround for https://github.com/sonatype/nexus-public/issues/224 + var project npm.Project + err = json.Unmarshal(buf, &project) // parse the complete project + if err != nil { + return nil, errors.Wrapf(err, "cannot unmarshal version metadata for %s", a.PackageVersionUrl()) + } + v, ok := project.Version[a.Version] // and pick only the specified version + if !ok { + return nil, errors.Newf("version '%s' doesn't exist", a.Version) + } + version = v } - return &metadata, nil + return &version, nil } //////////////////////////////////////////////////////////////////////////////// func newMethod(c accspeccpi.ComponentVersionAccess, a *AccessSpec) (accspeccpi.AccessMethodImpl, error) { factory := func() (blobaccess.BlobAccess, error) { - meta, err := a.getPackageMeta(c.GetContext()) + meta, err := a.GetPackageVersion(c.GetContext()) if err != nil { return nil, err } @@ -133,6 +146,20 @@ func newMethod(c accspeccpi.ComponentVersionAccess, a *AccessSpec) (accspeccpi.A f := func() (io.ReadCloser, error) { return reader(a, vfsattr.Get(c.GetContext()), c.GetContext(), meta.Dist.Tarball) } + if meta.Dist.Integrity != "" { + tf := f + f = func() (io.ReadCloser, error) { + r, err := tf() + if err != nil { + return nil, err + } + digest, err := iotools.DecodeBase64ToHex(meta.Dist.Integrity) + if err != nil { + return nil, err + } + return iotools.VerifyingReaderWithHash(r, crypto.SHA512, digest), nil + } + } if meta.Dist.Shasum != "" { tf := f f = func() (io.ReadCloser, error) { @@ -149,15 +176,8 @@ func newMethod(c accspeccpi.ComponentVersionAccess, a *AccessSpec) (accspeccpi.A return accspeccpi.NewDefaultMethodImpl(c, a, "", mime.MIME_TGZ, factory), nil } -type meta struct { - Dist struct { - Shasum string `json:"shasum"` - Tarball string `json:"tarball"` - } `json:"dist"` -} - func reader(a *AccessSpec, fs vfs.FileSystem, ctx cpi.ContextProvider, tar ...string) (io.ReadCloser, error) { - url := a.PackageUrl() + url := a.PackageVersionUrl() if len(tar) > 0 { url = tar[0] } @@ -170,12 +190,38 @@ func reader(a *AccessSpec, fs vfs.FileSystem, ctx cpi.ContextProvider, tar ...st if err != nil { return nil, err } - npm.Authorize(req, ctx, a.Registry, a.Package) + err = npm.BasicAuth(req, ctx, a.Registry, a.Package) + if err != nil { + return nil, err + } c := &http.Client{} resp, err := c.Do(req) if err != nil { return nil, err } + defer resp.Body.Close() + if resp.StatusCode == http.StatusNotFound { + // maybe it's stupid Nexus - https://github.com/sonatype/nexus-public/issues/224? + url = a.PackageUrl() + req, err = http.NewRequestWithContext(context.Background(), http.MethodGet, url, nil) + if err != nil { + return nil, err + } + err = npm.BasicAuth(req, ctx, a.Registry, a.Package) + if err != nil { + return nil, err + } + + // close body before overwriting to close any pending connections + resp.Body.Close() + resp, err = c.Do(req) + if err != nil { + return nil, err + } + + defer resp.Body.Close() + } + if resp.StatusCode != http.StatusOK { defer resp.Body.Close() buf := &bytes.Buffer{} @@ -185,5 +231,9 @@ func reader(a *AccessSpec, fs vfs.FileSystem, ctx cpi.ContextProvider, tar ...st } return nil, errors.Newf("version meta data request %s provides %s: %s", url, resp.Status, buf.String()) } - return resp.Body, nil + content, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + return io.NopCloser(bytes.NewBuffer(content)), nil } diff --git a/pkg/contexts/ocm/accessmethods/npm/method_test.go b/pkg/contexts/ocm/accessmethods/npm/method_test.go index dc4dbd2513..97c8ec7630 100644 --- a/pkg/contexts/ocm/accessmethods/npm/method_test.go +++ b/pkg/contexts/ocm/accessmethods/npm/method_test.go @@ -5,15 +5,15 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - . "github.com/open-component-model/ocm/pkg/env" - . "github.com/open-component-model/ocm/pkg/env/builder" - . "github.com/open-component-model/ocm/pkg/testutils" "github.com/open-component-model/ocm/pkg/contexts/ocm" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/npm" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" + . "github.com/open-component-model/ocm/pkg/env" + . "github.com/open-component-model/ocm/pkg/env/builder" "github.com/open-component-model/ocm/pkg/iotools" "github.com/open-component-model/ocm/pkg/mime" + . "github.com/open-component-model/ocm/pkg/testutils" ) const NPMPATH = "/testdata/registry" @@ -62,4 +62,20 @@ var _ = Describe("Method", func() { _, err := m.Reader() Expect(err).To(MatchError(ContainSubstring("SHA-1 digest mismatch: expected 44a77645201d1a8fc5213ace787c220eabbd0967, found 34a77645201d1a8fc5213ace787c220eabbd0967"))) }) + + It("PackageUrl()", func() { + packageUrl := "https://registry.npmjs.org/yargs" + acc := npm.New("https://registry.npmjs.org", "yargs", "17.7.1") + Expect(acc.PackageUrl()).To(Equal(packageUrl)) + acc = npm.New("https://registry.npmjs.org/", "yargs", "17.7.1") + Expect(acc.PackageUrl()).To(Equal(packageUrl)) + }) + + It("PackageVersionUrl()", func() { + packageVersionUrl := "https://registry.npmjs.org/yargs/17.7.1" + acc := npm.New("https://registry.npmjs.org", "yargs", "17.7.1") + Expect(acc.PackageVersionUrl()).To(Equal(packageVersionUrl)) + acc = npm.New("https://registry.npmjs.org/", "yargs", "17.7.1") + Expect(acc.PackageVersionUrl()).To(Equal(packageVersionUrl)) + }) }) diff --git a/pkg/contexts/ocm/blobhandler/handlers/generic/npm/blobhandler.go b/pkg/contexts/ocm/blobhandler/handlers/generic/npm/blobhandler.go index 76032ffca3..526b1f3dc2 100644 --- a/pkg/contexts/ocm/blobhandler/handlers/generic/npm/blobhandler.go +++ b/pkg/contexts/ocm/blobhandler/handlers/generic/npm/blobhandler.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" + crds "github.com/open-component-model/ocm/pkg/contexts/credentials/cpi" "github.com/open-component-model/ocm/pkg/contexts/ocm/accessmethods/npm" "github.com/open-component-model/ocm/pkg/contexts/ocm/cpi" "github.com/open-component-model/ocm/pkg/logging" @@ -64,14 +65,8 @@ func (b *artifactHandler) StoreBlob(blob cpi.BlobAccess, _ string, _ string, _ c log = log.WithValues("package", pkg.Name, "version", pkg.Version) log.Debug("identified") - token, err := npmLogin.BearerToken(ctx.GetContext(), b.spec.Url, pkg.Name) - if err != nil { - // we assume, it's not possible to publish anonymous - without token - return nil, err - } - // check if package exists - exists, err := packageExists(b.spec.Url, *pkg, token) + exists, err := packageExists(b.spec.Url, *pkg, ctx.GetContext()) if err != nil { return nil, err } @@ -104,8 +99,11 @@ func (b *artifactHandler) StoreBlob(blob cpi.BlobAccess, _ string, _ string, _ c if err != nil { return nil, err } - req.Header.Set("authorization", "Bearer "+token) - req.Header.Set("content-type", "application/json") + err = npmLogin.Authorize(req, ctx.GetContext(), b.spec.Url, pkg.Name) + if err != nil { + return nil, err + } + req.Header.Set("Content-Type", "application/json") // send PUT request - upload tgz client := http.Client{} @@ -127,13 +125,16 @@ func (b *artifactHandler) StoreBlob(blob cpi.BlobAccess, _ string, _ string, _ c } // Check if package already exists in npm registry. If it does, checks if it's the same. -func packageExists(repoUrl string, pkg Package, token string) (bool, error) { +func packageExists(repoUrl string, pkg Package, ctx crds.ContextProvider) (bool, error) { client := http.Client{} req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, repoUrl+"/"+url.PathEscape(pkg.Name)+"/"+url.PathEscape(pkg.Version), nil) if err != nil { return false, err } - req.Header.Set("authorization", "Bearer "+token) + err = npmLogin.Authorize(req, ctx, repoUrl, pkg.Name) + if err != nil { + return false, err + } resp, err := client.Do(req) if err != nil { return false, err diff --git a/pkg/iotools/digests.go b/pkg/iotools/digests.go new file mode 100644 index 0000000000..ab52988499 --- /dev/null +++ b/pkg/iotools/digests.go @@ -0,0 +1,21 @@ +package iotools + +import ( + "encoding/base64" + "encoding/hex" + "regexp" +) + +// Regular expression matching: e.g. 'sha512-', 'SHA-1:', 'Sha-256:', 'sHA42-',. +var re = regexp.MustCompile(`(?i)^sha(\d+-|\-\d+:)`) + +// DecodeBase64ToHex decodes a base64 encoded string and returns the hex representation. +// Any prefix like 'sha512-' or 'SHA-256:' or 'Sha1-' is removed. +func DecodeBase64ToHex(b64encoded string) (string, error) { + b64encoded = re.ReplaceAllString(b64encoded, "") + digest, err := base64.StdEncoding.DecodeString(b64encoded) + if err != nil { + return "", err + } + return hex.EncodeToString(digest), nil +} diff --git a/pkg/iotools/digests_test.go b/pkg/iotools/digests_test.go new file mode 100644 index 0000000000..980472223a --- /dev/null +++ b/pkg/iotools/digests_test.go @@ -0,0 +1,39 @@ +package iotools_test + +import ( + "crypto" + "encoding/base64" + "encoding/hex" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/open-component-model/ocm/pkg/iotools" +) + +var _ = Describe("digests.go tests", func() { + It("DecodeBase64ToHex", func() { + hx, err := iotools.DecodeBase64ToHex("04cXMnFlKzgudf//lH/VqGUtFkplvGv0BCmPREEJsVYTJrxyiBFlsOiZIrjPENBkHWPnK6kOG53VTiqtsILNgw==") + Expect(err).To(BeNil()) + Expect(hx).To(Equal("d387173271652b382e75ffff947fd5a8652d164a65bc6bf404298f444109b1561326bc72881165b0e89922b8cf10d0641d63e72ba90e1b9dd54e2aadb082cd83")) + + hx, err = iotools.DecodeBase64ToHex("sha512-04cXMnFlKzgudf//lH/VqGUtFkplvGv0BCmPREEJsVYTJrxyiBFlsOiZIrjPENBkHWPnK6kOG53VTiqtsILNgw==") + Expect(err).To(BeNil()) + Expect(hx).To(Equal("d387173271652b382e75ffff947fd5a8652d164a65bc6bf404298f444109b1561326bc72881165b0e89922b8cf10d0641d63e72ba90e1b9dd54e2aadb082cd83")) + + hx, err = iotools.DecodeBase64ToHex("SHA512-04cXMnFlKzgudf//lH/VqGUtFkplvGv0BCmPREEJsVYTJrxyiBFlsOiZIrjPENBkHWPnK6kOG53VTiqtsILNgw==") + Expect(err).To(BeNil()) + Expect(hx).To(Equal("d387173271652b382e75ffff947fd5a8652d164a65bc6bf404298f444109b1561326bc72881165b0e89922b8cf10d0641d63e72ba90e1b9dd54e2aadb082cd83")) + + hx, err = iotools.DecodeBase64ToHex("Sha-512:04cXMnFlKzgudf//lH/VqGUtFkplvGv0BCmPREEJsVYTJrxyiBFlsOiZIrjPENBkHWPnK6kOG53VTiqtsILNgw==") + Expect(err).To(BeNil()) + Expect(hx).To(Equal("d387173271652b382e75ffff947fd5a8652d164a65bc6bf404298f444109b1561326bc72881165b0e89922b8cf10d0641d63e72ba90e1b9dd54e2aadb082cd83")) + + s1 := crypto.SHA1.New() + s1.Write([]byte("hello")) + sum := s1.Sum(nil) + hx, err = iotools.DecodeBase64ToHex("sHa-1:" + base64.StdEncoding.EncodeToString(sum)) + Expect(err).To(BeNil()) + Expect(hx).To(Equal(hex.EncodeToString(sum))) + }) +}) diff --git a/pkg/npm/login.go b/pkg/npm/login.go index 17f45b0298..955750cdf3 100644 --- a/pkg/npm/login.go +++ b/pkg/npm/login.go @@ -54,46 +54,71 @@ func Login(registry string, username string, password string, email string) (str return token.Token, nil } +func GetCredentials(ctx cpi.ContextProvider, repoUrl string, pkgName string) (string, string, error) { + credentials, err := identity.GetCredentials(ctx, repoUrl, pkgName) + if err != nil { + return "", "", err + } + if credentials == nil { + return "", "", fmt.Errorf("no credentials found for %s. Couldn't access '%s'", repoUrl, pkgName) + } + return credentials.GetProperty(identity.ATTR_USERNAME), credentials.GetProperty(identity.ATTR_PASSWORD), nil +} + // BearerToken retrieves the bearer token for the given repository URL and package name. // Either it's setup in the credentials or it will login to the registry and retrieve it. func BearerToken(ctx cpi.ContextProvider, repoUrl string, pkgName string) (string, error) { // get credentials and TODO cache it - cred := identity.GetCredentials(ctx, repoUrl, pkgName) - if cred == nil { - return "", fmt.Errorf("no credentials found for %s. Couldn't upload '%s'", repoUrl, pkgName) + credentials, err := identity.GetCredentials(ctx, repoUrl, pkgName) + if err != nil { + return "", err + } + if credentials == nil { + return "", fmt.Errorf("no credentials found for %s. Couldn't access '%s'", repoUrl, pkgName) } log := logging.Context().Logger(identity.REALM) log.Debug("found credentials") // check if token exists, if not login and retrieve token - token := cred[identity.ATTR_TOKEN] + token := credentials.GetProperty(identity.ATTR_TOKEN) if token != "" { log.Debug("token found, skipping login") return token, nil } // use user+pass+mail from credentials to login and retrieve bearer token - username := cred[identity.ATTR_USERNAME] - password := cred[identity.ATTR_PASSWORD] - email := cred[identity.ATTR_EMAIL] + username := credentials.GetProperty(identity.ATTR_USERNAME) + password := credentials.GetProperty(identity.ATTR_PASSWORD) + email := credentials.GetProperty(identity.ATTR_EMAIL) if username == "" || password == "" || email == "" { return "", fmt.Errorf("credentials for %s are invalid. Username, password or email missing! Couldn't upload '%s'", repoUrl, pkgName) } - log = log.WithValues("user", username, "repo", repoUrl) - log.Debug("login") + log.Debug("login", "user", username, "repo", repoUrl) // TODO: check different kinds of .npmrc content - return Login(repoUrl, username, password, email) + token, err = Login(repoUrl, username, password, email) + return token, err } // Authorize the given request with the bearer token for the given repository URL and package name. // If the token is empty (login failed or credentials not found), it will not be set. -func Authorize(req *http.Request, ctx cpi.ContextProvider, repoUrl string, pkgName string) { +func Authorize(req *http.Request, ctx cpi.ContextProvider, repoUrl string, pkgName string) error { token, err := BearerToken(ctx, repoUrl, pkgName) if err != nil { - log := logging.Context().Logger(identity.REALM) - log.Debug("Couldn't authorize", "error", err.Error(), "repo", repoUrl, "package", pkgName) + return err } else if token != "" { - req.Header.Set("authorization", "Bearer "+token) + req.Header.Set("Authorization", "Bearer "+token) + } + return nil +} + +func BasicAuth(req *http.Request, ctx cpi.ContextProvider, repoUrl string, pkgName string) error { + username, password, err := GetCredentials(ctx, repoUrl, pkgName) + if err != nil { + return err + } + if username != "" && password != "" { + req.SetBasicAuth(username, password) } + return nil } diff --git a/pkg/npm/structs.go b/pkg/npm/structs.go new file mode 100644 index 0000000000..e3c52c6af6 --- /dev/null +++ b/pkg/npm/structs.go @@ -0,0 +1,18 @@ +package npm + +type Dist struct { + Integrity string `json:"integrity"` + Shasum string `json:"shasum"` + Tarball string `json:"tarball"` +} + +type Version struct { + Name string `json:"name"` + Version string `json:"version"` + Dist Dist `json:"dist"` +} + +type Project struct { + Name string `json:"name"` + Version map[string]Version `json:"versions"` +} From 89b6e9608cf50df2b0700636dcaf1d7a4761ff6a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 09:37:03 +0200 Subject: [PATCH 09/12] Bump github.com/sigstore/sigstore from 1.8.3 to 1.8.4 in the go group (#786) Bumps the go group with 1 update: [github.com/sigstore/sigstore](https://github.com/sigstore/sigstore). Updates `github.com/sigstore/sigstore` from 1.8.3 to 1.8.4 - [Release notes](https://github.com/sigstore/sigstore/releases) - [Commits](https://github.com/sigstore/sigstore/compare/v1.8.3...v1.8.4) --- updated-dependencies: - dependency-name: github.com/sigstore/sigstore dependency-type: direct:production update-type: version-update:semver-patch dependency-group: go ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/go.mod b/go.mod index 84a8c9eeed..51d0888ad3 100644 --- a/go.mod +++ b/go.mod @@ -55,7 +55,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/sigstore/cosign/v2 v2.2.4 github.com/sigstore/rekor v1.3.6 - github.com/sigstore/sigstore v1.8.3 + github.com/sigstore/sigstore v1.8.4 github.com/sirupsen/logrus v1.9.3 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 @@ -66,6 +66,7 @@ require ( github.com/xeipuuv/gojsonschema v1.2.0 golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 + golang.org/x/mod v0.17.0 golang.org/x/net v0.25.0 golang.org/x/oauth2 v0.20.0 golang.org/x/text v0.15.0 @@ -326,7 +327,6 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/crypto v0.23.0 // indirect - golang.org/x/mod v0.17.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect diff --git a/go.sum b/go.sum index f635f11af8..7ed03f182c 100644 --- a/go.sum +++ b/go.sum @@ -435,8 +435,8 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.18.0 h1:BvolUXjp4zuvkZ5YN5t7ebzbhlUtPsPm2S9NAZ5nl9U= github.com/go-playground/validator/v10 v10.18.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= -github.com/go-rod/rod v0.114.7 h1:h4pimzSOUnw7Eo41zdJA788XsawzHjJMyzCE3BrBww0= -github.com/go-rod/rod v0.114.7/go.mod h1:aiedSEFg5DwG/fnNbUOTPMTTWX3MRj6vIs/a684Mthw= +github.com/go-rod/rod v0.116.0 h1:ypRryjTys3EnqHskJ/TdgodFMvXV0EHvmy4bSkKZgHM= +github.com/go-rod/rod v0.116.0/go.mod h1:aiedSEFg5DwG/fnNbUOTPMTTWX3MRj6vIs/a684Mthw= github.com/go-sql-driver/mysql v1.3.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= @@ -882,8 +882,8 @@ github.com/sigstore/fulcio v1.4.5 h1:WWNnrOknD0DbruuZWCbN+86WRROpEl3Xts+WT2Ek1yc github.com/sigstore/fulcio v1.4.5/go.mod h1:oz3Qwlma8dWcSS/IENR/6SjbW4ipN0cxpRVfgdsjMU8= github.com/sigstore/rekor v1.3.6 h1:QvpMMJVWAp69a3CHzdrLelqEqpTM3ByQRt5B5Kspbi8= github.com/sigstore/rekor v1.3.6/go.mod h1:JDTSNNMdQ/PxdsS49DJkJ+pRJCO/83nbR5p3aZQteXc= -github.com/sigstore/sigstore v1.8.3 h1:G7LVXqL+ekgYtYdksBks9B38dPoIsbscjQJX/MGWkA4= -github.com/sigstore/sigstore v1.8.3/go.mod h1:mqbTEariiGA94cn6G3xnDiV6BD8eSLdL/eA7bvJ0fVs= +github.com/sigstore/sigstore v1.8.4 h1:g4ICNpiENFnWxjmBzBDWUn62rNFeny/P77HUC8da32w= +github.com/sigstore/sigstore v1.8.4/go.mod h1:1jIKtkTFEeISen7en+ZPWdDHazqhxco/+v9CNjc7oNg= github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.3 h1:LTfPadUAo+PDRUbbdqbeSl2OuoFQwUFTnJ4stu+nwWw= github.com/sigstore/sigstore/pkg/signature/kms/aws v1.8.3/go.mod h1:QV/Lxlxm0POyhfyBtIbTWxNeF18clMlkkyL9mu45y18= github.com/sigstore/sigstore/pkg/signature/kms/azure v1.8.3 h1:xgbPRCr2npmmsuVVteJqi/ERw9+I13Wou7kq0Yk4D8g= From 165edcc4c8e800aed37f0345bed834f9d7313f5c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 3 Jun 2024 07:46:48 +0000 Subject: [PATCH 10/12] Bump github.com/cloudflare/cfssl from 0.0.0-20180223231731-4e2dcbde5004 to 1.6.5 (#787) Bump github.com/cloudflare/cfssl Bumps [github.com/cloudflare/cfssl](https://github.com/cloudflare/cfssl) from 0.0.0-20180223231731-4e2dcbde5004 to 1.6.5. - [Release notes](https://github.com/cloudflare/cfssl/releases) - [Changelog](https://github.com/cloudflare/cfssl/blob/master/CHANGELOG) - [Commits](https://github.com/cloudflare/cfssl/commits/v1.6.5) --- updated-dependencies: - dependency-name: github.com/cloudflare/cfssl dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 51d0888ad3..9c9602d284 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,7 @@ require ( github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.21 github.com/aws/aws-sdk-go-v2/service/ecr v1.28.3 github.com/aws/aws-sdk-go-v2/service/s3 v1.54.3 - github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 + github.com/cloudflare/cfssl v1.6.5 github.com/containerd/containerd v1.7.17 github.com/containerd/log v0.1.0 github.com/containers/image/v5 v5.31.0 diff --git a/go.sum b/go.sum index 7ed03f182c..6555a0c94f 100644 --- a/go.sum +++ b/go.sum @@ -249,8 +249,9 @@ github.com/clbanning/mxj/v2 v2.5.5/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn github.com/clbanning/mxj/v2 v2.7.0 h1:WA/La7UGCanFe5NpHF0Q3DNtnCsVoxbPKuyBNHWRyME= github.com/clbanning/mxj/v2 v2.7.0/go.mod h1:hNiWqW14h+kc+MdF9C6/YoRfjEJoR3ou6tn/Qo+ve2s= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/cfssl v0.0.0-20180223231731-4e2dcbde5004 h1:lkAMpLVBDaj17e85keuznYcH5rqI438v41pKcBl4ZxQ= 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.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= @@ -975,6 +976,8 @@ github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQ github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/vbatts/tar-split v0.11.5 h1:3bHCTIheBm1qFTcgh9oPu+nNBtX+XJIupG/vacinCts= github.com/vbatts/tar-split v0.11.5/go.mod h1:yZbwRsSeGjusneWgA781EKej9HF8vme8okylkAeNKLk= +github.com/weppos/publicsuffix-go v0.30.1-0.20230620154423-38c92ad2d5c6 h1:kNn7cjQYeNjKUflvFFCxFeyS7ENcDdfPmkhFpgd0G/A= +github.com/weppos/publicsuffix-go v0.30.1-0.20230620154423-38c92ad2d5c6/go.mod h1:wdMq89hDN07Zqr0yqYAXIBTJXl4MEELx+HYHOZdf5gM= github.com/xanzy/go-gitlab v0.102.0 h1:ExHuJ1OTQ2yt25zBMMj0G96ChBirGYv8U7HyUiYkZ+4= github.com/xanzy/go-gitlab v0.102.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= @@ -1015,6 +1018,10 @@ github.com/zalando/go-keyring v0.2.3 h1:v9CUu9phlABObO4LPWycf+zwMG7nlbb3t/B5wa97 github.com/zalando/go-keyring v0.2.3/go.mod h1:HL4k+OXQfJUWaMnqyuSOc0drfGPX2b51Du6K+MRgZMk= github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs= github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300 h1:DZH5n7L3L8RxKdSyJHZt7WePgwdhHnPhQFdQSJaHF+o= +github.com/zmap/zcrypto v0.0.0-20230310154051-c8b263fd8300/go.mod h1:mOd4yUMgn2fe2nV9KXsa9AyQBFZGzygVPovsZR+Rl5w= +github.com/zmap/zlint/v3 v3.5.0 h1:Eh2B5t6VKgVH0DFmTwOqE50POvyDhUaU9T2mJOe1vfQ= +github.com/zmap/zlint/v3 v3.5.0/go.mod h1:JkNSrsDJ8F4VRtBZcYUQSvnWFL7utcjDIn+FE64mlBI= go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= From 7a913dc51ebc2f8db714d99a8e061017ee71ae01 Mon Sep 17 00:00:00 2001 From: Uwe Krueger Date: Mon, 3 Jun 2024 09:59:34 +0200 Subject: [PATCH 11/12] various fixes/improvements for tests and paths to prepare migration (#788) Co-authored-by: Hilmar Falkenberg --- .../commands/misccmds/hash/sign/cmd_test.go | 3 ++- .../common/inputs/types/maven/input_test.go | 5 ++-- .../lib/tour/04-working-with-config/README.md | 2 +- .../docsrc/04-working-with-config/README.md | 2 +- pkg/blobaccess/maven/access_test.go | 11 +++++--- .../ocm/accessmethods/maven/method_test.go | 25 +++++++++--------- .../ocm/accessmethods/ociartifact/README.md | 2 +- .../accessmethods/relativeociref/README.md | 4 +-- pkg/contexts/ocm/repositories/ctf/README.md | 2 +- .../ocm/repositories/ocireg/README.md | 2 +- pkg/contexts/ocm/signing/signing_test.go | 4 +-- .../ocm/signing/signingtest/testdata.go | 13 +++++++++ ...425f502dd6518e40eaa3ac7d24023d4c73d55dc12e | 0 .../component-descriptor.yaml | 0 .../testdata/compat/rsa.priv | 0 .../{ => signingtest}/testdata/compat/rsa.pub | 0 pkg/maven/maventest/const.go | 8 ++++++ pkg/maven/maventest/testdata.go | 4 +++ .../5.7.0/sdk-modules-bom-5.7.0-sources.jar | Bin 595 -> 424 bytes .../sdk-modules-bom-5.7.0-sources.jar.sha1 | 2 +- .../5.7.0/sdk-modules-bom-5.7.0.jar | Bin 595 -> 424 bytes .../5.7.0/sdk-modules-bom-5.7.0.jar.sha1 | 2 +- 22 files changed, 62 insertions(+), 29 deletions(-) create mode 100644 pkg/contexts/ocm/signing/signingtest/testdata.go rename pkg/contexts/ocm/signing/{ => signingtest}/testdata/compat/component-archive/blobs/sha256.c893900c1106f13d55648a425f502dd6518e40eaa3ac7d24023d4c73d55dc12e (100%) rename pkg/contexts/ocm/signing/{ => signingtest}/testdata/compat/component-archive/component-descriptor.yaml (100%) rename pkg/contexts/ocm/signing/{ => signingtest}/testdata/compat/rsa.priv (100%) rename pkg/contexts/ocm/signing/{ => signingtest}/testdata/compat/rsa.pub (100%) create mode 100644 pkg/maven/maventest/const.go diff --git a/cmds/ocm/commands/misccmds/hash/sign/cmd_test.go b/cmds/ocm/commands/misccmds/hash/sign/cmd_test.go index 0c542f75ab..faf7dd8bfc 100644 --- a/cmds/ocm/commands/misccmds/hash/sign/cmd_test.go +++ b/cmds/ocm/commands/misccmds/hash/sign/cmd_test.go @@ -6,6 +6,7 @@ import ( . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/open-component-model/ocm/cmds/ocm/testhelper" + "github.com/open-component-model/ocm/pkg/contexts/ocm/signing/signingtest" . "github.com/open-component-model/ocm/pkg/testutils" ) @@ -15,7 +16,7 @@ var _ = Describe("Test Environment", func() { var env *TestEnv BeforeEach(func() { - env = NewTestEnv(TestData("../../../../../../pkg/contexts/ocm/signing/testdata")) + env = NewTestEnv(signingtest.TestData()) }) AfterEach(func() { diff --git a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go index 7731e45ac5..ea833e53e8 100644 --- a/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go +++ b/cmds/ocm/commands/ocmcmds/common/inputs/types/maven/input_test.go @@ -2,6 +2,7 @@ package maven_test import ( "crypto" + "github.com/open-component-model/ocm/pkg/maven/maventest" . "github.com/mandelsoft/goutils/testutils" @@ -44,7 +45,7 @@ var _ = Describe("Test Environment", func() { access := Must(env.Context.OCMContext().AccessSpecForSpec(cd.Resources[0].Access)).(*localblob.AccessSpec) Expect(access.MediaType).To(Equal(mime.MIME_TGZ)) fi := Must(env.FileSystem().Stat(env.Join(ARCH, "blobs", access.LocalReference))) - Expect(fi.Size()).To(Equal(int64(1570))) + Expect(fi.Size()).To(Equal(int64(maventest.ARTIFACT_SIZE))) li := Must(tarutils.ListArchiveContent(env.Join(ARCH, "blobs", access.LocalReference), env.FileSystem())) Expect(li).To(ConsistOf( "sdk-modules-bom-5.7.0-random-content.json", @@ -53,7 +54,7 @@ var _ = Describe("Test Environment", func() { "sdk-modules-bom-5.7.0.jar", "sdk-modules-bom-5.7.0.pom")) Expect(cd.Resources[0].Digest.HashAlgorithm).To(Equal(crypto.SHA256.String())) - Expect(cd.Resources[0].Digest.Value).To(Equal("16cfb5ced0ea7688dba14aeb0d3aa76ad46e4661bfcc556ffd7287de3b2f7152")) + Expect(cd.Resources[0].Digest.Value).To(Equal(maventest.ARTIFACT_DIGEST)) }) It("add maven from file system described by cli options", func() { diff --git a/examples/lib/tour/04-working-with-config/README.md b/examples/lib/tour/04-working-with-config/README.md index 2b156dc19a..0ec8a67c0c 100644 --- a/examples/lib/tour/04-working-with-config/README.md +++ b/examples/lib/tour/04-working-with-config/README.md @@ -115,7 +115,7 @@ settings for the given object and calls the appropriate methods on this object (after a type cast). Here is the code snippet from the apply method of the credential -config object ([.../pkg/contexts/credentials/config/type.go](../../../../../pkg/contexts/credentials/config/type.go)): +config object ([.../pkg/contexts/credentials/config/type.go](../../../../pkg/contexts/credentials/config/type.go)): ```go diff --git a/examples/lib/tour/docsrc/04-working-with-config/README.md b/examples/lib/tour/docsrc/04-working-with-config/README.md index 74572d52bb..bd0cf2a5bd 100644 --- a/examples/lib/tour/docsrc/04-working-with-config/README.md +++ b/examples/lib/tour/docsrc/04-working-with-config/README.md @@ -90,7 +90,7 @@ settings for the given object and calls the appropriate methods on this object (after a type cast). Here is the code snippet from the apply method of the credential -config object ([.../pkg/contexts/credentials/config/type.go](../../../../../pkg/contexts/credentials/config/type.go)): +config object ([.../pkg/contexts/credentials/config/type.go](../../../../pkg/contexts/credentials/config/type.go)): ```go {{include}{../../../../../pkg/contexts/credentials/config/type.go}{apply}} diff --git a/pkg/blobaccess/maven/access_test.go b/pkg/blobaccess/maven/access_test.go index e2e10c96df..de275eae53 100644 --- a/pkg/blobaccess/maven/access_test.go +++ b/pkg/blobaccess/maven/access_test.go @@ -1,9 +1,10 @@ package maven_test import ( - "github.com/open-component-model/ocm/pkg/maven/maventest" "time" + "github.com/open-component-model/ocm/pkg/maven/maventest" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/open-component-model/ocm/pkg/env/builder" @@ -45,8 +46,12 @@ var _ = Describe("blobaccess for maven", func() { b := Must(me.BlobAccessForMaven(repo, coords.GroupId, coords.ArtifactId, coords.Version, me.WithCachingFileSystem(env.FileSystem()))) defer Close(b, "blobaccess") files := Must(tarutils.ListArchiveContentFromReader(Must(b.Reader()))) - Expect(files).To(ConsistOf("sdk-modules-bom-5.7.0.pom", "sdk-modules-bom-5.7.0.jar", "sdk-modules-bom-5.7.0-random-content.txt", - "sdk-modules-bom-5.7.0-random-content.json", "sdk-modules-bom-5.7.0-sources.jar")) + Expect(files).To(ConsistOf( + "sdk-modules-bom-5.7.0.pom", + "sdk-modules-bom-5.7.0.jar", + "sdk-modules-bom-5.7.0-random-content.txt", + "sdk-modules-bom-5.7.0-random-content.json", + "sdk-modules-bom-5.7.0-sources.jar")) }) It("blobaccess for files with the same classifier", func() { diff --git a/pkg/contexts/ocm/accessmethods/maven/method_test.go b/pkg/contexts/ocm/accessmethods/maven/method_test.go index 20310c92d0..bfd7a43103 100644 --- a/pkg/contexts/ocm/accessmethods/maven/method_test.go +++ b/pkg/contexts/ocm/accessmethods/maven/method_test.go @@ -2,9 +2,10 @@ package maven_test import ( "crypto" - "github.com/open-component-model/ocm/pkg/maven/maventest" "time" + "github.com/open-component-model/ocm/pkg/maven/maventest" + . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" . "github.com/open-component-model/ocm/pkg/env/builder" @@ -48,16 +49,16 @@ var _ = Describe("local accessmethods.maven.AccessSpec tests", func() { Expect(m.MimeType()).To(Equal(mime.MIME_TGZ)) r := Must(m.Reader()) defer Close(r) - dr := iotools.NewDigestReaderWithHash(crypto.SHA1, r) - for { - var buf [8096]byte - _, err := dr.Read(buf[:]) - if err != nil { - break - } - } - Expect(dr.Size()).To(Equal(int64(1570))) - Expect(dr.Digest().String()).To(Equal("SHA-1:359d02795bcc737e81c7f2f0ac32f49351d41867")) + dr := iotools.NewDigestReaderWithHash(crypto.SHA256, r) + li := Must(tarutils.ListArchiveContentFromReader(dr)) + Expect(li).To(ConsistOf( + "sdk-modules-bom-5.7.0-random-content.json", + "sdk-modules-bom-5.7.0-random-content.txt", + "sdk-modules-bom-5.7.0-sources.jar", + "sdk-modules-bom-5.7.0.jar", + "sdk-modules-bom-5.7.0.pom")) + Expect(dr.Size()).To(Equal(int64(maventest.ARTIFACT_SIZE))) + Expect(dr.Digest().String()).To(Equal("SHA-256:" + maventest.ARTIFACT_DIGEST)) }) It("accesses local artifact with empty classifier and with extension", func() { @@ -78,7 +79,7 @@ var _ = Describe("local accessmethods.maven.AccessSpec tests", func() { } Expect(dr.Size()).To(Equal(int64(7153))) - Expect(dr.Digest().String()).To(Equal("SHA-1:34ccdeb9c008f8aaef90873fc636b09d3ae5c709")) + Expect(dr.Digest().String()).To(Equal(maventest.POM_SHA1)) }) It("accesses local artifact with extension", func() { diff --git a/pkg/contexts/ocm/accessmethods/ociartifact/README.md b/pkg/contexts/ocm/accessmethods/ociartifact/README.md index fa818f6525..5b3b14b547 100644 --- a/pkg/contexts/ocm/accessmethods/ociartifact/README.md +++ b/pkg/contexts/ocm/accessmethods/ociartifact/README.md @@ -15,7 +15,7 @@ Provided blobs use the following media type: Depending on the repository appropriate docker legacy types might be used. -The artifact content is provided in the [Artifact Set Format](../../../oci/repositories/ctf/README.md#artifact-set-archive-format). +The artifact content is provided in the [Artifact Set Format](../../../../../pkg/contexts/oci/repositories/ctf/formatspec.md#artifact-set-archive-format). The tag is provided as annotation. ### Description diff --git a/pkg/contexts/ocm/accessmethods/relativeociref/README.md b/pkg/contexts/ocm/accessmethods/relativeociref/README.md index c174d43a8e..a08466d4f5 100644 --- a/pkg/contexts/ocm/accessmethods/relativeociref/README.md +++ b/pkg/contexts/ocm/accessmethods/relativeociref/README.md @@ -15,7 +15,7 @@ Provided blobs use the following media type: Depending on the repository appropriate docker legacy types might be used. -The artifact content is provided in the [Artifact Set Format](../../../oci/repositories/ctf/formatspec.md#artifact-set-archive-format). +The artifact content is provided in the [Artifact Set Format](../../../../../pkg/contexts/oci/repositories/ctf/formatspec.md#artifact-set-archive-format). The tag is provided as annotation. ### Description @@ -23,7 +23,7 @@ The tag is provided as annotation. This method implements the access of an OCI artifact stored in an OCI registry, which is used to host the OCM repository the component version is retrieved from. -It works similar to the [`ociArtifact`](../ociartifact/README.md) access method, +It works similar to the [`ociArtifact`](../../../../../pkg/contexts/ocm/accessmethods/ociartifact/README.md) access method, but the used reference does not contain the OCI registry host, which is taken from the OCI registry used to host the component version containing the access specification. diff --git a/pkg/contexts/ocm/repositories/ctf/README.md b/pkg/contexts/ocm/repositories/ctf/README.md index 0907d9ae08..22bd5f73ed 100644 --- a/pkg/contexts/ocm/repositories/ctf/README.md +++ b/pkg/contexts/ocm/repositories/ctf/README.md @@ -34,4 +34,4 @@ The type specific specification fields are: ### Go Bindings -The Go binding can be found [here](../../../oci/repositories/ctf/type.go). +The Go binding can be found [here](../../../../../pkg/contexts/oci/repositories/ctf/type.go). diff --git a/pkg/contexts/ocm/repositories/ocireg/README.md b/pkg/contexts/ocm/repositories/ocireg/README.md index f832cbfe2a..e7df056359 100644 --- a/pkg/contexts/ocm/repositories/ocireg/README.md +++ b/pkg/contexts/ocm/repositories/ocireg/README.md @@ -40,4 +40,4 @@ The type specific specification fields are: ### Go Bindings -The Go binding can be found [here](../../../oci/repositories/ocireg/type.go). +The Go binding can be found [here](../../../../../pkg/contexts/oci/repositories/ocireg/type.go). diff --git a/pkg/contexts/ocm/signing/signing_test.go b/pkg/contexts/ocm/signing/signing_test.go index 4ec44fc1a7..1abe817506 100644 --- a/pkg/contexts/ocm/signing/signing_test.go +++ b/pkg/contexts/ocm/signing/signing_test.go @@ -10,6 +10,7 @@ import ( . "github.com/onsi/gomega" . "github.com/open-component-model/ocm/pkg/contexts/oci/testhelper" . "github.com/open-component-model/ocm/pkg/contexts/ocm/signing" + "github.com/open-component-model/ocm/pkg/contexts/ocm/signing/signingtest" . "github.com/open-component-model/ocm/pkg/contexts/ocm/testhelper" . "github.com/open-component-model/ocm/pkg/env/builder" . "github.com/open-component-model/ocm/pkg/testutils" @@ -29,7 +30,6 @@ import ( "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/composition" "github.com/open-component-model/ocm/pkg/contexts/ocm/repositories/ctf" "github.com/open-component-model/ocm/pkg/contexts/ocm/resourcetypes" - tenv "github.com/open-component-model/ocm/pkg/env" "github.com/open-component-model/ocm/pkg/mime" "github.com/open-component-model/ocm/pkg/signing" "github.com/open-component-model/ocm/pkg/signing/handlers/rsa" @@ -59,7 +59,7 @@ var _ = Describe("access method", func() { var env *Builder BeforeEach(func() { - env = NewBuilder(tenv.ModifiableTestData()) + env = NewBuilder(signingtest.ModifiableTestData()) env.RSAKeyPair(SIGNATURE, SIGNATURE2) }) diff --git a/pkg/contexts/ocm/signing/signingtest/testdata.go b/pkg/contexts/ocm/signing/signingtest/testdata.go new file mode 100644 index 0000000000..ea51fa190b --- /dev/null +++ b/pkg/contexts/ocm/signing/signingtest/testdata.go @@ -0,0 +1,13 @@ +package signingtest + +import ( + "github.com/open-component-model/ocm/pkg/env" +) + +func TestData(dest ...string) env.Option { + return env.ProjectTestDataForCaller(dest...) +} + +func ModifiableTestData(dest ...string) env.Option { + return env.ModifiableProjectTestDataForCaller(dest...) +} diff --git a/pkg/contexts/ocm/signing/testdata/compat/component-archive/blobs/sha256.c893900c1106f13d55648a425f502dd6518e40eaa3ac7d24023d4c73d55dc12e b/pkg/contexts/ocm/signing/signingtest/testdata/compat/component-archive/blobs/sha256.c893900c1106f13d55648a425f502dd6518e40eaa3ac7d24023d4c73d55dc12e similarity index 100% rename from pkg/contexts/ocm/signing/testdata/compat/component-archive/blobs/sha256.c893900c1106f13d55648a425f502dd6518e40eaa3ac7d24023d4c73d55dc12e rename to pkg/contexts/ocm/signing/signingtest/testdata/compat/component-archive/blobs/sha256.c893900c1106f13d55648a425f502dd6518e40eaa3ac7d24023d4c73d55dc12e diff --git a/pkg/contexts/ocm/signing/testdata/compat/component-archive/component-descriptor.yaml b/pkg/contexts/ocm/signing/signingtest/testdata/compat/component-archive/component-descriptor.yaml similarity index 100% rename from pkg/contexts/ocm/signing/testdata/compat/component-archive/component-descriptor.yaml rename to pkg/contexts/ocm/signing/signingtest/testdata/compat/component-archive/component-descriptor.yaml diff --git a/pkg/contexts/ocm/signing/testdata/compat/rsa.priv b/pkg/contexts/ocm/signing/signingtest/testdata/compat/rsa.priv similarity index 100% rename from pkg/contexts/ocm/signing/testdata/compat/rsa.priv rename to pkg/contexts/ocm/signing/signingtest/testdata/compat/rsa.priv diff --git a/pkg/contexts/ocm/signing/testdata/compat/rsa.pub b/pkg/contexts/ocm/signing/signingtest/testdata/compat/rsa.pub similarity index 100% rename from pkg/contexts/ocm/signing/testdata/compat/rsa.pub rename to pkg/contexts/ocm/signing/signingtest/testdata/compat/rsa.pub diff --git a/pkg/maven/maventest/const.go b/pkg/maven/maventest/const.go new file mode 100644 index 0000000000..1e80a4db00 --- /dev/null +++ b/pkg/maven/maventest/const.go @@ -0,0 +1,8 @@ +package maventest + +const ( + ARTIFACT_SIZE = 1504 + ARTIFACT_DIGEST = "dc5b38b58fd18cb0336c2e0deebeb5d2277c34312ae7024074812f34acfebc65" //nolint: gosec // yes +) + +const POM_SHA1 = "SHA-1:34ccdeb9c008f8aaef90873fc636b09d3ae5c709" diff --git a/pkg/maven/maventest/testdata.go b/pkg/maven/maventest/testdata.go index 64f0c103e8..efd26ff62a 100644 --- a/pkg/maven/maventest/testdata.go +++ b/pkg/maven/maventest/testdata.go @@ -7,3 +7,7 @@ import ( func TestData(dest ...string) env.Option { return env.ProjectTestDataForCaller(dest...) } + +func ModifiableTestData(dest ...string) env.Option { + return env.ModifiableProjectTestDataForCaller(dest...) +} diff --git a/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-sources.jar b/pkg/maven/maventest/testdata/.m2/repository/com/sap/cloud/sdk/sdk-modules-bom/5.7.0/sdk-modules-bom-5.7.0-sources.jar index 8564f0addae8de5525417df8294d13c0c2a3a7c0..1d5cd83128edaf5e6980edcf4344fc8e1701b0a1 100644 GIT binary patch literal 424 zcmWIWW@Zs#;Nak3V2L>t!GHuf8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1g=~? literal 595 zcmWIWW@h1HVBlb2I6ZY+1OpP_WME~0p0C?y-!rFuymj?1@_OrPojY@WbCAIm;|EWR^t^m^Jbf>guG$i0z|{3Z zQZu9C$@67uqD!Y`e=7P|#0a#Cor7naNwg)65ZVVl++yk z{N!Byg6wqtq@4Vu#N_1E;$r>W#In>p{gTw;l9a@fME%s^D&0A%HfJ3D=4gl*pE23j>4+%YaO}g$OGf$YN$76k=px&<0`# F1^|3_lot!GHuf8CV#6T|*poJ^kGD|D9rBU}gyLX6FE@V1g=~? literal 595 zcmWIWW@h1HVBlb2I6ZY+1OpP_WME~0p0C?y-!rFuymj?1@_OrPojY@WbCAIm;|EWR^t^m^Jbf>guG$i0z|{3Z zQZu9C$@67uqD!Y`e=7P|#0a#Cor7naNwg)65ZVVl++yk z{N!Byg6wqtq@4Vu#N_1E;$r>W#In>p{gTw;l9a@fME%s^D&0A%HfJ3D=4gl*pE23j>4+%YaO}g$OGf$YN$76k=px&<0`# F1^|3_lo Date: Mon, 3 Jun 2024 12:38:06 +0200 Subject: [PATCH 12/12] add workflow for updateVendorHash of flake (#789) flake updateVendorHash workflow --- .github/workflows/flake_vendorhash.yaml | 62 +++++++++++++++++++++++++ flake.nix | 5 ++ 2 files changed, 67 insertions(+) create mode 100644 .github/workflows/flake_vendorhash.yaml diff --git a/.github/workflows/flake_vendorhash.yaml b/.github/workflows/flake_vendorhash.yaml new file mode 100644 index 0000000000..68788602d0 --- /dev/null +++ b/.github/workflows/flake_vendorhash.yaml @@ -0,0 +1,62 @@ +name: "Flake vendorHash Updater" +on: + push: + branches: + - main + paths: + - 'go.mod' + - 'go.sum' + workflow_dispatch: + workflow_call: + +jobs: + updateVendorHash: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: write + 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 repository + uses: actions/checkout@v4 + with: + 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>" + - name: Install Nix + uses: DeterminateSystems/nix-installer-action@main + - name: Update ocm vendor hash + run: nix run .#nixpkgs.nix-update -- --flake --version=skip ocm + - name: Check diff + id: check-diff + run: | + diff=$(git diff) + if [[ -z "$diff" ]]; then + echo "Everything is tidy." + exit 0 + fi + + cat << EOF >> "${GITHUB_STEP_SUMMARY}" + \`\`\`diff + ${diff} + \`\`\` + EOF + echo "push='true'" >> $GITHUB_ENV + - name: Push changes + if: github.event.pull_request.head.repo.fork == false && env.push == 'true' + run: | + diff=$(git diff) + if [[ ! -z "$diff" ]]; then + git config --global user.name "ocm-vendorhash" + git config --global user.email "ocm-vendorhash@users.noreply.github.com" + git commit -am "flake: update ocm vendorHash" + git push + fi diff --git a/flake.nix b/flake.nix index f27a550d44..e6f9d9ddd2 100644 --- a/flake.nix +++ b/flake.nix @@ -118,5 +118,10 @@ program = self.packages.${system}.${pname} + "/bin/ecrplugin"; }; }); + + legacyPackages = forAllSystems (system: rec { + nixpkgs = nixpkgsFor.${system}; + }); + }; }