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:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package auth
|
||||
|
||||
type RegistryCredentialsInterface interface {
|
||||
type RegistryCredentials interface {
|
||||
User() string
|
||||
Password() string
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = ®istryApi{
|
||||
cfg: cfg,
|
||||
connector: NewRegistryConnector(cfg),
|
||||
}
|
||||
|
||||
return
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user