content.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package daemon
  2. import (
  3. "context"
  4. "os"
  5. "path/filepath"
  6. "github.com/containerd/containerd/content"
  7. "github.com/containerd/containerd/content/local"
  8. "github.com/containerd/containerd/leases"
  9. "github.com/containerd/containerd/metadata"
  10. "github.com/containerd/containerd/namespaces"
  11. "github.com/opencontainers/go-digest"
  12. ocispec "github.com/opencontainers/image-spec/specs-go/v1"
  13. "github.com/pkg/errors"
  14. "go.etcd.io/bbolt"
  15. )
  16. func (daemon *Daemon) configureLocalContentStore(ns string) (*namespacedContent, *namespacedLeases, error) {
  17. if err := os.MkdirAll(filepath.Join(daemon.root, "content"), 0o700); err != nil {
  18. return nil, nil, errors.Wrap(err, "error creating dir for content store")
  19. }
  20. db, err := bbolt.Open(filepath.Join(daemon.root, "content", "metadata.db"), 0o600, nil)
  21. if err != nil {
  22. return nil, nil, errors.Wrap(err, "error opening bolt db for content metadata store")
  23. }
  24. cs, err := local.NewStore(filepath.Join(daemon.root, "content", "data"))
  25. if err != nil {
  26. return nil, nil, errors.Wrap(err, "error setting up content store")
  27. }
  28. md := metadata.NewDB(db, cs, nil)
  29. daemon.mdDB = db
  30. cp := &namespacedContent{
  31. ns: ns,
  32. provider: md.ContentStore(),
  33. }
  34. lm := &namespacedLeases{
  35. ns: ns,
  36. manager: metadata.NewLeaseManager(md),
  37. }
  38. return cp, lm, nil
  39. }
  40. // withDefaultNamespace sets the given namespace on the context if the current
  41. // context doesn't hold any namespace
  42. func withDefaultNamespace(ctx context.Context, namespace string) context.Context {
  43. if _, ok := namespaces.Namespace(ctx); ok {
  44. return ctx
  45. }
  46. return namespaces.WithNamespace(ctx, namespace)
  47. }
  48. type namespacedContent struct {
  49. ns string
  50. provider content.Store
  51. }
  52. // Delete removes the content from the store.
  53. func (cp namespacedContent) Delete(ctx context.Context, dgst digest.Digest) error {
  54. return cp.provider.Delete(withDefaultNamespace(ctx, cp.ns), dgst)
  55. }
  56. // Info will return metadata about content available in the content store.
  57. //
  58. // If the content is not present, ErrNotFound will be returned.
  59. func (cp namespacedContent) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
  60. return cp.provider.Info(withDefaultNamespace(ctx, cp.ns), dgst)
  61. }
  62. // Update updates mutable information related to content.
  63. // If one or more fieldpaths are provided, only those
  64. // fields will be updated.
  65. // Mutable fields:
  66. //
  67. // labels.*
  68. func (cp namespacedContent) Update(ctx context.Context, info content.Info, fieldpaths ...string) (content.Info, error) {
  69. return cp.provider.Update(withDefaultNamespace(ctx, cp.ns), info, fieldpaths...)
  70. }
  71. // Walk will call fn for each item in the content store which
  72. // match the provided filters. If no filters are given all
  73. // items will be walked.
  74. func (cp namespacedContent) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error {
  75. return cp.provider.Walk(withDefaultNamespace(ctx, cp.ns), fn, filters...)
  76. }
  77. // Abort completely cancels the ingest operation targeted by ref.
  78. func (cp namespacedContent) Abort(ctx context.Context, ref string) error {
  79. return cp.provider.Abort(withDefaultNamespace(ctx, cp.ns), ref)
  80. }
  81. // ListStatuses returns the status of any active ingestions whose ref match the
  82. // provided regular expression. If empty, all active ingestions will be
  83. // returned.
  84. func (cp namespacedContent) ListStatuses(ctx context.Context, filters ...string) ([]content.Status, error) {
  85. return cp.provider.ListStatuses(withDefaultNamespace(ctx, cp.ns), filters...)
  86. }
  87. // Status returns the status of the provided ref.
  88. func (cp namespacedContent) Status(ctx context.Context, ref string) (content.Status, error) {
  89. return cp.provider.Status(withDefaultNamespace(ctx, cp.ns), ref)
  90. }
  91. // Some implementations require WithRef to be included in opts.
  92. func (cp namespacedContent) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
  93. return cp.provider.Writer(withDefaultNamespace(ctx, cp.ns), opts...)
  94. }
  95. // ReaderAt only requires desc.Digest to be set.
  96. // Other fields in the descriptor may be used internally for resolving
  97. // the location of the actual data.
  98. func (cp namespacedContent) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
  99. return cp.provider.ReaderAt(withDefaultNamespace(ctx, cp.ns), desc)
  100. }
  101. type namespacedLeases struct {
  102. ns string
  103. manager leases.Manager
  104. }
  105. // AddResource references the resource by the provided lease.
  106. func (nl namespacedLeases) AddResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error {
  107. return nl.manager.AddResource(withDefaultNamespace(ctx, nl.ns), lease, resource)
  108. }
  109. // Create creates a new lease using the provided lease
  110. func (nl namespacedLeases) Create(ctx context.Context, opt ...leases.Opt) (leases.Lease, error) {
  111. return nl.manager.Create(withDefaultNamespace(ctx, nl.ns), opt...)
  112. }
  113. // Delete deletes the lease with the provided lease ID
  114. func (nl namespacedLeases) Delete(ctx context.Context, lease leases.Lease, opt ...leases.DeleteOpt) error {
  115. return nl.manager.Delete(withDefaultNamespace(ctx, nl.ns), lease, opt...)
  116. }
  117. // DeleteResource dereferences the resource by the provided lease.
  118. func (nl namespacedLeases) DeleteResource(ctx context.Context, lease leases.Lease, resource leases.Resource) error {
  119. return nl.manager.DeleteResource(withDefaultNamespace(ctx, nl.ns), lease, resource)
  120. }
  121. // List lists all active leases
  122. func (nl namespacedLeases) List(ctx context.Context, filter ...string) ([]leases.Lease, error) {
  123. return nl.manager.List(withDefaultNamespace(ctx, nl.ns), filter...)
  124. }
  125. // ListResources lists all the resources referenced by the lease.
  126. func (nl namespacedLeases) ListResources(ctx context.Context, lease leases.Lease) ([]leases.Resource, error) {
  127. return nl.manager.ListResources(withDefaultNamespace(ctx, nl.ns), lease)
  128. }