Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
feat(buildah): enable :local mode for buildah backend
Also fixed buildah non-staged dockerfile builder: labels were not applied to the built images.

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Apr 12, 2023
1 parent e519902 commit d1e400d
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 60 deletions.
16 changes: 2 additions & 14 deletions cmd/werf/common/common.go
Expand Up @@ -862,16 +862,6 @@ func GetLocalStagesStorage(containerBackend container_backend.ContainerBackend)
}

func GetStagesStorage(ctx context.Context, containerBackend container_backend.ContainerBackend, cmdData *CmdData) (storage.PrimaryStagesStorage, error) {
if _, match := containerBackend.(*container_backend.BuildahBackend); match {
addr, err := cmdData.Repo.GetAddress()
if err != nil {
return nil, err
}

if addr == storage.LocalStorageAddress {
return nil, fmt.Errorf(`"--repo" should be specified and not equal ":local" for Buildah container backend`)
}
}
return cmdData.Repo.CreateStagesStorage(ctx, containerBackend, *cmdData.InsecureRegistry, *cmdData.SkipTlsVerifyRegistry)
}

Expand Down Expand Up @@ -902,10 +892,8 @@ func GetCacheStagesStorageList(ctx context.Context, containerBackend container_b
func GetSecondaryStagesStorageList(ctx context.Context, stagesStorage storage.StagesStorage, containerBackend container_backend.ContainerBackend, cmdData *CmdData) ([]storage.StagesStorage, error) {
var res []storage.StagesStorage

if _, matched := containerBackend.(*container_backend.DockerServerBackend); matched {
if stagesStorage.Address() != storage.LocalStorageAddress {
res = append(res, storage.NewLocalStagesStorage(containerBackend))
}
if stagesStorage.Address() != storage.LocalStorageAddress {
res = append(res, storage.NewLocalStagesStorage(containerBackend))
}

for _, address := range GetSecondaryStagesStorage(cmdData) {
Expand Down
1 change: 1 addition & 0 deletions pkg/buildah/common.go
Expand Up @@ -47,6 +47,7 @@ type BuildFromDockerfileOpts struct {
ContextDir string
BuildArgs map[string]string
Target string
Labels []string
}

type RunMount struct {
Expand Down
13 changes: 10 additions & 3 deletions pkg/buildah/native_linux.go
Expand Up @@ -26,7 +26,9 @@ import (
"github.com/containers/common/libimage"
"github.com/containers/image/v5/manifest"
imgstor "github.com/containers/image/v5/storage"
storageTransport "github.com/containers/image/v5/storage"
"github.com/containers/image/v5/transports/alltransports"
"github.com/containers/image/v5/types"
imgtypes "github.com/containers/image/v5/types"
"github.com/containers/storage"
"github.com/containers/storage/drivers/overlay"
Expand Down Expand Up @@ -313,6 +315,7 @@ func (b *NativeBuildah) BuildFromDockerfile(ctx context.Context, dockerfile stri
RemoveIntermediateCtrs: true,
ForceRmIntermediateCtrs: false,
NoCache: false,
Labels: opts.Labels,
}

if targetPlatform != b.GetRuntimePlatform() {
Expand Down Expand Up @@ -516,11 +519,15 @@ func (b *NativeBuildah) Commit(ctx context.Context, container string, opts Commi
return "", fmt.Errorf("error getting builder: %w", err)
}

var imageRef imgtypes.ImageReference
var imageRef types.ImageReference
if opts.Image != "" {
imageRef, err = alltransports.ParseImageName(opts.Image)
normalizedImage, err := libimage.NormalizeName(opts.Image)
if err != nil {
return "", fmt.Errorf("error parsing image name: %w", err)
return "", fmt.Errorf("normalizing target image name %q: %w", opts.Image, err)
}
imageRef, err = storageTransport.Transport.ParseStoreReference(b.Store, normalizedImage.String())
if err != nil {
return "", fmt.Errorf("parsing target image name %q: %w", opts.Image, err)
}
}

Expand Down
34 changes: 24 additions & 10 deletions pkg/container_backend/buildah_backend.go
Expand Up @@ -695,6 +695,7 @@ func (backend *BuildahBackend) BuildDockerfile(ctx context.Context, dockerfileCo
ContextDir: buildContextTmpDir,
BuildArgs: buildArgs,
Target: opts.Target,
Labels: opts.Labels,
})
}

Expand Down Expand Up @@ -782,7 +783,7 @@ func (backend *BuildahBackend) RemoveImage(ctx context.Context, img LegacyImageI
}

func (backend *BuildahBackend) String() string {
return "buildah-runtime"
return "buildah-backend"
}

func (backend *BuildahBackend) RemoveHostDirs(ctx context.Context, mountDir string, dirs []string) error {
Expand Down Expand Up @@ -988,22 +989,35 @@ func newHealthConfigFromString(healthcheck string) (*thirdparty.BuildahHealthCon
return healthconfig, nil
}

func (runtime *BuildahBackend) Images(ctx context.Context, opts ImagesOptions) (image.ImagesList, error) {
func (backend *BuildahBackend) Images(ctx context.Context, opts ImagesOptions) (image.ImagesList, error) {
imagesOpts := buildah.ImagesOptions{Filters: opts.Filters}
return runtime.buildah.Images(ctx, imagesOpts)
return backend.buildah.Images(ctx, imagesOpts)
}

func (runtime *BuildahBackend) Containers(ctx context.Context, opts ContainersOptions) (image.ContainerList, error) {
func (backend *BuildahBackend) Containers(ctx context.Context, opts ContainersOptions) (image.ContainerList, error) {
containersOpts := buildah.ContainersOptions{Filters: opts.Filters}
return runtime.buildah.Containers(ctx, containersOpts)
return backend.buildah.Containers(ctx, containersOpts)
}

func (runtime *BuildahBackend) Rm(ctx context.Context, name string, opts RmOpts) error {
return runtime.buildah.Rm(ctx, name, buildah.RmOpts{})
func (backend *BuildahBackend) Rm(ctx context.Context, name string, opts RmOpts) error {
return backend.buildah.Rm(ctx, name, buildah.RmOpts{})
}

func (runtime *BuildahBackend) PostManifest(ctx context.Context, ref string, opts PostManifestOpts) error {
return fmt.Errorf("not implemented")
func (backend *BuildahBackend) PostManifest(ctx context.Context, ref string, opts PostManifestOpts) error {
containerID := uuid.New().String()
_, err := backend.buildah.FromCommand(ctx, containerID, "", buildah.FromCommandOpts(backend.getBuildahCommonOpts(ctx, true, nil, opts.TargetPlatform)))
if err != nil {
return fmt.Errorf("unable to create container using scratch base image: %w", err)
}

if err := backend.buildah.Config(ctx, containerID, buildah.ConfigOpts{Labels: opts.Labels}); err != nil {
return fmt.Errorf("unable to configure container %q labels: %w", containerID, err)
}

if _, err := backend.buildah.Commit(ctx, containerID, buildah.CommitOpts{Image: ref}); err != nil {
return fmt.Errorf("unable to commit container %q: %w", containerID, err)
}
return nil
}

func (runtime *BuildahBackend) ClaimTargetPlatforms(ctx context.Context, targetPlatforms []string) {}
func (backend *BuildahBackend) ClaimTargetPlatforms(ctx context.Context, targetPlatforms []string) {}
66 changes: 33 additions & 33 deletions pkg/container_backend/docker_server_backend.go
Expand Up @@ -23,31 +23,31 @@ func NewDockerServerBackend() *DockerServerBackend {
return &DockerServerBackend{}
}

func (runtime *DockerServerBackend) ClaimTargetPlatforms(ctx context.Context, targetPlatforms []string) {
func (backend *DockerServerBackend) ClaimTargetPlatforms(ctx context.Context, targetPlatforms []string) {
docker.ClaimTargetPlatforms(targetPlatforms)
}

func (runtime *DockerServerBackend) GetDefaultPlatform() string {
func (backend *DockerServerBackend) GetDefaultPlatform() string {
return docker.GetDefaultPlatform()
}

func (runtime *DockerServerBackend) GetRuntimePlatform() string {
func (backend *DockerServerBackend) GetRuntimePlatform() string {
return docker.GetRuntimePlatform()
}

func (runtime *DockerServerBackend) HasStapelBuildSupport() bool {
func (backend *DockerServerBackend) HasStapelBuildSupport() bool {
return false
}

func (runtime *DockerServerBackend) BuildStapelStage(ctx context.Context, baseImage string, opts BuildStapelStageOptions) (string, error) {
func (backend *DockerServerBackend) BuildStapelStage(ctx context.Context, baseImage string, opts BuildStapelStageOptions) (string, error) {
panic("BuildStapelStage does not implemented for DockerServerBackend. Please report the bug if you've received this message.")
}

func (runtime *DockerServerBackend) CalculateDependencyImportChecksum(ctx context.Context, dependencyImport DependencyImportSpec, opts CalculateDependencyImportChecksum) (string, error) {
func (backend *DockerServerBackend) CalculateDependencyImportChecksum(ctx context.Context, dependencyImport DependencyImportSpec, opts CalculateDependencyImportChecksum) (string, error) {
panic("CalculateDependencyImportChecksum does not implemented for DockerServerBackend. Please report the bug if you've received this message.")
}

func (runtime *DockerServerBackend) BuildDockerfile(ctx context.Context, _ []byte, opts BuildDockerfileOpts) (string, error) {
func (backend *DockerServerBackend) BuildDockerfile(ctx context.Context, _ []byte, opts BuildDockerfileOpts) (string, error) {
switch {
case opts.BuildContextArchive == nil:
panic(fmt.Sprintf("BuildContextArchive can't be nil: %+v", opts))
Expand Down Expand Up @@ -102,7 +102,7 @@ func (runtime *DockerServerBackend) BuildDockerfile(ctx context.Context, _ []byt
return tempID, docker.CliBuild_LiveOutputWithCustomIn(ctx, contextReader, cliArgs...)
}

func (runtime *DockerServerBackend) BuildDockerfileStage(ctx context.Context, baseImage string, opts BuildDockerfileStageOptions, instructions ...InstructionInterface) (string, error) {
func (backend *DockerServerBackend) BuildDockerfileStage(ctx context.Context, baseImage string, opts BuildDockerfileStageOptions, instructions ...InstructionInterface) (string, error) {
logboek.Context(ctx).Error().LogF("Staged build of Dockerfile is not available for Docker Server backend.")
logboek.Context(ctx).Error().LogF("Please either:\n")
logboek.Context(ctx).Error().LogF(" * switch to Buildah backend;\n")
Expand All @@ -113,11 +113,11 @@ func (runtime *DockerServerBackend) BuildDockerfileStage(ctx context.Context, ba

// ShouldCleanupDockerfileImage for docker-server backend we should cleanup image built from dockerfrom tagged with tempID
// which is implementation detail of the BuildDockerfile.
func (runtime *DockerServerBackend) ShouldCleanupDockerfileImage() bool {
func (backend *DockerServerBackend) ShouldCleanupDockerfileImage() bool {
return true
}

func (runtime *DockerServerBackend) GetImageInfo(ctx context.Context, ref string, opts GetImageInfoOpts) (*image.Info, error) {
func (backend *DockerServerBackend) GetImageInfo(ctx context.Context, ref string, opts GetImageInfoOpts) (*image.Info, error) {
inspect, err := docker.ImageInspect(ctx, ref)
if client.IsErrNotFound(err) {
return nil, nil
Expand All @@ -129,16 +129,16 @@ func (runtime *DockerServerBackend) GetImageInfo(ctx context.Context, ref string
}

// GetImageInspect only available for DockerServerBackend
func (runtime *DockerServerBackend) GetImageInspect(ctx context.Context, ref string) (*types.ImageInspect, error) {
func (backend *DockerServerBackend) GetImageInspect(ctx context.Context, ref string) (*types.ImageInspect, error) {
inspect, err := docker.ImageInspect(ctx, ref)
if client.IsErrNotFound(err) {
return nil, nil
}
return inspect, err
}

func (runtime *DockerServerBackend) RefreshImageObject(ctx context.Context, img LegacyImageInterface) error {
if info, err := runtime.GetImageInfo(ctx, img.Name(), GetImageInfoOpts{TargetPlatform: img.GetTargetPlatform()}); err != nil {
func (backend *DockerServerBackend) RefreshImageObject(ctx context.Context, img LegacyImageInterface) error {
if info, err := backend.GetImageInfo(ctx, img.Name(), GetImageInfoOpts{TargetPlatform: img.GetTargetPlatform()}); err != nil {
return err
} else {
img.SetInfo(info)
Expand All @@ -147,7 +147,7 @@ func (runtime *DockerServerBackend) RefreshImageObject(ctx context.Context, img
}

// FIXME(multiarch): targetPlatform support needed?
func (runtime *DockerServerBackend) RenameImage(ctx context.Context, img LegacyImageInterface, newImageName string, removeOldName bool) error {
func (backend *DockerServerBackend) RenameImage(ctx context.Context, img LegacyImageInterface, newImageName string, removeOldName bool) error {
if err := logboek.Context(ctx).Info().LogProcess(fmt.Sprintf("Tagging image %s by name %s", img.Name(), newImageName)).DoError(func() error {
if err := docker.CliTag(ctx, img.Name(), newImageName); err != nil {
return fmt.Errorf("unable to tag image %s by name %s: %w", img.Name(), newImageName, err)
Expand All @@ -170,7 +170,7 @@ func (runtime *DockerServerBackend) RenameImage(ctx context.Context, img LegacyI

img.SetName(newImageName)

if info, err := runtime.GetImageInfo(ctx, img.Name(), GetImageInfoOpts{TargetPlatform: img.GetTargetPlatform()}); err != nil {
if info, err := backend.GetImageInfo(ctx, img.Name(), GetImageInfoOpts{TargetPlatform: img.GetTargetPlatform()}); err != nil {
return err
} else {
img.SetInfo(info)
Expand All @@ -186,20 +186,20 @@ func (runtime *DockerServerBackend) RenameImage(ctx context.Context, img LegacyI
return nil
}

func (runtime *DockerServerBackend) RemoveImage(ctx context.Context, img LegacyImageInterface) error {
func (backend *DockerServerBackend) RemoveImage(ctx context.Context, img LegacyImageInterface) error {
return logboek.Context(ctx).Info().LogProcess(fmt.Sprintf("Removing image tag %s", img.Name())).DoError(func() error {
return runtime.Rmi(ctx, img.Name(), RmiOpts{
return backend.Rmi(ctx, img.Name(), RmiOpts{
CommonOpts: CommonOpts{TargetPlatform: img.GetTargetPlatform()},
})
})
}

func (runtime *DockerServerBackend) PullImageFromRegistry(ctx context.Context, img LegacyImageInterface) error {
func (backend *DockerServerBackend) PullImageFromRegistry(ctx context.Context, img LegacyImageInterface) error {
if err := img.Pull(ctx); err != nil {
return fmt.Errorf("unable to pull image %s: %w", img.Name(), err)
}

if info, err := runtime.GetImageInfo(ctx, img.Name(), GetImageInfoOpts{TargetPlatform: img.GetTargetPlatform()}); err != nil {
if info, err := backend.GetImageInfo(ctx, img.Name(), GetImageInfoOpts{TargetPlatform: img.GetTargetPlatform()}); err != nil {
return fmt.Errorf("unable to get inspect of image %s: %w", img.Name(), err)
} else {
img.SetInfo(info)
Expand All @@ -208,15 +208,15 @@ func (runtime *DockerServerBackend) PullImageFromRegistry(ctx context.Context, i
return nil
}

func (runtime *DockerServerBackend) Tag(ctx context.Context, ref, newRef string, opts TagOpts) error {
func (backend *DockerServerBackend) Tag(ctx context.Context, ref, newRef string, opts TagOpts) error {
return docker.CliTag(ctx, ref, newRef)
}

func (runtime *DockerServerBackend) Push(ctx context.Context, ref string, opts PushOpts) error {
func (backend *DockerServerBackend) Push(ctx context.Context, ref string, opts PushOpts) error {
return docker.CliPushWithRetries(ctx, ref)
}

func (runtime *DockerServerBackend) Pull(ctx context.Context, ref string, opts PullOpts) error {
func (backend *DockerServerBackend) Pull(ctx context.Context, ref string, opts PullOpts) error {
var args []string
if opts.TargetPlatform != "" {
args = append(args, "--platform", opts.TargetPlatform)
Expand All @@ -229,19 +229,19 @@ func (runtime *DockerServerBackend) Pull(ctx context.Context, ref string, opts P
return nil
}

func (runtime *DockerServerBackend) Rmi(ctx context.Context, ref string, opts RmiOpts) error {
func (backend *DockerServerBackend) Rmi(ctx context.Context, ref string, opts RmiOpts) error {
args := []string{ref}
if opts.Force {
args = append(args, "--force")
}
return docker.CliRmi(ctx, args...)
}

func (runtime *DockerServerBackend) Rm(ctx context.Context, ref string, opts RmOpts) error {
func (backend *DockerServerBackend) Rm(ctx context.Context, ref string, opts RmOpts) error {
return docker.ContainerRemove(ctx, ref, types.ContainerRemoveOptions{Force: opts.Force})
}

func (runtime *DockerServerBackend) PushImage(ctx context.Context, img LegacyImageInterface) error {
func (backend *DockerServerBackend) PushImage(ctx context.Context, img LegacyImageInterface) error {
if err := logboek.Context(ctx).Info().LogProcess(fmt.Sprintf("Pushing %s", img.Name())).DoError(func() error {
return docker.CliPushWithRetries(ctx, img.Name())
}); err != nil {
Expand All @@ -250,24 +250,24 @@ func (runtime *DockerServerBackend) PushImage(ctx context.Context, img LegacyIma
return nil
}

func (runtime *DockerServerBackend) TagImageByName(ctx context.Context, img LegacyImageInterface) error {
func (backend *DockerServerBackend) TagImageByName(ctx context.Context, img LegacyImageInterface) error {
if img.BuiltID() != "" {
if err := docker.CliTag(ctx, img.BuiltID(), img.Name()); err != nil {
return fmt.Errorf("unable to tag image %s: %w", img.Name(), err)
}
} else {
if err := runtime.RefreshImageObject(ctx, img); err != nil {
if err := backend.RefreshImageObject(ctx, img); err != nil {
return err
}
}
return nil
}

func (runtime *DockerServerBackend) String() string {
return "local-docker-server"
func (backend *DockerServerBackend) String() string {
return "docker-server-backend"
}

func (runtime *DockerServerBackend) RemoveHostDirs(ctx context.Context, mountDir string, dirs []string) error {
func (backend *DockerServerBackend) RemoveHostDirs(ctx context.Context, mountDir string, dirs []string) error {
var containerDirs []string
for _, dir := range dirs {
containerDirs = append(containerDirs, util.ToLinuxContainerPath(dir))
Expand All @@ -285,7 +285,7 @@ func (runtime *DockerServerBackend) RemoveHostDirs(ctx context.Context, mountDir
return docker.CliRun(ctx, args...)
}

func (runtime *DockerServerBackend) Images(ctx context.Context, opts ImagesOptions) (image.ImagesList, error) {
func (backend *DockerServerBackend) Images(ctx context.Context, opts ImagesOptions) (image.ImagesList, error) {
filterSet := filters.NewArgs()
for _, item := range opts.Filters {
filterSet.Add(item.First, item.Second)
Expand All @@ -304,7 +304,7 @@ func (runtime *DockerServerBackend) Images(ctx context.Context, opts ImagesOptio
return res, nil
}

func (runtime *DockerServerBackend) Containers(ctx context.Context, opts ContainersOptions) (image.ContainerList, error) {
func (backend *DockerServerBackend) Containers(ctx context.Context, opts ContainersOptions) (image.ContainerList, error) {
filterSet := filters.NewArgs()
for _, filter := range opts.Filters {
if filter.ID != "" {
Expand Down Expand Up @@ -339,6 +339,6 @@ func (runtime *DockerServerBackend) Containers(ctx context.Context, opts Contain
return res, nil
}

func (runtime *DockerServerBackend) PostManifest(ctx context.Context, ref string, opts PostManifestOpts) error {
func (backend *DockerServerBackend) PostManifest(ctx context.Context, ref string, opts PostManifestOpts) error {
return docker.CreateImage(ctx, ref, docker.CreateImageOptions{Labels: opts.Labels})
}

0 comments on commit d1e400d

Please sign in to comment.