Add Registry to client bindings for Repositories
The way Repositories() was initially called was somewhat different than other parts of the client bindings because there was no way to instantiate a Namespace. This change implements a NewRegistry() function which changes it so that Repositories() can be called the way one would expect. It doesn't implement any of the other functions of Namespaces. Signed-off-by: Patrick Devine <patrick.devine@docker.com>master
							parent
							
								
									b7e26bac74
								
							
						
					
					
						commit
						14749fdce4
					
				|  | @ -21,6 +21,83 @@ import ( | |||
| 	"github.com/docker/distribution/registry/storage/cache/memory" | ||||
| ) | ||||
| 
 | ||||
| // Registry provides an interface for calling Repositories, which returns a catalog of repositories.
 | ||||
| type Registry interface { | ||||
| 	Repositories(ctx context.Context, repos []string, last string) (n int, err error) | ||||
| } | ||||
| 
 | ||||
| // NewRegistry creates a registry namespace which can be used to get a listing of repositories
 | ||||
| func NewRegistry(ctx context.Context, baseURL string, transport http.RoundTripper) (Registry, error) { | ||||
| 	ub, err := v2.NewURLBuilderFromString(baseURL) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	client := &http.Client{ | ||||
| 		Transport: transport, | ||||
| 		Timeout:   1 * time.Minute, | ||||
| 	} | ||||
| 
 | ||||
| 	return ®istry{ | ||||
| 		client:  client, | ||||
| 		ub:      ub, | ||||
| 		context: ctx, | ||||
| 	}, nil | ||||
| } | ||||
| 
 | ||||
| type registry struct { | ||||
| 	client  *http.Client | ||||
| 	ub      *v2.URLBuilder | ||||
| 	context context.Context | ||||
| } | ||||
| 
 | ||||
| // Repositories returns a lexigraphically sorted catalog given a base URL.  The 'entries' slice will be filled up to the size
 | ||||
| // of the slice, starting at the value provided in 'last'.  The number of entries will be returned along with io.EOF if there
 | ||||
| // are no more entries
 | ||||
| func (r *registry) Repositories(ctx context.Context, entries []string, last string) (int, error) { | ||||
| 	var numFilled int | ||||
| 	var returnErr error | ||||
| 
 | ||||
| 	values := buildCatalogValues(len(entries), last) | ||||
| 	u, err := r.ub.BuildCatalogURL(values) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 
 | ||||
| 	resp, err := r.client.Get(u) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 
 | ||||
| 	switch resp.StatusCode { | ||||
| 	case http.StatusOK: | ||||
| 		var ctlg struct { | ||||
| 			Repositories []string `json:"repositories"` | ||||
| 		} | ||||
| 		decoder := json.NewDecoder(resp.Body) | ||||
| 
 | ||||
| 		if err := decoder.Decode(&ctlg); err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 
 | ||||
| 		for cnt := range ctlg.Repositories { | ||||
| 			entries[cnt] = ctlg.Repositories[cnt] | ||||
| 		} | ||||
| 		numFilled = len(ctlg.Repositories) | ||||
| 
 | ||||
| 		link := resp.Header.Get("Link") | ||||
| 		if link == "" { | ||||
| 			returnErr = io.EOF | ||||
| 		} | ||||
| 
 | ||||
| 	default: | ||||
| 		return 0, handleErrorResponse(resp) | ||||
| 	} | ||||
| 
 | ||||
| 	return numFilled, returnErr | ||||
| } | ||||
| 
 | ||||
| // NewRepository creates a new Repository for the given repository name and base URL
 | ||||
| func NewRepository(ctx context.Context, name, baseURL string, transport http.RoundTripper) (distribution.Repository, error) { | ||||
| 	if err := v2.ValidateRepositoryName(name); err != nil { | ||||
|  | @ -458,60 +535,3 @@ func buildCatalogValues(maxEntries int, last string) url.Values { | |||
| 
 | ||||
| 	return values | ||||
| } | ||||
| 
 | ||||
| // Repositories returns a lexigraphically sorted catalog given a base URL.  The 'entries' slice will be filled up to the size
 | ||||
| // of the slice, starting at the value provided in 'last'.  The number of entries will be returned along with io.EOF if there
 | ||||
| // are no more entries
 | ||||
| func Repositories(ctx context.Context, baseURL string, entries []string, last string, transport http.RoundTripper) (int, error) { | ||||
| 	var numFilled int | ||||
| 	var returnErr error | ||||
| 
 | ||||
| 	ub, err := v2.NewURLBuilderFromString(baseURL) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 
 | ||||
| 	client := &http.Client{ | ||||
| 		Transport: transport, | ||||
| 		Timeout:   1 * time.Minute, | ||||
| 	} | ||||
| 
 | ||||
| 	values := buildCatalogValues(len(entries), last) | ||||
| 	u, err := ub.BuildCatalogURL(values) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 
 | ||||
| 	resp, err := client.Get(u) | ||||
| 	if err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
| 
 | ||||
| 	switch resp.StatusCode { | ||||
| 	case http.StatusOK: | ||||
| 		var ctlg struct { | ||||
| 			Repositories []string `json:"repositories"` | ||||
| 		} | ||||
| 		decoder := json.NewDecoder(resp.Body) | ||||
| 
 | ||||
| 		if err := decoder.Decode(&ctlg); err != nil { | ||||
| 			return 0, err | ||||
| 		} | ||||
| 
 | ||||
| 		for cnt := range ctlg.Repositories { | ||||
| 			entries[cnt] = ctlg.Repositories[cnt] | ||||
| 		} | ||||
| 		numFilled = len(ctlg.Repositories) | ||||
| 
 | ||||
| 		link := resp.Header.Get("Link") | ||||
| 		if link == "" { | ||||
| 			returnErr = io.EOF | ||||
| 		} | ||||
| 
 | ||||
| 	default: | ||||
| 		return 0, handleErrorResponse(resp) | ||||
| 	} | ||||
| 
 | ||||
| 	return numFilled, returnErr | ||||
| } | ||||
|  |  | |||
|  | @ -768,8 +768,13 @@ func TestCatalog(t *testing.T) { | |||
| 
 | ||||
| 	entries := make([]string, 5) | ||||
| 
 | ||||
| 	r, err := NewRegistry(context.Background(), e, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	ctx := context.Background() | ||||
| 	numFilled, err := Repositories(ctx, e, entries, "", nil) | ||||
| 	numFilled, err := r.Repositories(ctx, entries, "") | ||||
| 	if err != io.EOF { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | @ -795,8 +800,13 @@ func TestCatalogInParts(t *testing.T) { | |||
| 
 | ||||
| 	entries := make([]string, 2) | ||||
| 
 | ||||
| 	r, err := NewRegistry(context.Background(), e, nil) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 
 | ||||
| 	ctx := context.Background() | ||||
| 	numFilled, err := Repositories(ctx, e, entries, "", nil) | ||||
| 	numFilled, err := r.Repositories(ctx, entries, "") | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | @ -805,7 +815,7 @@ func TestCatalogInParts(t *testing.T) { | |||
| 		t.Fatalf("Got wrong number of repos") | ||||
| 	} | ||||
| 
 | ||||
| 	numFilled, err = Repositories(ctx, e, entries, "baz", nil) | ||||
| 	numFilled, err = r.Repositories(ctx, entries, "baz") | ||||
| 	if err != io.EOF { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue