build: Fix the ModTime for files created during build

When creating files for the "intermediate" tar ball,
fix the ModTime. This reduces the difference between
LinuxKit images build from identical inputs.

Signed-off-by: Rolf Neugebauer <rn@rneugeba.io>
This commit is contained in:
Rolf Neugebauer 2018-12-22 16:52:48 +00:00
parent 1616b18fb0
commit 02579b22e5
4 changed files with 83 additions and 57 deletions

View File

@ -51,10 +51,11 @@ var additions = map[string]addFun{
"docker": func(tw *tar.Writer) error { "docker": func(tw *tar.Writer) error {
log.Infof(" Adding Dockerfile") log.Infof(" Adding Dockerfile")
hdr := &tar.Header{ hdr := &tar.Header{
Name: "Dockerfile", Name: "Dockerfile",
Mode: 0644, Mode: 0644,
Size: int64(len(dockerfile)), Size: int64(len(dockerfile)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -368,6 +369,7 @@ func (k *kernelFilter) WriteHeader(hdr *tar.Header) error {
Name: "boot", Name: "boot",
Mode: 0755, Mode: 0755,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
ModTime: defaultModTime,
Format: tar.FormatPAX, Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(whdr); err != nil { if err := tw.WriteHeader(whdr); err != nil {
@ -376,10 +378,11 @@ func (k *kernelFilter) WriteHeader(hdr *tar.Header) error {
} }
// add the cmdline in /boot/cmdline // add the cmdline in /boot/cmdline
whdr := &tar.Header{ whdr := &tar.Header{
Name: "boot/cmdline", Name: "boot/cmdline",
Mode: 0644, Mode: 0644,
Size: int64(len(k.cmdline)), Size: int64(len(k.cmdline)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(whdr); err != nil { if err := tw.WriteHeader(whdr); err != nil {
return err return err
@ -391,10 +394,11 @@ func (k *kernelFilter) WriteHeader(hdr *tar.Header) error {
} }
// Stash the kernel header and prime the buffer for the kernel // Stash the kernel header and prime the buffer for the kernel
k.hdr = &tar.Header{ k.hdr = &tar.Header{
Name: "boot/kernel", Name: "boot/kernel",
Mode: hdr.Mode, Mode: hdr.Mode,
Size: hdr.Size, Size: hdr.Size,
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
k.buffer = new(bytes.Buffer) k.buffer = new(bytes.Buffer)
case k.tar: case k.tar:
@ -410,6 +414,7 @@ func (k *kernelFilter) WriteHeader(hdr *tar.Header) error {
Name: "boot", Name: "boot",
Mode: 0755, Mode: 0755,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
ModTime: defaultModTime,
Format: tar.FormatPAX, Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(whdr); err != nil { if err := tw.WriteHeader(whdr); err != nil {
@ -417,10 +422,11 @@ func (k *kernelFilter) WriteHeader(hdr *tar.Header) error {
} }
} }
whdr := &tar.Header{ whdr := &tar.Header{
Name: "boot/ucode.cpio", Name: "boot/ucode.cpio",
Mode: hdr.Mode, Mode: hdr.Mode,
Size: hdr.Size, Size: hdr.Size,
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(whdr); err != nil { if err := tw.WriteHeader(whdr); err != nil {
return err return err
@ -653,6 +659,7 @@ func filesystem(m Moby, tw *tar.Writer, idMap map[string]uint32) error {
Name: root, Name: root,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
Mode: dirMode, Mode: dirMode,
ModTime: defaultModTime,
Uid: int(uid), Uid: int(uid),
Gid: int(gid), Gid: int(gid),
Format: tar.FormatPAX, Format: tar.FormatPAX,
@ -666,11 +673,12 @@ func filesystem(m Moby, tw *tar.Writer, idMap map[string]uint32) error {
} }
addedFiles[f.Path] = true addedFiles[f.Path] = true
hdr := &tar.Header{ hdr := &tar.Header{
Name: f.Path, Name: f.Path,
Mode: mode, Mode: mode,
Uid: int(uid), ModTime: defaultModTime,
Gid: int(gid), Uid: int(uid),
Format: tar.FormatPAX, Gid: int(gid),
Format: tar.FormatPAX,
} }
if f.Directory { if f.Directory {
if f.Contents != nil { if f.Contents != nil {

View File

@ -71,6 +71,7 @@ func tarPrefix(path string, tw tarWriter) error {
hdr := &tar.Header{ hdr := &tar.Header{
Name: mkdir, Name: mkdir,
Mode: 0755, Mode: 0755,
ModTime: defaultModTime,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
Format: tar.FormatPAX, Format: tar.FormatPAX,
} }
@ -154,6 +155,7 @@ func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull
contents := replace[hdr.Name] contents := replace[hdr.Name]
hdr.Size = int64(len(contents)) hdr.Size = int64(len(contents))
hdr.Name = prefix + hdr.Name hdr.Name = prefix + hdr.Name
hdr.ModTime = defaultModTime
log.Debugf("image tar: %s %s add %s", ref, prefix, hdr.Name) log.Debugf("image tar: %s %s add %s", ref, prefix, hdr.Name)
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -169,6 +171,7 @@ func ImageTar(ref *reference.Spec, prefix string, tw tarWriter, trust bool, pull
hdr.Size = 0 hdr.Size = 0
hdr.Typeflag = tar.TypeSymlink hdr.Typeflag = tar.TypeSymlink
hdr.Linkname = resolv hdr.Linkname = resolv
hdr.ModTime = defaultModTime
log.Debugf("image tar: %s %s add resolv symlink /etc/resolv.conf -> %s", ref, prefix, resolv) log.Debugf("image tar: %s %s add resolv symlink /etc/resolv.conf -> %s", ref, prefix, resolv)
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -221,10 +224,11 @@ func ImageBundle(prefix string, ref *reference.Spec, config []byte, runtime Runt
} }
hdr := &tar.Header{ hdr := &tar.Header{
Name: path.Join(prefix, "config.json"), Name: path.Join(prefix, "config.json"),
Mode: 0644, Mode: 0644,
Size: int64(len(config)), Size: int64(len(config)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -242,6 +246,7 @@ func ImageBundle(prefix string, ref *reference.Spec, config []byte, runtime Runt
Name: tmp, Name: tmp,
Mode: 0755, Mode: 0755,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
ModTime: defaultModTime,
Format: tar.FormatPAX, Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
@ -252,6 +257,7 @@ func ImageBundle(prefix string, ref *reference.Spec, config []byte, runtime Runt
Name: path.Join(prefix, "rootfs"), Name: path.Join(prefix, "rootfs"),
Mode: 0755, Mode: 0755,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
ModTime: defaultModTime,
Format: tar.FormatPAX, Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
@ -271,6 +277,7 @@ func ImageBundle(prefix string, ref *reference.Spec, config []byte, runtime Runt
Name: path.Join(prefix, "rootfs"), Name: path.Join(prefix, "rootfs"),
Mode: 0755, Mode: 0755,
Typeflag: tar.TypeDir, Typeflag: tar.TypeDir,
ModTime: defaultModTime,
Format: tar.FormatPAX, Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
@ -294,10 +301,11 @@ func ImageBundle(prefix string, ref *reference.Spec, config []byte, runtime Runt
} }
hdr = &tar.Header{ hdr = &tar.Header{
Name: path.Join(prefix, "runtime.json"), Name: path.Join(prefix, "runtime.json"),
Mode: 0644, Mode: 0644,
Size: int64(len(runtimeConfig)), Size: int64(len(runtimeConfig)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err

View File

@ -281,10 +281,11 @@ func tarInitrdKernel(kernel, initrd []byte, cmdline string) (*bytes.Buffer, erro
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
tw := tar.NewWriter(buf) tw := tar.NewWriter(buf)
hdr := &tar.Header{ hdr := &tar.Header{
Name: "kernel", Name: "kernel",
Mode: 0600, Mode: 0600,
Size: int64(len(kernel)), Size: int64(len(kernel)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
err := tw.WriteHeader(hdr) err := tw.WriteHeader(hdr)
if err != nil { if err != nil {
@ -295,10 +296,11 @@ func tarInitrdKernel(kernel, initrd []byte, cmdline string) (*bytes.Buffer, erro
return buf, err return buf, err
} }
hdr = &tar.Header{ hdr = &tar.Header{
Name: "initrd.img", Name: "initrd.img",
Mode: 0600, Mode: 0600,
Size: int64(len(initrd)), Size: int64(len(initrd)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
err = tw.WriteHeader(hdr) err = tw.WriteHeader(hdr)
if err != nil { if err != nil {
@ -309,10 +311,11 @@ func tarInitrdKernel(kernel, initrd []byte, cmdline string) (*bytes.Buffer, erro
return buf, err return buf, err
} }
hdr = &tar.Header{ hdr = &tar.Header{
Name: "cmdline", Name: "cmdline",
Mode: 0600, Mode: 0600,
Size: int64(len(cmdline)), Size: int64(len(cmdline)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
err = tw.WriteHeader(hdr) err = tw.WriteHeader(hdr)
if err != nil { if err != nil {
@ -410,10 +413,11 @@ func outputKernelInitrdTarball(base string, kernel []byte, initrd []byte, cmdlin
tw := tar.NewWriter(f) tw := tar.NewWriter(f)
if len(kernel) != 0 { if len(kernel) != 0 {
hdr := &tar.Header{ hdr := &tar.Header{
Name: "kernel", Name: "kernel",
Mode: 0644, Mode: 0644,
Size: int64(len(kernel)), Size: int64(len(kernel)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -424,10 +428,11 @@ func outputKernelInitrdTarball(base string, kernel []byte, initrd []byte, cmdlin
} }
if len(initrd) != 0 { if len(initrd) != 0 {
hdr := &tar.Header{ hdr := &tar.Header{
Name: "initrd.img", Name: "initrd.img",
Mode: 0644, Mode: 0644,
Size: int64(len(initrd)), Size: int64(len(initrd)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -438,10 +443,11 @@ func outputKernelInitrdTarball(base string, kernel []byte, initrd []byte, cmdlin
} }
if len(cmdline) != 0 { if len(cmdline) != 0 {
hdr := &tar.Header{ hdr := &tar.Header{
Name: "cmdline", Name: "cmdline",
Mode: 0644, Mode: 0644,
Size: int64(len(cmdline)), Size: int64(len(cmdline)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err
@ -452,10 +458,11 @@ func outputKernelInitrdTarball(base string, kernel []byte, initrd []byte, cmdlin
} }
if len(ucode) != 0 { if len(ucode) != 0 {
hdr := &tar.Header{ hdr := &tar.Header{
Name: "ucode.cpio", Name: "ucode.cpio",
Mode: 0644, Mode: 0644,
Size: int64(len(ucode)), Size: int64(len(ucode)),
Format: tar.FormatPAX, ModTime: defaultModTime,
Format: tar.FormatPAX,
} }
if err := tw.WriteHeader(hdr); err != nil { if err := tw.WriteHeader(hdr); err != nil {
return err return err

View File

@ -2,11 +2,14 @@ package moby
import ( import (
"path/filepath" "path/filepath"
"time"
) )
var ( var (
// MobyDir is the location of the cache directory, defaults to ~/.moby // MobyDir is the location of the cache directory, defaults to ~/.moby
MobyDir string MobyDir string
// Default ModTime for files created during build. Roughly the time LinuxKit got open sourced.
defaultModTime = time.Date(2017, time.April, 18, 16, 30, 0, 0, time.UTC)
) )
func defaultMobyConfigDir() string { func defaultMobyConfigDir() string {