Updates documentation to follow godoc conventions

This commit is contained in:
Brian Bland 2014-10-29 12:14:19 -07:00
parent ca0084fad1
commit 0e5d41ff9b
9 changed files with 84 additions and 64 deletions

View file

@ -7,13 +7,14 @@ import (
"github.com/docker/docker-registry/storagedriver/ipc"
)
// Internal mapping between storage driver names and their respective factories
// driverFactories stores an internal mapping between storage driver names and their respective
// factories
var driverFactories = make(map[string]StorageDriverFactory)
// Factory interface for the storagedriver.StorageDriver interface
// StorageDriverFactory is a factory interface for creating storagedriver.StorageDriver interfaces
// Storage drivers should call Register() with a factory to make the driver available by name
type StorageDriverFactory interface {
// Creates and returns a new storagedriver.StorageDriver with the given parameters
// Create returns a new storagedriver.StorageDriver with the given parameters
// Parameters will vary by driver and may be ignored
// Each parameter key must only consist of lowercase letters and numbers
Create(parameters map[string]string) (storagedriver.StorageDriver, error)
@ -54,7 +55,7 @@ func Create(name string, parameters map[string]string) (storagedriver.StorageDri
return driverFactory.Create(parameters)
}
// Error returned when attempting to construct an unregistered storage driver
// InvalidStorageDriverError records an attempt to construct an unregistered storage driver
type InvalidStorageDriverError struct {
Name string
}

View file

@ -18,20 +18,20 @@ func init() {
factory.Register(DriverName, &filesystemDriverFactory{})
}
// Implements the factory.StorageDriverFactory interface
// filesystemDriverFactory implements the factory.StorageDriverFactory interface
type filesystemDriverFactory struct{}
func (factory *filesystemDriverFactory) Create(parameters map[string]string) (storagedriver.StorageDriver, error) {
return FromParameters(parameters), nil
}
// Storage Driver backed by a local filesystem
// FilesystemDriver is a storagedriver.StorageDriver implementation backed by a local filesystem
// All provided paths will be subpaths of the RootDirectory
type FilesystemDriver struct {
rootDirectory string
}
// Constructs a new FilesystemDriver with a given parameters map
// FromParameters constructs a new FilesystemDriver with a given parameters map
// Optional Parameters:
// - rootdirectory
func FromParameters(parameters map[string]string) *FilesystemDriver {
@ -45,11 +45,12 @@ func FromParameters(parameters map[string]string) *FilesystemDriver {
return New(rootDirectory)
}
// Constructs a new FilesystemDriver with a given rootDirectory
// New constructs a new FilesystemDriver with a given rootDirectory
func New(rootDirectory string) *FilesystemDriver {
return &FilesystemDriver{rootDirectory}
}
// subPath returns the absolute path of a key within the FilesystemDriver's storage
func (d *FilesystemDriver) subPath(subPath string) string {
return path.Join(d.rootDirectory, subPath)
}

View file

@ -19,25 +19,27 @@ func init() {
factory.Register(DriverName, &inMemoryDriverFactory{})
}
// Implements the factory.StorageDriverFactory interface
// inMemoryDriverFacotry implements the factory.StorageDriverFactory interface
type inMemoryDriverFactory struct{}
func (factory *inMemoryDriverFactory) Create(parameters map[string]string) (storagedriver.StorageDriver, error) {
return New(), nil
}
// InMemory Storage Driver backed by a map
// InMemoryDriver is a storagedriver.StorageDriver implementation backed by a local map
// Intended solely for example and testing purposes
type InMemoryDriver struct {
storage map[string][]byte
mutex sync.RWMutex
}
// Constructs a new InMemoryDriver
// New constructs a new InMemoryDriver
func New() *InMemoryDriver {
return &InMemoryDriver{storage: make(map[string][]byte)}
}
// Implement the storagedriver.StorageDriver interface
func (d *InMemoryDriver) GetContent(path string) ([]byte, error) {
d.mutex.RLock()
defer d.mutex.RUnlock()

View file

@ -15,7 +15,8 @@ import (
"github.com/docker/libchan/spdy"
)
// Storage Driver implementation using a managed child process communicating over IPC
// StorageDriverClient is a storagedriver.StorageDriver implementation using a managed child process
// communicating over IPC using libchan with a unix domain socket
type StorageDriverClient struct {
subprocess *exec.Cmd
socket *os.File
@ -23,8 +24,9 @@ type StorageDriverClient struct {
sender libchan.Sender
}
// Constructs a new out-of-process storage driver using the driver name and configuration parameters
// Must call Start() on this driver client before remote method calls can be made
// NewDriverClient constructs a new out-of-process storage driver using the driver name and
// configuration parameters
// A user must call Start on this driver client before remote method calls can be made
//
// Looks for drivers in the following locations in order:
// - Storage drivers directory (to be determined, yet not implemented)
@ -54,7 +56,8 @@ func NewDriverClient(name string, parameters map[string]string) (*StorageDriverC
}, nil
}
// Starts the designated child process storage driver and binds a socket to this process for IPC
// Start starts the designated child process storage driver and binds a socket to this process for
// IPC method calls
func (driver *StorageDriverClient) Start() error {
fileDescriptors, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
if err != nil {
@ -102,8 +105,8 @@ func (driver *StorageDriverClient) Start() error {
return nil
}
// Stops the child process storage driver
// storagedriver.StorageDriver methods called after Stop() will fail
// Stop stops the child process storage driver
// storagedriver.StorageDriver methods called after Stop will fail
func (driver *StorageDriverClient) Stop() error {
closeSenderErr := driver.sender.Close()
closeTransportErr := driver.transport.Close()

View file

@ -10,7 +10,7 @@ import (
"github.com/docker/libchan"
)
// Defines a remote method call request
// Request defines a remote method call request
// A return value struct is to be sent over the ResponseChannel
type Request struct {
Type string
@ -18,8 +18,9 @@ type Request struct {
ResponseChannel libchan.Sender
}
// A simple wrapper around an io.ReadCloser that implements the io.ReadWriteCloser interface
// Writes are disallowed and will return an error if ever called
// noWriteReadWriteCloser is a simple wrapper around an io.ReadCloser that implements the
// io.ReadWriteCloser interface
// Calls to Write are disallowed and will return an error
type noWriteReadWriteCloser struct {
io.ReadCloser
}
@ -28,7 +29,7 @@ func (r noWriteReadWriteCloser) Write(p []byte) (n int, err error) {
return 0, errors.New("Write unsupported")
}
// Wraps an io.Reader as an io.ReadWriteCloser with a nop Close and unsupported Write method
// WrapReader wraps an io.Reader as an io.ReadWriteCloser with a nop Close and unsupported Write
// Has no effect when an io.ReadWriteCloser is passed in
func WrapReader(reader io.Reader) io.ReadWriteCloser {
if readWriteCloser, ok := reader.(io.ReadWriteCloser); ok {
@ -45,7 +46,7 @@ type responseError struct {
Message string
}
// Wraps an error in a serializable struct containing the error's type and message
// ResponseError wraps an error in a serializable struct containing the error's type and message
func ResponseError(err error) *responseError {
if err == nil {
return nil
@ -62,35 +63,35 @@ func (err *responseError) Error() string {
// IPC method call response object definitions
// Response for a ReadStream request
// ReadStreamResponse is a response for a ReadStream request
type ReadStreamResponse struct {
Reader io.ReadWriteCloser
Error *responseError
}
// Response for a WriteStream request
// WriteStreamResponse is a response for a WriteStream request
type WriteStreamResponse struct {
Error *responseError
}
// Response for a ResumeWritePosition request
// ResumeWritePositionResponse is a response for a ResumeWritePosition request
type ResumeWritePositionResponse struct {
Position uint64
Error *responseError
}
// Response for a List request
// ListResponse is a response for a List request
type ListResponse struct {
Keys []string
Error *responseError
}
// Response for a Move request
// MoveResponse is a response for a Move request
type MoveResponse struct {
Error *responseError
}
// Response for a Delete request
// DeleteResponse is a response for a Delete request
type DeleteResponse struct {
Error *responseError
}

View file

@ -13,10 +13,13 @@ import (
"github.com/docker/libchan/spdy"
)
// Construct a new IPC server handling requests for the given storagedriver.StorageDriver
// This explicitly uses file descriptor 3 for IPC communication, as storage drivers are spawned in client.go
// StorageDriverServer runs a new IPC server handling requests for the given
// storagedriver.StorageDriver
// This explicitly uses file descriptor 3 for IPC communication, as storage drivers are spawned in
// client.go
//
// To create a new out-of-process driver, create a main package which calls StorageDriverServer with a storagedriver.StorageDriver
// To create a new out-of-process driver, create a main package which calls StorageDriverServer with
// a storagedriver.StorageDriver
func StorageDriverServer(driver storagedriver.StorageDriver) error {
childSocket := os.NewFile(3, "childSocket")
defer childSocket.Close()
@ -39,9 +42,10 @@ func StorageDriverServer(driver storagedriver.StorageDriver) error {
}
}
// Receives new storagedriver.StorageDriver method requests and creates a new goroutine to handle each request
//
// Requests are expected to be of type ipc.Request as the parameters are unknown until the request type is deserialized
// receive receives new storagedriver.StorageDriver method requests and creates a new goroutine to
// handle each request
// Requests are expected to be of type ipc.Request as the parameters are unknown until the request
// type is deserialized
func receive(driver storagedriver.StorageDriver, receiver libchan.Receiver) {
for {
var request Request
@ -53,7 +57,7 @@ func receive(driver storagedriver.StorageDriver, receiver libchan.Receiver) {
}
}
// Handles storagedriver.StorageDriver method requests as defined in client.go
// handleRequest handles storagedriver.StorageDriver method requests as defined in client.go
// Responds to requests using the Request.ResponseChannel
func handleRequest(driver storagedriver.StorageDriver, request Request) {
switch request.Type {

View file

@ -15,24 +15,25 @@ import (
const DriverName = "s3"
// Chunks need to be at least 5MB to store with a multipart upload on S3
// minChunkSize defines the minimum multipart upload chunk size
// S3 API requires multipart upload chunks to be at least 5MB
const minChunkSize = uint64(5 * 1024 * 1024)
// The largest amount of parts you can request from S3
// listPartsMax is the largest amount of parts you can request from S3
const listPartsMax = 1000
func init() {
factory.Register(DriverName, &s3DriverFactory{})
}
// Implements the factory.StorageDriverFactory interface
// s3DriverFactory implements the factory.StorageDriverFactory interface
type s3DriverFactory struct{}
func (factory *s3DriverFactory) Create(parameters map[string]string) (storagedriver.StorageDriver, error) {
return FromParameters(parameters)
}
// Storage Driver backed by Amazon S3
// S3Driver is a storagedriver.StorageDriver implementation backed by Amazon S3
// Objects are stored at absolute keys in the provided bucket
type S3Driver struct {
S3 *s3.S3
@ -40,7 +41,7 @@ type S3Driver struct {
Encrypt bool
}
// Constructs a new S3Driver with a given parameters map
// FromParameters constructs a new S3Driver with a given parameters map
// Required parameters:
// - accesskey
// - secretkey
@ -84,7 +85,8 @@ func FromParameters(parameters map[string]string) (*S3Driver, error) {
return New(accessKey, secretKey, region, encryptBool, bucket)
}
// Constructs a new S3Driver with the given AWS credentials, region, encryption flag, and bucketName
// New constructs a new S3Driver with the given AWS credentials, region, encryption flag, and
// bucketName
func New(accessKey string, secretKey string, region aws.Region, encrypt bool, bucketName string) (*S3Driver, error) {
auth := aws.Auth{AccessKey: accessKey, SecretKey: secretKey}
s3obj := s3.New(auth, region)
@ -100,6 +102,8 @@ func New(accessKey string, secretKey string, region aws.Region, encrypt bool, bu
return &S3Driver{s3obj, bucket, encrypt}, nil
}
// Implement the storagedriver.StorageDriver interface
func (d *S3Driver) GetContent(path string) ([]byte, error) {
return d.Bucket.Get(path)
}

View file

@ -5,41 +5,45 @@ import (
"io"
)
// Defines methods that a Storage Driver must implement for a filesystem-like key/value object storage
// StorageDriver defines methods that a Storage Driver must implement for a filesystem-like
// key/value object storage
type StorageDriver interface {
// Retrieve the content stored at "path" as a []byte
// GetContent retrieves the content stored at "path" as a []byte
// Should primarily be used for small objects
GetContent(path string) ([]byte, error)
// Store the []byte content at a location designated by "path"
// PutContent stores the []byte content at a location designated by "path"
// Should primarily be used for small objects
PutContent(path string, content []byte) error
// Retrieve an io.ReadCloser for the content stored at "path" with a given byte offset
// ReadStream 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
ReadStream(path string, offset uint64) (io.ReadCloser, error)
// Store the contents of the provided io.ReadCloser at a location designated by "path"
// WriteStream stores the contents of the provided io.ReadCloser at a location designated by
// the given path
// The driver will know it has received the full contents when it has read "size" bytes
// May be used to resume writing a stream by providing a nonzero offset
// The offset must be no larger than the number of bytes already written to this path
WriteStream(path string, offset, size uint64, readCloser io.ReadCloser) error
// Retrieve the byte offset at which it is safe to continue writing at "path"
// ResumeWritePosition retrieves the byte offset at which it is safe to continue writing at the
// given path
ResumeWritePosition(path string) (uint64, error)
// Recursively lists the objects stored at a subpath of the given prefix
// List recursively lists the objects stored at a subpath of the given prefix
List(prefix string) ([]string, error)
// Moves an object stored at sourcePath to destPath, removing the original object
// 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
Move(sourcePath string, destPath string) error
// Recursively deletes all objects stored at "path" and its subpaths
// Delete recursively deletes all objects stored at "path" and its subpaths
Delete(path string) error
}
// Error returned when operating on a nonexistent path
// PathNotFoundError is returned when operating on a nonexistent path
type PathNotFoundError struct {
Path string
}
@ -48,7 +52,7 @@ func (err PathNotFoundError) Error() string {
return fmt.Sprintf("Path not found: %s", err.Path)
}
// Error returned when attempting to read or write from an invalid offset
// InvalidOffsetError is returned when attempting to read or write from an invalid offset
type InvalidOffsetError struct {
Path string
Offset uint64

View file

@ -17,9 +17,7 @@ import (
// Hook up gocheck into the "go test" runner
func Test(t *testing.T) { TestingT(t) }
// Registers an in-process storage driver test suite with the go test runner
//
// If skipCheck returns a non-empty skip reason, the suite is skipped with the given reason
// RegisterInProcessSuite registers an in-process storage driver test suite with the go test runner
func RegisterInProcessSuite(driverConstructor DriverConstructor, skipCheck SkipCheck) {
Suite(&DriverSuite{
Constructor: driverConstructor,
@ -27,9 +25,8 @@ func RegisterInProcessSuite(driverConstructor DriverConstructor, skipCheck SkipC
})
}
// Registers a storage driver test suite which runs the named driver as a child process with the given parameters
//
// If skipCheck returns a non-empty skip reason, the suite is skipped with the given reason
// RegisterIPCSuite registers a storage driver test suite which runs the named driver as a child
// process with the given parameters
func RegisterIPCSuite(driverName string, ipcParams map[string]string, skipCheck SkipCheck) {
suite := &DriverSuite{
Constructor: func() (storagedriver.StorageDriver, error) {
@ -56,13 +53,21 @@ func RegisterIPCSuite(driverName string, ipcParams map[string]string, skipCheck
Suite(suite)
}
// SkipCheck is a function used to determine if a test suite should be skipped
// If a SkipCheck returns a non-empty skip reason, the suite is skipped with the given reason
type SkipCheck func() (reason string)
var NeverSkip = func() string { return "" }
// NeverSkip is a default SkipCheck which never skips the suite
var NeverSkip SkipCheck = func() string { return "" }
// DriverConstructor is a function which returns a new storagedriver.StorageDriver
type DriverConstructor func() (storagedriver.StorageDriver, error)
// DriverTeardown is a function which cleans up a suite's storagedriver.StorageDriver
type DriverTeardown func() error
// DriverSuite is a gocheck test suite designed to test a storagedriver.StorageDriver
// The intended way to create a DriverSuite is with RegisterInProcessSuite or RegisterIPCSuite
type DriverSuite struct {
Constructor DriverConstructor
Teardown DriverTeardown
@ -70,11 +75,6 @@ type DriverSuite struct {
storagedriver.StorageDriver
}
type TestDriverConfig struct {
name string
params map[string]string
}
func (suite *DriverSuite) SetUpSuite(c *C) {
if reason := suite.SkipCheck(); reason != "" {
c.Skip(reason)