diff --git a/README.md b/README.md index 823b0712b..8f16488d4 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ _If you are interested in contributing to kaniko, see [DEVELOPMENT.md](DEVELOPME - [--cache-dir](#--cache-dir) - [--cache-repo](#--cache-repo) - [--cleanup](#--cleanup) + - [--digestfile](#--digestfile) - [--insecure](#--insecure) - [--insecure-pull](#--insecure-pull) - [--no-push](#--no-push) @@ -356,6 +357,18 @@ If `--destination=gcr.io/kaniko-project/test`, then cached layers will be stored _This flag must be used in conjunction with the `--cache=true` flag._ + +#### --digestfile + +Set this flag to specify a file in the container. This file will +receive the digest of a built image. This can be used to +automatically track the exact image built by Kaniko. + +For example, setting the flag to `--digestfile=/dev/termination-log` +will write the digest to that file, which is picked up by +Kubernetes automatically as the `{{.state.terminated.message}}` +of the container. + #### --insecure-registry Set this flag to use plain HTTP requests when accessing a registry. It is supposed to be used for testing purposes only and should not be used in production! diff --git a/cmd/executor/cmd/root.go b/cmd/executor/cmd/root.go index e51a03ae3..a3a59511b 100644 --- a/cmd/executor/cmd/root.go +++ b/cmd/executor/cmd/root.go @@ -128,6 +128,7 @@ func addKanikoOptionsFlags(cmd *cobra.Command) { RootCmd.PersistentFlags().BoolVarP(&opts.NoPush, "no-push", "", false, "Do not push the image to the registry") RootCmd.PersistentFlags().StringVarP(&opts.CacheRepo, "cache-repo", "", "", "Specify a repository to use as a cache, otherwise one will be inferred from the destination provided") RootCmd.PersistentFlags().StringVarP(&opts.CacheDir, "cache-dir", "", "/cache", "Specify a local directory to use as a cache.") + RootCmd.PersistentFlags().StringVarP(&opts.DigestFile, "digestfile", "", "", "Specify a file to save the digest of the built image to.") RootCmd.PersistentFlags().BoolVarP(&opts.Cache, "cache", "", false, "Use cache when building image") RootCmd.PersistentFlags().BoolVarP(&opts.Cleanup, "cleanup", "", false, "Clean the filesystem at the end") RootCmd.PersistentFlags().DurationVarP(&opts.CacheTTL, "cache-ttl", "", time.Hour*336, "Cache timeout in hours. Defaults to two weeks.") diff --git a/pkg/config/options.go b/pkg/config/options.go index 9a912f919..ff4d60a13 100644 --- a/pkg/config/options.go +++ b/pkg/config/options.go @@ -30,6 +30,7 @@ type KanikoOptions struct { Target string CacheRepo string CacheDir string + DigestFile string Destinations multiArg BuildArgs multiArg Insecure bool diff --git a/pkg/executor/push.go b/pkg/executor/push.go index 579aabc61..628982c95 100644 --- a/pkg/executor/push.go +++ b/pkg/executor/push.go @@ -19,6 +19,7 @@ package executor import ( "crypto/tls" "fmt" + "io/ioutil" "net/http" "time" @@ -74,6 +75,19 @@ func CheckPushPermissions(opts *config.KanikoOptions) error { // DoPush is responsible for pushing image to the destinations specified in opts func DoPush(image v1.Image, opts *config.KanikoOptions) error { t := timing.Start("Total Push Time") + + if image != nil && opts.DigestFile != "" { + digest, err := image.Digest() + if err != nil { + return errors.Wrap(err, "error fetching digest") + } + digestByteArray := []byte(digest.String()) + err = ioutil.WriteFile(opts.DigestFile, digestByteArray, 0644) + if err != nil { + return errors.Wrap(err, "writing digest to file failed") + } + } + destRefs := []name.Tag{} for _, destination := range opts.Destinations { destRef, err := name.NewTag(destination, name.WeakValidation)