Browse Source

Add supplementary disks with virsh

master v0.7.5
Doug Le Tough 1 year ago
parent
commit
7296a2c7e6
2 changed files with 64 additions and 0 deletions
  1. +7
    -0
      README.md
  2. +57
    -0
      virt_vm.py

+ 7
- 0
README.md View File

@ -51,6 +51,7 @@ The following module is not available in basic _Centos 8_ packages repositories
- Generates and define persistent [_libvirt_ domains](https://libvirt.org/docs/libvirt-appdev-guide-python/en-US/html/) from XML definition
- Hot configuration modification and application whenever possible
- VM deployment from template disk image
- Supplementary disk creation and attachment
- Idempotent module
### Usage
@ -105,6 +106,7 @@ Due to complex combinations of parameters, all parameters are mandatory:
| `name` | Domain name | **str**. Should **not** contain space characters |
| `description` | Description for domain | **str** |
| `src_img` | Name of disk image file template virtual machine. This disk image file will be used as a base disk and must be present on **host** | **str** |
| `disks` | List of disks that will be added to VM. Must be set as an empty list if no disk have to added. See example below | **List** |
| `force_copy` | If set to `True`. This system disk image file will be replaced (or created) by coying `src_img`. This operation applies only on shutdown system and **will have no effect** on a running system. | **bool** |
| `machine_type` | Virtual machine type (see [documentation](https://libvirt.org/formatdomaincaps.html)) | **str** |
| `vcpus` | Max number of CPUs used by virtual machine | **int** |
@ -128,6 +130,7 @@ The `foo`'s disk path will be `/var/lib/libvirt/images/foo.img` while the `bar`'
`192.168.122.2` _IP_ address will be assigned to `foo` while `192.168.122.3` _IP_ address will be assigned to `bar` by _libvirt_ _DHCP_ server.
The `bar` VM will receive a supplementary 100GB disk that will be seen as `/dev/vdb` by the guest O.S. (see the `disks` parameter).
```yaml
---
@ -142,6 +145,7 @@ kvm_vms:
name: foo
description: The famous Foo VM
src_img: centos_8.img
disks: []
force_copy: yes
machine_type: pc-q35-rhel7.6.0
vcpus: 2
@ -161,6 +165,9 @@ kvm_vms:
name: bar
description: The infamous Bar VM
src_img: centos_8.img
disks:
- name: vdb
size: 100G
force_copy: yes
machine_type: pc-q35-rhel7.6.0
vcpus: 1


+ 57
- 0
virt_vm.py View File

@ -4,6 +4,7 @@
import os
import shutil
import libvirt
import subprocess
from lxml import etree
from xmldiff import main as xd_main
from ansible.module_utils.basic import AnsibleModule
@ -20,6 +21,53 @@ class VM:
self.xml_tmp_domain_root = None
self.vir_domain = None
def create_disks(self):
"""Create supplementary disk files according to self.params['disks']
"""
out = []
err = ''
for disk in self.params['disks']:
disk_size = disk['size']
disk_filename = '{}.{}.img'.format(self.params['name'], disk['name'])
disk_filepath = os.path.join(self.params['libvirt_img_path'], disk_filename)
try:
if not os.path.isfile(disk_filepath):
# Ugly way to create disk
# FIXME: Use libvirt to create storage pool and add disks to it
cmd = '/usr/bin/qemu-img create -f qcow2 {} {}'.format(disk_filepath, disk_size)
process = subprocess.run(cmd,
shell=True,
stderr=subprocess.PIPE)
stderr = process.stderr
if len(stderr) != 0:
return (out, err)
out.append(disk['name'])
except Exception as e:
err = str(e)
return (out, err)
def _add_disks(self, element):
"""Add disks to element
"""
address = 4
for disk in self.params['disks']:
address += 1
if address < 10:
address = '0{}'.format(address)
disk_filename = '{}.{}.img'.format(self.params['name'], disk['name'])
disk_filepath = os.path.join(self.params['libvirt_img_path'], disk_filename)
xml_disk = "<disk type='file' device='disk'></disk>"
xml_driver = "<driver name='qemu' type='qcow2'/>"
xml_source = "<source file='{}'/>".format(disk_filepath)
xml_target = "<target dev='{}' bus='virtio'/>".format(disk['name'])
xml_address = "<address type='pci' domain='0x0000' bus='0x00' slot='0x{}' function='0x0'/>".format(address)
disk = etree.fromstring(xml_disk)
disk.append(etree.fromstring(xml_driver))
disk.append(etree.fromstring(xml_source))
disk.append(etree.fromstring(xml_target))
disk.append(etree.fromstring(xml_address))
element.append(disk)
def _set_xml_uuid(self, element):
"""Set VM UUID
"""
@ -78,6 +126,7 @@ class VM:
self.params['spice_password'])
element.find('graphics').find('listen').set('address',
self.params['spice_interface'])
self._add_disks(element)
def _set_autostart(self):
"""Set domain autostart parameter.
@ -306,6 +355,7 @@ def main():
name = dict(required=True),
description = dict(required=True),
src_img = dict(required=True),
disks = dict(required=True,type='list'),
force_copy = dict(required=True, type='bool'),
machine_type = dict(required=True),
vcpus = dict(required=True, type='int'),
@ -331,7 +381,14 @@ def main():
'compare': 0,
'already_exists': False}
# Disk creation
out, err = virt_vm.create_disks()
if len(err) != 0:
module.fail_json(msg=err)
if len(out) > 0:
result['changed'] = True
# XML domain file generation
result['create_disks'] = True
err = virt_vm.create_xml_file()
if len(err) != 0:
module.fail_json(msg=err)


Loading…
Cancel
Save