aboutsummaryrefslogtreecommitdiffstats
path: root/routers/api
diff options
context:
space:
mode:
authorKN4CK3R <admin@oldschoolhack.me>2022-07-28 05:59:39 +0200
committerGitHub <noreply@github.com>2022-07-28 11:59:39 +0800
commit86e5268c396bd89716b2617a4949837982c1b0c3 (patch)
treea01a04c069644694470c3159ce3daed94436ef08 /routers/api
parent4604048010347ea946ae57628d694a631787ab17 (diff)
downloadgitea-86e5268c396bd89716b2617a4949837982c1b0c3.tar.gz
gitea-86e5268c396bd89716b2617a4949837982c1b0c3.zip
Add Docker /v2/_catalog endpoint (#20469)
* Added properties for packages. * Fixed authenticate header format. * Added _catalog endpoint. * Check owner visibility. * Extracted condition. * Added test for _catalog. Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'routers/api')
-rw-r--r--routers/api/packages/api.go1
-rw-r--r--routers/api/packages/composer/api.go2
-rw-r--r--routers/api/packages/composer/composer.go2
-rw-r--r--routers/api/packages/container/blob.go12
-rw-r--r--routers/api/packages/container/container.go35
-rw-r--r--routers/api/packages/container/manifest.go12
-rw-r--r--routers/api/packages/npm/api.go2
7 files changed, 60 insertions, 6 deletions
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index b5fdc739d7..bb9a42e33d 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -257,6 +257,7 @@ func ContainerRoutes() *web.Route {
r.Get("", container.ReqContainerAccess, container.DetermineSupport)
r.Get("/token", container.Authenticate)
+ r.Get("/_catalog", container.ReqContainerAccess, container.GetRepositoryList)
r.Group("/{username}", func() {
r.Group("/{image}", func() {
r.Group("/blobs/uploads", func() {
diff --git a/routers/api/packages/composer/api.go b/routers/api/packages/composer/api.go
index 5e1cc293da..45bb7eae1c 100644
--- a/routers/api/packages/composer/api.go
+++ b/routers/api/packages/composer/api.go
@@ -88,7 +88,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac
for _, pd := range pds {
packageType := ""
- for _, pvp := range pd.Properties {
+ for _, pvp := range pd.VersionProperties {
if pvp.Name == composer_module.TypeProperty {
packageType = pvp.Value
break
diff --git a/routers/api/packages/composer/composer.go b/routers/api/packages/composer/composer.go
index b7c1f140dc..81cef39f1c 100644
--- a/routers/api/packages/composer/composer.go
+++ b/routers/api/packages/composer/composer.go
@@ -227,7 +227,7 @@ func UploadPackage(ctx *context.Context) {
SemverCompatible: true,
Creator: ctx.Doer,
Metadata: cp.Metadata,
- Properties: map[string]string{
+ VersionProperties: map[string]string{
composer_module.TypeProperty: cp.Type,
},
},
diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go
index 8f6254f583..8a9cbd4a15 100644
--- a/routers/api/packages/container/blob.go
+++ b/routers/api/packages/container/blob.go
@@ -29,6 +29,7 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
contentStore := packages_module.NewContentStore()
err := db.WithTx(func(ctx context.Context) error {
+ created := true
p := &packages_model.Package{
OwnerID: pi.Owner.ID,
Type: packages_model.TypeContainer,
@@ -37,12 +38,21 @@ func saveAsPackageBlob(hsr packages_module.HashedSizeReader, pi *packages_servic
}
var err error
if p, err = packages_model.TryInsertPackage(ctx, p); err != nil {
- if err != packages_model.ErrDuplicatePackage {
+ if err == packages_model.ErrDuplicatePackage {
+ created = false
+ } else {
log.Error("Error inserting package: %v", err)
return err
}
}
+ if created {
+ if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, p.ID, container_module.PropertyRepository, strings.ToLower(pi.Owner.LowerName+"/"+pi.Name)); err != nil {
+ log.Error("Error setting package property: %v", err)
+ return err
+ }
+ }
+
pv := &packages_model.PackageVersion{
PackageID: p.ID,
CreatorID: pi.Owner.ID,
diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go
index 2a564b3446..b961cd4afb 100644
--- a/routers/api/packages/container/container.go
+++ b/routers/api/packages/container/container.go
@@ -112,7 +112,7 @@ func apiErrorDefined(ctx *context.Context, err *namedError) {
// ReqContainerAccess is a middleware which checks the current user valid (real user or ghost for anonymous access)
func ReqContainerAccess(ctx *context.Context) {
if ctx.Doer == nil {
- ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token"`)
+ ctx.Resp.Header().Add("WWW-Authenticate", `Bearer realm="`+setting.AppURL+`v2/token",service="container_registry",scope="*"`)
apiErrorDefined(ctx, errUnauthorized)
}
}
@@ -151,6 +151,39 @@ func Authenticate(ctx *context.Context) {
})
}
+// https://docs.docker.com/registry/spec/api/#listing-repositories
+func GetRepositoryList(ctx *context.Context) {
+ n := ctx.FormInt("n")
+ if n <= 0 || n > 100 {
+ n = 100
+ }
+ last := ctx.FormTrim("last")
+
+ repositories, err := container_model.GetRepositories(ctx, ctx.Doer, n, last)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ type RepositoryList struct {
+ Repositories []string `json:"repositories"`
+ }
+
+ if len(repositories) == n {
+ v := url.Values{}
+ if n > 0 {
+ v.Add("n", strconv.Itoa(n))
+ }
+ v.Add("last", repositories[len(repositories)-1])
+
+ ctx.Resp.Header().Set("Link", fmt.Sprintf(`</v2/_catalog?%s>; rel="next"`, v.Encode()))
+ }
+
+ jsonResponse(ctx, http.StatusOK, RepositoryList{
+ Repositories: repositories,
+ })
+}
+
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#mounting-a-blob-from-another-repository
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#single-post
// https://github.com/opencontainers/distribution-spec/blob/main/spec.md#pushing-a-blob-in-chunks
diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go
index d899ac8ee2..319c9bcabc 100644
--- a/routers/api/packages/container/manifest.go
+++ b/routers/api/packages/container/manifest.go
@@ -267,6 +267,7 @@ func processImageManifestIndex(mci *manifestCreationInfo, buf *packages_module.H
}
func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, metadata *container_module.Metadata) (*packages_model.PackageVersion, error) {
+ created := true
p := &packages_model.Package{
OwnerID: mci.Owner.ID,
Type: packages_model.TypeContainer,
@@ -275,12 +276,21 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
}
var err error
if p, err = packages_model.TryInsertPackage(ctx, p); err != nil {
- if err != packages_model.ErrDuplicatePackage {
+ if err == packages_model.ErrDuplicatePackage {
+ created = false
+ } else {
log.Error("Error inserting package: %v", err)
return nil, err
}
}
+ if created {
+ if _, err := packages_model.InsertProperty(ctx, packages_model.PropertyTypePackage, p.ID, container_module.PropertyRepository, strings.ToLower(mci.Owner.LowerName+"/"+mci.Image)); err != nil {
+ log.Error("Error setting package property: %v", err)
+ return nil, err
+ }
+ }
+
metadata.IsTagged = mci.IsTagged
metadataJSON, err := json.Marshal(metadata)
diff --git a/routers/api/packages/npm/api.go b/routers/api/packages/npm/api.go
index 56c8977043..4b6b803971 100644
--- a/routers/api/packages/npm/api.go
+++ b/routers/api/packages/npm/api.go
@@ -25,7 +25,7 @@ func createPackageMetadataResponse(registryURL string, pds []*packages_model.Pac
for _, pd := range pds {
versions[pd.SemVer.String()] = createPackageMetadataVersion(registryURL, pd)
- for _, pvp := range pd.Properties {
+ for _, pvp := range pd.VersionProperties {
if pvp.Name == npm_module.TagProperty {
distTags[pvp.Value] = pd.Version.Version
}