diff --git a/cmd/registry/config-torrent.yml b/cmd/registry/config-torrent.yml new file mode 100644 index 00000000..215b4288 --- /dev/null +++ b/cmd/registry/config-torrent.yml @@ -0,0 +1,20 @@ +version: 0.1 +log: + fields: + service: registry +storage: + cache: + blobdescriptor: inmemory + torrent: + rootdirectory: /var/lib/registry +http: + addr: :5000 + headers: + X-Content-Type-Options: [nosniff] +auth: + absent +health: + storagedriver: + enabled: true + interval: 10s + threshold: 3 diff --git a/cmd/registry/main.go b/cmd/registry/main.go index 09a09260..170a965b 100644 --- a/cmd/registry/main.go +++ b/cmd/registry/main.go @@ -4,6 +4,7 @@ import ( _ "net/http/pprof" "github.com/distribution/distribution/v3/registry" + _ "github.com/distribution/distribution/v3/registry/auth/absent" _ "github.com/distribution/distribution/v3/registry/auth/htpasswd" _ "github.com/distribution/distribution/v3/registry/auth/silly" _ "github.com/distribution/distribution/v3/registry/auth/token" @@ -17,6 +18,7 @@ import ( _ "github.com/distribution/distribution/v3/registry/storage/driver/middleware/redirect" _ "github.com/distribution/distribution/v3/registry/storage/driver/oss" _ "github.com/distribution/distribution/v3/registry/storage/driver/s3-aws" + _ "github.com/distribution/distribution/v3/registry/storage/driver/swarm" _ "github.com/distribution/distribution/v3/registry/storage/driver/swift" ) diff --git a/registry/auth/absent/access.go b/registry/auth/absent/access.go new file mode 100644 index 00000000..826cb78c --- /dev/null +++ b/registry/auth/absent/access.go @@ -0,0 +1,35 @@ +package auth + +import ( + "context" + + "github.com/distribution/distribution/v3/registry/auth" +) + +type accessController struct{} + +var _ auth.AccessController = &accessController{} + +// Authorized returns a non-nil error if the context is granted access and +// returns a new authorized context. If one or more Access structs are +// provided, the requested access will be compared with what is available +// to the context. The given context will contain a "http.request" key with +// a `*http.Request` value. If the error is non-nil, access should always +// be denied. The error may be of type Challenge, in which case the caller +// may have the Challenge handle the request or choose what action to take +// based on the Challenge header or response status. The returned context +// object should have a "auth.user" value set to a UserInfo struct. +func (a *accessController) Authorized(ctx context.Context, access ...auth.Access) (context.Context, error) { + return context.WithValue(ctx, "auth.user", &auth.UserInfo{Name: "leet hax0r"}), nil +} + +func newAccessController(options map[string]interface{}) (*accessController, error) { + return &accessController{}, nil +} + +func init() { + f := func(options map[string]interface{}) (auth.AccessController, error) { + return newAccessController(options) + } + auth.Register("absent", auth.InitFunc(f)) +} diff --git a/registry/storage/driver/swarm/driver.go b/registry/storage/driver/swarm/driver.go new file mode 100644 index 00000000..8de5ba74 --- /dev/null +++ b/registry/storage/driver/swarm/driver.go @@ -0,0 +1,106 @@ +package swarm + +import ( + "context" + "io" + + "github.com/distribution/distribution/v3/registry/storage/driver" + "github.com/distribution/distribution/v3/registry/storage/driver/factory" +) + +const driverName = "torrent" + +func init() { + factory.Register(driverName, &torrentDriverFactory{}) +} + +// torrentDriverFactory implements the factory.StorageDriverFactory interface. +type torrentDriverFactory struct{} + +var _ factory.StorageDriverFactory = (*torrentDriverFactory)(nil) + +func (f *torrentDriverFactory) Create(map[string]interface{}) (driver.StorageDriver, error) { + return New(), nil +} + +// torrentDriver implements the driver.StorageDriver interface +type torrentDriver struct{} + +var _ driver.StorageDriver = (*torrentDriver)(nil) + +func New() *torrentDriver { + return &torrentDriver{} +} + +// Name returns the human-readable "name" of the driver, useful in error +// messages and logging. By convention, this will just be the registration +// name, but drivers may provide other information here. +func (t *torrentDriver) Name() string { + return driverName +} + +func (t *torrentDriver) Delete(ctx context.Context, path string) error { + return nil +} + +// GetContent retrieves the content stored at "path" as a []byte. +// This should primarily be used for small objects. +func (t *torrentDriver) GetContent(ctx context.Context, path string) ([]byte, error) { + panic("not implemented") // TODO: Implement +} + +// PutContent stores the []byte content at a location designated by "path". +// This should primarily be used for small objects. +func (t *torrentDriver) PutContent(ctx context.Context, path string, content []byte) error { + panic("not implemented") // TODO: Implement +} + +// Reader retrieves an io.ReadCloser for the content stored at "path" +// with a given byte offset. +// May be used to resume reading a stream by providing a nonzero offset. +func (t *torrentDriver) Reader(ctx context.Context, path string, offset int64) (io.ReadCloser, error) { + panic("not implemented") // TODO: Implement +} + +// Writer returns a FileWriter which will store the content written to it +// at the location designated by "path" after the call to Commit. +func (t *torrentDriver) Writer(ctx context.Context, path string, append bool) (driver.FileWriter, error) { + panic("not implemented") // TODO: Implement +} + +// Stat retrieves the FileInfo for the given path, including the current +// size in bytes and the creation time. +func (t *torrentDriver) Stat(ctx context.Context, path string) (driver.FileInfo, error) { + return &swarmFile{}, nil +} + +// List returns a list of the objects that are direct descendants of the +// given path. +func (t *torrentDriver) List(ctx context.Context, path string) ([]string, error) { + panic("not implemented") // TODO: Implement +} + +// Move moves an object stored at sourcePath to destPath, removing the +// original object. +// Note: This may be no more efficient than a copy followed by a delete for +// many implementations. +func (t *torrentDriver) Move(ctx context.Context, sourcePath string, destPath string) error { + panic("not implemented") // TODO: Implement +} + +// URLFor returns a URL which may be used to retrieve the content stored at +// the given path, possibly using the given options. +// May return an ErrUnsupportedMethod in certain StorageDriver +// implementations. +func (t *torrentDriver) URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error) { + panic("not implemented") // TODO: Implement +} + +// Walk traverses a filesystem defined within driver, starting +// from the given path, calling f on each file. +// If the returned error from the WalkFn is ErrSkipDir and fileInfo refers +// to a directory, the directory will not be entered and Walk +// will continue the traversal. If fileInfo refers to a normal file, processing stops +func (t *torrentDriver) Walk(ctx context.Context, path string, f driver.WalkFn) error { + panic("not implemented") // TODO: Implement +} diff --git a/registry/storage/driver/swarm/file.go b/registry/storage/driver/swarm/file.go new file mode 100644 index 00000000..4c856e1a --- /dev/null +++ b/registry/storage/driver/swarm/file.go @@ -0,0 +1,28 @@ +package swarm + +import "time" + +type swarmFile struct{} + +// Path provides the full path of the target of this file info. +func (f *swarmFile) Path() string { + return "" +} + +// Size returns current length in bytes of the file. The return value can +// be used to write to the end of the file at path. The value is +// meaningless if IsDir returns true. +func (f *swarmFile) Size() int64 { + return 0 +} + +// ModTime returns the modification time for the file. For backends that +// don't have a modification time, the creation time should be returned. +func (f *swarmFile) ModTime() time.Time { + return time.Now() +} + +// IsDir returns true if the path is a directory. +func (f *swarmFile) IsDir() bool { + return false +}