Skip to content

Commit

Permalink
feat(build): add ability to regulate the final property of an image
Browse files Browse the repository at this point in the history
Signed-off-by: Aleksei Igrychev <aleksei.igrychev@palark.com>
  • Loading branch information
alexey-igrychev committed Jul 9, 2024
1 parent 199afde commit 62ecb42
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 5 deletions.
11 changes: 11 additions & 0 deletions docs/_data/werf_yaml.yml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,16 @@ sections:
en: One or more unique names for image
ru: Одно или несколько уникальных имён для образа
required: true
- &dockerfile-image-section-final
name: final
value: bool
default: true
description:
en: "Mark image as final"
ru: "Пометить образ как финальный"
detailsArticle:
en: "/usage/build/images.html#using-intermediate-and-final-images"
ru: "/usage/build/images.html#использование-промежуточных-и-конечных-образов"
- name: dockerfile
value: "string"
description:
Expand Down Expand Up @@ -289,6 +299,7 @@ sections:
ru: Уникальное имя артефакта
detailsArticle:
all: "/usage/build/stapel/imports.html"
- << : *dockerfile-image-section-final
- name: platform
description:
en: List of target platforms for this image (for example ['linux/amd64', 'linux/arm64', 'linux/arm/v8'])
Expand Down
29 changes: 29 additions & 0 deletions docs/pages_en/usage/build/images.md
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,35 @@ dependencies:

During the build, werf will automatically insert the appropriate names and identifiers into the referenced build-arguments. werf will take care of all orchestration and dependency mapping and then build everything in one step (as part of the `werf build` command).

### Using intermediate and final images

By default, all images are final, allowing the user to operate with them using their names as arguments for most werf commands and in Helm chart templates. The `final` directive can be used to regulate this property of an image.

Intermediate images (`final: false`), unlike final images:
- Do not appear [in the service values for the Helm chart]({{ "usage/deploy/values.html#information-about-the-built-images-werf-only" | true_relative_url }}).
- Are not tagged with arbitrary tags ([more about --add-custom-tag]({{ "usage/build/process.html#adding-custom-tags" | true_relative_url }})).
- Are not published to the final repository ([more about --final-repo]({{ "usage/build/process.html#extra-repository-for-final-images" | true_relative_url }})).
- Are not exported ([more about werf export]({{ "reference/cli/werf_export.html" | true_relative_url }})).

Example of using the `final` directive:

```yaml
project: example
configVersion: 1
---
image: builder
final: false
dockerfile: Dockerfile.builder
---
image: app
dockerfile: Dockerfile.app
dependencies:
- image: builder
imports:
- type: ImageName
targetBuildArg: BUILDER_IMAGE_NAME
```

## Multi-platform and cross-platform building

werf can build images for either the native host platform in which it is running, or for arbitrary platform in cross-platform mode using emulation. It is also possible to build images for multiple target platforms at once (i.e. manifest-list images).
Expand Down
33 changes: 31 additions & 2 deletions docs/pages_ru/usage/build/images.md
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,7 @@ project: example
configVersion: 1
---
image: builder
from: golang
from: golang:1.23rc1-alpine3.20
git:
- add: /
to: /app
Expand Down Expand Up @@ -368,7 +368,7 @@ ARG CONTROLPLANE_IMAGE_NAME
ARG CONTROLPLANE_IMAGE_DIGEST

