mirror of
https://github.com/glanceapp/glance.git
synced 2024-12-14 17:13:11 +03:00
103 lines
2.5 KiB
Go
103 lines
2.5 KiB
Go
package feed
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
type dockerHubRepositoryTagsResponse struct {
|
|
Results []dockerHubRepositoryTagResponse `json:"results"`
|
|
}
|
|
|
|
type dockerHubRepositoryTagResponse struct {
|
|
Name string `json:"name"`
|
|
LastPushed string `json:"tag_last_pushed"`
|
|
}
|
|
|
|
const dockerHubOfficialRepoTagURLFormat = "https://hub.docker.com/_/%s/tags?name=%s"
|
|
const dockerHubRepoTagURLFormat = "https://hub.docker.com/r/%s/tags?name=%s"
|
|
const dockerHubTagsURLFormat = "https://hub.docker.com/v2/namespaces/%s/repositories/%s/tags"
|
|
const dockerHubSpecificTagURLFormat = "https://hub.docker.com/v2/namespaces/%s/repositories/%s/tags/%s"
|
|
|
|
func fetchLatestDockerHubRelease(request *ReleaseRequest) (*AppRelease, error) {
|
|
|
|
nameParts := strings.Split(request.Repository, "/")
|
|
|
|
if len(nameParts) > 2 {
|
|
return nil, fmt.Errorf("invalid repository name: %s", request.Repository)
|
|
} else if len(nameParts) == 1 {
|
|
nameParts = []string{"library", nameParts[0]}
|
|
}
|
|
|
|
tagParts := strings.SplitN(nameParts[1], ":", 2)
|
|
|
|
var requestURL string
|
|
|
|
if len(tagParts) == 2 {
|
|
requestURL = fmt.Sprintf(dockerHubSpecificTagURLFormat, nameParts[0], tagParts[0], tagParts[1])
|
|
} else {
|
|
requestURL = fmt.Sprintf(dockerHubTagsURLFormat, nameParts[0], nameParts[1])
|
|
}
|
|
|
|
httpRequest, err := http.NewRequest("GET", requestURL, nil)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if request.Token != nil {
|
|
httpRequest.Header.Add("Authorization", "Bearer "+(*request.Token))
|
|
}
|
|
|
|
var tag *dockerHubRepositoryTagResponse
|
|
|
|
if len(tagParts) == 1 {
|
|
response, err := decodeJsonFromRequest[dockerHubRepositoryTagsResponse](defaultClient, httpRequest)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if len(response.Results) == 0 {
|
|
return nil, fmt.Errorf("no tags found for repository: %s", request.Repository)
|
|
}
|
|
|
|
tag = &response.Results[0]
|
|
} else {
|
|
response, err := decodeJsonFromRequest[dockerHubRepositoryTagResponse](defaultClient, httpRequest)
|
|
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tag = &response
|
|
}
|
|
|
|
var repo string
|
|
var displayName string
|
|
var notesURL string
|
|
|
|
if len(tagParts) == 1 {
|
|
repo = nameParts[1]
|
|
} else {
|
|
repo = tagParts[0]
|
|
}
|
|
|
|
if nameParts[0] == "library" {
|
|
displayName = repo
|
|
notesURL = fmt.Sprintf(dockerHubOfficialRepoTagURLFormat, repo, tag.Name)
|
|
} else {
|
|
displayName = nameParts[0] + "/" + repo
|
|
notesURL = fmt.Sprintf(dockerHubRepoTagURLFormat, displayName, tag.Name)
|
|
}
|
|
|
|
return &AppRelease{
|
|
Source: ReleaseSourceDockerHub,
|
|
NotesUrl: notesURL,
|
|
Name: displayName,
|
|
Version: tag.Name,
|
|
TimeReleased: parseRFC3339Time(tag.LastPushed),
|
|
}, nil
|
|
}
|