github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/image/daemon/docker.go (about) 1 package daemon 2 3 import ( 4 "context" 5 "os" 6 7 "github.com/docker/docker/client" 8 "github.com/google/go-containerregistry/pkg/name" 9 "golang.org/x/xerrors" 10 ) 11 12 // DockerImage implements v1.Image by extending daemon.Image. 13 // The caller must call cleanup() to remove a temporary file. 14 func DockerImage(ref name.Reference, host string) (Image, func(), error) { 15 cleanup := func() {} 16 17 opts := []client.Opt{ 18 client.FromEnv, 19 client.WithAPIVersionNegotiation(), 20 } 21 if host != "" { 22 // adding host parameter to the last assuming it will pick up more preference 23 opts = append(opts, client.WithHost(host)) 24 } 25 c, err := client.NewClientWithOpts(opts...) 26 27 if err != nil { 28 return nil, cleanup, xerrors.Errorf("failed to initialize a docker client: %w", err) 29 } 30 defer func() { 31 if err != nil { 32 _ = c.Close() 33 } 34 }() 35 36 // <image_name>:<tag> pattern like "alpine:3.15" 37 // or 38 // <image_name>@<digest> pattern like "alpine@sha256:21a3deaa0d32a8057914f36584b5288d2e5ecc984380bc0118285c70fa8c9300" 39 imageID := ref.Name() 40 inspect, _, err := c.ImageInspectWithRaw(context.Background(), imageID) 41 if err != nil { 42 imageID = ref.String() // <image_id> pattern like `5ac716b05a9c` 43 inspect, _, err = c.ImageInspectWithRaw(context.Background(), imageID) 44 if err != nil { 45 return nil, cleanup, xerrors.Errorf("unable to inspect the image (%s): %w", imageID, err) 46 } 47 } 48 49 history, err := c.ImageHistory(context.Background(), imageID) 50 if err != nil { 51 return nil, cleanup, xerrors.Errorf("unable to get history (%s): %w", imageID, err) 52 } 53 54 f, err := os.CreateTemp("", "fanal-*") 55 if err != nil { 56 return nil, cleanup, xerrors.Errorf("failed to create a temporary file: %w", err) 57 } 58 59 cleanup = func() { 60 _ = c.Close() 61 _ = f.Close() 62 _ = os.Remove(f.Name()) 63 } 64 65 return &image{ 66 opener: imageOpener(context.Background(), imageID, f, c.ImageSave), 67 inspect: inspect, 68 history: configHistory(history), 69 }, cleanup, nil 70 }