Skip to content

Commit

Permalink
feat(staged-dockerfile): support ONBUILD instructions
Browse files Browse the repository at this point in the history
refs #2215

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Nov 16, 2022
1 parent 9e6aa60 commit 839bb61
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 8 deletions.
7 changes: 5 additions & 2 deletions pkg/build/build_phase.go
Expand Up @@ -225,8 +225,11 @@ func (phase *BuildPhase) ImageProcessingShouldBeStopped(_ context.Context, _ *im
func (phase *BuildPhase) BeforeImageStages(ctx context.Context, img *image.Image) (deferFn func(), err error) {
phase.StagesIterator = NewStagesIterator(phase.Conveyor)

if err := img.SetupBaseImage(); err != nil {
return nil, err
if err := img.SetupBaseImage(ctx, phase.Conveyor.StorageManager, manager.StorageOptions{
ContainerBackend: phase.Conveyor.ContainerBackend,
DockerRegistry: docker_registry.API(),
}); err != nil {
return nil, fmt.Errorf("unable to setup base image: %w", err)
}

if img.UsesBuildContext() {
Expand Down
20 changes: 19 additions & 1 deletion pkg/build/image/image.go
Expand Up @@ -201,7 +201,7 @@ func (i *Image) GetRebuilt() bool {
return i.rebuilt
}

func (i *Image) SetupBaseImage() error {
func (i *Image) SetupBaseImage(ctx context.Context, storageManager manager.StorageManagerInterface, storageOpts manager.StorageOptions) error {
switch i.baseImageType {
case StageAsBaseImage:
i.stageAsBaseImage = i.Conveyor.GetImage(i.baseImageName).GetLastNonEmptyStage()
Expand All @@ -222,6 +222,24 @@ func (i *Image) SetupBaseImage() error {
panic(fmt.Sprintf("unknown base image type %q", i.baseImageType))
}

if i.IsDockerfileImage && i.DockerfileImageConfig.Staged {
switch i.baseImageType {
case StageAsBaseImage, ImageFromRegistryAsBaseImage:

fmt.Printf("-- %s SetupBaseImage %q\n", i.Name, i.baseImageReference)

info, err := storageManager.GetImageInfo(ctx, i.baseImageReference, storageOpts)
if err != nil {
return fmt.Errorf("unable to get base image %q manifest: %w", i.baseImageReference, err)
}

fmt.Printf("-- %s SetupBaseImage %q -> %#v\n", i.Name, i.baseImageReference, info)
for _, expression := range info.OnBuild {
fmt.Printf(">> %q\n", expression)
}
}
}

return nil
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/dockerfile/frontend/buildkit_dockerfile.go
Expand Up @@ -18,14 +18,14 @@ func ParseDockerfileWithBuildkit(dockerfileBytes []byte, opts dockerfile.Dockerf
return nil, fmt.Errorf("parsing dockerfile data: %w", err)
}

dockerStages, dockerMetaArgs, err := instructions.Parse(p.AST)
dockerStages, dockerMetaArgsCommands, err := instructions.Parse(p.AST)
if err != nil {
return nil, fmt.Errorf("parsing instructions tree: %w", err)
}

expanderFactory := NewShlexExpanderFactory(p.EscapeToken)

metaArgs, err := resolveMetaArgs(dockerMetaArgs, opts.BuildArgs, opts.DependenciesArgsKeys, expanderFactory)
metaArgs, err := resolveMetaArgs(dockerMetaArgsCommands, opts.BuildArgs, opts.DependenciesArgsKeys, expanderFactory)
if err != nil {
return nil, fmt.Errorf("unable to process meta args: %w", err)
}
Expand Down Expand Up @@ -233,7 +233,7 @@ func removeDependenciesArgs(args []instructions.KeyValuePairOptional, dependenci
return
}

func resolveMetaArgs(metaArgs []instructions.ArgCommand, buildArgs map[string]string, dependenciesArgsKeys []string, expanderFactory *ShlexExpanderFactory) (map[string]string, error) {
func resolveMetaArgs(metaArgsCommands []instructions.ArgCommand, buildArgs map[string]string, dependenciesArgsKeys []string, expanderFactory *ShlexExpanderFactory) (map[string]string, error) {
var optMetaArgs []instructions.KeyValuePairOptional

// TODO(staged-dockerfile): need to support builtin BUILD* and TARGET* args
Expand All @@ -244,7 +244,7 @@ func resolveMetaArgs(metaArgs []instructions.ArgCommand, buildArgs map[string]st
// optMetaArgs[i] = setKVValue(arg, opt.BuildArgs)
// }

for _, cmd := range metaArgs {
for _, cmd := range metaArgsCommands {
for _, metaArg := range cmd.Args {
if isDependencyArg(metaArg.Key, dependenciesArgsKeys) {
continue
Expand All @@ -257,7 +257,7 @@ func resolveMetaArgs(metaArgs []instructions.ArgCommand, buildArgs map[string]st
}
}

return nil, nil
return metaArgsToMap(optMetaArgs), nil
}

func metaArgsToMap(metaArgs []instructions.KeyValuePairOptional) map[string]string {
Expand Down
17 changes: 17 additions & 0 deletions pkg/image/info.go
Expand Up @@ -6,6 +6,7 @@ import (
"time"

"github.com/docker/docker/api/types"
v1 "github.com/google/go-containerregistry/pkg/v1"

"github.com/werf/werf/pkg/util"
)
Expand Down Expand Up @@ -84,3 +85,19 @@ func ParseRepositoryAndTag(ref string) (string, string) {
repository := util.Reverse(parts[1])
return repository, tag
}

func NewImageInfoFromRegistryConfig(ref string, cfg *v1.ConfigFile) *Info {
repository, tag := ParseRepositoryAndTag(ref)
return &Info{
Name: ref,
Repository: repository,
Tag: tag,
Labels: cfg.Config.Labels,
OnBuild: cfg.Config.OnBuild,
CreatedAtUnixNano: cfg.Created.UnixNano(),
RepoDigest: "", // TODO
ID: "", // TODO
ParentID: "", // TODO
Size: 0, // TODO
}
}
31 changes: 31 additions & 0 deletions pkg/storage/manager/storage_manager.go
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/werf/logboek/pkg/types"
"github.com/werf/werf/pkg/build/stage"
"github.com/werf/werf/pkg/container_backend"
"github.com/werf/werf/pkg/docker_registry"
"github.com/werf/werf/pkg/image"
"github.com/werf/werf/pkg/storage"
"github.com/werf/werf/pkg/storage/lrumeta"
Expand Down Expand Up @@ -47,6 +48,11 @@ type ForEachDeleteStageOptions struct {
storage.FilterStagesAndProcessRelatedDataOptions
}

type StorageOptions struct {
ContainerBackend container_backend.ContainerBackend
DockerRegistry docker_registry.ApiInterface
}

type StorageManagerInterface interface {
InitCache(ctx context.Context) error

Expand All @@ -59,6 +65,8 @@ type StorageManagerInterface interface {
MaxNumberOfWorkers() int
GenerateStageUniqueID(digest string, stages []*image.StageDescription) (string, int64)

GetImageInfo(ctx context.Context, ref string, opts StorageOptions) (*image.Info, error)

LockStageImage(ctx context.Context, imageName string) error
GetStagesByDigest(ctx context.Context, stageName, stageDigest string) ([]*image.StageDescription, error)
GetStagesByDigestWithCache(ctx context.Context, stageName, stageDigest string) ([]*image.StageDescription, error)
Expand Down Expand Up @@ -342,6 +350,29 @@ func (m *StorageManager) ForEachDeleteStage(ctx context.Context, options ForEach
})
}

func (m *StorageManager) GetImageInfo(ctx context.Context, ref string, opts StorageOptions) (*image.Info, error) {
info, err := m.getImageInfoFromContainerBackend(ctx, ref, opts.ContainerBackend)
if err != nil {
return nil, err
}
if info != nil {
return info, err
}
return m.getImageInfoFromRegistry(ctx, ref, opts.DockerRegistry)
}

func (m *StorageManager) getImageInfoFromContainerBackend(ctx context.Context, ref string, containerBackend container_backend.ContainerBackend) (*image.Info, error) {
return containerBackend.GetImageInfo(ctx, ref, container_backend.GetImageInfoOpts{})
}

func (m *StorageManager) getImageInfoFromRegistry(ctx context.Context, ref string, dockerRegistry docker_registry.ApiInterface) (*image.Info, error) {
cfg, err := dockerRegistry.GetRepoImageConfigFile(ctx, ref)
if err != nil {
return nil, err
}
return image.NewImageInfoFromRegistryConfig(ref, cfg), nil
}

func (m *StorageManager) LockStageImage(ctx context.Context, imageName string) error {
imageLockName := container_backend.ImageLockName(imageName)

Expand Down

0 comments on commit 839bb61

Please sign in to comment.