Compare commits
4 Commits
377e7dd595
...
aa3ff604e1
| Author | SHA1 | Date |
|---|---|---|
|
|
aa3ff604e1 | |
|
|
236ba5690e | |
|
|
fa67e45814 | |
|
|
e1369aadf7 |
|
|
@ -1,2 +0,0 @@
|
||||||
Jerome Ju <jeromeju@google.com>
|
|
||||||
Quan Zhang <zhangquan@google.com>
|
|
||||||
|
|
@ -1,3 +1,11 @@
|
||||||
|
# 🧊 This project is archived and no longer developed or maintained. 🧊
|
||||||
|
|
||||||
|
The code remains available for historic purposes.
|
||||||
|
|
||||||
|
The README as of the archival date remains unchanged below for historic purposes.
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
# kaniko - Build Images In Kubernetes
|
# kaniko - Build Images In Kubernetes
|
||||||
|
|
||||||
## 🚨NOTE: kaniko is not an officially supported Google product🚨
|
## 🚨NOTE: kaniko is not an officially supported Google product🚨
|
||||||
|
|
|
||||||
|
|
@ -257,6 +257,8 @@ func addKanikoOptionsFlags() {
|
||||||
RootCmd.PersistentFlags().VarP(&opts.Compression, "compression", "", "Compression algorithm (gzip, zstd)")
|
RootCmd.PersistentFlags().VarP(&opts.Compression, "compression", "", "Compression algorithm (gzip, zstd)")
|
||||||
RootCmd.PersistentFlags().IntVarP(&opts.CompressionLevel, "compression-level", "", -1, "Compression level")
|
RootCmd.PersistentFlags().IntVarP(&opts.CompressionLevel, "compression-level", "", -1, "Compression level")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.Cache, "cache", "", false, "Use cache when building image")
|
RootCmd.PersistentFlags().BoolVarP(&opts.Cache, "cache", "", false, "Use cache when building image")
|
||||||
|
RootCmd.PersistentFlags().VarP(&opts.ExcludeBuildArgsFromCacheKey, "exclude-build-arg-from-cache-key", "", "This flag allows you to exclude ARG values from the cache key. Set it repeatedly for multiple values.")
|
||||||
|
RootCmd.PersistentFlags().VarP(&opts.ExcludeEnvsFromCacheKey, "exclude-env-from-cache-key", "", "This flag allows you to exclude ENV values from the cache key. Set it repeatedly for multiple values.")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.CompressedCaching, "compressed-caching", "", true, "Compress the cached layers. Decreases build time, but increases memory usage.")
|
RootCmd.PersistentFlags().BoolVarP(&opts.CompressedCaching, "compressed-caching", "", true, "Compress the cached layers. Decreases build time, but increases memory usage.")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.Cleanup, "cleanup", "", false, "Clean the filesystem at the end")
|
RootCmd.PersistentFlags().BoolVarP(&opts.Cleanup, "cleanup", "", false, "Clean the filesystem at the end")
|
||||||
RootCmd.PersistentFlags().DurationVarP(&opts.CacheTTL, "cache-ttl", "", time.Hour*336, "Cache timeout, requires value and unit of duration -> ex: 6h. Defaults to two weeks.")
|
RootCmd.PersistentFlags().DurationVarP(&opts.CacheTTL, "cache-ttl", "", time.Hour*336, "Cache timeout, requires value and unit of duration -> ex: 6h. Defaults to two weeks.")
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,9 @@ import (
|
||||||
type CacheOptions struct {
|
type CacheOptions struct {
|
||||||
CacheDir string
|
CacheDir string
|
||||||
CacheTTL time.Duration
|
CacheTTL time.Duration
|
||||||
|
|
||||||
|
ExcludeBuildArgsFromCacheKey multiArg
|
||||||
|
ExcludeEnvsFromCacheKey multiArg
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegistryOptions are all the options related to the registries, set by command line arguments.
|
// RegistryOptions are all the options related to the registries, set by command line arguments.
|
||||||
|
|
|
||||||
|
|
@ -199,20 +199,39 @@ func isOCILayout(path string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *stageBuilder) populateCompositeKey(command commands.DockerCommand, files []string, compositeKey CompositeCache, args *dockerfile.BuildArgs, env []string) (CompositeCache, error) {
|
func (s *stageBuilder) populateCompositeKey(command commands.DockerCommand, files []string, compositeKey CompositeCache, args *dockerfile.BuildArgs, env []string) (CompositeCache, error) {
|
||||||
// First replace all the environment variables or args in the command
|
|
||||||
replacementEnvs := args.ReplacementEnvs(env)
|
|
||||||
// The sort order of `replacementEnvs` is basically undefined, sort it
|
|
||||||
// so we can ensure a stable cache key.
|
|
||||||
sort.Strings(replacementEnvs)
|
|
||||||
// Use the special argument "|#" at the start of the args array. This will
|
|
||||||
// avoid conflicts with any RUN command since commands can not
|
|
||||||
// start with | (vertical bar). The "#" (number of build envs) is there to
|
|
||||||
// help ensure proper cache matches.
|
|
||||||
|
|
||||||
if command.IsArgsEnvsRequiredInCache() {
|
if command.IsArgsEnvsRequiredInCache() {
|
||||||
if len(replacementEnvs) > 0 {
|
filteredEnvs := []string{}
|
||||||
compositeKey.AddKey(fmt.Sprintf("|%d", len(replacementEnvs)))
|
for _, e := range env {
|
||||||
compositeKey.AddKey(replacementEnvs...)
|
envName := strings.SplitN(e, "=", 2)[0]
|
||||||
|
if s.opts.ExcludeEnvsFromCacheKey.Contains(envName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filteredEnvs = append(filteredEnvs, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
// First replace all the environment variables or args in the command
|
||||||
|
envsAndBuildArgs := args.ReplacementEnvs(filteredEnvs)
|
||||||
|
|
||||||
|
filteredEnvsAndBuildArgs := []string{}
|
||||||
|
for i, env := range envsAndBuildArgs {
|
||||||
|
envArgName := strings.SplitN(env, "=", 2)[0]
|
||||||
|
if s.opts.ExcludeBuildArgsFromCacheKey.Contains(envArgName) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
filteredEnvsAndBuildArgs = append(filteredEnvs, envsAndBuildArgs[i])
|
||||||
|
}
|
||||||
|
|
||||||
|
// The sort order of `filteredEnvs` is basically undefined, sort it
|
||||||
|
// so we can ensure a stable cache key.
|
||||||
|
sort.Strings(filteredEnvsAndBuildArgs)
|
||||||
|
|
||||||
|
if len(filteredEnvsAndBuildArgs) > 0 {
|
||||||
|
// Use the special argument "|#" at the start of the args array. This will
|
||||||
|
// avoid conflicts with any RUN command since commands can not
|
||||||
|
// start with | (vertical bar). The "#" (number of build envs) is there to
|
||||||
|
// help ensure proper cache matches.
|
||||||
|
compositeKey.AddKey(fmt.Sprintf("|%d", len(filteredEnvsAndBuildArgs)))
|
||||||
|
compositeKey.AddKey(filteredEnvsAndBuildArgs...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -655,10 +655,12 @@ func newStageContext(command string, args map[string]string, env []string) stage
|
||||||
|
|
||||||
func Test_stageBuilder_populateCompositeKey(t *testing.T) {
|
func Test_stageBuilder_populateCompositeKey(t *testing.T) {
|
||||||
type testcase struct {
|
type testcase struct {
|
||||||
description string
|
description string
|
||||||
cmd1 stageContext
|
cmd1 stageContext
|
||||||
cmd2 stageContext
|
cmd2 stageContext
|
||||||
shdEqual bool
|
shdEqual bool
|
||||||
|
excludeBuildArgsFromCacheKey []string
|
||||||
|
excludeEnvsFromCacheKey []string
|
||||||
}
|
}
|
||||||
testCases := []testcase{
|
testCases := []testcase{
|
||||||
{
|
{
|
||||||
|
|
@ -744,6 +746,21 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) {
|
||||||
[]string{},
|
[]string{},
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "cache key for same command [RUN] with a build arg values, with excludeBuildArgsFromCacheKey set",
|
||||||
|
cmd1: newStageContext(
|
||||||
|
"RUN echo $ARG > test",
|
||||||
|
map[string]string{"ARG": "foo"},
|
||||||
|
[]string{},
|
||||||
|
),
|
||||||
|
cmd2: newStageContext(
|
||||||
|
"RUN echo $ARG > test",
|
||||||
|
map[string]string{"ARG": "bar"},
|
||||||
|
[]string{},
|
||||||
|
),
|
||||||
|
shdEqual: true,
|
||||||
|
excludeBuildArgsFromCacheKey: []string{"ARG"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
description: "cache key for same command [RUN] with different env values",
|
description: "cache key for same command [RUN] with different env values",
|
||||||
cmd1: newStageContext(
|
cmd1: newStageContext(
|
||||||
|
|
@ -798,6 +815,21 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) {
|
||||||
),
|
),
|
||||||
shdEqual: false,
|
shdEqual: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
description: "cache key for command [RUN] with different env values, when excludeEnvsFromCacheKey is set",
|
||||||
|
cmd1: newStageContext(
|
||||||
|
"RUN echo ${APP_VERSION%.*} ${APP_VERSION%-*} > test",
|
||||||
|
map[string]string{"ARG": "foo"},
|
||||||
|
[]string{"ENV=1"},
|
||||||
|
),
|
||||||
|
cmd2: newStageContext(
|
||||||
|
"RUN echo ${APP_VERSION%.*} ${APP_VERSION%-*} > test",
|
||||||
|
map[string]string{"ARG": "foo"},
|
||||||
|
[]string{"ENV=2"},
|
||||||
|
),
|
||||||
|
shdEqual: true,
|
||||||
|
excludeEnvsFromCacheKey: []string{"ENV"},
|
||||||
|
},
|
||||||
func() testcase {
|
func() testcase {
|
||||||
dir, files := tempDirAndFile(t)
|
dir, files := tempDirAndFile(t)
|
||||||
file := files[0]
|
file := files[0]
|
||||||
|
|
@ -867,7 +899,15 @@ func Test_stageBuilder_populateCompositeKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.description, func(t *testing.T) {
|
t.Run(tc.description, func(t *testing.T) {
|
||||||
sb := &stageBuilder{fileContext: util.FileContext{Root: "workspace"}}
|
sb := &stageBuilder{
|
||||||
|
fileContext: util.FileContext{Root: "workspace"},
|
||||||
|
opts: &config.KanikoOptions{
|
||||||
|
CacheOptions: config.CacheOptions{
|
||||||
|
ExcludeBuildArgsFromCacheKey: tc.excludeBuildArgsFromCacheKey,
|
||||||
|
ExcludeEnvsFromCacheKey: tc.excludeEnvsFromCacheKey,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
ck := CompositeCache{}
|
ck := CompositeCache{}
|
||||||
|
|
||||||
instructions1, err := dockerfile.ParseCommands([]string{tc.cmd1.command.String()})
|
instructions1, err := dockerfile.ParseCommands([]string{tc.cmd1.command.String()})
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue