diff --git a/pkg/cloudprovider/objectstore.go b/pkg/cloudprovider/objectstore.go index 0e8dd573c1..6dd6d359cc 100644 --- a/pkg/cloudprovider/objectstore.go +++ b/pkg/cloudprovider/objectstore.go @@ -840,7 +840,7 @@ func DeleteBucketCORS(ibucket ICloudBucket, id []string) ([]SBucketCORSRule, err return deletedRules, nil } -func SetBucketTags(iBucket ICloudBucket, tags map[string]string) (TagsUpdateInfo, error) { +func SetBucketTags(ctx context.Context, iBucket ICloudBucket, mangerId string, tags map[string]string) (TagsUpdateInfo, error) { ret := TagsUpdateInfo{} old, err := iBucket.GetTags() if err != nil { @@ -853,5 +853,5 @@ func SetBucketTags(iBucket ICloudBucket, tags map[string]string) (TagsUpdateInfo if !ret.IsChanged() { return ret, nil } - return ret, iBucket.SetTags(tags, true) + return ret, SetTags(ctx, iBucket, mangerId, tags, true) } diff --git a/pkg/cloudprovider/resourcetags.go b/pkg/cloudprovider/resourcetags.go index f212b7b4e9..81de0809c8 100644 --- a/pkg/cloudprovider/resourcetags.go +++ b/pkg/cloudprovider/resourcetags.go @@ -14,7 +14,16 @@ package cloudprovider -import "reflect" +import ( + "context" + "reflect" + + "yunion.io/x/onecloud/pkg/cloudcommon/db/lockman" +) + +const ( + SET_TAGS = "set-tags" +) type TagsUpdateInfo struct { OldTags map[string]string @@ -24,3 +33,12 @@ type TagsUpdateInfo struct { func (t TagsUpdateInfo) IsChanged() bool { return !reflect.DeepEqual(t.OldTags, t.NewTags) } + +func SetTags(ctx context.Context, res ICloudResource, managerId string, tags map[string]string, replace bool) error { + // 避免同时设置多个资源标签出现以下错误 + // Code=ResourceInUse.TagDuplicate, Message=tagKey-tagValue have exists., RequestId=e87714c0-e50b-4241-b79d-32897437174d + lockman.LockRawObject(ctx, SET_TAGS, managerId) + defer lockman.ReleaseRawObject(ctx, SET_TAGS, managerId) + + return res.SetTags(tags, replace) +} diff --git a/pkg/compute/guestdrivers/managedvirtual.go b/pkg/compute/guestdrivers/managedvirtual.go index 38514c843b..c09fff9522 100644 --- a/pkg/compute/guestdrivers/managedvirtual.go +++ b/pkg/compute/guestdrivers/managedvirtual.go @@ -1235,7 +1235,8 @@ func (self *SManagedVirtualizedGuestDriver) RequestRemoteUpdate(ctx context.Cont return errors.Wrapf(err, "GetAllUserMetadata") } tagsUpdateInfo := cloudprovider.TagsUpdateInfo{OldTags: oldTags, NewTags: tags} - err = iVM.SetTags(tags, replaceTags) + + err = cloudprovider.SetTags(ctx, iVM, guest.GetHost().ManagerId, tags, replaceTags) if err != nil { if errors.Cause(err) == cloudprovider.ErrNotSupported || errors.Cause(err) == cloudprovider.ErrNotImplemented { return nil diff --git a/pkg/compute/models/buckets.go b/pkg/compute/models/buckets.go index bc350a8b20..4883309add 100644 --- a/pkg/compute/models/buckets.go +++ b/pkg/compute/models/buckets.go @@ -541,7 +541,7 @@ func (bucket *SBucket) RemoteCreate(ctx context.Context, userCred mcclient.Token } tags, _ := bucket.GetAllUserMetadata() if len(tags) > 0 { - _, err = cloudprovider.SetBucketTags(extBucket, tags) + _, err = cloudprovider.SetBucketTags(ctx, extBucket, bucket.ManagerId, tags) if err != nil { logclient.AddSimpleActionLog(bucket, logclient.ACT_UPDATE_TAGS, err, userCred, false) } @@ -1906,7 +1906,7 @@ func (bucket *SBucket) OnMetadataUpdated(ctx context.Context, userCred mcclient. if err != nil { return } - diff, err := cloudprovider.SetBucketTags(iBucket, tags) + diff, err := cloudprovider.SetBucketTags(ctx, iBucket, bucket.ManagerId, tags) if err != nil { logclient.AddSimpleActionLog(bucket, logclient.ACT_UPDATE_TAGS, err, userCred, false) return diff --git a/pkg/compute/regiondrivers/managedvirtual.go b/pkg/compute/regiondrivers/managedvirtual.go index 42523e4c13..1716b75084 100644 --- a/pkg/compute/regiondrivers/managedvirtual.go +++ b/pkg/compute/regiondrivers/managedvirtual.go @@ -342,7 +342,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestRemoteUpdateLoadbalancer( return nil, errors.Wrapf(err, "lb.GetAllUserMetadata") } tagsUpdateInfo := cloudprovider.TagsUpdateInfo{OldTags: oldTags, NewTags: tags} - err = iLoadbalancer.SetTags(tags, replaceTags) + err = cloudprovider.SetTags(ctx, iLoadbalancer, lb.ManagerId, tags, replaceTags) if err != nil { if errors.Cause(err) == cloudprovider.ErrNotSupported || errors.Cause(err) == cloudprovider.ErrNotImplemented { return nil, nil @@ -2527,7 +2527,7 @@ func (self *SManagedVirtualizationRegionDriver) RequestRemoteUpdateDBInstance(ct return nil, errors.Wrapf(err, "instance.GetAllUserMetadata") } tagsUpdateInfo := cloudprovider.TagsUpdateInfo{OldTags: oldTags, NewTags: tags} - err = iRds.SetTags(tags, replaceTags) + err = cloudprovider.SetTags(ctx, iRds, instance.ManagerId, tags, replaceTags) if err != nil { if errors.Cause(err) == cloudprovider.ErrNotSupported || errors.Cause(err) == cloudprovider.ErrNotImplemented { return nil, nil @@ -2936,7 +2936,11 @@ func (self *SManagedVirtualizationRegionDriver) RequestRemoteUpdateElasticcache( return nil, errors.Wrapf(err, "GetAllUserMetadata") } tagsUpdateInfo := cloudprovider.TagsUpdateInfo{OldTags: oldTags, NewTags: tags} - err = iElasticcache.SetTags(tags, replaceTags) + mangerId := "" + if vpc := elasticcache.GetVpc(); vpc != nil { + mangerId = vpc.ManagerId + } + err = cloudprovider.SetTags(ctx, iElasticcache, mangerId, tags, replaceTags) if err != nil { if errors.Cause(err) == cloudprovider.ErrNotSupported || errors.Cause(err) == cloudprovider.ErrNotImplemented { return nil, nil diff --git a/pkg/multicloud/objectstore/shell.go b/pkg/multicloud/objectstore/shell.go index 3596e81ec8..3c831b31b1 100644 --- a/pkg/multicloud/objectstore/shell.go +++ b/pkg/multicloud/objectstore/shell.go @@ -722,7 +722,7 @@ func S3Shell() { tags[pair[0]] = pair[1] } } - _, err = cloudprovider.SetBucketTags(bucket, tags) + _, err = cloudprovider.SetBucketTags(context.Background(), bucket, "", tags) if err != nil { return err }