fix replcation issue on accessory (#16912)

The tag/lable filter only works on the subject manifest, and if the subject manifest is mathed, all the accessories are marked as matched.

Signed-off-by: Wang Yan <wangyan@vmware.com>
This commit is contained in:
Wang Yan 2022-05-27 01:36:38 +08:00 committed by GitHub
parent 9d8e9158de
commit 3eb668c0a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 15 deletions

View File

@ -18,6 +18,7 @@ import (
"fmt" "fmt"
"github.com/goharbor/harbor/src/common/utils" "github.com/goharbor/harbor/src/common/utils"
"github.com/goharbor/harbor/src/controller/artifact" "github.com/goharbor/harbor/src/controller/artifact"
ctltag "github.com/goharbor/harbor/src/controller/tag"
"github.com/goharbor/harbor/src/lib/encode/repository" "github.com/goharbor/harbor/src/lib/encode/repository"
labelmodel "github.com/goharbor/harbor/src/pkg/label/model" labelmodel "github.com/goharbor/harbor/src/pkg/label/model"
"github.com/goharbor/harbor/src/pkg/reg/adapter/harbor/base" "github.com/goharbor/harbor/src/pkg/reg/adapter/harbor/base"
@ -58,12 +59,16 @@ func (c *client) listArtifacts(repo string) ([]*model.Artifact, error) {
var arts []*model.Artifact var arts []*model.Artifact
// append the accessory objects behind the subject artifact if it has. // append the accessory objects behind the subject artifact if it has.
var getAccessoryArts = func(art *artifact.Artifact, labels []*labelmodel.Label) ([]*model.Artifact, error) { var getAccessoryArts = func(art *artifact.Artifact, labels []*labelmodel.Label, tags []*ctltag.Tag) ([]*model.Artifact, error) {
var accArts = []*model.Artifact{} var accArts = []*model.Artifact{}
for _, acc := range art.Accessories { for _, acc := range art.Accessories {
accArt := &model.Artifact{ accArt := &model.Artifact{
Type: art.Type, Type: art.Type,
Digest: acc.GetData().Digest, Digest: acc.GetData().Digest,
IsAcc: true,
}
for _, tag := range tags {
accArt.ParentTags = append(accArt.ParentTags, tag.Name)
} }
// set the labels belonging to the subject manifest to the accessories. // set the labels belonging to the subject manifest to the accessories.
for _, label := range labels { for _, label := range labels {
@ -96,7 +101,7 @@ func (c *client) listArtifacts(repo string) ([]*model.Artifact, error) {
arts = append(arts, art) arts = append(arts, art)
// append the accessory of index or individual artifact // append the accessory of index or individual artifact
accArts, err := getAccessoryArts(artItem, artItem.Labels) accArts, err := getAccessoryArts(artItem, artItem.Labels, artItem.Tags)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -110,7 +115,7 @@ func (c *client) listArtifacts(repo string) ([]*model.Artifact, error) {
if err := c.C.Get(url, &artRef); err != nil { if err := c.C.Get(url, &artRef); err != nil {
return nil, err return nil, err
} }
accArts, err := getAccessoryArts(&artRef, artItem.Labels) accArts, err := getAccessoryArts(&artRef, artItem.Labels, artItem.Tags)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -167,8 +167,17 @@ func (a *artifactTagFilter) Filter(artifacts []*model.Artifact) ([]*model.Artifa
} }
var result []*model.Artifact var result []*model.Artifact
for _, artifact := range artifacts { for _, artifact := range artifacts {
// for individual artifact, use its own tags to match, reserve the matched tags.
// for accessory artifact, use the parent tags to match,
var tagsForMatching []string
if artifact.IsAcc {
tagsForMatching = append(tagsForMatching, artifact.ParentTags...)
} else {
tagsForMatching = append(tagsForMatching, artifact.Tags...)
}
// untagged artifact // untagged artifact
if len(artifact.Tags) == 0 { if len(tagsForMatching) == 0 {
match, err := util.Match(a.pattern, "") match, err := util.Match(a.pattern, "")
if err != nil { if err != nil {
return nil, err return nil, err
@ -187,7 +196,7 @@ func (a *artifactTagFilter) Filter(artifacts []*model.Artifact) ([]*model.Artifa
// tagged artifact // tagged artifact
var tags []string var tags []string
for _, tag := range artifact.Tags { for _, tag := range tagsForMatching {
match, err := util.Match(a.pattern, tag) match, err := util.Match(a.pattern, tag)
if err != nil { if err != nil {
return nil, err return nil, err
@ -206,12 +215,21 @@ func (a *artifactTagFilter) Filter(artifacts []*model.Artifact) ([]*model.Artifa
continue continue
} }
// copy a new artifact here to avoid changing the original one // copy a new artifact here to avoid changing the original one
if artifact.IsAcc {
result = append(result, &model.Artifact{ result = append(result, &model.Artifact{
Type: artifact.Type, Type: artifact.Type,
Digest: artifact.Digest, Digest: artifact.Digest,
Labels: artifact.Labels, Labels: artifact.Labels,
Tags: tags, Tags: artifact.Tags, // use its own tags to replicate
}) })
} else {
result = append(result, &model.Artifact{
Type: artifact.Type,
Digest: artifact.Digest,
Labels: artifact.Labels,
Tags: tags, // only replicate the matched tags
})
}
} }
return result, nil return result, nil
} }

View File

@ -62,6 +62,8 @@ type Artifact struct {
Digest string `json:"digest"` Digest string `json:"digest"`
Labels []string `json:"labels"` Labels []string `json:"labels"`
Tags []string `json:"tags"` Tags []string `json:"tags"`
IsAcc bool `json:"-"` // indicate whether it is an accessory artifact
ParentTags []string `json:"-"` // the tags belong to the artifact which the accessory is attached.
} }
func (r *ResourceMetadata) String() string { func (r *ResourceMetadata) String() string {