diff --git a/api/replication_job.go b/api/replication_job.go index fd9da76cc..380018c7c 100644 --- a/api/replication_job.go +++ b/api/replication_job.go @@ -117,11 +117,8 @@ func (ra *RepJobAPI) GetLog() { } if resp.StatusCode == http.StatusOK { - for key, values := range resp.Header { - for _, value := range values { - ra.Ctx.ResponseWriter.Header().Set(key, value) - } - } + ra.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Length"), resp.Header.Get(http.CanonicalHeaderKey("Content-Length"))) + ra.Ctx.ResponseWriter.Header().Set(http.CanonicalHeaderKey("Content-Type"), "text/plain") if _, err = io.Copy(ra.Ctx.ResponseWriter, resp.Body); err != nil { log.Errorf("failed to write log to response; %v", err) diff --git a/dao/replication_job.go b/dao/replication_job.go index f77ce2b9f..6de5af82d 100644 --- a/dao/replication_job.go +++ b/dao/replication_job.go @@ -17,6 +17,7 @@ package dao import ( "fmt" + "time" "strings" @@ -253,8 +254,16 @@ func UpdateRepPolicyEnablement(id int64, enabled int) error { o := GetOrmer() p := models.RepPolicy{ ID: id, - Enabled: enabled} - _, err := o.Update(&p, "Enabled") + Enabled: enabled, + } + + var err error + if enabled == 1 { + p.StartTime = time.Now() + _, err = o.Update(&p, "Enabled", "StartTime") + } else { + _, err = o.Update(&p, "Enabled") + } return err } @@ -315,7 +324,7 @@ func FilterRepJobs(policyID int64, repository, status string) ([]*models.RepJob, if len(status) != 0 { qs = qs.Filter("Status__icontains", status) } - qs = qs.OrderBy("CreationTime") + qs = qs.OrderBy("-CreationTime") var jobs []*models.RepJob _, err := qs.All(&jobs) diff --git a/job/replication/transfer.go b/job/replication/transfer.go index dd2fba546..1df309f72 100644 --- a/job/replication/transfer.go +++ b/job/replication/transfer.go @@ -68,6 +68,7 @@ type BaseHandler struct { dstClient *registry.Repository manifest distribution.Manifest // manifest of tags[0] + digest string //digest of tags[0]'s manifest blobs []string // blobs need to be transferred for tags[0] blobsExistence map[string]bool //key: digest of blob, value: existence @@ -329,6 +330,7 @@ func (m *ManifestPuller) Enter() (string, error) { m.logger.Errorf("an error occurred while pulling manifest of %s:%s from %s: %v", name, tag, m.srcURL, err) return "", err } + m.digest = digest m.logger.Infof("manifest of %s:%s pulled successfully from %s: %s", name, tag, m.srcURL, digest) if strings.Contains(mediaType, "application/json") { @@ -426,6 +428,19 @@ func (m *ManifestPusher) Enter() (string, error) { m.logger.Infof("manifest of %s:%s does not exist on source registry %s, cancel manifest pushing", name, tag, m.srcURL) } 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 { + m.logger.Infof("manifest of %s:%s exists on destination registry %s, skip manifest pushing", name, tag, m.dstURL) + + m.tags = m.tags[1:] + m.manifest = nil + m.digest = "" + m.blobs = nil + + return StatePullManifest, nil + } + mediaType, data, err := m.manifest.Payload() if err != nil { m.logger.Errorf("an error occurred while getting payload of manifest for %s:%s : %v", name, tag, err) @@ -441,6 +456,7 @@ func (m *ManifestPusher) Enter() (string, error) { m.tags = m.tags[1:] m.manifest = nil + m.digest = "" m.blobs = nil return StatePullManifest, nil