From 35cf936ebbac54d5ba8a9432a78a587abdea433d Mon Sep 17 00:00:00 2001 From: Massaki Archambault Date: Fri, 11 Sep 2020 00:31:55 -0400 Subject: [PATCH] create new script to attach usb devices to vm --- .../sway-session.target.wants/wayvnc.service | 1 - files/bin/virt-usb | 80 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) delete mode 120000 files/.config/systemd/user/sway-session.target.wants/wayvnc.service create mode 100755 files/bin/virt-usb diff --git a/files/.config/systemd/user/sway-session.target.wants/wayvnc.service b/files/.config/systemd/user/sway-session.target.wants/wayvnc.service deleted file mode 120000 index 39ee78a..0000000 --- a/files/.config/systemd/user/sway-session.target.wants/wayvnc.service +++ /dev/null @@ -1 +0,0 @@ -/home/marchambault/.config/systemd/user/wayvnc.service \ No newline at end of file diff --git a/files/bin/virt-usb b/files/bin/virt-usb new file mode 100755 index 0000000..a9f3c01 --- /dev/null +++ b/files/bin/virt-usb @@ -0,0 +1,80 @@ +#!/usr/bin/env python3 +# PYTHON_ARGCOMPLETE_OK + +import argparse +import logging +import re +import subprocess +import tempfile + +def main(**kwargs): + if kwargs.get('detach'): + virsh_subcommand = 'detach-device' + virsh_action = 'detach' + else: + virsh_subcommand = 'attach-device' + virsh_action = 'attach' + + for device in kwargs.get('device_ids'): + bus, dev = device.split(':') + with tempfile.NamedTemporaryFile('w+') as f: + f.write(f""" + + + + + + + """) + f.flush() + logging.info('%s %s',virsh_action, device) + subprocess.run(['virsh', virsh_subcommand, kwargs.get('domain'), f.name, '--live'], check=False) + +def regex_arg_type(regex): + pat = re.compile(regex) + def regex_type(value): + if pat.match(value): + return value + else: + raise argparse.ArgumentTypeError('argument "%s" must match regex "%s"' % (value, regex)) + return regex_type + +def get_libvirt_domains(): + sp = subprocess.run(['virsh', 'list', '--name'], capture_output=True, encoding='utf8', check=True) + for line in sp.stdout.split('\n'): + if line: + yield line.strip() + +def get_usb_devices(): + sp = subprocess.run(['lsusb'], capture_output=True, encoding='utf8', check=True) + for line in sp.stdout.split('\n'): + if line: + yield line.split()[5] + +if __name__ == '__main__': + logging.basicConfig(format='%(message)s', level=logging.INFO) + parser = argparse.ArgumentParser() + action_group = parser.add_mutually_exclusive_group() + action_group.add_argument('--attach', + action='store_true', + help='attach the usb devices (default)') + action_group.add_argument('--detach', + action='store_true', + help='detach the usb devices') + parser.add_argument('-d', '--domain', + choices=list(get_libvirt_domains()), + default=next(get_libvirt_domains(), None), + help='the libvirt domain on which to attach/detach the usb devices (default: %(default)s)') + parser.add_argument('device_ids', + metavar='device_ids', + nargs='+', + choices=list(get_usb_devices()), + help='a list of usb vendor:product ids in hexadecimal to attach/detach to the vm') + try: + import argcomplete + argcomplete.autocomplete(parser) + except ImportError: + pass + + args = parser.parse_args() + main(**args.__dict__)