Add CacheCommand to DockerCommand interface

CacheCommand returns true if the command should be cached. Currently,
it's only true for RUN but can be added to ADD/COPY later on (these are
different since the contents of files for ADD/COPY need to be included
in the cache key generation).

I also changed CreatedBy to String so that we can log each command
before cache extraction or regular execution takes place.
This commit is contained in:
Priya Wadhwa 2018-09-04 13:16:05 -07:00
parent 2e10d2761c
commit 4f3ab61b96
18 changed files with 132 additions and 119 deletions

View File

@ -18,7 +18,6 @@ package commands
import (
"path/filepath"
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
@ -47,9 +46,6 @@ func (a *AddCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bui
srcs := a.cmd.SourcesAndDest[:len(a.cmd.SourcesAndDest)-1]
dest := a.cmd.SourcesAndDest[len(a.cmd.SourcesAndDest)-1]
logrus.Infof("cmd: Add %s", srcs)
logrus.Infof("dest: %s", dest)
// First, resolve any environment replacement
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
resolvedEnvs, err := util.ResolveEnvironmentReplacementList(a.cmd.SourcesAndDest, replacementEnvs, true)
@ -112,7 +108,12 @@ func (a *AddCommand) FilesToSnapshot() []string {
return a.snapshotFiles
}
// CreatedBy returns some information about the command for the image config
func (a *AddCommand) CreatedBy() string {
return strings.Join(a.cmd.SourcesAndDest, " ")
// String returns some information about the command for the image config
func (a *AddCommand) String() string {
return a.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (a *AddCommand) CacheCommand() bool {
return false
}

View File

@ -17,13 +17,10 @@ limitations under the License.
package commands
import (
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
"github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/google/go-containerregistry/pkg/v1"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/sirupsen/logrus"
)
type ArgCommand struct {
@ -32,7 +29,6 @@ type ArgCommand struct {
// ExecuteCommand only needs to add this ARG key/value as seen
func (r *ArgCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("ARG")
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
resolvedKey, err := util.ResolveEnvironmentReplacement(r.cmd.Key, replacementEnvs, false)
if err != nil {
@ -55,7 +51,12 @@ func (r *ArgCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (r *ArgCommand) CreatedBy() string {
return strings.Join([]string{r.cmd.Name(), r.cmd.Key}, " ")
// String returns some information about the command for the image config history
func (r *ArgCommand) String() string {
return r.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (r *ArgCommand) CacheCommand() bool {
return false
}

View File

@ -33,7 +33,6 @@ type CmdCommand struct {
// ExecuteCommand executes the CMD command
// Argument handling is the same as RUN.
func (c *CmdCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("cmd: CMD")
var newCommand []string
if c.cmd.PrependShell {
// This is the default shell on Linux
@ -60,15 +59,12 @@ func (c *CmdCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (c *CmdCommand) CreatedBy() string {
cmd := []string{"CMD"}
cmdLine := strings.Join(c.cmd.CmdLine, " ")
if c.cmd.PrependShell {
// TODO: Support shell command here
shell := []string{"/bin/sh", "-c"}
appendedShell := append(cmd, shell...)
return strings.Join(append(appendedShell, cmdLine), " ")
}
return strings.Join(append(cmd, cmdLine), " ")
// String returns some information about the command for the image config history
func (c *CmdCommand) String() string {
return c.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (c *CmdCommand) CacheCommand() bool {
return false
}

View File

@ -30,10 +30,13 @@ type DockerCommand interface {
// 2. Updating metadata fields in the config
// It should not change the config history.
ExecuteCommand(*v1.Config, *dockerfile.BuildArgs) error
// The config history has a "created by" field, should return information about the command
CreatedBy() string
// Returns a string representation of the command
String() string
// A list of files to snapshot, empty for metadata commands or nil if we don't know
FilesToSnapshot() []string
// Return true if this command should be true
// Currently only true for RUN
CacheCommand() bool
}
func GetCommand(cmd instructions.Command, buildcontext string) (DockerCommand, error) {

View File

@ -19,7 +19,6 @@ package commands
import (
"os"
"path/filepath"
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/constants"
@ -27,7 +26,6 @@ import (
"github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/google/go-containerregistry/pkg/v1"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/sirupsen/logrus"
)
type CopyCommand struct {
@ -40,9 +38,6 @@ func (c *CopyCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.Bu
srcs := c.cmd.SourcesAndDest[:len(c.cmd.SourcesAndDest)-1]
dest := c.cmd.SourcesAndDest[len(c.cmd.SourcesAndDest)-1]
logrus.Infof("cmd: copy %s", srcs)
logrus.Infof("dest: %s", dest)
// Resolve from
if c.cmd.From != "" {
c.buildcontext = filepath.Join(constants.KanikoDir, c.cmd.From)
@ -106,7 +101,12 @@ func (c *CopyCommand) FilesToSnapshot() []string {
return c.snapshotFiles
}
// CreatedBy returns some information about the command for the image config
func (c *CopyCommand) CreatedBy() string {
return strings.Join(c.cmd.SourcesAndDest, " ")
// String returns some information about the command for the image config
func (c *CopyCommand) String() string {
return c.cmd.String()
}
// CacheCommand returns true since this command should be cached
func (c *CopyCommand) CacheCommand() bool {
return false
}

View File

@ -32,7 +32,6 @@ type EntrypointCommand struct {
// ExecuteCommand handles command processing similar to CMD and RUN,
func (e *EntrypointCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("cmd: ENTRYPOINT")
var newCommand []string
if e.cmd.PrependShell {
// This is the default shell on Linux
@ -58,15 +57,12 @@ func (e *EntrypointCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (e *EntrypointCommand) CreatedBy() string {
entrypoint := []string{"ENTRYPOINT"}
cmdLine := strings.Join(e.cmd.CmdLine, " ")
if e.cmd.PrependShell {
// TODO: Support shell command here
shell := []string{"/bin/sh", "-c"}
appendedShell := append(entrypoint, shell...)
return strings.Join(append(appendedShell, cmdLine), " ")
}
return strings.Join(append(entrypoint, cmdLine), " ")
// String returns some information about the command for the image config history
func (e *EntrypointCommand) String() string {
return e.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (e *EntrypointCommand) CacheCommand() bool {
return false
}

View File

@ -17,14 +17,11 @@ limitations under the License.
package commands
import (
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
"github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/google/go-containerregistry/pkg/v1"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/sirupsen/logrus"
)
type EnvCommand struct {
@ -32,7 +29,6 @@ type EnvCommand struct {
}
func (e *EnvCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("cmd: ENV")
newEnvs := e.cmd.Env
replacementEnvs := buildArgs.ReplacementEnvs(config.Env)
return util.UpdateConfigEnv(newEnvs, config, replacementEnvs)
@ -43,11 +39,12 @@ func (e *EnvCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (e *EnvCommand) CreatedBy() string {
envArray := []string{e.cmd.Name()}
for _, pair := range e.cmd.Env {
envArray = append(envArray, pair.Key+"="+pair.Value)
}
return strings.Join(envArray, " ")
// String returns some information about the command for the image config history
func (e *EnvCommand) String() string {
return e.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (e *EnvCommand) CacheCommand() bool {
return false
}

View File

@ -76,7 +76,11 @@ func (r *ExposeCommand) FilesToSnapshot() []string {
return []string{}
}
func (r *ExposeCommand) CreatedBy() string {
s := []string{r.cmd.Name()}
return strings.Join(append(s, r.cmd.Ports...), " ")
func (r *ExposeCommand) String() string {
return r.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (r *ExposeCommand) CacheCommand() bool {
return false
}

View File

@ -17,12 +17,9 @@ limitations under the License.
package commands
import (
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
"github.com/google/go-containerregistry/pkg/v1"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
"github.com/sirupsen/logrus"
)
type HealthCheckCommand struct {
@ -31,8 +28,6 @@ type HealthCheckCommand struct {
// ExecuteCommand handles command processing similar to CMD and RUN,
func (h *HealthCheckCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("cmd: HEALTHCHECK")
check := v1.HealthConfig(*h.cmd.Health)
config.Healthcheck = &check
@ -44,9 +39,12 @@ func (h *HealthCheckCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (h *HealthCheckCommand) CreatedBy() string {
entrypoint := []string{"HEALTHCHECK"}
return strings.Join(append(entrypoint, strings.Join(h.cmd.Health.Test, " ")), " ")
// String returns some information about the command for the image config history
func (h *HealthCheckCommand) String() string {
return h.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (h *HealthCheckCommand) CacheCommand() bool {
return false
}

View File

@ -17,8 +17,6 @@ limitations under the License.
package commands
import (
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
"github.com/GoogleContainerTools/kaniko/pkg/util"
@ -32,7 +30,6 @@ type LabelCommand struct {
}
func (r *LabelCommand) ExecuteCommand(config *v1.Config, buildArgs *dockerfile.BuildArgs) error {
logrus.Info("cmd: LABEL")
return updateLabels(r.cmd.Labels, config, buildArgs)
}
@ -72,11 +69,12 @@ func (r *LabelCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (r *LabelCommand) CreatedBy() string {
l := []string{r.cmd.Name()}
for _, kvp := range r.cmd.Labels {
l = append(l, kvp.String())
}
return strings.Join(l, " ")
// String returns some information about the command for the image config history
func (r *LabelCommand) String() string {
return r.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (r *LabelCommand) CacheCommand() bool {
return false
}

View File

@ -44,7 +44,12 @@ func (o *OnBuildCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (o *OnBuildCommand) CreatedBy() string {
return o.cmd.Expression
// String returns some information about the command for the image config history
func (o *OnBuildCommand) String() string {
return o.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (o *OnBuildCommand) CacheCommand() bool {
return false
}

View File

@ -137,13 +137,12 @@ func (r *RunCommand) FilesToSnapshot() []string {
return nil
}
// CreatedBy returns some information about the command for the image config
func (r *RunCommand) CreatedBy() string {
cmdLine := strings.Join(r.cmd.CmdLine, " ")
if r.cmd.PrependShell {
// TODO: Support shell command here
shell := []string{"/bin/sh", "-c"}
return strings.Join(append(shell, cmdLine), " ")
}
return cmdLine
// String returns some information about the command for the image config
func (r *RunCommand) String() string {
return r.cmd.String()
}
// CacheCommand returns true since this command should be cached
func (r *RunCommand) CacheCommand() bool {
return true
}

View File

@ -17,8 +17,6 @@ limitations under the License.
package commands
import (
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
"github.com/google/go-containerregistry/pkg/v1"
"github.com/moby/buildkit/frontend/dockerfile/instructions"
@ -46,10 +44,12 @@ func (s *ShellCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (s *ShellCommand) CreatedBy() string {
entrypoint := []string{"SHELL"}
cmdLine := strings.Join(s.cmd.Shell, " ")
return strings.Join(append(entrypoint, cmdLine), " ")
// String returns some information about the command for the image config history
func (s *ShellCommand) String() string {
return s.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (s *ShellCommand) CacheCommand() bool {
return false
}

View File

@ -17,8 +17,6 @@ limitations under the License.
package commands
import (
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
"github.com/GoogleContainerTools/kaniko/pkg/util"
"github.com/docker/docker/pkg/signal"
@ -59,9 +57,12 @@ func (s *StopSignalCommand) FilesToSnapshot() []string {
return []string{}
}
// CreatedBy returns some information about the command for the image config history
func (s *StopSignalCommand) CreatedBy() string {
entrypoint := []string{"STOPSIGNAL"}
return strings.Join(append(entrypoint, s.cmd.Signal), " ")
// String returns some information about the command for the image config history
func (s *StopSignalCommand) String() string {
return s.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (s *StopSignalCommand) CacheCommand() bool {
return false
}

View File

@ -63,7 +63,11 @@ func (r *UserCommand) FilesToSnapshot() []string {
return []string{}
}
func (r *UserCommand) CreatedBy() string {
s := []string{r.cmd.Name(), r.cmd.User}
return strings.Join(s, " ")
func (r *UserCommand) String() string {
return r.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (r *UserCommand) CacheCommand() bool {
return false
}

View File

@ -19,7 +19,6 @@ package commands
import (
"fmt"
"os"
"strings"
"github.com/GoogleContainerTools/kaniko/pkg/dockerfile"
@ -72,6 +71,11 @@ func (v *VolumeCommand) FilesToSnapshot() []string {
return v.snapshotFiles
}
func (v *VolumeCommand) CreatedBy() string {
return strings.Join(append([]string{v.cmd.Name()}, v.cmd.Volumes...), " ")
func (v *VolumeCommand) String() string {
return v.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (v *VolumeCommand) CacheCommand() bool {
return false
}

View File

@ -62,7 +62,12 @@ func (w *WorkdirCommand) FilesToSnapshot() []string {
return w.snapshotFiles
}
// CreatedBy returns some information about the command for the image config history
func (w *WorkdirCommand) CreatedBy() string {
return w.cmd.Name() + " " + w.cmd.Path
// String returns some information about the command for the image config history
func (w *WorkdirCommand) String() string {
return w.cmd.String()
}
// CacheCommand returns false since this command shouldn't be cached
func (w *WorkdirCommand) CacheCommand() bool {
return false
}

View File

@ -85,6 +85,7 @@ func DoBuild(opts *options.KanikoOptions) (v1.Image, error) {
if dockerCommand == nil {
continue
}
logrus.Info(dockerCommand.String())
if err := dockerCommand.ExecuteCommand(&imageConfig.Config, buildArgs); err != nil {
return nil, err
}
@ -138,7 +139,7 @@ func DoBuild(opts *options.KanikoOptions) (v1.Image, error) {
Layer: layer,
History: v1.History{
Author: constants.Author,
CreatedBy: dockerCommand.CreatedBy(),
CreatedBy: dockerCommand.String(),
},
},
)