Merge branch 'master' into snapshot-directories
This commit is contained in:
commit
fd8a2d6dd8
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package commands
|
||||
|
||||
import (
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||
|
|
@ -25,12 +24,6 @@ import (
|
|||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var RootDir string
|
||||
|
||||
func init() {
|
||||
RootDir = constants.RootDir
|
||||
}
|
||||
|
||||
type CurrentCacheKey func() (string, error)
|
||||
|
||||
type DockerCommand interface {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
kConfig "github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -47,7 +47,7 @@ type CopyCommand struct {
|
|||
func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
||||
// Resolve from
|
||||
if c.cmd.From != "" {
|
||||
c.buildcontext = filepath.Join(constants.KanikoDir, c.cmd.From)
|
||||
c.buildcontext = filepath.Join(kConfig.KanikoDir, c.cmd.From)
|
||||
}
|
||||
|
||||
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
|
||||
|
|
@ -74,7 +74,7 @@ func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu
|
|||
}
|
||||
cwd := config.WorkingDir
|
||||
if cwd == "" {
|
||||
cwd = constants.RootDir
|
||||
cwd = kConfig.RootDir
|
||||
}
|
||||
|
||||
destPath, err := util.DestinationFilepath(fullPath, dest, cwd)
|
||||
|
|
@ -191,7 +191,7 @@ func (cr *CachingCopyCommand) ExecuteCommand(config *v1.Config, buildArgs *docke
|
|||
cr.layer = layers[0]
|
||||
cr.readSuccess = true
|
||||
|
||||
cr.extractedFiles, err = util.GetFSFromLayers(RootDir, layers, util.ExtractFunc(cr.extractFn), util.IncludeWhiteout())
|
||||
cr.extractedFiles, err = util.GetFSFromLayers(kConfig.RootDir, layers, util.ExtractFunc(cr.extractFn), util.IncludeWhiteout())
|
||||
|
||||
logrus.Debugf("extractedFiles: %s", cr.extractedFiles)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -405,7 +405,6 @@ func TestCopyCommand_ExecuteCommand_Extended(t *testing.T) {
|
|||
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
file := filepath.Join(dir, "bam.txt")
|
||||
|
||||
if err := ioutil.WriteFile(file, []byte("meow"), 0777); err != nil {
|
||||
|
|
@ -418,6 +417,7 @@ func TestCopyCommand_ExecuteCommand_Extended(t *testing.T) {
|
|||
if err := os.Symlink("dam.txt", filepath.Join(dir, "sym.link")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return testDir, filepath.Base(dir)
|
||||
}
|
||||
|
||||
|
|
@ -922,4 +922,42 @@ func TestCopyCommand_ExecuteCommand_Extended(t *testing.T) {
|
|||
testutil.CheckNoError(t, err)
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("copy src dir with relative symlinks in a dir", func(t *testing.T) {
|
||||
testDir, srcDir := setupDirs(t)
|
||||
defer os.RemoveAll(testDir)
|
||||
|
||||
// Make another dir inside bar with a relative symlink
|
||||
dir := filepath.Join(testDir, srcDir, "another")
|
||||
if err := os.MkdirAll(dir, 0777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Symlink("../bam.txt", filepath.Join(dir, "bam_relative.txt"))
|
||||
|
||||
dest := filepath.Join(testDir, "copy")
|
||||
cmd := CopyCommand{
|
||||
cmd: &instructions.CopyCommand{
|
||||
SourcesAndDest: []string{srcDir, dest},
|
||||
},
|
||||
buildcontext: testDir,
|
||||
}
|
||||
|
||||
cfg := &v1.Config{
|
||||
Cmd: nil,
|
||||
Env: []string{},
|
||||
WorkingDir: testDir,
|
||||
}
|
||||
err := cmd.ExecuteCommand(cfg, dockerfile.NewBuildArgs([]string{}))
|
||||
testutil.CheckNoError(t, err)
|
||||
actual, err := ioutil.ReadDir(filepath.Join(dest, "another"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testutil.CheckDeepEqual(t, "bam_relative.txt", actual[0].Name())
|
||||
linkName, err := os.Readlink(filepath.Join(dest, "another", "bam_relative.txt"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testutil.CheckDeepEqual(t, "../bam.txt", linkName)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
|
||||
kConfig "github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
|
|
@ -202,7 +203,7 @@ func (cr *CachingRunCommand) ExecuteCommand(config *v1.Config, buildArgs *docker
|
|||
cr.readSuccess = true
|
||||
|
||||
cr.extractedFiles, err = util.GetFSFromLayers(
|
||||
constants.RootDir,
|
||||
kConfig.RootDir,
|
||||
layers,
|
||||
util.ExtractFunc(cr.extractFn),
|
||||
util.IncludeWhiteout(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
Copyright 2020 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 config
|
||||
|
||||
import (
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
)
|
||||
|
||||
var RootDir string
|
||||
var KanikoDir string
|
||||
var WhitelistPath string
|
||||
|
||||
func init() {
|
||||
RootDir = constants.RootDir
|
||||
KanikoDir = constants.KanikoDir
|
||||
WhitelistPath = constants.WhitelistPath
|
||||
}
|
||||
|
|
@ -98,7 +98,7 @@ func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, cross
|
|||
return nil, err
|
||||
}
|
||||
l := snapshot.NewLayeredMap(hasher, util.CacheHasher())
|
||||
snapshotter := snapshot.NewSnapshotter(l, constants.RootDir)
|
||||
snapshotter := snapshot.NewSnapshotter(l, config.RootDir)
|
||||
|
||||
digest, err := sourceImage.Digest()
|
||||
if err != nil {
|
||||
|
|
@ -299,7 +299,7 @@ func (s *stageBuilder) build() error {
|
|||
if shouldUnpack {
|
||||
t := timing.Start("FS Unpacking")
|
||||
|
||||
if _, err := util.GetFSFromImage(constants.RootDir, s.image, util.ExtractFile); err != nil {
|
||||
if _, err := util.GetFSFromImage(config.RootDir, s.image, util.ExtractFile); err != nil {
|
||||
return errors.Wrap(err, "failed to get filesystem from image")
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ func (s *stageBuilder) build() error {
|
|||
logrus.Info("Skipping unpacking as no commands require it.")
|
||||
}
|
||||
|
||||
if err := util.DetectFilesystemWhitelist(constants.WhitelistPath); err != nil {
|
||||
if err := util.DetectFilesystemWhitelist(config.WhitelistPath); err != nil {
|
||||
return errors.Wrap(err, "failed to check filesystem whitelist")
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +525,6 @@ func CalculateDependencies(opts *config.KanikoOptions) (map[int][]string, error)
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
depGraph[i] = append(depGraph[i], resolved[0:len(resolved)-1]...)
|
||||
}
|
||||
case *instructions.EnvCommand:
|
||||
|
|
@ -641,20 +640,23 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dstDir := filepath.Join(constants.KanikoDir, strconv.Itoa(index))
|
||||
dstDir := filepath.Join(config.KanikoDir, strconv.Itoa(index))
|
||||
if err := os.MkdirAll(dstDir, 0644); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err,
|
||||
fmt.Sprintf("to create workspace for stage %s",
|
||||
stageIdxToDigest[strconv.Itoa(index)],
|
||||
))
|
||||
}
|
||||
for _, p := range filesToSave {
|
||||
logrus.Infof("Saving file %s for later use", p)
|
||||
if err := util.CopyFileOrSymlink(p, dstDir); err != nil {
|
||||
return nil, err
|
||||
if err := util.CopyFileOrSymlink(p, dstDir, config.RootDir); err != nil {
|
||||
return nil, errors.Wrap(err, "could not save file")
|
||||
}
|
||||
}
|
||||
|
||||
// Delete the filesystem
|
||||
if err := util.DeleteFilesystem(); err != nil {
|
||||
return nil, err
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("deleting file system after satge %d", index))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -666,14 +668,22 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
|
|||
func filesToSave(deps []string) ([]string, error) {
|
||||
srcFiles := []string{}
|
||||
for _, src := range deps {
|
||||
srcs, err := filepath.Glob(src)
|
||||
srcs, err := filepath.Glob(filepath.Join(config.RootDir, src))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, f := range srcs {
|
||||
if link, err := util.EvalSymLink(f); err == nil {
|
||||
link, err = filepath.Rel(config.RootDir, link)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("could not find relative path to %s", config.RootDir))
|
||||
}
|
||||
srcFiles = append(srcFiles, link)
|
||||
}
|
||||
f, err = filepath.Rel(config.RootDir, f)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, fmt.Sprintf("could not find relative path to %s", config.RootDir))
|
||||
}
|
||||
srcFiles = append(srcFiles, f)
|
||||
}
|
||||
}
|
||||
|
|
@ -729,7 +739,7 @@ func fetchExtraStages(stages []config.KanikoStage, opts *config.KanikoOptions) e
|
|||
func extractImageToDependencyDir(name string, image v1.Image) error {
|
||||
t := timing.Start("Extracting Image to Dependency Dir")
|
||||
defer timing.DefaultRun.Stop(t)
|
||||
dependencyDir := filepath.Join(constants.KanikoDir, name)
|
||||
dependencyDir := filepath.Join(config.KanikoDir, name)
|
||||
if err := os.MkdirAll(dependencyDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -371,10 +371,15 @@ func Test_filesToSave(t *testing.T) {
|
|||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
tmpDir, err := ioutil.TempDir("", "")
|
||||
original := config.RootDir
|
||||
config.RootDir = tmpDir
|
||||
if err != nil {
|
||||
t.Errorf("error creating tmpdir: %s", err)
|
||||
}
|
||||
defer os.RemoveAll(tmpDir)
|
||||
defer func() {
|
||||
config.RootDir = original
|
||||
os.RemoveAll(tmpDir)
|
||||
}()
|
||||
|
||||
for _, f := range tt.files {
|
||||
p := filepath.Join(tmpDir, f)
|
||||
|
|
@ -391,22 +396,14 @@ func Test_filesToSave(t *testing.T) {
|
|||
fp.Close()
|
||||
}
|
||||
|
||||
args := []string{}
|
||||
for _, arg := range tt.args {
|
||||
args = append(args, filepath.Join(tmpDir, arg))
|
||||
}
|
||||
got, err := filesToSave(args)
|
||||
got, err := filesToSave(tt.args)
|
||||
if err != nil {
|
||||
t.Errorf("got err: %s", err)
|
||||
}
|
||||
want := []string{}
|
||||
for _, w := range tt.want {
|
||||
want = append(want, filepath.Join(tmpDir, w))
|
||||
}
|
||||
sort.Strings(want)
|
||||
sort.Strings(tt.want)
|
||||
sort.Strings(got)
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("filesToSave() = %v, want %v", got, want)
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("filesToSave() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -1129,9 +1126,9 @@ COPY %s bar.txt
|
|||
for key, value := range tc.args {
|
||||
sb.args.AddArg(key, &value)
|
||||
}
|
||||
tmp := commands.RootDir
|
||||
tmp := config.RootDir
|
||||
if tc.rootDir != "" {
|
||||
commands.RootDir = tc.rootDir
|
||||
config.RootDir = tc.rootDir
|
||||
}
|
||||
err := sb.build()
|
||||
if err != nil {
|
||||
|
|
@ -1141,7 +1138,7 @@ COPY %s bar.txt
|
|||
assertCacheKeys(t, tc.expectedCacheKeys, lc.receivedKeys, "receive")
|
||||
assertCacheKeys(t, tc.pushedCacheKeys, keys, "push")
|
||||
|
||||
commands.RootDir = tmp
|
||||
config.RootDir = tmp
|
||||
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
Copyright 2020 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 executor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
)
|
||||
|
||||
func TestCopyCommand_Multistage(t *testing.T) {
|
||||
t.Run("copy a file across multistage", func(t *testing.T) {
|
||||
testDir, fn := setupMultistageTests(t)
|
||||
defer fn()
|
||||
dockerFile := fmt.Sprintf(`
|
||||
FROM scratch as first
|
||||
COPY foo/bam.txt copied/
|
||||
ENV test test
|
||||
|
||||
From scratch as second
|
||||
COPY --from=first copied/bam.txt output/bam.txt`)
|
||||
ioutil.WriteFile(filepath.Join(testDir, "workspace", "Dockerfile"), []byte(dockerFile), 0755)
|
||||
opts := &config.KanikoOptions{
|
||||
DockerfilePath: filepath.Join(testDir, "workspace", "Dockerfile"),
|
||||
SrcContext: filepath.Join(testDir, "workspace"),
|
||||
SnapshotMode: constants.SnapshotModeFull,
|
||||
}
|
||||
_, err := DoBuild(opts)
|
||||
testutil.CheckNoError(t, err)
|
||||
// Check Image has one layer bam.txt
|
||||
files, err := ioutil.ReadDir(filepath.Join(testDir, "output"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testutil.CheckDeepEqual(t, 1, len(files))
|
||||
testutil.CheckDeepEqual(t, files[0].Name(), "bam.txt")
|
||||
|
||||
})
|
||||
|
||||
t.Run("copy a file across multistage into a directory", func(t *testing.T) {
|
||||
testDir, fn := setupMultistageTests(t)
|
||||
defer fn()
|
||||
dockerFile := fmt.Sprintf(`
|
||||
FROM scratch as first
|
||||
COPY foo/bam.txt copied/
|
||||
ENV test test
|
||||
|
||||
From scratch as second
|
||||
COPY --from=first copied/bam.txt output/`)
|
||||
ioutil.WriteFile(filepath.Join(testDir, "workspace", "Dockerfile"), []byte(dockerFile), 0755)
|
||||
opts := &config.KanikoOptions{
|
||||
DockerfilePath: filepath.Join(testDir, "workspace", "Dockerfile"),
|
||||
SrcContext: filepath.Join(testDir, "workspace"),
|
||||
SnapshotMode: constants.SnapshotModeFull,
|
||||
}
|
||||
_, err := DoBuild(opts)
|
||||
testutil.CheckNoError(t, err)
|
||||
files, err := ioutil.ReadDir(filepath.Join(testDir, "output"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testutil.CheckDeepEqual(t, 1, len(files))
|
||||
testutil.CheckDeepEqual(t, files[0].Name(), "bam.txt")
|
||||
})
|
||||
t.Run("copy directory across multistage into a directory", func(t *testing.T) {
|
||||
testDir, fn := setupMultistageTests(t)
|
||||
defer fn()
|
||||
dockerFile := fmt.Sprintf(`
|
||||
FROM scratch as first
|
||||
COPY foo copied
|
||||
ENV test test
|
||||
|
||||
From scratch as second
|
||||
COPY --from=first copied another`)
|
||||
ioutil.WriteFile(filepath.Join(testDir, "workspace", "Dockerfile"), []byte(dockerFile), 0755)
|
||||
opts := &config.KanikoOptions{
|
||||
DockerfilePath: filepath.Join(testDir, "workspace", "Dockerfile"),
|
||||
SrcContext: filepath.Join(testDir, "workspace"),
|
||||
SnapshotMode: constants.SnapshotModeFull,
|
||||
}
|
||||
_, err := DoBuild(opts)
|
||||
testutil.CheckNoError(t, err)
|
||||
// Check Image has one layer bam.txt
|
||||
files, err := ioutil.ReadDir(filepath.Join(testDir, "another"))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testutil.CheckDeepEqual(t, 2, len(files))
|
||||
testutil.CheckDeepEqual(t, files[0].Name(), "bam.link")
|
||||
testutil.CheckDeepEqual(t, files[1].Name(), "bam.txt")
|
||||
// TODO fix this
|
||||
// path := filepath.Join(testDir, "output/another", "bam.link")
|
||||
//linkName, err := os.Readlink(path)
|
||||
//if err != nil {
|
||||
// t.Fatal(err)
|
||||
//}
|
||||
//testutil.CheckDeepEqual(t, linkName, "bam.txt")
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func setupMultistageTests(t *testing.T) (string, func()) {
|
||||
testDir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Create workspace with files, dirs, and symlinks
|
||||
// workspace tree:
|
||||
// /root
|
||||
// /kaniko
|
||||
// /workspace
|
||||
// - /foo
|
||||
// - bam.txt
|
||||
// - bam.link -> bam.txt
|
||||
// - /bin
|
||||
// - exec.link -> ../exec
|
||||
// exec
|
||||
|
||||
// Make directory for stage or else the executor will create with permissions 0664
|
||||
// and we will run into issue https://github.com/golang/go/issues/22323
|
||||
if err := os.MkdirAll(filepath.Join(testDir, "kaniko/0"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
workspace := filepath.Join(testDir, "workspace")
|
||||
// Make foo
|
||||
if err := os.MkdirAll(filepath.Join(workspace, "foo"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
file := filepath.Join(workspace, "foo", "bam.txt")
|
||||
if err := ioutil.WriteFile(file, []byte("meow"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Symlink("bam.txt", filepath.Join(workspace, "foo", "bam.link"))
|
||||
|
||||
// Make a file with contents link
|
||||
file = filepath.Join(workspace, "exec")
|
||||
if err := ioutil.WriteFile(file, []byte("woof"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Make bin
|
||||
if err := os.MkdirAll(filepath.Join(workspace, "bin"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
os.Symlink("../exec", filepath.Join(workspace, "bin", "exec.link"))
|
||||
|
||||
// set up config
|
||||
config.RootDir = testDir
|
||||
config.KanikoDir = fmt.Sprintf("%s/%s", testDir, "kaniko")
|
||||
// Write a whitelist path
|
||||
if err := os.MkdirAll(filepath.Join(testDir, "proc"), 0755); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mFile := filepath.Join(testDir, "proc/mountinfo")
|
||||
mountInfo := fmt.Sprintf(
|
||||
`36 35 98:0 /kaniko %s/kaniko rw,noatime master:1 - ext3 /dev/root rw,errors=continue
|
||||
36 35 98:0 /proc %s/proc rw,noatime master:1 - ext3 /dev/root rw,errors=continue
|
||||
`, testDir, testDir)
|
||||
if err := ioutil.WriteFile(mFile, []byte(mountInfo), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
config.WhitelistPath = mFile
|
||||
return testDir, func() {
|
||||
config.KanikoDir = constants.KanikoDir
|
||||
config.RootDir = constants.RootDir
|
||||
config.WhitelistPath = constants.WhitelistPath
|
||||
}
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import (
|
|||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -89,7 +90,6 @@ func ResolvePaths(paths []string, wl []util.WhitelistEntry) (pathsToAdd []string
|
|||
|
||||
// Also add parent directories to keep the permission of them correctly.
|
||||
pathsToAdd = filesWithParentDirs(pathsToAdd)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +130,7 @@ func resolveSymlinkAncestor(path string) (string, error) {
|
|||
newPath := filepath.Clean(path)
|
||||
|
||||
loop:
|
||||
for newPath != "/" {
|
||||
for newPath != config.RootDir {
|
||||
fi, err := os.Lstat(newPath)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "resolvePaths: failed to lstat")
|
||||
|
|
|
|||
|
|
@ -28,14 +28,14 @@ import (
|
|||
"github.com/GoogleContainerTools/kaniko/pkg/timing"
|
||||
"github.com/karrick/godirwalk"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// For testing
|
||||
var snapshotPathPrefix = constants.KanikoDir
|
||||
var snapshotPathPrefix = config.KanikoDir
|
||||
|
||||
// Snapshotter holds the root directory from which to take snapshots, and a list of snapshots taken
|
||||
type Snapshotter struct {
|
||||
|
|
@ -63,7 +63,7 @@ func (s *Snapshotter) Key() (string, error) {
|
|||
// TakeSnapshot takes a snapshot of the specified files, avoiding directories in the whitelist, 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) {
|
||||
f, err := ioutil.TempFile(snapshotPathPrefix, "")
|
||||
f, err := ioutil.TempFile(config.KanikoDir, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/util"
|
||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
"github.com/pkg/errors"
|
||||
|
|
@ -174,7 +175,6 @@ func TestSnapshotFSChangePermissions(t *testing.T) {
|
|||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
t.Logf("Info %s in tar", hdr.Name)
|
||||
foundFiles = append(foundFiles, hdr.Name)
|
||||
if _, isFile := snapshotFiles[hdr.Name]; !isFile {
|
||||
t.Fatalf("File %s unexpectedly in tar", hdr.Name)
|
||||
|
|
@ -478,8 +478,11 @@ func setUpTest() (string, *Snapshotter, func(), error) {
|
|||
return "", nil, nil, errors.Wrap(err, "initializing snapshotter")
|
||||
}
|
||||
|
||||
original := config.KanikoDir
|
||||
config.KanikoDir = testDir
|
||||
cleanup := func() {
|
||||
os.RemoveAll(snapshotPath)
|
||||
config.KanikoDir = original
|
||||
dirCleanUp()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,13 +26,14 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/parser"
|
||||
"github.com/moby/buildkit/frontend/dockerfile/shell"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
)
|
||||
|
||||
// for testing
|
||||
|
|
@ -130,7 +131,6 @@ func ResolveSources(srcs []string, root string) ([]string, error) {
|
|||
return nil, errors.Wrap(err, "matching sources")
|
||||
}
|
||||
logrus.Debugf("Resolved sources to %v", resolved)
|
||||
fmt.Println("end of resolve sources")
|
||||
return resolved, nil
|
||||
}
|
||||
|
||||
|
|
@ -145,7 +145,7 @@ func matchSources(srcs, files []string) ([]string, error) {
|
|||
src = filepath.Clean(src)
|
||||
for _, file := range files {
|
||||
if filepath.IsAbs(src) {
|
||||
file = filepath.Join(constants.RootDir, file)
|
||||
file = filepath.Join(config.RootDir, file)
|
||||
}
|
||||
matched, err := filepath.Match(src, file)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import (
|
|||
|
||||
otiai10Cpy "github.com/otiai10/copy"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/constants"
|
||||
"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"
|
||||
|
|
@ -51,7 +51,7 @@ type WhitelistEntry struct {
|
|||
|
||||
var initialWhitelist = []WhitelistEntry{
|
||||
{
|
||||
Path: "/kaniko",
|
||||
Path: config.KanikoDir,
|
||||
PrefixMatchOnly: false,
|
||||
},
|
||||
{
|
||||
|
|
@ -125,7 +125,7 @@ func GetFSFromLayers(root string, layers []v1.Layer, opts ...FSOpt) ([]string, e
|
|||
return nil, errors.New("must supply an extract function")
|
||||
}
|
||||
|
||||
if err := DetectFilesystemWhitelist(constants.WhitelistPath); err != nil {
|
||||
if err := DetectFilesystemWhitelist(config.WhitelistPath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -185,7 +185,7 @@ func GetFSFromLayers(root string, layers []v1.Layer, opts ...FSOpt) ([]string, e
|
|||
// DeleteFilesystem deletes the extracted image file system
|
||||
func DeleteFilesystem() error {
|
||||
logrus.Info("Deleting filesystem...")
|
||||
return filepath.Walk(constants.RootDir, func(path string, info os.FileInfo, err error) error {
|
||||
return filepath.Walk(config.RootDir, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
// ignore errors when deleting.
|
||||
return nil
|
||||
|
|
@ -206,7 +206,7 @@ func DeleteFilesystem() error {
|
|||
logrus.Debugf("Not deleting %s, as it contains a whitelisted path", path)
|
||||
return nil
|
||||
}
|
||||
if path == constants.RootDir {
|
||||
if path == config.RootDir {
|
||||
return nil
|
||||
}
|
||||
return os.RemoveAll(path)
|
||||
|
|
@ -385,7 +385,7 @@ func CheckWhitelist(path string) bool {
|
|||
}
|
||||
|
||||
func checkWhitelistRoot(root string) bool {
|
||||
if root == constants.RootDir {
|
||||
if root == config.RootDir {
|
||||
return false
|
||||
}
|
||||
return CheckWhitelist(root)
|
||||
|
|
@ -420,7 +420,7 @@ func DetectFilesystemWhitelist(path string) error {
|
|||
}
|
||||
continue
|
||||
}
|
||||
if lineArr[4] != constants.RootDir {
|
||||
if lineArr[4] != config.RootDir {
|
||||
logrus.Tracef("Appending %s from line: %s", lineArr[4], line)
|
||||
whitelist = append(whitelist, WhitelistEntry{
|
||||
Path: lineArr[4],
|
||||
|
|
@ -460,16 +460,18 @@ func RelativeFiles(fp string, root string) ([]string, error) {
|
|||
// ParentDirectories returns a list of paths to all parent directories
|
||||
// Ex. /some/temp/dir -> [/, /some, /some/temp, /some/temp/dir]
|
||||
func ParentDirectories(path string) []string {
|
||||
path = filepath.Clean(path)
|
||||
dirs := strings.Split(path, "/")
|
||||
dirPath := constants.RootDir
|
||||
paths := []string{constants.RootDir}
|
||||
for index, dir := range dirs {
|
||||
if dir == "" || index == (len(dirs)-1) {
|
||||
continue
|
||||
dir := filepath.Clean(path)
|
||||
var paths []string
|
||||
for {
|
||||
if dir == filepath.Clean(config.RootDir) || dir == "" || dir == "." {
|
||||
break
|
||||
}
|
||||
dirPath = filepath.Join(dirPath, dir)
|
||||
paths = append(paths, dirPath)
|
||||
dir, _ = filepath.Split(dir)
|
||||
dir = filepath.Clean(dir)
|
||||
paths = append(paths, dir)
|
||||
}
|
||||
if len(paths) == 0 {
|
||||
paths = append(paths, config.RootDir)
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
|
@ -481,7 +483,7 @@ func ParentDirectoriesWithoutLeadingSlash(path string) []string {
|
|||
path = filepath.Clean(path)
|
||||
dirs := strings.Split(path, "/")
|
||||
dirPath := ""
|
||||
paths := []string{constants.RootDir}
|
||||
paths := []string{config.RootDir}
|
||||
for index, dir := range dirs {
|
||||
if dir == "" || index == (len(dirs)-1) {
|
||||
continue
|
||||
|
|
@ -725,7 +727,7 @@ func mkdirAllWithPermissions(path string, mode os.FileMode, uid, gid int64) erro
|
|||
}
|
||||
if uid > math.MaxUint32 || gid > math.MaxUint32 {
|
||||
// due to https://github.com/golang/go/issues/8537
|
||||
return errors.New(fmt.Sprintf("Numeric User-ID or Group-ID greater than %v are not properly supported.", math.MaxUint32))
|
||||
return errors.New(fmt.Sprintf("Numeric User-ID or Group-ID greater than %v are not properly supported.", uint64(math.MaxUint32)))
|
||||
}
|
||||
if err := os.Chown(path, int(uid), int(gid)); err != nil {
|
||||
return err
|
||||
|
|
@ -821,12 +823,13 @@ func getSymlink(path string) error {
|
|||
// For cross stage dependencies kaniko must persist the referenced path so that it can be used in
|
||||
// the dependent stage. For symlinks we copy the target path because copying the symlink would
|
||||
// result in a dead link
|
||||
func CopyFileOrSymlink(src string, destDir string) error {
|
||||
func CopyFileOrSymlink(src string, destDir string, root string) error {
|
||||
destFile := filepath.Join(destDir, src)
|
||||
src = filepath.Join(root, src)
|
||||
if fi, _ := os.Lstat(src); IsSymlink(fi) {
|
||||
link, err := os.Readlink(src)
|
||||
if err != nil {
|
||||
return err
|
||||
return errors.Wrap(err, "copying file or symlink")
|
||||
}
|
||||
if err := createParentDirectory(destFile); err != nil {
|
||||
return err
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/mocks/go-containerregistry/mockv1"
|
||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
"github.com/golang/mock/gomock"
|
||||
|
|
@ -157,11 +158,13 @@ func Test_ParentDirectories(t *testing.T) {
|
|||
tests := []struct {
|
||||
name string
|
||||
path string
|
||||
rootDir string
|
||||
expected []string
|
||||
}{
|
||||
{
|
||||
name: "regular path",
|
||||
path: "/path/to/dir",
|
||||
name: "regular path",
|
||||
path: "/path/to/dir",
|
||||
rootDir: "/",
|
||||
expected: []string{
|
||||
"/",
|
||||
"/path",
|
||||
|
|
@ -169,17 +172,50 @@ func Test_ParentDirectories(t *testing.T) {
|
|||
},
|
||||
},
|
||||
{
|
||||
name: "current directory",
|
||||
path: ".",
|
||||
name: "current directory",
|
||||
path: ".",
|
||||
rootDir: "/",
|
||||
expected: []string{
|
||||
"/",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non / root directory",
|
||||
path: "/tmp/kaniko/test/another/dir",
|
||||
rootDir: "/tmp/kaniko/",
|
||||
expected: []string{
|
||||
"/tmp/kaniko",
|
||||
"/tmp/kaniko/test",
|
||||
"/tmp/kaniko/test/another",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non / root director same path",
|
||||
path: "/tmp/123",
|
||||
rootDir: "/tmp/123",
|
||||
expected: []string{
|
||||
"/tmp/123",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "non / root directory path",
|
||||
path: "/tmp/120162240/kaniko",
|
||||
rootDir: "/tmp/120162240",
|
||||
expected: []string{
|
||||
"/tmp/120162240",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
original := config.RootDir
|
||||
defer func() { config.RootDir = original }()
|
||||
config.RootDir = tt.rootDir
|
||||
actual := ParentDirectories(tt.path)
|
||||
sort.Strings(actual)
|
||||
sort.Strings(tt.expected)
|
||||
|
||||
testutil.CheckErrorAndDeepEqual(t, false, nil, tt.expected, actual)
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ import (
|
|||
"strings"
|
||||
"syscall"
|
||||
|
||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||
"github.com/docker/docker/pkg/archive"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
|
@ -76,18 +77,17 @@ func (t *Tar) AddFileToTar(p string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if p != "/" {
|
||||
// Docker uses no leading / in the tarball
|
||||
hdr.Name = strings.TrimLeft(p, "/")
|
||||
} else {
|
||||
if p == config.RootDir {
|
||||
// allow entry for / to preserve permission changes etc. (currently ignored anyway by Docker runtime)
|
||||
hdr.Name = p
|
||||
hdr.Name = "/"
|
||||
} else {
|
||||
// Docker uses no leading / in the tarball
|
||||
hdr.Name = strings.TrimPrefix(p, config.RootDir)
|
||||
hdr.Name = strings.TrimLeft(hdr.Name, "/")
|
||||
}
|
||||
|
||||
if hdr.Typeflag == tar.TypeDir && !strings.HasSuffix(hdr.Name, "/") {
|
||||
hdr.Name = hdr.Name + "/"
|
||||
}
|
||||
|
||||
// rootfs may not have been extracted when using cache, preventing uname/gname from resolving
|
||||
// this makes this layer unnecessarily differ from a cached layer which does contain this information
|
||||
hdr.Uname = ""
|
||||
|
|
|
|||
Loading…
Reference in New Issue