From a6e3ddfc7976b399644d076f7d9bcfbe5d1f7fb9 Mon Sep 17 00:00:00 2001 From: Gijs Date: Thu, 2 May 2019 13:34:38 +0200 Subject: [PATCH] Add `--digestfile` flag to output built digest to file. This flag, when set, takes a file in the container and writes the image digest to it. This can be used to extract the exact digest of the built image by surrounding tooling without having to parse the logs from Kaniko, for example by pointing the file to a mounted volume or to a file used durint exit status, such as with Kubernetes' [Termination message policy](https://kubernetes.io/docs/tasks/debug-application-cluster/determine-reason-pod-failure/)] When the flag is not set, the digest is not written to file and the executor behaves as before. The digest is also written to file in case of a tarball or a `--no-push`. Closes #654 --- README.md | 13 +++++++++++++ cmd/executor/cmd/root.go | 1 + pkg/config/options.go | 1 + pkg/executor/push.go | 14 ++++++++++++++ 4 files changed, 29 insertions(+) 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)