From ae115062330605a4b85201562c9cc60dffbb8be6 Mon Sep 17 00:00:00 2001 From: "Brad P. Crochet" Date: Thu, 10 Nov 2022 11:24:33 -0500 Subject: [PATCH] Add the ability to check a container from another platform If a multiarch manifest is supplied to check container, it would default to the platform preflight is running on. This --platform flag allows the user to choose with platform image to use, without having to resort to using SHA digests. Fixes #807 Signed-off-by: Brad P. Crochet --- certification/config.go | 1 + certification/internal/engine/engine.go | 3 +-- certification/internal/policy/container/has_unique_tag.go | 6 ------ certification/runtime/assets.go | 3 ++- certification/runtime/config.go | 2 ++ certification/runtime/config_read.go | 4 ++++ certification/runtime/config_read_test.go | 2 ++ certification/runtime/config_test.go | 4 +++- cmd/preflight/cmd/check_container.go | 4 ++++ 9 files changed, 19 insertions(+), 10 deletions(-) diff --git a/certification/config.go b/certification/config.go index 91ca932e..e0bd0405 100644 --- a/certification/config.go +++ b/certification/config.go @@ -29,6 +29,7 @@ type containerConfig interface { PyxisHost() string PyxisAPIToken() string Submit() bool + Platform() string } // operatorConfig are configurables relevant to diff --git a/certification/internal/engine/engine.go b/certification/internal/engine/engine.go index 20ad39af..1376800c 100644 --- a/certification/internal/engine/engine.go +++ b/certification/internal/engine/engine.go @@ -13,7 +13,6 @@ import ( "path" "path/filepath" "regexp" - goruntime "runtime" "sort" "strings" "sync" @@ -81,7 +80,7 @@ func (c *CraneEngine) ExecuteChecks(ctx context.Context) error { ), crane.WithPlatform(&cranev1.Platform{ OS: "linux", - Architecture: goruntime.GOARCH, + Architecture: c.Config.Platform(), }), retryOnceAfter(5 * time.Second), } diff --git a/certification/internal/policy/container/has_unique_tag.go b/certification/internal/policy/container/has_unique_tag.go index 5f9475ff..19288374 100644 --- a/certification/internal/policy/container/has_unique_tag.go +++ b/certification/internal/policy/container/has_unique_tag.go @@ -3,14 +3,12 @@ package container import ( "context" "fmt" - goruntime "runtime" "strings" "github.com/redhat-openshift-ecosystem/openshift-preflight/certification" "github.com/redhat-openshift-ecosystem/openshift-preflight/certification/internal/authn" "github.com/google/go-containerregistry/pkg/crane" - cranev1 "github.com/google/go-containerregistry/pkg/v1" ) var _ certification.Check = &hasUniqueTagCheck{} @@ -59,10 +57,6 @@ func (p *hasUniqueTagCheck) getDataToValidate(ctx context.Context, image string) options := []crane.Option{ crane.WithContext(ctx), crane.WithAuthFromKeychain(authn.PreflightKeychain(authn.WithDockerConfig(p.dockercfg))), - crane.WithPlatform(&cranev1.Platform{ - OS: "linux", - Architecture: goruntime.GOARCH, - }), } return crane.ListTags(image, options...) diff --git a/certification/runtime/assets.go b/certification/runtime/assets.go index 8156fe4c..29a17442 100644 --- a/certification/runtime/assets.go +++ b/certification/runtime/assets.go @@ -29,7 +29,8 @@ func imageList(ctx context.Context) []string { crane.WithContext(ctx), crane.WithAuthFromKeychain(authn.PreflightKeychain()), crane.WithPlatform(&cranev1.Platform{ - OS: "linux", + OS: "linux", + // This remains the runtime arch, as we don't specify the arch for operators Architecture: goruntime.GOARCH, }), } diff --git a/certification/runtime/config.go b/certification/runtime/config.go index 9dc7f18f..4d1138ff 100644 --- a/certification/runtime/config.go +++ b/certification/runtime/config.go @@ -24,6 +24,7 @@ type Config struct { PyxisAPIToken string DockerConfig string Submit bool + Platform string // Operator-Specific Fields Namespace string ServiceAccount string @@ -63,6 +64,7 @@ func (c *Config) storeContainerPolicyConfiguration(vcfg viper.Viper) { c.Submit = vcfg.GetBool("submit") c.PyxisHost = pyxisHostLookup(vcfg.GetString("pyxis_env"), vcfg.GetString("pyxis_host")) c.CertificationProjectID = vcfg.GetString("certification_project_id") + c.Platform = vcfg.GetString("platform") } // storeOperatorPolicyConfiguration reads operator-policy-specific config diff --git a/certification/runtime/config_read.go b/certification/runtime/config_read.go index 0187e30b..096932e8 100644 --- a/certification/runtime/config_read.go +++ b/certification/runtime/config_read.go @@ -93,3 +93,7 @@ func (ro *ReadOnlyConfig) Kubeconfig() string { func (ro *ReadOnlyConfig) IndexImage() string { return ro.cfg.IndexImage } + +func (ro *ReadOnlyConfig) Platform() string { + return ro.cfg.Platform +} diff --git a/certification/runtime/config_read_test.go b/certification/runtime/config_read_test.go index f6154008..d7a434e2 100644 --- a/certification/runtime/config_read_test.go +++ b/certification/runtime/config_read_test.go @@ -21,6 +21,7 @@ var _ = Describe("Runtime ReadOnlyConfig test", func() { PyxisAPIToken: "pyxisapitoken", DockerConfig: "dockercfg", Submit: true, + Platform: "s390x", Namespace: "ns", ServiceAccount: "sa", ScorecardImage: "scorecardimg", @@ -44,6 +45,7 @@ var _ = Describe("Runtime ReadOnlyConfig test", func() { Expect(cro.PyxisAPIToken()).To(Equal("pyxisapitoken")) Expect(cro.DockerConfig()).To(Equal("dockercfg")) Expect(cro.Submit()).To(Equal(true)) + Expect(cro.Platform()).To(Equal("s390x")) Expect(cro.Namespace()).To(Equal("ns")) Expect(cro.ServiceAccount()).To(Equal("sa")) Expect(cro.ScorecardImage()).To(Equal("scorecardimg")) diff --git a/certification/runtime/config_test.go b/certification/runtime/config_test.go index b07f6317..ac29c6d3 100644 --- a/certification/runtime/config_test.go +++ b/certification/runtime/config_test.go @@ -37,6 +37,8 @@ var _ = Describe("Viper to Runtime Config", func() { expectedRuntimeCfg.PyxisHost = "catalog.redhat.com/api/containers" baseViperCfg.Set("certification_project_id", "000000000000") expectedRuntimeCfg.CertificationProjectID = "000000000000" + baseViperCfg.Set("platform", "s390x") + expectedRuntimeCfg.Platform = "s390x" baseViperCfg.Set("namespace", "myns") expectedRuntimeCfg.Namespace = "myns" @@ -66,6 +68,6 @@ var _ = Describe("Viper to Runtime Config", func() { // accurate in confirming that the derived configuration from viper // matches. keys := reflect.TypeOf(Config{}).NumField() - Expect(keys).To(Equal(20)) + Expect(keys).To(Equal(21)) }) }) diff --git a/cmd/preflight/cmd/check_container.go b/cmd/preflight/cmd/check_container.go index 9911a74b..960c4ab9 100644 --- a/cmd/preflight/cmd/check_container.go +++ b/cmd/preflight/cmd/check_container.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + rt "runtime" "strings" "github.com/redhat-openshift-ecosystem/openshift-preflight/certification" @@ -47,6 +48,9 @@ func checkContainerCmd() *cobra.Command { "URL paramater. This value may differ from the PID on the overview page. (env: PFLT_CERTIFICATION_PROJECT_ID)")) _ = viper.BindPFlag("certification_project_id", checkContainerCmd.Flags().Lookup("certification-project-id")) + checkContainerCmd.Flags().String("platform", rt.GOARCH, "Architecture of image to pull. Defaults to current platform.") + _ = viper.BindPFlag("platform", checkContainerCmd.Flags().Lookup("platform")) + return checkContainerCmd }