github.com/adityamillind98/moby@v23.0.0-rc.4+incompatible/layer/layer_store.go (about) 1 package layer // import "github.com/docker/docker/layer" 2 3 import ( 4 "errors" 5 "fmt" 6 "io" 7 "os" 8 "path/filepath" 9 "sync" 10 11 "github.com/docker/distribution" 12 "github.com/docker/docker/daemon/graphdriver" 13 "github.com/docker/docker/pkg/idtools" 14 "github.com/docker/docker/pkg/plugingetter" 15 "github.com/docker/docker/pkg/stringid" 16 "github.com/moby/locker" 17 "github.com/opencontainers/go-digest" 18 "github.com/sirupsen/logrus" 19 "github.com/vbatts/tar-split/tar/asm" 20 "github.com/vbatts/tar-split/tar/storage" 21 ) 22 23 // maxLayerDepth represents the maximum number of 24 // layers which can be chained together. 125 was 25 // chosen to account for the 127 max in some 26 // graphdrivers plus the 2 additional layers 27 // used to create a rwlayer. 28 const maxLayerDepth = 125 29 30 type layerStore struct { 31 store *fileMetadataStore 32 driver graphdriver.Driver 33 useTarSplit bool 34 35 layerMap map[ChainID]*roLayer 36 layerL sync.Mutex 37 38 mounts map[string]*mountedLayer 39 mountL sync.Mutex 40 41 // protect *RWLayer() methods from operating on the same name/id 42 locker *locker.Locker 43 } 44 45 // StoreOptions are the options used to create a new Store instance 46 type StoreOptions struct { 47 Root string 48 MetadataStorePathTemplate string 49 GraphDriver string 50 GraphDriverOptions []string 51 IDMapping idtools.IdentityMapping 52 PluginGetter plugingetter.PluginGetter 53 ExperimentalEnabled bool 54 } 55 56 // NewStoreFromOptions creates a new Store instance 57 func NewStoreFromOptions(options StoreOptions) (Store, error) { 58 driver, err := graphdriver.New(options.GraphDriver, options.PluginGetter, graphdriver.Options{ 59 Root: options.Root, 60 DriverOptions: options.GraphDriverOptions, 61 IDMap: options.IDMapping, 62 ExperimentalEnabled: options.ExperimentalEnabled, 63 }) 64 if err != nil { 65 return nil, fmt.Errorf("error initializing graphdriver: %v", err) 66 } 67 logrus.Debugf("Initialized graph driver %s", driver) 68 69 root := fmt.Sprintf(options.MetadataStorePathTemplate, driver) 70 71 return newStoreFromGraphDriver(root, driver) 72 } 73 74 // newStoreFromGraphDriver creates a new Store instance using the provided 75 // metadata store and graph driver. The metadata store will be used to restore 76 // the Store. 77 func newStoreFromGraphDriver(root string, driver graphdriver.Driver) (Store, error) { 78 caps := graphdriver.Capabilities{} 79 if capDriver, ok := driver.(graphdriver.CapabilityDriver); ok { 80 caps = capDriver.Capabilities() 81 } 82 83 ms, err := newFSMetadataStore(root) 84 if err != nil { 85 return nil, err 86 } 87 88 ls := &layerStore{ 89 store: ms, 90 driver: driver, 91 layerMap: map[ChainID]*roLayer{}, 92 mounts: map[string]*mountedLayer{}, 93 locker: locker.New(), 94 useTarSplit: !caps.ReproducesExactDiffs, 95 } 96 97 ids, mounts, err := ms.List() 98 if err != nil { 99 return nil, err 100 } 101 102 for _, id := range ids { 103 l, err := ls.loadLayer(id) 104 if err != nil { 105 logrus.Debugf("Failed to load layer %s: %s", id, err) 106 continue 107 } 108 if l.parent != nil { 109 l.parent.referenceCount++ 110 } 111 } 112 113 for _, mount := range mounts { 114 if err := ls.loadMount(mount); err != nil { 115 logrus.Debugf("Failed to load mount %s: %s", mount, err) 116 } 117 } 118 119 return ls, nil 120 } 121 122 func (ls *layerStore) Driver() graphdriver.Driver { 123 return ls.driver 124 } 125 126 func (ls *layerStore) loadLayer(layer ChainID) (*roLayer, error) { 127 cl, ok := ls.layerMap[layer] 128 if ok { 129 return cl, nil 130 } 131 132 diff, err := ls.store.GetDiffID(layer) 133 if err != nil { 134 return nil, fmt.Errorf("failed to get diff id for %s: %s", layer, err) 135 } 136 137 size, err := ls.store.GetSize(layer) 138 if err != nil { 139 return nil, fmt.Errorf("failed to get size for %s: %s", layer, err) 140 } 141 142 cacheID, err := ls.store.GetCacheID(layer) 143 if err != nil { 144 return nil, fmt.Errorf("failed to get cache id for %s: %s", layer, err) 145 } 146 147 parent, err := ls.store.GetParent(layer) 148 if err != nil { 149 return nil, fmt.Errorf("failed to get parent for %s: %s", layer, err) 150 } 151 152 descriptor, err := ls.store.GetDescriptor(layer) 153 if err != nil { 154 return nil, fmt.Errorf("failed to get descriptor for %s: %s", layer, err) 155 } 156 157 cl = &roLayer{ 158 chainID: layer, 159 diffID: diff, 160 size: size, 161 cacheID: cacheID, 162 layerStore: ls, 163 references: map[Layer]struct{}{}, 164 descriptor: descriptor, 165 } 166 167 if parent != "" { 168 p, err := ls.loadLayer(parent) 169 if err != nil { 170 return nil, err 171 } 172 cl.parent = p 173 } 174 175 ls.layerMap[cl.chainID] = cl 176 177 return cl, nil 178 } 179 180 func (ls *layerStore) loadMount(mount string) error { 181 ls.mountL.Lock() 182 defer ls.mountL.Unlock() 183 if _, ok := ls.mounts[mount]; ok { 184 return nil 185 } 186 187 mountID, err := ls.store.GetMountID(mount) 188 if err != nil { 189 return err 190 } 191 192 initID, err := ls.store.GetInitID(mount) 193 if err != nil { 194 return err 195 } 196 197 parent, err := ls.store.GetMountParent(mount) 198 if err != nil { 199 return err 200 } 201 202 ml := &mountedLayer{ 203 name: mount, 204 mountID: mountID, 205 initID: initID, 206 layerStore: ls, 207 references: map[RWLayer]*referencedRWLayer{}, 208 } 209 210 if parent != "" { 211 p, err := ls.loadLayer(parent) 212 if err != nil { 213 return err 214 } 215 ml.parent = p 216 217 p.referenceCount++ 218 } 219 220 ls.mounts[ml.name] = ml 221 222 return nil 223 } 224 225 func (ls *layerStore) applyTar(tx *fileMetadataTransaction, ts io.Reader, parent string, layer *roLayer) error { 226 digester := digest.Canonical.Digester() 227 tr := io.TeeReader(ts, digester.Hash()) 228 229 rdr := tr 230 if ls.useTarSplit { 231 tsw, err := tx.TarSplitWriter(true) 232 if err != nil { 233 return err 234 } 235 metaPacker := storage.NewJSONPacker(tsw) 236 defer tsw.Close() 237 238 // we're passing nil here for the file putter, because the ApplyDiff will 239 // handle the extraction of the archive 240 rdr, err = asm.NewInputTarStream(tr, metaPacker, nil) 241 if err != nil { 242 return err 243 } 244 } 245 246 applySize, err := ls.driver.ApplyDiff(layer.cacheID, parent, rdr) 247 // discard trailing data but ensure metadata is picked up to reconstruct stream 248 // unconditionally call io.Copy here before checking err to ensure the resources 249 // allocated by NewInputTarStream above are always released 250 io.Copy(io.Discard, rdr) // ignore error as reader may be closed 251 if err != nil { 252 return err 253 } 254 255 layer.size = applySize 256 layer.diffID = DiffID(digester.Digest()) 257 258 logrus.Debugf("Applied tar %s to %s, size: %d", layer.diffID, layer.cacheID, applySize) 259 260 return nil 261 } 262 263 func (ls *layerStore) Register(ts io.Reader, parent ChainID) (Layer, error) { 264 return ls.registerWithDescriptor(ts, parent, distribution.Descriptor{}) 265 } 266 267 func (ls *layerStore) registerWithDescriptor(ts io.Reader, parent ChainID, descriptor distribution.Descriptor) (Layer, error) { 268 // err is used to hold the error which will always trigger 269 // cleanup of creates sources but may not be an error returned 270 // to the caller (already exists). 271 var err error 272 var pid string 273 var p *roLayer 274 275 if string(parent) != "" { 276 ls.layerL.Lock() 277 p = ls.get(parent) 278 ls.layerL.Unlock() 279 if p == nil { 280 return nil, ErrLayerDoesNotExist 281 } 282 pid = p.cacheID 283 // Release parent chain if error 284 defer func() { 285 if err != nil { 286 ls.layerL.Lock() 287 ls.releaseLayer(p) 288 ls.layerL.Unlock() 289 } 290 }() 291 if p.depth() >= maxLayerDepth { 292 err = ErrMaxDepthExceeded 293 return nil, err 294 } 295 } 296 297 // Create new roLayer 298 layer := &roLayer{ 299 parent: p, 300 cacheID: stringid.GenerateRandomID(), 301 referenceCount: 1, 302 layerStore: ls, 303 references: map[Layer]struct{}{}, 304 descriptor: descriptor, 305 } 306 307 if err = ls.driver.Create(layer.cacheID, pid, nil); err != nil { 308 return nil, err 309 } 310 311 tx, err := ls.store.StartTransaction() 312 if err != nil { 313 return nil, err 314 } 315 316 defer func() { 317 if err != nil { 318 logrus.Debugf("Cleaning up layer %s: %v", layer.cacheID, err) 319 if err := ls.driver.Remove(layer.cacheID); err != nil { 320 logrus.Errorf("Error cleaning up cache layer %s: %v", layer.cacheID, err) 321 } 322 if err := tx.Cancel(); err != nil { 323 logrus.Errorf("Error canceling metadata transaction %q: %s", tx.String(), err) 324 } 325 } 326 }() 327 328 if err = ls.applyTar(tx, ts, pid, layer); err != nil { 329 return nil, err 330 } 331 332 if layer.parent == nil { 333 layer.chainID = ChainID(layer.diffID) 334 } else { 335 layer.chainID = createChainIDFromParent(layer.parent.chainID, layer.diffID) 336 } 337 338 if err = storeLayer(tx, layer); err != nil { 339 return nil, err 340 } 341 342 ls.layerL.Lock() 343 defer ls.layerL.Unlock() 344 345 if existingLayer := ls.get(layer.chainID); existingLayer != nil { 346 // Set error for cleanup, but do not return the error 347 err = errors.New("layer already exists") 348 return existingLayer.getReference(), nil 349 } 350 351 if err = tx.Commit(layer.chainID); err != nil { 352 return nil, err 353 } 354 355 ls.layerMap[layer.chainID] = layer 356 357 return layer.getReference(), nil 358 } 359 360 func (ls *layerStore) get(layer ChainID) *roLayer { 361 l, ok := ls.layerMap[layer] 362 if !ok { 363 return nil 364 } 365 l.referenceCount++ 366 return l 367 } 368 369 func (ls *layerStore) Get(l ChainID) (Layer, error) { 370 ls.layerL.Lock() 371 defer ls.layerL.Unlock() 372 373 layer := ls.get(l) 374 if layer == nil { 375 return nil, ErrLayerDoesNotExist 376 } 377 378 return layer.getReference(), nil 379 } 380 381 func (ls *layerStore) Map() map[ChainID]Layer { 382 ls.layerL.Lock() 383 defer ls.layerL.Unlock() 384 385 layers := map[ChainID]Layer{} 386 387 for k, v := range ls.layerMap { 388 layers[k] = v 389 } 390 391 return layers 392 } 393 394 func (ls *layerStore) deleteLayer(layer *roLayer, metadata *Metadata) error { 395 // Rename layer digest folder first so we detect orphan layer(s) 396 // if ls.driver.Remove fails 397 var dir string 398 for { 399 dgst := digest.Digest(layer.chainID) 400 tmpID := fmt.Sprintf("%s-%s-removing", dgst.Encoded(), stringid.GenerateRandomID()) 401 dir = filepath.Join(ls.store.root, string(dgst.Algorithm()), tmpID) 402 err := os.Rename(ls.store.getLayerDirectory(layer.chainID), dir) 403 if os.IsExist(err) { 404 continue 405 } 406 break 407 } 408 err := ls.driver.Remove(layer.cacheID) 409 if err != nil { 410 return err 411 } 412 err = os.RemoveAll(dir) 413 if err != nil { 414 return err 415 } 416 metadata.DiffID = layer.diffID 417 metadata.ChainID = layer.chainID 418 metadata.Size = layer.Size() 419 if err != nil { 420 return err 421 } 422 metadata.DiffSize = layer.size 423 424 return nil 425 } 426 427 func (ls *layerStore) releaseLayer(l *roLayer) ([]Metadata, error) { 428 depth := 0 429 removed := []Metadata{} 430 for { 431 if l.referenceCount == 0 { 432 panic("layer not retained") 433 } 434 l.referenceCount-- 435 if l.referenceCount != 0 { 436 return removed, nil 437 } 438 439 if len(removed) == 0 && depth > 0 { 440 panic("cannot remove layer with child") 441 } 442 if l.hasReferences() { 443 panic("cannot delete referenced layer") 444 } 445 // Remove layer from layer map first so it is not considered to exist 446 // when if ls.deleteLayer fails. 447 delete(ls.layerMap, l.chainID) 448 449 var metadata Metadata 450 if err := ls.deleteLayer(l, &metadata); err != nil { 451 return nil, err 452 } 453 removed = append(removed, metadata) 454 455 if l.parent == nil { 456 return removed, nil 457 } 458 459 depth++ 460 l = l.parent 461 } 462 } 463 464 func (ls *layerStore) Release(l Layer) ([]Metadata, error) { 465 ls.layerL.Lock() 466 defer ls.layerL.Unlock() 467 layer, ok := ls.layerMap[l.ChainID()] 468 if !ok { 469 return []Metadata{}, nil 470 } 471 if !layer.hasReference(l) { 472 return nil, ErrLayerNotRetained 473 } 474 475 layer.deleteReference(l) 476 477 return ls.releaseLayer(layer) 478 } 479 480 func (ls *layerStore) CreateRWLayer(name string, parent ChainID, opts *CreateRWLayerOpts) (_ RWLayer, err error) { 481 var ( 482 storageOpt map[string]string 483 initFunc MountInit 484 mountLabel string 485 ) 486 487 if opts != nil { 488 mountLabel = opts.MountLabel 489 storageOpt = opts.StorageOpt 490 initFunc = opts.InitFunc 491 } 492 493 ls.locker.Lock(name) 494 defer ls.locker.Unlock(name) 495 496 ls.mountL.Lock() 497 _, ok := ls.mounts[name] 498 ls.mountL.Unlock() 499 if ok { 500 return nil, ErrMountNameConflict 501 } 502 503 var pid string 504 var p *roLayer 505 if string(parent) != "" { 506 ls.layerL.Lock() 507 p = ls.get(parent) 508 ls.layerL.Unlock() 509 if p == nil { 510 return nil, ErrLayerDoesNotExist 511 } 512 pid = p.cacheID 513 514 // Release parent chain if error 515 defer func() { 516 if err != nil { 517 ls.layerL.Lock() 518 ls.releaseLayer(p) 519 ls.layerL.Unlock() 520 } 521 }() 522 } 523 524 m := &mountedLayer{ 525 name: name, 526 parent: p, 527 mountID: ls.mountID(name), 528 layerStore: ls, 529 references: map[RWLayer]*referencedRWLayer{}, 530 } 531 532 if initFunc != nil { 533 pid, err = ls.initMount(m.mountID, pid, mountLabel, initFunc, storageOpt) 534 if err != nil { 535 return 536 } 537 m.initID = pid 538 } 539 540 createOpts := &graphdriver.CreateOpts{ 541 StorageOpt: storageOpt, 542 } 543 544 if err = ls.driver.CreateReadWrite(m.mountID, pid, createOpts); err != nil { 545 return 546 } 547 if err = ls.saveMount(m); err != nil { 548 return 549 } 550 551 return m.getReference(), nil 552 } 553 554 func (ls *layerStore) GetRWLayer(id string) (RWLayer, error) { 555 ls.locker.Lock(id) 556 defer ls.locker.Unlock(id) 557 558 ls.mountL.Lock() 559 mount := ls.mounts[id] 560 ls.mountL.Unlock() 561 if mount == nil { 562 return nil, ErrMountDoesNotExist 563 } 564 565 return mount.getReference(), nil 566 } 567 568 func (ls *layerStore) GetMountID(id string) (string, error) { 569 ls.mountL.Lock() 570 mount := ls.mounts[id] 571 ls.mountL.Unlock() 572 573 if mount == nil { 574 return "", ErrMountDoesNotExist 575 } 576 logrus.Debugf("GetMountID id: %s -> mountID: %s", id, mount.mountID) 577 578 return mount.mountID, nil 579 } 580 581 func (ls *layerStore) ReleaseRWLayer(l RWLayer) ([]Metadata, error) { 582 name := l.Name() 583 ls.locker.Lock(name) 584 defer ls.locker.Unlock(name) 585 586 ls.mountL.Lock() 587 m := ls.mounts[name] 588 ls.mountL.Unlock() 589 if m == nil { 590 return []Metadata{}, nil 591 } 592 593 if err := m.deleteReference(l); err != nil { 594 return nil, err 595 } 596 597 if m.hasReferences() { 598 return []Metadata{}, nil 599 } 600 601 if err := ls.driver.Remove(m.mountID); err != nil { 602 logrus.Errorf("Error removing mounted layer %s: %s", m.name, err) 603 m.retakeReference(l) 604 return nil, err 605 } 606 607 if m.initID != "" { 608 if err := ls.driver.Remove(m.initID); err != nil { 609 logrus.Errorf("Error removing init layer %s: %s", m.name, err) 610 m.retakeReference(l) 611 return nil, err 612 } 613 } 614 615 if err := ls.store.RemoveMount(m.name); err != nil { 616 logrus.Errorf("Error removing mount metadata: %s: %s", m.name, err) 617 m.retakeReference(l) 618 return nil, err 619 } 620 621 ls.mountL.Lock() 622 delete(ls.mounts, name) 623 ls.mountL.Unlock() 624 625 ls.layerL.Lock() 626 defer ls.layerL.Unlock() 627 if m.parent != nil { 628 return ls.releaseLayer(m.parent) 629 } 630 631 return []Metadata{}, nil 632 } 633 634 func (ls *layerStore) saveMount(mount *mountedLayer) error { 635 if err := ls.store.SetMountID(mount.name, mount.mountID); err != nil { 636 return err 637 } 638 639 if mount.initID != "" { 640 if err := ls.store.SetInitID(mount.name, mount.initID); err != nil { 641 return err 642 } 643 } 644 645 if mount.parent != nil { 646 if err := ls.store.SetMountParent(mount.name, mount.parent.chainID); err != nil { 647 return err 648 } 649 } 650 651 ls.mountL.Lock() 652 ls.mounts[mount.name] = mount 653 ls.mountL.Unlock() 654 655 return nil 656 } 657 658 func (ls *layerStore) initMount(graphID, parent, mountLabel string, initFunc MountInit, storageOpt map[string]string) (string, error) { 659 // Use "<graph-id>-init" to maintain compatibility with graph drivers 660 // which are expecting this layer with this special name. If all 661 // graph drivers can be updated to not rely on knowing about this layer 662 // then the initID should be randomly generated. 663 initID := fmt.Sprintf("%s-init", graphID) 664 665 createOpts := &graphdriver.CreateOpts{ 666 MountLabel: mountLabel, 667 StorageOpt: storageOpt, 668 } 669 670 if err := ls.driver.CreateReadWrite(initID, parent, createOpts); err != nil { 671 return "", err 672 } 673 p, err := ls.driver.Get(initID, "") 674 if err != nil { 675 return "", err 676 } 677 678 if err := initFunc(p); err != nil { 679 ls.driver.Put(initID) 680 return "", err 681 } 682 683 if err := ls.driver.Put(initID); err != nil { 684 return "", err 685 } 686 687 return initID, nil 688 } 689 690 func (ls *layerStore) getTarStream(rl *roLayer) (io.ReadCloser, error) { 691 if !ls.useTarSplit { 692 var parentCacheID string 693 if rl.parent != nil { 694 parentCacheID = rl.parent.cacheID 695 } 696 697 return ls.driver.Diff(rl.cacheID, parentCacheID) 698 } 699 700 r, err := ls.store.TarSplitReader(rl.chainID) 701 if err != nil { 702 return nil, err 703 } 704 705 pr, pw := io.Pipe() 706 go func() { 707 err := ls.assembleTarTo(rl.cacheID, r, nil, pw) 708 if err != nil { 709 pw.CloseWithError(err) 710 } else { 711 pw.Close() 712 } 713 }() 714 715 return pr, nil 716 } 717 718 func (ls *layerStore) assembleTarTo(graphID string, metadata io.ReadCloser, size *int64, w io.Writer) error { 719 diffDriver, ok := ls.driver.(graphdriver.DiffGetterDriver) 720 if !ok { 721 diffDriver = &naiveDiffPathDriver{ls.driver} 722 } 723 724 defer metadata.Close() 725 726 // get our relative path to the container 727 fileGetCloser, err := diffDriver.DiffGetter(graphID) 728 if err != nil { 729 return err 730 } 731 defer fileGetCloser.Close() 732 733 metaUnpacker := storage.NewJSONUnpacker(metadata) 734 upackerCounter := &unpackSizeCounter{metaUnpacker, size} 735 logrus.Debugf("Assembling tar data for %s", graphID) 736 return asm.WriteOutputTarStream(fileGetCloser, upackerCounter, w) 737 } 738 739 func (ls *layerStore) Cleanup() error { 740 orphanLayers, err := ls.store.getOrphan() 741 if err != nil { 742 logrus.WithError(err).Error("cannot get orphan layers") 743 } 744 if len(orphanLayers) > 0 { 745 logrus.Debugf("found %v orphan layers", len(orphanLayers)) 746 } 747 for _, orphan := range orphanLayers { 748 logrus.WithField("cache-id", orphan.cacheID).Debugf("removing orphan layer, chain ID: %v", orphan.chainID) 749 err = ls.driver.Remove(orphan.cacheID) 750 if err != nil && !os.IsNotExist(err) { 751 logrus.WithError(err).WithField("cache-id", orphan.cacheID).Error("cannot remove orphan layer") 752 continue 753 } 754 err = ls.store.Remove(orphan.chainID, orphan.cacheID) 755 if err != nil { 756 logrus.WithError(err).WithField("chain-id", orphan.chainID).Error("cannot remove orphan layer metadata") 757 } 758 } 759 return ls.driver.Cleanup() 760 } 761 762 func (ls *layerStore) DriverStatus() [][2]string { 763 return ls.driver.Status() 764 } 765 766 func (ls *layerStore) DriverName() string { 767 return ls.driver.String() 768 } 769 770 type naiveDiffPathDriver struct { 771 graphdriver.Driver 772 } 773 774 type fileGetPutter struct { 775 storage.FileGetter 776 driver graphdriver.Driver 777 id string 778 } 779 780 func (w *fileGetPutter) Close() error { 781 return w.driver.Put(w.id) 782 } 783 784 func (n *naiveDiffPathDriver) DiffGetter(id string) (graphdriver.FileGetCloser, error) { 785 p, err := n.Driver.Get(id, "") 786 if err != nil { 787 return nil, err 788 } 789 return &fileGetPutter{storage.NewPathFileGetter(p.Path()), n.Driver, id}, nil 790 }