Skip to content

Commit 9d2057a

Browse files
feat(image): customer podman host or socket option (aquasecurity#6256)
Co-authored-by: DmitriyLewen <[email protected]> Co-authored-by: DmitriyLewen <[email protected]>
1 parent 2a9d9bd commit 9d2057a

File tree

10 files changed

+77
-7
lines changed

10 files changed

+77
-7
lines changed

docs/docs/references/configuration/cli/trivy_image.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ trivy image [flags] IMAGE_NAME
7878
--parallel int number of goroutines enabled for parallel scanning, set 0 to auto-detect parallelism (default 5)
7979
--password strings password. Comma-separated passwords allowed. TRIVY_PASSWORD should be used for security reasons.
8080
--platform string set platform in the form os/arch if image is multi-platform capable
81+
--podman-host string unix podman socket path to use for podman scanning
8182
--policy-bundle-repository string OCI registry URL to retrieve policy bundle from (default "ghcr.io/aquasecurity/trivy-policies:0")
8283
--policy-namespaces strings Rego namespaces
8384
--redis-ca string redis ca file location, if using redis as cache backend

docs/docs/references/configuration/config-file.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,11 @@ image:
203203
# Same as '--docker-host'
204204
# Default is empty
205205
host:
206+
207+
podman:
208+
# Same as '--podman-host'
209+
# Default is empty
210+
host:
206211
```
207212
208213
## Vulnerability Options

docs/docs/target/container_image.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,3 +500,10 @@ You can configure Docker daemon socket with `DOCKER_HOST` or `--docker-host`.
500500
```shell
501501
$ trivy image --docker-host tcp://127.0.0.1:2375 YOUR_IMAGE
502502
```
503+
504+
### Configure Podman daemon socket to connect to.
505+
You can configure Podman daemon socket with `--podman-host`.
506+
507+
```shell
508+
$ trivy image --podman-host /run/user/1000/podman/podman.sock YOUR_IMAGE
509+
```

pkg/commands/artifact/run.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,9 @@ func initScannerConfig(opts flag.Options, cacheClient cache.Cache) (ScannerConfi
670670
DockerOptions: ftypes.DockerOptions{
671671
Host: opts.DockerHost,
672672
},
673+
PodmanOptions: ftypes.PodmanOptions{
674+
Host: opts.PodmanHost,
675+
},
673676
ImageSources: opts.ImageSources,
674677
},
675678

pkg/fanal/image/daemon.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ func tryDockerDaemon(_ context.Context, imageName string, ref name.Reference, op
2121

2222
}
2323

24-
func tryPodmanDaemon(_ context.Context, imageName string, _ name.Reference, _ types.ImageOptions) (types.Image, func(), error) {
25-
img, cleanup, err := daemon.PodmanImage(imageName)
24+
func tryPodmanDaemon(_ context.Context, imageName string, _ name.Reference, opts types.ImageOptions) (types.Image, func(), error) {
25+
img, cleanup, err := daemon.PodmanImage(imageName, opts.PodmanOptions.Host)
2626
if err != nil {
2727
return nil, nil, err
2828
}

pkg/fanal/image/daemon/image_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,46 @@ func Test_image_ConfigNameWithCustomDockerHost(t *testing.T) {
115115
assert.Nil(t, err)
116116
}
117117

118+
func Test_image_ConfigNameWithCustomPodmanHost(t *testing.T) {
119+
if runtime.GOOS == "windows" {
120+
t.Skip("podman.sock is not available for Windows CI")
121+
}
122+
123+
ref, err := name.ParseReference("alpine:3.11")
124+
require.NoError(t, err)
125+
126+
eo := engine.Option{
127+
APIVersion: opt.APIVersion,
128+
ImagePaths: map[string]string{
129+
"index.docker.io/library/alpine:3.11": "../../test/testdata/alpine-311.tar.gz",
130+
},
131+
}
132+
133+
runtimeDir, err := os.MkdirTemp("", "daemon")
134+
require.NoError(t, err)
135+
136+
dir := filepath.Join(runtimeDir, "image")
137+
err = os.MkdirAll(dir, os.ModePerm)
138+
require.NoError(t, err)
139+
140+
podmanSocket := filepath.Join(dir, "image-test-podman-socket.sock")
141+
eo.UnixDomainSocket = podmanSocket
142+
143+
te := engine.NewDockerEngine(eo)
144+
defer te.Close()
145+
146+
img, cleanup, err := PodmanImage(ref.Name(), podmanSocket)
147+
require.NoError(t, err)
148+
defer cleanup()
149+
150+
conf, err := img.ConfigName()
151+
assert.Equal(t, v1.Hash{
152+
Algorithm: "sha256",
153+
Hex: "a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72",
154+
}, conf)
155+
assert.Nil(t, err)
156+
}
157+
118158
func Test_image_ConfigFile(t *testing.T) {
119159
tests := []struct {
120160
name string

pkg/fanal/image/daemon/podman.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ type podmanClient struct {
2525
c http.Client
2626
}
2727

28-
func newPodmanClient() (podmanClient, error) {
28+
func newPodmanClient(host string) (podmanClient, error) {
2929
// Get Podman socket location
3030
sockDir := os.Getenv("XDG_RUNTIME_DIR")
3131
socket := filepath.Join(sockDir, "podman", "podman.sock")
32+
if host != "" {
33+
socket = host
34+
}
3235

3336
if _, err := os.Stat(socket); err != nil {
3437
return podmanClient{}, xerrors.Errorf("no podman socket found: %w", err)
@@ -109,10 +112,10 @@ func (p podmanClient) imageSave(_ context.Context, imageNames []string) (io.Read
109112

110113
// PodmanImage implements v1.Image by extending daemon.Image.
111114
// The caller must call cleanup() to remove a temporary file.
112-
func PodmanImage(ref string) (Image, func(), error) {
115+
func PodmanImage(ref, host string) (Image, func(), error) {
113116
cleanup := func() {}
114117

115-
c, err := newPodmanClient()
118+
c, err := newPodmanClient(host)
116119
if err != nil {
117120
return nil, cleanup, xerrors.Errorf("unable to initialize Podman client: %w", err)
118121
}

pkg/fanal/image/daemon/podman_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func TestPodmanImage(t *testing.T) {
8484
ref, err := name.ParseReference(tt.imageName)
8585
require.NoError(t, err)
8686

87-
img, cleanup, err := PodmanImage(ref.Name())
87+
img, cleanup, err := PodmanImage(ref.Name(), "")
8888
defer cleanup()
8989

9090
if tt.wantErr {

pkg/fanal/types/image.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type DockerOptions struct {
6060
}
6161

6262
type PodmanOptions struct {
63-
// Add Podman-specific options
63+
Host string
6464
}
6565

6666
type ContainerdOptions struct {

pkg/flag/image_flags.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ var (
4545
Default: "",
4646
Usage: "unix domain socket path to use for docker scanning",
4747
}
48+
PodmanHostFlag = Flag[string]{
49+
Name: "podman-host",
50+
ConfigName: "image.podman.host",
51+
Default: "",
52+
Usage: "unix podman socket path to use for podman scanning",
53+
}
4854
SourceFlag = Flag[[]string]{
4955
Name: "image-src",
5056
ConfigName: "image.source",
@@ -60,6 +66,7 @@ type ImageFlagGroup struct {
6066
ScanRemovedPkgs *Flag[bool]
6167
Platform *Flag[string]
6268
DockerHost *Flag[string]
69+
PodmanHost *Flag[string]
6370
ImageSources *Flag[[]string]
6471
}
6572

@@ -69,6 +76,7 @@ type ImageOptions struct {
6976
ScanRemovedPkgs bool
7077
Platform ftypes.Platform
7178
DockerHost string
79+
PodmanHost string
7280
ImageSources ftypes.ImageSources
7381
}
7482

@@ -79,6 +87,7 @@ func NewImageFlagGroup() *ImageFlagGroup {
7987
ScanRemovedPkgs: ScanRemovedPkgsFlag.Clone(),
8088
Platform: PlatformFlag.Clone(),
8189
DockerHost: DockerHostFlag.Clone(),
90+
PodmanHost: PodmanHostFlag.Clone(),
8291
ImageSources: SourceFlag.Clone(),
8392
}
8493
}
@@ -94,6 +103,7 @@ func (f *ImageFlagGroup) Flags() []Flagger {
94103
f.ScanRemovedPkgs,
95104
f.Platform,
96105
f.DockerHost,
106+
f.PodmanHost,
97107
f.ImageSources,
98108
}
99109
}
@@ -121,6 +131,7 @@ func (f *ImageFlagGroup) ToOptions() (ImageOptions, error) {
121131
ScanRemovedPkgs: f.ScanRemovedPkgs.Value(),
122132
Platform: platform,
123133
DockerHost: f.DockerHost.Value(),
134+
PodmanHost: f.PodmanHost.Value(),
124135
ImageSources: xstrings.ToTSlice[ftypes.ImageSource](f.ImageSources.Value()),
125136
}, nil
126137
}

0 commit comments

Comments
 (0)