Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
| ... | ... |
@@ -118,6 +118,7 @@ func (b *Backend) PruneCache(ctx context.Context) (*types.BuildCachePruneReport, |
| 118 | 118 |
return &types.BuildCachePruneReport{SpaceReclaimed: fsCacheSize + uint64(buildCacheSize)}, nil
|
| 119 | 119 |
} |
| 120 | 120 |
|
| 121 |
+// Cancel cancels the build by ID |
|
| 121 | 122 |
func (b *Backend) Cancel(ctx context.Context, id string) error {
|
| 122 | 123 |
return b.buildkit.Cancel(ctx, id) |
| 123 | 124 |
} |
| ... | ... |
@@ -76,10 +76,7 @@ func (s *systemRouter) getDiskUsage(ctx context.Context, w http.ResponseWriter, |
| 76 | 76 |
eg.Go(func() error {
|
| 77 | 77 |
var err error |
| 78 | 78 |
du, err = s.backend.SystemDiskUsage(ctx) |
| 79 |
- if err != nil {
|
|
| 80 |
- return err |
|
| 81 |
- } |
|
| 82 |
- return nil |
|
| 79 |
+ return err |
|
| 83 | 80 |
}) |
| 84 | 81 |
|
| 85 | 82 |
var builderSize int64 // legacy |
| ... | ... |
@@ -189,8 +189,10 @@ type ImageBuildOptions struct {
|
| 189 | 189 |
type BuilderVersion string |
| 190 | 190 |
|
| 191 | 191 |
const ( |
| 192 |
- BuilderV1 BuilderVersion = "1" |
|
| 193 |
- BuilderBuildKit = "2" |
|
| 192 |
+ // BuilderV1 is the first generation builder in docker daemon |
|
| 193 |
+ BuilderV1 BuilderVersion = "1" |
|
| 194 |
+ // BuilderBuildKit is builder based on moby/buildkit project |
|
| 195 |
+ BuilderBuildKit = "2" |
|
| 194 | 196 |
) |
| 195 | 197 |
|
| 196 | 198 |
// ImageBuildResponse holds information |
| ... | ... |
@@ -43,6 +43,7 @@ import ( |
| 43 | 43 |
|
| 44 | 44 |
const preferLocal = true // FIXME: make this optional from the op |
| 45 | 45 |
|
| 46 |
+// SourceOpt is options for creating the image source |
|
| 46 | 47 |
type SourceOpt struct {
|
| 47 | 48 |
SessionManager *session.Manager |
| 48 | 49 |
ContentStore content.Store |
| ... | ... |
@@ -58,6 +59,7 @@ type imageSource struct {
|
| 58 | 58 |
g flightcontrol.Group |
| 59 | 59 |
} |
| 60 | 60 |
|
| 61 |
+// NewSource creates a new image source |
|
| 61 | 62 |
func NewSource(opt SourceOpt) (source.Source, error) {
|
| 62 | 63 |
is := &imageSource{
|
| 63 | 64 |
SourceOpt: opt, |
| ... | ... |
@@ -69,10 +69,7 @@ func (s *snapshotter) EnsureLayer(ctx context.Context, key string) ([]layer.Diff |
| 69 | 69 |
} |
| 70 | 70 |
} |
| 71 | 71 |
diffID, size, err = s.reg.ChecksumForGraphID(id, parent, "", tarSplitPath) |
| 72 |
- if err != nil {
|
|
| 73 |
- return err |
|
| 74 |
- } |
|
| 75 |
- return nil |
|
| 72 |
+ return err |
|
| 76 | 73 |
}) |
| 77 | 74 |
|
| 78 | 75 |
if err := eg.Wait(); err != nil {
|
| ... | ... |
@@ -23,6 +23,7 @@ var keyCommitted = []byte("committed")
|
| 23 | 23 |
var keyChainID = []byte("chainid")
|
| 24 | 24 |
var keySize = []byte("size")
|
| 25 | 25 |
|
| 26 |
+// Opt defines options for creating the snapshotter |
|
| 26 | 27 |
type Opt struct {
|
| 27 | 28 |
GraphDriver graphdriver.Driver |
| 28 | 29 |
LayerStore layer.Store |
| ... | ... |
@@ -50,6 +51,7 @@ type snapshotter struct {
|
| 50 | 50 |
|
| 51 | 51 |
var _ snapshot.SnapshotterBase = &snapshotter{}
|
| 52 | 52 |
|
| 53 |
+// NewSnapshotter creates a new snapshotter |
|
| 53 | 54 |
func NewSnapshotter(opt Opt) (snapshot.SnapshotterBase, error) {
|
| 54 | 55 |
dbPath := filepath.Join(opt.Root, "snapshots.db") |
| 55 | 56 |
db, err := bolt.Open(dbPath, 0600, nil) |
| ... | ... |
@@ -196,7 +198,7 @@ func (s *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, err |
| 196 | 196 |
inf.Parent = p.ChainID().String() |
| 197 | 197 |
} |
| 198 | 198 |
inf.Kind = snapshots.KindCommitted |
| 199 |
- inf.Name = string(key) |
|
| 199 |
+ inf.Name = key |
|
| 200 | 200 |
return inf, nil |
| 201 | 201 |
} |
| 202 | 202 |
|
| ... | ... |
@@ -215,7 +217,7 @@ func (s *snapshotter) Stat(ctx context.Context, key string) (snapshots.Info, err |
| 215 | 215 |
if b == nil && l == nil {
|
| 216 | 216 |
return errors.Errorf("snapshot %s not found", id) // TODO: typed
|
| 217 | 217 |
} |
| 218 |
- inf.Name = string(key) |
|
| 218 |
+ inf.Name = key |
|
| 219 | 219 |
if b != nil {
|
| 220 | 220 |
v := b.Get(keyParent) |
| 221 | 221 |
if v != nil {
|
| ... | ... |
@@ -322,7 +324,7 @@ func (s *snapshotter) Remove(ctx context.Context, key string) error {
|
| 322 | 322 |
} |
| 323 | 323 |
|
| 324 | 324 |
func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snapshots.Opt) error {
|
| 325 |
- if err := s.db.Update(func(tx *bolt.Tx) error {
|
|
| 325 |
+ return s.db.Update(func(tx *bolt.Tx) error {
|
|
| 326 | 326 |
b, err := tx.CreateBucketIfNotExists([]byte(name)) |
| 327 | 327 |
if err != nil {
|
| 328 | 328 |
return err |
| ... | ... |
@@ -331,10 +333,7 @@ func (s *snapshotter) Commit(ctx context.Context, name, key string, opts ...snap |
| 331 | 331 |
return err |
| 332 | 332 |
} |
| 333 | 333 |
return nil |
| 334 |
- }); err != nil {
|
|
| 335 |
- return err |
|
| 336 |
- } |
|
| 337 |
- return nil |
|
| 334 |
+ }) |
|
| 338 | 335 |
} |
| 339 | 336 |
|
| 340 | 337 |
func (s *snapshotter) View(ctx context.Context, key, parent string, opts ...snapshots.Opt) (snapshot.Mountable, error) {
|
| ... | ... |
@@ -421,7 +420,7 @@ func (s *snapshotter) Usage(ctx context.Context, key string) (us snapshots.Usage |
| 421 | 421 |
}); err != nil {
|
| 422 | 422 |
return usage, err |
| 423 | 423 |
} |
| 424 |
- usage.Size = int64(diffSize) |
|
| 424 |
+ usage.Size = diffSize |
|
| 425 | 425 |
return usage, nil |
| 426 | 426 |
} |
| 427 | 427 |
|
| ... | ... |
@@ -24,12 +24,14 @@ import ( |
| 24 | 24 |
grpcmetadata "google.golang.org/grpc/metadata" |
| 25 | 25 |
) |
| 26 | 26 |
|
| 27 |
+// Opt is option struct required for creating the builder |
|
| 27 | 28 |
type Opt struct {
|
| 28 | 29 |
SessionManager *session.Manager |
| 29 | 30 |
Root string |
| 30 | 31 |
Dist images.DistributionServices |
| 31 | 32 |
} |
| 32 | 33 |
|
| 34 |
+// Builder can build using BuildKit backend |
|
| 33 | 35 |
type Builder struct {
|
| 34 | 36 |
controller *control.Controller |
| 35 | 37 |
reqBodyHandler *reqBodyHandler |
| ... | ... |
@@ -38,6 +40,7 @@ type Builder struct {
|
| 38 | 38 |
jobs map[string]*buildJob |
| 39 | 39 |
} |
| 40 | 40 |
|
| 41 |
+// New creates a new builder |
|
| 41 | 42 |
func New(opt Opt) (*Builder, error) {
|
| 42 | 43 |
reqHandler := newReqBodyHandler(tracing.DefaultTransport) |
| 43 | 44 |
|
| ... | ... |
@@ -53,6 +56,7 @@ func New(opt Opt) (*Builder, error) {
|
| 53 | 53 |
return b, nil |
| 54 | 54 |
} |
| 55 | 55 |
|
| 56 |
+// Cancel cancels a build using ID |
|
| 56 | 57 |
func (b *Builder) Cancel(ctx context.Context, id string) error {
|
| 57 | 58 |
b.mu.Lock() |
| 58 | 59 |
if j, ok := b.jobs[id]; ok && j.cancel != nil {
|
| ... | ... |
@@ -62,6 +66,7 @@ func (b *Builder) Cancel(ctx context.Context, id string) error {
|
| 62 | 62 |
return nil |
| 63 | 63 |
} |
| 64 | 64 |
|
| 65 |
+// DiskUsage returns a report about space used by build cache |
|
| 65 | 66 |
func (b *Builder) DiskUsage(ctx context.Context) ([]*types.BuildCache, error) {
|
| 66 | 67 |
duResp, err := b.controller.DiskUsage(ctx, &controlapi.DiskUsageRequest{})
|
| 67 | 68 |
if err != nil {
|
| ... | ... |
@@ -86,6 +91,7 @@ func (b *Builder) DiskUsage(ctx context.Context) ([]*types.BuildCache, error) {
|
| 86 | 86 |
return items, nil |
| 87 | 87 |
} |
| 88 | 88 |
|
| 89 |
+// Prune clears all reclaimable build cache |
|
| 89 | 90 |
func (b *Builder) Prune(ctx context.Context) (int64, error) {
|
| 90 | 91 |
ch := make(chan *controlapi.UsageRecord) |
| 91 | 92 |
|
| ... | ... |
@@ -114,6 +120,7 @@ func (b *Builder) Prune(ctx context.Context) (int64, error) {
|
| 114 | 114 |
return size, nil |
| 115 | 115 |
} |
| 116 | 116 |
|
| 117 |
+// Build executes a build request |
|
| 117 | 118 |
func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder.Result, error) {
|
| 118 | 119 |
var rc = opt.Source |
| 119 | 120 |
|
| ... | ... |
@@ -181,10 +188,8 @@ func (b *Builder) Build(ctx context.Context, opt backend.BuildConfig) (*builder. |
| 181 | 181 |
frontendAttrs["context"] = url |
| 182 | 182 |
} |
| 183 | 183 |
|
| 184 |
- var cacheFrom []string |
|
| 185 |
- for _, v := range opt.Options.CacheFrom {
|
|
| 186 |
- cacheFrom = append(cacheFrom, v) |
|
| 187 |
- } |
|
| 184 |
+ cacheFrom := append([]string{}, opt.Options.CacheFrom...)
|
|
| 185 |
+ |
|
| 188 | 186 |
frontendAttrs["cache-from"] = strings.Join(cacheFrom, ",") |
| 189 | 187 |
|
| 190 | 188 |
for k, v := range opt.Options.BuildArgs {
|
| ... | ... |
@@ -117,7 +117,7 @@ func newController(rt http.RoundTripper, opt Opt) (*control.Controller, error) {
|
| 117 | 117 |
frontends["dockerfile.v0"] = dockerfile.NewDockerfileFrontend() |
| 118 | 118 |
frontends["gateway.v0"] = gateway.NewGatewayFrontend() |
| 119 | 119 |
|
| 120 |
- wopt := mobyworker.WorkerOpt{
|
|
| 120 |
+ wopt := mobyworker.Opt{
|
|
| 121 | 121 |
ID: "moby", |
| 122 | 122 |
SessionManager: opt.SessionManager, |
| 123 | 123 |
MetadataStore: md, |
| ... | ... |
@@ -19,10 +19,12 @@ const ( |
| 19 | 19 |
exporterImageConfig = "containerimage.config" |
| 20 | 20 |
) |
| 21 | 21 |
|
| 22 |
+// Differ can make a moby layer from a snapshot |
|
| 22 | 23 |
type Differ interface {
|
| 23 | 24 |
EnsureLayer(ctx context.Context, key string) ([]layer.DiffID, error) |
| 24 | 25 |
} |
| 25 | 26 |
|
| 27 |
+// Opt defines a struct for creating new exporter |
|
| 26 | 28 |
type Opt struct {
|
| 27 | 29 |
ImageStore image.Store |
| 28 | 30 |
ReferenceStore reference.Store |
| ... | ... |
@@ -33,6 +35,7 @@ type imageExporter struct {
|
| 33 | 33 |
opt Opt |
| 34 | 34 |
} |
| 35 | 35 |
|
| 36 |
+// New creates a new moby imagestore exporter |
|
| 36 | 37 |
func New(opt Opt) (exporter.Exporter, error) {
|
| 37 | 38 |
im := &imageExporter{opt: opt}
|
| 38 | 39 |
return im, nil |
| ... | ... |
@@ -49,9 +49,8 @@ func patchImageConfig(dt []byte, dps []digest.Digest, history []ocispec.History) |
| 49 | 49 |
|
| 50 | 50 |
var rootFS ocispec.RootFS |
| 51 | 51 |
rootFS.Type = "layers" |
| 52 |
- for _, dp := range dps {
|
|
| 53 |
- rootFS.DiffIDs = append(rootFS.DiffIDs, dp) |
|
| 54 |
- } |
|
| 52 |
+ rootFS.DiffIDs = append(rootFS.DiffIDs, dps...) |
|
| 53 |
+ |
|
| 55 | 54 |
dt, err := json.Marshal(rootFS) |
| 56 | 55 |
if err != nil {
|
| 57 | 56 |
return nil, errors.Wrap(err, "failed to marshal rootfs") |
| ... | ... |
@@ -87,7 +86,7 @@ func normalizeLayersAndHistory(diffs []digest.Digest, history []ocispec.History, |
| 87 | 87 |
var historyLayers int |
| 88 | 88 |
for _, h := range history {
|
| 89 | 89 |
if !h.EmptyLayer {
|
| 90 |
- historyLayers += 1 |
|
| 90 |
+ historyLayers++ |
|
| 91 | 91 |
} |
| 92 | 92 |
} |
| 93 | 93 |
if historyLayers > len(diffs) {
|
| ... | ... |
@@ -39,9 +39,8 @@ import ( |
| 39 | 39 |
"github.com/pkg/errors" |
| 40 | 40 |
) |
| 41 | 41 |
|
| 42 |
-// WorkerOpt is specific to a worker. |
|
| 43 |
-// See also CommonOpt. |
|
| 44 |
-type WorkerOpt struct {
|
|
| 42 |
+// Opt defines a structure for creating a worker. |
|
| 43 |
+type Opt struct {
|
|
| 45 | 44 |
ID string |
| 46 | 45 |
Labels map[string]string |
| 47 | 46 |
SessionManager *session.Manager |
| ... | ... |
@@ -60,12 +59,12 @@ type WorkerOpt struct {
|
| 60 | 60 |
// Worker is a local worker instance with dedicated snapshotter, cache, and so on. |
| 61 | 61 |
// TODO: s/Worker/OpWorker/g ? |
| 62 | 62 |
type Worker struct {
|
| 63 |
- WorkerOpt |
|
| 63 |
+ Opt |
|
| 64 | 64 |
SourceManager *source.Manager |
| 65 | 65 |
} |
| 66 | 66 |
|
| 67 | 67 |
// NewWorker instantiates a local worker |
| 68 |
-func NewWorker(opt WorkerOpt) (*Worker, error) {
|
|
| 68 |
+func NewWorker(opt Opt) (*Worker, error) {
|
|
| 69 | 69 |
sm, err := source.NewManager() |
| 70 | 70 |
if err != nil {
|
| 71 | 71 |
return nil, err |
| ... | ... |
@@ -106,23 +105,27 @@ func NewWorker(opt WorkerOpt) (*Worker, error) {
|
| 106 | 106 |
sm.Register(ss) |
| 107 | 107 |
|
| 108 | 108 |
return &Worker{
|
| 109 |
- WorkerOpt: opt, |
|
| 109 |
+ Opt: opt, |
|
| 110 | 110 |
SourceManager: sm, |
| 111 | 111 |
}, nil |
| 112 | 112 |
} |
| 113 | 113 |
|
| 114 |
+// ID returns worker ID |
|
| 114 | 115 |
func (w *Worker) ID() string {
|
| 115 |
- return w.WorkerOpt.ID |
|
| 116 |
+ return w.Opt.ID |
|
| 116 | 117 |
} |
| 117 | 118 |
|
| 119 |
+// Labels returns map of all worker labels |
|
| 118 | 120 |
func (w *Worker) Labels() map[string]string {
|
| 119 |
- return w.WorkerOpt.Labels |
|
| 121 |
+ return w.Opt.Labels |
|
| 120 | 122 |
} |
| 121 | 123 |
|
| 124 |
+// LoadRef loads a reference by ID |
|
| 122 | 125 |
func (w *Worker) LoadRef(id string) (cache.ImmutableRef, error) {
|
| 123 | 126 |
return w.CacheManager.Get(context.TODO(), id) |
| 124 | 127 |
} |
| 125 | 128 |
|
| 129 |
+// ResolveOp converts a LLB vertex into a LLB operation |
|
| 126 | 130 |
func (w *Worker) ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solver.Op, error) {
|
| 127 | 131 |
switch op := v.Sys().(type) {
|
| 128 | 132 |
case *pb.Op_Source: |
| ... | ... |
@@ -136,6 +139,7 @@ func (w *Worker) ResolveOp(v solver.Vertex, s frontend.FrontendLLBBridge) (solve |
| 136 | 136 |
} |
| 137 | 137 |
} |
| 138 | 138 |
|
| 139 |
+// ResolveImageConfig returns image config for an image |
|
| 139 | 140 |
func (w *Worker) ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) {
|
| 140 | 141 |
// ImageSource is typically source/containerimage |
| 141 | 142 |
resolveImageConfig, ok := w.ImageSource.(resolveImageConfig) |
| ... | ... |
@@ -145,10 +149,7 @@ func (w *Worker) ResolveImageConfig(ctx context.Context, ref string) (digest.Dig |
| 145 | 145 |
return resolveImageConfig.ResolveImageConfig(ctx, ref) |
| 146 | 146 |
} |
| 147 | 147 |
|
| 148 |
-type resolveImageConfig interface {
|
|
| 149 |
- ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
| 150 |
-} |
|
| 151 |
- |
|
| 148 |
+// Exec executes a process directly on a worker |
|
| 152 | 149 |
func (w *Worker) Exec(ctx context.Context, meta executor.Meta, rootFS cache.ImmutableRef, stdin io.ReadCloser, stdout, stderr io.WriteCloser) error {
|
| 153 | 150 |
active, err := w.CacheManager.New(ctx, rootFS) |
| 154 | 151 |
if err != nil {
|
| ... | ... |
@@ -158,14 +159,17 @@ func (w *Worker) Exec(ctx context.Context, meta executor.Meta, rootFS cache.Immu |
| 158 | 158 |
return w.Executor.Exec(ctx, meta, active, nil, stdin, stdout, stderr) |
| 159 | 159 |
} |
| 160 | 160 |
|
| 161 |
+// DiskUsage returns disk usage report |
|
| 161 | 162 |
func (w *Worker) DiskUsage(ctx context.Context, opt client.DiskUsageInfo) ([]*client.UsageInfo, error) {
|
| 162 | 163 |
return w.CacheManager.DiskUsage(ctx, opt) |
| 163 | 164 |
} |
| 164 | 165 |
|
| 166 |
+// Prune deletes reclaimable build cache |
|
| 165 | 167 |
func (w *Worker) Prune(ctx context.Context, ch chan client.UsageInfo) error {
|
| 166 | 168 |
return w.CacheManager.Prune(ctx, ch) |
| 167 | 169 |
} |
| 168 | 170 |
|
| 171 |
+// Exporter returns exporter by name |
|
| 169 | 172 |
func (w *Worker) Exporter(name string) (exporter.Exporter, error) {
|
| 170 | 173 |
exp, ok := w.Exporters[name] |
| 171 | 174 |
if !ok {
|
| ... | ... |
@@ -174,10 +178,12 @@ func (w *Worker) Exporter(name string) (exporter.Exporter, error) {
|
| 174 | 174 |
return exp, nil |
| 175 | 175 |
} |
| 176 | 176 |
|
| 177 |
+// GetRemote returns a remote snapshot reference for a local one |
|
| 177 | 178 |
func (w *Worker) GetRemote(ctx context.Context, ref cache.ImmutableRef, createIfNeeded bool) (*solver.Remote, error) {
|
| 178 | 179 |
return nil, errors.Errorf("getremote not implemented")
|
| 179 | 180 |
} |
| 180 | 181 |
|
| 182 |
+// FromRemote converts a remote snapshot reference to a local one |
|
| 181 | 183 |
func (w *Worker) FromRemote(ctx context.Context, remote *solver.Remote) (cache.ImmutableRef, error) {
|
| 182 | 184 |
rootfs, err := getLayers(ctx, remote.Descriptors) |
| 183 | 185 |
if err != nil {
|
| ... | ... |
@@ -219,7 +225,7 @@ func (w *Worker) FromRemote(ctx context.Context, remote *solver.Remote) (cache.I |
| 219 | 219 |
|
| 220 | 220 |
type discardProgress struct{}
|
| 221 | 221 |
|
| 222 |
-func (_ *discardProgress) WriteProgress(_ pkgprogress.Progress) error {
|
|
| 222 |
+func (*discardProgress) WriteProgress(_ pkgprogress.Progress) error {
|
|
| 223 | 223 |
return nil |
| 224 | 224 |
} |
| 225 | 225 |
|
| ... | ... |
@@ -309,3 +315,7 @@ func oneOffProgress(ctx context.Context, id string) func(err error) error {
|
| 309 | 309 |
return err |
| 310 | 310 |
} |
| 311 | 311 |
} |
| 312 |
+ |
|
| 313 |
+type resolveImageConfig interface {
|
|
| 314 |
+ ResolveImageConfig(ctx context.Context, ref string) (digest.Digest, []byte, error) |
|
| 315 |
+} |
| ... | ... |
@@ -922,6 +922,7 @@ func NewDaemon(config *config.Config, registryService registry.Service, containe |
| 922 | 922 |
return d, nil |
| 923 | 923 |
} |
| 924 | 924 |
|
| 925 |
+// DistributionServices returns services controlling daemon storage |
|
| 925 | 926 |
func (daemon *Daemon) DistributionServices() images.DistributionServices {
|
| 926 | 927 |
return daemon.imageService.DistributionServices() |
| 927 | 928 |
} |
| ... | ... |
@@ -76,6 +76,7 @@ type ImageService struct {
|
| 76 | 76 |
uploadManager *xfer.LayerUploadManager |
| 77 | 77 |
} |
| 78 | 78 |
|
| 79 |
+// DistributionServices provides daemon image storage services |
|
| 79 | 80 |
type DistributionServices struct {
|
| 80 | 81 |
DownloadManager distribution.RootFSDownloadManager |
| 81 | 82 |
V2MetadataService metadata.V2MetadataService |
| ... | ... |
@@ -84,6 +85,7 @@ type DistributionServices struct {
|
| 84 | 84 |
ReferenceStore dockerreference.Store |
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 |
+// DistributionServices return services controlling daemon image storage |
|
| 87 | 88 |
func (i *ImageService) DistributionServices() DistributionServices {
|
| 88 | 89 |
return DistributionServices{
|
| 89 | 90 |
DownloadManager: i.downloadManager, |