diff --git a/cmd/werf/build/main.go b/cmd/werf/build/main.go index afe31932f5..6b69f8ea70 100644 --- a/cmd/werf/build/main.go +++ b/cmd/werf/build/main.go @@ -117,6 +117,7 @@ func NewCmd(ctx context.Context) *cobra.Command { common.SetupProjectName(&commonCmdData, cmd, false) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupSkipImageSpecStage(cmd) commonCmdData.SetupDebugTemplates(cmd) diff --git a/cmd/werf/bundle/publish/publish.go b/cmd/werf/bundle/publish/publish.go index a610010c63..ca07a22981 100644 --- a/cmd/werf/bundle/publish/publish.go +++ b/cmd/werf/bundle/publish/publish.go @@ -134,6 +134,7 @@ func NewCmd(ctx context.Context) *cobra.Command { common.SetupRequireBuiltImages(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupSkipImageSpecStage(cmd) commonCmdData.SetupDebugTemplates(cmd) diff --git a/cmd/werf/common/cmd_data.go b/cmd/werf/common/cmd_data.go index f7cd255052..57459cb3d1 100644 --- a/cmd/werf/common/cmd_data.go +++ b/cmd/werf/common/cmd_data.go @@ -53,6 +53,7 @@ type CmdData struct { UseCustomTag *string Synchronization *string + BackendNetwork *string Parallel *bool ParallelTasksLimit *int64 @@ -246,6 +247,15 @@ func (cmdData *CmdData) SetupAllowIncludesUpdate(cmd *cobra.Command) { cmd.Flags().BoolVarP(&cmdData.AllowIncludesUpdate, "allow-includes-update", "", util.GetBoolEnvironmentDefaultFalse("WERF_ALLOW_INCLUDES_UPDATE"), `Allow use includes latest versions (default $WERF_ALLOW_INCLUDES_UPDATE or false)`) } +func (cmdData *CmdData) SetupBackendNetwork(cmd *cobra.Command) { + cmdData.BackendNetwork = new(string) + cmd.Flags().StringVarP(cmdData.BackendNetwork, "backend-network", "", os.Getenv("WERF_BACKEND_NETWORK"), "Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default)") +} + +func (cmdData *CmdData) GetBackendNetwork() string { + return option.PtrValueOrDefault(cmdData.BackendNetwork, "") +} + func (cmdData *CmdData) SetupIncludesLsFilter(cmd *cobra.Command) { cmdData.IncludesLsFilter = new(string) cmd.Flags().StringVar(cmdData.IncludesLsFilter, "filter", os.Getenv("WERF_INCLUDES_LIST_FILTER"), "Filter by source, e.g. --filter=source=local,remoteRepo (default $WERF_INCLUDES_LIST_FILTER or all sources).") diff --git a/cmd/werf/common/conveyor_options.go b/cmd/werf/common/conveyor_options.go index 0f3c65346e..7179749244 100644 --- a/cmd/werf/common/conveyor_options.go +++ b/cmd/werf/common/conveyor_options.go @@ -150,6 +150,7 @@ func GetBuildOptions(ctx context.Context, commonCmdData *CmdData, werfConfig *co ImageBuildOptions: container_backend.BuildOptions{ IntrospectAfterError: GetIntrospectAfterError(commonCmdData), IntrospectBeforeError: GetIntrospectBeforeError(commonCmdData), + Network: commonCmdData.GetBackendNetwork(), }, IntrospectOptions: introspectOptions, ManifestSigningOptions: manifestSigningOptions, diff --git a/cmd/werf/compose/main.go b/cmd/werf/compose/main.go index bd847a1b30..b415bd7c03 100644 --- a/cmd/werf/compose/main.go +++ b/cmd/werf/compose/main.go @@ -340,6 +340,7 @@ func newCmd(ctx context.Context, composeCmdName string, options *newCmdOptions) common.SetupProjectName(&commonCmdData, cmd, false) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupDebugTemplates(cmd) cmd.Flags().StringVarP(&cmdData.RawComposeOptions, "docker-compose-options", "", os.Getenv("WERF_DOCKER_COMPOSE_OPTIONS"), "Define docker-compose options (default $WERF_DOCKER_COMPOSE_OPTIONS)") @@ -502,7 +503,12 @@ func run(ctx context.Context, containerBackend container_backend.ContainerBacken return err } } else { - if _, err := c.Build(ctx, build.BuildOptions{SkipImageMetadataPublication: *commonCmdData.Dev}); err != nil { + buildOptions, err := common.GetBuildOptions(ctx, &commonCmdData, werfConfig, imagesToProcess) + if err != nil { + return err + } + + if _, err := c.Build(ctx, buildOptions); err != nil { return err } } diff --git a/cmd/werf/converge/converge.go b/cmd/werf/converge/converge.go index b02186e345..790cdf12af 100644 --- a/cmd/werf/converge/converge.go +++ b/cmd/werf/converge/converge.go @@ -139,6 +139,7 @@ werf converge --repo registry.mydomain.com/web --env production`, common.SetupParallelOptions(&commonCmdData, cmd, common.DefaultBuildParallelTasksLimit) common.SetupRequireBuiltImages(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) common.SetupFollow(&commonCmdData, cmd) common.SetupDisableAutoHostCleanup(&commonCmdData, cmd) diff --git a/cmd/werf/export/export.go b/cmd/werf/export/export.go index f1098fd2c5..8e31d939ac 100644 --- a/cmd/werf/export/export.go +++ b/cmd/werf/export/export.go @@ -130,6 +130,7 @@ func NewExportCmd(ctx context.Context) *cobra.Command { common.SetupVirtualMerge(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupDebugTemplates(cmd) commonCmdData.SetupFinalImagesOnly(cmd, true) commonCmdData.SetupAllowIncludesUpdate(cmd) @@ -261,7 +262,7 @@ func run(ctx context.Context, imageNameListFromArgs, tagTemplateList []string, e return err } } else { - if _, err := c.Build(ctx, build.BuildOptions{SkipImageMetadataPublication: *commonCmdData.Dev}); err != nil { + if _, err := c.Build(ctx, buildOptions); err != nil { return err } } diff --git a/cmd/werf/helm/get_autogenerated_values.go b/cmd/werf/helm/get_autogenerated_values.go index 530bb01492..0459339d07 100644 --- a/cmd/werf/helm/get_autogenerated_values.go +++ b/cmd/werf/helm/get_autogenerated_values.go @@ -108,6 +108,7 @@ func NewGetAutogeneratedValuesCmd(ctx context.Context) *cobra.Command { common.SetupRequireBuiltImages(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupSkipImageSpecStage(cmd) commonCmdData.SetupDebugTemplates(cmd) diff --git a/cmd/werf/kube_run/kube_run.go b/cmd/werf/kube_run/kube_run.go index ec9ad78a1a..89aba15cd2 100644 --- a/cmd/werf/kube_run/kube_run.go +++ b/cmd/werf/kube_run/kube_run.go @@ -193,6 +193,7 @@ func NewCmd(ctx context.Context) *cobra.Command { common.SetupVirtualMerge(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) cmd.Flags().StringVarP(&cmdData.Pod, "pod", "", os.Getenv("WERF_POD"), "Set created pod name (default $WERF_POD or autogenerated if not specified)") cmd.Flags().StringVarP(&cmdData.Overrides, "overrides", "", os.Getenv("WERF_OVERRIDES"), "Inline JSON to override/extend any fields in created Pod, e.g. to add imagePullSecrets field (default $WERF_OVERRIDES). %pod_name%, %container_name%, and %container_image% will be replaced with the names of the created pod, container, and container image, respectively.") @@ -384,12 +385,17 @@ func run(ctx context.Context, pod, secret, namespace string, werfConfig *config. return fmt.Errorf("unable to get full name for image %q: %w", imageName, err) } } else { + buildOptions, err := common.GetBuildOptions(ctx, &commonCmdData, werfConfig, imagesToProcess) + if err != nil { + return err + } + if common.GetRequireBuiltImages(&commonCmdData) { if _, err := c.ShouldBeBuilt(ctx, build.ShouldBeBuiltOptions{}); err != nil { return err } } else { - if _, err := c.Build(ctx, build.BuildOptions{}); err != nil { + if _, err := c.Build(ctx, buildOptions); err != nil { return err } } diff --git a/cmd/werf/lint/lint.go b/cmd/werf/lint/lint.go index 60b40cef4d..4a3129f7a8 100644 --- a/cmd/werf/lint/lint.go +++ b/cmd/werf/lint/lint.go @@ -113,6 +113,7 @@ func NewCmd(ctx context.Context) *cobra.Command { common.SetupRequireBuiltImages(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupSkipImageSpecStage(cmd) commonCmdData.SetupDebugTemplates(cmd) diff --git a/cmd/werf/plan/plan.go b/cmd/werf/plan/plan.go index f3567cb65b..de72c0dc56 100644 --- a/cmd/werf/plan/plan.go +++ b/cmd/werf/plan/plan.go @@ -143,6 +143,7 @@ werf plan --repo registry.mydomain.com/web --env production`, common.SetupParallelOptions(&commonCmdData, cmd, common.DefaultBuildParallelTasksLimit) common.SetupRequireBuiltImages(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) common.SetupFollow(&commonCmdData, cmd) common.SetupAnnotateLayersWithDmVerityRootHash(&commonCmdData, cmd) diff --git a/cmd/werf/render/render.go b/cmd/werf/render/render.go index 1d8589677b..a34884b12a 100644 --- a/cmd/werf/render/render.go +++ b/cmd/werf/render/render.go @@ -124,6 +124,7 @@ func NewCmd(ctx context.Context) *cobra.Command { common.SetupELFSigningOptions(&commonCmdData, cmd) common.SetupRequireBuiltImages(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) commonCmdData.SetupSkipImageSpecStage(cmd) commonCmdData.SetupDebugTemplates(cmd) diff --git a/cmd/werf/run/run.go b/cmd/werf/run/run.go index bc259bce60..dd671188c8 100644 --- a/cmd/werf/run/run.go +++ b/cmd/werf/run/run.go @@ -161,6 +161,7 @@ func NewCmd(ctx context.Context) *cobra.Command { common.SetupVirtualMerge(&commonCmdData, cmd) commonCmdData.SetupPlatform(cmd) + commonCmdData.SetupBackendNetwork(cmd) cmd.Flags().BoolVarP(&cmdData.Shell, "shell", "", false, "Use predefined docker options and command for debug") cmd.Flags().BoolVarP(&cmdData.Bash, "bash", "", false, "Use predefined docker options and command for debug") @@ -387,7 +388,12 @@ func run(ctx context.Context, containerBackend container_backend.ContainerBacken return err } } else { - if _, err := c.Build(ctx, build.BuildOptions{SkipImageMetadataPublication: *commonCmdData.Dev}); err != nil { + buildOptions, err := common.GetBuildOptions(ctx, &commonCmdData, werfConfig, imagesToProcess) + if err != nil { + return err + } + + if _, err := c.Build(ctx, buildOptions); err != nil { return err } } diff --git a/docs/_includes/reference/cli/werf_build.md b/docs/_includes/reference/cli/werf_build.md index 401f1dfc2d..8cef2d4079 100644 --- a/docs/_includes/reference/cli/werf_build.md +++ b/docs/_includes/reference/cli/werf_build.md @@ -72,6 +72,8 @@ werf build [IMAGE_NAME...] [options] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_bundle_publish.md b/docs/_includes/reference/cli/werf_bundle_publish.md index 3a7bebac52..af9f6ecd13 100644 --- a/docs/_includes/reference/cli/werf_bundle_publish.md +++ b/docs/_includes/reference/cli/werf_bundle_publish.md @@ -59,6 +59,8 @@ werf bundle publish [IMAGE_NAME...] [options] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_compose_config.md b/docs/_includes/reference/cli/werf_compose_config.md index 99ce475b49..daced52fd6 100644 --- a/docs/_includes/reference/cli/werf_compose_config.md +++ b/docs/_includes/reference/cli/werf_compose_config.md @@ -91,6 +91,8 @@ werf compose config [IMAGE_NAME...] [options] [--docker-compose-options="OPTIONS --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_compose_down.md b/docs/_includes/reference/cli/werf_compose_down.md index 75f992d0a7..5137928928 100644 --- a/docs/_includes/reference/cli/werf_compose_down.md +++ b/docs/_includes/reference/cli/werf_compose_down.md @@ -84,6 +84,8 @@ werf compose down [IMAGE_NAME...] [options] [--docker-compose-options="OPTIONS"] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_compose_run.md b/docs/_includes/reference/cli/werf_compose_run.md index 40ded3fc78..2db853a347 100644 --- a/docs/_includes/reference/cli/werf_compose_run.md +++ b/docs/_includes/reference/cli/werf_compose_run.md @@ -81,6 +81,8 @@ werf compose run [IMAGE_NAME...] [options] [--docker-compose-options="OPTIONS"] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_compose_up.md b/docs/_includes/reference/cli/werf_compose_up.md index 04deda046c..832ab8cd60 100644 --- a/docs/_includes/reference/cli/werf_compose_up.md +++ b/docs/_includes/reference/cli/werf_compose_up.md @@ -87,6 +87,8 @@ werf compose up [IMAGE_NAME...] [options] [--docker-compose-options="OPTIONS"] [ --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_converge.md b/docs/_includes/reference/cli/werf_converge.md index 31cfee9980..4ba5734c9f 100644 --- a/docs/_includes/reference/cli/werf_converge.md +++ b/docs/_includes/reference/cli/werf_converge.md @@ -88,6 +88,8 @@ werf converge --repo registry.mydomain.com/web --env production -R, --auto-rollback=false Enable auto rollback of the failed release to the previous deployed release version when current deploy process have failed ($WERF_AUTO_ROLLBACK by default) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_export.md b/docs/_includes/reference/cli/werf_export.md index daaac9e6bb..51defaccd7 100644 --- a/docs/_includes/reference/cli/werf_export.md +++ b/docs/_includes/reference/cli/werf_export.md @@ -50,6 +50,8 @@ werf export [IMAGE_NAME...] [options] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --bsign-elf-files=false Enable ELF files signing with bsign (default $WERF_BSIGN_ELF_FILES). When enabled, the private elf key must be specified with --elf-pgp-private-key-base64 diff --git a/docs/_includes/reference/cli/werf_helm_get_autogenerated_values.md b/docs/_includes/reference/cli/werf_helm_get_autogenerated_values.md index 59e7495ca8..63259c61de 100644 --- a/docs/_includes/reference/cli/werf_helm_get_autogenerated_values.md +++ b/docs/_includes/reference/cli/werf_helm_get_autogenerated_values.md @@ -29,6 +29,8 @@ werf helm get-autogenerated-values [IMAGE_NAME...] [options] ```shell --allow-includes-update=false Allow use includes latest versions (default $WERF_ALLOW_INCLUDES_UPDATE or false) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --build-report-path="" Change build report path and format (by default $WERF_BUILD_REPORT_PATH or ".werf-build-report.json" if not set). Extension must be either .json for JSON format diff --git a/docs/_includes/reference/cli/werf_kube_run.md b/docs/_includes/reference/cli/werf_kube_run.md index 7c843aeb9b..266bb03e32 100644 --- a/docs/_includes/reference/cli/werf_kube_run.md +++ b/docs/_includes/reference/cli/werf_kube_run.md @@ -48,6 +48,8 @@ werf kube-run [options] [IMAGE_NAME] [-- COMMAND ARG...] Automatically create docker config secret in the namespace and plug it via pod`s imagePullSecrets for private registry access (default $WERF_AUTO_PULL_SECRET or true if not specified) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --bsign-elf-files=false Enable ELF files signing with bsign (default $WERF_BSIGN_ELF_FILES). When enabled, the private elf key must be specified with --elf-pgp-private-key-base64 diff --git a/docs/_includes/reference/cli/werf_lint.md b/docs/_includes/reference/cli/werf_lint.md index 32319cc136..3aa98976cb 100644 --- a/docs/_includes/reference/cli/werf_lint.md +++ b/docs/_includes/reference/cli/werf_lint.md @@ -39,6 +39,8 @@ werf lint [IMAGE_NAME...] [options] $WERF_ADD_LABEL_1=labelName1=labelValue1, $WERF_ADD_LABEL_2=labelName2=labelValue2) --allow-includes-update=false Allow use includes latest versions (default $WERF_ALLOW_INCLUDES_UPDATE or false) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --build-report-path="" Change build report path and format (by default $WERF_BUILD_REPORT_PATH or ".werf-build-report.json" if not set). Extension must be either .json for JSON format diff --git a/docs/_includes/reference/cli/werf_plan.md b/docs/_includes/reference/cli/werf_plan.md index ad0b2cd5b7..c8842149d5 100644 --- a/docs/_includes/reference/cli/werf_plan.md +++ b/docs/_includes/reference/cli/werf_plan.md @@ -80,6 +80,8 @@ werf plan --repo registry.mydomain.com/web --env production --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --backend-storage-path="" Use specified path to the local backend (Docker or Buildah) storage to check backend storage volume usage while performing garbage collection of local backend images diff --git a/docs/_includes/reference/cli/werf_render.md b/docs/_includes/reference/cli/werf_render.md index 6719783c5f..d85e66ed70 100644 --- a/docs/_includes/reference/cli/werf_render.md +++ b/docs/_includes/reference/cli/werf_render.md @@ -42,6 +42,8 @@ werf render [IMAGE_NAME...] [options] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --bsign-elf-files=false Enable ELF files signing with bsign (default $WERF_BSIGN_ELF_FILES). When enabled, the private elf key must be specified with --elf-pgp-private-key-base64 diff --git a/docs/_includes/reference/cli/werf_run.md b/docs/_includes/reference/cli/werf_run.md index cc9fc0fdca..a865fa30d8 100644 --- a/docs/_includes/reference/cli/werf_run.md +++ b/docs/_includes/reference/cli/werf_run.md @@ -36,6 +36,8 @@ werf run [options] [IMAGE_NAME] [-- COMMAND ARG...] --annotate-layers-with-dm-verity-root-hash=false Enable annotation of image layers with dm-verity root hash (default $WERF_ANNOTATE_LAYERS_WITH_DM_VERITY_ROOT_HASH) + --backend-network="" + Network mode for the build containers ($WERF_BACKEND_NETWORK or nothing by default) --bash=false Use predefined docker options and command for debug --bsign-elf-files=false diff --git a/docs/pages_en/usage/build/process.md b/docs/pages_en/usage/build/process.md index 60e01b7991..bd8d6d1e62 100644 --- a/docs/pages_en/usage/build/process.md +++ b/docs/pages_en/usage/build/process.md @@ -237,6 +237,39 @@ In this case, werf will compose the following sets to build: └ Concurrent builds plan (no more than 5 images at the same time) ``` +## Network isolation + +werf supports configuring the networking mode for the build containers. This allows you to restrict network access during the build process, which can be useful for security or reproducibility. + +Network isolation is currently supported only when using the **Docker** container backend. It works for both **Dockerfile** and **Stapel** image syntaxes. + +### Configuration + +You can specify the network mode in the `werf.yaml` configuration for each image using the `network` parameter: + +```yaml +project: my-project +configVersion: 1 +--- +image: backend +dockerfile: Dockerfile +network: none # network is disabled during the build +--- +image: frontend +from: alpine:3.14 +network: host # use host's network +``` + +### CLI option + +You can also set the network mode globally for the build process using the `--backend-network` CLI option: + +```bash +werf build --backend-network none +``` + +The `--backend-network` CLI option has **priority** over the `network` parameter defined in the `werf.yaml` configuration. + ## Using the SSH agent werf allows using the SSH agent for authentication when accessing remote Git repositories or executing commands in build containers. diff --git a/docs/pages_ru/usage/build/process.md b/docs/pages_ru/usage/build/process.md index 6bbb19240e..a73699e195 100644 --- a/docs/pages_ru/usage/build/process.md +++ b/docs/pages_ru/usage/build/process.md @@ -236,6 +236,39 @@ target: assets └ Concurrent builds plan (no more than 5 images at the same time) ``` +## Сетевая изоляция + +werf поддерживает настройку режима сети для сборочных контейнеров. Это позволяет ограничивать доступ к сети во время процесса сборки, что может быть полезно для безопасности или воспроизводимости. + +На текущий момент сетевая изоляция поддерживается только при использовании **Docker** в качестве сборочного бэкенда. Она работает как для **Dockerfile**, так и для **Stapel** синтаксисов. + +### Конфигурация + +Вы можете указать сетевой режим в конфигурации `werf.yaml` для каждого образа с помощью параметра `network`: + +```yaml +project: my-project +configVersion: 1 +--- +image: backend +dockerfile: Dockerfile +network: none # сеть отключена во время сборки +--- +image: frontend +from: alpine:3.14 +network: host # использовать сеть хоста +``` + +### Опция CLI + +Вы также можете установить сетевой режим глобально для процесса сборки с помощью опции CLI `--backend-network`: + +```bash +werf build --backend-network none +``` + +Опция CLI `--backend-network` имеет **приоритет** над параметром `network`, определенным в конфигурации `werf.yaml`. + ## Использование SSH-агента werf позволяет использовать SSH-агент для аутентификации при доступе к удалённым Git-репозиториям или выполнении команд в сборочных контейнерах. diff --git a/pkg/build/build_phase.go b/pkg/build/build_phase.go index 8d8fb30db1..76b68e9e0f 100644 --- a/pkg/build/build_phase.go +++ b/pkg/build/build_phase.go @@ -675,6 +675,18 @@ func (phase *BuildPhase) getPrevNonEmptyStageCreationTs() int64 { return 0 } +func (phase *BuildPhase) getLogImageNetwork(img *image.Image) string { + network := phase.ImageBuildOptions.Network + if network == "" { + if img.IsDockerfileImage && img.DockerfileImageConfig != nil { + network = img.DockerfileImageConfig.Network + } else if img.StapelImageConfig != nil { + network = img.StapelImageConfig.ImageBaseConfig().Network + } + } + return network +} + func (phase *BuildPhase) OnImageStage(ctx context.Context, img *image.Image, stg stage.Interface) error { return phase.StagesIterator.OnImageStage(ctx, img, stg, func(img *image.Image, stg stage.Interface, isEmpty bool) error { if isEmpty { @@ -727,7 +739,7 @@ func (phase *BuildPhase) onImageStage(ctx context.Context, img *image.Image, stg if foundSuitableStage { logboek.Context(ctx).Default().LogFHighlight("Use previously built image for %s\n", stg.LogDetailedName()) - container_backend.LogImageInfo(ctx, stg.GetStageImage().Image, phase.getPrevNonEmptyStageImageSize(), img.ShouldLogPlatform()) + container_backend.LogImageInfo(ctx, stg.GetStageImage().Image, phase.getPrevNonEmptyStageImageSize(), img.ShouldLogPlatform(), phase.getLogImageNetwork(img)) logboek.Context(ctx).LogOptionalLn() @@ -868,7 +880,7 @@ func (phase *BuildPhase) findAndFetchStageFromSecondaryStagesStorage(ctx context } logboek.Context(ctx).Default().LogFHighlight("Use previously built image for %s\n", stg.LogDetailedName()) - container_backend.LogImageInfo(ctx, stg.GetStageImage().Image, phase.getPrevNonEmptyStageImageSize(), img.ShouldLogPlatform()) + container_backend.LogImageInfo(ctx, stg.GetStageImage().Image, phase.getPrevNonEmptyStageImageSize(), img.ShouldLogPlatform(), phase.getLogImageNetwork(img)) return nil } @@ -1107,7 +1119,7 @@ func (phase *BuildPhase) buildStage(ctx context.Context, img *image.Image, stg s if err != nil { return } - container_backend.LogImageInfo(ctx, stg.GetStageImage().Image, phase.getPrevNonEmptyStageImageSize(), img.ShouldLogPlatform()) + container_backend.LogImageInfo(ctx, stg.GetStageImage().Image, phase.getPrevNonEmptyStageImageSize(), img.ShouldLogPlatform(), phase.getLogImageNetwork(img)) } if err := logboek.Context(ctx).Default().LogProcess("Building stage %s", stg.LogDetailedName()). diff --git a/pkg/build/conveyor.go b/pkg/build/conveyor.go index 837bad3194..c1462a96bd 100644 --- a/pkg/build/conveyor.go +++ b/pkg/build/conveyor.go @@ -688,6 +688,18 @@ func (c *Conveyor) printDeferredBuildLog(_ context.Context, buf *bytes.Buffer) { } func (c *Conveyor) Build(ctx context.Context, opts BuildOptions) ([]*ImagesReport, error) { + if opts.ImageBuildOptions.Network != "" { + if _, isBuildah := c.ContainerBackend.(*container_backend.BuildahBackend); isBuildah { + return nil, fmt.Errorf("--network option is not supported with Buildah backend") + } + + for _, i := range c.werfConfig.Images(false) { + if img, ok := i.(*config.ImageFromDockerfile); ok && img.Staged { + return nil, fmt.Errorf("staged Dockerfile build (staged: true) is not supported with --network option (use staged: false for %q image or remove --network option)", img.Name) + } + } + } + if err := c.checkContainerBackendSupported(ctx); err != nil { return nil, err } diff --git a/pkg/build/image/dockerfile.go b/pkg/build/image/dockerfile.go index 02ad43429d..2cbeb94e36 100644 --- a/pkg/build/image/dockerfile.go +++ b/pkg/build/image/dockerfile.go @@ -173,6 +173,7 @@ func mapDockerfileToImagesSets(ctx context.Context, cfg *dockerfile.Dockerfile, ImageTmpDir: img.TmpDir, ContainerWerfDir: img.ContainerWerfDir, ProjectName: opts.ProjectName, + Network: dockerfileImageConfig.Network, } var instrNum int @@ -337,6 +338,7 @@ func mapLegacyDockerfileToImage(ctx context.Context, metaConfig *config.Meta, do TargetPlatform: targetPlatform, ImageName: dockerfileImageConfig.Name, ProjectName: opts.ProjectName, + Network: dockerfileImageConfig.Network, } buildSecrets := make([]string, 0, len(dockerfileImageConfig.Secrets)) @@ -358,7 +360,6 @@ func mapLegacyDockerfileToImage(ctx context.Context, metaConfig *config.Meta, do dockerfileImageConfig.ContextAddFiles, dockerfileImageConfig.Args, dockerfileImageConfig.AddHost, - dockerfileImageConfig.Network, dockerfileImageConfig.SSH, buildSecrets, ), ds, stage.NewContextChecksum(dockerIgnorePathMatcher), baseStageOptions, dockerfileImageConfig.Dependencies, imageCacheVersion) diff --git a/pkg/build/image/image.go b/pkg/build/image/image.go index 7db7a50aa1..1f73c52d3b 100644 --- a/pkg/build/image/image.go +++ b/pkg/build/image/image.go @@ -52,6 +52,7 @@ type ImageOptions struct { CommonImageOptions IsFinal bool DockerfileImageConfig *config.ImageFromDockerfile + StapelImageConfig config.StapelImageInterface IsDockerfileImage bool BaseImageReference string @@ -79,6 +80,7 @@ func NewImage(ctx context.Context, targetPlatform, name string, baseImageType Ba IsFinal: opts.IsFinal, IsDockerfileImage: opts.IsDockerfileImage, DockerfileImageConfig: opts.DockerfileImageConfig, + StapelImageConfig: opts.StapelImageConfig, TargetPlatform: targetPlatform, baseImageType: baseImageType, @@ -106,6 +108,7 @@ type Image struct { IsDockerfileTargetStage bool Name string DockerfileImageConfig *config.ImageFromDockerfile + StapelImageConfig config.StapelImageInterface TargetPlatform string BuildDuration time.Duration diff --git a/pkg/build/image/stapel.go b/pkg/build/image/stapel.go index dcb28f34af..2934ee0dd2 100644 --- a/pkg/build/image/stapel.go +++ b/pkg/build/image/stapel.go @@ -33,6 +33,7 @@ func mapStapelConfigToImage(ctx context.Context, metaConfig *config.Meta, stapel IsFinal: stapelImageConfig.IsFinal(), UseCustomTag: useCustomTag, Sbom: stapelImageConfig.Sbom(), + StapelImageConfig: stapelImageConfig, } var baseImageType BaseImageType @@ -75,6 +76,7 @@ func initStages(ctx context.Context, image *Image, metaConfig *config.Meta, stap ImageTmpDir: filepath.Join(opts.TmpDir, "image", imageBaseConfig.Name), ContainerWerfDir: opts.ContainerWerfDir, ProjectName: opts.ProjectName, + Network: imageBaseConfig.Network, } gitArchiveStageOptions := &stage.NewGitArchiveStageOptions{ diff --git a/pkg/build/stage/base.go b/pkg/build/stage/base.go index 6cfff4c7ee..43ba7cb5ad 100644 --- a/pkg/build/stage/base.go +++ b/pkg/build/stage/base.go @@ -86,6 +86,7 @@ type BaseStageOptions struct { ImageTmpDir string ContainerWerfDir string ProjectName string + Network string } func NewBaseStage(name StageName, options *BaseStageOptions) *BaseStage { @@ -98,6 +99,7 @@ func NewBaseStage(name StageName, options *BaseStageOptions) *BaseStage { s.imageTmpDir = options.ImageTmpDir s.containerWerfDir = options.ContainerWerfDir s.projectName = options.ProjectName + s.network = options.Network s.meta = &StageMeta{} return s } @@ -115,6 +117,7 @@ type BaseStage struct { containerWerfDir string configMounts []*config.Mount projectName string + network string meta *StageMeta } @@ -318,6 +321,14 @@ func (s *BaseStage) PrepareImage(ctx context.Context, c Conveyor, cb container_b stageImage.Builder.StapelStageBuilder().AddLabels(addLabels) } + if s.network != "" { + if c.UseLegacyStapelBuilder(cb) { + stageImage.Builder.LegacyStapelStageBuilder().Container().RunOptions().AddNetwork(s.network) + } else { + stageImage.Builder.StapelStageBuilder().SetNetwork(s.network) + } + } + serviceMounts := s.getServiceMounts(prevBuiltImage) s.addServiceMountsLabels(serviceMounts, c, cb, stageImage) if err := s.addServiceMountsVolumes(serviceMounts, c, cb, stageImage, false); err != nil { diff --git a/pkg/build/stage/full_dockerfile.go b/pkg/build/stage/full_dockerfile.go index c84a86bc98..3d470e5956 100644 --- a/pkg/build/stage/full_dockerfile.go +++ b/pkg/build/stage/full_dockerfile.go @@ -61,7 +61,7 @@ type FullDockerfileStage struct { *BaseStage } -func NewDockerRunArgs(dockerfile []byte, dockerfilePath, target, context string, contextAddFiles []string, buildArgs map[string]interface{}, addHost []string, network, ssh string, secrets []string) *DockerRunArgs { +func NewDockerRunArgs(dockerfile []byte, dockerfilePath, target, context string, contextAddFiles []string, buildArgs map[string]interface{}, addHost []string, ssh string, secrets []string) *DockerRunArgs { return &DockerRunArgs{ dockerfile: dockerfile, dockerfilePath: dockerfilePath, @@ -70,7 +70,6 @@ func NewDockerRunArgs(dockerfile []byte, dockerfilePath, target, context string, contextAddFiles: contextAddFiles, buildArgs: buildArgs, addHost: addHost, - network: network, ssh: ssh, secrets: secrets, } @@ -84,7 +83,6 @@ type DockerRunArgs struct { contextAddFiles []string buildArgs map[string]interface{} addHost []string - network string ssh string secrets []string } @@ -649,8 +647,8 @@ func (s *FullDockerfileStage) SetupDockerImageBuilder(b stage_builder.Dockerfile b.AppendAddHost(s.addHost...) } - if s.network != "" { - b.SetNetwork(s.network) + if s.BaseStage.network != "" { + b.SetNetwork(s.BaseStage.network) } if s.ssh != "" { diff --git a/pkg/build/stage/full_dockerfile_test.go b/pkg/build/stage/full_dockerfile_test.go index 4ab04f1f4b..83c22e38fc 100644 --- a/pkg/build/stage/full_dockerfile_test.go +++ b/pkg/build/stage/full_dockerfile_test.go @@ -48,7 +48,6 @@ func newTestFullDockerfileStage(dockerfileData []byte, target string, buildArgs buildArgs, nil, "", - "", nil, ), ds, NewContextChecksum(nil), &BaseStageOptions{ ImageName: "example-image", diff --git a/pkg/config/raw_stapel_image.go b/pkg/config/raw_stapel_image.go index 6c5440aee2..773f460b87 100644 --- a/pkg/config/raw_stapel_image.go +++ b/pkg/config/raw_stapel_image.go @@ -27,6 +27,7 @@ type rawStapelImage struct { RawDependencies []*rawDependency `yaml:"dependencies,omitempty"` Platform []string `yaml:"platform,omitempty"` RawSbom *rawSbom `yaml:"sbom,omitempty"` + Network string `yaml:"network,omitempty"` RawSecrets []*rawSecret `yaml:"secrets,omitempty"` RawImageSpec *rawImageSpec `yaml:"imageSpec,omitempty"` @@ -245,6 +246,7 @@ func (c *rawStapelImage) toStapelImageBaseDirective(giterminismManager gitermini imageBase.cacheVersion = c.CacheVersion imageBase.platform = append([]string{}, c.Platform...) + imageBase.Network = c.Network for _, git := range c.RawGit { if git.gitType() == "local" { diff --git a/pkg/config/stapel_image_base.go b/pkg/config/stapel_image_base.go index e0be1882ac..8498ef5089 100644 --- a/pkg/config/stapel_image_base.go +++ b/pkg/config/stapel_image_base.go @@ -23,6 +23,7 @@ type StapelImageBase struct { Dependencies []*Dependency Secrets []Secret ImageSpec *ImageSpec + Network string FromExternal bool cacheVersion string diff --git a/pkg/container_backend/build_stapel_stage_options.go b/pkg/container_backend/build_stapel_stage_options.go index c3a48fde5a..37db67ec84 100644 --- a/pkg/container_backend/build_stapel_stage_options.go +++ b/pkg/container_backend/build_stapel_stage_options.go @@ -19,6 +19,7 @@ type BuildStapelStageOptionsInterface interface { SetUser(user string) BuildStapelStageOptionsInterface SetWorkdir(workdir string) BuildStapelStageOptionsInterface SetHealthcheck(healthcheck string) BuildStapelStageOptionsInterface + SetNetwork(network string) BuildStapelStageOptionsInterface AddBuildVolumes(volumes ...string) BuildStapelStageOptionsInterface AddCommands(commands ...string) BuildStapelStageOptionsInterface @@ -41,6 +42,7 @@ type BuildStapelStageOptions struct { User string Workdir string Healthcheck string + Network string BuildVolumes []string Commands []string @@ -144,6 +146,11 @@ func (opts *BuildStapelStageOptions) SetHealthcheck(healthcheck string) BuildSta return opts } +func (opts *BuildStapelStageOptions) SetNetwork(network string) BuildStapelStageOptionsInterface { + opts.Network = network + return opts +} + func (opts *BuildStapelStageOptions) AddBuildVolumes(volumes ...string) BuildStapelStageOptionsInterface { opts.BuildVolumes = append(opts.BuildVolumes, volumes...) return opts diff --git a/pkg/container_backend/interface.go b/pkg/container_backend/interface.go index 7818c08a3f..94f46fc669 100644 --- a/pkg/container_backend/interface.go +++ b/pkg/container_backend/interface.go @@ -57,6 +57,7 @@ type BuildDockerfileStageOptions struct { type BuildOptions struct { TargetPlatform string + Network string IntrospectBeforeError bool IntrospectAfterError bool } diff --git a/pkg/container_backend/legacy_interface.go b/pkg/container_backend/legacy_interface.go index d1e0432f53..66e568c492 100644 --- a/pkg/container_backend/legacy_interface.go +++ b/pkg/container_backend/legacy_interface.go @@ -83,4 +83,5 @@ type LegacyContainerOptions interface { AddUser(user string) AddEntrypoint(entrypoint string) AddHealthCheck(check string) + AddNetwork(network string) } diff --git a/pkg/container_backend/legacy_stage_image.go b/pkg/container_backend/legacy_stage_image.go index ebfc522802..4d64214f5c 100644 --- a/pkg/container_backend/legacy_stage_image.go +++ b/pkg/container_backend/legacy_stage_image.go @@ -70,6 +70,10 @@ func (i *LegacyStageImage) GetID() string { } func (i *LegacyStageImage) Build(ctx context.Context, options BuildOptions) error { + if options.Network != "" { + i.container.runOptions.AddNetwork(options.Network) + } + if i.GetTargetPlatform() == i.ContainerBackend.GetDefaultPlatform() && i.ContainerBackend.GetDefaultPlatform() != "linux/amd64" { logboek.Context(ctx).Error().LogF("Detected your default build platform as %s.\n", i.ContainerBackend.GetDefaultPlatform()) logboek.Context(ctx).Error().LogF("Building of stapel-type images using Docker-Server backend for platforms other than linux/amd64 is not supported.\n") diff --git a/pkg/container_backend/legacy_stage_image_container_options.go b/pkg/container_backend/legacy_stage_image_container_options.go index f1d4b64061..56d6a05be1 100644 --- a/pkg/container_backend/legacy_stage_image_container_options.go +++ b/pkg/container_backend/legacy_stage_image_container_options.go @@ -23,6 +23,7 @@ type LegacyStageImageContainerOptions struct { User string Entrypoint string HealthCheck string + Network string } func newLegacyStageContainerOptions() *LegacyStageImageContainerOptions { @@ -76,6 +77,10 @@ func (co *LegacyStageImageContainerOptions) AddEntrypoint(entrypoint string) { co.Entrypoint = entrypoint } +func (co *LegacyStageImageContainerOptions) AddNetwork(network string) { + co.Network = network +} + func (co *LegacyStageImageContainerOptions) merge(co2 *LegacyStageImageContainerOptions) *LegacyStageImageContainerOptions { mergedCo := newLegacyStageContainerOptions() @@ -132,6 +137,12 @@ func (co *LegacyStageImageContainerOptions) merge(co2 *LegacyStageImageContainer mergedCo.HealthCheck = co2.HealthCheck } + if co2.Network == "" { + mergedCo.Network = co.Network + } else { + mergedCo.Network = co2.Network + } + return mergedCo } @@ -179,6 +190,10 @@ func (co *LegacyStageImageContainerOptions) toRunArgs() ([]string, error) { args = append(args, fmt.Sprintf("--entrypoint=%s", co.Entrypoint)) } + if co.Network != "" { + args = append(args, fmt.Sprintf("--network=%s", co.Network)) + } + return args, nil } diff --git a/pkg/container_backend/stage_builder/dockerfile_builder.go b/pkg/container_backend/stage_builder/dockerfile_builder.go index 28b466658e..7295078158 100644 --- a/pkg/container_backend/stage_builder/dockerfile_builder.go +++ b/pkg/container_backend/stage_builder/dockerfile_builder.go @@ -44,6 +44,9 @@ func (b *DockerfileBuilder) Build(ctx context.Context, opts container_backend.Bu finalOpts := b.BuildDockerfileOptions finalOpts.BuildContextArchive = b.BuildContextArchive finalOpts.TargetPlatform = opts.TargetPlatform + if opts.Network != "" { + finalOpts.Network = opts.Network + } if container_backend.Debug() { fmt.Printf("BuildContextArchive=%q\n", b.BuildContextArchive) diff --git a/pkg/container_backend/stage_builder/stapel_stage_builder.go b/pkg/container_backend/stage_builder/stapel_stage_builder.go index 32e6ffb663..905897109c 100644 --- a/pkg/container_backend/stage_builder/stapel_stage_builder.go +++ b/pkg/container_backend/stage_builder/stapel_stage_builder.go @@ -31,6 +31,9 @@ func NewStapelStageBuilder(containerBackend container_backend.ContainerBackend, func (builder *StapelStageBuilder) Build(ctx context.Context, opts container_backend.BuildOptions) error { finalOpts := builder.BuildStapelStageOptions finalOpts.TargetPlatform = opts.TargetPlatform + if opts.Network != "" { + finalOpts.Network = opts.Network + } // TODO: support introspect options builtID, err := builder.ContainerBackend.BuildStapelStage(ctx, builder.BaseImage, finalOpts) diff --git a/pkg/container_backend/utils.go b/pkg/container_backend/utils.go index 8498b6bb69..31d48a5ef4 100644 --- a/pkg/container_backend/utils.go +++ b/pkg/container_backend/utils.go @@ -33,7 +33,7 @@ func LogImageName(ctx context.Context, name string) { logboek.Context(ctx).Default().LogFDetails(logImageInfoFormat, "name", name) } -func LogImageInfo(ctx context.Context, img LegacyImageInterface, prevStageImageSize int64, withPlatform bool) { +func LogImageInfo(ctx context.Context, img LegacyImageInterface, prevStageImageSize int64, withPlatform bool, network string) { LogImageName(ctx, img.Name()) logboek.Context(ctx).Default().LogFDetails(logImageInfoFormat, "id", stringid.TruncateID(img.GetStageDesc().Info.ID)) @@ -52,6 +52,8 @@ func LogImageInfo(ctx context.Context, img LegacyImageInterface, prevStageImageS if withPlatform { logboek.Context(ctx).Default().LogFDetails(logImageInfoFormat, "platform", img.GetTargetPlatform()) } + + logboek.Context(ctx).Default().LogFDetails(logImageInfoFormat, "network", network) } func LogMultiplatformImageInfo(ctx context.Context, platforms []string) { diff --git a/test/e2e/build/_fixtures/network/dockerfile/Dockerfile b/test/e2e/build/_fixtures/network/dockerfile/Dockerfile new file mode 100644 index 0000000000..feec489937 --- /dev/null +++ b/test/e2e/build/_fixtures/network/dockerfile/Dockerfile @@ -0,0 +1,2 @@ +FROM registry.werf.io/base/alpine +RUN apk add --no-cache bash diff --git a/test/e2e/build/_fixtures/network/dockerfile/werf.yaml b/test/e2e/build/_fixtures/network/dockerfile/werf.yaml new file mode 100644 index 0000000000..c5eab9c685 --- /dev/null +++ b/test/e2e/build/_fixtures/network/dockerfile/werf.yaml @@ -0,0 +1,5 @@ +project: network-test +configVersion: 1 +--- +image: dockerfile +dockerfile: Dockerfile diff --git a/test/e2e/build/_fixtures/network/dockerfile_yml/Dockerfile b/test/e2e/build/_fixtures/network/dockerfile_yml/Dockerfile new file mode 100644 index 0000000000..feec489937 --- /dev/null +++ b/test/e2e/build/_fixtures/network/dockerfile_yml/Dockerfile @@ -0,0 +1,2 @@ +FROM registry.werf.io/base/alpine +RUN apk add --no-cache bash diff --git a/test/e2e/build/_fixtures/network/dockerfile_yml/werf.yaml b/test/e2e/build/_fixtures/network/dockerfile_yml/werf.yaml new file mode 100644 index 0000000000..0849490dc0 --- /dev/null +++ b/test/e2e/build/_fixtures/network/dockerfile_yml/werf.yaml @@ -0,0 +1,6 @@ +project: network-test +configVersion: 1 +--- +image: dockerfile +dockerfile: Dockerfile +network: none diff --git a/test/e2e/build/_fixtures/network/dockerfile_yml_success/Dockerfile b/test/e2e/build/_fixtures/network/dockerfile_yml_success/Dockerfile new file mode 100644 index 0000000000..feec489937 --- /dev/null +++ b/test/e2e/build/_fixtures/network/dockerfile_yml_success/Dockerfile @@ -0,0 +1,2 @@ +FROM registry.werf.io/base/alpine +RUN apk add --no-cache bash diff --git a/test/e2e/build/_fixtures/network/dockerfile_yml_success/werf.yaml b/test/e2e/build/_fixtures/network/dockerfile_yml_success/werf.yaml new file mode 100644 index 0000000000..84adc51c99 --- /dev/null +++ b/test/e2e/build/_fixtures/network/dockerfile_yml_success/werf.yaml @@ -0,0 +1,6 @@ +project: network-test +configVersion: 1 +--- +image: dockerfile +dockerfile: Dockerfile +network: host diff --git a/test/e2e/build/_fixtures/network/stapel/werf.yaml b/test/e2e/build/_fixtures/network/stapel/werf.yaml new file mode 100644 index 0000000000..1422eb1a5b --- /dev/null +++ b/test/e2e/build/_fixtures/network/stapel/werf.yaml @@ -0,0 +1,8 @@ +project: network-test +configVersion: 1 +--- +image: stapel +from: registry.werf.io/base/alpine +shell: + setup: + - apk add --no-cache bash diff --git a/test/e2e/build/_fixtures/network/stapel_yml/werf.yaml b/test/e2e/build/_fixtures/network/stapel_yml/werf.yaml new file mode 100644 index 0000000000..afabcfe730 --- /dev/null +++ b/test/e2e/build/_fixtures/network/stapel_yml/werf.yaml @@ -0,0 +1,9 @@ +project: network-test +configVersion: 1 +--- +image: stapel +from: registry.werf.io/base/alpine +network: none +shell: + setup: + - apk add --no-cache bash diff --git a/test/e2e/build/_fixtures/network/stapel_yml_success/werf.yaml b/test/e2e/build/_fixtures/network/stapel_yml_success/werf.yaml new file mode 100644 index 0000000000..d9f0049db2 --- /dev/null +++ b/test/e2e/build/_fixtures/network/stapel_yml_success/werf.yaml @@ -0,0 +1,9 @@ +project: network-test +configVersion: 1 +--- +image: stapel +from: registry.werf.io/base/alpine +network: host +shell: + setup: + - apk add --no-cache bash diff --git a/test/e2e/build/network_test.go b/test/e2e/build/network_test.go new file mode 100644 index 0000000000..f51684db78 --- /dev/null +++ b/test/e2e/build/network_test.go @@ -0,0 +1,124 @@ +package e2e_build_test + +import ( + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + + "github.com/werf/werf/v2/test/pkg/contback" + "github.com/werf/werf/v2/test/pkg/werf" +) + +type networkTestOptions struct { + setupEnvOptions + ExpectError bool + FixturePath string + NetworkNone bool + ExpectNetworkValue string +} + +var _ = Describe("Network isolation build", Label("e2e", "build", "network"), func() { + DescribeTable("should handle network isolation correctly", + func(ctx SpecContext, testOpts networkTestOptions) { + By("initializing") + setupEnv(testOpts.setupEnvOptions) + _, err := contback.NewContainerBackend(testOpts.ContainerBackendMode) + if err == contback.ErrRuntimeUnavailable { + Skip(err.Error()) + } else if err != nil { + Fail(err.Error()) + } + + repoDirname := "repo0" + fixtureRelPath := testOpts.FixturePath + + By("preparing test repo") + SuiteData.InitTestRepo(ctx, repoDirname, fixtureRelPath) + werfProject := werf.NewProject(SuiteData.WerfBinPath, SuiteData.GetTestRepoPath(repoDirname)) + + var extraArgs []string + if testOpts.NetworkNone { + extraArgs = append(extraArgs, "--backend-network", "none") + } + + By("building images") + opts := &werf.BuildOptions{ + CommonOptions: werf.CommonOptions{ + ShouldFail: testOpts.ExpectError, + ExtraArgs: extraArgs, + }, + } + buildOut := werfProject.Build(ctx, opts) + + if !testOpts.ExpectError { + Expect(buildOut).To(ContainSubstring("Building stage")) + if testOpts.ExpectNetworkValue != "" { + Expect(buildOut).To(ContainSubstring("network: " + testOpts.ExpectNetworkValue)) + } else { + Expect(buildOut).To(ContainSubstring("network:")) + } + } + }, + + // CLI tests (verify CLI works when YAML is empty) + Entry("Stapel (Vanilla): Failure with --backend-network=none", Label("stapel"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: true, + FixturePath: "network/stapel", + NetworkNone: true, + }), + Entry("Stapel (Vanilla): Success without --backend-network flag", Label("stapel"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: false, + FixturePath: "network/stapel", + NetworkNone: false, + }), + Entry("Dockerfile (Vanilla): Failure with --backend-network=none", Label("dockerfile"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: true, + FixturePath: "network/dockerfile", + NetworkNone: true, + }), + Entry("Dockerfile (Vanilla): Success without --backend-network flag", Label("dockerfile"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: false, + FixturePath: "network/dockerfile", + NetworkNone: false, + }), + + // YAML tests (verify network directive in werf.yaml) + Entry("Stapel (Vanilla): Failure with network:none in werf.yaml", Label("stapel", "yml"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: true, + FixturePath: "network/stapel_yml", + NetworkNone: false, + }), + Entry("Stapel (Vanilla): Success with network:host in werf.yaml", Label("stapel", "yml"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: false, + FixturePath: "network/stapel_yml_success", + NetworkNone: false, + ExpectNetworkValue: "host", + }), + Entry("Dockerfile (Vanilla): Failure with network:none in werf.yaml", Label("dockerfile", "yml"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: true, + FixturePath: "network/dockerfile_yml", + NetworkNone: false, + }), + Entry("Dockerfile (Vanilla): Success with network:host in werf.yaml", Label("dockerfile", "yml"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: false, + FixturePath: "network/dockerfile_yml_success", + NetworkNone: false, + ExpectNetworkValue: "host", + }), + + // CLI overriding YAML + Entry("Stapel (Vanilla): CLI --backend-network=none overrides YAML network:host (should fail)", Label("stapel", "override"), networkTestOptions{ + setupEnvOptions: setupEnvOptions{ContainerBackendMode: "vanilla-docker", WithLocalRepo: false}, + ExpectError: true, + FixturePath: "network/stapel_yml_success", + NetworkNone: true, // CLI 'none' overrides YAML 'host' + }), + ) +})