1
0
mirror of https://github.com/mayflower/docker-ls.git synced 2026-01-03 18:02:36 +03:00

Refactoring, make add pagesize as a parameter.

This commit is contained in:
Christian Speckner
2016-02-16 10:14:40 +01:00
parent 3cedb0cfb5
commit 3cb3c5fa27
7 changed files with 78 additions and 60 deletions

View File

@@ -4,11 +4,10 @@ import (
"encoding/json"
"net/http"
"net/url"
"strconv"
)
type RepositoryListResponse struct {
repositories chan *Repository
type repositoryListResponse struct {
repositories chan Repository
err error
}
@@ -16,15 +15,15 @@ type repositoryListJsonResponse struct {
Repositories *[]string `json:"repositories"`
}
func (r *RepositoryListResponse) Repositories() <-chan *Repository {
func (r *repositoryListResponse) Repositories() <-chan Repository {
return (r.repositories)
}
func (r *RepositoryListResponse) LastError() error {
func (r *repositoryListResponse) LastError() error {
return r.err
}
func (r *RegistryApi) executeListRequest(url *url.URL, initialRequest bool) (response *http.Response, close bool, err error) {
func (r *registryApi) executeListRequest(url *url.URL, initialRequest bool) (response *http.Response, close bool, err error) {
response, err = r.connector.Get(url)
if err != nil {
@@ -57,29 +56,11 @@ func (r *RegistryApi) executeListRequest(url *url.URL, initialRequest bool) (res
return
}
func (r *RegistryApi) iterateRepositoryList(lastApiResponse *http.Response, listResponse *RepositoryListResponse) (apiResponse *http.Response, more bool, err error) {
requestUrl := r.endpointUrl("v2/_catalog")
func (r *registryApi) iterateRepositoryList(lastApiResponse *http.Response, listResponse *repositoryListResponse) (apiResponse *http.Response, more bool, err error) {
requestUrl, err := r.paginatedRequestEndpointUrl("v2/_catalog", lastApiResponse)
if lastApiResponse != nil {
linkHeader := lastApiResponse.Header.Get("link")
if linkHeader != "" {
// This is a hack to work around what looks like a bug in the registry:
// the supplied link URL currently lacks scheme and host
scheme, host := requestUrl.Scheme, requestUrl.Host
requestUrl, err = parseLinkToNextHeader(linkHeader)
requestUrl.Scheme = scheme
requestUrl.Host = host
}
if err != nil {
return
}
} else {
queryParams := requestUrl.Query()
queryParams.Set("n", strconv.Itoa(r.pageSize))
requestUrl.RawQuery = queryParams.Encode()
if err != nil {
return
}
apiResponse, needsClose, err := r.executeListRequest(requestUrl, lastApiResponse == nil)
@@ -114,26 +95,27 @@ func (r *RegistryApi) iterateRepositoryList(lastApiResponse *http.Response, list
return
}
func (r *RegistryApi) ListRepositories() (response *RepositoryListResponse, err error) {
response = &RepositoryListResponse{
repositories: make(chan *Repository, r.pageSize),
func (r *registryApi) ListRepositories() (response RepositoryListResponse, err error) {
listResponse := &repositoryListResponse{
repositories: make(chan Repository, r.pageSize()),
}
response = listResponse
var apiResponse *http.Response
apiResponse, more, err := r.iterateRepositoryList(apiResponse, response)
apiResponse, more, err := r.iterateRepositoryList(apiResponse, listResponse)
go func() {
for more {
var err error
apiResponse, more, err = r.iterateRepositoryList(apiResponse, response)
apiResponse, more, err = r.iterateRepositoryList(apiResponse, listResponse)
if err != nil {
response.err = err
listResponse.err = err
break
}
}
close(response.repositories)
close(listResponse.repositories)
}()
return

View File

@@ -7,13 +7,9 @@ import (
"strings"
)
type AuthenticatorInterface interface {
PerformRequest(*Challenge) (token string, err error)
}
type authenticator struct {
httpClient *http.Client
credentials RegistryCredentialsInterface
credentials RegistryCredentials
}
func (a *authenticator) PerformRequest(c *Challenge) (token string, err error) {
@@ -58,7 +54,7 @@ func (a *authenticator) PerformRequest(c *Challenge) (token string, err error) {
return
}
func NewAuthenticator(client *http.Client, credentials RegistryCredentialsInterface) *authenticator {
func NewAuthenticator(client *http.Client, credentials RegistryCredentials) Authenticator {
return &authenticator{
httpClient: client,
credentials: credentials,

View File

@@ -1,6 +1,6 @@
package auth
type RegistryCredentialsInterface interface {
type RegistryCredentials interface {
User() string
Password() string
}

View File

@@ -29,6 +29,7 @@ func (u *urlValue) Set(value string) (err error) {
type Config struct {
registryUrl url.URL
credentials RegistryCredentials
pageSize uint
}
func (u *urlValue) String() string {
@@ -39,6 +40,7 @@ func (c *Config) BindToFlags(flags *flag.FlagSet) {
c.registryUrl = DEFAULT_REGISTRY_URL
flags.Var((*urlValue)(&c.registryUrl), "registry", "registry URL")
flags.UintVar(&c.pageSize, "page-size", 100, "page size for paginated requests")
c.credentials.BindToFlags(flags)
}

View File

@@ -1,16 +1,17 @@
package lib
import (
"net/http"
"net/url"
"strconv"
)
type RegistryApi struct {
type registryApi struct {
cfg Config
connector *RegistryConnector
pageSize int
connector *registryConnector
}
func (r *RegistryApi) endpointUrl(path string) *url.URL {
func (r *registryApi) endpointUrl(path string) *url.URL {
url := r.cfg.registryUrl
url.Path = path
@@ -18,11 +19,48 @@ func (r *RegistryApi) endpointUrl(path string) *url.URL {
return &url
}
func NewRegistryApi(cfg Config) (registry *RegistryApi) {
registry = &RegistryApi{
cfg: cfg,
connector: NewRegistryConnector(cfg),
pageSize: 20,
func (r *registryApi) paginatedRequestEndpointUrl(path string, lastApiResponse *http.Response) (url *url.URL, err error) {
url = r.endpointUrl(path)
if lastApiResponse != nil {
linkHeader := lastApiResponse.Header.Get("link")
if linkHeader != "" {
// This is a hack to work around what looks like a bug in the registry:
// the supplied link URL currently lacks scheme and host
scheme, host := url.Scheme, url.Host
url, err = parseLinkToNextHeader(linkHeader)
if err != nil {
return
}
if url.Scheme == "" {
url.Scheme = scheme
}
if url.Host == "" {
url.Host = host
}
}
} else {
queryParams := url.Query()
queryParams.Set("n", strconv.Itoa(int(r.pageSize())))
url.RawQuery = queryParams.Encode()
}
return
}
func (r *registryApi) pageSize() uint {
return r.cfg.pageSize
}
func NewRegistryApi(cfg Config) (registry RegistryApi) {
registry = &registryApi{
cfg: cfg,
connector: NewRegistryConnector(cfg),
}
return

View File

@@ -8,13 +8,13 @@ import (
"git.mayflower.de/vaillant-team/docker-ls/lib/auth"
)
type RegistryConnector struct {
type registryConnector struct {
cfg Config
httpClient *http.Client
authenticator auth.AuthenticatorInterface
authenticator auth.Authenticator
}
func (r *RegistryConnector) Get(url *url.URL) (response *http.Response, err error) {
func (r *registryConnector) Get(url *url.URL) (response *http.Response, err error) {
request, err := http.NewRequest("GET", url.String(), strings.NewReader(""))
if err != nil {
@@ -51,8 +51,8 @@ func (r *RegistryConnector) Get(url *url.URL) (response *http.Response, err erro
return
}
func NewRegistryConnector(cfg Config) *RegistryConnector {
connector := RegistryConnector{
func NewRegistryConnector(cfg Config) *registryConnector {
connector := registryConnector{
cfg: cfg,
httpClient: http.DefaultClient,
}

View File

@@ -1,15 +1,15 @@
package lib
type Repository struct {
type repository struct {
name string
}
func (r *Repository) Name() string {
func (r *repository) Name() string {
return r.name
}
func newRepository(name string) *Repository {
return &Repository{
func newRepository(name string) *repository {
return &repository{
name: name,
}
}