Reputation: 329
I am writing a shell script that copies our AWS EBS Snapshot from one region to another region. It's a simple thing that i am doing, which is running a for loop with below command from a list of ID that are stored in a file(snap_id).
for SID in `cat snap_id`
do
aws --region us-east-1 ec2 copy-snapshot --source-region us-west-2 --source-snapshot-id $SID --description "copy to us-west"
done
Here is a sample snap_id file(100's of line of snap-id)
snap-5ddffd59
snap-9c054999
snap-d94496d9
snap-er2df342
snap-234as234
snap-as234asd
......
......
......
Now the problem i am running into is, I can only run 5 of those at any given time as AWS limit how many snapshot you can copy to another region concurrently.
So basically i have to create a queue of 5, and I have to wait until those 5 are done before i send the batch of next 5. I can run something like below command to get a status of current copy(which should be "completed", we would get 5 completed if things are complete)
aws ec2 describe-snapshots --snapshot-ids (LIST OF CURRENT 5 BATCH) --query Snapshots[].State --output text
so any idea on how to build a queue like this using bash ?
UPDATE 2: After suggestion from @jyvet
I changed my waitbatch to below, In that way i have a timeout of 1800 seconds and i look for all of the 5 (in that batch) to have a complete status and increment the counter to 5, if the count is 5 (5 out of 5 in the current batch) i break out... Suggestions are welcomed ...
waitbatch() {
count=0
if [ ${ibatch} -gt 0 ]; then
END=$((SECONDS+1800))
while [ $SECONDS -lt $END ]; do
while [ "$count" -le 5 ]; do
# look for errors ??? and put retries/timeout
aws ec2 describe-snapshots --snapshot-ids ${list} --query Snapshots[].State --output text > completed_list
count=0
for i in `cat completed_list`
do
if [ "$i" = "completed" ]
then
count=$((count+1))
fi
done
if [ "$count" = "5" ]
then
echo count is good, ready to move to next batch
break
fi
echo "sleeping 5 seconds"
sleep 5
done
if [ "$count" = "5" ]
then
break
fi
done
fi
}
Upvotes: 0
Views: 1320
Reputation: 2201
What's about something like:
#!/bin/bash
BATCH=5 # nb of snap ids in a batch
TIMEOUT=10 # seconds to wait for completion of a batch
ibatch=0
waitbatch() {
retries=0
if [ ${ibatch} -gt 0 ]; then
while [ `aws ec2 describe-snapshots --snapshot-ids (${list}) --query Snapshots[].State --output text | grep -o 'completed' | wc -w` -lt ${BATCH} ]; do
sleep 1
retries=$(( ${retries} + 1))
# Give up if TIMEOUT
if [ ${retries} -eq ${TIMEOUT} ]; then
>&2 echo "timeout for ${list}"
break
fi
done
fi
}
# Loop over all snap ids
for SID in `cat snap_id`
do
aws --region us-east-1 ec2 copy-snapshot --source-region us-west-2 --source-snapshot-id ${SID} --description "copy to us-west"
list="${list} ${SID}"
ibatch=$(( ${ibatch} + 1 ))
# Check if BATCH is reached
if [ ${ibatch} -eq ${BATCH} ]; then
# Wait for completion
waitbatch
ibatch=0
list=""
fi
done
# Wait for completion
waitbatch
Upvotes: 2