github.com/jaylevin/jenkins-library@v1.230.4/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  }