mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-26 12:15:20 +01:00
Update swagger file to add retag API
Signed-off-by: 陈德 <chende@caicloud.io>
This commit is contained in:
parent
48d2435146
commit
75f1cdb449
@ -41,6 +41,32 @@ paths:
|
||||
$ref: '#/definitions/Search'
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/retag:
|
||||
post:
|
||||
summary: Retag an image
|
||||
description: >
|
||||
This endpoint tags an image with another tag in the same repo, or
|
||||
to another repo or project.
|
||||
parameters:
|
||||
- name: request
|
||||
in: body
|
||||
description: reqeust to given source image and target image
|
||||
required: true
|
||||
schema:
|
||||
$ref: '#/definitions/RetagReq'
|
||||
tags:
|
||||
- Products
|
||||
responses:
|
||||
'200':
|
||||
description: Image retag successfully.
|
||||
'400':
|
||||
description: Invalid image values provided
|
||||
'401':
|
||||
description: User has no permission to the source project or destination project.
|
||||
'404':
|
||||
description: Project or repository not found.
|
||||
'500':
|
||||
description: Unexpected internal errors.
|
||||
/projects:
|
||||
get:
|
||||
summary: List projects
|
||||
@ -2966,6 +2992,15 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/definitions/SearchResult'
|
||||
RetagReq:
|
||||
type: object
|
||||
properties:
|
||||
src_image:
|
||||
description: Source image to be retagged, e.g. 'stage/app:v1.0'
|
||||
type: string
|
||||
dest_image:
|
||||
description: Destination image tag to, e.g. 'product/app:v1.0'
|
||||
type: string
|
||||
SearchRepository:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -19,17 +19,21 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
// RetagRequest gives the source image and target image of retag
|
||||
type RetagRequest struct {
|
||||
SrcImage string `json:"src_image"`
|
||||
DestImage string `json:"dest_image"`
|
||||
SrcImage string `json:"src_image"`
|
||||
DestImage string `json:"dest_image"`
|
||||
}
|
||||
|
||||
// Image holds each part (project, repo, tag) of an image name
|
||||
type Image struct {
|
||||
Project string
|
||||
Repo string
|
||||
Tag string
|
||||
}
|
||||
|
||||
// ParseImage parses an image name such as 'library/app:v1.0' to a structure with
|
||||
// project, repo, and tag fields
|
||||
func ParseImage(image string) (*Image, error) {
|
||||
repo := strings.SplitN(image, "/", 2)
|
||||
if len(repo) < 2 {
|
||||
@ -38,10 +42,10 @@ func ParseImage(image string) (*Image, error) {
|
||||
i := strings.SplitN(repo[1], ":", 2)
|
||||
res := &Image{
|
||||
Project: repo[0],
|
||||
Repo: i[0],
|
||||
Repo: i[0],
|
||||
}
|
||||
if len(i) == 2 {
|
||||
res.Tag = i[1]
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
}
|
||||
|
@ -15,23 +15,24 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestParseImage(t *testing.T) {
|
||||
cases := []struct {
|
||||
Input string
|
||||
Input string
|
||||
Expected *Image
|
||||
Valid bool
|
||||
} {
|
||||
Valid bool
|
||||
}{
|
||||
{
|
||||
Input: "library/busybox",
|
||||
Expected: &Image{
|
||||
Project: "library",
|
||||
Repo: "busybox",
|
||||
Tag: "",
|
||||
Repo: "busybox",
|
||||
Tag: "",
|
||||
},
|
||||
Valid: true,
|
||||
},
|
||||
@ -39,8 +40,8 @@ func TestParseImage(t *testing.T) {
|
||||
Input: "library/busybox:v1.0",
|
||||
Expected: &Image{
|
||||
Project: "library",
|
||||
Repo: "busybox",
|
||||
Tag: "v1.0",
|
||||
Repo: "busybox",
|
||||
Tag: "v1.0",
|
||||
},
|
||||
Valid: true,
|
||||
},
|
||||
@ -62,4 +63,4 @@ func TestParseImage(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,6 +258,7 @@ func (r *Repository) DeleteManifest(digest string) error {
|
||||
}
|
||||
}
|
||||
|
||||
// MountBlob ...
|
||||
func (r *Repository) MountBlob(digest, from string) error {
|
||||
req, err := http.NewRequest("POST", buildMountBlobURL(r.Endpoint.String(), r.Name, digest, from), nil)
|
||||
req.Header.Set(http.CanonicalHeaderKey("Content-Length"), "0")
|
||||
|
@ -28,6 +28,7 @@ type RetagAPI struct {
|
||||
BaseController
|
||||
}
|
||||
|
||||
// Retag tags an image to another
|
||||
func (r *RetagAPI) Retag() {
|
||||
if !r.SecurityCtx.IsAuthenticated() {
|
||||
r.HandleUnauthorized()
|
||||
|
@ -25,13 +25,15 @@ import (
|
||||
"github.com/docker/distribution/manifest/schema2"
|
||||
)
|
||||
|
||||
// Retag tags an image to another
|
||||
func Retag(srcImage, destImage *models.Image) error {
|
||||
isSameRepo := getRepoName(srcImage) == getRepoName(destImage)
|
||||
srcClient, err := NewRepositoryClientForUI("harbor-ui", getRepoName(srcImage))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
destClient := srcClient
|
||||
if getRepoName(srcImage) != getRepoName(destImage) {
|
||||
if !isSameRepo {
|
||||
destClient, err = NewRepositoryClientForUI("harbor-ui", getRepoName(destImage))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -70,7 +72,7 @@ func Retag(srcImage, destImage *models.Image) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if getRepoName(srcImage) != getRepoName(destImage) {
|
||||
if !isSameRepo {
|
||||
for _, descriptor := range manifest.References() {
|
||||
err := destClient.MountBlob(descriptor.Digest.String(), srcClient.Name)
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user