Quick and Dirty Snapshots of Instances Booted from Volume

I've discussed my local OpenStack installation before, such as here and here. One of the results of the changes I've made to it over time is that I have some instances that are booted from volume. Unfortunately, instances booted from volume don't snapshot properly with the nova image-create. Below is the quick and dirty method I've been using to take snapshot backups of those vms for a while now.

I won't go too deeply into the implementation details since you can read the script below, but the basic process is to stop the instance, find the volume it was booted from, use Cinder to create an image from the volume, then restart the instance. I also download the image and then delete it from Glance because I'm primarily using this as a backup method.

There are some obvious limitations to this method (having to stop the instance could be a problem for many people), but I've been running it a few times a week for several months now and it's been working well for me so I figured I'd share it. If there's a simpler way to do this I'm all ears. :-)

vms_to_backup="space separated list of vms to run the script on"
wait_for_image()
{
   image=$1
   count=0
   while ! glance image-show $image | grep active
   do
      count=$(($count+1))
      if [ $count -ge 200 ]
      then
         echo "Image never became active"
         exit 1
      fi
      sleep 10
   done
}

for i in $vms_to_backup
do
   img_name=backup-$i
   restart=0
   
   if nova show $i | grep ACTIVE
   then
      nova stop $i
      restart=1
   fi
   # This is likely to break with multiple attached volumes
   volid=$(nova show $i | grep volumes_attached | sed 's/.*\[{"id": "\([a-zA-Z0-9\-]\+\)"}\].*/\1/')
   while nova show $i | grep ACTIVE
   do
      sleep 1
   done
   cinder upload-to-image $volid $img_name --disk-format qcow2 --force True || continue
   
   wait_for_image $img_name
   
   if [ $restart -eq 1 ]
   then
      nova start $i
   fi
      
   glance image-download $img_name --file /backup/$i.qcow2

   glance image-delete $img_name
   
done