github.com/jwhonce/docker@v0.6.7-0.20190327063223-da823cf3a5a3/builder/builder-next/controller.go (about) 1 package buildkit 2 3 import ( 4 "net/http" 5 "os" 6 "path/filepath" 7 8 "github.com/containerd/containerd/content/local" 9 "github.com/containerd/containerd/platforms" 10 "github.com/docker/docker/api/types" 11 "github.com/docker/docker/builder/builder-next/adapters/containerimage" 12 "github.com/docker/docker/builder/builder-next/adapters/localinlinecache" 13 "github.com/docker/docker/builder/builder-next/adapters/snapshot" 14 containerimageexp "github.com/docker/docker/builder/builder-next/exporter" 15 "github.com/docker/docker/builder/builder-next/imagerefchecker" 16 mobyworker "github.com/docker/docker/builder/builder-next/worker" 17 "github.com/docker/docker/daemon/config" 18 "github.com/docker/docker/daemon/graphdriver" 19 units "github.com/docker/go-units" 20 "github.com/moby/buildkit/cache" 21 "github.com/moby/buildkit/cache/metadata" 22 "github.com/moby/buildkit/cache/remotecache" 23 inlineremotecache "github.com/moby/buildkit/cache/remotecache/inline" 24 "github.com/moby/buildkit/client" 25 "github.com/moby/buildkit/control" 26 "github.com/moby/buildkit/frontend" 27 dockerfile "github.com/moby/buildkit/frontend/dockerfile/builder" 28 "github.com/moby/buildkit/frontend/gateway" 29 "github.com/moby/buildkit/frontend/gateway/forwarder" 30 "github.com/moby/buildkit/snapshot/blobmapping" 31 "github.com/moby/buildkit/solver/bboltcachestorage" 32 "github.com/moby/buildkit/util/binfmt_misc" 33 "github.com/moby/buildkit/worker" 34 specs "github.com/opencontainers/image-spec/specs-go/v1" 35 "github.com/pkg/errors" 36 ) 37 38 func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) { 39 if err := os.MkdirAll(opt.Root, 0700); err != nil { 40 return nil, err 41 } 42 43 dist := opt.Dist 44 root := opt.Root 45 46 var driver graphdriver.Driver 47 if ls, ok := dist.LayerStore.(interface { 48 Driver() graphdriver.Driver 49 }); ok { 50 driver = ls.Driver() 51 } else { 52 return nil, errors.Errorf("could not access graphdriver") 53 } 54 55 sbase, err := snapshot.NewSnapshotter(snapshot.Opt{ 56 GraphDriver: driver, 57 LayerStore: dist.LayerStore, 58 Root: root, 59 }) 60 if err != nil { 61 return nil, err 62 } 63 64 store, err := local.NewStore(filepath.Join(root, "content")) 65 if err != nil { 66 return nil, err 67 } 68 store = &contentStoreNoLabels{store} 69 70 md, err := metadata.NewStore(filepath.Join(root, "metadata.db")) 71 if err != nil { 72 return nil, err 73 } 74 75 snapshotter := blobmapping.NewSnapshotter(blobmapping.Opt{ 76 Content: store, 77 Snapshotter: sbase, 78 MetadataStore: md, 79 }) 80 81 layerGetter, ok := sbase.(imagerefchecker.LayerGetter) 82 if !ok { 83 return nil, errors.Errorf("snapshotter does not implement layergetter") 84 } 85 86 refChecker := imagerefchecker.New(imagerefchecker.Opt{ 87 ImageStore: dist.ImageStore, 88 LayerGetter: layerGetter, 89 }) 90 91 cm, err := cache.NewManager(cache.ManagerOpt{ 92 Snapshotter: snapshotter, 93 MetadataStore: md, 94 PruneRefChecker: refChecker, 95 }) 96 if err != nil { 97 return nil, err 98 } 99 100 src, err := containerimage.NewSource(containerimage.SourceOpt{ 101 CacheAccessor: cm, 102 ContentStore: store, 103 DownloadManager: dist.DownloadManager, 104 MetadataStore: dist.V2MetadataService, 105 ImageStore: dist.ImageStore, 106 ReferenceStore: dist.ReferenceStore, 107 ResolverOpt: opt.ResolverOpt, 108 }) 109 if err != nil { 110 return nil, err 111 } 112 113 exec, err := newExecutor(root, opt.DefaultCgroupParent, opt.NetworkController, opt.Rootless) 114 if err != nil { 115 return nil, err 116 } 117 118 differ, ok := sbase.(containerimageexp.Differ) 119 if !ok { 120 return nil, errors.Errorf("snapshotter doesn't support differ") 121 } 122 123 exp, err := containerimageexp.New(containerimageexp.Opt{ 124 ImageStore: dist.ImageStore, 125 ReferenceStore: dist.ReferenceStore, 126 Differ: differ, 127 }) 128 if err != nil { 129 return nil, err 130 } 131 132 cacheStorage, err := bboltcachestorage.NewStore(filepath.Join(opt.Root, "cache.db")) 133 if err != nil { 134 return nil, err 135 } 136 137 gcPolicy, err := getGCPolicy(opt.BuilderConfig, root) 138 if err != nil { 139 return nil, errors.Wrap(err, "could not get builder GC policy") 140 } 141 142 layers, ok := sbase.(mobyworker.LayerAccess) 143 if !ok { 144 return nil, errors.Errorf("snapshotter doesn't support differ") 145 } 146 147 p, err := parsePlatforms(binfmt_misc.SupportedPlatforms()) 148 if err != nil { 149 return nil, err 150 } 151 152 wopt := mobyworker.Opt{ 153 ID: "moby", 154 MetadataStore: md, 155 ContentStore: store, 156 CacheManager: cm, 157 GCPolicy: gcPolicy, 158 Snapshotter: snapshotter, 159 Executor: exec, 160 ImageSource: src, 161 DownloadManager: dist.DownloadManager, 162 V2MetadataService: dist.V2MetadataService, 163 Exporter: exp, 164 Transport: rt, 165 Layers: layers, 166 Platforms: p, 167 } 168 169 wc := &worker.Controller{} 170 w, err := mobyworker.NewWorker(wopt) 171 if err != nil { 172 return nil, err 173 } 174 wc.Add(w) 175 176 frontends := map[string]frontend.Frontend{ 177 "dockerfile.v0": forwarder.NewGatewayForwarder(wc, dockerfile.Build), 178 "gateway.v0": gateway.NewGatewayFrontend(wc), 179 } 180 181 return control.NewController(control.Opt{ 182 SessionManager: opt.SessionManager, 183 WorkerController: wc, 184 Frontends: frontends, 185 CacheKeyStorage: cacheStorage, 186 ResolveCacheImporterFuncs: map[string]remotecache.ResolveCacheImporterFunc{ 187 "registry": localinlinecache.ResolveCacheImporterFunc(opt.SessionManager, opt.ResolverOpt, dist.ReferenceStore, dist.ImageStore), 188 }, 189 ResolveCacheExporterFuncs: map[string]remotecache.ResolveCacheExporterFunc{ 190 "inline": inlineremotecache.ResolveCacheExporterFunc(), 191 }, 192 }) 193 } 194 195 func getGCPolicy(conf config.BuilderConfig, root string) ([]client.PruneInfo, error) { 196 var gcPolicy []client.PruneInfo 197 if conf.GC.Enabled { 198 var ( 199 defaultKeepStorage int64 200 err error 201 ) 202 203 if conf.GC.DefaultKeepStorage != "" { 204 defaultKeepStorage, err = units.RAMInBytes(conf.GC.DefaultKeepStorage) 205 if err != nil { 206 return nil, errors.Wrapf(err, "could not parse '%s' as Builder.GC.DefaultKeepStorage config", conf.GC.DefaultKeepStorage) 207 } 208 } 209 210 if conf.GC.Policy == nil { 211 gcPolicy = mobyworker.DefaultGCPolicy(root, defaultKeepStorage) 212 } else { 213 gcPolicy = make([]client.PruneInfo, len(conf.GC.Policy)) 214 for i, p := range conf.GC.Policy { 215 b, err := units.RAMInBytes(p.KeepStorage) 216 if err != nil { 217 return nil, err 218 } 219 if b == 0 { 220 b = defaultKeepStorage 221 } 222 gcPolicy[i], err = toBuildkitPruneInfo(types.BuildCachePruneOptions{ 223 All: p.All, 224 KeepStorage: b, 225 Filters: p.Filter, 226 }) 227 if err != nil { 228 return nil, err 229 } 230 } 231 } 232 } 233 return gcPolicy, nil 234 } 235 236 func parsePlatforms(platformsStr []string) ([]specs.Platform, error) { 237 out := make([]specs.Platform, 0, len(platformsStr)) 238 for _, s := range platformsStr { 239 p, err := platforms.Parse(s) 240 if err != nil { 241 return nil, err 242 } 243 out = append(out, platforms.Normalize(p)) 244 } 245 return out, nil 246 }