Skip to content

Add usb support to libvirt-vm role #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,27 @@ Role Variables
- `dev`: (optional) Block device path when type is `block`.
- `remote_src`: (optional) When type is `file` or `block`, specify wether `image` points to a remote file (true) or a file local to the host that launched the playbook (false). Defaults to true.

- `usb_devices`: a list of usb devices to present to the vm from the host.

Each usb device is defined with the following dict:

- `vendor`: The vendor id of the USB device.
- `product`: The product id of the USB device.

Note - Libvirt will error if the VM is provisioned and the USB device is not attached.

To obtain the vendor id and product id of the usb device from the host running as sudo / root with the usb device plugged in
run `lsusb -v`. Example below with an attached Sandisk USB Memory Stick with vendor id: `0x0781` and product id: `0x5567`

```
lsusb -v | grep -A4 -i sandisk

idVendor 0x0781 SanDisk Corp.
idProduct 0x5567 Cruzer Blade
bcdDevice 1.00
iManufacturer 1
iProduct 2
```

- `interfaces`: a list of network interfaces to attach to the VM.
Each network interface is defined with the following dict:
Expand Down Expand Up @@ -231,6 +252,10 @@ Example Playbook

interfaces:
- network: 'br-datacentre'

usb_devices:
- vendor: '0x0781'
product: '0x5567'

- state: present
name: 'vm2'
Expand Down
15 changes: 15 additions & 0 deletions tasks/check-usb-devices.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
- name: List USB hardware
command: lsusb -d {{ usb_device.vendor }}:{{ usb_device.product }}
register: host_attached_usb_device
become: true
changed_when: false
failed_when: false

- name: Check USB device is present on Host system
fail:
msg: >
The USB Device with Vendor ID:{{ usb_device.vendor }} and Product ID:{{ usb_device.product }} is not seen on host system
Is the USB device plugged in correctly ?
when:
- host_attached_usb_device.rc != 0
1 change: 1 addition & 0 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
cpu_mode: "{{ vm.cpu_mode | default(libvirt_cpu_mode_default) }}"
volumes: "{{ vm.volumes | default([], true) }}"
interfaces: "{{ vm.interfaces | default([], true) }}"
usb_devices: "{{ vm.usb_devices | default([], false) }}"
start: "{{ vm.start | default(true) }}"
autostart: "{{ vm.autostart | default(true) }}"
enable_vnc: "{{ vm.enable_vnc | default(false) }}"
Expand Down
6 changes: 6 additions & 0 deletions tasks/vm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@
interface: "{{ item }}"
with_items: "{{ interfaces }}"

- name: Validate Host USB Devices
include_tasks: check-usb-devices.yml
vars:
usb_device: "{{ item }}"
with_items: "{{ usb_devices }}"

- name: Ensure the VM is defined
virt:
command: define
Expand Down
8 changes: 8 additions & 0 deletions templates/vm.xml.j2
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,14 @@
<listen type='address'/>
</graphics>
{% endif %}
{% for usb_device in usb_devices %}
<hostdev mode='subsystem' type='usb' managed='yes'>
<source>
<vendor id='{{ usb_device.vendor }}'/>
<product id='{{ usb_device.product }}'/>
</source>
</hostdev>
{% endfor %}
<rng model="virtio"><backend model="random">/dev/urandom</backend></rng>
</devices>
</domain>