github.com/xgoffin/jenkins-library@v1.154.0/cmd/kanikoExecute_generated.go (about) 1 // Code generated by piper's step-generator. DO NOT EDIT. 2 3 package cmd 4 5 import ( 6 "fmt" 7 "os" 8 "path/filepath" 9 "time" 10 11 "github.com/SAP/jenkins-library/pkg/config" 12 "github.com/SAP/jenkins-library/pkg/log" 13 "github.com/SAP/jenkins-library/pkg/piperenv" 14 "github.com/SAP/jenkins-library/pkg/splunk" 15 "github.com/SAP/jenkins-library/pkg/telemetry" 16 "github.com/SAP/jenkins-library/pkg/validation" 17 "github.com/spf13/cobra" 18 ) 19 20 type kanikoExecuteOptions struct { 21 BuildOptions []string `json:"buildOptions,omitempty"` 22 BuildSettingsInfo string `json:"buildSettingsInfo,omitempty"` 23 ContainerBuildOptions string `json:"containerBuildOptions,omitempty"` 24 ContainerImage string `json:"containerImage,omitempty"` 25 ContainerImageName string `json:"containerImageName,omitempty"` 26 ContainerImageTag string `json:"containerImageTag,omitempty"` 27 ContainerMultiImageBuild bool `json:"containerMultiImageBuild,omitempty"` 28 ContainerMultiImageBuildExcludes []string `json:"containerMultiImageBuildExcludes,omitempty"` 29 ContainerMultiImageBuildTrimDir string `json:"containerMultiImageBuildTrimDir,omitempty"` 30 ContainerPreparationCommand string `json:"containerPreparationCommand,omitempty"` 31 ContainerRegistryURL string `json:"containerRegistryUrl,omitempty"` 32 CustomTLSCertificateLinks []string `json:"customTlsCertificateLinks,omitempty"` 33 DockerConfigJSON string `json:"dockerConfigJSON,omitempty"` 34 DockerfilePath string `json:"dockerfilePath,omitempty"` 35 TargetArchitectures []string `json:"targetArchitectures,omitempty"` 36 ReadImageDigest bool `json:"readImageDigest,omitempty"` 37 } 38 39 type kanikoExecuteCommonPipelineEnvironment struct { 40 container struct { 41 registryURL string 42 imageNameTag string 43 imageDigest string 44 imageNames []string 45 imageNameTags []string 46 imageDigests []string 47 } 48 custom struct { 49 buildSettingsInfo string 50 } 51 } 52 53 func (p *kanikoExecuteCommonPipelineEnvironment) persist(path, resourceName string) { 54 content := []struct { 55 category string 56 name string 57 value interface{} 58 }{ 59 {category: "container", name: "registryUrl", value: p.container.registryURL}, 60 {category: "container", name: "imageNameTag", value: p.container.imageNameTag}, 61 {category: "container", name: "imageDigest", value: p.container.imageDigest}, 62 {category: "container", name: "imageNames", value: p.container.imageNames}, 63 {category: "container", name: "imageNameTags", value: p.container.imageNameTags}, 64 {category: "container", name: "imageDigests", value: p.container.imageDigests}, 65 {category: "custom", name: "buildSettingsInfo", value: p.custom.buildSettingsInfo}, 66 } 67 68 errCount := 0 69 for _, param := range content { 70 err := piperenv.SetResourceParameter(path, resourceName, filepath.Join(param.category, param.name), param.value) 71 if err != nil { 72 log.Entry().WithError(err).Error("Error persisting piper environment.") 73 errCount++ 74 } 75 } 76 if errCount > 0 { 77 log.Entry().Error("failed to persist Piper environment") 78 } 79 } 80 81 // KanikoExecuteCommand Executes a [Kaniko](https://github.com/GoogleContainerTools/kaniko) build for creating a Docker container. 82 func KanikoExecuteCommand() *cobra.Command { 83 const STEP_NAME = "kanikoExecute" 84 85 metadata := kanikoExecuteMetadata() 86 var stepConfig kanikoExecuteOptions 87 var startTime time.Time 88 var commonPipelineEnvironment kanikoExecuteCommonPipelineEnvironment 89 var logCollector *log.CollectorHook 90 var splunkClient *splunk.Splunk 91 telemetryClient := &telemetry.Telemetry{} 92 93 var createKanikoExecuteCmd = &cobra.Command{ 94 Use: STEP_NAME, 95 Short: "Executes a [Kaniko](https://github.com/GoogleContainerTools/kaniko) build for creating a Docker container.", 96 Long: `Executes a [Kaniko](https://github.com/GoogleContainerTools/kaniko) build for creating a Docker container. 97 98 ### Building multiple container images 99 100 The step allows you to build multiple container images with one run. 101 This is suitable in case you need to create multiple images for one microservice, e.g. for testing. 102 103 All images will get the same "root" name and the same versioning.<br /> 104 **Thus, this is not suitable to be used for a monorepo approach!** For monorepos you need to use a build tool natively capable to take care for monorepos 105 or implement a custom logic and for example execute this ` + "`" + `kanikoExecute` + "`" + ` step multiple times in your custom pipeline. 106 107 You can activate multiple builds using the parameter [containerMultiImageBuild](#containermultiimagebuild) 108 109 Behavior can be adapted using: 110 111 * [containerMultiImageBuildExcludes](#containermultiimagebuildexcludes) for defining excludes 112 * [containerMultiImageBuildTrimDir](#containermultiimagebuildtrimdir) for removing parent directory part from image name 113 114 Examples: 115 116 #### Multiple containers in sub directories 117 118 Configuration as follows: 119 120 ` + "`" + `` + "`" + `` + "`" + ` 121 general: 122 containerImageName: myImage 123 steps: 124 kanikoExecute: 125 containerMultiImageBuild: true 126 ` + "`" + `` + "`" + `` + "`" + ` 127 128 Following Dockerfiles are available in the repository: 129 130 * sub1/Dockerfile 131 * sub2/Dockerfile 132 133 Following final image names will be built: 134 135 * ` + "`" + `myImage-sub1` + "`" + ` 136 * ` + "`" + `myImage-sub2` + "`" + ` 137 138 #### Multiple containers in sub directories while trimming a directory part 139 140 Configuration as follows: 141 142 ` + "`" + `` + "`" + `` + "`" + ` 143 general: 144 containerImageName: myImage 145 steps: 146 kanikoExecute: 147 containerMultiImageBuild: true 148 containerMultiImageBuildTrimDir: .ci 149 ` + "`" + `` + "`" + `` + "`" + ` 150 151 Following Dockerfiles are available in the repository: 152 153 * .ci/sub1/Dockerfile 154 * .ci/sub2/Dockerfile 155 156 Following final image names will be built: 157 158 * ` + "`" + `myImage-sub1` + "`" + ` 159 * ` + "`" + `myImage-sub2` + "`" + ``, 160 PreRunE: func(cmd *cobra.Command, _ []string) error { 161 startTime = time.Now() 162 log.SetStepName(STEP_NAME) 163 log.SetVerbose(GeneralConfig.Verbose) 164 165 GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens) 166 167 path, _ := os.Getwd() 168 fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path} 169 log.RegisterHook(fatalHook) 170 171 err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile) 172 if err != nil { 173 log.SetErrorCategory(log.ErrorConfiguration) 174 return err 175 } 176 log.RegisterSecret(stepConfig.DockerConfigJSON) 177 178 if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 { 179 sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID) 180 log.RegisterHook(&sentryHook) 181 } 182 183 if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { 184 splunkClient = &splunk.Splunk{} 185 logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID} 186 log.RegisterHook(logCollector) 187 } 188 189 validation, err := validation.New(validation.WithJSONNamesForStructFields(), validation.WithPredefinedErrorMessages()) 190 if err != nil { 191 return err 192 } 193 if err = validation.ValidateStruct(stepConfig); err != nil { 194 log.SetErrorCategory(log.ErrorConfiguration) 195 return err 196 } 197 198 return nil 199 }, 200 Run: func(_ *cobra.Command, _ []string) { 201 stepTelemetryData := telemetry.CustomData{} 202 stepTelemetryData.ErrorCode = "1" 203 handler := func() { 204 commonPipelineEnvironment.persist(GeneralConfig.EnvRootPath, "commonPipelineEnvironment") 205 config.RemoveVaultSecretFiles() 206 stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds()) 207 stepTelemetryData.ErrorCategory = log.GetErrorCategory().String() 208 stepTelemetryData.PiperCommitHash = GitCommit 209 telemetryClient.SetData(&stepTelemetryData) 210 telemetryClient.Send() 211 if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { 212 splunkClient.Send(telemetryClient.GetData(), logCollector) 213 } 214 } 215 log.DeferExitHandler(handler) 216 defer handler() 217 telemetryClient.Initialize(GeneralConfig.NoTelemetry, STEP_NAME) 218 if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 { 219 splunkClient.Initialize(GeneralConfig.CorrelationID, 220 GeneralConfig.HookConfig.SplunkConfig.Dsn, 221 GeneralConfig.HookConfig.SplunkConfig.Token, 222 GeneralConfig.HookConfig.SplunkConfig.Index, 223 GeneralConfig.HookConfig.SplunkConfig.SendLogs) 224 } 225 kanikoExecute(stepConfig, &stepTelemetryData, &commonPipelineEnvironment) 226 stepTelemetryData.ErrorCode = "0" 227 log.Entry().Info("SUCCESS") 228 }, 229 } 230 231 addKanikoExecuteFlags(createKanikoExecuteCmd, &stepConfig) 232 return createKanikoExecuteCmd 233 } 234 235 func addKanikoExecuteFlags(cmd *cobra.Command, stepConfig *kanikoExecuteOptions) { 236 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.") 237 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.") 238 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.") 239 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 left empty, image will not be pushed.") 240 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`") 241 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`") 242 cmd.Flags().BoolVar(&stepConfig.ContainerMultiImageBuild, "containerMultiImageBuild", false, "Defines if multiple containers should be build. Dockerfiles are used using the pattern **/Dockerfile*. Excludes can be defined via [`containerMultiImageBuildExcludes`](#containermultiimagebuildexscludes).") 243 cmd.Flags().StringSliceVar(&stepConfig.ContainerMultiImageBuildExcludes, "containerMultiImageBuildExcludes", []string{}, "Defines a list of Dockerfile paths to exclude from the build when using [`containerMultiImageBuild`](#containermultiimagebuild).") 244 cmd.Flags().StringVar(&stepConfig.ContainerMultiImageBuildTrimDir, "containerMultiImageBuildTrimDir", os.Getenv("PIPER_containerMultiImageBuildTrimDir"), "Defines a trailing directory part which should not be considered in the final image name.") 245 cmd.Flags().StringVar(&stepConfig.ContainerPreparationCommand, "containerPreparationCommand", `rm -f /kaniko/.docker/config.json`, "Defines the command to prepare the Kaniko container. By default the contained credentials are removed in order to allow anonymous access to container registries.") 246 cmd.Flags().StringVar(&stepConfig.ContainerRegistryURL, "containerRegistryUrl", os.Getenv("PIPER_containerRegistryUrl"), "http(s) url of the Container registry where the image should be pushed to - will be used instead of parameter `containerImage`") 247 cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List containing download links of custom TLS certificates. This is required to ensure trusted connections to registries with custom certificates.") 248 cmd.Flags().StringVar(&stepConfig.DockerConfigJSON, "dockerConfigJSON", os.Getenv("PIPER_dockerConfigJSON"), "Path to the file `.docker/config.json` - this is typically provided by your CI/CD system. You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).") 249 cmd.Flags().StringVar(&stepConfig.DockerfilePath, "dockerfilePath", `Dockerfile`, "Defines the location of the Dockerfile relative to the Jenkins workspace.") 250 cmd.Flags().StringSliceVar(&stepConfig.TargetArchitectures, "targetArchitectures", []string{``}, "Defines the target architectures for which the build should run using OS and architecture separated by a comma. (EXPERIMENTAL)") 251 cmd.Flags().BoolVar(&stepConfig.ReadImageDigest, "readImageDigest", false, "") 252 253 } 254 255 // retrieve step metadata 256 func kanikoExecuteMetadata() config.StepData { 257 var theMetaData = config.StepData{ 258 Metadata: config.StepMetadata{ 259 Name: "kanikoExecute", 260 Aliases: []config.Alias{}, 261 Description: "Executes a [Kaniko](https://github.com/GoogleContainerTools/kaniko) build for creating a Docker container.", 262 }, 263 Spec: config.StepSpec{ 264 Inputs: config.StepInputs{ 265 Secrets: []config.StepSecrets{ 266 {Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can create it like explained in the [protocodeExecuteScan Prerequisites section](https://www.project-piper.io/steps/protecodeExecuteScan/#prerequisites).", Type: "jenkins"}, 267 }, 268 Parameters: []config.StepParameters{ 269 { 270 Name: "buildOptions", 271 ResourceRef: []config.ResourceReference{}, 272 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 273 Type: "[]string", 274 Mandatory: false, 275 Aliases: []config.Alias{}, 276 Default: []string{`--skip-tls-verify-pull`, `--ignore-path=/workspace`, `--ignore-path=/busybox`}, 277 }, 278 { 279 Name: "buildSettingsInfo", 280 ResourceRef: []config.ResourceReference{ 281 { 282 Name: "commonPipelineEnvironment", 283 Param: "custom/buildSettingsInfo", 284 }, 285 }, 286 Scope: []string{"STEPS", "STAGES", "PARAMETERS"}, 287 Type: "string", 288 Mandatory: false, 289 Aliases: []config.Alias{}, 290 Default: os.Getenv("PIPER_buildSettingsInfo"), 291 }, 292 { 293 Name: "containerBuildOptions", 294 ResourceRef: []config.ResourceReference{}, 295 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 296 Type: "string", 297 Mandatory: false, 298 Aliases: []config.Alias{}, 299 Default: os.Getenv("PIPER_containerBuildOptions"), 300 }, 301 { 302 Name: "containerImage", 303 ResourceRef: []config.ResourceReference{}, 304 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 305 Type: "string", 306 Mandatory: false, 307 Aliases: []config.Alias{{Name: "containerImageNameAndTag", Deprecated: true}}, 308 Default: os.Getenv("PIPER_containerImage"), 309 }, 310 { 311 Name: "containerImageName", 312 ResourceRef: []config.ResourceReference{}, 313 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 314 Type: "string", 315 Mandatory: false, 316 Aliases: []config.Alias{{Name: "dockerImageName"}}, 317 Default: os.Getenv("PIPER_containerImageName"), 318 }, 319 { 320 Name: "containerImageTag", 321 ResourceRef: []config.ResourceReference{ 322 { 323 Name: "commonPipelineEnvironment", 324 Param: "artifactVersion", 325 }, 326 }, 327 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 328 Type: "string", 329 Mandatory: false, 330 Aliases: []config.Alias{{Name: "artifactVersion"}}, 331 Default: os.Getenv("PIPER_containerImageTag"), 332 }, 333 { 334 Name: "containerMultiImageBuild", 335 ResourceRef: []config.ResourceReference{}, 336 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 337 Type: "bool", 338 Mandatory: false, 339 Aliases: []config.Alias{}, 340 Default: false, 341 }, 342 { 343 Name: "containerMultiImageBuildExcludes", 344 ResourceRef: []config.ResourceReference{}, 345 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 346 Type: "[]string", 347 Mandatory: false, 348 Aliases: []config.Alias{}, 349 Default: []string{}, 350 }, 351 { 352 Name: "containerMultiImageBuildTrimDir", 353 ResourceRef: []config.ResourceReference{}, 354 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 355 Type: "string", 356 Mandatory: false, 357 Aliases: []config.Alias{}, 358 Default: os.Getenv("PIPER_containerMultiImageBuildTrimDir"), 359 }, 360 { 361 Name: "containerPreparationCommand", 362 ResourceRef: []config.ResourceReference{}, 363 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 364 Type: "string", 365 Mandatory: false, 366 Aliases: []config.Alias{}, 367 Default: `rm -f /kaniko/.docker/config.json`, 368 }, 369 { 370 Name: "containerRegistryUrl", 371 ResourceRef: []config.ResourceReference{ 372 { 373 Name: "commonPipelineEnvironment", 374 Param: "container/registryUrl", 375 }, 376 }, 377 Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, 378 Type: "string", 379 Mandatory: false, 380 Aliases: []config.Alias{{Name: "dockerRegistryUrl"}}, 381 Default: os.Getenv("PIPER_containerRegistryUrl"), 382 }, 383 { 384 Name: "customTlsCertificateLinks", 385 ResourceRef: []config.ResourceReference{}, 386 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 387 Type: "[]string", 388 Mandatory: false, 389 Aliases: []config.Alias{}, 390 Default: []string{}, 391 }, 392 { 393 Name: "dockerConfigJSON", 394 ResourceRef: []config.ResourceReference{ 395 { 396 Name: "commonPipelineEnvironment", 397 Param: "custom/dockerConfigJSON", 398 }, 399 400 { 401 Name: "dockerConfigJsonCredentialsId", 402 Type: "secret", 403 }, 404 405 { 406 Name: "dockerConfigFileVaultSecretName", 407 Type: "vaultSecretFile", 408 Default: "docker-config", 409 }, 410 }, 411 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 412 Type: "string", 413 Mandatory: false, 414 Aliases: []config.Alias{}, 415 Default: os.Getenv("PIPER_dockerConfigJSON"), 416 }, 417 { 418 Name: "dockerfilePath", 419 ResourceRef: []config.ResourceReference{}, 420 Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, 421 Type: "string", 422 Mandatory: false, 423 Aliases: []config.Alias{{Name: "dockerfile"}}, 424 Default: `Dockerfile`, 425 }, 426 { 427 Name: "targetArchitectures", 428 ResourceRef: []config.ResourceReference{}, 429 Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, 430 Type: "[]string", 431 Mandatory: false, 432 Aliases: []config.Alias{}, 433 Default: []string{``}, 434 }, 435 { 436 Name: "readImageDigest", 437 ResourceRef: []config.ResourceReference{}, 438 Scope: []string{"STEPS", "STAGES", "PARAMETERS"}, 439 Type: "bool", 440 Mandatory: false, 441 Aliases: []config.Alias{}, 442 Default: false, 443 }, 444 }, 445 }, 446 Containers: []config.Container{ 447 {Image: "gcr.io/kaniko-project/executor:debug", EnvVars: []config.EnvVar{{Name: "container", Value: "docker"}}, Options: []config.Option{{Name: "-u", Value: "0"}, {Name: "--entrypoint", Value: ""}}}, 448 }, 449 Outputs: config.StepOutputs{ 450 Resources: []config.StepResources{ 451 { 452 Name: "commonPipelineEnvironment", 453 Type: "piperEnvironment", 454 Parameters: []map[string]interface{}{ 455 {"name": "container/registryUrl"}, 456 {"name": "container/imageNameTag"}, 457 {"name": "container/imageDigest"}, 458 {"name": "container/imageNames", "type": "[]string"}, 459 {"name": "container/imageNameTags", "type": "[]string"}, 460 {"name": "container/imageDigests", "type": "[]string"}, 461 {"name": "custom/buildSettingsInfo"}, 462 }, 463 }, 464 }, 465 }, 466 }, 467 } 468 return theMetaData 469 }