Skip to content
Permalink
Browse files
feat(staged-dockerfile): implement whether stage uses build-context c…
…orrectly

This fixes panic when trying to use uninitialized build-context because of unimplemented UsesBuildContext method at the pkg/build/stage/instruction level. Also refactored pkg/build/stage/instruction a bit: common PrepareImage method implementation in Base.

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Oct 19, 2022
1 parent 306ed6c commit 2851923135a4926c8ba44b85917d600ad1e03462
Show file tree
Hide file tree
Showing 20 changed files with 37 additions and 95 deletions.
@@ -695,6 +695,7 @@ func (phase *BuildPhase) prepareStageInstructions(ctx context.Context, img *imag
return stageImage.Builder.DockerfileBuilder().Cleanup(ctx)
})
} else {
stageImage.Builder.DockerfileStageBuilder().SetBuildContextArchive(phase.buildContextArchive)
stageImage.Builder.DockerfileStageBuilder().AppendPostInstruction(backend_instruction.NewLabel(*dockerfile_instruction.NewLabel(serviceLabels)))
}

@@ -118,7 +118,7 @@ func mapDockerfileToImagesSets(ctx context.Context, cfg *dockerfile.Dockerfile,
}

for ind, instr := range stg.Instructions {
stageName := stage.StageName(fmt.Sprintf("%d-%s", ind, instr.GetInstructionData().Name()))
stageName := stage.StageName(fmt.Sprintf("%s%d", instr.GetInstructionData().Name(), ind))
isFirstStage := (len(img.stages) == 0)
baseStageOptions := &stage.BaseStageOptions{
ImageName: img.Name,
@@ -17,7 +17,7 @@ type Add struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -29,7 +29,3 @@ func (stage *Add) GetDependencies(ctx context.Context, c stage.Conveyor, cb cont
args = append(args, stage.instruction.Data.Chmod)
return util.Sha256Hash(args...), nil
}

func (stage *Add) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewAdd(*stage.instruction.Data))
}
@@ -12,17 +12,19 @@ import (
type Base[T dockerfile.InstructionDataInterface] struct {
*stage.BaseStage

instruction *dockerfile.DockerfileStageInstruction[T]
dependencies []*config.Dependency
hasPrevStage bool
instruction *dockerfile.DockerfileStageInstruction[T]
backendInstruction container_backend.InstructionInterface
dependencies []*config.Dependency
hasPrevStage bool
}

func NewBase[T dockerfile.InstructionDataInterface](name stage.StageName, instruction *dockerfile.DockerfileStageInstruction[T], dependencies []*config.Dependency, hasPrevStage bool, opts *stage.BaseStageOptions) *Base[T] {
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]{
BaseStage: stage.NewBaseStage(name, opts),
instruction: instruction,
dependencies: dependencies,
hasPrevStage: hasPrevStage,
BaseStage: stage.NewBaseStage(name, opts),
instruction: instruction,
backendInstruction: backendInstruction,
dependencies: dependencies,
hasPrevStage: hasPrevStage,
}
}

@@ -34,8 +36,11 @@ func (stg *Base[T]) IsStapelStage() bool {
return false
}

func (stg *Base[T]) prepareInstruction(ctx context.Context, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver, backendInstruction container_backend.InstructionInterface) error {
stageImage.Builder.DockerfileStageBuilder().SetBuildContextArchive(buildContextArchive) // FIXME(staged-dockerfile): set context at build-phase level
stageImage.Builder.DockerfileStageBuilder().AppendInstruction(backendInstruction)
func (stg *Base[T]) 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 {
stageImage.Builder.DockerfileStageBuilder().AppendInstruction(stg.backendInstruction)
return nil
}
@@ -18,7 +18,7 @@ type Cmd struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -28,7 +28,3 @@ func (stage *Cmd) GetDependencies(ctx context.Context, c stage.Conveyor, cb cont
args = append(args, fmt.Sprintf("%v", stage.instruction.Data.PrependShell))
return util.Sha256Hash(args...), nil
}

func (stage *Cmd) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewCmd(*stage.instruction.Data))
}
@@ -17,7 +17,7 @@ type Copy struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -30,7 +30,3 @@ func (stage *Copy) GetDependencies(ctx context.Context, c stage.Conveyor, cb con
args = append(args, stage.instruction.Data.Chmod)
return util.Sha256Hash(args...), nil
}

