Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: resolve issue around copying root #2592

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions integration/dockerfiles-with-context/issue-960/Dockerfile
Original file line number Diff line number Diff line change
@@ -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
36 changes: 34 additions & 2 deletions pkg/util/fs_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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")
}
Expand Down
10 changes: 10 additions & 0 deletions pkg/util/fs_util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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,
Expand Down