I want to check if I can delete some of our AWS EBS snapshots that meet a certain criteria. However, since we have a LOT of snapshots, I don't want to iterate one-by-one, and instead perform the check if I can delete them in parallel. I get a list of snapshots in JSON form like this
{
"Snapshots": [
{
"Description": "",
"Encrypted": false,
"OwnerId": "0123456789",
"Progress": "100%",
"SnapshotId": "snap-0123456789",
"StartTime": "2021-03-23T23:58:42.019000+00:00",
"State": "completed",
"VolumeId": "vol-ffffffff",
"VolumeSize": 8,
"OwnerAlias": "amazon",
"StorageTier": "standard"
},
// more snapshots
]
}
Here's the (simplified) closure to determine if I can delete a snapshot, passing to it a snapshot element from the JSON
// Closure to check if I can delete snapshot
private Closure snapshotCanBeDeleted(final String s) {
return {
s.State.equals("completed")
}
}
Here's the code that uses the above closure.
// Get a list of snapshots via AWS SDK or CLI in JSON
def snapshots = functionToGetAListOfSnapshots() // function not shown
// Create a map of snapshots and closures that can be run in parallel
Map<String, Closure> map = new TreeMap()
snapshots.Snapshots.each {
map.put(it.SnapshotId, snapshotCanBeDeleted(it))
}
parallel map // This runs the snapshotCanBeDeleted(it) closures in parallel
But how I now print out the values of the closure, which are boolean values? I tried this
map.each {k,v ->
println "Snapshot $k can be deleted: $v"
}
But I think this is trying to print the closure itself, instead of its value, which should be true
for false
, because I just get, without the v
part of the map being printed out.
snap-0123456789 can be deleted:
[Pipeline] echo
snap-1234567890 can be deleted:
[Pipeline] echo
snap-9876543210 can be deleted:
I want
snap-0123456789 can be deleted: true
[Pipeline] echo
snap-1234567890 can be deleted: false
[Pipeline] echo
snap-9876543210 can be deleted: true
Any clues? Is this not the proper way to run a closure that returns a value? Thanks.
parallel
step doesn't modify the map you provide. Think of it as .each{}
. So you will have to define a list outside the closure and put all the results there:
def completedSnapshots = []
private Closure snapshotCanBeDeleted(final String s) {
return {
if (s.State.equals("completed")) {
completedSnapshots.add(s.SnapshotId)
}
}
}