github.com/dean7474/operator-registry@v1.21.1-0.20220418203638-d4717f98c2e5/pkg/image/containerdregistry/options.go (about)

     1  package containerdregistry
     2  
     3  import (
     4  	"crypto/x509"
     5  	"os"
     6  	"path/filepath"
     7  	"sync"
     8  
     9  	contentlocal "github.com/containerd/containerd/content/local"
    10  	"github.com/containerd/containerd/metadata"
    11  	"github.com/containerd/containerd/platforms"
    12  	"github.com/containerd/containerd/remotes"
    13  	specs "github.com/opencontainers/image-spec/specs-go/v1"
    14  	"github.com/sirupsen/logrus"
    15  	bolt "go.etcd.io/bbolt"
    16  )
    17  
    18  type RegistryConfig struct {
    19  	Log               *logrus.Entry
    20  	ResolverConfigDir string
    21  	DBPath            string
    22  	CacheDir          string
    23  	PreserveCache     bool
    24  	SkipTLSVerify     bool
    25  	PlainHTTP         bool
    26  	Roots             *x509.CertPool
    27  }
    28  
    29  func (r *RegistryConfig) apply(options []RegistryOption) {
    30  	for _, option := range options {
    31  		option(r)
    32  	}
    33  }
    34  
    35  func (r *RegistryConfig) complete() error {
    36  	if err := os.Mkdir(r.CacheDir, os.ModePerm); err != nil && !os.IsExist(err) {
    37  		return err
    38  	}
    39  
    40  	if r.DBPath == "" {
    41  		r.DBPath = filepath.Join(r.CacheDir, "metadata.db")
    42  	}
    43  
    44  	return nil
    45  }
    46  
    47  func defaultConfig() *RegistryConfig {
    48  	config := &RegistryConfig{
    49  		Log:               logrus.NewEntry(logrus.New()),
    50  		ResolverConfigDir: "",
    51  		CacheDir:          "cache",
    52  	}
    53  
    54  	return config
    55  }
    56  
    57  // NewRegistry returns a new containerd Registry and a function to destroy it after use.
    58  // The destroy function is safe to call more than once, but is a no-op after the first call.
    59  func NewRegistry(options ...RegistryOption) (registry *Registry, err error) {
    60  	config := defaultConfig()
    61  	config.apply(options)
    62  	if err = config.complete(); err != nil {
    63  		return
    64  	}
    65  
    66  	cs, err := contentlocal.NewStore(config.CacheDir)
    67  	if err != nil {
    68  		return
    69  	}
    70  
    71  	var bdb *bolt.DB
    72  	bdb, err = bolt.Open(config.DBPath, 0644, nil)
    73  	if err != nil {
    74  		return
    75  	}
    76  
    77  	var once sync.Once
    78  	destroy := func() (destroyErr error) {
    79  		once.Do(func() {
    80  			if destroyErr = bdb.Close(); destroyErr != nil {
    81  				return
    82  			}
    83  			if config.PreserveCache {
    84  				return
    85  			}
    86  
    87  			destroyErr = os.RemoveAll(config.CacheDir)
    88  		})
    89  
    90  		return
    91  	}
    92  
    93  	var resolver remotes.Resolver
    94  	resolver, err = NewResolver(config.ResolverConfigDir, config.SkipTLSVerify, config.PlainHTTP, config.Roots)
    95  	if err != nil {
    96  		return
    97  	}
    98  
    99  	registry = &Registry{
   100  		Store:    newStore(metadata.NewDB(bdb, cs, nil)),
   101  		destroy:  destroy,
   102  		log:      config.Log,
   103  		resolver: resolver,
   104  		platform: platforms.Ordered(platforms.DefaultSpec(), specs.Platform{
   105  			OS:           "linux",
   106  			Architecture: "amd64",
   107  		}),
   108  	}
   109  	return
   110  }
   111  
   112  type RegistryOption func(config *RegistryConfig)
   113  
   114  func WithLog(log *logrus.Entry) RegistryOption {
   115  	return func(config *RegistryConfig) {
   116  		config.Log = log
   117  	}
   118  }
   119  
   120  func WithResolverConfigDir(path string) RegistryOption {
   121  	return func(config *RegistryConfig) {
   122  		config.ResolverConfigDir = path
   123  	}
   124  }
   125  
   126  func WithCacheDir(dir string) RegistryOption {
   127  	return func(config *RegistryConfig) {
   128  		config.CacheDir = dir
   129  	}
   130  }
   131  
   132  func WithRootCAs(pool *x509.CertPool) RegistryOption {
   133  	return func(config *RegistryConfig) {
   134  		config.Roots = pool
   135  	}
   136  }
   137  
   138  func PreserveCache(preserve bool) RegistryOption {
   139  	return func(config *RegistryConfig) {
   140  		config.PreserveCache = preserve
   141  	}
   142  }
   143  
   144  func SkipTLSVerify(skip bool) RegistryOption {
   145  	return func(config *RegistryConfig) {
   146  		config.SkipTLSVerify = skip
   147  	}
   148  }
   149  
   150  func WithPlainHTTP(insecure bool) RegistryOption {
   151  	return func(config *RegistryConfig) {
   152  		config.PlainHTTP = insecure
   153  	}
   154  }