github.com/rawahars/moby@v24.0.4+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) (content.Store, leases.Manager, error) {
    20  	if err := os.MkdirAll(filepath.Join(daemon.root, "content"), 0700); 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"), 0600, 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  	return namespacedContentProvider(md.ContentStore(), ns), namespacedLeaseManager(metadata.NewLeaseManager(md), ns), nil
    34  }
    35  
    36  // withDefaultNamespace sets the given namespace on the context if the current
    37  // context doesn't hold any namespace
    38  func withDefaultNamespace(ctx context.Context, namespace string) context.Context {
    39  	if _, ok := namespaces.Namespace(ctx); ok {
    40  		return ctx
    41  	}
    42  	return namespaces.WithNamespace(ctx, namespace)
    43  }
    44  
    45  type namespacedContent struct {
    46  	ns       string
    47  	provider content.Store
    48  }
    49  
    50  // Delete removes the content from the store.
    51  func (cp namespacedContent) Delete(ctx context.Context, dgst digest.Digest) error {
    52  	return cp.provider.Delete(withDefaultNamespace(ctx, cp.ns), dgst)
    53  }
    54  
    55  // Info will return metadata about content available in the content store.
    56  //
    57  // If the content is not present, ErrNotFound will be returned.
    58  func (cp namespacedContent) Info(ctx context.Context, dgst digest.Digest) (content.Info, error) {
    59  	return cp.provider.Info(withDefaultNamespace(ctx, cp.ns), dgst)
    60  }
    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  
    72  // Walk will call fn for each item in the content store which
    73  // match the provided filters. If no filters are given all
    74  // items will be walked.
    75  func (cp namespacedContent) Walk(ctx context.Context, fn content.WalkFunc, filters ...string) error {
    76  	return cp.provider.Walk(withDefaultNamespace(ctx, cp.ns), fn, filters...)
    77  }
    78  
    79  // Abort completely cancels the ingest operation targeted by ref.
    80  func (cp namespacedContent) Abort(ctx context.Context, ref string) error {
    81  	return cp.provider.Abort(withDefaultNamespace(ctx, cp.ns), ref)
    82  }
    83  
    84  // ListStatuses returns the status of any active ingestions whose ref match the
    85  // provided regular expression. If empty, all active ingestions will be
    86  // returned.
    87  func (cp namespacedContent) ListStatuses(ctx context.Context, filters ...string) ([]content.Status, error) {
    88  	return cp.provider.ListStatuses(withDefaultNamespace(ctx, cp.ns), filters...)
    89  }
    90  
    91  // Status returns the status of the provided ref.
    92  func (cp namespacedContent) Status(ctx context.Context, ref string) (content.Status, error) {
    93  	return cp.provider.Status(withDefaultNamespace(ctx, cp.ns), ref)
    94  }
    95  
    96  // Some implementations require WithRef to be included in opts.
    97  func (cp namespacedContent) Writer(ctx context.Context, opts ...content.WriterOpt) (content.Writer, error) {
    98  	return cp.provider.Writer(withDefaultNamespace(ctx, cp.ns), opts...)
    99  }
   100  
   101  // ReaderAt only requires desc.Digest to be set.
   102  // Other fields in the descriptor may be used internally for resolving
   103  // the location of the actual data.
   104  func (cp namespacedContent) ReaderAt(ctx context.Context, desc ocispec.Descriptor) (content.ReaderAt, error) {
   105  	return cp.provider.ReaderAt(withDefaultNamespace(ctx, cp.ns), desc)
   106  }
   107  
   108  // namespacedContentProvider sets the namespace if missing before calling the inner provider
   109  func namespacedContentProvider(provider content.Store, ns string) content.Store {
   110  	return namespacedContent{
   111  		ns,
   112  		provider,
   113  	}
   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  }
   150  
   151  // namespacedLeaseManager sets the namespace if missing before calling the inner manager
   152  func namespacedLeaseManager(manager leases.Manager, ns string) leases.Manager {
   153  	return namespacedLeases{
   154  		ns,
   155  		manager,
   156  	}
   157  }