diff --git a/pkg/build/image/stapel_test.go b/pkg/build/image/stapel_test.go index de7a79fb1c..fecf802450 100644 --- a/pkg/build/image/stapel_test.go +++ b/pkg/build/image/stapel_test.go @@ -113,6 +113,60 @@ packages: ) }) +var _ = Describe("network isolation under build.sbom.enable", func() { + werfYaml := func(importPosition string) string { + return fmt.Sprintf(`project: test +configVersion: 1 +build: + sbom: + enable: true + standard: cyclonedx@1.6 +--- +image: donor +from: alpine:3.20 +--- +image: app +from: alpine:3.20 +import: +- image: donor + add: /etc/os-release + to: /donor/os-release + %s +shell: + install: + - echo install + setup: + - echo setup +`, importPosition) + } + + stageNetwork := func(image *Image, name stage.StageName) string { + s := image.GetStage(name) + Expect(s).NotTo(BeNil()) + n, ok := s.(interface{ Network() string }) + Expect(ok).To(BeTrue()) + return n.Network() + } + + DescribeTable("disables network for shell stages but leaves the import stage reachable", + func(importPosition string, importStage stage.StageName) { + ctx := context.Background() + projectDir := newProjectRepo(ctx, map[string]string{"werf.yaml": werfYaml(importPosition)}) + + image, err := stapelImage(ctx, projectDir) + Expect(err).NotTo(HaveOccurred()) + + Expect(stageNetwork(image, stage.Install)).To(Equal("none")) + Expect(stageNetwork(image, stage.Setup)).To(Equal("none")) + Expect(stageNetwork(image, importStage)).To(BeEmpty()) + }, + Entry("before install", "before: install", stage.DependenciesBeforeInstall), + Entry("after install", "after: install", stage.DependenciesAfterInstall), + Entry("before setup", "before: setup", stage.DependenciesBeforeSetup), + Entry("after setup", "after: setup", stage.DependenciesAfterSetup), + ) +}) + var _ = Describe("sign files stages", func() { werfYaml := func(sbomBlock string) string { return fmt.Sprintf(`project: test diff --git a/pkg/build/stage/dependencies.go b/pkg/build/stage/dependencies.go index fe7a48177a..8d082f7481 100644 --- a/pkg/build/stage/dependencies.go +++ b/pkg/build/stage/dependencies.go @@ -44,11 +44,15 @@ func getDependencies(imageBaseConfig *config.StapelImageBase, options *getImport return dependencies } +// newDependenciesStage marks the stage as needing network: under the Docker backend imports +// are rsynced from an import-server container, and the stage carries no shell: commands. func newDependenciesStage(imports []*config.Import, dependencies []*config.Dependency, name StageName, baseStageOptions *BaseStageOptions) *DependenciesStage { + opts := *baseStageOptions + opts.NeedsNetwork = true s := &DependenciesStage{} s.imports = imports s.dependencies = dependencies - s.BaseStage = NewBaseStage(name, baseStageOptions) + s.BaseStage = NewBaseStage(name, &opts) return s } diff --git a/pkg/build/stage/dependencies_test.go b/pkg/build/stage/dependencies_test.go index b56120a483..58d7e8b3c3 100644 --- a/pkg/build/stage/dependencies_test.go +++ b/pkg/build/stage/dependencies_test.go @@ -13,6 +13,20 @@ import ( ) var _ = Describe("DependenciesStage", func() { + DescribeTable("needs network regardless of the base options", + func(name StageName) { + stage := newDependenciesStage(nil, nil, name, &BaseStageOptions{ + ImageName: "example-image", + ProjectName: "example-project", + }) + Expect(stage.NeedsNetwork()).To(BeTrue()) + }, + Entry("dependenciesBeforeInstall", DependenciesBeforeInstall), + Entry("dependenciesAfterInstall", DependenciesAfterInstall), + Entry("dependenciesBeforeSetup", DependenciesBeforeSetup), + Entry("dependenciesAfterSetup", DependenciesAfterSetup), + ) + DescribeTable("configuring images dependencies for dependencies stage", func(ctx SpecContext, data TestDependencies) { conveyor := NewConveyorStubForDependencies(NewGiterminismManagerStub(NewLocalGitRepoStub("9d8059842b6fde712c58315ca0ab4713d90761c0"), NewGiterminismInspectorStub()), data.Dependencies)