diff --git a/cmd/executor/cmd/root.go b/cmd/executor/cmd/root.go index 8b60da706..eed04861f 100644 --- a/cmd/executor/cmd/root.go +++ b/cmd/executor/cmd/root.go @@ -174,6 +174,7 @@ func addKanikoOptionsFlags() { RootCmd.PersistentFlags().BoolVarP(&opts.IgnoreVarRun, "whitelist-var-run", "", true, "Ignore /var/run directory when taking image snapshot. Set it to false to preserve /var/run/ in destination image. (Default true).") RootCmd.PersistentFlags().VarP(&opts.Labels, "label", "", "Set metadata for an image. Set it repeatedly for multiple labels.") RootCmd.PersistentFlags().BoolVarP(&opts.SkipUnusedStages, "skip-unused-stages", "", false, "Build only used stages if defined to true. Otherwise it builds by default all stages, even the unnecessaries ones until it reaches the target stage / end of Dockerfile") + RootCmd.PersistentFlags().BoolVarP(&opts.RunV2, "use-new-run", "", false, "Experimental run command to detect file system changes. This new run command does no rely on snapshotting to detect changes.") } // addHiddenFlags marks certain flags as hidden from the executor help text diff --git a/integration/dockerfiles/Dockerfile_test_run_new b/integration/dockerfiles/Dockerfile_test_run_new new file mode 100644 index 000000000..e6aa5ef31 --- /dev/null +++ b/integration/dockerfiles/Dockerfile_test_run_new @@ -0,0 +1,26 @@ +# Copyright 2020 Google, Inc. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +FROM debian:9.11 +RUN echo "hey" > /etc/foo +RUN echo "baz" > /etc/baz +RUN cp /etc/baz /etc/bar +RUN rm /etc/baz + +# Test with ARG +ARG file +RUN echo "run" > $file + +RUN echo "test home" > $HOME/file +COPY context/foo $HOME/foo diff --git a/integration/images.go b/integration/images.go index b149294c8..ea5d1f464 100644 --- a/integration/images.go +++ b/integration/images.go @@ -48,6 +48,7 @@ const ( // Arguments to build Dockerfiles with, used for both docker and kaniko builds var argsMap = map[string][]string{ "Dockerfile_test_run": {"file=/file"}, + "Dockerfile_test_run_new": {"file=/file"}, "Dockerfile_test_run_redo": {"file=/file"}, "Dockerfile_test_workdir": {"workdir=/arg/workdir"}, "Dockerfile_test_add": {"file=context/foo"}, @@ -75,6 +76,7 @@ var additionalDockerFlagsMap = map[string][]string{ // Arguments to build Dockerfiles with when building with kaniko var additionalKanikoFlagsMap = map[string][]string{ "Dockerfile_test_add": {"--single-snapshot"}, + "Dockerfile_test_run_new": {"--use-new-run=true"}, "Dockerfile_test_run_redo": {"--snapshotMode=redo"}, "Dockerfile_test_scratch": {"--single-snapshot"}, "Dockerfile_test_maintainer": {"--single-snapshot"}, diff --git a/pkg/commands/base_command.go b/pkg/commands/base_command.go index 94c4fe156..f42e68e02 100644 --- a/pkg/commands/base_command.go +++ b/pkg/commands/base_command.go @@ -51,3 +51,7 @@ func (b *BaseCommand) RequiresUnpackedFS() bool { func (b *BaseCommand) ShouldCacheOutput() bool { return false } + +func (b *BaseCommand) ShouldDetectDeletedFiles() bool { + return false +} diff --git a/pkg/commands/commands.go b/pkg/commands/commands.go index 0a4e57134..44139093f 100644 --- a/pkg/commands/commands.go +++ b/pkg/commands/commands.go @@ -52,11 +52,17 @@ type DockerCommand interface { RequiresUnpackedFS() bool ShouldCacheOutput() bool + + // ShouldDetectDeletedFiles returns true if the command could delete files. + ShouldDetectDeletedFiles() bool } -func GetCommand(cmd instructions.Command, buildcontext string) (DockerCommand, error) { +func GetCommand(cmd instructions.Command, buildcontext string, useNewRun bool) (DockerCommand, error) { switch c := cmd.(type) { case *instructions.RunCommand: + if useNewRun { + return &RunMarkerCommand{cmd: c}, nil + } return &RunCommand{cmd: c}, nil case *instructions.CopyCommand: return &CopyCommand{cmd: c, buildcontext: buildcontext}, nil diff --git a/pkg/commands/run.go b/pkg/commands/run.go index e0dd1beef..b99461eaa 100644 --- a/pkg/commands/run.go +++ b/pkg/commands/run.go @@ -46,8 +46,12 @@ var ( ) func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error { + return runCommandInExec(config, buildArgs, r.cmd) +} + +func runCommandInExec(config *v1.Config, buildArgs *dockerfile.BuildArgs, cmdRun *instructions.RunCommand) error { var newCommand []string - if r.cmd.PrependShell { + if cmdRun.PrependShell { // This is the default shell on Linux var shell []string if len(config.Shell) > 0 { @@ -56,9 +60,9 @@ func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui shell = append(shell, "/bin/sh", "-c") } - newCommand = append(shell, strings.Join(r.cmd.CmdLine, " ")) + newCommand = append(shell, strings.Join(cmdRun.CmdLine, " ")) } else { - newCommand = r.cmd.CmdLine + newCommand = cmdRun.CmdLine } logrus.Infof("cmd: %s", newCommand[0]) @@ -111,7 +115,6 @@ func (r *RunCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui if err := syscall.Kill(-pgid, syscall.SIGKILL); err != nil && err.Error() != "no such process" { return err } - return nil } diff --git a/pkg/commands/run_marker.go b/pkg/commands/run_marker.go new file mode 100644 index 000000000..8d67160bf --- /dev/null +++ b/pkg/commands/run_marker.go @@ -0,0 +1,108 @@ +/* +Copyright 2018 Google LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package commands + +import ( + "fmt" + "io/ioutil" + "os" + "time" + + "github.com/GoogleContainerTools/kaniko/pkg/dockerfile" + "github.com/GoogleContainerTools/kaniko/pkg/util" + v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/moby/buildkit/frontend/dockerfile/instructions" + "github.com/sirupsen/logrus" +) + +type RunMarkerCommand struct { + BaseCommand + cmd *instructions.RunCommand + Files []string +} + +func (r *RunMarkerCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error { + // run command `touch filemarker` + logrus.Debugf("using new RunMarker command") + markerFile, err := ioutil.TempFile("", "marker") + if err != nil { + return fmt.Errorf("could not place a marker file") + } + defer func() { + os.Remove(markerFile.Name()) + }() + markerInfo, err := os.Stat(markerFile.Name()) + if err != nil { + return fmt.Errorf("could not place a marker file") + } + // introduce a delay + time.Sleep(time.Second) + if err := runCommandInExec(config, buildArgs, r.cmd); err != nil { + return err + } + + // run command find to find all new files generate + isNewer := func(p string) (bool, error) { + fi, err := os.Stat(p) + if err != nil { + return false, err + } + return fi.ModTime().After(markerInfo.ModTime()), nil + } + r.Files, _ = util.WalkFS("/", map[string]struct{}{}, isNewer) + logrus.Debugf("files changed %s", r.Files) + return nil +} + +// String returns some information about the command for the image config +func (r *RunMarkerCommand) String() string { + return r.cmd.String() +} + +func (r *RunMarkerCommand) FilesToSnapshot() []string { + return r.Files +} + +func (r *RunMarkerCommand) ProvidesFilesToSnapshot() bool { + return true +} + +// CacheCommand returns true since this command should be cached +func (r *RunMarkerCommand) CacheCommand(img v1.Image) DockerCommand { + + return &CachingRunCommand{ + img: img, + cmd: r.cmd, + extractFn: util.ExtractFile, + } +} + +func (r *RunMarkerCommand) MetadataOnly() bool { + return false +} + +func (r *RunMarkerCommand) RequiresUnpackedFS() bool { + return true +} + +func (r *RunMarkerCommand) ShouldCacheOutput() bool { + return true +} + +func (r *RunMarkerCommand) ShouldDetectDeletedFiles() bool { + return true +} diff --git a/pkg/config/options.go b/pkg/config/options.go index 576d42f09..74db79b6f 100644 --- a/pkg/config/options.go +++ b/pkg/config/options.go @@ -57,6 +57,7 @@ type KanikoOptions struct { Cleanup bool IgnoreVarRun bool SkipUnusedStages bool + RunV2 bool } // WarmerOptions are options that are set by command line arguments to the cache warmer. diff --git a/pkg/executor/build.go b/pkg/executor/build.go index 87c8cad43..38d6471a5 100644 --- a/pkg/executor/build.go +++ b/pkg/executor/build.go @@ -62,7 +62,7 @@ type cachePusher func(*config.KanikoOptions, string, string, string) error type snapShotter interface { Init() error TakeSnapshotFS() (string, error) - TakeSnapshot([]string) (string, error) + TakeSnapshot([]string, bool) (string, error) } // stageBuilder contains all fields necessary to build one stage of a Dockerfile @@ -127,7 +127,7 @@ func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, cross } for _, cmd := range s.stage.Commands { - command, err := commands.GetCommand(cmd, opts.SrcContext) + command, err := commands.GetCommand(cmd, opts.SrcContext, opts.RunV2) if err != nil { return nil, err } @@ -319,7 +319,7 @@ func (s *stageBuilder) build() error { } initSnapshotTaken := false - if s.opts.SingleSnapshot { + if s.opts.SingleSnapshot || s.opts.RunV2 { if err := s.initSnapshotWithTimings(); err != nil { return err } @@ -372,7 +372,7 @@ func (s *stageBuilder) build() error { files = command.FilesToSnapshot() timing.DefaultRun.Stop(t) - if !s.shouldTakeSnapshot(index, files, command.ProvidesFilesToSnapshot()) { + if !s.shouldTakeSnapshot(index, command.MetadataOnly()) { continue } if isCacheCommand { @@ -382,7 +382,7 @@ func (s *stageBuilder) build() error { return errors.Wrap(err, "failed to save layer") } } else { - tarPath, err := s.takeSnapshot(files) + tarPath, err := s.takeSnapshot(files, command.ShouldDetectDeletedFiles()) if err != nil { return errors.Wrap(err, "failed to take snapshot") } @@ -416,7 +416,7 @@ func (s *stageBuilder) build() error { return nil } -func (s *stageBuilder) takeSnapshot(files []string) (string, error) { +func (s *stageBuilder) takeSnapshot(files []string, shdDelete bool) (string, error) { var snapshot string var err error @@ -426,13 +426,13 @@ func (s *stageBuilder) takeSnapshot(files []string) (string, error) { } else { // Volumes are very weird. They get snapshotted in the next command. files = append(files, util.Volumes()...) - snapshot, err = s.snapshotter.TakeSnapshot(files) + snapshot, err = s.snapshotter.TakeSnapshot(files, shdDelete) } timing.DefaultRun.Stop(t) return snapshot, err } -func (s *stageBuilder) shouldTakeSnapshot(index int, files []string, provideFiles bool) bool { +func (s *stageBuilder) shouldTakeSnapshot(index int, isMetadatCmd bool) bool { isLastCommand := index == len(s.cmds)-1 // We only snapshot the very end with single snapshot mode on. @@ -445,17 +445,8 @@ func (s *stageBuilder) shouldTakeSnapshot(index int, files []string, provideFile return true } - // if command does not provide files, snapshot everything. - if !provideFiles { - return true - } - - // Don't snapshot an empty list. - if len(files) == 0 { - return false - } - - return true + // if command is a metadata command, do not snapshot. + return !isMetadatCmd } func (s *stageBuilder) saveSnapshotToImage(createdBy string, tarPath string) error { diff --git a/pkg/executor/build_test.go b/pkg/executor/build_test.go index dd1a377ce..00631ccca 100644 --- a/pkg/executor/build_test.go +++ b/pkg/executor/build_test.go @@ -103,9 +103,8 @@ func Test_stageBuilder_shouldTakeSnapshot(t *testing.T) { cmds []commands.DockerCommand } type args struct { - index int - files []string - hasFiles bool + index int + metadataOnly bool } tests := []struct { name string @@ -158,9 +157,8 @@ func Test_stageBuilder_shouldTakeSnapshot(t *testing.T) { stage: config.KanikoStage{}, }, args: args{ - index: 0, - files: []string{}, - hasFiles: true, + index: 0, + metadataOnly: true, }, want: false, }, @@ -172,9 +170,8 @@ func Test_stageBuilder_shouldTakeSnapshot(t *testing.T) { }, }, args: args{ - index: 0, - files: nil, - hasFiles: false, + index: 0, + metadataOnly: false, }, want: true, }, @@ -204,7 +201,7 @@ func Test_stageBuilder_shouldTakeSnapshot(t *testing.T) { opts: tt.fields.opts, cmds: tt.fields.cmds, } - if got := s.shouldTakeSnapshot(tt.args.index, tt.args.files, tt.args.hasFiles); got != tt.want { + if got := s.shouldTakeSnapshot(tt.args.index, tt.args.metadataOnly); got != tt.want { t.Errorf("stageBuilder.shouldTakeSnapshot() = %v, want %v", got, tt.want) } }) @@ -1246,6 +1243,7 @@ func getCommands(dir string, cmds []instructions.Command) []commands.DockerComma cmd, err := commands.GetCommand( c, dir, + false, ) if err != nil { panic(err) diff --git a/pkg/executor/fakes.go b/pkg/executor/fakes.go index 41793af12..193396f31 100644 --- a/pkg/executor/fakes.go +++ b/pkg/executor/fakes.go @@ -38,7 +38,7 @@ func (f fakeSnapShotter) Init() error { return nil } func (f fakeSnapShotter) TakeSnapshotFS() (string, error) { return f.tarPath, nil } -func (f fakeSnapShotter) TakeSnapshot(_ []string) (string, error) { +func (f fakeSnapShotter) TakeSnapshot(_ []string, _ bool) (string, error) { return f.tarPath, nil } @@ -73,6 +73,9 @@ func (m MockDockerCommand) RequiresUnpackedFS() bool { func (m MockDockerCommand) ShouldCacheOutput() bool { return true } +func (m MockDockerCommand) ShouldDetectDeletedFiles() bool { + return false +} type MockCachedDockerCommand struct { contextFiles []string @@ -93,6 +96,9 @@ func (m MockCachedDockerCommand) ProvidesFilesToSnapshot() bool { func (m MockCachedDockerCommand) CacheCommand(image v1.Image) commands.DockerCommand { return nil } +func (m MockCachedDockerCommand) ShouldDetectDeletedFiles() bool { + return false +} func (m MockCachedDockerCommand) FilesUsedFromContext(c *v1.Config, args *dockerfile.BuildArgs) ([]string, error) { return m.contextFiles, nil } diff --git a/pkg/snapshot/layered_map.go b/pkg/snapshot/layered_map.go index 49bff0101..976ad19d1 100644 --- a/pkg/snapshot/layered_map.go +++ b/pkg/snapshot/layered_map.go @@ -31,7 +31,7 @@ import ( type LayeredMap struct { layers []map[string]string - whiteouts []map[string]string + whiteouts []map[string]struct{} layerHashCache map[string]string hasher func(string) (string, error) // cacheHasher doesn't include mtime in it's hash so that filesystem cache keys are stable @@ -49,7 +49,7 @@ func NewLayeredMap(h func(string) (string, error), c func(string) (string, error } func (l *LayeredMap) Snapshot() { - l.whiteouts = append(l.whiteouts, map[string]string{}) + l.whiteouts = append(l.whiteouts, map[string]struct{}{}) l.layers = append(l.layers, map[string]string{}) } @@ -84,21 +84,21 @@ func (l *LayeredMap) Get(s string) (string, bool) { return "", false } -func (l *LayeredMap) GetWhiteout(s string) (string, bool) { +func (l *LayeredMap) GetWhiteout(s string) bool { for i := len(l.whiteouts) - 1; i >= 0; i-- { - if v, ok := l.whiteouts[i][s]; ok { - return v, ok + if _, ok := l.whiteouts[i][s]; ok { + return ok } } - return "", false + return false } func (l *LayeredMap) MaybeAddWhiteout(s string) bool { - whiteout, ok := l.GetWhiteout(s) - if ok && whiteout == s { + ok := l.GetWhiteout(s) + if ok { return false } - l.whiteouts[len(l.whiteouts)-1][s] = s + l.whiteouts[len(l.whiteouts)-1][s] = struct{}{} return true } diff --git a/pkg/snapshot/snapshot.go b/pkg/snapshot/snapshot.go index 783d83083..e8523d4e3 100644 --- a/pkg/snapshot/snapshot.go +++ b/pkg/snapshot/snapshot.go @@ -24,13 +24,11 @@ import ( "sort" "syscall" + "github.com/GoogleContainerTools/kaniko/pkg/config" "github.com/GoogleContainerTools/kaniko/pkg/filesystem" "github.com/GoogleContainerTools/kaniko/pkg/timing" - "github.com/karrick/godirwalk" - - "github.com/GoogleContainerTools/kaniko/pkg/config" - "github.com/GoogleContainerTools/kaniko/pkg/util" + "github.com/sirupsen/logrus" ) @@ -62,7 +60,7 @@ func (s *Snapshotter) Key() (string, error) { // TakeSnapshot takes a snapshot of the specified files, avoiding directories in the ignorelist, and creates // a tarball of the changed files. Return contents of the tarball, and whether or not any files were changed -func (s *Snapshotter) TakeSnapshot(files []string) (string, error) { +func (s *Snapshotter) TakeSnapshot(files []string, shdCheckDelete bool) (string, error) { f, err := ioutil.TempFile(config.KanikoDir, "") if err != nil { return "", err @@ -81,7 +79,7 @@ func (s *Snapshotter) TakeSnapshot(files []string) (string, error) { } logrus.Info("Taking snapshot of files...") - logrus.Debugf("Taking snapshot of files %v", files) + logrus.Debugf("Taking snapshot of files %v", filesToAdd) sort.Strings(filesToAdd) @@ -92,9 +90,27 @@ func (s *Snapshotter) TakeSnapshot(files []string) (string, error) { } } + // Get whiteout paths + filesToWhiteout := []string{} + if shdCheckDelete { + _, deletedFiles := util.WalkFS(s.directory, s.l.getFlattenedPathsForWhiteOut(), func(s string) (bool, error) { + return true, nil + }) + // The paths left here are the ones that have been deleted in this layer. + for path := range deletedFiles { + // Only add the whiteout if the directory for the file still exists. + dir := filepath.Dir(path) + if _, ok := deletedFiles[dir]; !ok { + if s.l.MaybeAddWhiteout(path) { + logrus.Debugf("Adding whiteout for %s", path) + filesToWhiteout = append(filesToWhiteout, path) + } + } + } + } t := util.NewTar(f) defer t.Close() - if err := writeToTar(t, filesToAdd, nil); err != nil { + if err := writeToTar(t, filesToAdd, filesToWhiteout); err != nil { return "", err } return f.Name(), nil @@ -133,36 +149,8 @@ func (s *Snapshotter) scanFullFilesystem() ([]string, []string, error) { s.l.Snapshot() - timer := timing.Start("Walking filesystem") - - changedPaths := make([]string, 0) - - // Get a list of all the files that existed before this layer - existingPaths := s.l.getFlattenedPathsForWhiteOut() - - godirwalk.Walk(s.directory, &godirwalk.Options{ - Callback: func(path string, ent *godirwalk.Dirent) error { - if util.IsInIgnoreList(path) { - if util.IsDestDir(path) { - logrus.Tracef("Skipping paths under %s, as it is a ignored directory", path) - return filepath.SkipDir - } - - return nil - } - if ok, err := s.l.CheckFileChange(path); err != nil { - return err - } else if ok { - changedPaths = append(changedPaths, path) - } - delete(existingPaths, path) - return nil - }, - Unsorted: true, - }, - ) - timing.DefaultRun.Stop(timer) - timer = timing.Start("Resolving Paths") + changedPaths, deletedPaths := util.WalkFS(s.directory, s.l.getFlattenedPathsForWhiteOut(), s.l.CheckFileChange) + timer := timing.Start("Resolving Paths") filesToAdd := []string{} resolvedFiles, err := filesystem.ResolvePaths(changedPaths, s.ignorelist) @@ -179,10 +167,10 @@ func (s *Snapshotter) scanFullFilesystem() ([]string, []string, error) { // The paths left here are the ones that have been deleted in this layer. filesToWhiteOut := []string{} - for path := range existingPaths { + for path := range deletedPaths { // Only add the whiteout if the directory for the file still exists. dir := filepath.Dir(path) - if _, ok := existingPaths[dir]; !ok { + if _, ok := deletedPaths[dir]; !ok { if s.l.MaybeAddWhiteout(path) { logrus.Debugf("Adding whiteout for %s", path) filesToWhiteOut = append(filesToWhiteOut, path) diff --git a/pkg/snapshot/snapshot_test.go b/pkg/snapshot/snapshot_test.go index abe211038..7150ae0c4 100644 --- a/pkg/snapshot/snapshot_test.go +++ b/pkg/snapshot/snapshot_test.go @@ -214,7 +214,7 @@ func TestSnapshotFiles(t *testing.T) { filesToSnapshot := []string{ filepath.Join(testDir, "foo"), } - tarPath, err := snapshotter.TakeSnapshot(filesToSnapshot) + tarPath, err := snapshotter.TakeSnapshot(filesToSnapshot, false) if err != nil { t.Fatal(err) } @@ -361,7 +361,7 @@ func TestSnasphotPreservesFileOrder(t *testing.T) { } // Take a snapshot - tarPath, err := snapshotter.TakeSnapshot(filesToSnapshot) + tarPath, err := snapshotter.TakeSnapshot(filesToSnapshot, false) if err != nil { t.Fatalf("Error taking snapshot of fs: %s", err) diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index d957e64be..9a34f2974 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -31,14 +31,16 @@ import ( "syscall" "time" - otiai10Cpy "github.com/otiai10/copy" - - "github.com/GoogleContainerTools/kaniko/pkg/config" "github.com/docker/docker/builder/dockerignore" "github.com/docker/docker/pkg/fileutils" v1 "github.com/google/go-containerregistry/pkg/v1" + "github.com/karrick/godirwalk" + otiai10Cpy "github.com/otiai10/copy" "github.com/pkg/errors" "github.com/sirupsen/logrus" + + "github.com/GoogleContainerTools/kaniko/pkg/config" + "github.com/GoogleContainerTools/kaniko/pkg/timing" ) const DoNotChangeUID = -1 @@ -875,3 +877,31 @@ func UpdateInitialIgnoreList(ignoreVarRun bool) { PrefixMatchOnly: false, }) } + +func WalkFS(dir string, existingPaths map[string]struct{}, f func(string) (bool, error)) ([]string, map[string]struct{}) { + foundPaths := make([]string, 0) + timer := timing.Start("Walking filesystem") + godirwalk.Walk(dir, &godirwalk.Options{ + Callback: func(path string, ent *godirwalk.Dirent) error { + if IsInIgnoreList(path) { + if IsDestDir(path) { + logrus.Tracef("Skipping paths under %s, as it is a ignored directory", path) + return filepath.SkipDir + } + + return nil + } + delete(existingPaths, path) + if t, err := f(path); err != nil { + return err + } else if t { + foundPaths = append(foundPaths, path) + } + return nil + }, + Unsorted: true, + }, + ) + timing.DefaultRun.Stop(timer) + return foundPaths, existingPaths +} diff --git a/scripts/misc-integration-test.sh b/scripts/misc-integration-test.sh index b989152b3..93f6df8d6 100755 --- a/scripts/misc-integration-test.sh +++ b/scripts/misc-integration-test.sh @@ -19,7 +19,7 @@ set -e TESTS=$(./scripts/integration-test.sh -list=Test -mod=vendor) -TESTS=$(echo $TESTS | tr ' ' '\n' | grep 'Test'| grep -v 'TestRun' | grep -v 'TestLayers' | grep -v 'TestK8s') +TESTS=$(echo $TESTS | tr ' ' '\n' | grep 'Test'| grep -v 'TestRun' | grep -v 'TestLayers' | grep -v 'TestK8s' | grep -v 'TestSnapshotBenchmark') RUN_ARG='' count=0