Miscellaneous storagedriver+ipc fixes

Fixes/tests listing for keys beginning with "/"
No longer extraneously wraps Closers in ioutil.NopClosers
Uses omitempty for all ipc struct type fields
This commit is contained in:
Brian Bland 2014-11-20 14:11:49 -08:00
parent b65d8d046e
commit 68fd15b688
6 changed files with 33 additions and 25 deletions

View file

@ -5,7 +5,6 @@ import (
"io/ioutil" "io/ioutil"
"os" "os"
"path" "path"
"strings"
"github.com/docker/docker-registry/storagedriver" "github.com/docker/docker-registry/storagedriver"
"github.com/docker/docker-registry/storagedriver/factory" "github.com/docker/docker-registry/storagedriver/factory"
@ -177,7 +176,9 @@ func (d *Driver) CurrentSize(subPath string) (uint64, error) {
// List returns a list of the objects that are direct descendants of the given // List returns a list of the objects that are direct descendants of the given
// path. // path.
func (d *Driver) List(subPath string) ([]string, error) { func (d *Driver) List(subPath string) ([]string, error) {
subPath = strings.TrimRight(subPath, "/") if subPath[len(subPath)-1] != '/' {
subPath += "/"
}
fullPath := d.subPath(subPath) fullPath := d.subPath(subPath)
dir, err := os.Open(fullPath) dir, err := os.Open(fullPath)

View file

@ -121,14 +121,17 @@ func (d *Driver) CurrentSize(path string) (uint64, error) {
// List returns a list of the objects that are direct descendants of the given // List returns a list of the objects that are direct descendants of the given
// path. // path.
func (d *Driver) List(path string) ([]string, error) { func (d *Driver) List(path string) ([]string, error) {
subPathMatcher, err := regexp.Compile(fmt.Sprintf("^%s/[^/]+", path)) if path[len(path)-1] != '/' {
path += "/"
}
subPathMatcher, err := regexp.Compile(fmt.Sprintf("^%s[^/]+", path))
if err != nil { if err != nil {
return nil, err return nil, err
} }
d.mutex.RLock() d.mutex.RLock()
defer d.mutex.RUnlock() defer d.mutex.RUnlock()
// we use map to collect uniq keys // we use map to collect unique keys
keySet := make(map[string]struct{}) keySet := make(map[string]struct{})
for k := range d.storage { for k := range d.storage {
if key := subPathMatcher.FindString(k); key != "" { if key := subPathMatcher.FindString(k); key != "" {

View file

@ -267,7 +267,7 @@ func (driver *StorageDriverClient) WriteStream(path string, offset, size uint64,
} }
receiver, remoteSender := libchan.Pipe() receiver, remoteSender := libchan.Pipe()
params := map[string]interface{}{"Path": path, "Offset": offset, "Size": size, "Reader": ioutil.NopCloser(reader)} params := map[string]interface{}{"Path": path, "Offset": offset, "Size": size, "Reader": reader}
err := driver.sender.Send(&Request{Type: "WriteStream", Parameters: params, ResponseChannel: remoteSender}) err := driver.sender.Send(&Request{Type: "WriteStream", Parameters: params, ResponseChannel: remoteSender})
if err != nil { if err != nil {
return err return err

View file

@ -31,9 +31,9 @@ func (e IncompatibleVersionError) Error() string {
// Request defines a remote method call request // Request defines a remote method call request
// A return value struct is to be sent over the ResponseChannel // A return value struct is to be sent over the ResponseChannel
type Request struct { type Request struct {
Type string Type string `codec:",omitempty"`
Parameters map[string]interface{} Parameters map[string]interface{} `codec:",omitempty"`
ResponseChannel libchan.Sender ResponseChannel libchan.Sender `codec:",omitempty"`
} }
// ResponseError is a serializable error type. // ResponseError is a serializable error type.
@ -41,9 +41,9 @@ type Request struct {
// client side, falling back to using the Type and Message if this cannot be // client side, falling back to using the Type and Message if this cannot be
// done. // done.
type ResponseError struct { type ResponseError struct {
Type string Type string `codec:",omitempty"`
Message string Message string `codec:",omitempty"`
Parameters map[string]interface{} Parameters map[string]interface{} `codec:",omitempty"`
} }
// WrapError wraps an error in a serializable struct containing the error's type // WrapError wraps an error in a serializable struct containing the error's type
@ -108,39 +108,39 @@ func (err *ResponseError) Error() string {
// VersionResponse is a response for a Version request // VersionResponse is a response for a Version request
type VersionResponse struct { type VersionResponse struct {
Version storagedriver.Version Version storagedriver.Version `codec:",omitempty"`
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }
// ReadStreamResponse is a response for a ReadStream request // ReadStreamResponse is a response for a ReadStream request
type ReadStreamResponse struct { type ReadStreamResponse struct {
Reader io.ReadCloser Reader io.ReadCloser `codec:",omitempty"`
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }
// WriteStreamResponse is a response for a WriteStream request // WriteStreamResponse is a response for a WriteStream request
type WriteStreamResponse struct { type WriteStreamResponse struct {
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }
// CurrentSizeResponse is a response for a CurrentSize request // CurrentSizeResponse is a response for a CurrentSize request
type CurrentSizeResponse struct { type CurrentSizeResponse struct {
Position uint64 Position uint64 `codec:",omitempty"`
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }
// ListResponse is a response for a List request // ListResponse is a response for a List request
type ListResponse struct { type ListResponse struct {
Keys []string Keys []string `codec:",omitempty"`
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }
// MoveResponse is a response for a Move request // MoveResponse is a response for a Move request
type MoveResponse struct { type MoveResponse struct {
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }
// DeleteResponse is a response for a Delete request // DeleteResponse is a response for a Delete request
type DeleteResponse struct { type DeleteResponse struct {
Error *ResponseError Error *ResponseError `codec:",omitempty"`
} }

View file

@ -106,7 +106,7 @@ func handleRequest(driver storagedriver.StorageDriver, request Request) {
if err != nil { if err != nil {
response = ReadStreamResponse{Error: WrapError(err)} response = ReadStreamResponse{Error: WrapError(err)}
} else { } else {
response = ReadStreamResponse{Reader: ioutil.NopCloser(reader)} response = ReadStreamResponse{Reader: reader}
} }
err = request.ResponseChannel.Send(&response) err = request.ResponseChannel.Send(&response)
if err != nil { if err != nil {

View file

@ -253,7 +253,7 @@ func (suite *DriverSuite) TestReadNonexistentStream(c *check.C) {
// TestList checks the returned list of keys after populating a directory tree // TestList checks the returned list of keys after populating a directory tree
func (suite *DriverSuite) TestList(c *check.C) { func (suite *DriverSuite) TestList(c *check.C) {
rootDirectory := randomString(uint64(8 + rand.Intn(8))) rootDirectory := "/" + randomString(uint64(8+rand.Intn(8)))
defer suite.StorageDriver.Delete(rootDirectory) defer suite.StorageDriver.Delete(rootDirectory)
parentDirectory := rootDirectory + "/" + randomString(uint64(8+rand.Intn(8))) parentDirectory := rootDirectory + "/" + randomString(uint64(8+rand.Intn(8)))
@ -266,7 +266,11 @@ func (suite *DriverSuite) TestList(c *check.C) {
} }
sort.Strings(childFiles) sort.Strings(childFiles)
keys, err := suite.StorageDriver.List(rootDirectory) keys, err := suite.StorageDriver.List("/")
c.Assert(err, check.IsNil)
c.Assert(keys, check.DeepEquals, []string{rootDirectory})
keys, err = suite.StorageDriver.List(rootDirectory)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(keys, check.DeepEquals, []string{parentDirectory}) c.Assert(keys, check.DeepEquals, []string{parentDirectory})