forked from TrueCloudLab/distribution
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:
parent
b65d8d046e
commit
68fd15b688
6 changed files with 33 additions and 25 deletions
|
@ -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)
|
||||||
|
|
|
@ -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 != "" {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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})
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue