diff --git a/api/target.go b/api/target.go index c89f1a3fd..1c78b915d 100644 --- a/api/target.go +++ b/api/target.go @@ -190,14 +190,14 @@ func (t *TargetAPI) Post() { t.CustomAbort(http.StatusConflict, "name is already used") } - ta, err = dao.GetRepTargetByConnInfo(target.URL, target.Username) + ta, err = dao.GetRepTargetByEndpoint(target.URL) if err != nil { - log.Errorf("failed to get target [ %s %s ]: %v", target.URL, target.Username, err) + log.Errorf("failed to get target [ %s ]: %v", target.URL, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if ta != nil { - t.CustomAbort(http.StatusConflict, "the connection information[ endpoint, username ] is conflict with other target") + t.CustomAbort(http.StatusConflict, fmt.Sprintf("the target whose endpoint is %s already exists", target.URL)) } if len(target.Password) != 0 { @@ -260,15 +260,15 @@ func (t *TargetAPI) Put() { } } - if target.URL != originalTarget.URL || target.Username != originalTarget.Username { - ta, err := dao.GetRepTargetByConnInfo(target.URL, target.Username) + if target.URL != originalTarget.URL { + ta, err := dao.GetRepTargetByEndpoint(target.URL) if err != nil { - log.Errorf("failed to get target [ %s %s ]: %v", target.URL, target.Username, err) + log.Errorf("failed to get target [ %s ]: %v", target.URL, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } if ta != nil { - t.CustomAbort(http.StatusConflict, "the connection information[ endpoint, username ] is conflict with other target") + t.CustomAbort(http.StatusConflict, fmt.Sprintf("the target whose endpoint is %s already exists", target.URL)) } } diff --git a/dao/dao_test.go b/dao/dao_test.go index 699224700..3d375927d 100644 --- a/dao/dao_test.go +++ b/dao/dao_test.go @@ -855,6 +855,22 @@ func TestGetRepTargetByName(t *testing.T) { } } +func TestGetRepTargetByEndpoint(t *testing.T) { + target, err := GetRepTarget(targetID) + if err != nil { + t.Fatalf("failed to get target %d: %v", targetID, err) + } + + target2, err := GetRepTargetByEndpoint(target.URL) + if err != nil { + t.Fatalf("failed to get target %s: %v", target.URL, err) + } + + if target.URL != target2.URL { + t.Errorf("unexpected target URL: %s, expected: %s", target2.URL, target.URL) + } +} + func TestUpdateRepTarget(t *testing.T) { target := &models.RepTarget{ Name: "name", diff --git a/dao/replication_job.go b/dao/replication_job.go index adc47391c..1c5a31cbc 100644 --- a/dao/replication_job.go +++ b/dao/replication_job.go @@ -53,14 +53,13 @@ func GetRepTargetByName(name string) (*models.RepTarget, error) { return &t, err } -// GetRepTargetByConnInfo ... -func GetRepTargetByConnInfo(endpoint, username string) (*models.RepTarget, error) { +// GetRepTargetByEndpoint ... +func GetRepTargetByEndpoint(endpoint string) (*models.RepTarget, error) { o := GetOrmer() t := models.RepTarget{ - URL: endpoint, - Username: username, + URL: endpoint, } - err := o.Read(&t, "URL", "Username") + err := o.Read(&t, "URL") if err == orm.ErrNoRows { return nil, nil } diff --git a/job/replication/transfer.go b/job/replication/transfer.go index 8ac3015bd..506f35477 100644 --- a/job/replication/transfer.go +++ b/job/replication/transfer.go @@ -28,6 +28,7 @@ import ( "github.com/docker/distribution" "github.com/docker/distribution/manifest/schema1" "github.com/docker/distribution/manifest/schema2" + "github.com/vmware/harbor/dao" "github.com/vmware/harbor/models" "github.com/vmware/harbor/utils/log" "github.com/vmware/harbor/utils/registry" @@ -192,7 +193,13 @@ enter: return "", err } if !exist { - err := c.createProject() + project, err := dao.GetProjectByName(c.project) + if err != nil { + c.logger.Errorf("an error occurred while getting project %s on %s: %v", c.project, c.srcURL, err) + return "", err + } + + err = c.createProject(project.Public == 1) if err != nil { // other job may be also doing the same thing when the current job // is creating project, so when the response code is 409, re-check @@ -286,13 +293,13 @@ func (c *Checker) projectExist() (exist, canWrite bool, err error) { return } -func (c *Checker) createProject() error { - // TODO handle publicity of project +func (c *Checker) createProject(isPublic bool) error { project := struct { ProjectName string `json:"project_name"` Public bool `json:"public"` }{ ProjectName: c.project, + Public: isPublic, } data, err := json.Marshal(project) @@ -495,8 +502,8 @@ func (m *ManifestPusher) enter() (string, error) { } else { m.logger.Infof("manifest of %s:%s exists on source registry %s, continue manifest pushing", name, tag, m.srcURL) - _, manifestExist, err := m.dstClient.ManifestExist(m.digest) - if manifestExist { + digest, manifestExist, err := m.dstClient.ManifestExist(tag) + if manifestExist && digest == m.digest { m.logger.Infof("manifest of %s:%s exists on destination registry %s, skip manifest pushing", name, tag, m.dstURL) m.tags = m.tags[1:]