Skip to content

Commit c211431

Browse files
committed
aliyun: make image replication idempotent
There is a history of failure copying images to other regions on aliyun. Upstream code that calls the CopyImage code more than once will get a DuplicateImage error when an image with the same name already exists. Let's check to see if the image name exists in the region before attempting to copy the image to the region and return early if it already exists.
1 parent db803c3 commit c211431

File tree

1 file changed

+24
-0
lines changed
  • mantle/platform/api/aliyun

1 file changed

+24
-0
lines changed

mantle/platform/api/aliyun/api.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,20 @@ func (a *API) CopyImage(source_id, dest_name, dest_region, dest_description, kms
134134
Value: "mantle",
135135
},
136136
}
137+
138+
// Check if an image with the name has already been uploaded. This can
139+
// happen when replication to a region fails which happens often on aliyun
140+
images, err := a.GetImagesInRegion(dest_name, dest_region)
141+
if err != nil {
142+
return "", fmt.Errorf("getting image: %v", err)
143+
}
144+
145+
// return early if there is already an image with that tag
146+
if len(images.Images.Image) > 0 {
147+
plog.Infof("image with name %v in %v region already exists--skipping copy", dest_name, dest_region)
148+
return images.Images.Image[0].ImageId, nil
149+
}
150+
137151
response, err := a.ecs.CopyImage(request)
138152
if err != nil {
139153
return "", fmt.Errorf("copying image: %v", err)
@@ -296,6 +310,16 @@ func (a *API) finishImportImageTask(importImageResponse *ecs.ImportImageResponse
296310
return importImageResponse.ImageId, nil
297311
}
298312

313+
// GetImagesInRegion retrieves a list of images by ImageName in a specified region
314+
func (a *API) GetImagesInRegion(name string, region string) (*ecs.DescribeImagesResponse, error) {
315+
request := ecs.CreateDescribeImagesRequest()
316+
request.SetConnectTimeout(defaultConnectTimeout)
317+
request.SetReadTimeout(defaultReadTimeout)
318+
request.ImageName = name
319+
request.RegionId = region
320+
return a.ecs.DescribeImages(request)
321+
}
322+
299323
// GetImages retrieves a list of images by ImageName
300324
func (a *API) GetImages(name string) (*ecs.DescribeImagesResponse, error) {
301325
request := ecs.CreateDescribeImagesRequest()

0 commit comments

Comments
 (0)