github.com/moby/docker@v26.1.3+incompatible/daemon/content.go (about)

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