mirror of
https://github.com/goharbor/harbor.git
synced 2024-12-24 09:38:09 +01:00
fix(scanner): process scenario reinstall without clair flag
1. Fix name conflict when install internal clair adapter. 2. Remove all internal adapters when reinstall harbor without --with-clair flag Signed-off-by: He Weiwei <hweiwei@vmware.com>
This commit is contained in:
parent
7b12ed14a1
commit
0246ca7aa4
@ -226,9 +226,13 @@ func main() {
|
|||||||
Immutable: true,
|
Immutable: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := scan.EnsureScanner(reg); err != nil {
|
if err := scan.EnsureScanner(reg, true); err != nil {
|
||||||
log.Fatalf("failed to initialize clair scanner: %v", err)
|
log.Fatalf("failed to initialize clair scanner: %v", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if err := scan.RemoveImmutableScanners(); err != nil {
|
||||||
|
log.Warningf("failed to remove immutable scanners: %v", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
closing := make(chan struct{})
|
closing := make(chan struct{})
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/astaxie/beego/orm"
|
"github.com/astaxie/beego/orm"
|
||||||
"github.com/goharbor/harbor/src/common/dao"
|
"github.com/goharbor/harbor/src/common/dao"
|
||||||
"github.com/goharbor/harbor/src/pkg/q"
|
"github.com/goharbor/harbor/src/pkg/q"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +32,16 @@ func init() {
|
|||||||
// AddRegistration adds a new registration
|
// AddRegistration adds a new registration
|
||||||
func AddRegistration(r *Registration) (int64, error) {
|
func AddRegistration(r *Registration) (int64, error) {
|
||||||
o := dao.GetOrmer()
|
o := dao.GetOrmer()
|
||||||
return o.Insert(r)
|
|
||||||
|
id, err := o.Insert(r)
|
||||||
|
if err != nil {
|
||||||
|
if strings.Contains(err.Error(), "duplicate key value violates unique constraint") {
|
||||||
|
return 0, types.ErrDupRows
|
||||||
|
}
|
||||||
|
return 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetRegistration gets the specified registration
|
// GetRegistration gets the specified registration
|
||||||
|
@ -21,14 +21,17 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/pkg/q"
|
"github.com/goharbor/harbor/src/pkg/q"
|
||||||
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
|
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
|
||||||
sc "github.com/goharbor/harbor/src/pkg/scan/scanner"
|
sc "github.com/goharbor/harbor/src/pkg/scan/scanner"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/types"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/pkg/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
scannerManager = sc.New()
|
scannerManager = sc.New()
|
||||||
)
|
)
|
||||||
|
|
||||||
// EnsureScanner ensure the scanner which specially name exists in the system
|
// EnsureScanner ensure the scanner which specially endpoint exists in the system
|
||||||
func EnsureScanner(registration *scanner.Registration) error {
|
func EnsureScanner(registration *scanner.Registration, resolveConflicts ...bool) error {
|
||||||
q := &q.Query{
|
q := &q.Query{
|
||||||
Keywords: map[string]interface{}{"url": registration.URL},
|
Keywords: map[string]interface{}{"url": registration.URL},
|
||||||
}
|
}
|
||||||
@ -39,8 +42,17 @@ func EnsureScanner(registration *scanner.Registration) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(registrations) == 0 {
|
if len(registrations) > 0 {
|
||||||
defaultReg, err := scannerManager.GetDefault()
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var resolveConflict bool
|
||||||
|
if len(resolveConflicts) > 0 {
|
||||||
|
resolveConflict = resolveConflicts[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
var defaultReg *scanner.Registration
|
||||||
|
defaultReg, err = scannerManager.GetDefault()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get the default scanner, error: %v", err)
|
return fmt.Errorf("failed to get the default scanner, error: %v", err)
|
||||||
}
|
}
|
||||||
@ -48,11 +60,47 @@ func EnsureScanner(registration *scanner.Registration) error {
|
|||||||
// Set the registration to be default one when no default registration exist in the system
|
// Set the registration to be default one when no default registration exist in the system
|
||||||
registration.IsDefault = defaultReg == nil
|
registration.IsDefault = defaultReg == nil
|
||||||
|
|
||||||
if _, err := scannerManager.Create(registration); err != nil {
|
for {
|
||||||
|
_, err = scannerManager.Create(registration)
|
||||||
|
if err != nil {
|
||||||
|
if resolveConflict && errors.Cause(err) == types.ErrDupRows {
|
||||||
|
var id uuid.UUID
|
||||||
|
id, err = uuid.NewUUID()
|
||||||
|
if err != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
registration.Name = registration.Name + "-" + id.String()
|
||||||
|
resolveConflict = false
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == nil {
|
||||||
|
log.Infof("initialized scanner named %s", registration.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveImmutableScanners remove all immutable scanners in the system
|
||||||
|
func RemoveImmutableScanners() error {
|
||||||
|
q := &q.Query{
|
||||||
|
Keywords: map[string]interface{}{"immutable": true},
|
||||||
|
}
|
||||||
|
|
||||||
|
registrations, err := scannerManager.List(q)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Infof("initialized scanner named %s", registration.Name)
|
for _, reg := range registrations {
|
||||||
|
if err := scannerManager.Delete(reg.UUID); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
|
"github.com/goharbor/harbor/src/pkg/scan/dao/scanner"
|
||||||
sc "github.com/goharbor/harbor/src/pkg/scan/scanner"
|
sc "github.com/goharbor/harbor/src/pkg/scan/scanner"
|
||||||
"github.com/goharbor/harbor/src/pkg/scan/scanner/mocks"
|
"github.com/goharbor/harbor/src/pkg/scan/scanner/mocks"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
@ -32,6 +33,7 @@ type managerOptions struct {
|
|||||||
getError error
|
getError error
|
||||||
getDefaultError error
|
getDefaultError error
|
||||||
createError error
|
createError error
|
||||||
|
createErrorFn func(*scanner.Registration) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func newManager(opts *managerOptions) sc.Manager {
|
func newManager(opts *managerOptions) sc.Manager {
|
||||||
@ -95,10 +97,18 @@ func newManager(opts *managerOptions) sc.Manager {
|
|||||||
return reg.URL
|
return reg.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
createError := func(reg *scanner.Registration) error {
|
||||||
|
if opts.createErrorFn != nil {
|
||||||
|
return opts.createErrorFn(reg)
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts.createError
|
||||||
|
}
|
||||||
|
|
||||||
mgr.On("List", mock.AnythingOfType("*q.Query")).Return(listFn, opts.listError)
|
mgr.On("List", mock.AnythingOfType("*q.Query")).Return(listFn, opts.listError)
|
||||||
mgr.On("Get", mock.AnythingOfType("string")).Return(getFn, opts.getError)
|
mgr.On("Get", mock.AnythingOfType("string")).Return(getFn, opts.getError)
|
||||||
mgr.On("GetDefault").Return(getDefaultFn, opts.getDefaultError)
|
mgr.On("GetDefault").Return(getDefaultFn, opts.getDefaultError)
|
||||||
mgr.On("Create", mock.AnythingOfType("*scanner.Registration")).Return(createFn, opts.createError)
|
mgr.On("Create", mock.AnythingOfType("*scanner.Registration")).Return(createFn, createError)
|
||||||
|
|
||||||
return mgr
|
return mgr
|
||||||
}
|
}
|
||||||
@ -176,3 +186,30 @@ func TestEnsureScanner(t *testing.T) {
|
|||||||
assert.NotNil(reg3)
|
assert.NotNil(reg3)
|
||||||
assert.False(reg3.IsDefault)
|
assert.False(reg3.IsDefault)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestEnsureScannerWithResolveConflict(t *testing.T) {
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
registrations := []*scanner.Registration{
|
||||||
|
{URL: "reg1"},
|
||||||
|
}
|
||||||
|
|
||||||
|
// create registration got ErrDupRows when its name is Clair
|
||||||
|
scannerManager = newManager(
|
||||||
|
&managerOptions{
|
||||||
|
registrations: registrations,
|
||||||
|
|
||||||
|
createErrorFn: func(reg *scanner.Registration) error {
|
||||||
|
if reg.Name == "Clair" {
|
||||||
|
return errors.Wrap(types.ErrDupRows, "failed to create reg")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.Nil(EnsureScanner(&scanner.Registration{Name: "Clair", URL: "reg1"}))
|
||||||
|
assert.Error(EnsureScanner(&scanner.Registration{Name: "Clair", URL: "reg2"}))
|
||||||
|
assert.Nil(EnsureScanner(&scanner.Registration{Name: "Clair", URL: "reg2"}, true))
|
||||||
|
}
|
||||||
|
24
src/pkg/types/error.go
Normal file
24
src/pkg/types/error.go
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright Project Harbor Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package types
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
// ErrDupRows is returned by DAO when inserting failed with error "duplicate key value violates unique constraint"
|
||||||
|
ErrDupRows = errors.New("sql: duplicate row in DB")
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user