parent
87e646a0b3
commit
a9062b97f7
|
|
@ -18,6 +18,7 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
|
@ -300,7 +301,7 @@ func checkKanikoDir(dir string) error {
|
|||
if dir != constants.DefaultKanikoPath {
|
||||
|
||||
// The destination directory may be across a different partition, so we cannot simply rename/move the directory in this case.
|
||||
if _, err := util.CopyDir(constants.DefaultKanikoPath, dir, util.FileContext{}, util.DoNotChangeUID, util.DoNotChangeGID); err != nil {
|
||||
if _, err := util.CopyDir(constants.DefaultKanikoPath, dir, util.FileContext{}, util.DoNotChangeUID, util.DoNotChangeGID, fs.FileMode(0o600), true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
@ -321,7 +322,6 @@ func checkContained() bool {
|
|||
|
||||
// checkNoDeprecatedFlags return an error if deprecated flags are used.
|
||||
func checkNoDeprecatedFlags() {
|
||||
|
||||
// In version >=2.0.0 make it fail (`Warn` -> `Fatal`)
|
||||
if opts.CustomPlatformDeprecated != "" {
|
||||
logrus.Warn("Flag --customPlatform is deprecated. Use: --custom-platform")
|
||||
|
|
@ -391,12 +391,12 @@ func resolveEnvironmentBuildArgs(arguments []string, resolver func(string) strin
|
|||
// copy Dockerfile to /kaniko/Dockerfile so that if it's specified in the .dockerignore
|
||||
// it won't be copied into the image
|
||||
func copyDockerfile() error {
|
||||
if _, err := util.CopyFile(opts.DockerfilePath, config.DockerfilePath, util.FileContext{}, util.DoNotChangeUID, util.DoNotChangeGID); err != nil {
|
||||
if _, err := util.CopyFile(opts.DockerfilePath, config.DockerfilePath, util.FileContext{}, util.DoNotChangeUID, util.DoNotChangeGID, fs.FileMode(0o600), true); err != nil {
|
||||
return errors.Wrap(err, "copying dockerfile")
|
||||
}
|
||||
dockerignorePath := opts.DockerfilePath + ".dockerignore"
|
||||
if util.FilepathExists(dockerignorePath) {
|
||||
if _, err := util.CopyFile(dockerignorePath, config.DockerfilePath+".dockerignore", util.FileContext{}, util.DoNotChangeUID, util.DoNotChangeGID); err != nil {
|
||||
if _, err := util.CopyFile(dockerignorePath, config.DockerfilePath+".dockerignore", util.FileContext{}, util.DoNotChangeUID, util.DoNotChangeGID, fs.FileMode(0o600), true); err != nil {
|
||||
return errors.Wrap(err, "copying Dockerfile.dockerignore")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
FROM alpine@sha256:5ce5f501c457015c4b91f91a15ac69157d9b06f1a75cf9107bf2b62e0843983a
|
||||
|
||||
ADD --chmod=0666 context/foo /file666
|
||||
ADD --chmod=777 context/qux /dir777
|
||||
|
||||
# ADD tests
|
||||
# simple file
|
||||
RUN test "$(stat -c "%a" /file666)" = "666"
|
||||
|
||||
# recurive dir
|
||||
RUN test "$(stat -c "%a" /dir777/qup)" = "777"
|
||||
RUN test "$(stat -c "%a" /dir777/quw/que)" = "777"
|
||||
|
||||
# COPY tests
|
||||
|
||||
COPY --chmod=0755 context/foo /copyfile755
|
||||
COPY --chmod=755 context/qux /copydir755
|
||||
|
||||
RUN test "$(stat -c "%a" /copyfile755)" = "755"
|
||||
|
||||
RUN test "$(stat -c "%a" /copydir755/qup)" = "755"
|
||||
RUN test "$(stat -c "%a" /copydir755/quw/que)" = "755"
|
||||
|
|
@ -39,7 +39,7 @@ import (
|
|||
const (
|
||||
// ExecutorImage is the name of the kaniko executor image
|
||||
ExecutorImage = "executor-image"
|
||||
//WarmerImage is the name of the kaniko cache warmer image
|
||||
// WarmerImage is the name of the kaniko cache warmer image
|
||||
WarmerImage = "warmer-image"
|
||||
|
||||
dockerPrefix = "docker-"
|
||||
|
|
@ -69,7 +69,8 @@ var argsMap = map[string][]string{
|
|||
|
||||
// Environment to build Dockerfiles with, used for both docker and kaniko builds
|
||||
var envsMap = map[string][]string{
|
||||
"Dockerfile_test_arg_secret": {"SSH_PRIVATE_KEY=ThEPriv4t3Key"},
|
||||
"Dockerfile_test_arg_secret": {"SSH_PRIVATE_KEY=ThEPriv4t3Key"},
|
||||
"Dockerfile_test_copyadd_chmod": {"DOCKER_BUILDKIT=1"},
|
||||
}
|
||||
|
||||
// Arguments to build Dockerfiles with when building with docker
|
||||
|
|
@ -138,8 +139,10 @@ func checkArgsNotPrinted(dockerfile string, out []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
var bucketContextTests = []string{"Dockerfile_test_copy_bucket"}
|
||||
var reproducibleTests = []string{"Dockerfile_test_reproducible"}
|
||||
var (
|
||||
bucketContextTests = []string{"Dockerfile_test_copy_bucket"}
|
||||
reproducibleTests = []string{"Dockerfile_test_reproducible"}
|
||||
)
|
||||
|
||||
// GetDockerImage constructs the name of the docker image that would be built with
|
||||
// dockerfile if it was tagged with imageRepo.
|
||||
|
|
@ -347,13 +350,15 @@ func populateVolumeCache() error {
|
|||
_, ex, _, _ := runtime.Caller(0)
|
||||
cwd := filepath.Dir(ex)
|
||||
warmerCmd := exec.Command("docker",
|
||||
append([]string{"run", "--net=host",
|
||||
append([]string{
|
||||
"run", "--net=host",
|
||||
"-d",
|
||||
"-v", os.Getenv("HOME") + "/.config/gcloud:/root/.config/gcloud",
|
||||
"-v", cwd + ":/workspace",
|
||||
WarmerImage,
|
||||
"-c", cacheDir,
|
||||
"-i", baseImageToCache},
|
||||
"-i", baseImageToCache,
|
||||
},
|
||||
)...,
|
||||
)
|
||||
|
||||
|
|
@ -374,14 +379,16 @@ func (d *DockerFileBuilder) buildCachedImage(config *integrationTestConfig, cach
|
|||
|
||||
benchmarkEnv := "BENCHMARK_FILE=false"
|
||||
if b, err := strconv.ParseBool(os.Getenv("BENCHMARK")); err == nil && b {
|
||||
os.Mkdir("benchmarks", 0755)
|
||||
os.Mkdir("benchmarks", 0o755)
|
||||
benchmarkEnv = "BENCHMARK_FILE=/workspace/benchmarks/" + dockerfile
|
||||
}
|
||||
kanikoImage := GetVersionedKanikoImage(imageRepo, dockerfile, version)
|
||||
|
||||
dockerRunFlags := []string{"run", "--net=host",
|
||||
dockerRunFlags := []string{
|
||||
"run", "--net=host",
|
||||
"-v", cwd + ":/workspace",
|
||||
"-e", benchmarkEnv}
|
||||
"-e", benchmarkEnv,
|
||||
}
|
||||
dockerRunFlags = addServiceAccountFlags(dockerRunFlags, serviceAccount)
|
||||
dockerRunFlags = append(dockerRunFlags, ExecutorImage,
|
||||
"-f", path.Join(buildContextPath, dockerfilesPath, dockerfile),
|
||||
|
|
@ -411,10 +418,12 @@ func (d *DockerFileBuilder) buildRelativePathsImage(imageRepo, dockerfile, servi
|
|||
kanikoImage := GetKanikoImage(imageRepo, "test_relative_"+dockerfile)
|
||||
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
"./context"},
|
||||
"./context",
|
||||
},
|
||||
)...,
|
||||
)
|
||||
|
||||
|
|
@ -483,7 +492,8 @@ func buildKanikoImage(
|
|||
additionalFlags := append(buildArgs, kanikoArgs...)
|
||||
logf("Going to build image with kaniko: %s, flags: %s \n", kanikoImage, additionalFlags)
|
||||
|
||||
dockerRunFlags := []string{"run", "--net=host",
|
||||
dockerRunFlags := []string{
|
||||
"run", "--net=host",
|
||||
"-e", benchmarkEnv,
|
||||
"-v", contextDir + ":/workspace",
|
||||
"-v", benchmarkDir + ":/kaniko/benchmarks",
|
||||
|
|
|
|||
|
|
@ -46,9 +46,11 @@ import (
|
|||
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||
)
|
||||
|
||||
var config *integrationTestConfig
|
||||
var imageBuilder *DockerFileBuilder
|
||||
var allDockerfiles []string
|
||||
var (
|
||||
config *integrationTestConfig
|
||||
imageBuilder *DockerFileBuilder
|
||||
allDockerfiles []string
|
||||
)
|
||||
|
||||
const (
|
||||
daemonPrefix = "daemon://"
|
||||
|
|
@ -148,7 +150,6 @@ func TestMain(m *testing.M) {
|
|||
fmt.Println(err)
|
||||
}
|
||||
os.Exit(exitCode)
|
||||
|
||||
}
|
||||
|
||||
func buildRequiredImages() error {
|
||||
|
|
@ -207,7 +208,6 @@ func TestRun(t *testing.T) {
|
|||
|
||||
expected := fmt.Sprintf(emptyContainerDiff, dockerImage, kanikoImage, dockerImage, kanikoImage)
|
||||
checkContainerDiffOutput(t, diff, expected)
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -253,10 +253,12 @@ func testGitBuildcontextHelper(t *testing.T, repo string) {
|
|||
// Build with docker
|
||||
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_test_git")
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
repo})...)
|
||||
repo,
|
||||
})...)
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build image %s with docker command %q: %s %s", dockerImage, dockerCmd.Args, err, string(out))
|
||||
|
|
@ -363,10 +365,12 @@ func TestBuildViaRegistryMirrors(t *testing.T) {
|
|||
// Build with docker
|
||||
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_registry_mirror")
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
repo})...)
|
||||
repo,
|
||||
})...)
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build image %s with docker command %q: %s %s", dockerImage, dockerCmd.Args, err, string(out))
|
||||
|
|
@ -403,10 +407,12 @@ func TestBuildViaRegistryMap(t *testing.T) {
|
|||
// Build with docker
|
||||
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_registry_mirror")
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
repo})...)
|
||||
repo,
|
||||
})...)
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build image %s with docker command %q: %s %s", dockerImage, dockerCmd.Args, err, string(out))
|
||||
|
|
@ -467,10 +473,12 @@ func TestKanikoDir(t *testing.T) {
|
|||
// Build with docker
|
||||
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_registry_mirror")
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
repo})...)
|
||||
repo,
|
||||
})...)
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build image %s with docker command %q: %s %s", dockerImage, dockerCmd.Args, err, string(out))
|
||||
|
|
@ -508,11 +516,13 @@ func TestBuildWithLabels(t *testing.T) {
|
|||
// Build with docker
|
||||
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_test_label:mylabel")
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
"--label", testLabel,
|
||||
repo})...)
|
||||
repo,
|
||||
})...)
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
if err != nil {
|
||||
t.Errorf("Failed to build image %s with docker command %q: %s %s", dockerImage, dockerCmd.Args, err, string(out))
|
||||
|
|
@ -549,10 +559,12 @@ func TestBuildWithHTTPError(t *testing.T) {
|
|||
// Build with docker
|
||||
dockerImage := GetDockerImage(config.imageRepo, "Dockerfile_test_add_404")
|
||||
dockerCmd := exec.Command("docker",
|
||||
append([]string{"build",
|
||||
append([]string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile,
|
||||
repo})...)
|
||||
repo,
|
||||
})...)
|
||||
out, err := RunCommandWithoutTest(dockerCmd)
|
||||
if err == nil {
|
||||
t.Errorf("an error was expected, got %s", string(out))
|
||||
|
|
@ -588,6 +600,7 @@ func TestLayers(t *testing.T) {
|
|||
// produces a different amount of layers (?).
|
||||
offset["Dockerfile_test_copy_same_file_many_times"] = 47
|
||||
offset["Dockerfile_test_meta_arg"] = 1
|
||||
offset["Dockerfile_test_copyadd_chmod"] = 6
|
||||
}
|
||||
|
||||
for _, dockerfile := range allDockerfiles {
|
||||
|
|
@ -732,7 +745,6 @@ func verifyBuildWith(t *testing.T, cache, dockerfile string) {
|
|||
}
|
||||
|
||||
func TestRelativePaths(t *testing.T) {
|
||||
|
||||
dockerfile := "Dockerfile_relative_copy"
|
||||
|
||||
t.Run("test_relative_"+dockerfile, func(t *testing.T) {
|
||||
|
|
@ -763,7 +775,6 @@ func TestRelativePaths(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestExitCodePropagation(t *testing.T) {
|
||||
|
||||
currentDir, err := os.Getwd()
|
||||
if err != nil {
|
||||
t.Fatal("Could not get working dir")
|
||||
|
|
@ -778,7 +789,8 @@ func TestExitCodePropagation(t *testing.T) {
|
|||
dockerFlags := []string{
|
||||
"build",
|
||||
"-t", dockerImage,
|
||||
"-f", dockerfile}
|
||||
"-f", dockerfile,
|
||||
}
|
||||
dockerCmd := exec.Command("docker", append(dockerFlags, context)...)
|
||||
|
||||
out, kanikoErr := RunCommandWithoutTest(dockerCmd)
|
||||
|
|
@ -798,7 +810,7 @@ func TestExitCodePropagation(t *testing.T) {
|
|||
t.Fatalf("did not produce the expected error:\n%s", out)
|
||||
}
|
||||
|
||||
//try to build the same image with kaniko the error code should match with the one from the plain docker build
|
||||
// try to build the same image with kaniko the error code should match with the one from the plain docker build
|
||||
contextVolume := fmt.Sprintf("%s:/workspace", context)
|
||||
|
||||
dockerFlags = []string{
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ limitations under the License.
|
|||
package commands
|
||||
|
||||
import (
|
||||
"io/fs"
|
||||
"path/filepath"
|
||||
|
||||
v1 "github.com/google/go-containerregistry/pkg/v1"
|
||||
|
|
@ -47,6 +48,14 @@ type AddCommand struct {
|
|||
func (a *AddCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
||||
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
|
||||
|
||||
chmod, useDefaultChmod, err := util.GetChmod(a.cmd.Chmod, replacementEnvs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting permissions from chmod")
|
||||
}
|
||||
if useDefaultChmod {
|
||||
chmod = fs.FileMode(0o600)
|
||||
}
|
||||
|
||||
uid, gid, err := util.GetUserGroup(a.cmd.Chown, replacementEnvs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting user group from chown")
|
||||
|
|
@ -71,7 +80,7 @@ func (a *AddCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
|
|||
return err
|
||||
}
|
||||
logrus.Infof("Adding remote URL %s to %s", src, urlDest)
|
||||
if err := util.DownloadFileToDest(src, urlDest, uid, gid); err != nil {
|
||||
if err := util.DownloadFileToDest(src, urlDest, uid, gid, chmod); err != nil {
|
||||
return errors.Wrap(err, "downloading remote source file")
|
||||
}
|
||||
a.snapshotFiles = append(a.snapshotFiles, urlDest)
|
||||
|
|
@ -100,6 +109,7 @@ func (a *AddCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
|
|||
cmd: &instructions.CopyCommand{
|
||||
SourcesAndDest: instructions.SourcesAndDest{SourcePaths: unresolvedSrcs, DestPath: dest},
|
||||
Chown: a.cmd.Chown,
|
||||
Chmod: a.cmd.Chmod,
|
||||
},
|
||||
fileContext: a.fileContext,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,11 @@ func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu
|
|||
return errors.Wrap(err, "resolving src")
|
||||
}
|
||||
|
||||
chmod, useDefaultChmod, err := util.GetChmod(c.cmd.Chmod, replacementEnvs)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "getting permissions from chmod")
|
||||
}
|
||||
|
||||
// For each source, iterate through and copy it over
|
||||
for _, src := range srcs {
|
||||
fullPath := filepath.Join(c.fileContext.Root, src)
|
||||
|
|
@ -93,7 +98,7 @@ func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu
|
|||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
copiedFiles, err := util.CopyDir(fullPath, destPath, c.fileContext, uid, gid)
|
||||
copiedFiles, err := util.CopyDir(fullPath, destPath, c.fileContext, uid, gid, chmod, useDefaultChmod)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "copying dir")
|
||||
}
|
||||
|
|
@ -110,7 +115,7 @@ func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu
|
|||
c.snapshotFiles = append(c.snapshotFiles, destPath)
|
||||
} else {
|
||||
// ... Else, we want to copy over a file
|
||||
exclude, err := util.CopyFile(fullPath, destPath, c.fileContext, uid, gid)
|
||||
exclude, err := util.CopyFile(fullPath, destPath, c.fileContext, uid, gid, chmod, useDefaultChmod)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "copying file")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package util
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/user"
|
||||
|
|
@ -370,6 +371,24 @@ func GetUserGroup(chownStr string, env []string) (int64, int64, error) {
|
|||
return int64(uid32), int64(gid32), nil
|
||||
}
|
||||
|
||||
func GetChmod(chmodStr string, env []string) (chmod fs.FileMode, useDefault bool, err error) {
|
||||
if chmodStr == "" {
|
||||
return fs.FileMode(0o600), true, nil
|
||||
}
|
||||
|
||||
chmodStr, err = ResolveEnvironmentReplacement(chmodStr, env, false)
|
||||
if err != nil {
|
||||
return 0, false, err
|
||||
}
|
||||
|
||||
mode, err := strconv.ParseUint(chmodStr, 8, 32)
|
||||
if err != nil {
|
||||
return 0, false, errors.Wrap(err, "parsing value from chmod")
|
||||
}
|
||||
chmod = fs.FileMode(mode)
|
||||
return
|
||||
}
|
||||
|
||||
// Extract user and group id from a string formatted 'user:group'.
|
||||
// UserID and GroupID don't need to be present on the system.
|
||||
func getUIDAndGIDFromString(userGroupString string) (uint32, uint32, error) {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package util
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os/user"
|
||||
"reflect"
|
||||
"sort"
|
||||
|
|
@ -308,7 +309,8 @@ var updateConfigEnvTests = []struct {
|
|||
{
|
||||
Key: "foo",
|
||||
Value: "baz",
|
||||
}},
|
||||
},
|
||||
},
|
||||
config: &v1.Config{},
|
||||
replacementEnvs: []string{},
|
||||
expectedEnv: []string{"key=var", "foo=baz"},
|
||||
|
|
@ -326,7 +328,8 @@ var updateConfigEnvTests = []struct {
|
|||
{
|
||||
Key: "foo",
|
||||
Value: "$argarg",
|
||||
}},
|
||||
},
|
||||
},
|
||||
config: &v1.Config{},
|
||||
replacementEnvs: []string{"var=/test/with'chars'/", "not=used", "argarg=\"a\"b\""},
|
||||
expectedEnv: []string{"key=/var/run", "env=/test/with'chars'/", "foo=\"a\"b\""},
|
||||
|
|
@ -340,7 +343,8 @@ var updateConfigEnvTests = []struct {
|
|||
{
|
||||
Key: "bob",
|
||||
Value: "cool",
|
||||
}},
|
||||
},
|
||||
},
|
||||
config: &v1.Config{Env: []string{"bob=used", "more=test"}},
|
||||
replacementEnvs: []string{},
|
||||
expectedEnv: []string{"bob=cool", "more=test", "alice=nice"},
|
||||
|
|
@ -585,6 +589,43 @@ func TestGetUserGroup(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestGetChmod(t *testing.T) {
|
||||
tests := []struct {
|
||||
description string
|
||||
chmod string
|
||||
env []string
|
||||
expected fs.FileMode
|
||||
shdErr bool
|
||||
}{
|
||||
{
|
||||
description: "non empty chmod",
|
||||
chmod: "0755",
|
||||
env: []string{},
|
||||
expected: fs.FileMode(0o755),
|
||||
},
|
||||
{
|
||||
description: "non empty chmod with env replacement",
|
||||
chmod: "$foo",
|
||||
env: []string{"foo=0750"},
|
||||
expected: fs.FileMode(0o750),
|
||||
},
|
||||
{
|
||||
description: "empty chmod string",
|
||||
expected: fs.FileMode(0o600),
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
defaultChmod := fs.FileMode(0o600)
|
||||
chmod, useDefault, err := GetChmod(tc.chmod, tc.env)
|
||||
if useDefault {
|
||||
chmod = defaultChmod
|
||||
}
|
||||
testutil.CheckErrorAndDeepEqual(t, tc.shdErr, err, tc.expected, chmod)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolveEnvironmentReplacementList(t *testing.T) {
|
||||
type args struct {
|
||||
values []string
|
||||
|
|
@ -806,7 +847,6 @@ func TestLookupUser(t *testing.T) {
|
|||
testutil.CheckErrorAndDeepEqual(t, tt.wantErr, err, tt.expected, got)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestIsSrcRemoteFileURL(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
|
|
@ -325,7 +326,7 @@ func ExtractFile(dest string, hdr *tar.Header, cleanedName string, tr io.Reader)
|
|||
if os.IsNotExist(err) || !fi.IsDir() {
|
||||
logrus.Debugf("Base %s for file %s does not exist. Creating.", base, path)
|
||||
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
|
@ -377,7 +378,7 @@ func ExtractFile(dest string, hdr *tar.Header, cleanedName string, tr io.Reader)
|
|||
return nil
|
||||
}
|
||||
// The base directory for a link may not exist before it is created.
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check if something already exists at path
|
||||
|
|
@ -395,7 +396,7 @@ func ExtractFile(dest string, hdr *tar.Header, cleanedName string, tr io.Reader)
|
|||
case tar.TypeSymlink:
|
||||
logrus.Tracef("Symlink from %s to %s", hdr.Linkname, path)
|
||||
// The base directory for a symlink may not exist before it is created.
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
return err
|
||||
}
|
||||
// Check if something already exists at path
|
||||
|
|
@ -621,9 +622,9 @@ func AddVolumePathToIgnoreList(path string) {
|
|||
// DownloadFileToDest downloads the file at rawurl to the given dest for the ADD command
|
||||
// From add command docs:
|
||||
// 1. If <src> is a remote file URL:
|
||||
// - destination will have permissions of 0600
|
||||
// - destination will have permissions of 0600 by default if not specified with chmod
|
||||
// - If remote file has HTTP Last-Modified header, we set the mtime of the file to that timestamp
|
||||
func DownloadFileToDest(rawurl, dest string, uid, gid int64) error {
|
||||
func DownloadFileToDest(rawurl, dest string, uid, gid int64, chmod fs.FileMode) error {
|
||||
resp, err := http.Get(rawurl) //nolint:noctx
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -634,7 +635,7 @@ func DownloadFileToDest(rawurl, dest string, uid, gid int64) error {
|
|||
return fmt.Errorf("invalid response status %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
if err := CreateFile(dest, resp.Body, 0600, uint32(uid), uint32(gid)); err != nil {
|
||||
if err := CreateFile(dest, resp.Body, chmod, uint32(uid), uint32(gid)); err != nil {
|
||||
return err
|
||||
}
|
||||
mTime := time.Time{}
|
||||
|
|
@ -661,7 +662,7 @@ func DetermineTargetFileOwnership(fi os.FileInfo, uid, gid int64) (int64, int64)
|
|||
|
||||
// CopyDir copies the file or directory at src to dest
|
||||
// It returns a list of files it copied over
|
||||
func CopyDir(src, dest string, context FileContext, uid, gid int64) ([]string, error) {
|
||||
func CopyDir(src, dest string, context FileContext, uid, gid int64, chmod fs.FileMode, useDefaultChmod bool) ([]string, error) {
|
||||
files, err := RelativeFiles("", src)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "copying dir")
|
||||
|
|
@ -681,7 +682,10 @@ func CopyDir(src, dest string, context FileContext, uid, gid int64) ([]string, e
|
|||
if fi.IsDir() {
|
||||
logrus.Tracef("Creating directory %s", destPath)
|
||||
|
||||
mode := fi.Mode()
|
||||
mode := chmod
|
||||
if useDefaultChmod {
|
||||
mode = fi.Mode()
|
||||
}
|
||||
uid, gid := DetermineTargetFileOwnership(fi, uid, gid)
|
||||
if err := MkdirAllWithPermissions(destPath, mode, uid, gid); err != nil {
|
||||
return nil, err
|
||||
|
|
@ -693,7 +697,12 @@ func CopyDir(src, dest string, context FileContext, uid, gid int64) ([]string, e
|
|||
}
|
||||
} else {
|
||||
// ... Else, we want to copy over a file
|
||||
if _, err := CopyFile(fullPath, destPath, context, uid, gid); err != nil {
|
||||
mode := chmod
|
||||
if useDefaultChmod {
|
||||
mode = fs.FileMode(0o600)
|
||||
}
|
||||
|
||||
if _, err := CopyFile(fullPath, destPath, context, uid, gid, mode, useDefaultChmod); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -724,7 +733,7 @@ func CopySymlink(src, dest string, context FileContext) (bool, error) {
|
|||
}
|
||||
|
||||
// CopyFile copies the file at src to dest
|
||||
func CopyFile(src, dest string, context FileContext, uid, gid int64) (bool, error) {
|
||||
func CopyFile(src, dest string, context FileContext, uid, gid int64, chmod fs.FileMode, useDefaultChmod bool) (bool, error) {
|
||||
if context.ExcludesFile(src) {
|
||||
logrus.Debugf("%s found in .dockerignore, ignoring", src)
|
||||
return true, nil
|
||||
|
|
@ -746,7 +755,12 @@ func CopyFile(src, dest string, context FileContext, uid, gid int64) (bool, erro
|
|||
}
|
||||
defer srcFile.Close()
|
||||
uid, gid = DetermineTargetFileOwnership(fi, uid, gid)
|
||||
return false, CreateFile(dest, srcFile, fi.Mode(), uint32(uid), uint32(gid))
|
||||
|
||||
mode := chmod
|
||||
if useDefaultChmod {
|
||||
mode = fi.Mode()
|
||||
}
|
||||
return false, CreateFile(dest, srcFile, mode, uint32(uid), uint32(gid))
|
||||
}
|
||||
|
||||
func NewFileContextFromDockerfile(dockerfilePath, buildcontext string) (FileContext, error) {
|
||||
|
|
@ -903,7 +917,7 @@ func CreateTargetTarfile(tarpath string) (*os.File, error) {
|
|||
baseDir := filepath.Dir(tarpath)
|
||||
if _, err := os.Lstat(baseDir); os.IsNotExist(err) {
|
||||
logrus.Debugf("BaseDir %s for file %s does not exist. Creating.", baseDir, tarpath)
|
||||
if err := os.MkdirAll(baseDir, 0755); err != nil {
|
||||
if err := os.MkdirAll(baseDir, 0o755); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
|
@ -1040,7 +1054,7 @@ func createParentDirectory(path string, uid int, gid int) error {
|
|||
dir := dirs[i]
|
||||
|
||||
if _, err := os.Lstat(dir); os.IsNotExist(err) {
|
||||
os.Mkdir(dir, 0755)
|
||||
os.Mkdir(dir, 0o755)
|
||||
if uid != DoNotChangeUID {
|
||||
if gid != DoNotChangeGID {
|
||||
os.Chown(dir, uid, gid)
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import (
|
|||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
|
|
@ -48,10 +49,10 @@ func Test_DetectFilesystemSkiplist(t *testing.T) {
|
|||
232 228 0:101 / /sys ro,nosuid,nodev,noexec,relatime - sysfs sysfs ro`
|
||||
|
||||
path := filepath.Join(testDir, "mountinfo")
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0750); err != nil {
|
||||
if err := os.MkdirAll(filepath.Dir(path), 0o750); err != nil {
|
||||
t.Fatalf("Error creating tempdir: %s", err)
|
||||
}
|
||||
if err := os.WriteFile(path, []byte(fileContents), 0644); err != nil {
|
||||
if err := os.WriteFile(path, []byte(fileContents), 0o644); err != nil {
|
||||
t.Fatalf("Error writing file contents to %s: %s", path, err)
|
||||
}
|
||||
|
||||
|
|
@ -671,7 +672,6 @@ func Test_UnTar(t *testing.T) {
|
|||
sort.Strings(tc.expectedFileList)
|
||||
sort.Strings(fileList)
|
||||
testutil.CheckErrorAndDeepEqual(t, tc.errorExpected, err, tc.expectedFileList, fileList)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -694,37 +694,37 @@ func TestExtractFile(t *testing.T) {
|
|||
{
|
||||
name: "normal file",
|
||||
contents: []byte("helloworld"),
|
||||
hdrs: []*tar.Header{fileHeader("./bar", "helloworld", 0644, defaultTestTime)},
|
||||
hdrs: []*tar.Header{fileHeader("./bar", "helloworld", 0o644, defaultTestTime)},
|
||||
checkers: []checker{
|
||||
fileExists("/bar"),
|
||||
fileMatches("/bar", []byte("helloworld")),
|
||||
permissionsMatch("/bar", 0644),
|
||||
permissionsMatch("/bar", 0o644),
|
||||
timesMatch("/bar", defaultTestTime),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "normal file, directory does not exist",
|
||||
contents: []byte("helloworld"),
|
||||
hdrs: []*tar.Header{fileHeader("./foo/bar", "helloworld", 0644, defaultTestTime)},
|
||||
hdrs: []*tar.Header{fileHeader("./foo/bar", "helloworld", 0o644, defaultTestTime)},
|
||||
checkers: []checker{
|
||||
fileExists("/foo/bar"),
|
||||
fileMatches("/foo/bar", []byte("helloworld")),
|
||||
permissionsMatch("/foo/bar", 0644),
|
||||
permissionsMatch("/foo", 0755|os.ModeDir),
|
||||
permissionsMatch("/foo/bar", 0o644),
|
||||
permissionsMatch("/foo", 0o755|os.ModeDir),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "normal file, directory is created after",
|
||||
contents: []byte("helloworld"),
|
||||
hdrs: []*tar.Header{
|
||||
fileHeader("./foo/bar", "helloworld", 0644, defaultTestTime),
|
||||
dirHeader("./foo", 0722),
|
||||
fileHeader("./foo/bar", "helloworld", 0o644, defaultTestTime),
|
||||
dirHeader("./foo", 0o722),
|
||||
},
|
||||
checkers: []checker{
|
||||
fileExists("/foo/bar"),
|
||||
fileMatches("/foo/bar", []byte("helloworld")),
|
||||
permissionsMatch("/foo/bar", 0644),
|
||||
permissionsMatch("/foo", 0722|os.ModeDir),
|
||||
permissionsMatch("/foo/bar", 0o644),
|
||||
permissionsMatch("/foo", 0o722|os.ModeDir),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
@ -753,15 +753,15 @@ func TestExtractFile(t *testing.T) {
|
|||
hdrs: []*tar.Header{linkHeader("./foo/bar/baz", "../../bat")},
|
||||
checkers: []checker{
|
||||
linkPointsTo("/foo/bar/baz", "../../bat"),
|
||||
permissionsMatch("/foo", 0755|os.ModeDir),
|
||||
permissionsMatch("/foo/bar", 0755|os.ModeDir),
|
||||
permissionsMatch("/foo", 0o755|os.ModeDir),
|
||||
permissionsMatch("/foo/bar", 0o755|os.ModeDir),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hardlink",
|
||||
tmpdir: "/tmp/hardlink",
|
||||
hdrs: []*tar.Header{
|
||||
fileHeader("/bin/gzip", "gzip-binary", 0751, defaultTestTime),
|
||||
fileHeader("/bin/gzip", "gzip-binary", 0o751, defaultTestTime),
|
||||
hardlinkHeader("/bin/uncompress", "/bin/gzip"),
|
||||
},
|
||||
checkers: []checker{
|
||||
|
|
@ -772,25 +772,25 @@ func TestExtractFile(t *testing.T) {
|
|||
{
|
||||
name: "file with setuid bit",
|
||||
contents: []byte("helloworld"),
|
||||
hdrs: []*tar.Header{fileHeader("./bar", "helloworld", 04644, defaultTestTime)},
|
||||
hdrs: []*tar.Header{fileHeader("./bar", "helloworld", 0o4644, defaultTestTime)},
|
||||
checkers: []checker{
|
||||
fileExists("/bar"),
|
||||
fileMatches("/bar", []byte("helloworld")),
|
||||
permissionsMatch("/bar", 0644|os.ModeSetuid),
|
||||
permissionsMatch("/bar", 0o644|os.ModeSetuid),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "dir with sticky bit",
|
||||
contents: []byte("helloworld"),
|
||||
hdrs: []*tar.Header{
|
||||
dirHeader("./foo", 01755),
|
||||
fileHeader("./foo/bar", "helloworld", 0644, defaultTestTime),
|
||||
dirHeader("./foo", 0o1755),
|
||||
fileHeader("./foo/bar", "helloworld", 0o644, defaultTestTime),
|
||||
},
|
||||
checkers: []checker{
|
||||
fileExists("/foo/bar"),
|
||||
fileMatches("/foo/bar", []byte("helloworld")),
|
||||
permissionsMatch("/foo/bar", 0644),
|
||||
permissionsMatch("/foo", 0755|os.ModeDir|os.ModeSticky),
|
||||
permissionsMatch("/foo/bar", 0o644),
|
||||
permissionsMatch("/foo", 0o755|os.ModeDir|os.ModeSticky),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -839,7 +839,7 @@ func TestCopySymlink(t *testing.T) {
|
|||
linkTarget: "/abs/dest",
|
||||
dest: "overwrite_me",
|
||||
beforeLink: func(r string) error {
|
||||
return os.WriteFile(filepath.Join(r, "overwrite_me"), nil, 0644)
|
||||
return os.WriteFile(filepath.Join(r, "overwrite_me"), nil, 0o644)
|
||||
},
|
||||
}}
|
||||
|
||||
|
|
@ -848,9 +848,9 @@ func TestCopySymlink(t *testing.T) {
|
|||
tc := tc
|
||||
t.Parallel()
|
||||
r := t.TempDir()
|
||||
os.MkdirAll(filepath.Join(r, filepath.Dir(tc.linkTarget)), 0777)
|
||||
os.MkdirAll(filepath.Join(r, filepath.Dir(tc.linkTarget)), 0o777)
|
||||
tc.linkTarget = filepath.Join(r, tc.linkTarget)
|
||||
os.WriteFile(tc.linkTarget, nil, 0644)
|
||||
os.WriteFile(tc.linkTarget, nil, 0o644)
|
||||
|
||||
if tc.beforeLink != nil {
|
||||
if err := tc.beforeLink(r); err != nil {
|
||||
|
|
@ -982,12 +982,12 @@ func Test_CopyFile_skips_self(t *testing.T) {
|
|||
if err := os.WriteFile(
|
||||
tempFile,
|
||||
[]byte(expected),
|
||||
0755,
|
||||
0o755,
|
||||
); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ignored, err := CopyFile(tempFile, tempFile, FileContext{}, DoNotChangeUID, DoNotChangeGID)
|
||||
ignored, err := CopyFile(tempFile, tempFile, FileContext{}, DoNotChangeUID, DoNotChangeGID, fs.FileMode(0o600), true)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
@ -1012,7 +1012,7 @@ func fakeExtract(_ string, _ *tar.Header, _ string, _ io.Reader) error {
|
|||
}
|
||||
|
||||
func Test_GetFSFromLayers_with_whiteouts_include_whiteout_enabled(t *testing.T) {
|
||||
var resetMountInfoFile = provideEmptyMountinfoFile()
|
||||
resetMountInfoFile := provideEmptyMountinfoFile()
|
||||
defer resetMountInfoFile()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
|
|
@ -1020,7 +1020,7 @@ func Test_GetFSFromLayers_with_whiteouts_include_whiteout_enabled(t *testing.T)
|
|||
root := t.TempDir()
|
||||
// Write a whiteout path
|
||||
d1 := []byte("Hello World\n")
|
||||
if err := os.WriteFile(filepath.Join(root, "foobar"), d1, 0644); err != nil {
|
||||
if err := os.WriteFile(filepath.Join(root, "foobar"), d1, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -1039,7 +1039,7 @@ func Test_GetFSFromLayers_with_whiteouts_include_whiteout_enabled(t *testing.T)
|
|||
|
||||
hdr := &tar.Header{
|
||||
Name: f,
|
||||
Mode: 0644,
|
||||
Mode: 0o644,
|
||||
Size: int64(len("Hello World\n")),
|
||||
}
|
||||
|
||||
|
|
@ -1121,7 +1121,7 @@ func provideEmptyMountinfoFile() func() {
|
|||
}
|
||||
|
||||
func Test_GetFSFromLayers_with_whiteouts_include_whiteout_disabled(t *testing.T) {
|
||||
var resetMountInfoFile = provideEmptyMountinfoFile()
|
||||
resetMountInfoFile := provideEmptyMountinfoFile()
|
||||
defer resetMountInfoFile()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
|
|
@ -1129,7 +1129,7 @@ func Test_GetFSFromLayers_with_whiteouts_include_whiteout_disabled(t *testing.T)
|
|||
root := t.TempDir()
|
||||
// Write a whiteout path
|
||||
d1 := []byte("Hello World\n")
|
||||
if err := os.WriteFile(filepath.Join(root, "foobar"), d1, 0644); err != nil {
|
||||
if err := os.WriteFile(filepath.Join(root, "foobar"), d1, 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -1147,7 +1147,7 @@ func Test_GetFSFromLayers_with_whiteouts_include_whiteout_disabled(t *testing.T)
|
|||
|
||||
hdr := &tar.Header{
|
||||
Name: f,
|
||||
Mode: 0644,
|
||||
Mode: 0o644,
|
||||
Size: int64(len("Hello world\n")),
|
||||
}
|
||||
|
||||
|
|
@ -1224,7 +1224,7 @@ func Test_GetFSFromLayers_with_whiteouts_include_whiteout_disabled(t *testing.T)
|
|||
}
|
||||
|
||||
func Test_GetFSFromLayers_ignorelist(t *testing.T) {
|
||||
var resetMountInfoFile = provideEmptyMountinfoFile()
|
||||
resetMountInfoFile := provideEmptyMountinfoFile()
|
||||
defer resetMountInfoFile()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
|
|
@ -1232,7 +1232,7 @@ func Test_GetFSFromLayers_ignorelist(t *testing.T) {
|
|||
root := t.TempDir()
|
||||
// Write a whiteout path
|
||||
fileContents := []byte("Hello World\n")
|
||||
if err := os.Mkdir(filepath.Join(root, "testdir"), 0775); err != nil {
|
||||
if err := os.Mkdir(filepath.Join(root, "testdir"), 0o775); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -1249,7 +1249,7 @@ func Test_GetFSFromLayers_ignorelist(t *testing.T) {
|
|||
|
||||
hdr := &tar.Header{
|
||||
Name: f,
|
||||
Mode: 0644,
|
||||
Mode: 0o644,
|
||||
Size: int64(len(string(fileContents))),
|
||||
}
|
||||
|
||||
|
|
@ -1321,7 +1321,7 @@ func Test_GetFSFromLayers_ignorelist(t *testing.T) {
|
|||
defaultIgnoreList = append(defaultIgnoreList, IgnoreListEntry{
|
||||
Path: filepath.Join(root, "testdir"),
|
||||
})
|
||||
if err := os.Mkdir(filepath.Join(root, "testdir"), 0775); err != nil {
|
||||
if err := os.Mkdir(filepath.Join(root, "testdir"), 0o775); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
@ -1392,7 +1392,7 @@ func Test_GetFSFromLayers(t *testing.T) {
|
|||
|
||||
hdr := &tar.Header{
|
||||
Name: f,
|
||||
Mode: 0644,
|
||||
Mode: 0o644,
|
||||
Size: int64(len("Hello world\n")),
|
||||
}
|
||||
|
||||
|
|
@ -1519,7 +1519,7 @@ func Test_setFileTimes(t *testing.T) {
|
|||
|
||||
p := filepath.Join(testDir, "foo.txt")
|
||||
|
||||
if err := os.WriteFile(p, []byte("meow"), 0777); err != nil {
|
||||
if err := os.WriteFile(p, []byte("meow"), 0o777); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue