Fix intermediate layer caching (#474)
* Fix intermediate layer caching * Move the if statement into the ShouldTakeSnapshot function. Also add some unit tests.
This commit is contained in:
parent
7f9ea39bf7
commit
01329d5ac1
|
|
@ -279,13 +279,18 @@ func (s *stageBuilder) takeSnapshot(files []string) (string, error) {
|
||||||
func (s *stageBuilder) shouldTakeSnapshot(index int, files []string) bool {
|
func (s *stageBuilder) shouldTakeSnapshot(index int, files []string) bool {
|
||||||
isLastCommand := index == len(s.stage.Commands)-1
|
isLastCommand := index == len(s.stage.Commands)-1
|
||||||
|
|
||||||
// We only snapshot the very end of intermediate stages.
|
// We only snapshot the very end with single snapshot mode on.
|
||||||
if !s.stage.Final {
|
if s.opts.SingleSnapshot {
|
||||||
return isLastCommand
|
return isLastCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only snapshot the very end with single snapshot mode on.
|
// Always take snapshots if we're using the cache.
|
||||||
if s.opts.SingleSnapshot {
|
if s.opts.Cache {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
// We only snapshot the very end of intermediate stages.
|
||||||
|
if !s.stage.Final {
|
||||||
return isLastCommand
|
return isLastCommand
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -298,6 +303,7 @@ func (s *stageBuilder) shouldTakeSnapshot(index int, files []string) bool {
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ package executor
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/moby/buildkit/frontend/dockerfile/instructions"
|
||||||
|
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
"github.com/GoogleContainerTools/kaniko/pkg/config"
|
||||||
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
|
||||||
"github.com/GoogleContainerTools/kaniko/testutil"
|
"github.com/GoogleContainerTools/kaniko/testutil"
|
||||||
|
|
@ -74,3 +76,107 @@ func stage(t *testing.T, d string) config.KanikoStage {
|
||||||
Stage: stages[0],
|
Stage: stages[0],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MockCommand struct {
|
||||||
|
name string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *MockCommand) Name() string {
|
||||||
|
return m.name
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_stageBuilder_shouldTakeSnapshot(t *testing.T) {
|
||||||
|
commands := []instructions.Command{
|
||||||
|
&MockCommand{name: "command1"},
|
||||||
|
&MockCommand{name: "command2"},
|
||||||
|
&MockCommand{name: "command3"},
|
||||||
|
}
|
||||||
|
|
||||||
|
stage := instructions.Stage{
|
||||||
|
Commands: commands,
|
||||||
|
}
|
||||||
|
|
||||||
|
type fields struct {
|
||||||
|
stage config.KanikoStage
|
||||||
|
opts *config.KanikoOptions
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
index int
|
||||||
|
files []string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
want bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "final stage not last command",
|
||||||
|
fields: fields{
|
||||||
|
stage: config.KanikoStage{
|
||||||
|
Final: true,
|
||||||
|
Stage: stage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not final stage last command",
|
||||||
|
fields: fields{
|
||||||
|
stage: config.KanikoStage{
|
||||||
|
Final: false,
|
||||||
|
Stage: stage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
index: len(commands) - 1,
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "not final stage not last command",
|
||||||
|
fields: fields{
|
||||||
|
stage: config.KanikoStage{
|
||||||
|
Final: false,
|
||||||
|
Stage: stage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
want: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "caching enabled intermediate container",
|
||||||
|
fields: fields{
|
||||||
|
stage: config.KanikoStage{
|
||||||
|
Final: false,
|
||||||
|
Stage: stage,
|
||||||
|
},
|
||||||
|
opts: &config.KanikoOptions{Cache: true},
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
want: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
|
||||||
|
if tt.fields.opts == nil {
|
||||||
|
tt.fields.opts = &config.KanikoOptions{}
|
||||||
|
}
|
||||||
|
s := &stageBuilder{
|
||||||
|
stage: tt.fields.stage,
|
||||||
|
opts: tt.fields.opts,
|
||||||
|
}
|
||||||
|
if got := s.shouldTakeSnapshot(tt.args.index, tt.args.files); got != tt.want {
|
||||||
|
t.Errorf("stageBuilder.shouldTakeSnapshot() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue