diff --git a/Makefile b/Makefile index 9a75abaa..9aa5cd54 100644 --- a/Makefile +++ b/Makefile @@ -117,7 +117,7 @@ test-e2e: $(GINKGO) ## Run the e2e tests $(GINKGO) $(E2E_FLAGS) --trace $(FOCUS) test/e2e e2e: KIND_CLUSTER_NAME := rukpak-e2e -e2e: run image-registry local-git kind-load-bundles registry-load-bundles test-e2e kind-cluster-cleanup ## Run e2e tests against an ephemeral kind cluster +e2e: run image-registry secure-image-registry local-git kind-load-bundles registry-load-bundles secure-registry-load-bundles test-e2e kind-cluster-cleanup ## Run e2e tests against an ephemeral kind cluster kind-cluster: $(KIND) kind-cluster-cleanup ## Standup a kind cluster $(KIND) create cluster --name ${KIND_CLUSTER_NAME} ${KIND_CLUSTER_CONFIG} @@ -127,7 +127,10 @@ kind-cluster-cleanup: $(KIND) ## Delete the kind cluster $(KIND) delete cluster --name ${KIND_CLUSTER_NAME} image-registry: ## Setup in-cluster image registry - ./test/tools/imageregistry/setup_imageregistry.sh ${KIND_CLUSTER_NAME} + ./test/tools/imageregistry/image-registry.sh ${REGISTRY_NAMESPACE} ${REGISTRY_NAME} + +secure-image-registry: ## Setup a private in-cluster image registry + ./test/tools/imageregistry/image-registry-secure.sh ${REGISTRY_NAMESPACE} ${REGISTRY_NAME} local-git: ## Setup in-cluster git repository ./test/tools/git/setup_git.sh ${KIND_CLUSTER_NAME} @@ -218,8 +221,19 @@ kind-load: $(KIND) ## Loads the currently constructed image onto the cluster $(KIND) load docker-image $(IMAGE) --name $(KIND_CLUSTER_NAME) registry-load-bundles: ## Load selected e2e testdata container images created in kind-load-bundles into registry - $(CONTAINER_RUNTIME) tag localhost/testdata/bundles/plain-v0:valid $(DNS_NAME):5000/bundles/plain-v0:valid - ./test/tools/imageregistry/load_test_image.sh $(KIND) $(KIND_CLUSTER_NAME) + testdata/bundles/plain-v0/valid/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:valid + testdata/bundles/plain-v0/dependent/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:dependent + testdata/bundles/plain-v0/provides/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:provides + testdata/bundles/plain-v0/empty/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:empty + testdata/bundles/plain-v0/no-manifests/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:no-manifests + testdata/bundles/plain-v0/invalid-missing-crds/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:invalid-missing-crds + testdata/bundles/plain-v0/invalid-crds-and-crs/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:invalid-crds-and-crs + testdata/bundles/plain-v0/subdir/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/plain-v0:subdir + testdata/bundles/registry/valid/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/registry:valid + testdata/bundles/registry/invalid/build-push-e2e-bundle.sh ${REGISTRY_NAMESPACE} $(DNS_NAME):5000/bundles/registry:invalid + +secure-registry-load-bundles: ## Load selected e2e testdata container images created in kind-load-bundles into private registry + testdata/bundles/plain-v0/valid/build-push-e2e-bundle-secure.sh ${REGISTRY_NAMESPACE} docker-registry-secure.rukpak-e2e.svc.cluster.local:5000/bundles/plain-v0:valid ########### # Release # diff --git a/api/v1alpha2/bundle_types.go b/api/v1alpha2/bundle_types.go index 77003aa5..602e8ffb 100644 --- a/api/v1alpha2/bundle_types.go +++ b/api/v1alpha2/bundle_types.go @@ -61,6 +61,12 @@ type ImageSource struct { Ref string `json:"ref"` // ImagePullSecretName contains the name of the image pull secret in the namespace that the provisioner is deployed. ImagePullSecretName string `json:"pullSecret,omitempty"` + // InsecureSkipTLSVerify indicates that TLS certificate validation should be skipped. + // If this option is specified, the HTTPS protocol will still be used to + // fetch the specified image reference. + // This should not be used in a production environment. + // +optional + InsecureSkipTLSVerify bool `json:"insecureSkipTLSVerify,omitempty"` } type GitSource struct { diff --git a/cmd/core/main.go b/cmd/core/main.go index 3badffa2..575d2239 100644 --- a/cmd/core/main.go +++ b/cmd/core/main.go @@ -77,7 +77,7 @@ func main() { enableLeaderElection bool probeAddr string systemNamespace string - unpackImage string + unpackCacheDir string rukpakVersion bool provisionerStorageDirectory string ) @@ -86,7 +86,7 @@ func main() { flag.StringVar(&bundleCAFile, "bundle-ca-file", "", "The file containing the certificate authority for connecting to bundle content servers.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") flag.StringVar(&systemNamespace, "system-namespace", "", "Configures the namespace that gets used to deploy system resources.") - flag.StringVar(&unpackImage, "unpack-image", util.DefaultUnpackImage, "Configures the container image that gets used to unpack Bundle contents.") + flag.StringVar(&unpackCacheDir, "unpack-cache-dir", "/var/cache/unpack", "Configures the directory that gets used to unpack and cache Bundle contents.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ "Enabling this will ensure there is only one active controller manager.") @@ -107,7 +107,7 @@ func main() { } ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts))) - setupLog.Info("starting up the core controllers and servers", "git commit", version.String(), "unpacker image", unpackImage) + setupLog.Info("starting up the core controllers and servers", "git commit", version.String(), "unpacker cache", unpackCacheDir) dependentRequirement, err := labels.NewRequirement(util.CoreOwnerKindKey, selection.In, []string{rukpakv1alpha2.BundleDeploymentKind}) if err != nil { @@ -196,12 +196,17 @@ func main() { os.Exit(1) } - unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackImage, rootCAs) + unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackCacheDir, rootCAs) if err != nil { setupLog.Error(err, "unable to setup bundle unpacker") os.Exit(1) } + if err := bundleFinalizers.Register(finalizer.CleanupUnpackCacheKey, &finalizer.CleanupUnpackCache{Unpacker: unpacker}); err != nil { + setupLog.Error(err, "unable to register finalizer", "finalizerKey", finalizer.CleanupUnpackCacheKey) + os.Exit(1) + } + bdNamespaceMapper := func(obj client.Object) (string, error) { bd, ok := obj.(*rukpakv1alpha2.BundleDeployment) if !ok { @@ -261,8 +266,9 @@ func main() { os.Exit(1) } + ctx := ctrl.SetupSignalHandler() setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + if err := mgr.Start(ctx); err != nil { setupLog.Error(err, "problem running manager") os.Exit(1) } diff --git a/cmd/helm/main.go b/cmd/helm/main.go index 50b7de67..9402ffa5 100644 --- a/cmd/helm/main.go +++ b/cmd/helm/main.go @@ -70,7 +70,7 @@ func main() { enableLeaderElection bool probeAddr string systemNamespace string - unpackImage string + unpackCacheDir string rukpakVersion bool storageDirectory string ) @@ -78,7 +78,7 @@ func main() { flag.StringVar(&httpExternalAddr, "http-external-address", "http://localhost:8080", "The external address at which the http server is reachable.") flag.StringVar(&bundleCAFile, "bundle-ca-file", "", "The file containing the certificate authority for connecting to bundle content servers.") flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.") - flag.StringVar(&unpackImage, "unpack-image", util.DefaultUnpackImage, "Configures the container image that gets used to unpack Bundle contents.") + flag.StringVar(&unpackCacheDir, "unpack-cache-dir", "/var/cache/unpack", "Configures the directory that gets used to unpack and cache Bundle contents.") flag.StringVar(&systemNamespace, "system-namespace", "", "Configures the namespace that gets used to deploy system resources.") flag.BoolVar(&enableLeaderElection, "leader-elect", false, "Enable leader election for controller manager. "+ @@ -188,12 +188,17 @@ func main() { os.Exit(1) } - unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackImage, rootCAs) + unpacker, err := source.NewDefaultUnpacker(mgr, systemNamespace, unpackCacheDir, rootCAs) if err != nil { setupLog.Error(err, "unable to setup bundle unpacker") os.Exit(1) } + if err := bundleFinalizers.Register(finalizer.CleanupUnpackCacheKey, &finalizer.CleanupUnpackCache{Unpacker: unpacker}); err != nil { + setupLog.Error(err, "unable to register finalizer", "finalizerKey", finalizer.CleanupUnpackCacheKey) + os.Exit(1) + } + bdNamespaceMapper := func(obj client.Object) (string, error) { bd, ok := obj.(*rukpakv1alpha2.BundleDeployment) if !ok { @@ -243,8 +248,9 @@ func main() { os.Exit(1) } + ctx := ctrl.SetupSignalHandler() setupLog.Info("starting manager") - if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil { + if err := mgr.Start(ctx); err != nil { setupLog.Error(err, "problem running manager") os.Exit(1) } diff --git a/go.mod b/go.mod index 4aa5d56a..1f8c07bc 100644 --- a/go.mod +++ b/go.mod @@ -5,9 +5,13 @@ go 1.21 toolchain go1.21.0 require ( + github.com/containerd/containerd v1.7.15 github.com/go-git/go-billy/v5 v5.5.0 github.com/go-git/go-git/v5 v5.12.0 github.com/go-logr/logr v1.4.1 + github.com/google/go-containerregistry v0.19.1 + github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240418155129-98dd3e91704f + github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240418155129-98dd3e91704f github.com/gorilla/handlers v1.5.2 github.com/nlepage/go-tarfs v1.2.1 github.com/onsi/ginkgo/v2 v2.17.2 @@ -35,9 +39,20 @@ require ( ) require ( + cloud.google.com/go/compute v1.24.0 // indirect + cloud.google.com/go/compute/metadata v0.2.3 // indirect dario.cat/mergo v1.0.0 // indirect github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 // indirect + github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect + github.com/Azure/go-autorest v14.2.0+incompatible // indirect + github.com/Azure/go-autorest/autorest v0.11.29 // indirect + github.com/Azure/go-autorest/autorest/adal v0.9.23 // indirect + github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 // indirect + github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 // indirect + github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect + github.com/Azure/go-autorest/logger v0.2.1 // indirect + github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/BurntSushi/toml v1.3.2 // indirect github.com/MakeNowJust/heredoc v1.0.0 // indirect github.com/Masterminds/goutils v1.1.1 // indirect @@ -49,17 +64,33 @@ require ( github.com/ProtonMail/go-crypto v1.0.0 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect + github.com/aws/aws-sdk-go-v2 v1.18.0 // indirect + github.com/aws/aws-sdk-go-v2/config v1.18.25 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.13.24 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 // indirect + github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 // indirect + github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 // indirect + github.com/aws/smithy-go v1.13.5 // indirect + github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230510185313-f5e39e5f34c7 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chai2010/gettext-go v1.0.2 // indirect + github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/cgroups/v3 v3.0.2 // indirect - github.com/containerd/containerd v1.7.15 // indirect github.com/containerd/continuity v0.4.2 // indirect github.com/containerd/errdefs v0.1.0 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/containerd/stargz-snapshotter/estargz v0.15.1 // indirect github.com/containerd/ttrpc v1.2.3 // indirect github.com/containerd/typeurl/v2 v2.1.1 // indirect github.com/containers/common v0.58.2 // indirect @@ -69,6 +100,7 @@ require ( github.com/containers/storage v1.53.0 // indirect github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/dimchansky/utfbom v1.1.1 // indirect github.com/distribution/reference v0.6.0 // indirect github.com/docker/cli v26.0.1+incompatible // indirect github.com/docker/distribution v2.8.3+incompatible // indirect @@ -96,6 +128,7 @@ require ( github.com/go-task/slim-sprig/v3 v3.0.0 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang-jwt/jwt/v4 v4.5.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/btree v1.1.2 // indirect @@ -119,6 +152,7 @@ require ( github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmoiron/sqlx v1.3.5 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect @@ -134,6 +168,7 @@ require ( github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect diff --git a/go.sum b/go.sum index eb3ae9ac..80ee8171 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,39 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= +cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= +cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= +cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU= github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible h1:fcYLmCpyNYRnvJbPerq7U0hS+6+I79yEDJBqVNcqUzU= +github.com/Azure/azure-sdk-for-go v68.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0= github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.29 h1:I4+HL/JDvErx2LjyzaVxllw2lRDB5/BT2Bm4g20iqYw= +github.com/Azure/go-autorest/autorest v0.11.29/go.mod h1:ZtEzC4Jy2JDrZLxvWs8LrBWEBycl1hbT1eknI8MtfAs= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.22/go.mod h1:XuAbAEUv2Tta//+voMI038TrJBqjKam0me7qR+L8Cmk= +github.com/Azure/go-autorest/autorest/adal v0.9.23 h1:Yepx8CvFxwNKpH6ja7RZ+sKX+DWYNldbLiALMC3BTz8= +github.com/Azure/go-autorest/autorest/adal v0.9.23/go.mod h1:5pcMqFkdPhviJdlEy3kC/v1ZLnQl0MH6XA5YCcMhy4c= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 h1:wkAZRgT/pn8HhFyzfe9UnqOjJYqlembgCTi72Bm/xKk= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.12/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6 h1:w77/uPk80ZET2F+AfQExZyEWtn+0Rk/uw17m9fv5Ajc= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2 h1:PGN4EDXnuQbojHbU0UWoNvmu9AGVwYHG9/fkDYhtAfw= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -38,6 +67,36 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-sdk-go-v2 v1.18.0 h1:882kkTpSFhdgYRKVZ/VCgf7sd0ru57p2JCxz4/oN5RY= +github.com/aws/aws-sdk-go-v2 v1.18.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= +github.com/aws/aws-sdk-go-v2/config v1.18.25 h1:JuYyZcnMPBiFqn87L2cRppo+rNwgah6YwD3VuyvaW6Q= +github.com/aws/aws-sdk-go-v2/config v1.18.25/go.mod h1:dZnYpD5wTW/dQF0rRNLVypB396zWCcPiBIvdvSWHEg4= +github.com/aws/aws-sdk-go-v2/credentials v1.13.24 h1:PjiYyls3QdCrzqUN35jMWtUK1vqVZ+zLfdOa/UPFDp0= +github.com/aws/aws-sdk-go-v2/credentials v1.13.24/go.mod h1:jYPYi99wUOPIFi0rhiOvXeSEReVOzBqFNOX5bXYoG2o= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3 h1:jJPgroehGvjrde3XufFIJUZVK5A2L9a3KwSFgKy9n8w= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.3/go.mod h1:4Q0UFP0YJf0NrsEuEYHpM9fTSEVnD16Z3uyEF7J9JGM= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33 h1:kG5eQilShqmJbv11XL1VpyDbaEJzWxd4zRiCG30GSn4= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.33/go.mod h1:7i0PF1ME/2eUPFcjkVIwq+DOygHEoK92t5cDqNgYbIw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27 h1:vFQlirhuM8lLlpI7imKOMsjdQLuN9CPi+k44F/OFVsk= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.27/go.mod h1:UrHnn3QV/d0pBZ6QBAEQcqFLf8FAzLmoUfPVIueOvoM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 h1:gGLG7yKaXG02/jBlg210R7VgQIotiQntNhsCFejawx8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc= +github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 h1:wlTgmb/sCmVRJrN5De3CiHj4v/bTCgL5+qpdEd0CPtw= +github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11/go.mod h1:Ce1q2jlNm8BVpjLaOnwnm5v2RClAbK6txwPljFzyW6c= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 h1:yflJrGmi1pXtP9lOpOeaNZyc0vXnJTuP2sor3nJcGGo= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2/go.mod h1:uHtRE7aqXNmpeYL+7Ec7LacH5zC9+w2T5MBOeEKDdu0= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27 h1:0iKliEXAcCa2qVtRs7Ot5hItA2MsufrphbRFlz1Owxo= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27/go.mod h1:EOwBD4J4S5qYszS5/3DpkejfuK+Z5/1uzICfPaZLtqw= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.10 h1:UBQjaMTCKwyUYwiVnUt6toEJwGXsLBI6al083tpjJzY= +github.com/aws/aws-sdk-go-v2/service/sso v1.12.10/go.mod h1:ouy2P4z6sJN70fR3ka3wD3Ro3KezSxU6eKGQI2+2fjI= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10 h1:PkHIIJs8qvq0e5QybnZoG1K/9QTrLr9OsqCIo59jOBA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10/go.mod h1:AFvkxc8xfBe8XA+5St5XIHHrQQtkxqrRincx4hmMHOk= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.0 h1:2DQLAKDteoEDI8zpCzqBMaZlJuoE9iTYD0gFmXVax9E= +github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jelyPW7NoZcZXLVpDsXunGDrk8= +github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8= +github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230510185313-f5e39e5f34c7 h1:G5IT+PEpFY0CDb3oITDP9tkmLrHkVD8Ny+elUmBqVYI= +github.com/awslabs/amazon-ecr-credential-helper/ecr-login v0.0.0-20230510185313-f5e39e5f34c7/go.mod h1:VVALgT1UESBh91dY0GprHnT1Z7mKd96VDk8qVy+bmu0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -54,6 +113,8 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chai2010/gettext-go v1.0.2 h1:1Lwwip6Q2QGsAdl/ZKPCwTe9fe0CjlUbqj5bFNSjIRk= github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 h1:krfRl01rzPzxSxyLyrChD+U+MzsBXbm0OwYYB67uF+4= +github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589/go.mod h1:OuDyvmLnMCwa2ep4Jkm6nyA0ocJuZlGyk2gGseVzERM= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -72,6 +133,8 @@ github.com/containerd/errdefs v0.1.0 h1:m0wCRBiu1WJT/Fr+iOoQHMQS/eP5myQ8lCv4Dz5Z github.com/containerd/errdefs v0.1.0/go.mod h1:YgWiiHtLmSeBrvpw+UfPijzbLaB77mEG1WwJTDETIV0= 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/containerd/ttrpc v1.2.3 h1:4jlhbXIGvijRtNC8F/5CpuJZ7yKOBFGFOOXg1bkISz0= github.com/containerd/ttrpc v1.2.3/go.mod h1:ieWsXucbb8Mj9PH0rXCw1i8IunRbbAiDkpXkbfflWBM= github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4= @@ -95,11 +158,14 @@ github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnGqR5Vl2tAx0= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/distribution/distribution/v3 v3.0.0-alpha.1 h1:jn7I1gvjOvmLztH1+1cLiUFud7aeJCIQcgzugtwjyJo= github.com/distribution/distribution/v3 v3.0.0-alpha.1/go.mod h1:LCp4JZp1ZalYg0W/TN05jarCQu+h4w7xc7ZfQF4Y/cY= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= @@ -110,6 +176,7 @@ github.com/docker/distribution v2.8.3+incompatible h1:AtKxIZ36LoNK51+Z6RpzLpddBi github.com/docker/distribution v2.8.3+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/docker v25.0.5+incompatible h1:UmQydMduGkrD5nQde1mecF/YnSbTOaPeFIeP5C4W+DE= github.com/docker/docker v25.0.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0= github.com/docker/docker-credential-helpers v0.8.1 h1:j/eKUktUltBtMzKqmfLB0PAgqYyMHOp5vfsD1807oKo= github.com/docker/docker-credential-helpers v0.8.1/go.mod h1:P3ci7E3lwkZg6XiHdRKft1KckHiO9a2rNtyFbZ/ry9M= github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c= @@ -194,6 +261,10 @@ github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJA github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= +github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-migrate/migrate/v4 v4.17.0 h1:rd40H3QXU0AA4IoLllFcEAEo9dYKRHYND2gB4p7xcaU= github.com/golang-migrate/migrate/v4 v4.17.0/go.mod h1:+Cp2mtLP4/aXDTKb9wmXYitdrNx2HGs45rbWAo6OsKM= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= @@ -231,9 +302,16 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm88DeNujc7C1KY= +github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= +github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240418155129-98dd3e91704f h1:HqnjbuZokjLKB/qgZi3jXPM74jvpots2u4YvsBmzlng= +github.com/google/go-containerregistry/pkg/authn/k8schain v0.0.0-20240418155129-98dd3e91704f/go.mod h1:5UXYZJNyCPf2YD+6J76geTiLAXA8fJbDy7mGQa5m5Vc= +github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240418155129-98dd3e91704f h1:yvqkwgo5+YJNRSpaCwo1GbEdYlJAnkWVYVb0oInLc9s= +github.com/google/go-containerregistry/pkg/authn/kubernetes v0.0.0-20240418155129-98dd3e91704f/go.mod h1:8oYKXummIO/NNasXRCKr4DBziuA1MZ+VEhSQMYI8aJ0= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -284,6 +362,10 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -345,6 +427,8 @@ github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -454,6 +538,7 @@ github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5g github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/skeema/knownhosts v1.2.2 h1:Iug2P4fLmDw9f41PB6thxUkNUkJzB5i+1/exaj40L3A= @@ -482,6 +567,7 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI= @@ -561,9 +647,12 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= @@ -624,10 +713,12 @@ golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/internal/finalizer/cleanupunpackcache.go b/internal/finalizer/cleanupunpackcache.go new file mode 100644 index 00000000..51d5407d --- /dev/null +++ b/internal/finalizer/cleanupunpackcache.go @@ -0,0 +1,23 @@ +package finalizer + +import ( + "context" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/finalizer" + + "github.com/operator-framework/rukpak/api/v1alpha2" + "github.com/operator-framework/rukpak/pkg/source" +) + +var _ finalizer.Finalizer = &CleanupUnpackCache{} + +const CleanupUnpackCacheKey = "core.rukpak.io/cleanup-unpack-cache" + +type CleanupUnpackCache struct { + Unpacker source.Unpacker +} + +func (f CleanupUnpackCache) Finalize(ctx context.Context, obj client.Object) (finalizer.Result, error) { + return finalizer.Result{}, f.Unpacker.Cleanup(ctx, obj.(*v1alpha2.BundleDeployment)) +} diff --git a/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml b/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml index 41e2dbf2..49556a80 100644 --- a/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml +++ b/manifests/base/apis/crds/core.rukpak.io_bundledeployments.yaml @@ -210,6 +210,13 @@ spec: description: Image is the bundle image that backs the content of this bundle. properties: + insecureSkipTLSVerify: + description: |- + InsecureSkipTLSVerify indicates that TLS certificate validation should be skipped. + If this option is specified, the HTTPS protocol will still be used to + fetch the specified image reference. + This should not be used in a production environment. + type: boolean pullSecret: description: ImagePullSecretName contains the name of the image pull secret in the namespace that the provisioner @@ -448,6 +455,13 @@ spec: description: Image is the bundle image that backs the content of this bundle. properties: + insecureSkipTLSVerify: + description: |- + InsecureSkipTLSVerify indicates that TLS certificate validation should be skipped. + If this option is specified, the HTTPS protocol will still be used to + fetch the specified image reference. + This should not be used in a production environment. + type: boolean pullSecret: description: ImagePullSecretName contains the name of the image pull secret in the namespace that the provisioner diff --git a/manifests/base/core/resources/deployment.yaml b/manifests/base/core/resources/deployment.yaml index 146ccdec..28febbe2 100644 --- a/manifests/base/core/resources/deployment.yaml +++ b/manifests/base/core/resources/deployment.yaml @@ -55,7 +55,7 @@ spec: imagePullPolicy: IfNotPresent command: ["/core"] args: - - "--unpack-image=quay.io/operator-framework/rukpak:devel" + - "--unpack-cache-dir=/var/cache/unpack" - "--provisioner-storage-dir=/var/cache/bundles" - "--http-bind-address=127.0.0.1:8080" - "--http-external-address=https://$(CORE_SERVICE_NAME).$(CORE_SERVICE_NAMESPACE).svc" @@ -65,6 +65,8 @@ spec: volumeMounts: - name: bundle-cache mountPath: /var/cache/bundles + - name: unpack-cache + mountPath: /var/cache/unpack resources: requests: cpu: 10m @@ -73,3 +75,5 @@ spec: volumes: - name: bundle-cache emptyDir: {} + - name: unpack-cache + emptyDir: {} diff --git a/manifests/base/provisioners/helm/resources/deployment.yaml b/manifests/base/provisioners/helm/resources/deployment.yaml index fe558997..486cf0b5 100644 --- a/manifests/base/provisioners/helm/resources/deployment.yaml +++ b/manifests/base/provisioners/helm/resources/deployment.yaml @@ -55,7 +55,7 @@ spec: imagePullPolicy: IfNotPresent command: ["/helm"] args: - - "--unpack-image=quay.io/operator-framework/rukpak:devel" + - "--unpack-cache-dir=/var/cache/unpack" - "--storage-dir=/var/cache/bundles" - "--http-bind-address=127.0.0.1:8080" - "--http-external-address=https://$(HELM_PROVISIONER_SERVICE_NAME).$(HELM_PROVISIONER_SERVICE_NAMESPACE).svc" @@ -64,6 +64,8 @@ spec: volumeMounts: - name: bundle-cache mountPath: /var/cache/bundles + - name: unpack-cache + mountPath: /var/cache/unpack resources: requests: cpu: 10m @@ -72,3 +74,5 @@ spec: volumes: - name: bundle-cache emptyDir: {} + - name: unpack-cache + emptyDir: {} diff --git a/pkg/errors/unrecoverable.go b/pkg/errors/unrecoverable.go new file mode 100644 index 00000000..c212422b --- /dev/null +++ b/pkg/errors/unrecoverable.go @@ -0,0 +1,12 @@ +package errors + +// Unrecoverable represents an error that can not be recovered +// from without user intervention. When this error is returned +// the request should not be requeued. +type Unrecoverable struct { + error +} + +func NewUnrecoverable(err error) *Unrecoverable { + return &Unrecoverable{err} +} diff --git a/pkg/source/configmaps.go b/pkg/source/configmaps.go index b676f650..9f2b5b41 100644 --- a/pkg/source/configmaps.go +++ b/pkg/source/configmaps.go @@ -82,3 +82,7 @@ func (o *ConfigMaps) Unpack(ctx context.Context, bundle *rukpakv1alpha2.BundleDe message := generateMessage("configMaps") return &Result{Bundle: bundleFS, ResolvedSource: resolvedSource, State: StateUnpacked, Message: message}, nil } + +func (o *ConfigMaps) Cleanup(_ context.Context, _ *rukpakv1alpha2.BundleDeployment) error { + return nil +} diff --git a/pkg/source/git.go b/pkg/source/git.go index 3c2d3ebe..140ff6c0 100644 --- a/pkg/source/git.go +++ b/pkg/source/git.go @@ -128,6 +128,10 @@ func (r *Git) Unpack(ctx context.Context, bundle *rukpakv1alpha2.BundleDeploymen return &Result{Bundle: bundleFS, ResolvedSource: resolvedSource, State: StateUnpacked, Message: message}, nil } +func (r *Git) Cleanup(_ context.Context, _ *rukpakv1alpha2.BundleDeployment) error { + return nil +} + func (r *Git) configAuth(ctx context.Context, bundle *rukpakv1alpha2.BundleDeployment) (transport.AuthMethod, error) { var auth transport.AuthMethod if strings.HasPrefix(bundle.Spec.Source.Git.Repository, "http") { diff --git a/pkg/source/http.go b/pkg/source/http.go index 5fb33b95..1272493b 100644 --- a/pkg/source/http.go +++ b/pkg/source/http.go @@ -73,6 +73,10 @@ func (b *HTTP) Unpack(ctx context.Context, bundle *rukpakv1alpha2.BundleDeployme return &Result{Bundle: fs, ResolvedSource: bundle.Spec.Source.DeepCopy(), State: StateUnpacked, Message: message}, nil } +func (b *HTTP) Cleanup(_ context.Context, _ *rukpakv1alpha2.BundleDeployment) error { + return nil +} + // getCredentials reads credentials from the secret specified in the bundle // It returns the username ane password when they are in the secret func (b *HTTP) getCredentials(ctx context.Context, bundle *rukpakv1alpha2.BundleDeployment) (string, string, error) { diff --git a/pkg/source/image_registry.go b/pkg/source/image_registry.go new file mode 100644 index 00000000..745d8b3c --- /dev/null +++ b/pkg/source/image_registry.go @@ -0,0 +1,183 @@ +package source + +import ( + "archive/tar" + "context" + "crypto/tls" + "errors" + "fmt" + "io/fs" + "net/http" + "os" + "path/filepath" + "strings" + + "github.com/containerd/containerd/archive" + "github.com/google/go-containerregistry/pkg/authn/k8schain" + gcrkube "github.com/google/go-containerregistry/pkg/authn/kubernetes" + "github.com/google/go-containerregistry/pkg/name" + "github.com/google/go-containerregistry/pkg/v1/remote" + apimacherrors "k8s.io/apimachinery/pkg/util/errors" + "sigs.k8s.io/controller-runtime/pkg/log" + + rukpakv1alpha2 "github.com/operator-framework/rukpak/api/v1alpha2" + rukpakerrors "github.com/operator-framework/rukpak/pkg/errors" +) + +// TODO: Make asynchronous + +type ImageRegistry struct { + BaseCachePath string + AuthNamespace string +} + +func (i *ImageRegistry) Unpack(ctx context.Context, bundle *rukpakv1alpha2.BundleDeployment) (*Result, error) { + l := log.FromContext(ctx) + if bundle.Spec.Source.Type != rukpakv1alpha2.SourceTypeImage { + panic(fmt.Sprintf("programmer error: source type %q is unable to handle specified bundle source type %q", rukpakv1alpha2.SourceTypeImage, bundle.Spec.Source.Type)) + } + + if bundle.Spec.Source.Image == nil { + return nil, rukpakerrors.NewUnrecoverable(fmt.Errorf("error parsing bundle, bundle %s has a nil image source", bundle.Name)) + } + + imgRef, err := name.ParseReference(bundle.Spec.Source.Image.Ref) + if err != nil { + return nil, rukpakerrors.NewUnrecoverable(fmt.Errorf("error parsing image reference: %w", err)) + } + + remoteOpts := []remote.Option{} + if bundle.Spec.Source.Image.ImagePullSecretName != "" { + chainOpts := k8schain.Options{ + ImagePullSecrets: []string{bundle.Spec.Source.Image.ImagePullSecretName}, + Namespace: i.AuthNamespace, + // TODO: Do we want to use any secrets that are included in the rukpak service account? + // If so, we will need to add the permission to get service accounts and specify + // the rukpak service account name here. + ServiceAccountName: gcrkube.NoServiceAccount, + } + authChain, err := k8schain.NewInCluster(ctx, chainOpts) + if err != nil { + return nil, fmt.Errorf("error getting auth keychain: %w", err) + } + + remoteOpts = append(remoteOpts, remote.WithAuthFromKeychain(authChain)) + } + + if bundle.Spec.Source.Image.InsecureSkipTLSVerify { + insecureTransport := remote.DefaultTransport.(*http.Transport).Clone() + if insecureTransport.TLSClientConfig == nil { + insecureTransport.TLSClientConfig = &tls.Config{} // nolint:gosec + } + insecureTransport.TLSClientConfig.InsecureSkipVerify = true // nolint:gosec + remoteOpts = append(remoteOpts, remote.WithTransport(insecureTransport)) + } + + digest, isDigest := imgRef.(name.Digest) + if isDigest { + hexVal := strings.TrimPrefix(digest.DigestStr(), "sha256:") + unpackPath := filepath.Join(i.BaseCachePath, bundle.Name, hexVal) + if stat, err := os.Stat(unpackPath); err == nil && stat.IsDir() { + l.V(1).Info("found image in filesystem cache", "digest", hexVal) + return unpackedResult(os.DirFS(unpackPath), bundle, digest.String()), nil + } + } + + // always fetch the hash + imgDesc, err := remote.Head(imgRef, remoteOpts...) + if err != nil { + return nil, fmt.Errorf("error fetching image descriptor: %w", err) + } + l.V(1).Info("resolved image descriptor", "digest", imgDesc.Digest.String()) + + unpackPath := filepath.Join(i.BaseCachePath, bundle.Name, imgDesc.Digest.Hex) + if _, err = os.Stat(unpackPath); errors.Is(err, os.ErrNotExist) { //nolint: nestif + // Ensure any previous unpacked bundle is cleaned up before unpacking the new catalog. + if err := i.Cleanup(ctx, bundle); err != nil { + return nil, fmt.Errorf("error cleaning up bundle cache: %w", err) + } + + if err = os.MkdirAll(unpackPath, 0700); err != nil { + return nil, fmt.Errorf("error creating unpack path: %w", err) + } + + if err = unpackImage(ctx, imgRef, unpackPath, remoteOpts...); err != nil { + cleanupErr := os.RemoveAll(unpackPath) + if cleanupErr != nil { + err = apimacherrors.NewAggregate( + []error{ + err, + fmt.Errorf("error cleaning up unpack path after unpack failed: %w", cleanupErr), + }, + ) + } + return nil, wrapUnrecoverable(fmt.Errorf("error unpacking image: %w", err), isDigest) + } + } else if err != nil { + return nil, fmt.Errorf("error checking if image is in filesystem cache: %w", err) + } + + resolvedRef := fmt.Sprintf("%s@sha256:%s", imgRef.Context().Name(), imgDesc.Digest.Hex) + return unpackedResult(os.DirFS(unpackPath), bundle, resolvedRef), nil +} + +func wrapUnrecoverable(err error, isUnrecoverable bool) error { + if isUnrecoverable { + return rukpakerrors.NewUnrecoverable(err) + } + return err +} + +func (i *ImageRegistry) Cleanup(_ context.Context, bundle *rukpakv1alpha2.BundleDeployment) error { + return os.RemoveAll(filepath.Join(i.BaseCachePath, bundle.Name)) +} + +func unpackedResult(fsys fs.FS, bundle *rukpakv1alpha2.BundleDeployment, ref string) *Result { + return &Result{ + Bundle: fsys, + ResolvedSource: &rukpakv1alpha2.BundleSource{ + Type: rukpakv1alpha2.SourceTypeImage, + Image: &rukpakv1alpha2.ImageSource{ + Ref: ref, + ImagePullSecretName: bundle.Spec.Source.Image.ImagePullSecretName, + InsecureSkipTLSVerify: bundle.Spec.Source.Image.InsecureSkipTLSVerify, + }, + }, + State: StateUnpacked, + } +} + +// unpackImage unpacks a bundle image reference to the provided unpackPath, +// returning an error if any errors are encountered along the way. +func unpackImage(ctx context.Context, imgRef name.Reference, unpackPath string, remoteOpts ...remote.Option) error { + img, err := remote.Image(imgRef, remoteOpts...) + if err != nil { + return fmt.Errorf("error fetching remote image %q: %w", imgRef.Name(), err) + } + + layers, err := img.Layers() + if err != nil { + return fmt.Errorf("error getting image layers: %w", err) + } + + for _, layer := range layers { + layerRc, err := layer.Uncompressed() + if err != nil { + return fmt.Errorf("error getting uncompressed layer data: %w", err) + } + + // This filter ensures that the files created have the proper UID and GID + // for the filesystem they will be stored on to ensure no permission errors occur when attempting to create the + // files. + _, err = archive.Apply(ctx, unpackPath, layerRc, archive.WithFilter(func(th *tar.Header) (bool, error) { + th.Uid = os.Getuid() + th.Gid = os.Getgid() + return true, nil + })) + if err != nil { + return fmt.Errorf("error applying layer to archive: %w", err) + } + } + + return nil +} diff --git a/pkg/source/unpacker.go b/pkg/source/unpacker.go index 9fac0a14..bbe3a696 100644 --- a/pkg/source/unpacker.go +++ b/pkg/source/unpacker.go @@ -8,7 +8,6 @@ import ( "io/fs" "net/http" - "k8s.io/client-go/kubernetes" "sigs.k8s.io/controller-runtime/pkg/manager" rukpakv1alpha2 "github.com/operator-framework/rukpak/api/v1alpha2" @@ -30,6 +29,7 @@ import ( // file tree and delegate bundle format concerns to bundle parsers. type Unpacker interface { Unpack(context.Context, *rukpakv1alpha2.BundleDeployment) (*Result, error) + Cleanup(context.Context, *rukpakv1alpha2.BundleDeployment) error } // Result conveys progress information about unpacking bundle content. @@ -90,17 +90,20 @@ func (s *unpacker) Unpack(ctx context.Context, bundle *rukpakv1alpha2.BundleDepl return source.Unpack(ctx, bundle) } +func (s *unpacker) Cleanup(ctx context.Context, bundle *rukpakv1alpha2.BundleDeployment) error { + source, ok := s.sources[bundle.Spec.Source.Type] + if !ok { + return fmt.Errorf("source type %q not supported", bundle.Spec.Source.Type) + } + return source.Cleanup(ctx, bundle) +} + // NewDefaultUnpacker returns a new composite Source that unpacks bundles using // a default source mapping with built-in implementations of all of the supported // source types. // // TODO: refactor NewDefaultUnpacker due to growing parameter list -func NewDefaultUnpacker(mgr manager.Manager, namespace, unpackImage string, rootCAs *x509.CertPool) (Unpacker, error) { - cfg := mgr.GetConfig() - kubeClient, err := kubernetes.NewForConfig(cfg) - if err != nil { - return nil, err - } +func NewDefaultUnpacker(mgr manager.Manager, namespace, cacheDir string, rootCAs *x509.CertPool) (Unpacker, error) { httpTransport := http.DefaultTransport.(*http.Transport).Clone() if httpTransport.TLSClientConfig == nil { httpTransport.TLSClientConfig = &tls.Config{ @@ -109,11 +112,9 @@ func NewDefaultUnpacker(mgr manager.Manager, namespace, unpackImage string, root } httpTransport.TLSClientConfig.RootCAs = rootCAs return NewUnpacker(map[rukpakv1alpha2.SourceType]Unpacker{ - rukpakv1alpha2.SourceTypeImage: &Image{ - Client: mgr.GetClient(), - KubeClient: kubeClient, - PodNamespace: namespace, - UnpackImage: unpackImage, + rukpakv1alpha2.SourceTypeImage: &ImageRegistry{ + BaseCachePath: cacheDir, + AuthNamespace: namespace, }, rukpakv1alpha2.SourceTypeGit: &Git{ Reader: mgr.GetClient(), diff --git a/test/e2e/image_repo.go b/test/e2e/image_repo.go index 8784f8e0..c559e87a 100644 --- a/test/e2e/image_repo.go +++ b/test/e2e/image_repo.go @@ -2,4 +2,4 @@ package e2e // ImageRepo is meant to be set via -ldflags during execution of this code // where it will then be used to configure the testing suite. -var ImageRepo = "localhost/testdata/bundles" +var ImageRepo = "docker-registry.rukpak-e2e.svc.cluster.local:5000/bundles" diff --git a/test/e2e/plain_provisioner_test.go b/test/e2e/plain_provisioner_test.go index b39472f4..d9daec9d 100644 --- a/test/e2e/plain_provisioner_test.go +++ b/test/e2e/plain_provisioner_test.go @@ -66,7 +66,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:valid"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:valid"), + InsecureSkipTLSVerify: true, }, }, }, @@ -107,7 +108,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:valid"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:valid"), + InsecureSkipTLSVerify: true, }, }, }, @@ -122,7 +124,6 @@ var _ = Describe("plain provisioner bundle", func() { }) It("should eventually report a successful state", func() { - By("eventually writing a non-empty image digest to the status", func() { Eventually(func() (*rukpakv1alpha2.BundleSource, error) { if err := c.Get(ctx, client.ObjectKeyFromObject(bundleDeployment), bundleDeployment); err != nil { @@ -139,42 +140,6 @@ var _ = Describe("plain provisioner bundle", func() { )) }) }) - - It("should re-create underlying system resources", func() { - var ( - pod *corev1.Pod - ) - - By("getting the underlying bundle unpacking pod") - selector := util.NewBundleDeploymentLabelSelector(bundleDeployment) - Eventually(func() bool { - pods := &corev1.PodList{} - if err := c.List(ctx, pods, &client.ListOptions{ - Namespace: defaultSystemNamespace, - LabelSelector: selector, - }); err != nil { - return false - } - if len(pods.Items) != 1 { - return false - } - pod = &pods.Items[0] - return true - }).Should(BeTrue()) - - By("storing the pod's original UID") - originalUID := pod.GetUID() - - By("deleting the underlying pod and waiting for it to be re-created") - err := c.Delete(context.Background(), pod) - Expect(err).ToNot(HaveOccurred()) - - By("verifying the pod's UID has changed") - Eventually(func() (types.UID, error) { - err := c.Get(ctx, client.ObjectKeyFromObject(pod), pod) - return pod.GetUID(), err - }).ShouldNot(Equal(originalUID)) - }) }) When("a valid Bundle Deployment referencing a remote private container image is created", func() { @@ -196,8 +161,9 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: "docker-registry.rukpak-e2e.svc.cluster.local:5000/bundles/plain-v0:valid", - ImagePullSecretName: "registrysecret", + Ref: "docker-registry-secure.rukpak-e2e.svc.cluster.local:5000/bundles/plain-v0:valid", + ImagePullSecretName: "secureregistrysecret", + InsecureSkipTLSVerify: true, }, }, }, @@ -264,7 +230,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:non-existent-tag"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:non-existent-tag"), + InsecureSkipTLSVerify: true, }, }, }, @@ -279,26 +246,6 @@ var _ = Describe("plain provisioner bundle", func() { }) It("checks the bundle's phase is stuck in pending", func() { - By("waiting until the pod is reporting ImagePullBackOff state") - Eventually(func() bool { - pod := &corev1.Pod{} - if err := c.Get(ctx, types.NamespacedName{ - Name: bundleDeployment.GetName(), - Namespace: defaultSystemNamespace, - }, pod); err != nil { - return false - } - if pod.Status.Phase != corev1.PodPending { - return false - } - for _, status := range pod.Status.ContainerStatuses { - if status.State.Waiting != nil && status.State.Waiting.Reason == "ImagePullBackOff" { - return true - } - } - return false - }).Should(BeTrue()) - By("waiting for the bundle to report back that state") Eventually(func() bool { err := c.Get(ctx, client.ObjectKeyFromObject(bundleDeployment), bundleDeployment) @@ -309,7 +256,7 @@ var _ = Describe("plain provisioner bundle", func() { if unpackPending == nil { return false } - if unpackPending.Message != fmt.Sprintf(`Back-off pulling image "%s"`, bundleDeployment.Spec.Source.Image.Ref) { + if !strings.Contains(unpackPending.Message, "source bundle content: error fetching image descriptor") { return false } return true @@ -336,7 +283,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:empty"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:empty"), + InsecureSkipTLSVerify: true, }, }, }, @@ -386,7 +334,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:no-manifests"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:no-manifests"), + InsecureSkipTLSVerify: true, }, }, }, @@ -418,18 +367,14 @@ var _ = Describe("plain provisioner bundle", func() { }) When("Bundles are backed by a git repository", func() { - var ( - ctx context.Context - ) + var ctx context.Context BeforeEach(func() { ctx = context.Background() }) When("the bundle is backed by a git commit", func() { - var ( - bundleDeployment *rukpakv1alpha2.BundleDeployment - ) + var bundleDeployment *rukpakv1alpha2.BundleDeployment BeforeEach(func() { bundleDeployment = &rukpakv1alpha2.BundleDeployment{ ObjectMeta: metav1.ObjectMeta{ @@ -477,9 +422,7 @@ var _ = Describe("plain provisioner bundle", func() { }) }) When("the bundle deployment is backed by a git tag", func() { - var ( - bundleDeployment *rukpakv1alpha2.BundleDeployment - ) + var bundleDeployment *rukpakv1alpha2.BundleDeployment BeforeEach(func() { bundleDeployment = &rukpakv1alpha2.BundleDeployment{ ObjectMeta: metav1.ObjectMeta{ @@ -546,9 +489,7 @@ var _ = Describe("plain provisioner bundle", func() { }) When("the bundle deployment is backed by a git branch", func() { - var ( - bundleDeployment *rukpakv1alpha2.BundleDeployment - ) + var bundleDeployment *rukpakv1alpha2.BundleDeployment BeforeEach(func() { bundleDeployment = &rukpakv1alpha2.BundleDeployment{ ObjectMeta: metav1.ObjectMeta{ @@ -615,9 +556,7 @@ var _ = Describe("plain provisioner bundle", func() { }) When("the bundle deployment has a custom manifests directory", func() { - var ( - bundleDeployment *rukpakv1alpha2.BundleDeployment - ) + var bundleDeployment *rukpakv1alpha2.BundleDeployment BeforeEach(func() { bundleDeployment = &rukpakv1alpha2.BundleDeployment{ ObjectMeta: metav1.ObjectMeta{ @@ -1025,7 +964,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:subdir"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:subdir"), + InsecureSkipTLSVerify: true, }, }, }, @@ -1219,7 +1159,7 @@ var _ = Describe("plain provisioner bundle", func() { }) }) - var _ = Describe("plain provisioner bundleDeployment", func() { + _ = Describe("plain provisioner bundleDeployment", func() { When("a BundleDeployment is dependent on another BundleDeployment", func() { var ( ctx context.Context @@ -1238,7 +1178,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:dependent"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:dependent"), + InsecureSkipTLSVerify: true, }, }, }, @@ -1249,7 +1190,6 @@ var _ = Describe("plain provisioner bundle", func() { AfterEach(func() { By("deleting the testing dependent BundleDeployment resource") Expect(client.IgnoreNotFound(c.Delete(ctx, dependentBD))).To(Succeed()) - }) When("the providing BundleDeployment does not exist", func() { It("should eventually project a failed installation for the dependent BundleDeployment", func() { @@ -1269,9 +1209,7 @@ var _ = Describe("plain provisioner bundle", func() { }) }) When("the providing BundleDeployment is created", func() { - var ( - providesBD *rukpakv1alpha2.BundleDeployment - ) + var providesBD *rukpakv1alpha2.BundleDeployment BeforeEach(func() { ctx = context.Background() @@ -1286,7 +1224,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:provides"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:provides"), + InsecureSkipTLSVerify: true, }, }, }, @@ -1297,7 +1236,6 @@ var _ = Describe("plain provisioner bundle", func() { AfterEach(func() { By("deleting the testing providing BundleDeployment resource") Expect(client.IgnoreNotFound(c.Delete(ctx, providesBD))).To(Succeed()) - }) It("should eventually project a successful installation for the dependent BundleDeployment", func() { Eventually(func() (*metav1.Condition, error) { @@ -1335,7 +1273,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:invalid-crds-and-crs"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:invalid-crds-and-crs"), + InsecureSkipTLSVerify: true, }, }, }, @@ -1366,8 +1305,7 @@ var _ = Describe("plain provisioner bundle", func() { }) }) - var _ = Describe("plain provisioner garbage collection", func() { - + _ = Describe("plain provisioner garbage collection", func() { When("a BundleDeployment has been deleted", func() { var ( ctx context.Context @@ -1390,7 +1328,8 @@ var _ = Describe("plain provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:valid"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "plain-v0:valid"), + InsecureSkipTLSVerify: true, }, }, }, diff --git a/test/e2e/registry_provisioner_test.go b/test/e2e/registry_provisioner_test.go index e45eb3a9..73c425d1 100644 --- a/test/e2e/registry_provisioner_test.go +++ b/test/e2e/registry_provisioner_test.go @@ -37,7 +37,8 @@ var _ = Describe("registry provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "registry:valid"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "registry:valid"), + InsecureSkipTLSVerify: true, }, }, }, @@ -87,7 +88,8 @@ var _ = Describe("registry provisioner bundle", func() { Source: rukpakv1alpha2.BundleSource{ Type: rukpakv1alpha2.SourceTypeImage, Image: &rukpakv1alpha2.ImageSource{ - Ref: fmt.Sprintf("%v/%v", ImageRepo, "registry:invalid"), + Ref: fmt.Sprintf("%v/%v", ImageRepo, "registry:invalid"), + InsecureSkipTLSVerify: true, }, }, }, diff --git a/test/tools/imageregistry/bundle_local_image.yaml b/test/tools/imageregistry/bundle_local_image.yaml deleted file mode 100644 index 1812a506..00000000 --- a/test/tools/imageregistry/bundle_local_image.yaml +++ /dev/null @@ -1,11 +0,0 @@ -apiVersion: core.rukpak.io/v1alpha1 -kind: Bundle -metadata: - name: combo-v0.0.1 -spec: - source: - type: image - image: - ref: docker-registry.rukpak-e2e.svc.cluster.local:5000/bundles/plain-v0:valid - pullSecret: registrysecret - provisionerClassName: core-rukpak-io-plain diff --git a/test/tools/imageregistry/daemonset.yaml b/test/tools/imageregistry/daemonset.yaml deleted file mode 100644 index c2651152..00000000 --- a/test/tools/imageregistry/daemonset.yaml +++ /dev/null @@ -1,48 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: setup-script -data: - setup.sh: | - echo "$TRUSTED_CERT" > /usr/local/share/ca-certificates/ca.crt && update-ca-certificates && systemctl restart containerd ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: node-custom-setup - labels: - k8s-app: node-custom-setup -spec: - selector: - matchLabels: - k8s-app: node-custom-setup - template: - metadata: - labels: - k8s-app: node-custom-setup - spec: - hostPID: true - hostNetwork: true - initContainers: - - name: init-node - command: ["nsenter"] - args: ["--mount=/proc/1/ns/mnt", "--", "sh", "-c", "$(SETUP_SCRIPT)"] - image: debian - env: - - name: TRUSTED_CERT - valueFrom: - configMapKeyRef: - name: trusted-ca - key: ca.crt - - name: SETUP_SCRIPT - valueFrom: - configMapKeyRef: - name: setup-script - key: setup.sh - securityContext: - privileged: true - terminationMessagePolicy: FallbackToLogsOnError - containers: - - name: wait - image: registry.k8s.io/pause:3.1 - terminationMessagePolicy: FallbackToLogsOnError diff --git a/test/tools/imageregistry/image-registry-secure.sh b/test/tools/imageregistry/image-registry-secure.sh new file mode 100755 index 00000000..916ccb44 --- /dev/null +++ b/test/tools/imageregistry/image-registry-secure.sh @@ -0,0 +1,128 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +image-registry-secure.sh is a script to stand up an image registry within a cluster with authentication. +Usage: + image-registry-secure.sh [NAMESPACE] [NAME] + +Argument Descriptions: + - NAMESPACE is the namespace that should be created and is the namespace in which the image registry will be created + - NAME is the name that should be used for the image registry Deployment and Service +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +name=$2 + +kubectl apply -f - << EOF +apiVersion: v1 +kind: Namespace +metadata: + name: ${namespace} +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: ${namespace} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: ${namespace}-registry-secure + namespace: ${namespace} +spec: + secretName: ${namespace}-registry-secure + isCA: true + dnsNames: + - ${name}-secure.${namespace}.svc + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-issuer + kind: Issuer + group: cert-manager.io +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ${name}-secure + namespace: ${namespace} + labels: + app: registry-secure +spec: + replicas: 1 + selector: + matchLabels: + app: registry-secure + template: + metadata: + labels: + app: registry-secure + spec: + initContainers: + - name: auth + image: registry:2.6.2 + command: + - "sh" + - "-c" + - "htpasswd -Bbn myuser mypasswd >> /auth/htpasswd" + terminationMessagePolicy: FallbackToLogsOnError + volumeMounts: + - name: auth-vol + mountPath: "/auth" + containers: + - name: registry + image: registry:2 + volumeMounts: + - name: certs-vol + mountPath: "/certs" + - name: auth-vol + mountPath: "/auth" + readOnly: true + env: + - name: REGISTRY_HTTP_TLS_CERTIFICATE + value: "/certs/tls.crt" + - name: REGISTRY_HTTP_TLS_KEY + value: "/certs/tls.key" + - name: REGISTRY_AUTH + value: "htpasswd" + - name: REGISTRY_AUTH_HTPASSWD_REALM + value: "Registry Realm" + - name: REGISTRY_AUTH_HTPASSWD_PATH + value: "/auth/htpasswd" + volumes: + - name: certs-vol + secret: + secretName: ${namespace}-registry-secure + - name: auth-vol + emptyDir: {} +--- +apiVersion: v1 +kind: Service +metadata: + name: ${name}-secure + namespace: ${namespace} +spec: + selector: + app: registry-secure + ports: + - port: 5000 + targetPort: 5000 +EOF + +kubectl create secret docker-registry "secureregistrysecret" --docker-server=${name}-secure.${namespace}.svc.cluster.local:5000 --docker-username="myuser" --docker-password="mypasswd" --docker-email="email@foo.com" -n rukpak-system +kubectl create secret docker-registry "secureregistrysecret" --docker-server=${name}-secure.${namespace}.svc.cluster.local:5000 --docker-username="myuser" --docker-password="mypasswd" --docker-email="email@foo.com" -n rukpak-e2e +kubectl wait --for=condition=Available -n "${namespace}" "deploy/${name}-secure" --timeout=60s diff --git a/test/tools/imageregistry/image-registry.sh b/test/tools/imageregistry/image-registry.sh new file mode 100755 index 00000000..b3d2d6af --- /dev/null +++ b/test/tools/imageregistry/image-registry.sh @@ -0,0 +1,104 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +image-registry.sh is a script to stand up an image registry within a cluster. +Usage: + image-registry.sh [NAMESPACE] [NAME] + +Argument Descriptions: + - NAMESPACE is the namespace that should be created and is the namespace in which the image registry will be created + - NAME is the name that should be used for the image registry Deployment and Service +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +name=$2 + +kubectl apply -f - << EOF +apiVersion: v1 +kind: Namespace +metadata: + name: ${namespace} +--- +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer + namespace: ${namespace} +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: ${namespace}-registry + namespace: ${namespace} +spec: + secretName: ${namespace}-registry + isCA: true + dnsNames: + - ${name}.${namespace}.svc + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned-issuer + kind: Issuer + group: cert-manager.io +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: ${name} + namespace: ${namespace} + labels: + app: registry +spec: + replicas: 1 + selector: + matchLabels: + app: registry + template: + metadata: + labels: + app: registry + spec: + containers: + - name: registry + image: registry:2 + volumeMounts: + - name: certs-vol + mountPath: "/certs" + env: + - name: REGISTRY_HTTP_TLS_CERTIFICATE + value: "/certs/tls.crt" + - name: REGISTRY_HTTP_TLS_KEY + value: "/certs/tls.key" + volumes: + - name: certs-vol + secret: + secretName: ${namespace}-registry +--- +apiVersion: v1 +kind: Service +metadata: + name: ${name} + namespace: ${namespace} +spec: + selector: + app: registry + ports: + - port: 5000 + targetPort: 5000 +EOF + +kubectl wait --for=condition=Available -n "${namespace}" "deploy/${name}" --timeout=60s diff --git a/test/tools/imageregistry/load_test_image.sh b/test/tools/imageregistry/load_test_image.sh deleted file mode 100755 index 3347e6ad..00000000 --- a/test/tools/imageregistry/load_test_image.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -export REGISTRY_NAME="docker-registry" -export REGISTRY_NAMESPACE=rukpak-e2e -export DNS_NAME=$REGISTRY_NAME.$REGISTRY_NAMESPACE.svc.cluster.local -KIND=$1 -KIND_CLUSTER_NAME=$2 - -# push test bundle image into in-cluster docker registry -kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl login -u myuser -p mypasswd $DNS_NAME:5000 --insecure-registry" - -for x in $(docker images --format "{{.Repository}}:{{.Tag}}" | grep $DNS_NAME); do -echo $x - $KIND load docker-image $x --name $KIND_CLUSTER_NAME - kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl -n k8s.io push $x --insecure-registry" - kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl -n k8s.io rmi $x --insecure-registry" -done - diff --git a/test/tools/imageregistry/nerdctl.yaml b/test/tools/imageregistry/nerdctl.yaml deleted file mode 100644 index ad07058e..00000000 --- a/test/tools/imageregistry/nerdctl.yaml +++ /dev/null @@ -1,25 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: nerdctl -spec: - containers: - - command: - - sleep - - infinity - image: ghcr.io/containerd/nerdctl - imagePullPolicy: Always - name: nerdctl - terminationMessagePolicy: FallbackToLogsOnError - volumeMounts: - - mountPath: /run/containerd - name: run-containerd - - mountPath: /var/lib/containerd - name: var-lib-containerd - volumes: - - name: run-containerd - hostPath: - path: /run/containerd - - name: var-lib-containerd - hostPath: - path: /var/lib/containerd diff --git a/test/tools/imageregistry/registry.yaml b/test/tools/imageregistry/registry.yaml deleted file mode 100644 index 24c718de..00000000 --- a/test/tools/imageregistry/registry.yaml +++ /dev/null @@ -1,51 +0,0 @@ -apiVersion: v1 -kind: Pod -metadata: - name: docker-registry-pod - labels: - app: registry -spec: - initContainers: - - name: auth - image: registry:2.6.2 - command: - - "sh" - - "-c" - - "htpasswd -Bbn myuser mypasswd >> /auth/htpasswd" - terminationMessagePolicy: FallbackToLogsOnError - volumeMounts: - - name: auth-vol - mountPath: "/auth" - containers: - - name: registry - image: registry:2.6.2 - volumeMounts: - - name: repo-vol - mountPath: "/var/lib/registry" - - name: certs-vol - mountPath: "/certs" - readOnly: true - - name: auth-vol - mountPath: "/auth" - readOnly: true - env: - - name: REGISTRY_AUTH - value: "htpasswd" - - name: REGISTRY_AUTH_HTPASSWD_REALM - value: "Registry Realm" - - name: REGISTRY_AUTH_HTPASSWD_PATH - value: "/auth/htpasswd" - - name: REGISTRY_HTTP_TLS_CERTIFICATE - value: "/certs/tls.crt" - - name: REGISTRY_HTTP_TLS_KEY - value: "/certs/tls.key" - terminationMessagePolicy: FallbackToLogsOnError - volumes: - - name: repo-vol - emptyDir: {} - - name: certs-vol - secret: - secretName: certs-secret - - name: auth-vol - emptyDir: {} - diff --git a/test/tools/imageregistry/service.yaml b/test/tools/imageregistry/service.yaml deleted file mode 100644 index e99b2603..00000000 --- a/test/tools/imageregistry/service.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: docker-registry -spec: - selector: - app: registry - ports: - - port: 5000 - targetPort: 5000 diff --git a/test/tools/imageregistry/setup_imageregistry.sh b/test/tools/imageregistry/setup_imageregistry.sh deleted file mode 100755 index 0905e440..00000000 --- a/test/tools/imageregistry/setup_imageregistry.sh +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env bash - -export REGISTRY_NAME="docker-registry" -export REGISTRY_NAMESPACE=rukpak-e2e -export DNS_NAME=$REGISTRY_NAME.$REGISTRY_NAMESPACE.svc.cluster.local -export KIND_CLUSTER_NAME=$1 - -kubectl create ns $REGISTRY_NAMESPACE || true - -# create self-signed certificate for registry server -mkdir -p /tmp/var/imageregistry/certs -openssl req -x509 -newkey rsa:4096 -days 365 -nodes -sha256 -keyout /tmp/var/imageregistry/certs/tls.key -out /tmp/var/imageregistry/certs/tls.crt -subj "/CN=$DNS_NAME" -addext "subjectAltName = DNS:$DNS_NAME" -kubectl create secret tls certs-secret --cert=/tmp/var/imageregistry/certs/tls.crt --key=/tmp/var/imageregistry/certs/tls.key -n $REGISTRY_NAMESPACE -kubectl create configmap trusted-ca -n $REGISTRY_NAMESPACE --from-file=ca.crt=/tmp/var/imageregistry/certs/tls.crt - -# create image registry service -kubectl apply -f test/tools/imageregistry/service.yaml -n $REGISTRY_NAMESPACE - -# set local variables -export REGISTRY_IP=$(kubectl get service $REGISTRY_NAME -n $REGISTRY_NAMESPACE -o jsonpath='{ .spec.clusterIP }') -export REGISTRY_PORT=5000 - -# Add ca certificate to Node -kubectl apply -f test/tools/imageregistry/daemonset.yaml -n $REGISTRY_NAMESPACE - -# Add an entry in /etc/hosts of Node -docker exec $(docker ps | grep $KIND_CLUSTER_NAME'-control-plane' | cut -c 1-12) sh -c "/usr/bin/echo $REGISTRY_IP $DNS_NAME >>/etc/hosts" - -sleep 5 -# create image registry pod -kubectl apply -f test/tools/imageregistry/registry.yaml -n $REGISTRY_NAMESPACE - -# create image upload pod -kubectl apply -f test/tools/imageregistry/nerdctl.yaml -n $REGISTRY_NAMESPACE - -# create imagePull secret for provisioner -export IMAGE_PULL_RECRET="registrysecret" -kubectl create ns rukpak-system || true -kubectl create secret docker-registry $IMAGE_PULL_RECRET --docker-server=$DNS_NAME:5000 --docker-username="myuser" --docker-password="mypasswd" --docker-email="email@foo.com" -n rukpak-system - -echo #### Valiables #### -echo -echo REGISTRY_NAME $REGISTRY_NAME -echo REGISTRY_IP $REGISTRY_IP -echo REGISTRY_PORT $REGISTRY_PORT -echo IMAGE_PULL_RECRET $IMAGE_PULL_RECRET - -# clean up -rm -rf /tmp/var/imageregistry/certs -kubectl wait --for=condition=ContainersReady --namespace=rukpak-e2e pod/docker-registry-pod --timeout=60s -kubectl wait --for=condition=ContainersReady --namespace=rukpak-e2e pod/nerdctl --timeout=60s - diff --git a/test/tools/imageregistry/sniff.sh b/test/tools/imageregistry/sniff.sh deleted file mode 100755 index 3dabbefd..00000000 --- a/test/tools/imageregistry/sniff.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env bash - -export REGISTRY_NAME="docker-registry" -export REGISTRY_NAMESPACE=rukpak-e2e -export DNS_NAME=$REGISTRY_NAME.$REGISTRY_NAMESPACE.svc.cluster.local -export KIND_CLUSTER_NAME=$1 - -# push test bundle image into in-cluster docker registry -kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl login -u myuser -p mypasswd $DNS_NAME:5000 --insecure-registry" - -docker build testdata/bundles/plain-v0/valid -t localhost/testdata/bundles/plain-v0:valid -kind load docker-image localhost/testdata/bundles/plain-v0:valid --name $KIND_CLUSTER_NAME -kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl -n k8s.io tag localhost/testdata/bundles/plain-v0:valid $DNS_NAME:5000/bundles/plain-v0:valid" -kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl -n k8s.io push $DNS_NAME:5000/bundles/plain-v0:valid --insecure-registry" -kubectl exec nerdctl -n $REGISTRY_NAMESPACE -- sh -c "nerdctl -n k8s.io rmi $DNS_NAME:5000/bundles/plain-v0:valid --insecure-registry" - -# create bundle -kubectl apply -f tools/imageregistry/bundle_local_image.yaml diff --git a/testdata/bundles/plain-v0/dependent/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/dependent/build-push-e2e-bundle.sh new file mode 100755 index 00000000..e43d864b --- /dev/null +++ b/testdata/bundles/plain-v0/dependent/build-push-e2e-bundle.sh @@ -0,0 +1,75 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/dependent" +bundle_name="plain-dependent" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/empty/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/empty/build-push-e2e-bundle.sh new file mode 100755 index 00000000..8c55d740 --- /dev/null +++ b/testdata/bundles/plain-v0/empty/build-push-e2e-bundle.sh @@ -0,0 +1,58 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/empty" +bundle_name="plain-empty" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/invalid-crds-and-crs/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/invalid-crds-and-crs/build-push-e2e-bundle.sh new file mode 100755 index 00000000..59d8a791 --- /dev/null +++ b/testdata/bundles/plain-v0/invalid-crds-and-crs/build-push-e2e-bundle.sh @@ -0,0 +1,75 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/invalid-crds-and-crs" +bundle_name="plain-invalid-crds-and-crs" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/invalid-missing-crds/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/invalid-missing-crds/build-push-e2e-bundle.sh new file mode 100755 index 00000000..927240b1 --- /dev/null +++ b/testdata/bundles/plain-v0/invalid-missing-crds/build-push-e2e-bundle.sh @@ -0,0 +1,75 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/invalid-missing-crds" +bundle_name="plain-invalid-missing-crds" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/no-manifests/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/no-manifests/build-push-e2e-bundle.sh new file mode 100755 index 00000000..6afe823d --- /dev/null +++ b/testdata/bundles/plain-v0/no-manifests/build-push-e2e-bundle.sh @@ -0,0 +1,61 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/no-manifests" +bundle_name="plain-no-manifests" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} +EOF +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/provides/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/provides/build-push-e2e-bundle.sh new file mode 100755 index 00000000..0256a10c --- /dev/null +++ b/testdata/bundles/plain-v0/provides/build-push-e2e-bundle.sh @@ -0,0 +1,75 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/provides" +bundle_name="plain-provides" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/subdir/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/subdir/build-push-e2e-bundle.sh new file mode 100755 index 00000000..ee054152 --- /dev/null +++ b/testdata/bundles/plain-v0/subdir/build-push-e2e-bundle.sh @@ -0,0 +1,87 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/subdir" +bundle_name="plain-subdir" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests/emptydir" rukpak-e2e-${bundle_name}.manifests.emptydir +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests/subdir" rukpak-e2e-${bundle_name}.manifests.subdir + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp -r /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + - name: emptydir-data + mountPath: /manifests-data/emptydir + - name: subdir-data + mountPath: /manifests-data/subdir + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests + - name: emptydir-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests.emptydir + - name: subdir-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests.subdir +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/plain-v0/valid/build-push-e2e-bundle-secure.sh b/testdata/bundles/plain-v0/valid/build-push-e2e-bundle-secure.sh new file mode 100755 index 00000000..6f20c952 --- /dev/null +++ b/testdata/bundles/plain-v0/valid/build-push-e2e-bundle-secure.sh @@ -0,0 +1,86 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/valid" +bundle_name="plain-valid" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}-secure.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}-secure.manifests + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}-secure" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + - name: secure-registry-auth + mountPath: /workspace/.docker + env: + - name: DOCKER_CONFIG + value: /workspace/.docker + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}-secure.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}-secure.manifests + - name: secure-registry-auth + secret: + secretName: secureregistrysecret + items: + - key: .dockerconfigjson + path: config.json +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name}-secure --timeout=60s diff --git a/testdata/bundles/plain-v0/valid/build-push-e2e-bundle.sh b/testdata/bundles/plain-v0/valid/build-push-e2e-bundle.sh new file mode 100755 index 00000000..cd553293 --- /dev/null +++ b/testdata/bundles/plain-v0/valid/build-push-e2e-bundle.sh @@ -0,0 +1,75 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/plain-v0/valid" +bundle_name="plain-valid" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/registry/invalid/build-push-e2e-bundle.sh b/testdata/bundles/registry/invalid/build-push-e2e-bundle.sh new file mode 100755 index 00000000..0fa6542c --- /dev/null +++ b/testdata/bundles/registry/invalid/build-push-e2e-bundle.sh @@ -0,0 +1,91 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/registry/invalid" +bundle_name="registry-invalid" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/metadata" rukpak-e2e-${bundle_name}.metadata + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + - name: copy-metadata + image: busybox + command: ['sh', '-c', 'cp /metadata-data/* /metadata'] + volumeMounts: + - name: metadata + mountPath: /metadata + - name: metadata-data + mountPath: /metadata-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + - name: metadata + mountPath: /workspace/metadata/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: metadata + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests + - name: metadata-data + configMap: + name: rukpak-e2e-${bundle_name}.metadata +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s diff --git a/testdata/bundles/registry/valid/build-push-e2e-bundle.sh b/testdata/bundles/registry/valid/build-push-e2e-bundle.sh new file mode 100755 index 00000000..cce6c77f --- /dev/null +++ b/testdata/bundles/registry/valid/build-push-e2e-bundle.sh @@ -0,0 +1,91 @@ +#! /bin/bash + +set -o errexit +set -o nounset +set -o pipefail + +help=" +build-push-e2e-bundle.sh is a script to build and push the e2e bundle image using kaniko. +Usage: + build-push-e2e-bundle.sh [NAMESPACE] [TAG] [BUNDLE_DIR] [BUNDLE_NAME] + +Argument Descriptions: + - NAMESPACE is the namespace the kaniko Job should be created in + - TAG is the full tag used to build and push the catalog image +" + +if [[ "$#" -ne 2 ]]; then + echo "Illegal number of arguments passed" + echo "${help}" + exit 1 +fi + +namespace=$1 +tag=$2 +bundle_dir="testdata/bundles/registry/valid" +bundle_name="registry-valid" + +echo "${namespace}" "${tag}" + +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/" rukpak-e2e-${bundle_name}.root +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/manifests" rukpak-e2e-${bundle_name}.manifests +kubectl create configmap -n "${namespace}" --from-file="${bundle_dir}/metadata" rukpak-e2e-${bundle_name}.metadata + +kubectl apply -f - << EOF +apiVersion: batch/v1 +kind: Job +metadata: + name: "kaniko-${bundle_name}" + namespace: "${namespace}" +spec: + template: + spec: + initContainers: + - name: copy-manifests + image: busybox + command: ['sh', '-c', 'cp /manifests-data/* /manifests'] + volumeMounts: + - name: manifests + mountPath: /manifests + - name: manifests-data + mountPath: /manifests-data + - name: copy-metadata + image: busybox + command: ['sh', '-c', 'cp /metadata-data/* /metadata'] + volumeMounts: + - name: metadata + mountPath: /metadata + - name: metadata-data + mountPath: /metadata-data + containers: + - name: kaniko + image: gcr.io/kaniko-project/executor:latest + args: ["--dockerfile=/workspace/Dockerfile", + "--context=/workspace/", + "--destination=${tag}", + "--skip-tls-verify"] + volumeMounts: + - name: dockerfile + mountPath: /workspace/ + - name: manifests + mountPath: /workspace/manifests/ + - name: metadata + mountPath: /workspace/metadata/ + restartPolicy: Never + volumes: + - name: dockerfile + configMap: + name: rukpak-e2e-${bundle_name}.root + - name: manifests + emptyDir: {} + - name: metadata + emptyDir: {} + - name: manifests-data + configMap: + name: rukpak-e2e-${bundle_name}.manifests + - name: metadata-data + configMap: + name: rukpak-e2e-${bundle_name}.metadata +EOF + +kubectl wait --for=condition=Complete -n "${namespace}" jobs/kaniko-${bundle_name} --timeout=60s