Files
syft/syft/get_source_config_test.go
T
29b92a58c1 Add container-storage support for Podman and Buildah (#5368)
* feat: add containers-storage support for Podman and Buildah, update tests and documentation

Signed-off-by: Bruce Clark <bruce.clark@mandg.com>

* test: update containers-storage tests to validate package.json and handle missing images

Signed-off-by: Bruce Clark <bruce.clark@mandg.com>

* test: fix rootless containers-storage test setup

Install uidmap for Podman and Buildah CI jobs.
Align temporary rootful and rootless storage paths.
Clean up rootless stores within the builder's user namespace.

Signed-off-by: Bruce Clark <bruce.clark@mandg.com>

* fix: only use containers-storage when explicitly requested

- containers-storage is no longer part of automatic image resolution; it's used only for `--from containers-storage`, the `containers-storage:` scheme, or `default-pull-source: containers-storage` (now an accepted value). Opening a store runs full graph driver init (mounts, locks, store writes), which is too invasive as a probe on every plain image reference.
- rootless stores must be read from inside the builder's user namespace (`podman unshare syft ...`), documented in the README.
- the `containers_image_openpgp` tag is now applied to unit/integration tests and lint, so dev tooling compiles the same provider that ships.
- containers-storage CI runs through `make containers-storage-test` and covers both vfs and overlay stores.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* fix: exclude cgo btrfs driver and unmount overlay store in cleanup

- cgo-enabled linux builds (`-race` tests, lint) compile go.podman.io's btrfs graph driver, which needs libbtrfs headers. Add `exclude_graphdriver_btrfs` alongside `containers_image_openpgp` everywhere the tag is set; release builds are `CGO_ENABLED=0` and never included it.
- the overlay driver bind-mounts its graphroot inside the rootless user namespace, so the containers-storage test unmounts it before removing the store, and cleanup no longer fails the run.

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Bruce Clark <bruce.clark@mandg.com>
Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
Co-authored-by: Bruce Clark <bruce.clark@mandg.com>
Co-authored-by: Alex Goodman <wagoodman@users.noreply.github.com>
2026-10-05 15:02:37 +00:00

98 lines
2.9 KiB
Go

package syft
import (
"slices"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/anchore/stereoscope"
"github.com/anchore/stereoscope/pkg/image"
"github.com/anchore/syft/syft/source"
"github.com/anchore/syft/syft/source/sourceproviders"
)
func TestGetProviders_DefaultImagePullSource(t *testing.T) {
userInput := ""
cfg := &GetSourceConfig{DefaultImagePullSource: stereoscope.RegistryTag}
allSourceProviders := sourceproviders.All(userInput, cfg.SourceProviderConfig)
providers, err := cfg.getProviders(userInput)
if err != nil {
t.Errorf("Expected no error for DefaultImagePullSource parameter, got: %v", err)
}
// everything except containers-storage, which is only used when requested by name
if len(providers) != len(allSourceProviders)-1 {
t.Errorf("Expected %d providers, got %d", len(allSourceProviders)-1, len(providers))
}
}
func TestGetProviders_Sources(t *testing.T) {
userInput := ""
cfg := &GetSourceConfig{Sources: []string{stereoscope.RegistryTag}}
providers, err := cfg.getProviders(userInput)
if err != nil {
t.Errorf("Expected no error for Sources parameter, got: %v", err)
}
// Registry tag has two providers: OCIModel and Image
if len(providers) != 2 {
t.Errorf("Expected 2 providers, got %d", len(providers))
}
}
func TestGetProviders_ContainersStorageOnlyWhenRequested(t *testing.T) {
const storage = image.ContainersStorageSource
tests := []struct {
name string
cfg *GetSourceConfig
wantFound bool
// if set, containers-storage must be ordered ahead of this provider
wantBefore string
}{
{
name: "excluded from automatic resolution",
cfg: DefaultGetSourceConfig(),
},
{
name: "excluded when selecting all pull sources",
cfg: DefaultGetSourceConfig().WithSources(sourceproviders.PullTag),
},
{
name: "excluded when a different default pull source is set",
cfg: DefaultGetSourceConfig().WithDefaultImagePullSource(stereoscope.RegistryTag),
},
{
name: "included when explicitly selected",
cfg: DefaultGetSourceConfig().WithSources(storage),
wantFound: true,
},
{
name: "included ahead of other pull sources when it is the default pull source",
cfg: DefaultGetSourceConfig().WithDefaultImagePullSource(storage),
wantFound: true,
wantBefore: image.DockerDaemonSource,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
providers, err := tt.cfg.getProviders("localhost/myimage:latest")
require.NoError(t, err)
require.NotEmpty(t, providers)
assert.Equal(t, tt.wantFound, providerIndex(providers, storage) >= 0)
if tt.wantBefore != "" {
assert.Less(t, providerIndex(providers, storage), providerIndex(providers, tt.wantBefore))
}
})
}
}
func providerIndex(providers []source.Provider, name string) int {
return slices.IndexFunc(providers, func(p source.Provider) bool { return p.Name() == name })
}