mirror of
https://github.com/containers/buildah.git
synced 2025-07-31 15:24:26 +03:00
cmd/commit: add flag omit-timestamp to allow for deterministic builds
By default, a field called "createdAt" is written into the image manifest. However, even if my image build process is perfectly deterministic, the image sha256 hash will be different every time, even if my sources are exactly the same. In many cases it is desirable that the same input results in the exactly same output. This commit introduces the flag --omit-timestamp to the commit command. If set to true, the timestamp is set to epoch 0, instead of the current timestamp (which causes different results every time commit is invoked). Signed-off-by: Johannes Brüderl <johannes.bruederl@gmail.com> Closes: #1294 Approved by: nalind
This commit is contained in:
committed by
Atomic Bot
parent
23ed59594b
commit
4bcddb7cbe
@ -52,6 +52,10 @@ var (
|
|||||||
Name: "iidfile",
|
Name: "iidfile",
|
||||||
Usage: "Write the image ID to the file",
|
Usage: "Write the image ID to the file",
|
||||||
},
|
},
|
||||||
|
cli.BoolFlag{
|
||||||
|
Name: "omit-timestamp",
|
||||||
|
Usage: "set created timestamp to epoch 0 to allow for deterministic builds",
|
||||||
|
},
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "quiet, q",
|
Name: "quiet, q",
|
||||||
Usage: "don't output progress information when writing images",
|
Usage: "don't output progress information when writing images",
|
||||||
@ -172,6 +176,7 @@ func commitCmd(c *cli.Context) error {
|
|||||||
IIDFile: c.String("iidfile"),
|
IIDFile: c.String("iidfile"),
|
||||||
Squash: c.Bool("squash"),
|
Squash: c.Bool("squash"),
|
||||||
BlobDirectory: c.String("blob-cache"),
|
BlobDirectory: c.String("blob-cache"),
|
||||||
|
OmitTimestamp: c.Bool("omit-timestamp"),
|
||||||
}
|
}
|
||||||
if !c.Bool("quiet") {
|
if !c.Bool("quiet") {
|
||||||
options.ReportWriter = os.Stderr
|
options.ReportWriter = os.Stderr
|
||||||
|
@ -67,6 +67,10 @@ type CommitOptions struct {
|
|||||||
OnBuild []string
|
OnBuild []string
|
||||||
// Parent is the base image that this image was created by.
|
// Parent is the base image that this image was created by.
|
||||||
Parent string
|
Parent string
|
||||||
|
|
||||||
|
// OmitTimestamp forces epoch 0 as created timestamp to allow for
|
||||||
|
// deterministic, content-addressable builds.
|
||||||
|
OmitTimestamp bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// PushOptions can be used to alter how an image is copied somewhere.
|
// PushOptions can be used to alter how an image is copied somewhere.
|
||||||
@ -140,7 +144,7 @@ func (b *Builder) Commit(ctx context.Context, dest types.ImageReference, options
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
src, err := b.makeImageRef(options.PreferredManifestType, options.Parent, exportBaseLayers, options.Squash, options.BlobDirectory, options.Compression, options.HistoryTimestamp)
|
src, err := b.makeImageRef(options.PreferredManifestType, options.Parent, exportBaseLayers, options.Squash, options.BlobDirectory, options.Compression, options.HistoryTimestamp, options.OmitTimestamp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return imgID, nil, "", errors.Wrapf(err, "error computing layer digests and building metadata for container %q", b.ContainerID)
|
return imgID, nil, "", errors.Wrapf(err, "error computing layer digests and building metadata for container %q", b.ContainerID)
|
||||||
}
|
}
|
||||||
|
@ -317,6 +317,7 @@ return 1
|
|||||||
--rm
|
--rm
|
||||||
--squash
|
--squash
|
||||||
--tls-verify
|
--tls-verify
|
||||||
|
--omit-timestamp
|
||||||
"
|
"
|
||||||
|
|
||||||
local options_with_args="
|
local options_with_args="
|
||||||
|
@ -76,6 +76,14 @@ Squash all of the new image's layers (including those inherited from a base imag
|
|||||||
|
|
||||||
Require HTTPS and verify certificates when talking to container registries (defaults to true)
|
Require HTTPS and verify certificates when talking to container registries (defaults to true)
|
||||||
|
|
||||||
|
**--omit-timestamp** *bool-value*
|
||||||
|
|
||||||
|
Set the create timestamp to epoch 0 to allow for deterministic builds (defaults to false).
|
||||||
|
By default, the created timestamp is changed and written into the image manifest with every commit,
|
||||||
|
causing the image's sha256 hash to be different even if the sources are exactly the same otherwise.
|
||||||
|
When --omit-timestamp is set to true, the created timestamp is always set to the epoch and therefore not
|
||||||
|
changed, allowing the image's sha256 to remain the same.
|
||||||
|
|
||||||
## EXAMPLE
|
## EXAMPLE
|
||||||
|
|
||||||
This example saves an image based on the container.
|
This example saves an image based on the container.
|
||||||
|
6
image.go
6
image.go
@ -635,7 +635,7 @@ func (i *containerImageSource) GetBlob(ctx context.Context, blob types.BlobInfo,
|
|||||||
return ioutils.NewReadCloserWrapper(layerFile, closer), size, nil
|
return ioutils.NewReadCloserWrapper(layerFile, closer), size, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squash bool, blobDirectory string, compress archive.Compression, historyTimestamp *time.Time) (types.ImageReference, error) {
|
func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squash bool, blobDirectory string, compress archive.Compression, historyTimestamp *time.Time, omitTimestamp bool) (types.ImageReference, error) {
|
||||||
var name reference.Named
|
var name reference.Named
|
||||||
container, err := b.store.Container(b.ContainerID)
|
container, err := b.store.Container(b.ContainerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -662,6 +662,10 @@ func (b *Builder) makeImageRef(manifestType, parent string, exporting bool, squa
|
|||||||
created = historyTimestamp.UTC()
|
created = historyTimestamp.UTC()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if omitTimestamp {
|
||||||
|
created = time.Unix(0, 0)
|
||||||
|
}
|
||||||
|
|
||||||
ref := &containerImageRef{
|
ref := &containerImageRef{
|
||||||
store: b.store,
|
store: b.store,
|
||||||
compression: compress,
|
compression: compress,
|
||||||
|
Reference in New Issue
Block a user