go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/connection/container/image/docker.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package image 5 6 import ( 7 "io" 8 "os" 9 "strings" 10 11 "github.com/google/go-containerregistry/pkg/name" 12 v1 "github.com/google/go-containerregistry/pkg/v1" 13 "github.com/google/go-containerregistry/pkg/v1/daemon" 14 "github.com/google/go-containerregistry/pkg/v1/tarball" 15 "go.mondoo.com/cnquery/providers/os/connection/container/cache" 16 ) 17 18 type ShaReference struct { 19 SHA string 20 } 21 22 func (r ShaReference) Name() string { 23 return r.SHA 24 } 25 26 func (r ShaReference) String() string { 27 return r.SHA 28 } 29 30 func (r ShaReference) Context() name.Repository { 31 return name.Repository{} 32 } 33 34 func (r ShaReference) Identifier() string { 35 return r.SHA 36 } 37 38 func (r ShaReference) Scope(scope string) string { 39 return "" 40 } 41 42 func LoadImageFromDockerEngine(sha string, disableBuffer bool) (v1.Image, io.ReadCloser, error) { 43 opts := []daemon.Option{} 44 if disableBuffer { 45 opts = append(opts, daemon.WithUnbufferedOpener()) 46 } 47 img, err := daemon.Image(&ShaReference{SHA: strings.Replace(sha, "sha256:", "", -1)}, opts...) 48 if err != nil { 49 return nil, nil, err 50 } 51 52 // write image to disk (conmpressed, unflattened) 53 // Otherwise we can not later recognize it as a valid image 54 f, err := writeCompressedTarImage(img, sha) 55 if err != nil { 56 return nil, nil, err 57 } 58 59 return img, f, nil 60 } 61 62 // writeCompressedTarImage writes image including the metradata unflattened to disk 63 func writeCompressedTarImage(img v1.Image, digest string) (*os.File, error) { 64 f, err := cache.RandomFile() 65 if err != nil { 66 return nil, err 67 } 68 filename := f.Name() 69 70 ref, err := name.ParseReference(digest, name.WeakValidation) 71 if err != nil { 72 os.Remove(filename) 73 return nil, err 74 } 75 76 err = tarball.Write(ref, img, f) 77 if err != nil { 78 os.Remove(filename) 79 return nil, err 80 } 81 82 // Rewind, to later read the complete file for uncompress 83 f.Seek(0, io.SeekStart) 84 85 return f, nil 86 }