Skip to content

Commit

Permalink
Update copy command cache key logic
Browse files Browse the repository at this point in the history
Include the digest of the stage specified in the --from argument for
COPY commands which use --from
  • Loading branch information
cvgw committed Nov 26, 2019
1 parent bfd8562 commit 042771f
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 4 deletions.
4 changes: 4 additions & 0 deletions pkg/commands/copy.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ func (c *CopyCommand) CacheCommand(img v1.Image) DockerCommand {
}
}

func (c *CopyCommand) From() string {
return cr.cmd.From
}

type CachingCopyCommand struct {
BaseCommand
img v1.Image
Expand Down
4 changes: 3 additions & 1 deletion pkg/config/stage.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ limitations under the License.

package config

import "github.com/moby/buildkit/frontend/dockerfile/instructions"
import (
"github.com/moby/buildkit/frontend/dockerfile/instructions"
)

// KanikoStage wraps a stage of the Dockerfile and provides extra information
type KanikoStage struct {
Expand Down
28 changes: 25 additions & 3 deletions pkg/executor/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,11 @@ type stageBuilder struct {
cmds []commands.DockerCommand
args *dockerfile.BuildArgs
crossStageDeps map[int][]string
digestMap map[string]v1.Hash
}

// newStageBuilder returns a new type stageBuilder which contains all the information required to build the stage
func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string) (*stageBuilder, error) {
func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, crossStageDeps map[int][]string, dm map[string]v1.Hash) (*stageBuilder, error) {
sourceImage, err := util.RetrieveSourceImage(stage, opts)
if err != nil {
return nil, err
Expand Down Expand Up @@ -100,6 +101,7 @@ func newStageBuilder(opts *config.KanikoOptions, stage config.KanikoStage, cross
baseImageDigest: digest.String(),
opts: opts,
crossStageDeps: crossStageDeps,
digestMap: dm,
}

for _, cmd := range s.stage.Commands {
Expand Down Expand Up @@ -147,6 +149,15 @@ func (s *stageBuilder) optimize(compositeKey CompositeCache, cfg v1.Config) erro
if command == nil {
continue
}
switch v := command.(type) {
case *commands.CopyCommand:
if v.From() != "" {
digest := s.digestMap[v.From()].String()
logrus.Debugf("adding digest %v from previous stage to composite key for %v", digest, command.String())
compositeKey.AddKey(digest)
}
}

compositeKey.AddKey(command.String())
// If the command uses files from the context, add them.
files, err := command.FilesUsedFromContext(&cfg, s.args)
Expand Down Expand Up @@ -283,6 +294,7 @@ func (s *stageBuilder) build() error {
if err := cacheGroup.Wait(); err != nil {
logrus.Warnf("error uploading layer to cache: %s", err)
}

return nil
}

Expand Down Expand Up @@ -354,7 +366,6 @@ func (s *stageBuilder) saveSnapshotToImage(createdBy string, tarPath string) err
},
)
return err

}

func CalculateDependencies(opts *config.KanikoOptions) (map[int][]string, error) {
Expand Down Expand Up @@ -422,6 +433,9 @@ func CalculateDependencies(opts *config.KanikoOptions) (map[int][]string, error)
// DoBuild executes building the Dockerfile
func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
t := timing.Start("Total Build Time")

digestMap := make(map[string]v1.Hash)

// Parse dockerfile and unpack base image to root
stages, err := dockerfile.Stages(opts)
if err != nil {
Expand All @@ -442,13 +456,21 @@ func DoBuild(opts *config.KanikoOptions) (v1.Image, error) {
logrus.Infof("Built cross stage deps: %v", crossStageDependencies)

for index, stage := range stages {
sb, err := newStageBuilder(opts, stage, crossStageDependencies)
sb, err := newStageBuilder(opts, stage, crossStageDependencies, digestMap)
if err != nil {
return nil, err
}
if err := sb.build(); err != nil {
return nil, errors.Wrap(err, "error building stage")
}

d, err := sb.image.Digest()
if err != nil {
return nil, err
}

digestMap[fmt.Sprintf("%d", sb.stage.Index)] = d

reviewConfig(stage, &sb.cf.Config)
sourceImage, err := mutate.Config(sb.image, sb.cf.Config)
if err != nil {
Expand Down

0 comments on commit 042771f

Please sign in to comment.