diff --git a/pkg/executor/cache_probe_test.go b/pkg/executor/cache_probe_test.go index 86b54848b2..52677a053e 100644 --- a/pkg/executor/cache_probe_test.go +++ b/pkg/executor/cache_probe_test.go @@ -20,6 +20,7 @@ import ( "fmt" "net/http/httptest" "net/url" + "os" "path/filepath" "strings" "testing" @@ -165,6 +166,9 @@ COPY foo/baz.txt copied/ }) t.Run("MultiStage", func(t *testing.T) { + if os.Getuid() != 0 { + t.Skip("this test fails because DoBuild is not running as the root user") + } // Share cache between both builds. regCache := setupCacheRegistry(t) @@ -218,9 +222,13 @@ COPY foo/baz.txt copied/ opts, fn = prepare() defer fn() image2, err := DoCacheProbe(opts) - testutil.CheckNoError(t, err) + if err != nil { + t.Fatalf("cache probe failed: %+v", err) + } digest2, err := image2.Digest() - testutil.CheckNoError(t, err) + if err != nil { + t.Fatalf("digest failed: %+v", err) + } if digest1.String() != digest2.String() { t.Errorf("expected %s, got %s", digest1.String(), digest2.String()) diff --git a/pkg/util/util.go b/pkg/util/util.go index 7501984fbe..97703337ac 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -24,9 +24,7 @@ import ( "io" "math" "os" - "path/filepath" "strconv" - "strings" "sync" "syscall" "time" @@ -97,6 +95,13 @@ type CacheHasherFileInfoSum interface { // CacheHasher takes into account everything the regular hasher does except for mtime func CacheHasher() func(string) (string, error) { + // In order to avoid failing cache probes when a cache probe operation + // is run as a non-root user, we need to pretend that files are owned + // by root. + isRoot := os.Getuid() == 0 + if isRoot { + logrus.Debugf("kaniko running as root: %t", isRoot) + } hasher := func(p string) (string, error) { h := md5.New() fi, err := filesystem.FS.Lstat(p) @@ -114,17 +119,14 @@ func CacheHasher() func(string) (string, error) { h.Write([]byte(fi.Mode().String())) - // Cian: this is a disgusting hack, but it removes the need for the - // envbuilder binary to be owned by root when doing a cache probe. - // We want to ignore UID and GID changes for the envbuilder binary - // specifically. When building and pushing an image using the envbuilder - // image, the embedded envbuilder binary will most likely be owned by - // root:root. However, when performing a cache probe operation, it is more - // likely that the file will be owned by the UID/GID that is running - // envbuilder, which in this case is not guaranteed to be root. - // Let's just pretend that it is, cross our fingers, and hope for the best. - lyingAboutOwnership := !fi.IsDir() && - strings.HasSuffix(filepath.Clean(filepath.Dir(p)), ".envbuilder.tmp") + // Cian: this is a disgusting hack. When building and pushing an image + // using the envbuilder image, the files in .envbuilder will most likely + // be owned by root:root. However, when performing a cache probe operation, + // it is almost certain that the UID/GID that is running the cache probe + // operation is not root. This means that the cache probe operation will + // fail unless we lie about the UID/GID of the files used to build the + // image. + lyingAboutOwnership := !fi.IsDir() && !isRoot if lyingAboutOwnership { h.Write([]byte(strconv.FormatUint(uint64(0), 36))) h.Write([]byte(","))