2015-02-11 03:14:23 +01:00
|
|
|
package driver
|
2014-10-22 00:02:20 +02:00
|
|
|
|
|
|
|
import (
|
2017-08-12 00:31:16 +02:00
|
|
|
"context"
|
2014-10-22 00:02:20 +02:00
|
|
|
"fmt"
|
|
|
|
"io"
|
2014-12-11 23:11:47 +01:00
|
|
|
"regexp"
|
2014-11-06 21:16:14 +01:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2014-10-22 00:02:20 +02:00
|
|
|
)
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// Version is a string representing the storage driver version, of the form
|
|
|
|
// Major.Minor.
|
|
|
|
// The registry must accept storage drivers with equal major version and greater
|
|
|
|
// minor version, but may not be compatible with older storage driver versions.
|
2014-11-06 21:16:14 +01:00
|
|
|
type Version string
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// Major returns the major (primary) component of a version.
|
2014-11-06 21:16:14 +01:00
|
|
|
func (version Version) Major() uint {
|
|
|
|
majorPart := strings.Split(string(version), ".")[0]
|
|
|
|
major, _ := strconv.ParseUint(majorPart, 10, 0)
|
|
|
|
return uint(major)
|
|
|
|
}
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// Minor returns the minor (secondary) component of a version.
|
2014-11-06 21:16:14 +01:00
|
|
|
func (version Version) Minor() uint {
|
|
|
|
minorPart := strings.Split(string(version), ".")[1]
|
|
|
|
minor, _ := strconv.ParseUint(minorPart, 10, 0)
|
|
|
|
return uint(minor)
|
|
|
|
}
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// CurrentVersion is the current storage driver Version.
|
2014-11-06 21:16:14 +01:00
|
|
|
const CurrentVersion Version = "0.1"
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// StorageDriver defines methods that a Storage Driver must implement for a
|
2016-03-19 00:28:42 +01:00
|
|
|
// filesystem-like key/value object storage. Storage Drivers are automatically
|
|
|
|
// registered via an internal registration mechanism, and generally created
|
2020-08-24 13:18:39 +02:00
|
|
|
// via the StorageDriverFactory interface (https://godoc.org/github.com/distribution/distribution/registry/storage/driver/factory).
|
2016-03-24 17:35:04 +01:00
|
|
|
// Please see the aforementioned factory package for example code showing how to get an instance
|
|
|
|
// of a StorageDriver
|
2014-10-22 00:02:20 +02:00
|
|
|
type StorageDriver interface {
|
2015-04-23 02:30:01 +02:00
|
|
|
// 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.
|
|
|
|
Name() string
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// GetContent retrieves the content stored at "path" as a []byte.
|
|
|
|
// This should primarily be used for small objects.
|
2015-04-28 00:58:58 +02:00
|
|
|
GetContent(ctx context.Context, path string) ([]byte, error)
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// PutContent stores the []byte content at a location designated by "path".
|
|
|
|
// This should primarily be used for small objects.
|
2015-04-28 00:58:58 +02:00
|
|
|
PutContent(ctx context.Context, path string, content []byte) error
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2016-02-08 23:29:21 +01:00
|
|
|
// Reader retrieves an io.ReadCloser for the content stored at "path"
|
2014-11-18 00:44:07 +01:00
|
|
|
// with a given byte offset.
|
|
|
|
// May be used to resume reading a stream by providing a nonzero offset.
|
2016-02-08 23:29:21 +01:00
|
|
|
Reader(ctx context.Context, path string, offset int64) (io.ReadCloser, error)
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2016-02-08 23:29:21 +01:00
|
|
|
// Writer returns a FileWriter which will store the content written to it
|
|
|
|
// at the location designated by "path" after the call to Commit.
|
|
|
|
Writer(ctx context.Context, path string, append bool) (FileWriter, error)
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2014-12-03 06:00:42 +01:00
|
|
|
// Stat retrieves the FileInfo for the given path, including the current
|
|
|
|
// size in bytes and the creation time.
|
2015-04-28 00:58:58 +02:00
|
|
|
Stat(ctx context.Context, path string) (FileInfo, error)
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// List returns a list of the objects that are direct descendants of the
|
|
|
|
//given path.
|
2015-04-28 00:58:58 +02:00
|
|
|
List(ctx context.Context, path string) ([]string, error)
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// 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.
|
2015-04-28 00:58:58 +02:00
|
|
|
Move(ctx context.Context, sourcePath string, destPath string) error
|
2014-10-29 02:15:40 +01:00
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// Delete recursively deletes all objects stored at "path" and its subpaths.
|
2015-04-28 00:58:58 +02:00
|
|
|
Delete(ctx context.Context, path string) error
|
2015-01-07 17:31:38 +01:00
|
|
|
|
2015-01-09 02:10:32 +01:00
|
|
|
// URLFor returns a URL which may be used to retrieve the content stored at
|
|
|
|
// the given path, possibly using the given options.
|
2015-03-13 03:31:41 +01:00
|
|
|
// May return an ErrUnsupportedMethod in certain StorageDriver
|
2015-01-09 02:10:32 +01:00
|
|
|
// implementations.
|
2015-04-28 00:58:58 +02:00
|
|
|
URLFor(ctx context.Context, path string, options map[string]interface{}) (string, error)
|
2017-11-29 20:17:39 +01:00
|
|
|
|
|
|
|
// 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
|
|
|
|
Walk(ctx context.Context, path string, f WalkFn) error
|
2014-10-22 00:02:20 +02:00
|
|
|
}
|
|
|
|
|
2016-02-08 23:29:21 +01:00
|
|
|
// FileWriter provides an abstraction for an opened writable file-like object in
|
|
|
|
// the storage backend. The FileWriter must flush all content written to it on
|
|
|
|
// the call to Close, but is only required to make its content readable on a
|
|
|
|
// call to Commit.
|
|
|
|
type FileWriter interface {
|
|
|
|
io.WriteCloser
|
|
|
|
|
|
|
|
// Size returns the number of bytes written to this FileWriter.
|
|
|
|
Size() int64
|
|
|
|
|
|
|
|
// Cancel removes any written content from this FileWriter.
|
|
|
|
Cancel() error
|
|
|
|
|
|
|
|
// Commit flushes all content written to this FileWriter and makes it
|
|
|
|
// available for future calls to StorageDriver.GetContent and
|
|
|
|
// StorageDriver.Reader.
|
|
|
|
Commit() error
|
|
|
|
}
|
|
|
|
|
2015-02-02 22:17:33 +01:00
|
|
|
// PathRegexp is the regular expression which each file path must match. A
|
|
|
|
// file path is absolute, beginning with a slash and containing a positive
|
|
|
|
// number of path components separated by slashes, where each component is
|
2015-12-04 20:12:32 +01:00
|
|
|
// restricted to alphanumeric characters or a period, underscore, or
|
2015-02-02 22:17:33 +01:00
|
|
|
// hyphen.
|
2015-04-07 23:14:45 +02:00
|
|
|
var PathRegexp = regexp.MustCompile(`^(/[A-Za-z0-9._-]+)+$`)
|
2014-12-11 23:11:47 +01:00
|
|
|
|
2015-03-13 03:31:41 +01:00
|
|
|
// ErrUnsupportedMethod may be returned in the case where a StorageDriver implementation does not support an optional method.
|
2015-10-03 01:19:06 +02:00
|
|
|
type ErrUnsupportedMethod struct {
|
|
|
|
DriverName string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (err ErrUnsupportedMethod) Error() string {
|
2015-11-24 23:17:25 +01:00
|
|
|
return fmt.Sprintf("%s: unsupported method", err.DriverName)
|
2015-10-03 01:19:06 +02:00
|
|
|
}
|
2015-01-07 17:31:38 +01:00
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// PathNotFoundError is returned when operating on a nonexistent path.
|
2014-10-22 00:02:20 +02:00
|
|
|
type PathNotFoundError struct {
|
2015-10-03 01:19:06 +02:00
|
|
|
Path string
|
|
|
|
DriverName string
|
2014-10-22 00:02:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (err PathNotFoundError) Error() string {
|
2015-11-24 23:17:25 +01:00
|
|
|
return fmt.Sprintf("%s: Path not found: %s", err.DriverName, err.Path)
|
2014-10-22 00:02:20 +02:00
|
|
|
}
|
|
|
|
|
2014-12-11 23:11:47 +01:00
|
|
|
// InvalidPathError is returned when the provided path is malformed.
|
|
|
|
type InvalidPathError struct {
|
2015-10-03 01:19:06 +02:00
|
|
|
Path string
|
|
|
|
DriverName string
|
2014-12-11 23:11:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func (err InvalidPathError) Error() string {
|
2015-11-24 23:17:25 +01:00
|
|
|
return fmt.Sprintf("%s: invalid path: %s", err.DriverName, err.Path)
|
2014-12-11 23:11:47 +01:00
|
|
|
}
|
|
|
|
|
2014-11-18 00:44:07 +01:00
|
|
|
// InvalidOffsetError is returned when attempting to read or write from an
|
|
|
|
// invalid offset.
|
2014-10-22 00:02:20 +02:00
|
|
|
type InvalidOffsetError struct {
|
2015-10-03 01:19:06 +02:00
|
|
|
Path string
|
|
|
|
Offset int64
|
|
|
|
DriverName string
|
2014-10-22 00:02:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
func (err InvalidOffsetError) Error() string {
|
2015-11-24 23:17:25 +01:00
|
|
|
return fmt.Sprintf("%s: invalid offset: %d for path: %s", err.DriverName, err.Offset, err.Path)
|
2014-10-22 00:02:20 +02:00
|
|
|
}
|
2015-11-02 22:23:53 +01:00
|
|
|
|
|
|
|
// Error is a catch-all error type which captures an error string and
|
2016-02-11 01:26:29 +01:00
|
|
|
// the driver type on which it occurred.
|
2015-11-02 22:23:53 +01:00
|
|
|
type Error struct {
|
|
|
|
DriverName string
|
|
|
|
Enclosed error
|
|
|
|
}
|
|
|
|
|
|
|
|
func (err Error) Error() string {
|
2015-11-24 23:17:25 +01:00
|
|
|
return fmt.Sprintf("%s: %s", err.DriverName, err.Enclosed)
|
2015-11-02 22:23:53 +01:00
|
|
|
}
|