Merge pull request #7403 from ywk253100/190416_prepare_for_push

Update the PrepareForPush method
This commit is contained in:
Wenkai Yin 2019-04-16 18:47:42 +08:00 committed by GitHub
commit aa188954ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 155 additions and 135 deletions

View File

@ -30,9 +30,9 @@ type Factory func(*model.Registry) (Adapter, error)
type Adapter interface { type Adapter interface {
// Info return the information of this adapter // Info return the information of this adapter
Info() (*model.RegistryInfo, error) Info() (*model.RegistryInfo, error)
// PrepareForPush does the prepare work that needed for pushing/uploading the resource // PrepareForPush does the prepare work that needed for pushing/uploading the resources
// eg: create the namespace or repository // eg: create the namespace or repository
PrepareForPush(*model.Resource) error PrepareForPush([]*model.Resource) error
// HealthCheck checks health status of registry // HealthCheck checks health status of registry
HealthCheck() (model.HealthStatus, error) HealthCheck() (model.HealthStatus, error)
} }

View File

@ -79,7 +79,9 @@ func (a *adapter) Info() (*model.RegistryInfo, error) {
// PrepareForPush does the prepare work that needed for pushing/uploading the resource // PrepareForPush does the prepare work that needed for pushing/uploading the resource
// eg: create the namespace or repository // eg: create the namespace or repository
func (a *adapter) PrepareForPush(resource *model.Resource) error { func (a *adapter) PrepareForPush(resources []*model.Resource) error {
namespaces := map[string]struct{}{}
for _, resource := range resources {
if resource == nil { if resource == nil {
return errors.New("the resource cannot be null") return errors.New("the resource cannot be null")
} }
@ -97,16 +99,20 @@ func (a *adapter) PrepareForPush(resource *model.Resource) error {
// just skip here and the following task will fail // just skip here and the following task will fail
if len(namespace) == 0 { if len(namespace) == 0 {
log.Debug("the namespace is empty, skip") log.Debug("the namespace is empty, skip")
return nil continue
} }
namespaces[namespace] = struct{}{}
}
for namespace := range namespaces {
err := a.CreateNamespace(&model.Namespace{ err := a.CreateNamespace(&model.Namespace{
Name: namespace, Name: namespace,
}) })
if err != nil { if err != nil {
return fmt.Errorf("create namespace '%s' in DockerHub error: %v", namespace, err) return fmt.Errorf("create namespace '%s' in DockerHub error: %v", namespace, err)
} }
}
return nil return nil
} }

View File

@ -136,7 +136,9 @@ func (a *adapter) Info() (*model.RegistryInfo, error) {
return info, nil return info, nil
} }
func (a *adapter) PrepareForPush(resource *model.Resource) error { func (a *adapter) PrepareForPush(resources []*model.Resource) error {
projects := map[string]*project{}
for _, resource := range resources {
if resource == nil { if resource == nil {
return errors.New("the resource cannot be null") return errors.New("the resource cannot be null")
} }
@ -154,15 +156,22 @@ func (a *adapter) PrepareForPush(resource *model.Resource) error {
// just skip here and the following task will fail // just skip here and the following task will fail
if len(projectName) == 0 { if len(projectName) == 0 {
log.Debug("the project name is empty, skip") log.Debug("the project name is empty, skip")
continue
}
// TODO handle the public
projects[projectName] = &project{
Name: projectName,
}
}
for _, project := range projects {
err := a.client.Post(a.coreServiceURL+"/api/projects", project)
if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusConflict {
log.Debugf("got 409 when trying to create project %s", project.Name)
return nil return nil
} }
project := &struct { return err
Name string `json:"project_name"`
Metadata map[string]interface{} `json:"metadata"`
}{
Name: projectName,
// TODO handle the public
} }
return nil
// TODO // TODO
/* /*
@ -185,13 +194,6 @@ func (a *adapter) PrepareForPush(resource *model.Resource) error {
} }
} }
*/ */
err := a.client.Post(a.coreServiceURL+"/api/projects", project)
if httpErr, ok := err.(*common_http.Error); ok && httpErr.Code == http.StatusConflict {
log.Debugf("got 409 when trying to create project %s", projectName)
return nil
}
return err
} }
type project struct { type project struct {

View File

@ -87,30 +87,41 @@ func TestPrepareForPush(t *testing.T) {
adapter, err := newAdapter(registry) adapter, err := newAdapter(registry)
require.Nil(t, err) require.Nil(t, err)
// nil resource // nil resource
err = adapter.PrepareForPush(nil) err = adapter.PrepareForPush([]*model.Resource{nil})
require.NotNil(t, err) require.NotNil(t, err)
// nil metadata // nil metadata
err = adapter.PrepareForPush(&model.Resource{}) err = adapter.PrepareForPush([]*model.Resource{
{},
})
require.NotNil(t, err) require.NotNil(t, err)
// nil repository // nil repository
err = adapter.PrepareForPush(&model.Resource{ err = adapter.PrepareForPush(
[]*model.Resource{
{
Metadata: &model.ResourceMetadata{}, Metadata: &model.ResourceMetadata{},
},
}) })
require.NotNil(t, err) require.NotNil(t, err)
// nil repository name // nil repository name
err = adapter.PrepareForPush(&model.Resource{ err = adapter.PrepareForPush(
[]*model.Resource{
{
Metadata: &model.ResourceMetadata{ Metadata: &model.ResourceMetadata{
Repository: &model.Repository{}, Repository: &model.Repository{},
}, },
},
}) })
require.NotNil(t, err) require.NotNil(t, err)
// project doesn't exist // project doesn't exist
err = adapter.PrepareForPush(&model.Resource{ err = adapter.PrepareForPush(
[]*model.Resource{
{
Metadata: &model.ResourceMetadata{ Metadata: &model.ResourceMetadata{
Repository: &model.Repository{ Repository: &model.Repository{
Name: "library/hello-world", Name: "library/hello-world",
}, },
}, },
},
}) })
require.Nil(t, err) require.Nil(t, err)
@ -129,12 +140,15 @@ func TestPrepareForPush(t *testing.T) {
} }
adapter, err = newAdapter(registry) adapter, err = newAdapter(registry)
require.Nil(t, err) require.Nil(t, err)
err = adapter.PrepareForPush(&model.Resource{ err = adapter.PrepareForPush(
[]*model.Resource{
{
Metadata: &model.ResourceMetadata{ Metadata: &model.ResourceMetadata{
Repository: &model.Repository{ Repository: &model.Repository{
Name: "library/hello-world", Name: "library/hello-world",
}, },
}, },
},
}) })
require.Nil(t, err) require.Nil(t, err)
} }

View File

@ -120,8 +120,9 @@ func (adapter Adapter) ConvertResourceMetadata(resourceMetadata *model.ResourceM
} }
// PrepareForPush prepare for push to Huawei SWR // PrepareForPush prepare for push to Huawei SWR
func (adapter Adapter) PrepareForPush(resource *model.Resource) error { func (adapter Adapter) PrepareForPush(resources []*model.Resource) error {
// TODO optimize the logic by merging the same namesapces
for _, resource := range resources {
namespace, _ := util.ParseRepository(resource.Metadata.Repository.Name) namespace, _ := util.ParseRepository(resource.Metadata.Repository.Name)
ns, err := adapter.GetNamespace(namespace) ns, err := adapter.GetNamespace(namespace)
if err != nil { if err != nil {
@ -168,6 +169,7 @@ func (adapter Adapter) PrepareForPush(resource *model.Resource) error {
body, _ := ioutil.ReadAll(resp.Body) body, _ := ioutil.ReadAll(resp.Body)
return fmt.Errorf("[%d][%s]", code, string(body)) return fmt.Errorf("[%d][%s]", code, string(body))
} }
}
return nil return nil
} }

View File

@ -49,7 +49,7 @@ func TestAdapter_PrepareForPush(t *testing.T) {
Repository: repository, Repository: repository,
} }
resource.Metadata = metadata resource.Metadata = metadata
err := hwAdapter.PrepareForPush(resource) err := hwAdapter.PrepareForPush([]*model.Resource{resource})
if err != nil { if err != nil {
if strings.HasPrefix(err.Error(), "[401]") { if strings.HasPrefix(err.Error(), "[401]") {
t.Log("huawei ak/sk is not available", err.Error()) t.Log("huawei ak/sk is not available", err.Error())

View File

@ -74,4 +74,4 @@ func (native) Info() (info *model.RegistryInfo, err error) {
} }
// PrepareForPush nothing need to do. // PrepareForPush nothing need to do.
func (native) PrepareForPush(*model.Resource) error { return nil } func (native) PrepareForPush([]*model.Resource) error { return nil }

View File

@ -130,7 +130,7 @@ func (f *fakedAdapter) Info() (*model.RegistryInfo, error) {
}, nil }, nil
} }
func (f *fakedAdapter) PrepareForPush(*model.Resource) error { func (f *fakedAdapter) PrepareForPush([]*model.Resource) error {
return nil return nil
} }
func (f *fakedAdapter) HealthCheck() (model.HealthStatus, error) { func (f *fakedAdapter) HealthCheck() (model.HealthStatus, error) {

View File

@ -209,14 +209,10 @@ func assembleDestinationResources(resources []*model.Resource,
// do the prepare work for pushing/uploading the resources: create the namespace or repository // do the prepare work for pushing/uploading the resources: create the namespace or repository
func prepareForPush(adapter adp.Adapter, resources []*model.Resource) error { func prepareForPush(adapter adp.Adapter, resources []*model.Resource) error {
// TODO need to consider how to handle that both contains public/private namespace if err := adapter.PrepareForPush(resources); err != nil {
for _, resource := range resources { return fmt.Errorf("failed to do the prepare work for pushing/uploading resources: %v", err)
name := resource.Metadata.Repository.Name
if err := adapter.PrepareForPush(resource); err != nil {
return fmt.Errorf("failed to do the prepare work for pushing/uploading %s: %v", name, err)
}
log.Debugf("the prepare work for pushing/uploading %s completed", name)
} }
log.Debug("the prepare work for pushing/uploading resources completed")
return nil return nil
} }

View File

@ -46,7 +46,7 @@ func (f *fakedAdapter) Info() (*model.RegistryInfo, error) {
}, nil }, nil
} }
func (f *fakedAdapter) PrepareForPush(*model.Resource) error { func (f *fakedAdapter) PrepareForPush([]*model.Resource) error {
return nil return nil
} }
func (f *fakedAdapter) HealthCheck() (model.HealthStatus, error) { func (f *fakedAdapter) HealthCheck() (model.HealthStatus, error) {