harbor从v1.1.1升级到v1.5.1的记录(三)

之前写了两篇harbor的博客,主要是v1.1.1同步到v1.5.1的数据同步以及安装方面的,现在分析harbor的同步功能,因为公司的业务需要对接,就修改了harbor的同步规则,

主要是修改了harbor的同步机制

写了个interface{}

package registry

import (
    "io"
)

type RepositoryInterface interface {
    ListTag() ([]string, error)
    ManifestExist(reference string) (digest string, exist bool, err error)
    PullManifest(reference string, acceptMediaTypes []string) (digest, mediaType string, payload []byte, err error)
    PushManifest(reference, mediaType string, payload []byte) (digest string, err error)
    DeleteManifest(digest string) error
    DeleteTag(tag string) error
    BlobExist(digest string) (bool, error)
    PullBlob(digest string) (size int64, data io.ReadCloser, err error)
    initiateBlobUpload(name string) (location, uploadUUID string, err error)
    monolithicBlobUpload(location, digest string, size int64, data io.Reader) error
    PushBlob(digest string, size int64, data io.Reader) error
    DeleteBlob(digest string) error
}

harbor以及自己要实现的同步到huawei的镜像仓库都实现了这个接口RepositoryInterface

// PushBlob ...
func (r *RepositoryHuawei) PushBlob(digest string, size int64, data io.Reader) error {
    log.Infof("RepositoryHuawei r.Name=%s,r.client=%v,r.Endpoint=%s\n", r.Name, r.client, r.Endpoint)
    _, uuid, err := r.initiateBlobUpload(r.Name)
    if err != nil {
        return err
    }

    _, _, err = r.patchUploads(uuid, data)
    if err != nil {
        return err
    }

    return r.putUploads(digest, uuid)
}
func (r *RepositoryHuawei) putUploads(digest, uuid string) (err error) {
    req, err := http.NewRequest("PUT", buildBlobUploadURL(r.Endpoint.String(), r.Name, uuid, digest), nil)

    resp, err := r.client.Do(req)
    if nil != err {
        err = parseError(err)
        return
    }

    defer resp.Body.Close()

    if http.StatusAccepted == resp.StatusCode || http.StatusCreated == resp.StatusCode {
        return
    }
    b, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return
    }

    err = &registry_error.HTTPError{
        StatusCode: resp.StatusCode,
        Detail:     string(b),
    }

    return
}

func (r *RepositoryHuawei) patchUploads(uuid string, data io.Reader) (location, uploadUUID string, err error) {
    req, err := http.NewRequest("PATCH", buildInitiateBlobUploadWithUuidURL(r.Endpoint.String(), r.Name, uuid), data)

    resp, err := r.client.Do(req)
    if nil != err {
        err = parseError(err)
        return
    }
    defer resp.Body.Close()

    if http.StatusCreated == resp.StatusCode || http.StatusAccepted == resp.StatusCode {
        location = resp.Header.Get(http.CanonicalHeaderKey("Location"))
        uploadUUID = resp.Header.Get(http.CanonicalHeaderKey("Docker-Upload-Uuid"))
        return
    }

    b, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return
    }

    err = &registry_error.HTTPError{
        StatusCode: resp.StatusCode,
        Detail:     string(b),
    }

    return
}

这个是根据docker client的方式,先post 然后patch上传,put结束,
是docker client的方式,所以现在处理的是patch的时候保存镜像层,不然会报404的错误
111

猜你喜欢

转载自blog.csdn.net/qq_21816375/article/details/81480566