diff --git a/pkg/build/stage/instruction/add.go b/pkg/build/stage/instruction/add.go index e503dc7bd4..56b3b56463 100644 --- a/pkg/build/stage/instruction/add.go +++ b/pkg/build/stage/instruction/add.go @@ -14,33 +14,36 @@ import ( ) type Add struct { - *Base[*dockerfile_instruction.Add] + *Base[*dockerfile_instruction.Add, *backend_instruction.Add] } func NewAdd(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Add], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Add { return &Add{Base: NewBase(name, i, backend_instruction.NewAdd(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Add) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string +func (stg *Add) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "Raw", stg.instruction.Data.Raw) + args = append(args, append([]string{"Src"}, stg.instruction.Data.Src...)...) + args = append(args, "Dst", stg.instruction.Data.Dst) + args = append(args, "Chown", stg.instruction.Data.Chown) + args = append(args, "Chmod", stg.instruction.Data.Chmod) - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Raw) - args = append(args, stage.instruction.Data.Src...) - args = append(args, stage.instruction.Data.Dst) - args = append(args, stage.instruction.Data.Chown) - args = append(args, stage.instruction.Data.Chmod) + pathsChecksum, err := buildContextArchive.CalculatePathsChecksum(ctx, stg.instruction.Data.Src) + if err != nil { + return "", fmt.Errorf("unable to calculate build context paths checksum: %w", err) + } + args = append(args, "SrcChecksum", pathsChecksum) // TODO(staged-dockerfile): support http src and --checksum option: https://docs.docker.com/engine/reference/builder/#verifying-a-remote-file-checksum-add---checksumchecksum-http-src-dest // TODO(staged-dockerfile): support git ref: https://docs.docker.com/engine/reference/builder/#adding-a-git-repository-add-git-ref-dir // TODO(staged-dockerfile): support --keep-git-dir for git: https://docs.docker.com/engine/reference/builder/#adding-a-git-repository-add-git-ref-dir // TODO(staged-dockerfile): support --link - pathsChecksum, err := buildContextArchive.CalculatePathsChecksum(ctx, stage.instruction.Data.Src) - if err != nil { - return "", fmt.Errorf("unable to calculate build context paths checksum: %w", err) - } - args = append(args, fmt.Sprintf("src-checksum=%s", pathsChecksum)) - return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/base.go b/pkg/build/stage/instruction/base.go index f9740fd552..a4666c96e3 100644 --- a/pkg/build/stage/instruction/base.go +++ b/pkg/build/stage/instruction/base.go @@ -2,6 +2,7 @@ package instruction import ( "context" + "fmt" "github.com/werf/werf/pkg/build/stage" "github.com/werf/werf/pkg/config" @@ -9,17 +10,17 @@ import ( "github.com/werf/werf/pkg/dockerfile" ) -type Base[T dockerfile.InstructionDataInterface] struct { +type Base[T dockerfile.InstructionDataInterface, BT container_backend.InstructionInterface] struct { *stage.BaseStage instruction *dockerfile.DockerfileStageInstruction[T] - backendInstruction container_backend.InstructionInterface + backendInstruction BT dependencies []*config.Dependency hasPrevStage bool } -func NewBase[T dockerfile.InstructionDataInterface](name stage.StageName, instruction *dockerfile.DockerfileStageInstruction[T], backendInstruction container_backend.InstructionInterface, dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Base[T] { - return &Base[T]{ +func NewBase[T dockerfile.InstructionDataInterface, BT container_backend.InstructionInterface](name stage.StageName, instruction *dockerfile.DockerfileStageInstruction[T], backendInstruction BT, dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Base[T, BT] { + return &Base[T, BT]{ BaseStage: stage.NewBaseStage(name, opts), instruction: instruction, backendInstruction: backendInstruction, @@ -28,19 +29,34 @@ func NewBase[T dockerfile.InstructionDataInterface](name stage.StageName, instru } } -func (stg *Base[T]) HasPrevStage() bool { +func (stg *Base[T, BT]) HasPrevStage() bool { return stg.hasPrevStage } -func (stg *Base[T]) IsStapelStage() bool { +func (stg *Base[T, BT]) IsStapelStage() bool { return false } -func (stg *Base[T]) UsesBuildContext() bool { +func (stg *Base[T, BT]) UsesBuildContext() bool { return stg.backendInstruction.UsesBuildContext() } -func (stg *Base[T]) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error { +func (stg *Base[T, BT]) getDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver, expander InstructionExpander) ([]string, error) { + if err := expander.ExpandInstruction(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive); err != nil { + return nil, fmt.Errorf("unable to expand instruction %q: %w", stg.instruction.Data.Name(), err) + } + return nil, nil +} + +func (stg *Base[T, BT]) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error { stageImage.Builder.DockerfileStageBuilder().AppendInstruction(stg.backendInstruction) return nil } + +func (stg *Base[T, BT]) ExpandInstruction(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error { + return nil +} + +type InstructionExpander interface { + ExpandInstruction(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error +} diff --git a/pkg/build/stage/instruction/cmd.go b/pkg/build/stage/instruction/cmd.go index b929eeb0ee..33f260b969 100644 --- a/pkg/build/stage/instruction/cmd.go +++ b/pkg/build/stage/instruction/cmd.go @@ -14,17 +14,22 @@ import ( ) type Cmd struct { - *Base[*dockerfile_instruction.Cmd] + *Base[*dockerfile_instruction.Cmd, *backend_instruction.Cmd] } func NewCmd(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Cmd], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Cmd { return &Cmd{Base: NewBase(name, i, backend_instruction.NewCmd(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Cmd) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Cmd...) - args = append(args, fmt.Sprintf("%v", stage.instruction.Data.PrependShell)) +func (stg *Cmd) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, append([]string{"Cmd"}, stg.instruction.Data.Cmd...)...) + args = append(args, "PrependShell", fmt.Sprintf("%v", stg.instruction.Data.PrependShell)) + return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/copy.go b/pkg/build/stage/instruction/copy.go index 2132c10048..ddccb11f51 100644 --- a/pkg/build/stage/instruction/copy.go +++ b/pkg/build/stage/instruction/copy.go @@ -13,20 +13,39 @@ import ( ) type Copy struct { - *Base[*dockerfile_instruction.Copy] + *Base[*dockerfile_instruction.Copy, *backend_instruction.Copy] } func NewCopy(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Copy], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Copy { return &Copy{Base: NewBase(name, i, backend_instruction.NewCopy(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Copy) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.From) - args = append(args, stage.instruction.Data.Src...) - args = append(args, stage.instruction.Data.Dst) - args = append(args, stage.instruction.Data.Chown) - args = append(args, stage.instruction.Data.Chmod) +func (stg *Copy) ExpandInstruction(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error { + if stg.instruction.Data.From != "" { + if ds := stg.instruction.GetDependencyByStageRef(stg.instruction.Data.From); ds != nil { + depStageImageName := c.GetImageNameForLastImageStage(ds.WerfImageName()) + stg.backendInstruction.From = depStageImageName + } + } + + return nil +} + +func (stg *Copy) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "From", stg.instruction.Data.From) + args = append(args, append([]string{"Src"}, stg.instruction.Data.Src...)...) + args = append(args, "Dst", stg.instruction.Data.Dst) + args = append(args, "Chown", stg.instruction.Data.Chown) + args = append(args, "Chmod", stg.instruction.Data.Chmod) + args = append(args, "ExpandedFrom", stg.backendInstruction.From) + + // TODO(staged-dockerfile): support --link option: https://docs.docker.com/engine/reference/builder/#copy---link + return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/entrypoint.go b/pkg/build/stage/instruction/entrypoint.go index f2c46103c7..4fe31182e2 100644 --- a/pkg/build/stage/instruction/entrypoint.go +++ b/pkg/build/stage/instruction/entrypoint.go @@ -14,17 +14,21 @@ import ( ) type Entrypoint struct { - *Base[*dockerfile_instruction.Entrypoint] + *Base[*dockerfile_instruction.Entrypoint, *backend_instruction.Entrypoint] } func NewEntrypoint(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Entrypoint], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Entrypoint { return &Entrypoint{Base: NewBase(name, i, backend_instruction.NewEntrypoint(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Entrypoint) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Entrypoint...) - args = append(args, fmt.Sprintf("%v", stage.instruction.Data.PrependShell)) +func (stg *Entrypoint) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, append([]string{"Entrypoint"}, stg.instruction.Data.Entrypoint...)...) + args = append(args, "PrependShell", fmt.Sprintf("%v", stg.instruction.Data.PrependShell)) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/env.go b/pkg/build/stage/instruction/env.go index 9e66c2fd08..2612df410f 100644 --- a/pkg/build/stage/instruction/env.go +++ b/pkg/build/stage/instruction/env.go @@ -13,19 +13,26 @@ import ( ) type Env struct { - *Base[*dockerfile_instruction.Env] + *Base[*dockerfile_instruction.Env, *backend_instruction.Env] } func NewEnv(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Env], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Env { return &Env{Base: NewBase(name, i, backend_instruction.NewEnv(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Env) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) +func (stg *Env) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) // FIXME(staged-dockerfile): sort envs - for k, v := range stage.instruction.Data.Envs { - args = append(args, k, v) + if len(stg.instruction.Data.Envs) > 0 { + args = append(args, "Envs") + for k, v := range stg.instruction.Data.Envs { + args = append(args, k, v) + } } return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/expose.go b/pkg/build/stage/instruction/expose.go index c20d733071..dbb29ee65b 100644 --- a/pkg/build/stage/instruction/expose.go +++ b/pkg/build/stage/instruction/expose.go @@ -13,16 +13,20 @@ import ( ) type Expose struct { - *Base[*dockerfile_instruction.Expose] + *Base[*dockerfile_instruction.Expose, *backend_instruction.Expose] } func NewExpose(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Expose], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Expose { return &Expose{Base: NewBase(name, i, backend_instruction.NewExpose(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Expose) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Ports...) +func (stg *Expose) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, append([]string{"Ports"}, stg.instruction.Data.Ports...)...) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/healthcheck.go b/pkg/build/stage/instruction/healthcheck.go index cdc90cba07..804b1af6f2 100644 --- a/pkg/build/stage/instruction/healthcheck.go +++ b/pkg/build/stage/instruction/healthcheck.go @@ -14,21 +14,25 @@ import ( ) type Healthcheck struct { - *Base[*dockerfile_instruction.Healthcheck] + *Base[*dockerfile_instruction.Healthcheck, *backend_instruction.Healthcheck] } func NewHealthcheck(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Healthcheck], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Healthcheck { return &Healthcheck{Base: NewBase(name, i, backend_instruction.NewHealthcheck(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Healthcheck) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, string(stage.instruction.Data.Type)) - args = append(args, stage.instruction.Data.Config.Test...) - args = append(args, stage.instruction.Data.Config.Interval.String()) - args = append(args, stage.instruction.Data.Config.Timeout.String()) - args = append(args, stage.instruction.Data.Config.StartPeriod.String()) - args = append(args, fmt.Sprintf("%d", stage.instruction.Data.Config.Retries)) +func (stg *Healthcheck) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "Type", string(stg.instruction.Data.Type)) + args = append(args, append([]string{"Test"}, stg.instruction.Data.Config.Test...)...) + args = append(args, "Interval", stg.instruction.Data.Config.Interval.String()) + args = append(args, "Timeout", stg.instruction.Data.Config.Timeout.String()) + args = append(args, "StartPeriod", stg.instruction.Data.Config.StartPeriod.String()) + args = append(args, "Retries", fmt.Sprintf("%d", stg.instruction.Data.Config.Retries)) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/label.go b/pkg/build/stage/instruction/label.go index b1c23e7aed..9c890af2b8 100644 --- a/pkg/build/stage/instruction/label.go +++ b/pkg/build/stage/instruction/label.go @@ -13,19 +13,28 @@ import ( ) type Label struct { - *Base[*dockerfile_instruction.Label] + *Base[*dockerfile_instruction.Label, *backend_instruction.Label] } func NewLabel(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Label], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Label { return &Label{Base: NewBase(name, i, backend_instruction.NewLabel(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Label) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) +func (stg *Label) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + // FIXME(staged-dockerfile): sort labels map - for k, v := range stage.instruction.Data.Labels { - args = append(args, k, v) + if len(stg.instruction.Data.Labels) > 0 { + args = append(args, "Labels") + for k, v := range stg.instruction.Data.Labels { + args = append(args, k, v) + } } + return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/maintainer.go b/pkg/build/stage/instruction/maintainer.go index 35d2ab0069..4c2ca80714 100644 --- a/pkg/build/stage/instruction/maintainer.go +++ b/pkg/build/stage/instruction/maintainer.go @@ -13,16 +13,20 @@ import ( ) type Maintainer struct { - *Base[*dockerfile_instruction.Maintainer] + *Base[*dockerfile_instruction.Maintainer, *backend_instruction.Maintainer] } func NewMaintainer(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Maintainer], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Maintainer { return &Maintainer{Base: NewBase(name, i, backend_instruction.NewMaintainer(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Maintainer) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Maintainer) +func (stg *Maintainer) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "Maintainer", stg.instruction.Data.Maintainer) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/on_build.go b/pkg/build/stage/instruction/on_build.go index 0eae76f223..3633c046da 100644 --- a/pkg/build/stage/instruction/on_build.go +++ b/pkg/build/stage/instruction/on_build.go @@ -13,16 +13,20 @@ import ( ) type OnBuild struct { - *Base[*dockerfile_instruction.OnBuild] + *Base[*dockerfile_instruction.OnBuild, *backend_instruction.OnBuild] } func NewOnBuild(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.OnBuild], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *OnBuild { return &OnBuild{Base: NewBase(name, i, backend_instruction.NewOnBuild(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *OnBuild) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Instruction) +func (stg *OnBuild) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "Instruction", stg.instruction.Data.Instruction) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/run.go b/pkg/build/stage/instruction/run.go index 890fe3f551..7847c15736 100644 --- a/pkg/build/stage/instruction/run.go +++ b/pkg/build/stage/instruction/run.go @@ -13,13 +13,20 @@ import ( ) type Run struct { - *Base[*dockerfile_instruction.Run] + *Base[*dockerfile_instruction.Run, *backend_instruction.Run] } func NewRun(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Run], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Run { return &Run{Base: NewBase(name, i, backend_instruction.NewRun(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Run) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - return util.Sha256Hash(append([]string{stage.instruction.Data.Name()}, stage.instruction.Data.Command...)...), nil +func (stg *Run) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, append([]string{"Command"}, stg.instruction.Data.Command...)...) + return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/shell.go b/pkg/build/stage/instruction/shell.go index 92b0fa0759..51b4e94e49 100644 --- a/pkg/build/stage/instruction/shell.go +++ b/pkg/build/stage/instruction/shell.go @@ -13,16 +13,20 @@ import ( ) type Shell struct { - *Base[*dockerfile_instruction.Shell] + *Base[*dockerfile_instruction.Shell, *backend_instruction.Shell] } func NewShell(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Shell], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Shell { return &Shell{Base: NewBase(name, i, backend_instruction.NewShell(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Shell) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Shell...) +func (stg *Shell) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, append([]string{"Shell"}, stg.instruction.Data.Shell...)...) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/stop_signal.go b/pkg/build/stage/instruction/stop_signal.go index 9619e5755c..344e7cfbc0 100644 --- a/pkg/build/stage/instruction/stop_signal.go +++ b/pkg/build/stage/instruction/stop_signal.go @@ -13,16 +13,20 @@ import ( ) type StopSignal struct { - *Base[*dockerfile_instruction.StopSignal] + *Base[*dockerfile_instruction.StopSignal, *backend_instruction.StopSignal] } func NewStopSignal(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.StopSignal], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *StopSignal { return &StopSignal{Base: NewBase(name, i, backend_instruction.NewStopSignal(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *StopSignal) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Signal) +func (stg *StopSignal) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "Signal", stg.instruction.Data.Signal) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/user.go b/pkg/build/stage/instruction/user.go index 7a22ab5c09..b9f58c6641 100644 --- a/pkg/build/stage/instruction/user.go +++ b/pkg/build/stage/instruction/user.go @@ -13,16 +13,20 @@ import ( ) type User struct { - *Base[*dockerfile_instruction.User] + *Base[*dockerfile_instruction.User, *backend_instruction.User] } func NewUser(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.User], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *User { return &User{Base: NewBase(name, i, backend_instruction.NewUser(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *User) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.User) +func (stg *User) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "User", stg.instruction.Data.User) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/volume.go b/pkg/build/stage/instruction/volume.go index 0e1bf82114..65ccb222b0 100644 --- a/pkg/build/stage/instruction/volume.go +++ b/pkg/build/stage/instruction/volume.go @@ -13,16 +13,20 @@ import ( ) type Volume struct { - *Base[*dockerfile_instruction.Volume] + *Base[*dockerfile_instruction.Volume, *backend_instruction.Volume] } func NewVolume(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Volume], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Volume { return &Volume{Base: NewBase(name, i, backend_instruction.NewVolume(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Volume) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Volumes...) +func (stg *Volume) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, append([]string{"Volumes"}, stg.instruction.Data.Volumes...)...) return util.Sha256Hash(args...), nil } diff --git a/pkg/build/stage/instruction/workdir.go b/pkg/build/stage/instruction/workdir.go index 6a3b91d6e0..84b9fb1422 100644 --- a/pkg/build/stage/instruction/workdir.go +++ b/pkg/build/stage/instruction/workdir.go @@ -13,16 +13,20 @@ import ( ) type Workdir struct { - *Base[*dockerfile_instruction.Workdir] + *Base[*dockerfile_instruction.Workdir, *backend_instruction.Workdir] } func NewWorkdir(name stage.StageName, i *dockerfile.DockerfileStageInstruction[*dockerfile_instruction.Workdir], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Workdir { return &Workdir{Base: NewBase(name, i, backend_instruction.NewWorkdir(*i.Data), dependencies, hasPrevStage, opts)} } -func (stage *Workdir) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { - var args []string - args = append(args, stage.instruction.Data.Name()) - args = append(args, stage.instruction.Data.Workdir) +func (stg *Workdir) GetDependencies(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevImage, prevBuiltImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) (string, error) { + args, err := stg.getDependencies(ctx, c, cb, prevImage, prevBuiltImage, buildContextArchive, stg) + if err != nil { + return "", err + } + + args = append(args, "Instruction", stg.instruction.Data.Name()) + args = append(args, "Workdir", stg.instruction.Data.Workdir) return util.Sha256Hash(args...), nil }