func (stage *Copy) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewCopy(*stage.instruction.Data))
}
@@ -18,7 +18,7 @@ type Entrypoint struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -28,7 +28,3 @@ func (stage *Entrypoint) GetDependencies(ctx context.Context, c stage.Conveyor,
args = append(args, fmt.Sprintf("%v", stage.instruction.Data.PrependShell))
return util.Sha256Hash(args...), nil
}

func (stage *Entrypoint) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewEntrypoint(*stage.instruction.Data))
}
@@ -17,7 +17,7 @@ type Env struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -29,7 +29,3 @@ func (stage *Env) GetDependencies(ctx context.Context, c stage.Conveyor, cb cont
}
return util.Sha256Hash(args...), nil
}

func (stage *Env) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewEnv(*stage.instruction.Data))
}
@@ -17,7 +17,7 @@ type Expose struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -26,7 +26,3 @@ func (stage *Expose) GetDependencies(ctx context.Context, c stage.Conveyor, cb c
args = append(args, stage.instruction.Data.Ports...)
return util.Sha256Hash(args...), nil
}

func (stage *Expose) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewExpose(*stage.instruction.Data))
}
@@ -17,7 +17,8 @@ type Healthcheck struct {
}

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, dependencies, hasPrevStage, opts)}
// FIXME(staged-dockerfile): construct backend instruction
return &Healthcheck{Base: NewBase(name, i, nil, 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) {
@@ -31,8 +32,3 @@ func (stage *Healthcheck) GetDependencies(ctx context.Context, c stage.Conveyor,
args = append(args, fmt.Sprintf("%d", stage.instruction.Data.Config.Retries))
return util.Sha256Hash(args...), nil
}

func (stage *Healthcheck) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
// FIXME(staged-dockerfile): construct backend instruction
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, nil)
}
@@ -17,7 +17,7 @@ type Label struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -29,7 +29,3 @@ func (stage *Label) GetDependencies(ctx context.Context, c stage.Conveyor, cb co
}
return util.Sha256Hash(args...), nil
}

func (stage *Label) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewLabel(*stage.instruction.Data))
}
@@ -16,7 +16,8 @@ type Maintainer struct {
}

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, dependencies, hasPrevStage, opts)}
// FIXME(staged-dockerfile): no Maintainer instruction
return &Maintainer{Base: NewBase(name, i, nil, 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) {
@@ -25,8 +26,3 @@ func (stage *Maintainer) GetDependencies(ctx context.Context, c stage.Conveyor,
args = append(args, stage.instruction.Data.Maintainer)
return util.Sha256Hash(args...), nil
}

func (stage *Maintainer) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
// FIXME(staged-dockerfile): no Maintainer instruction
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, nil)
}
@@ -17,7 +17,7 @@ type OnBuild struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -26,7 +26,3 @@ func (stage *OnBuild) GetDependencies(ctx context.Context, c stage.Conveyor, cb
args = append(args, stage.instruction.Data.Instruction)
return util.Sha256Hash(args...), nil
}

func (stage *OnBuild) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewOnBuild(*stage.instruction.Data))
}
@@ -17,13 +17,9 @@ type Run struct {
}

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, dependencies, hasPrevStage, opts)}
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 (stage *Run) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewRun(*stage.instruction.Data))
}
@@ -17,7 +17,7 @@ type Shell struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -26,7 +26,3 @@ func (stage *Shell) GetDependencies(ctx context.Context, c stage.Conveyor, cb co
args = append(args, stage.instruction.Data.Shell...)
return util.Sha256Hash(args...), nil
}

func (stage *Shell) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewShell(*stage.instruction.Data))
}
@@ -17,7 +17,7 @@ type StopSignal struct {
}

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, dependencies, hasPrevStage, opts)}
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) {
@@ -26,7 +26,3 @@ func (stage *StopSignal) GetDependencies(ctx context.Context, c stage.Conveyor,
args = append(args, stage.instruction.Data.Signal)
return util.Sha256Hash(args...), nil
}

func (stage *StopSignal) PrepareImage(ctx context.Context, c stage.Conveyor, cb container_backend.ContainerBackend, prevBuiltImage, stageImage *stage.StageImage, buildContextArchive container_backend.BuildContextArchiver) error {
return stage.Base.prepareInstruction(ctx, stageImage, buildContextArchive, backend_instruction.NewStopSignal(*stage.instruction.Data))
}

0 comments on commit 2851923

Please sign in to comment.