Skip to content

Commit

Permalink
Merge pull request #1155 from tejal29/fix_multi_stage_symlinks
Browse files Browse the repository at this point in the history
Refactor Kaniko to test across multistages
  • Loading branch information
tejal29 authored Mar 30, 2020
2 parents 54c2a7a + 340ca79 commit 8dc6454
Show file tree
Hide file tree
Showing 15 changed files with 378 additions and 78 deletions.
7 changes: 0 additions & 7 deletions pkg/commands/commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,13 @@ 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"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)

var RootDir string

func init() {
RootDir = constants.RootDir
}

type CurrentCacheKey func() (string, error)

type DockerCommand interface {
Expand Down
8 changes: 4 additions & 4 deletions pkg/commands/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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 {
Expand Down
40 changes: 39 additions & 1 deletion pkg/commands/copy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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)
}

Expand Down Expand Up @@ -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)
})
}
3 changes: 2 additions & 1 deletion pkg/commands/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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(),
Expand Down
31 changes: 31 additions & 0 deletions pkg/config/init.go
Original file line number Diff line number Diff line change
@@ -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
}
32 changes: 21 additions & 11 deletions pkg/executor/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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")
}

Expand All @@ -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")
}

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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))
}
}

Expand All @@ -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)
}
}
Expand Down Expand Up @@ -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
}
Expand Down
29 changes: 13 additions & 16 deletions pkg/executor/build_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
}
})
}
Expand Down Expand Up @@ -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 {
Expand All @@ -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

})
}
Expand Down
Loading

0 comments on commit 8dc6454

Please sign in to comment.