Comment 24 for bug 1396965

Revision history for this message
HT (h5t4) wrote :

#!/bin/bash
#migrate VM root and/or non-root gpfs to rbd-ec (ceph)
#tested on OS 'Train' release, use with extreme care (DB dump + Volume backups)
#https://bugs.launchpad.net/nova/+bug/1396965

#2020, High Performance Computing Center, University of Tartu, https://hpc.ut.ee

vm_uuid="${1}"
new_backend=rbd-ec

migrate_root() {
echo "Prepare root volume for migration"
dev="$(openstack volume show -c attachments -f value ${root_disk_uuid} | grep -P -m 1 -o "/dev/[s]?[v]?da")"
cinder reset-state --state available ${root_disk_uuid}
mysql -e "delete from cinder.volume_attachment where volume_id=\"${root_disk_uuid}\" limit 1;"
mysql nova -e "delete from block_device_mapping where not deleted and volume_id=\"${root_disk_uuid}\";"

echo "Migrate root volume ${dev}, ${root_disk_uuid}"
cinder retype --migration-policy on-demand ${root_disk_uuid} ${new_backend}
while [ "$(openstack volume show -c migration_status -f value ${root_disk_uuid})" != "success" ] ;do sleep 5; echo -n "."; done
nova volume-attach ${vm_uuid} ${root_disk_uuid} >/dev/null;sleep 15
mysql nova -e "update block_device_mapping SET device_name=\"${dev}\" where volume_id=\"${root_disk_uuid}\";"
mysql nova -e "update block_device_mapping set boot_index=\"0\" where volume_id=\"${root_disk_uuid}\";"
mysql cinder -e "update volume_attachment set mountpoint=\"${dev}\" where volume_id=\"${root_disk_uuid}\";"
src="$(mysql cinder -sNe "select id from volumes where display_description=\"migration src for ${root_disk_uuid}\";")"
mysql cinder -e "UPDATE volume_attachment SET connector = JSON_SET(connector, '$.mountpoint', \"${dev}\") WHERE volume_id=\"${root_disk_uuid}\";"

echo -e "\nManually delete leftover migration source (unknown OS bug)."
cinder reset-state --state error "${src}"
cinder reset-state --reset-migration-status "${src}"
mysql cinder -sNe "update volumes set attach_status='detached' where id=\"${src}\";"
cinder delete "${src}"
}

echo -e "Detect if any migration is needed at all."
vol_list=$(openstack server show -c volumes_attached -f value ${vm_uuid} | awk -F "'" '{print $2}')
if [ -z "$(for i in ${vol_list} ;do echo -n "$(openstack volume show ${i} -c type -f value | grep -v "${new_backend}" )" ;done)" ];then
echo "No illplaced volume detected"; exit 0;
fi

echo "VM stop"
nova stop ${vm_uuid};
while [ "$(openstack server show ${vm_uuid} -c 'OS-EXT-STS:power_state' -f value)" != "Shutdown" ];do sleep 1;echo -n "."; done

echo -e "\nDetach all non-root disks before migration."
for i in ${vol_list} ;do nova volume-detach "${vm_uuid}" "${i}" 2>&1 | grep root >/dev/null && root_disk_uuid=${i};done

echo "Detect if root disk migration is needed."
if [ -n "${root_disk_uuid}" ] && [ "$(openstack volume show ${root_disk_uuid} -c type -f value)" != "${new_backend}" ];then
migrate_root
fi

echo "Migrate all non-root volumes."
for i in ${vol_list} ;do
if [ "${i}" != "${root_disk_uuid}" ] && [ "$(openstack volume show ${i} -c type -f value)" != "${new_backend}" ];then
cinder retype --migration-policy on-demand ${i} "${new_backend}"
while [ "$(openstack volume show -c migration_status -f value ${i})" != "success" ] ;do sleep 5;echo -n ".";done
fi
done

echo -e "\nRe-generate new libvirt configurtation."
nova reboot --hard ${vm_uuid}

echo "Attach all non-root volumes."
while [ "$(openstack server show ${vm_uuid} -c 'OS-EXT-STS:power_state' -f value)" != "Running" ];do sleep 1;echo -n "."; done
for i in ${vol_list} ;do
test "${i}" != "${root_disk_uuid}" && nova volume-attach "${vm_uuid}" "${i}" >/dev/null
done

echo "Reboot VM"
nova reboot ${vm_uuid}