diff --git a/cmd/artifactPrepareVersion.go b/cmd/artifactPrepareVersion.go index 4c7f77320d..531bc6579c 100644 --- a/cmd/artifactPrepareVersion.go +++ b/cmd/artifactPrepareVersion.go @@ -235,7 +235,9 @@ func runArtifactPrepareVersion(config *artifactPrepareVersionOptions, telemetryD log.Entry().Infof("New version: '%v'", newVersion) commonPipelineEnvironment.git.commitID = gitCommitID // this commitID changes and is not necessarily the HEAD commitID + commonPipelineEnvironment.container.labels["org.opencontainers.image.revision"] = gitCommitID commonPipelineEnvironment.artifactVersion = newVersion + commonPipelineEnvironment.container.labels["org.opencontainers.image.version"] = newVersion commonPipelineEnvironment.originalArtifactVersion = version gitCommitMessages := strings.Split(gitCommitMessage, "\n") diff --git a/cmd/artifactPrepareVersion_generated.go b/cmd/artifactPrepareVersion_generated.go index 24e29a34d1..3e61df548d 100644 --- a/cmd/artifactPrepareVersion_generated.go +++ b/cmd/artifactPrepareVersion_generated.go @@ -56,6 +56,9 @@ type artifactPrepareVersionCommonPipelineEnvironment struct { headCommitID string commitMessage string } + container struct { + labels map[string]interface{} + } } func (p *artifactPrepareVersionCommonPipelineEnvironment) persist(path, resourceName string) { @@ -72,6 +75,7 @@ func (p *artifactPrepareVersionCommonPipelineEnvironment) persist(path, resource {category: "git", name: "commitId", value: p.git.commitID}, {category: "git", name: "headCommitId", value: p.git.headCommitID}, {category: "git", name: "commitMessage", value: p.git.commitMessage}, + {category: "container", name: "labels", value: p.container.labels}, } errCount := 0 @@ -136,7 +140,7 @@ Another typical use-case is development of a library with regular releases where The version is then either manually set by the team in the course of the development process or automatically pushed to master after a successful release. -Unlike for the _Continuous Deloyment_ pattern described above, in this case there is no dedicated tagging required for the build process since the version is already available in the repository. +Unlike for the _Continuous Deployment_ pattern described above, in this case there is no dedicated tagging required for the build process since the version is already available in the repository. Configuration of this pattern is done via ` + "`" + `versioningType: library` + "`" + `. @@ -582,6 +586,7 @@ func artifactPrepareVersionMetadata() config.StepData { {"name": "git/commitId"}, {"name": "git/headCommitId"}, {"name": "git/commitMessage"}, + {"name": "container/labels", "type": "map[string]interface{}"}, }, }, }, diff --git a/cmd/kanikoExecute.go b/cmd/kanikoExecute.go index 1937dd66af..e058790063 100644 --- a/cmd/kanikoExecute.go +++ b/cmd/kanikoExecute.go @@ -170,7 +170,7 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus log.Entry().Debugf("Building image '%v' using file '%v'", image, file) containerImageNameAndTag := fmt.Sprintf("%v:%v", image, containerImageTag) buildOpts := append(config.BuildOptions, "--destination", fmt.Sprintf("%v/%v", containerRegistry, containerImageNameAndTag)) - if err = runKaniko(file, buildOpts, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { + if err = runKaniko(config, file, buildOpts, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { return fmt.Errorf("failed to build image '%v' using '%v': %w", image, file, err) } commonPipelineEnvironment.container.imageNames = append(commonPipelineEnvironment.container.imageNames, image) @@ -231,7 +231,7 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus dockerfilePath = entry.DockerfilePath } - if err = runKaniko(dockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { + if err = runKaniko(config, dockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { return fmt.Errorf("multipleImages: failed to build image '%v' using '%v': %w", entry.ContainerImageName, config.DockerfilePath, err) } @@ -262,7 +262,7 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus dockerfilePath = entry.DockerfilePath } - if err = runKaniko(dockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { + if err = runKaniko(config, dockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { return fmt.Errorf("multipleImages: failed to build image '%v' using '%v': %w", containerImageName, config.DockerfilePath, err) } @@ -356,7 +356,7 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus config.BuildOptions = append(config.BuildOptions, "--no-push") } - if err = runKaniko(config.DockerfilePath, config.BuildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { + if err = runKaniko(config, config.DockerfilePath, config.BuildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { return err } @@ -368,7 +368,7 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus return nil } -func runKaniko(dockerFilepath string, buildOptions []string, readDigest bool, execRunner command.ExecRunner, fileUtils piperutils.FileUtils, commonPipelineEnvironment *kanikoExecuteCommonPipelineEnvironment) error { +func runKaniko(config *kanikoExecuteOptions, dockerFilepath string, buildOptions []string, readDigest bool, execRunner command.ExecRunner, fileUtils piperutils.FileUtils, commonPipelineEnvironment *kanikoExecuteCommonPipelineEnvironment) error { cwd, err := fileUtils.Getwd() if err != nil { return fmt.Errorf("failed to get current working directory: %w", err) @@ -379,6 +379,10 @@ func runKaniko(dockerFilepath string, buildOptions []string, readDigest bool, ex kanikoOpts := []string{"--dockerfile", dockerFilepath, "--context", "dir://" + cwd} kanikoOpts = append(kanikoOpts, buildOptions...) + for label, value := range config.Labels { + kanikoOpts = append(kanikoOpts, "--label", fmt.Sprintf("%s=%s", label, value)) + } + tmpDir, err := fileUtils.TempDir("", "*-kanikoExecute") if err != nil { return fmt.Errorf("failed to create tmp dir for kanikoExecute: %w", err) diff --git a/cmd/kanikoExecute_generated.go b/cmd/kanikoExecute_generated.go index fd045081f2..4e683184bf 100644 --- a/cmd/kanikoExecute_generated.go +++ b/cmd/kanikoExecute_generated.go @@ -44,6 +44,7 @@ type kanikoExecuteOptions struct { ReadImageDigest bool `json:"readImageDigest,omitempty"` CreateBOM bool `json:"createBOM,omitempty"` SyftDownloadURL string `json:"syftDownloadUrl,omitempty"` + Labels map[string]interface{} `json:"labels,omitempty"` } type kanikoExecuteCommonPipelineEnvironment struct { @@ -318,7 +319,7 @@ Following final image names will be built: func addKanikoExecuteFlags(cmd *cobra.Command, stepConfig *kanikoExecuteOptions) { cmd.Flags().StringSliceVar(&stepConfig.BuildOptions, "buildOptions", []string{`--skip-tls-verify-pull`, `--ignore-path=/workspace`, `--ignore-path=/busybox`}, "Defines a list of build options for the [kaniko](https://github.com/GoogleContainerTools/kaniko) build.") cmd.Flags().StringVar(&stepConfig.BuildSettingsInfo, "buildSettingsInfo", os.Getenv("PIPER_buildSettingsInfo"), "Build settings info is typically filled by the step automatically to create information about the build settings that were used during the mta build. This information is typically used for compliance related processes.") - cmd.Flags().StringVar(&stepConfig.ContainerBuildOptions, "containerBuildOptions", os.Getenv("PIPER_containerBuildOptions"), "Deprected, please use buildOptions. Defines the build options for the [kaniko](https://github.com/GoogleContainerTools/kaniko) build.") + cmd.Flags().StringVar(&stepConfig.ContainerBuildOptions, "containerBuildOptions", os.Getenv("PIPER_containerBuildOptions"), "Deprecated, please use buildOptions. Defines the build options for the [kaniko](https://github.com/GoogleContainerTools/kaniko) build.") cmd.Flags().StringVar(&stepConfig.ContainerImage, "containerImage", os.Getenv("PIPER_containerImage"), "Defines the full name of the Docker image to be created including registry, image name and tag like `my.docker.registry/path/myImageName:myTag`. If `containerImage` is not provided, then `containerImageName` or `--destination` (via buildOptions) should be provided.") cmd.Flags().StringVar(&stepConfig.ContainerImageName, "containerImageName", os.Getenv("PIPER_containerImageName"), "Name of the container which will be built - will be used instead of parameter `containerImage`. If `containerImageName` is not provided, then `containerImage` or `--destination` (via buildOptions) should be provided.") cmd.Flags().StringVar(&stepConfig.ContainerImageTag, "containerImageTag", os.Getenv("PIPER_containerImageTag"), "Tag of the container which will be built - will be used instead of parameter `containerImage`") @@ -578,6 +579,19 @@ func kanikoExecuteMetadata() config.StepData { Aliases: []config.Alias{}, Default: `https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz`, }, + { + Name: "labels", + ResourceRef: []config.ResourceReference{ + { + Name: "commonPipelineEnvironment", + Param: "container/labels", + }, + }, + Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, }, }, Containers: []config.Container{ diff --git a/resources/metadata/artifactPrepareVersion.yaml b/resources/metadata/artifactPrepareVersion.yaml index 34389c21eb..1a9c8bb816 100644 --- a/resources/metadata/artifactPrepareVersion.yaml +++ b/resources/metadata/artifactPrepareVersion.yaml @@ -40,7 +40,7 @@ metadata: The version is then either manually set by the team in the course of the development process or automatically pushed to master after a successful release. - Unlike for the _Continuous Deloyment_ pattern described above, in this case there is no dedicated tagging required for the build process since the version is already available in the repository. + Unlike for the _Continuous Deployment_ pattern described above, in this case there is no dedicated tagging required for the build process since the version is already available in the repository. Configuration of this pattern is done via `versioningType: library`. @@ -385,6 +385,8 @@ spec: - name: git/commitId - name: git/headCommitId - name: git/commitMessage + - name: container/labels + type: map[string]interface{} containers: - image: maven:3.6-jdk-8 conditions: diff --git a/resources/metadata/kanikoExecute.yaml b/resources/metadata/kanikoExecute.yaml index 5efad0931c..4078eadb71 100644 --- a/resources/metadata/kanikoExecute.yaml +++ b/resources/metadata/kanikoExecute.yaml @@ -103,7 +103,7 @@ spec: param: custom/buildSettingsInfo - name: containerBuildOptions type: string - description: Deprected, please use buildOptions. Defines the build options for the [kaniko](https://github.com/GoogleContainerTools/kaniko) build. + description: Deprecated, please use buildOptions. Defines the build options for the [kaniko](https://github.com/GoogleContainerTools/kaniko) build. scope: - PARAMETERS - STAGES @@ -306,6 +306,19 @@ spec: - PARAMETERS - STEPS default: "https://github.com/anchore/syft/releases/download/v1.4.1/syft_1.4.1_linux_amd64.tar.gz" + - name: labels + type: map[string]interface{} + description: Map of labels to be added to the image. The key is the label name and the value is the label value. + # https://github.com/opencontainers/image-spec/blob/main/annotations.md#pre-defined-annotation-keys + default: [] + scope: + - GENERAL + - STEPS + - STAGES + - PARAMETERS + resourceRef: + - name: commonPipelineEnvironment + param: container/labels outputs: resources: - name: commonPipelineEnvironment