diff --git a/executor/cmd/root.go b/executor/cmd/root.go index 80b2c088f..a9244d701 100644 --- a/executor/cmd/root.go +++ b/executor/cmd/root.go @@ -33,6 +33,7 @@ var ( dockerfilePath string destination string srcContext string + mtime bool logLevel string ) @@ -40,6 +41,7 @@ func init() { RootCmd.PersistentFlags().StringVarP(&dockerfilePath, "dockerfile", "f", "/workspace/Dockerfile", "Path to the dockerfile to be built.") RootCmd.PersistentFlags().StringVarP(&srcContext, "context", "c", "", "Path to the dockerfile build context.") RootCmd.PersistentFlags().StringVarP(&destination, "destination", "d", "", "Registry the final image should be pushed to (ex: gcr.io/test/example:latest)") + RootCmd.PersistentFlags().BoolVarP(&mtime, "mtime", "", false, "Only look at mtime of a file when snapshotting") RootCmd.PersistentFlags().StringVarP(&logLevel, "verbosity", "v", constants.DefaultLogLevel, "Log level (debug, info, warn, error, fatal, panic") } @@ -74,8 +76,12 @@ func execute() error { if err := util.ExtractFileSystemFromImage(baseImage); err != nil { return err } - - l := snapshot.NewLayeredMap(util.Hasher()) + hasher := util.Hasher() + if mtime { + logrus.Info("Only file modification times will be considered when snapshotting.") + hasher = util.MtimeHasher() + } + l := snapshot.NewLayeredMap(hasher) snapshotter := snapshot.NewSnapshotter(l, constants.RootDir) // Take initial snapshot diff --git a/integration_tests/integration_test_yaml.go b/integration_tests/integration_test_yaml.go index 3129456ff..39ade9f14 100644 --- a/integration_tests/integration_test_yaml.go +++ b/integration_tests/integration_test_yaml.go @@ -28,6 +28,7 @@ var fileTests = []struct { configPath string context string repo string + mtime bool }{ { description: "test extract filesystem", @@ -35,6 +36,7 @@ var fileTests = []struct { configPath: "/workspace/integration_tests/dockerfiles/config_test_extract_fs.json", context: "integration_tests/dockerfiles/", repo: "extract-filesystem", + mtime: true, }, { description: "test run", @@ -49,6 +51,7 @@ var fileTests = []struct { configPath: "/workspace/integration_tests/dockerfiles/config_test_run_2.json", context: "integration_tests/dockerfiles/", repo: "test-run-2", + mtime: true, }, { description: "test copy", @@ -56,6 +59,7 @@ var fileTests = []struct { configPath: "/workspace/integration_tests/dockerfiles/config_test_copy.json", context: "/workspace/integration_tests/", repo: "test-copy", + mtime: true, }, } @@ -139,9 +143,13 @@ func main() { // Then, buld the image with kbuild kbuildImage := testRepo + kbuildPrefix + test.repo + mtime := "" + if test.mtime { + mtime = "--mtime" + } kbuild := step{ Name: executorImage, - Args: []string{executorCommand, "--destination", kbuildImage, "--dockerfile", test.dockerfilePath, "--context", test.context}, + Args: []string{executorCommand, "--destination", kbuildImage, "--dockerfile", test.dockerfilePath, "--context", test.context, mtime}, } // Pull the kbuild image diff --git a/pkg/util/util.go b/pkg/util/util.go index f27ebba5a..2e4a08851 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -61,3 +61,17 @@ func Hasher() func(string) (string, error) { } return hasher } + +// Hasher returns a hash function, which only looks at mtime to determine if a file has changed +func MtimeHasher() func(string) (string, error) { + hasher := func(p string) (string, error) { + h := md5.New() + fi, err := os.Lstat(p) + if err != nil { + return "", err + } + h.Write([]byte(fi.ModTime().String())) + return hex.EncodeToString(h.Sum(nil)), nil + } + return hasher +}