add cache run command option (#2032)
Co-authored-by: Rami CHAABANE <rchaabane@scaleway.com>
This commit is contained in:
parent
aad03dc285
commit
f9dcb92c38
|
|
@ -400,7 +400,7 @@ as a remote image destination:
|
||||||
### Caching
|
### Caching
|
||||||
|
|
||||||
#### Caching Layers
|
#### Caching Layers
|
||||||
kaniko can cache layers created by `RUN` (and `COPY`, configured by the `--cache-copy-layers` flag) commands in a remote repository.
|
kaniko can cache layers created by `RUN`(configured by flag `--cache-run-layers`) and `COPY` (configured by flag `--cache-copy-layers`) commands in a remote repository.
|
||||||
Before executing a command, kaniko checks the cache for the layer.
|
Before executing a command, kaniko checks the cache for the layer.
|
||||||
If it exists, kaniko will pull and extract the cached layer instead of executing the command.
|
If it exists, kaniko will pull and extract the cached layer instead of executing the command.
|
||||||
If not, kaniko will execute the command and then push the newly created layer to the cache.
|
If not, kaniko will execute the command and then push the newly created layer to the cache.
|
||||||
|
|
@ -669,6 +669,10 @@ _This flag must be used in conjunction with the `--cache=true` flag._
|
||||||
|
|
||||||
Set this flag to cache copy layers.
|
Set this flag to cache copy layers.
|
||||||
|
|
||||||
|
#### --cache-run-layers
|
||||||
|
|
||||||
|
Set this flag to cache run layers (default=true).
|
||||||
|
|
||||||
#### --cache-ttl duration
|
#### --cache-ttl duration
|
||||||
|
|
||||||
Cache timeout in hours. Defaults to two weeks.
|
Cache timeout in hours. Defaults to two weeks.
|
||||||
|
|
|
||||||
|
|
@ -221,6 +221,7 @@ func addKanikoOptionsFlags() {
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.RunV2, "use-new-run", "", false, "Use the experimental run implementation for detecting changes without requiring file system snapshots.")
|
RootCmd.PersistentFlags().BoolVarP(&opts.RunV2, "use-new-run", "", false, "Use the experimental run implementation for detecting changes without requiring file system snapshots.")
|
||||||
RootCmd.PersistentFlags().Var(&opts.Git, "git", "Branch to clone if build context is a git repository")
|
RootCmd.PersistentFlags().Var(&opts.Git, "git", "Branch to clone if build context is a git repository")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.CacheCopyLayers, "cache-copy-layers", "", false, "Caches copy layers")
|
RootCmd.PersistentFlags().BoolVarP(&opts.CacheCopyLayers, "cache-copy-layers", "", false, "Caches copy layers")
|
||||||
|
RootCmd.PersistentFlags().BoolVarP(&opts.CacheRunLayers, "cache-run-layers", "", true, "Caches run layers")
|
||||||
RootCmd.PersistentFlags().VarP(&opts.IgnorePaths, "ignore-path", "", "Ignore these paths when taking a snapshot. Set it repeatedly for multiple paths.")
|
RootCmd.PersistentFlags().VarP(&opts.IgnorePaths, "ignore-path", "", "Ignore these paths when taking a snapshot. Set it repeatedly for multiple paths.")
|
||||||
RootCmd.PersistentFlags().BoolVarP(&opts.ForceBuildMetadata, "force-build-metadata", "", false, "Force add metadata layers to build image")
|
RootCmd.PersistentFlags().BoolVarP(&opts.ForceBuildMetadata, "force-build-metadata", "", false, "Force add metadata layers to build image")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,13 +60,13 @@ type DockerCommand interface {
|
||||||
ShouldDetectDeletedFiles() bool
|
ShouldDetectDeletedFiles() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCommand(cmd instructions.Command, fileContext util.FileContext, useNewRun bool, cacheCopy bool) (DockerCommand, error) {
|
func GetCommand(cmd instructions.Command, fileContext util.FileContext, useNewRun bool, cacheCopy bool, cacheRun bool) (DockerCommand, error) {
|
||||||
switch c := cmd.(type) {
|
switch c := cmd.(type) {
|
||||||
case *instructions.RunCommand:
|
case *instructions.RunCommand:
|
||||||
if useNewRun {
|
if useNewRun {
|
||||||
return &RunMarkerCommand{cmd: c}, nil
|
return &RunMarkerCommand{cmd: c, shdCache: cacheRun}, nil
|
||||||
}
|
}
|
||||||
return &RunCommand{cmd: c}, nil
|
return &RunCommand{cmd: c, shdCache: cacheRun}, nil
|
||||||
case *instructions.CopyCommand:
|
case *instructions.CopyCommand:
|
||||||
return &CopyCommand{cmd: c, fileContext: fileContext, shdCache: cacheCopy}, nil
|
return &CopyCommand{cmd: c, fileContext: fileContext, shdCache: cacheCopy}, nil
|
||||||
case *instructions.ExposeCommand:
|
case *instructions.ExposeCommand:
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,8 @@ import (
|
||||||
|
|
||||||
type RunCommand struct {
|
type RunCommand struct {
|
||||||
BaseCommand
|
BaseCommand
|
||||||
cmd *instructions.RunCommand
|
cmd *instructions.RunCommand
|
||||||
|
shdCache bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// for testing
|
// for testing
|
||||||
|
|
@ -187,7 +188,7 @@ func (r *RunCommand) RequiresUnpackedFS() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RunCommand) ShouldCacheOutput() bool {
|
func (r *RunCommand) ShouldCacheOutput() bool {
|
||||||
return true
|
return r.shdCache
|
||||||
}
|
}
|
||||||
|
|
||||||
type CachingRunCommand struct {
|
type CachingRunCommand struct {
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,9 @@ import (
|
||||||
|
|
||||||
type RunMarkerCommand struct {
|
type RunMarkerCommand struct {
|
||||||
BaseCommand
|
BaseCommand
|
||||||
cmd *instructions.RunCommand
|
cmd *instructions.RunCommand
|
||||||
Files []string
|
Files []string
|
||||||
|
shdCache bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RunMarkerCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
func (r *RunMarkerCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
|
||||||
|
|
@ -77,7 +78,7 @@ func (r *RunMarkerCommand) RequiresUnpackedFS() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RunMarkerCommand) ShouldCacheOutput() bool {
|
func (r *RunMarkerCommand) ShouldCacheOutput() bool {
|
||||||
return true
|
return r.shdCache
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RunMarkerCommand) ShouldDetectDeletedFiles() bool {
|
func (r *RunMarkerCommand) ShouldDetectDeletedFiles() bool {
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,7 @@ type KanikoOptions struct {
|
||||||
SkipUnusedStages bool
|
SkipUnusedStages bool
|
||||||
RunV2 bool
|
RunV2 bool
|
||||||
CacheCopyLayers bool
|
CacheCopyLayers bool
|
||||||
|
CacheRunLayers bool
|
||||||
ForceBuildMetadata bool
|
ForceBuildMetadata bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ func newStageBuilder(args *dockerfile.BuildArgs, opts *config.KanikoOptions, sta
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, cmd := range s.stage.Commands {
|
for _, cmd := range s.stage.Commands {
|
||||||
command, err := commands.GetCommand(cmd, fileContext, opts.RunV2, opts.CacheCopyLayers)
|
command, err := commands.GetCommand(cmd, fileContext, opts.RunV2, opts.CacheCopyLayers, opts.CacheRunLayers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -913,7 +913,7 @@ COPY %s foo.txt
|
||||||
expectedCacheKeys: []string{copyCommandCacheKey},
|
expectedCacheKeys: []string{copyCommandCacheKey},
|
||||||
// CachingCopyCommand is not pushed to the cache
|
// CachingCopyCommand is not pushed to the cache
|
||||||
pushedCacheKeys: []string{},
|
pushedCacheKeys: []string{},
|
||||||
commands: getCommands(util.FileContext{Root: dir}, cmds, true),
|
commands: getCommands(util.FileContext{Root: dir}, cmds, true, false),
|
||||||
fileName: filename,
|
fileName: filename,
|
||||||
}
|
}
|
||||||
}(),
|
}(),
|
||||||
|
|
@ -970,7 +970,7 @@ COPY %s foo.txt
|
||||||
rootDir: dir,
|
rootDir: dir,
|
||||||
expectedCacheKeys: []string{hash},
|
expectedCacheKeys: []string{hash},
|
||||||
pushedCacheKeys: []string{hash},
|
pushedCacheKeys: []string{hash},
|
||||||
commands: getCommands(util.FileContext{Root: dir}, cmds, true),
|
commands: getCommands(util.FileContext{Root: dir}, cmds, true, false),
|
||||||
fileName: filename,
|
fileName: filename,
|
||||||
}
|
}
|
||||||
}(),
|
}(),
|
||||||
|
|
@ -1034,7 +1034,7 @@ COPY %s bar.txt
|
||||||
cmds := stage.Commands
|
cmds := stage.Commands
|
||||||
return testcase{
|
return testcase{
|
||||||
description: "cached run command followed by uncached copy command results in consistent read and write hashes",
|
description: "cached run command followed by uncached copy command results in consistent read and write hashes",
|
||||||
opts: &config.KanikoOptions{Cache: true, CacheCopyLayers: true},
|
opts: &config.KanikoOptions{Cache: true, CacheCopyLayers: true, CacheRunLayers: true},
|
||||||
rootDir: dir,
|
rootDir: dir,
|
||||||
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: destDir}},
|
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: destDir}},
|
||||||
layerCache: &fakeLayerCache{
|
layerCache: &fakeLayerCache{
|
||||||
|
|
@ -1045,7 +1045,7 @@ COPY %s bar.txt
|
||||||
// hash1 is the read cachekey for the first layer
|
// hash1 is the read cachekey for the first layer
|
||||||
expectedCacheKeys: []string{hash1, hash2},
|
expectedCacheKeys: []string{hash1, hash2},
|
||||||
pushedCacheKeys: []string{hash2},
|
pushedCacheKeys: []string{hash2},
|
||||||
commands: getCommands(util.FileContext{Root: dir}, cmds, true),
|
commands: getCommands(util.FileContext{Root: dir}, cmds, true, true),
|
||||||
}
|
}
|
||||||
}(),
|
}(),
|
||||||
func() testcase {
|
func() testcase {
|
||||||
|
|
@ -1108,7 +1108,7 @@ RUN foobar
|
||||||
cmds := stage.Commands
|
cmds := stage.Commands
|
||||||
return testcase{
|
return testcase{
|
||||||
description: "copy command followed by cached run command results in consistent read and write hashes",
|
description: "copy command followed by cached run command results in consistent read and write hashes",
|
||||||
opts: &config.KanikoOptions{Cache: true},
|
opts: &config.KanikoOptions{Cache: true, CacheRunLayers: true},
|
||||||
rootDir: dir,
|
rootDir: dir,
|
||||||
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: destDir}},
|
config: &v1.ConfigFile{Config: v1.Config{WorkingDir: destDir}},
|
||||||
layerCache: &fakeLayerCache{
|
layerCache: &fakeLayerCache{
|
||||||
|
|
@ -1118,7 +1118,7 @@ RUN foobar
|
||||||
image: image,
|
image: image,
|
||||||
expectedCacheKeys: []string{runHash},
|
expectedCacheKeys: []string{runHash},
|
||||||
pushedCacheKeys: []string{},
|
pushedCacheKeys: []string{},
|
||||||
commands: getCommands(util.FileContext{Root: dir}, cmds, false),
|
commands: getCommands(util.FileContext{Root: dir}, cmds, false, true),
|
||||||
}
|
}
|
||||||
}(),
|
}(),
|
||||||
func() testcase {
|
func() testcase {
|
||||||
|
|
@ -1331,7 +1331,7 @@ func assertCacheKeys(t *testing.T, expectedCacheKeys, actualCacheKeys []string,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCommands(fileContext util.FileContext, cmds []instructions.Command, cacheCopy bool) []commands.DockerCommand {
|
func getCommands(fileContext util.FileContext, cmds []instructions.Command, cacheCopy, cacheRun bool) []commands.DockerCommand {
|
||||||
outCommands := make([]commands.DockerCommand, 0)
|
outCommands := make([]commands.DockerCommand, 0)
|
||||||
for _, c := range cmds {
|
for _, c := range cmds {
|
||||||
cmd, err := commands.GetCommand(
|
cmd, err := commands.GetCommand(
|
||||||
|
|
@ -1339,6 +1339,7 @@ func getCommands(fileContext util.FileContext, cmds []instructions.Command, cach
|
||||||
fileContext,
|
fileContext,
|
||||||
false,
|
false,
|
||||||
cacheCopy,
|
cacheCopy,
|
||||||
|
cacheRun,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
@ -1434,7 +1435,7 @@ func Test_stageBuild_populateCompositeKeyForCopyCommand(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fc := util.FileContext{Root: "workspace"}
|
fc := util.FileContext{Root: "workspace"}
|
||||||
copyCommand, err := commands.GetCommand(instructions[0], fc, false, true)
|
copyCommand, err := commands.GetCommand(instructions[0], fc, false, true, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue