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 authored and openshift-cherrypick-robot committed Sep 13, 2024
1 parent b0e87e4 commit 0d10f94
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 0d10f94

Please sign in to comment.