RUN echo AUTH_IMAGE_NAME=${AUTH_IMAGE_NAME} >> modules_images.env
RUN echo AUTH_IMAGE_DIGEST=${AUTH_IMAGE_DIGEST} >> modules_images.env
RUN echo AUTH_IMAGE_DIGEST=${AUTH_IMAGE_DIGEST} >> modules_images.env
RUN echo CONTROLPLANE_IMAGE_NAME=${CONTROLPLANE_IMAGE_NAME} >> modules_images.env
RUN echo CONTROLPLANE_IMAGE_DIGEST=${CONTROLPLANE_IMAGE_DIGEST} >> modules_images.env
```
Expand Down Expand Up @@ -405,6 +405,35 @@ dependencies:

В процессе сборки werf автоматически подставит в указанные build-arguments соответствующие имена и идентификаторы. Всю оркестрацию и выстраивание зависимостей werf возьмёт на себя и произведёт сборку за один шаг (вызов `werf build`).

## Использование промежуточных и конечных образов

По умолчанию все образы являются конечными, что позволяет пользователю оперировать ими, используя их имена в качестве аргументов для большинства команд werf, а также в шаблонах Helm-чарта. С помощью директивы `final` можно регулировать это свойство образа.

Промежуточные образы (`final: false`) в отличие от конечных:
- не попадают [в служебные values для Helm-чарта]({{ "usage/deploy/values.html#информация-о-собранных-образах-только-в-werf" | true_relative_url }}).
- не тегируются произвольными тегами ([подробнее про --add-custom-tag]({{ "usage/build/process.html#добавление-произвольных-тегов" | true_relative_url }}));
- не публикуются в финальный репозиторий ([подробнее про --final-repo]({{ "usage/build/process.html#дополнительный-репозиторий-для-конечных-образов" | true_relative_url }}));
- не экспортируются ([подробнее про werf export]({{ "reference/cli/werf_export.html" | true_relative_url }})).

Пример использования директивы `final`:

```yaml
project: example
configVersion: 1
---
image: builder
final: false
dockerfile: Dockerfile.builder
---
image: app
dockerfile: Dockerfile.app
dependencies:
- image: builder
imports:
- type: ImageName
targetBuildArg: BUILDER_IMAGE_NAME
```

## Мультиплатформенная и кроссплатформенная сборка

werf позволяет собирать образы как для родной архитектуры хоста, где запущен werf, так и в кроссплатформенном режиме с помощью эмуляции целевой архитектуры, которая может быть отлична от архитектуры хоста. Также werf позволяет собрать образ сразу для множества целевых платформ.
Expand Down
2 changes: 1 addition & 1 deletion pkg/build/image/image_tree.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ func (tree *ImagesTree) Calculate(ctx context.Context) error {
commonImageOpts.ForceTargetPlatformLogging = (len(targetPlatforms) > 1)

for _, targetPlatform := range targetPlatforms {
imageLogName := logging.ImageLogProcessName(imageConfigI.GetName(), imageConfigI.IsFinal(), targetPlatform)
imageLogName := logging.ImageLogProcessName(imageConfigI.GetName(), imageConfigI.IsFinal(), targetPlatform)
style := ImageLogProcessStyle(imageConfigI.IsFinal())
err := logboek.Context(ctx).Info().LogProcess(imageLogName).
Options(func(options types.LogProcessOptionsInterface) {
Expand Down
3 changes: 2 additions & 1 deletion pkg/config/image_from_dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type ImageFromDockerfile struct {
Staged bool

platform []string
final bool
raw *rawImageFromDockerfile
}

Expand Down Expand Up @@ -63,7 +64,7 @@ func (c *ImageFromDockerfile) IsStapel() bool {
}

func (c *ImageFromDockerfile) IsFinal() bool {
return true
return c.final
}

func (c *ImageFromDockerfile) Platform() []string {
Expand Down
10 changes: 10 additions & 0 deletions pkg/config/raw_image_from_dockerfile.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

type rawImageFromDockerfile struct {
Images []string `yaml:"-"`
Final *bool `yaml:"final,omitempty"`
Dockerfile string `yaml:"dockerfile,omitempty"`
Context string `yaml:"context,omitempty"`
ContextAddFile interface{} `yaml:"contextAddFile,omitempty"`
Expand Down Expand Up @@ -89,6 +90,15 @@ func (c *rawImageFromDockerfile) toImageFromDockerfileDirective(giterminismManag
image.Dockerfile = c.Dockerfile
image.Context = c.Context

// Set final.
{
final := true
if c.Final != nil {
final = *c.Final
}
image.final = final
}

contextAddFile, err := InterfaceToStringArray(c.ContextAddFile, nil, c.doc)
if err != nil {
return nil, err
Expand Down
13 changes: 12 additions & 1 deletion pkg/config/raw_stapel_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

type rawStapelImage struct {
Images []string `yaml:"-"`
Final *bool `yaml:"final,omitempty"`
Artifact string `yaml:"artifact,omitempty"`
From string `yaml:"from,omitempty"`
FromLatest bool `yaml:"fromLatest,omitempty"`
Expand Down Expand Up @@ -135,7 +136,15 @@ func (c *rawStapelImage) toStapelImageDirective(giterminismManager giterminism_m
} else {
image.StapelImageBase = imageBase
}
image.StapelImageBase.final = true

// Set final.
{
final := true
if c.Final != nil {
final = *c.Final
}
image.StapelImageBase.final = final
}

if c.RawDocker != nil {
if docker, err := c.RawDocker.toDirective(); err != nil {
Expand Down Expand Up @@ -199,6 +208,8 @@ func (c *rawStapelImage) toAnsibleWithTaskByStage(task *AnsibleTask, stage strin
func (c *rawStapelImage) validateStapelImageArtifactDirective(imageArtifact *StapelImageArtifact) (err error) {
if c.RawDocker != nil {
return newDetailedConfigError("`docker` section is not supported for artifact!", nil, c.doc)
} else if c.Final != nil {
return newDetailedConfigError("`final` directive is not supported for artifact!", nil, c.doc)
}

if err := imageArtifact.validate(); err != nil {
Expand Down

0 comments on commit 62ecb42

Please sign in to comment.