mirror of
https://github.com/mayflower/docker-ls.git
synced 2025-11-28 00:01:09 +03:00
123 lines
2.5 KiB
Go
123 lines
2.5 KiB
Go
package lib
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/url"
|
|
)
|
|
|
|
type repositoryListResponse struct {
|
|
repositories chan Repository
|
|
err error
|
|
}
|
|
|
|
type repositoryListJsonResponse struct {
|
|
Repositories *[]string `json:"repositories"`
|
|
}
|
|
|
|
func (r *repositoryListResponse) Repositories() <-chan Repository {
|
|
return (r.repositories)
|
|
}
|
|
|
|
func (r *repositoryListResponse) LastError() error {
|
|
return r.err
|
|
}
|
|
|
|
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 {
|
|
return
|
|
}
|
|
|
|
close = response.Close
|
|
|
|
switch response.StatusCode {
|
|
case http.StatusUnauthorized, http.StatusForbidden:
|
|
err = genericAuthorizationError
|
|
return
|
|
|
|
case http.StatusNotFound:
|
|
if initialRequest {
|
|
err = NotImplementedByRemoteError("registry does not implement repository listings")
|
|
} else {
|
|
err = newInvalidStatusCodeError(response.StatusCode)
|
|
}
|
|
|
|
return
|
|
|
|
case http.StatusOK:
|
|
|
|
default:
|
|
err = newInvalidStatusCodeError(response.StatusCode)
|
|
return
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
func (r *registryApi) iterateRepositoryList(lastApiResponse *http.Response, listResponse *repositoryListResponse) (apiResponse *http.Response, more bool, err error) {
|
|
requestUrl, err := r.paginatedRequestEndpointUrl("v2/_catalog", lastApiResponse)
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
apiResponse, needsClose, err := r.executeListRequest(requestUrl, lastApiResponse == nil)
|
|
|
|
if needsClose {
|
|
defer apiResponse.Body.Close()
|
|
}
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
more = apiResponse.Header.Get("link") != ""
|
|
|
|
var jsonResponse repositoryListJsonResponse
|
|
decoder := json.NewDecoder(apiResponse.Body)
|
|
err = decoder.Decode(&jsonResponse)
|
|
|
|
if err != nil {
|
|
return
|
|
}
|
|
|
|
if jsonResponse.Repositories == nil {
|
|
err = genericMalformedResponseError
|
|
return
|
|
}
|
|
|
|
for _, repositoryName := range *jsonResponse.Repositories {
|
|
listResponse.repositories <- newRepository(repositoryName)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
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, listResponse)
|
|
|
|
go func() {
|
|
for more {
|
|
var err error
|
|
apiResponse, more, err = r.iterateRepositoryList(apiResponse, listResponse)
|
|
|
|
if err != nil {
|
|
listResponse.err = err
|
|
break
|
|
}
|
|
}
|
|
|
|
close(listResponse.repositories)
|
|
}()
|
|
|
|
return
|
|
}
|