From f29e088db0b3aa6accb5d1b43ab94bf5b724e5f8 Mon Sep 17 00:00:00 2001 From: Gaelle Fournier Date: Wed, 3 Jan 2024 10:16:04 +0100 Subject: [PATCH] fix(#5007): Jib publish strategy registry secret --- pkg/builder/jib.go | 29 ++++++++++++++++----- pkg/builder/spectrum.go | 39 ++-------------------------- pkg/util/jib/configuration.go | 3 +++ pkg/util/registry/registry.go | 40 +++++++++++++++++++++++++++++ pkg/util/registry/registry_test.go | 41 ++++++++++++++++++++++++++++++ 5 files changed, 108 insertions(+), 44 deletions(-) diff --git a/pkg/builder/jib.go b/pkg/builder/jib.go index 75a8c26f87..5e30637dec 100644 --- a/pkg/builder/jib.go +++ b/pkg/builder/jib.go @@ -30,6 +30,7 @@ import ( "github.com/apache/camel-k/v2/pkg/util/jib" "github.com/apache/camel-k/v2/pkg/util/log" "github.com/apache/camel-k/v2/pkg/util/maven" + "github.com/apache/camel-k/v2/pkg/util/registry" ) type jibTask struct { @@ -84,18 +85,13 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { registryConfigDir := "" if t.task.Registry.Secret != "" { - registryConfigDir, err = MountSecret(ctx, t.c, t.build.Namespace, t.task.Registry.Secret) + registryConfigDir, err = registry.MountSecretRegistryConfig(ctx, t.c, t.build.Namespace, "jib-secret-", t.task.Registry.Secret) + os.Setenv(jib.JibRegistryConfigEnvVar, registryConfigDir) if err != nil { return status.Failed(err) } } - if registryConfigDir != "" { - if err := os.RemoveAll(registryConfigDir); err != nil { - return status.Failed(err) - } - } - // TODO refactor maven code to avoid creating a file to pass command args mavenCommand, err := util.ReadFile(filepath.Join(mavenDir, "MAVEN_CONTEXT")) if err != nil { @@ -120,8 +116,10 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { cmd.Dir = mavenDir myerror := util.RunAndLog(ctx, cmd, maven.MavenLogHandler, maven.MavenLogHandler) + if myerror != nil { log.Errorf(myerror, "jib integration image containerization did not run successfully") + _ = cleanRegistryConfig(registryConfigDir) return status.Failed(myerror) } else { log.Debug("jib integration image containerization did run successfully") @@ -130,10 +128,27 @@ func (t *jibTask) Do(ctx context.Context) v1.BuildStatus { // retrieve image digest mavenDigest, errDigest := util.ReadFile(filepath.Join(mavenDir, jib.JibDigestFile)) if errDigest != nil { + _ = cleanRegistryConfig(registryConfigDir) return status.Failed(errDigest) } status.Digest = string(mavenDigest) } + if registryConfigDir != "" { + if err := cleanRegistryConfig(registryConfigDir); err != nil { + return status.Failed(err) + } + } + return status } + +func cleanRegistryConfig(registryConfigDir string) error { + if err := os.Unsetenv(jib.JibRegistryConfigEnvVar); err != nil { + return err + } + if err := os.RemoveAll(registryConfigDir); err != nil { + return err + } + return nil +} diff --git a/pkg/builder/spectrum.go b/pkg/builder/spectrum.go index 2bc3b2673c..2287a557b0 100644 --- a/pkg/builder/spectrum.go +++ b/pkg/builder/spectrum.go @@ -26,16 +26,13 @@ import ( "runtime" "strings" - "go.uber.org/multierr" - spectrum "github.com/container-tools/spectrum/pkg/builder" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "github.com/apache/camel-k/v2/pkg/apis/camel/v1" "github.com/apache/camel-k/v2/pkg/client" "github.com/apache/camel-k/v2/pkg/util" "github.com/apache/camel-k/v2/pkg/util/log" + "github.com/apache/camel-k/v2/pkg/util/registry" ) type spectrumTask struct { @@ -100,7 +97,7 @@ func (t *spectrumTask) Do(ctx context.Context) v1.BuildStatus { registryConfigDir := "" if t.task.Registry.Secret != "" { - registryConfigDir, err = MountSecret(ctx, t.c, t.build.Namespace, t.task.Registry.Secret) + registryConfigDir, err = registry.MountSecretRegistryConfig(ctx, t.c, t.build.Namespace, "spectrum-secret-", t.task.Registry.Secret) if err != nil { return status.Failed(err) } @@ -158,35 +155,3 @@ func readSpectrumLogs(newStdOut io.Reader) { log.Infof(line) } } - -func MountSecret(ctx context.Context, c client.Client, namespace, name string) (string, error) { - dir, err := os.MkdirTemp("", "spectrum-secret-") - if err != nil { - return "", err - } - - secret, err := c.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) - if err != nil { - if removeErr := os.RemoveAll(dir); removeErr != nil { - err = multierr.Append(err, removeErr) - } - return "", err - } - - for file, content := range secret.Data { - if err := os.WriteFile(filepath.Join(dir, remap(file)), content, 0o600); err != nil { - if removeErr := os.RemoveAll(dir); removeErr != nil { - err = multierr.Append(err, removeErr) - } - return "", err - } - } - return dir, nil -} - -func remap(name string) string { - if name == ".dockerconfigjson" { - return "config.json" - } - return name -} diff --git a/pkg/util/jib/configuration.go b/pkg/util/jib/configuration.go index ac54676e4c..1fb9bf2782 100644 --- a/pkg/util/jib/configuration.go +++ b/pkg/util/jib/configuration.go @@ -41,6 +41,9 @@ const JibDigestFile = "target/jib-image.digest" const JibMavenPluginVersionDefault = "3.3.2" const JibLayerFilterExtensionMavenVersionDefault = "0.3.0" +// See: https://github.com/GoogleContainerTools/jib/blob/master/jib-maven-plugin/README.md#using-docker-configuration-files +const JibRegistryConfigEnvVar = "DOCKER_CONFIG" + type JibBuild struct { Plugins []maven.Plugin `xml:"plugins>plugin,omitempty"` } diff --git a/pkg/util/registry/registry.go b/pkg/util/registry/registry.go index 39bda10c63..e2c118e167 100644 --- a/pkg/util/registry/registry.go +++ b/pkg/util/registry/registry.go @@ -18,10 +18,17 @@ limitations under the License. package registry import ( + "context" "encoding/base64" "encoding/json" "errors" "fmt" + "os" + "path/filepath" + + "github.com/apache/camel-k/v2/pkg/client" + "go.uber.org/multierr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) var knownServersByRegistry = map[string]string{ @@ -98,3 +105,36 @@ func (a Auth) getActualServer() string { func (a Auth) encodedCredentials() string { return base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", a.Username, a.Password))) } + +// MountSecretRegistryConfig write a file containing the secret registry config in a temporary folder. +func MountSecretRegistryConfig(ctx context.Context, c client.Client, namespace, prefix, name string) (string, error) { + dir, err := os.MkdirTemp("", prefix) + if err != nil { + return "", err + } + + secret, err := c.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if removeErr := os.RemoveAll(dir); removeErr != nil { + err = multierr.Append(err, removeErr) + } + return "", err + } + + for file, content := range secret.Data { + if err := os.WriteFile(filepath.Join(dir, remap(file)), content, 0o600); err != nil { + if removeErr := os.RemoveAll(dir); removeErr != nil { + err = multierr.Append(err, removeErr) + } + return "", err + } + } + return dir, nil +} + +func remap(name string) string { + if name == ".dockerconfigjson" { + return "config.json" + } + return name +} diff --git a/pkg/util/registry/registry_test.go b/pkg/util/registry/registry_test.go index 166d87cf13..948f2fa207 100644 --- a/pkg/util/registry/registry_test.go +++ b/pkg/util/registry/registry_test.go @@ -18,9 +18,15 @@ limitations under the License. package registry import ( + "context" + "os" "testing" + "github.com/apache/camel-k/v2/pkg/util" + "github.com/apache/camel-k/v2/pkg/util/test" "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) func TestAuth_GenerateDockerConfig(t *testing.T) { @@ -66,3 +72,38 @@ func TestAuth_Validate(t *testing.T) { Server: "quay.io", }.validate()) } + +func TestMountSecretRegistryConfig(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + a := Auth{ + Username: "nic", + Registry: "docker.io", + } + conf, _ := a.GenerateDockerConfig() + namespace := v1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + }, + } + secret := v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "test", + Name: "my-secret1", + }, + Type: v1.SecretTypeDockerConfigJson, + Data: map[string][]byte{ + v1.DockerConfigJsonKey: conf, + }, + } + + c, err := test.NewFakeClient(&namespace, &secret) + assert.Nil(t, err) + assert.NotNil(t, c) + registryConfigDir, err := MountSecretRegistryConfig(ctx, c, "test", "prefix-", "my-secret1") + assert.Nil(t, err) + assert.NotNil(t, registryConfigDir) + dockerfileExists, _ := util.FileExists(registryConfigDir + "/config.json") + assert.True(t, dockerfileExists) + os.RemoveAll(registryConfigDir) +}