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 fieldsmaster
							parent
							
								
									b65d8d046e
								
							
						
					
					
						commit
						68fd15b688
					
				| 
						 | 
					@ -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 New Issue