Skip to content

Commit

Permalink
chore(stapel-to-buildah): refactor pkg/build/stages to select impelem…
Browse files Browse the repository at this point in the history
…entation based on container-runtime type

Signed-off-by: Timofey Kirillov <timofey.kirillov@flant.com>
  • Loading branch information
distorhead committed Mar 29, 2022
1 parent 6594c23 commit 5291c2f
Show file tree
Hide file tree
Showing 27 changed files with 281 additions and 178 deletions.
2 changes: 1 addition & 1 deletion pkg/build/build_phase.go
Expand Up @@ -666,7 +666,7 @@ func (phase *BuildPhase) prepareStageInstructions(ctx context.Context, img *Imag
}
}

err := stg.PrepareImage(ctx, phase.Conveyor, phase.StagesIterator.GetPrevBuiltImage(img, stg), stageImage)
err := stg.PrepareImage(ctx, phase.Conveyor, phase.Conveyor.ContainerRuntime, phase.StagesIterator.GetPrevBuiltImage(img, stg), stageImage)
if err != nil {
return fmt.Errorf("error preparing stage %s: %s", stg.Name(), err)
}
Expand Down
120 changes: 64 additions & 56 deletions pkg/build/builder/ansible.go
Expand Up @@ -16,6 +16,7 @@ import (

"github.com/werf/logboek"
"github.com/werf/werf/pkg/config"
"github.com/werf/werf/pkg/container_runtime"
"github.com/werf/werf/pkg/stapel"
"github.com/werf/werf/pkg/util"
)
Expand Down Expand Up @@ -43,20 +44,20 @@ func (b *Ansible) IsBeforeSetupEmpty(ctx context.Context) bool {
}
func (b *Ansible) IsSetupEmpty(ctx context.Context) bool { return b.isEmptyStage(ctx, "Setup") }

func (b *Ansible) BeforeInstall(ctx context.Context, container Container) error {
return b.stage(ctx, "BeforeInstall", container)
func (b *Ansible) BeforeInstall(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(ctx, cr, stageBuilder, "BeforeInstall")
}

func (b *Ansible) Install(ctx context.Context, container Container) error {
return b.stage(ctx, "Install", container)
func (b *Ansible) Install(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(ctx, cr, stageBuilder, "Install")
}

func (b *Ansible) BeforeSetup(ctx context.Context, container Container) error {
return b.stage(ctx, "BeforeSetup", container)
func (b *Ansible) BeforeSetup(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(ctx, cr, stageBuilder, "BeforeSetup")
}

func (b *Ansible) Setup(ctx context.Context, container Container) error {
return b.stage(ctx, "Setup", container)
func (b *Ansible) Setup(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(ctx, cr, stageBuilder, "Setup")
}

func (b *Ansible) BeforeInstallChecksum(ctx context.Context) string {
Expand All @@ -72,63 +73,70 @@ func (b *Ansible) isEmptyStage(ctx context.Context, userStageName string) bool {
return b.stageChecksum(ctx, userStageName) == ""
}

func (b *Ansible) stage(ctx context.Context, userStageName string, container Container) error {
if len(b.stageTasks(userStageName)) == 0 {
return nil
}
func (b *Ansible) stage(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface, userStageName string) error {
if cr.HasContainerRootMountSupport() {
// TODO(stapel-to-buildah)
panic("not implemented")
} else {
container := stageBuilder.LegacyStapelStageBuilder().BuilderContainer()

if err := b.createStageWorkDirStructure(userStageName); err != nil {
return err
}
if len(b.stageTasks(userStageName)) == 0 {
return nil
}

container.AddEnv(
map[string]string{
"ANSIBLE_CONFIG": path.Join(b.containerWorkDir(), "ansible.cfg"),
"WERF_DUMP_CONFIG_DOC_PATH": path.Join(b.containerWorkDir(), "dump_config.json"),
"PYTHONIOENCODING": "utf-8",
"ANSIBLE_PREPEND_SYSTEM_PATH": stapel.AnsibleToolsOverlayPATH(),
"ANSIBLE_APPEND_SYSTEM_PATH": stapel.SystemPATH(),
"LD_LIBRARY_PATH": stapel.AnsibleLibsOverlayLDPATH(),
"LANG": "C.UTF-8",
"LC_ALL": "C.UTF-8",
"LOGBOEK_SO_PATH": "/.werf/stapel/embedded/lib/python2.7/_logboek.so",
},
)

stageHostWorkDir, err := b.stageHostWorkDir(userStageName)
if err != nil {
return err
}
if err := b.createStageWorkDirStructure(userStageName); err != nil {
return err
}

stageHostTmpDir, err := b.stageHostTmpDir(userStageName)
if err != nil {
return err
}
container.AddEnv(
map[string]string{
"ANSIBLE_CONFIG": path.Join(b.containerWorkDir(), "ansible.cfg"),
"WERF_DUMP_CONFIG_DOC_PATH": path.Join(b.containerWorkDir(), "dump_config.json"),
"PYTHONIOENCODING": "utf-8",
"ANSIBLE_PREPEND_SYSTEM_PATH": stapel.AnsibleToolsOverlayPATH(),
"ANSIBLE_APPEND_SYSTEM_PATH": stapel.SystemPATH(),
"LD_LIBRARY_PATH": stapel.AnsibleLibsOverlayLDPATH(),
"LANG": "C.UTF-8",
"LC_ALL": "C.UTF-8",
"LOGBOEK_SO_PATH": "/.werf/stapel/embedded/lib/python2.7/_logboek.so",
},
)

stageHostWorkDir, err := b.stageHostWorkDir(userStageName)
if err != nil {
return err
}

container.AddVolume(
fmt.Sprintf("%s:%s:ro", stageHostWorkDir, b.containerWorkDir()),
fmt.Sprintf("%s:%s:rw", stageHostTmpDir, b.containerTmpDir()),
)
stageHostTmpDir, err := b.stageHostTmpDir(userStageName)
if err != nil {
return err
}

containerName, err := stapel.GetOrCreateContainer(ctx)
if err != nil {
return err
}
container.AddVolumeFrom(fmt.Sprintf("%s:ro", containerName))
container.AddVolume(
fmt.Sprintf("%s:%s:ro", stageHostWorkDir, b.containerWorkDir()),
fmt.Sprintf("%s:%s:rw", stageHostTmpDir, b.containerTmpDir()),
)

commandParts := []string{
path.Join(b.containerWorkDir(), "ansible-playbook"),
path.Join(b.containerWorkDir(), "playbook.yml"),
}
containerName, err := stapel.GetOrCreateContainer(ctx)
if err != nil {
return err
}
container.AddVolumeFrom(fmt.Sprintf("%s:ro", containerName))

if value, exist := os.LookupEnv("WERF_DEBUG_ANSIBLE_ARGS"); exist {
commandParts = append(commandParts, value)
}
commandParts := []string{
path.Join(b.containerWorkDir(), "ansible-playbook"),
path.Join(b.containerWorkDir(), "playbook.yml"),
}

if value, exist := os.LookupEnv("WERF_DEBUG_ANSIBLE_ARGS"); exist {
commandParts = append(commandParts, value)
}

command := strings.Join(commandParts, " ")
container.AddServiceRunCommands(command)
command := strings.Join(commandParts, " ")
container.AddServiceRunCommands(command)

return nil
return nil
}
}

func (b *Ansible) stageChecksum(ctx context.Context, userStageName string) string {
Expand Down
10 changes: 6 additions & 4 deletions pkg/build/builder/builder.go
Expand Up @@ -3,17 +3,19 @@ package builder
import (
"context"
"os"

"github.com/werf/werf/pkg/container_runtime"
)

type Builder interface {
IsBeforeInstallEmpty(ctx context.Context) bool
IsInstallEmpty(ctx context.Context) bool
IsBeforeSetupEmpty(ctx context.Context) bool
IsSetupEmpty(ctx context.Context) bool
BeforeInstall(ctx context.Context, container Container) error
Install(ctx context.Context, container Container) error
BeforeSetup(ctx context.Context, container Container) error
Setup(ctx context.Context, container Container) error
BeforeInstall(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error
Install(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error
BeforeSetup(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error
Setup(ctx context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error
BeforeInstallChecksum(ctx context.Context) string
InstallChecksum(ctx context.Context) string
BeforeSetupChecksum(ctx context.Context) string
Expand Down
55 changes: 32 additions & 23 deletions pkg/build/builder/shell.go
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/werf/logboek"
"github.com/werf/werf/pkg/config"
"github.com/werf/werf/pkg/container_runtime"
"github.com/werf/werf/pkg/stapel"
"github.com/werf/werf/pkg/util"
)
Expand All @@ -35,20 +36,20 @@ func (b *Shell) IsBeforeSetupEmpty(ctx context.Context) bool {
}
func (b *Shell) IsSetupEmpty(ctx context.Context) bool { return b.isEmptyStage(ctx, "Setup") }

func (b *Shell) BeforeInstall(_ context.Context, container Container) error {
return b.stage("BeforeInstall", container)
func (b *Shell) BeforeInstall(_ context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(cr, stageBuilder, "BeforeInstall")
}

func (b *Shell) Install(_ context.Context, container Container) error {
return b.stage("Install", container)
func (b *Shell) Install(_ context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(cr, stageBuilder, "Install")
}

func (b *Shell) BeforeSetup(_ context.Context, container Container) error {
return b.stage("BeforeSetup", container)
func (b *Shell) BeforeSetup(_ context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(cr, stageBuilder, "BeforeSetup")
}

func (b *Shell) Setup(_ context.Context, container Container) error {
return b.stage("Setup", container)
func (b *Shell) Setup(_ context.Context, cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface) error {
return b.stage(cr, stageBuilder, "Setup")
}

func (b *Shell) BeforeInstallChecksum(ctx context.Context) string {
Expand All @@ -64,25 +65,33 @@ func (b *Shell) isEmptyStage(ctx context.Context, userStageName string) bool {
return b.stageChecksum(ctx, userStageName) == ""
}

func (b *Shell) stage(userStageName string, container Container) error {
stageHostTmpDir, err := b.stageHostTmpDir(userStageName)
if err != nil {
return err
}
func (b *Shell) stage(cr container_runtime.ContainerRuntime, stageBuilder StageBuilderAccessorInterface, userStageName string) error {
if cr.HasContainerRootMountSupport() {
// TODO(stapel-to-buildah)
panic("not implemented")
} else {
container := stageBuilder.LegacyStapelStageBuilder().BuilderContainer()

container.AddVolume(
fmt.Sprintf("%s:%s:rw", stageHostTmpDir, b.containerTmpDir()),
)
stageHostTmpDir, err := b.stageHostTmpDir(userStageName)
if err != nil {
return err
}

stageHostTmpScriptFilePath := filepath.Join(stageHostTmpDir, scriptFileName)
containerTmpScriptFilePath := path.Join(b.containerTmpDir(), scriptFileName)
container.AddVolume(
fmt.Sprintf("%s:%s:rw", stageHostTmpDir, b.containerTmpDir()),
)

if err := stapel.CreateScript(stageHostTmpScriptFilePath, b.stageCommands(userStageName)); err != nil {
return err
}
stageHostTmpScriptFilePath := filepath.Join(stageHostTmpDir, scriptFileName)
containerTmpScriptFilePath := path.Join(b.containerTmpDir(), scriptFileName)

container.AddServiceRunCommands(containerTmpScriptFilePath)
return nil
if err := stapel.CreateScript(stageHostTmpScriptFilePath, b.stageCommands(userStageName)); err != nil {
return err
}

container.AddServiceRunCommands(containerTmpScriptFilePath)

return nil
}
}

func (b *Shell) stageChecksum(ctx context.Context, userStageName string) string {
Expand Down
24 changes: 20 additions & 4 deletions pkg/build/builder/stage_builder.go
Expand Up @@ -41,25 +41,41 @@ func (accessor *StageBuilderAccessor) NativeDockerfileStageBuilder() NativeDocke
}

type StapelStageBuilderInterface interface {
AppendPrepareContainerAction(action PrepareContainerAction)
// FIXME(stapel-to-buildah) more needed methods
AppendPrepareContainerAction(action PrepareContainerAction) StapelStageBuilderInterface
AddLabels(map[string]string) StapelStageBuilderInterface
AddContainerVolumes(volumes ...string) StapelStageBuilderInterface
}

type PrepareContainerAction interface {
PrepareContainer(containerRoot string) error
}

// FIXME(stapel-to-buildah): full builder imlementation
type stapelStageBuilder struct {
ContainerRuntime container_runtime.ContainerRuntime

labels map[string]string
volumes []string
}

func NewStapelStageBuilder() *stapelStageBuilder {
return &stapelStageBuilder{}
}

func (builder *stapelStageBuilder) AppendPrepareContainerAction(action PrepareContainerAction) {
func (builder *stapelStageBuilder) AddLabels(labels map[string]string) StapelStageBuilderInterface {
for k, v := range labels {
builder.labels[k] = v
}
return builder
}

func (builder *stapelStageBuilder) AddContainerVolumes(volumes ...string) StapelStageBuilderInterface {
builder.volumes = append(builder.volumes, volumes...)
return builder
}

func (builder *stapelStageBuilder) AppendPrepareContainerAction(action PrepareContainerAction) StapelStageBuilderInterface {
panic("FIXME")
return builder
}

type NativeDockerfileStageBuilderInterface interface {
Expand Down
2 changes: 1 addition & 1 deletion pkg/build/conveyor.go
Expand Up @@ -399,7 +399,7 @@ func (c *Conveyor) checkContainerRuntimeSupported(_ context.Context) error {
}
}

if len(nonDockerfileImages) > 0 {
if len(nonDockerfileImages) > 0 && os.Getenv("WERF_BUILDAH_FOR_STAPEL_ENABLED") != "1" {
return fmt.Errorf(`Unable to build stapel type images and artifacts with buildah container runtime: %s
Please select only dockerfile images or delete all non-dockerfile images from your werf.yaml.
Expand Down
31 changes: 18 additions & 13 deletions pkg/build/stage/base.go
Expand Up @@ -238,27 +238,32 @@ func (s *BaseStage) SelectSuitableStage(_ context.Context, c Conveyor, stages []
return s.selectStageByOldestCreationTimestamp(stages)
}

func (s *BaseStage) PrepareImage(ctx context.Context, c Conveyor, prevBuiltImage, stageImage *StageImage) error {
func (s *BaseStage) PrepareImage(ctx context.Context, c Conveyor, cr container_runtime.ContainerRuntime, prevBuiltImage, stageImage *StageImage) error {
/*
* NOTE: BaseStage.PrepareImage does not called in From.PrepareImage.
* NOTE: Take into account when adding new base PrepareImage steps.
*/

stageImage.StageBuilderAccessor.LegacyStapelStageBuilder().Container().ServiceCommitChangeOptions().AddLabel(map[string]string{imagePkg.WerfProjectRepoCommitLabel: c.GiterminismManager().HeadCommit()})
if cr.HasContainerRootMountSupport() {
// TODO(stapel-to-buildah)
panic("not implemented")
} else {
stageImage.StageBuilderAccessor.LegacyStapelStageBuilder().Container().ServiceCommitChangeOptions().AddLabel(map[string]string{imagePkg.WerfProjectRepoCommitLabel: c.GiterminismManager().HeadCommit()})

serviceMounts := s.getServiceMounts(prevBuiltImage)
s.addServiceMountsLabels(serviceMounts, stageImage)
if err := s.addServiceMountsVolumes(serviceMounts, stageImage); err != nil {
return fmt.Errorf("error adding mounts volumes: %s", err)
}
serviceMounts := s.getServiceMounts(prevBuiltImage)
s.addServiceMountsLabels(serviceMounts, stageImage)
if err := s.addServiceMountsVolumes(serviceMounts, stageImage); err != nil {
return fmt.Errorf("error adding mounts volumes: %s", err)
}

customMounts := s.getCustomMounts(prevBuiltImage)
s.addCustomMountLabels(customMounts, stageImage)
if err := s.addCustomMountVolumes(customMounts, stageImage); err != nil {
return fmt.Errorf("error adding mounts volumes: %s", err)
}
customMounts := s.getCustomMounts(prevBuiltImage)
s.addCustomMountLabels(customMounts, stageImage)
if err := s.addCustomMountVolumes(customMounts, stageImage); err != nil {
return fmt.Errorf("error adding mounts volumes: %s", err)
}

return nil
return nil
}
}

func (s *BaseStage) PreRunHook(_ context.Context, _ Conveyor) error {
Expand Down
7 changes: 4 additions & 3 deletions pkg/build/stage/before_install.go
Expand Up @@ -5,6 +5,7 @@ import (

"github.com/werf/werf/pkg/build/builder"
"github.com/werf/werf/pkg/config"
"github.com/werf/werf/pkg/container_runtime"
)

func GenerateBeforeInstallStage(ctx context.Context, imageBaseConfig *config.StapelImageBase, baseStageOptions *NewBaseStageOptions) *BeforeInstallStage {
Expand All @@ -30,12 +31,12 @@ func (s *BeforeInstallStage) GetDependencies(ctx context.Context, _ Conveyor, _,
return s.builder.BeforeInstallChecksum(ctx), nil
}

func (s *BeforeInstallStage) PrepareImage(ctx context.Context, c Conveyor, prevBuiltImage, stageImage *StageImage) error {
if err := s.BaseStage.PrepareImage(ctx, c, prevBuiltImage, stageImage); err != nil {
func (s *BeforeInstallStage) PrepareImage(ctx context.Context, c Conveyor, cr container_runtime.ContainerRuntime, prevBuiltImage, stageImage *StageImage) error {
if err := s.BaseStage.PrepareImage(ctx, c, cr, prevBuiltImage, stageImage); err != nil {
return err
}

if err := s.builder.BeforeInstall(ctx, stageImage.StageBuilderAccessor.LegacyStapelStageBuilder().BuilderContainer()); err != nil {
if err := s.builder.BeforeInstall(ctx, cr, stageImage.StageBuilderAccessor); err != nil {
return err
}

Expand Down

0 comments on commit 5291c2f

Please sign in to comment.