Skip to content

Commit

Permalink
aliyun: make image replication idempotent
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
mike-nguyen committed Sep 12, 2024
1 parent db803c3 commit c211431
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions mantle/platform/api/aliyun/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,20 @@ func (a *API) CopyImage(source_id, dest_name, dest_region, dest_description, kms
Value: "mantle",
},
}

// Check if an image with the name has already been uploaded. This can
// happen when replication to a region fails which happens often on aliyun
images, err := a.GetImagesInRegion(dest_name, dest_region)
if err != nil {
return "", fmt.Errorf("getting image: %v", err)
}

// return early if there is already an image with that tag
if len(images.Images.Image) > 0 {
plog.Infof("image with name %v in %v region already exists--skipping copy", dest_name, dest_region)
return images.Images.Image[0].ImageId, nil
}

response, err := a.ecs.CopyImage(request)
if err != nil {
return "", fmt.Errorf("copying image: %v", err)
Expand Down Expand Up @@ -296,6 +310,16 @@ func (a *API) finishImportImageTask(importImageResponse *ecs.ImportImageResponse
return importImageResponse.ImageId, nil
}

// GetImagesInRegion retrieves a list of images by ImageName in a specified region
func (a *API) GetImagesInRegion(name string, region string) (*ecs.DescribeImagesResponse, error) {
request := ecs.CreateDescribeImagesRequest()
request.SetConnectTimeout(defaultConnectTimeout)
request.SetReadTimeout(defaultReadTimeout)
request.ImageName = name
request.RegionId = region
return a.ecs.DescribeImages(request)
}

// GetImages retrieves a list of images by ImageName
func (a *API) GetImages(name string) (*ecs.DescribeImagesResponse, error) {
request := ecs.CreateDescribeImagesRequest()
Expand Down

0 comments on commit c211431

Please sign in to comment.