copr-backend: scripts for listing and removing LibVirt domains

Previous approach was causing some volume leftovers.
This commit is contained in:
Pavel Raiskup 2022-05-19 11:49:11 +02:00
parent e1f2c2d991
commit a2b88e5e11
3 changed files with 126 additions and 11 deletions

View file

@ -0,0 +1,73 @@
#! /usr/bin/python3
"""
Delete the given Resalloc-related LibVirt domain (and the related resources)
"""
# pylint: disable=broad-except
import argparse
import logging
import time
import libvirt
def repeat(call, args):
""" Repeat the given function call, with args """
attempts = 3
for attempt in range(1, attempts+1):
try:
return call(*args)
except Exception:
seconds = 10
if attempt < attempts:
logging.exception("Failed repeatable call, sleep %ss",
seconds)
time.sleep(seconds)
continue
raise
def _get_parser():
parser = argparse.ArgumentParser()
parser.add_argument("--connection", required=True)
parser.add_argument("domainname")
return parser
def _delete_domain(domain):
try:
domain.destroy()
logging.info("Domain %s destroyed", domain.name())
except Exception:
logging.exception("can't destroy %s", domain.name())
domain.undefine()
logging.info("Domain %s undefined", domain.name())
def _delete_volume(pool, volume_name):
volume = pool.storageVolLookupByName(volume_name)
volume.delete()
def _main():
logging.basicConfig(level=logging.INFO)
args = _get_parser().parse_args()
conn = repeat(libvirt.open, (args.connection,))
try:
domain = repeat(conn.lookupByName, (args.domainname,))
repeat(_delete_domain, (domain,))
logging.info("domain %s removed", args.domainname)
except Exception:
logging.exception("domain can't be removed")
pool = repeat(conn.storagePoolLookupByName, ("images",))
for volume_name in repeat(pool.listVolumes, ()):
if not volume_name.startswith(args.domainname):
continue
try:
repeat(_delete_volume, (pool, volume_name,))
logging.info("volume %s removed", volume_name)
except Exception:
logging.exception("volume %s can not be removed", volume_name)
if __name__ == "__main__":
_main()

View file

@ -0,0 +1,52 @@
#! /usr/bin/python3
"""
List all the Resalloc Pool-related LibVirt domains that are either (a) still
defined/running, or (b) have some resource (e.g. storage) still available in the
LibVirt hypervisor.
"""
import argparse
import sys
import libvirt
def _get_parser():
parser = argparse.ArgumentParser()
parser.add_argument("--connection", required=True)
parser.add_argument("--pool", required=True)
return parser
def _main():
args = _get_parser().parse_args()
try:
conn = libvirt.openReadOnly(args.connection)
except libvirt.libvirtError:
print('Failed to open connection to the hypervisor')
sys.exit(1)
# Gather the list of all domains here
vm_names = set()
# List all the volumes in the 'images' pool that seem to be related to given
# Pool name
pool = conn.storagePoolLookupByName("images")
for volume in pool.listVolumes():
if volume.startswith(args.pool):
vm_names.add(volume.rsplit("_", 1)[0])
# List all domains that are related to given Pool (just to be 100% sure, but
# this shouldn't add any new items to the vm_names set actually).
for domain in conn.listAllDomains():
name = domain.name()
if name.startswith(args.pool):
vm_names.add(name)
# Print them out, so upper level tooling can work with the list. See:
# roles/copr/backend/files/provision/libvirt-list
for name in vm_names:
print(name)
if __name__ == "__main__":
_main()

View file

@ -66,14 +66,4 @@ copr_p09_01*)
esac
# The rest of this script is LibVirt only!
repeat()
{
for _ in a b c; do
"$@" && break
sleep 15
done
}
repeat virsh -c "$conn" destroy "$RESALLOC_NAME"
repeat virsh -c "$conn" undefine "$RESALLOC_NAME" --remove-all-storage --nvram
{{ provision_directory }}/libvirt-delete --connection "$conn" "$RESALLOC_NAME"