From d9771d8237c797e1a1e2fc91ae8ad04b8eb5e9bf Mon Sep 17 00:00:00 2001 From: Aaron Prindle Date: Tue, 20 Jun 2023 22:15:23 +0000 Subject: [PATCH] fix: resolve issue around copying root --- .../issue-960/Dockerfile | 39 +++++++++++++++++++ pkg/util/fs_util.go | 36 ++++++++++++++++- pkg/util/fs_util_test.go | 10 +++++ 3 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 integration/dockerfiles-with-context/issue-960/Dockerfile diff --git a/integration/dockerfiles-with-context/issue-960/Dockerfile b/integration/dockerfiles-with-context/issue-960/Dockerfile new file mode 100644 index 0000000000..055e3e3c37 --- /dev/null +++ b/integration/dockerfiles-with-context/issue-960/Dockerfile @@ -0,0 +1,39 @@ +# Copyright 2023 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 alpine:3.14 as rootfs + +FROM alpine:3.14 + +RUN mkdir -p /sysroot +COPY --from=rootfs / /sysroot/ + +# Workaround: we must remove some files to pass the integration test. +# Unlike Docker, kaniko has no access to the original layer data from the +# building context and can't preserve them in their original form. +RUN rm -f \ + /sysroot/etc/hostname \ + /sysroot/etc/hosts \ + /sysroot/etc/mtab \ + /sysroot/etc/nsswitch.conf + +# Additional check for preserved dirs. They must persist in image but be empty. +RUN printf "%s\n" \ + "/sysroot/dev/:" \ + "" \ + "/sysroot/sys/:" \ + > /tmp/expected \ + && ls -1 /sysroot/dev/ /sysroot/sys/ \ + > /tmp/got \ + && diff -u /tmp/got /tmp/expected \ No newline at end of file diff --git a/pkg/util/fs_util.go b/pkg/util/fs_util.go index f51e86444f..f3dcf67d3e 100644 --- a/pkg/util/fs_util.go +++ b/pkg/util/fs_util.go @@ -69,6 +69,14 @@ var defaultIgnoreList = []IgnoreListEntry{ Path: "/etc/mtab", PrefixMatchOnly: false, }, + { + Path: "/.dockerenv", + PrefixMatchOnly: false, + }, + { + Path: "/.dockerinit", + PrefixMatchOnly: false, + }, { // we ingore /tmp/apt-key-gpghome, since the apt keys are added temporarily in this directory. // from the base image @@ -81,6 +89,10 @@ var ignorelist = append([]IgnoreListEntry{}, defaultIgnoreList...) var volumes = []string{} +// these paths should be always preserved in the image +// adding them to ignore list will remove just nested paths +var preservelist = []string{"/dev", "/proc", "/run", "/sys", "/var/run"} + type FileContext struct { Root string ExcludedFiles []string @@ -297,7 +309,7 @@ func ExtractFile(dest string, hdr *tar.Header, tr io.Reader) error { return err } - if CheckIgnoreList(abs) && !checkIgnoreListRoot(dest) { + if CheckIgnoreList(abs) && !checkIgnoreListRoot(dest) && !checkPreserveList(dest) { logrus.Debugf("Not adding %s because it is ignored", path) return nil } @@ -398,6 +410,16 @@ func ExtractFile(dest string, hdr *tar.Header, tr io.Reader) error { return nil } +// Check if path should be always preserved +func checkPreserveList(path string) bool { + for _, p := range preservelist { + if path == p { + return true + } + } + return false +} + func IsInProvidedIgnoreList(path string, wl []IgnoreListEntry) bool { for _, entry := range wl { if !entry.PrefixMatchOnly && path == entry.Path { @@ -941,9 +963,19 @@ func CopyFileOrSymlink(src string, destDir string, root string) error { } return os.Symlink(link, destFile) } - if err := otiai10Cpy.Copy(src, destFile); err != nil { + opt := otiai10Cpy.Options{ + Skip: func(srcinfo os.FileInfo, src, dest string) (bool, error) { + if CheckIgnoreList(dest) && !checkPreserveList(dest) { + logrus.Debugf("Not copying %s, as it's ignored", dest) + return true, nil + } + return false, nil + }, + } + if err := otiai10Cpy.Copy(src, destFile, opt); err != nil { return errors.Wrap(err, "copying file") } + if err := CopyOwnership(src, destDir, root); err != nil { return errors.Wrap(err, "copying ownership") } diff --git a/pkg/util/fs_util_test.go b/pkg/util/fs_util_test.go index 6f13e808ac..d862f338fa 100644 --- a/pkg/util/fs_util_test.go +++ b/pkg/util/fs_util_test.go @@ -64,6 +64,8 @@ func Test_DetectFilesystemSkiplist(t *testing.T) { {"/dev/pts", false}, {"/sys", false}, {"/etc/mtab", false}, + {"/.dockerenv", false}, + {"/.dockerinit", false}, {"/tmp/apt-key-gpghome", true}, } actualSkiplist := ignorelist @@ -1493,6 +1495,14 @@ func TestInitIgnoreList(t *testing.T) { Path: "/etc/mtab", PrefixMatchOnly: false, }, + { + Path: "/.dockerenv", + PrefixMatchOnly: false, + }, + { + Path: "/.dockerinit", + PrefixMatchOnly: false, + }, { Path: "/tmp/apt-key-gpghome", PrefixMatchOnly: true,