diff --git a/cmd/buildah/manifest.go b/cmd/buildah/manifest.go index e35220dce1..c4051cf682 100644 --- a/cmd/buildah/manifest.go +++ b/cmd/buildah/manifest.go @@ -268,6 +268,7 @@ func manifestInit() { if err := flags.MarkHidden("insecure"); err != nil { panic(fmt.Sprintf("error marking insecure as hidden: %v", err)) } + flags.Int64Var(&manifestPushOpts.destTimestamp, "timestamp", 0, "set timestamps on new content to `seconds` after the epoch") flags.BoolVar(&manifestPushOpts.tlsVerify, "tls-verify", true, "require HTTPS and verify certificates when accessing the registry. TLS verification cannot be used when talking to an insecure registry.") flags.BoolVarP(&manifestPushOpts.quiet, "quiet", "q", false, "don't output progress information when pushing lists") flags.IntVar(&manifestPushOpts.retry, "retry", int(defaultContainerConfig.Engine.Retry), "number of times to retry in case of failure when performing push") @@ -1148,6 +1149,9 @@ func manifestPushCmd(c *cobra.Command, args []string, opts pushOptions) error { opts.forceCompressionFormat = true } } + if c.Flag("timestamp").Changed { + opts.timestampSet = true + } return manifestPush(systemContext, store, listImageSpec, destSpec, opts) } @@ -1219,7 +1223,10 @@ func manifestPush(systemContext *types.SystemContext, store storage.Store, listI if !opts.quiet { options.ReportWriter = os.Stderr } - + if opts.timestampSet { + ts := time.Unix(int64(opts.destTimestamp), 0).UTC() + options.DestinationTimestamp = &ts + } _, digest, err := list.Push(getContext(), dest, options) if err == nil && opts.rm { diff --git a/cmd/buildah/push.go b/cmd/buildah/push.go index 8c38e09f09..e2f6b105f9 100644 --- a/cmd/buildah/push.go +++ b/cmd/buildah/push.go @@ -48,6 +48,8 @@ type pushOptions struct { encryptLayers []int insecure bool addCompression []string + destTimestamp int64 + timestampSet bool } func pushInit() { diff --git a/docs/buildah-manifest-push.1.md b/docs/buildah-manifest-push.1.md index 97ee58d77a..3a6bb38363 100644 --- a/docs/buildah-manifest-push.1.md +++ b/docs/buildah-manifest-push.1.md @@ -99,6 +99,13 @@ Delete the manifest list or image index from local storage if pushing succeeds. Sign the pushed images using the GPG key that matches the specified fingerprint. +**--timestamp** *seconds* + +Set the "created" timestamp for outputs to this number of seconds since +the epoch (Unix time 0, i.e., 00:00:00 UTC on 1 January 1970) (defaults to +current time). For example, if an oci-archive output is used, the tar entries +created times are set to this value. + **--tls-verify** *bool-value* Require HTTPS and verification of certificates when talking to container registries (defaults to true). TLS verification cannot be used when talking to an insecure registry. diff --git a/tests/lists.bats b/tests/lists.bats index f5e323258d..75299fb36f 100644 --- a/tests/lists.bats +++ b/tests/lists.bats @@ -252,6 +252,26 @@ IMAGE_LIST_S390X_INSTANCE_DIGEST=sha256:882a20ee0df7399a445285361d38b711c299ca09 expect_output --substring "foo1: image not known" } +@test "manifest-push-with-timestamp" { + outpath=${TEST_SCRATCH_DIR}/out + + run_buildah manifest create foo + run_buildah manifest add --all foo ${IMAGE_LIST} + + run_buildah manifest push --timestamp=1 foo oci-archive:${outpath}.a + run_buildah manifest push --timestamp=0 foo oci-archive:${outpath}.b + sleep 1.1 + run_buildah manifest push --timestamp=0 foo oci-archive:${outpath}.c + + run_buildah manifest rm foo + + # should be different ( || false is due to bats weirdness ) + ! diff "${outpath}.a" "${outpath}.b" || false + + # should be the same + diff "${outpath}.b" "${outpath}.c" +} + @test "manifest-push" { run_buildah manifest create foo run_buildah manifest add --all foo ${IMAGE_LIST}