cloud-cleaner: clean up GCP Storage objects based on metadata
Add StorageListObjectsByMetadata() to internal GCP library. The method allows one to search specific Storage bucket for objects based on provided metadata. Extend cloud-cleaner to search for any Storage objects related to the image import, using custom metadata set on the object. Delete all found objects. Signed-off-by: Tomas Hozza <thozza@redhat.com>
This commit is contained in:
parent
e698080bc7
commit
e04b75f3df
2 changed files with 68 additions and 0 deletions
|
|
@ -28,6 +28,11 @@ func cleanupGCP(testID string, wg *sync.WaitGroup) {
|
|||
}
|
||||
// api.sh test uses '--zone="$GCP_REGION-a"'
|
||||
GCPZone := fmt.Sprintf("%s-a", GCPRegion)
|
||||
GCPBucket, ok := os.LookupEnv("GCP_BUCKET")
|
||||
if !ok {
|
||||
log.Println("[GCP] Error: 'GCP_BUCKET' is not set in the environment.")
|
||||
return
|
||||
}
|
||||
// max 62 characters
|
||||
// Must be a match of regex '[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?|[1-9][0-9]{0,19}'
|
||||
// use sha224sum to get predictable testID without invalid characters
|
||||
|
|
@ -73,6 +78,18 @@ func cleanupGCP(testID string, wg *sync.WaitGroup) {
|
|||
log.Printf("[GCP] 🧹 Deleted image import job file %s", cacheObject)
|
||||
}
|
||||
|
||||
// Try to find the potentially uploaded Storage objects using custom metadata
|
||||
objects, err := g.StorageListObjectsByMetadata(GCPBucket, map[string]string{gcp.MetadataKeyImageName: GCPImage})
|
||||
if err != nil {
|
||||
log.Printf("[GCP] Error: %v", err)
|
||||
}
|
||||
for _, obj := range objects {
|
||||
if err = g.StorageObjectDelete(obj.Bucket, obj.Name); err != nil {
|
||||
log.Printf("[GCP] Error: %v", err)
|
||||
}
|
||||
log.Printf("[GCP] 🧹 Deleted object %s/%s related to build of image %s", obj.Bucket, obj.Name, GCPImage)
|
||||
}
|
||||
|
||||
// Try to delete the imported image
|
||||
log.Printf("[GCP] 🧹 Deleting image %s. This should fail if the test succedded.", GCPImage)
|
||||
err = g.ComputeImageDelete(GCPImage)
|
||||
|
|
|
|||
|
|
@ -196,3 +196,54 @@ func (g *GCP) StorageImageImportCleanup(imageName string) ([]string, []error) {
|
|||
|
||||
return deletedObjects, errors
|
||||
}
|
||||
|
||||
// StorageListObjectsByMetadata searches specified Storage bucket for objects matching the provided
|
||||
// metadata. The provided metadata is used for filtering the bucket's content. Therefore if the provided
|
||||
// metadata is nil, then all objects present in the bucket will be returned.
|
||||
//
|
||||
// Matched objects are returned as a list of ObjectAttrs.
|
||||
//
|
||||
// Uses:
|
||||
// - Storage API
|
||||
func (g *GCP) StorageListObjectsByMetadata(bucket string, metadata map[string]string) ([]*storage.ObjectAttrs, error) {
|
||||
var matchedObjectAttr []*storage.ObjectAttrs
|
||||
ctx := context.Background()
|
||||
|
||||
storageClient, err := storage.NewClient(ctx, option.WithCredentials(g.creds))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get Storage client: %v", err)
|
||||
}
|
||||
defer storageClient.Close()
|
||||
|
||||
objects := storageClient.Bucket(bucket).Objects(ctx, nil)
|
||||
for {
|
||||
obj, err := objects.Next()
|
||||
if err == iterator.Done {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failure while iterating over bucket objects: %v", err)
|
||||
}
|
||||
|
||||
// check if the object's Metadata match the provided values
|
||||
metadataMatch := true
|
||||
for key, value := range metadata {
|
||||
objMetadataValue, ok := obj.Metadata[key]
|
||||
if !ok {
|
||||
metadataMatch = false
|
||||
break
|
||||
}
|
||||
if objMetadataValue != value {
|
||||
metadataMatch = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if metadataMatch {
|
||||
matchedObjectAttr = append(matchedObjectAttr, obj)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return matchedObjectAttr, nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue