github.com/rita33cool1/iot-system-gateway@v0.0.0-20200911033302-e65bde238cc5/docker-engine/builder/dockerfile/imagecontext.go (about) 1 package dockerfile // import "github.com/docker/docker/builder/dockerfile" 2 3 import ( 4 "runtime" 5 6 "github.com/docker/docker/api/types/backend" 7 "github.com/docker/docker/builder" 8 dockerimage "github.com/docker/docker/image" 9 "github.com/docker/docker/pkg/system" 10 "github.com/pkg/errors" 11 "github.com/sirupsen/logrus" 12 "golang.org/x/net/context" 13 ) 14 15 type getAndMountFunc func(string, bool) (builder.Image, builder.ROLayer, error) 16 17 // imageSources mounts images and provides a cache for mounted images. It tracks 18 // all images so they can be unmounted at the end of the build. 19 type imageSources struct { 20 byImageID map[string]*imageMount 21 mounts []*imageMount 22 getImage getAndMountFunc 23 } 24 25 func newImageSources(ctx context.Context, options builderOptions) *imageSources { 26 getAndMount := func(idOrRef string, localOnly bool) (builder.Image, builder.ROLayer, error) { 27 pullOption := backend.PullOptionNoPull 28 if !localOnly { 29 if options.Options.PullParent { 30 pullOption = backend.PullOptionForcePull 31 } else { 32 pullOption = backend.PullOptionPreferLocal 33 } 34 } 35 optionsPlatform := system.ParsePlatform(options.Options.Platform) 36 return options.Backend.GetImageAndReleasableLayer(ctx, idOrRef, backend.GetImageAndLayerOptions{ 37 PullOption: pullOption, 38 AuthConfig: options.Options.AuthConfigs, 39 Output: options.ProgressWriter.Output, 40 OS: optionsPlatform.OS, 41 }) 42 } 43 44 return &imageSources{ 45 byImageID: make(map[string]*imageMount), 46 getImage: getAndMount, 47 } 48 } 49 50 func (m *imageSources) Get(idOrRef string, localOnly bool) (*imageMount, error) { 51 if im, ok := m.byImageID[idOrRef]; ok { 52 return im, nil 53 } 54 55 image, layer, err := m.getImage(idOrRef, localOnly) 56 if err != nil { 57 return nil, err 58 } 59 im := newImageMount(image, layer) 60 m.Add(im) 61 return im, nil 62 } 63 64 func (m *imageSources) Unmount() (retErr error) { 65 for _, im := range m.mounts { 66 if err := im.unmount(); err != nil { 67 logrus.Error(err) 68 retErr = err 69 } 70 } 71 return 72 } 73 74 func (m *imageSources) Add(im *imageMount) { 75 switch im.image { 76 case nil: 77 // set the OS for scratch images 78 os := runtime.GOOS 79 // Windows does not support scratch except for LCOW 80 if runtime.GOOS == "windows" { 81 os = "linux" 82 } 83 im.image = &dockerimage.Image{V1Image: dockerimage.V1Image{OS: os}} 84 default: 85 m.byImageID[im.image.ImageID()] = im 86 } 87 m.mounts = append(m.mounts, im) 88 } 89 90 // imageMount is a reference to an image that can be used as a builder.Source 91 type imageMount struct { 92 image builder.Image 93 source builder.Source 94 layer builder.ROLayer 95 } 96 97 func newImageMount(image builder.Image, layer builder.ROLayer) *imageMount { 98 im := &imageMount{image: image, layer: layer} 99 return im 100 } 101 102 func (im *imageMount) unmount() error { 103 if im.layer == nil { 104 return nil 105 } 106 if err := im.layer.Release(); err != nil { 107 return errors.Wrapf(err, "failed to unmount previous build image %s", im.image.ImageID()) 108 } 109 im.layer = nil 110 return nil 111 } 112 113 func (im *imageMount) Image() builder.Image { 114 return im.image 115 } 116 117 func (im *imageMount) NewRWLayer() (builder.RWLayer, error) { 118 return im.layer.NewRWLayer() 119 } 120 121 func (im *imageMount) ImageID() string { 122 return im.image.ImageID() 123 }