From 484059205a6df8d795db4511a2ba6b1e98a869b5 Mon Sep 17 00:00:00 2001 From: Jesse Pretorius Date: Wed, 15 Aug 2018 14:18:28 +0100 Subject: [PATCH] MNAIO: Enable using a data disk for file-backed VM's In order to make use of a data disk, we enable the 'file' implementation of default_vm_disk_mode to use a data disk much like the 'lvm' implementation. To simplify changing from the default_vm_disk_mode of lvm to file and back again, the setup-host playbook will remove any previous implementation and replace it. This is useful when doing testing for these different modes because it does not require cleaning up by hand. This patch also fixes the implementation of the virt storage pool. Currently the tasks only execute if 'virt_data_volume.pools is not defined', but it is always defined so the tasks never execute. We now ensure that for both backing stores the 'default' storage pool is defined, started and set to auto start (as three tasks because the virt_pool module sucks really bad and can only do one thing at a time). The pool implementation for the 'file' backed VM's uses the largest data disk it can find and creates the /data mount for it. To cater for a different configuration, we ensure that all references to the disk files use the path that is configured in the pool ,rather than assuming the path. Change-Id: If7e7e37df4d7c0ebe9d003e5b5b97811d41eff22 --- multi-node-aio/README.rst | 6 +- multi-node-aio/playbooks/deploy-vms.yml | 13 +- multi-node-aio/playbooks/kvm/kvm-vm.xml.j2 | 2 +- multi-node-aio/playbooks/save-vms.yml | 9 +- multi-node-aio/playbooks/setup-host.yml | 184 +++++++++++++++------ 5 files changed, 150 insertions(+), 64 deletions(-) diff --git a/multi-node-aio/README.rst b/multi-node-aio/README.rst index 7b19ff2f..1b309030 100644 --- a/multi-node-aio/README.rst +++ b/multi-node-aio/README.rst @@ -263,9 +263,9 @@ backing store) for the VM's, then set the following option before executing If you wish to save the current file-based images in order to implement a thin-provisioned set of VM's which can be saved and re-used, then use the -``save-vms.yml`` playbook. This will stop the VM's and save the files to -``/var/lib/libvirt/images/*-base.img``. Re-executing the ``deploy-vms.yml`` -playbook afterwards will rebuild the VMs from those images. +``save-vms.yml`` playbook. This will stop the VM's and rename the files to +``*-base.img``. Re-executing the ``deploy-vms.yml`` playbook afterwards will +rebuild the VMs from those images. .. code-block:: bash diff --git a/multi-node-aio/playbooks/deploy-vms.yml b/multi-node-aio/playbooks/deploy-vms.yml index 6dbc44bf..c7a2256f 100644 --- a/multi-node-aio/playbooks/deploy-vms.yml +++ b/multi-node-aio/playbooks/deploy-vms.yml @@ -31,6 +31,11 @@ tags: - always + - name: Get info about the virt storage pools + virt_pool: + command: info + register: _virt_pools + - name: Stop running VMs virt: name: "{{ hostvars[item]['server_hostname'] }}" @@ -53,7 +58,7 @@ - name: Delete VM Disk Image file: - path: "/var/lib/libvirt/images/{{ hostvars[item]['server_hostname'] }}.img" + path: "{{ _virt_pools.pools.default.path | default('/data') }}/{{ hostvars[item]['server_hostname'] }}.img" state: absent when: - hostvars[item]['server_vm'] | default(false) | bool @@ -84,7 +89,7 @@ block: - name: Find existing base image files find: - paths: /var/lib/libvirt/images + paths: "{{ _virt_pools.pools.default.path | default('/data') }}" patterns: '*-base.img' register: _base_images @@ -99,9 +104,9 @@ qemu-img create -f qcow2 {% if vm_use_snapshot | bool %} - -b /var/lib/libvirt/images/{{ hostvars[item]['server_hostname'] }}-base.img + -b {{ _virt_pools.pools.default.path | default('/data') }}/{{ hostvars[item]['server_hostname'] }}-base.img {% endif %} - /var/lib/libvirt/images/{{ hostvars[item]['server_hostname'] }}.img + {{ _virt_pools.pools.default.path | default('/data') }}/{{ hostvars[item]['server_hostname'] }}.img {{ default_vm_storage }}m when: - hostvars[item]['server_vm'] | default(false) | bool diff --git a/multi-node-aio/playbooks/kvm/kvm-vm.xml.j2 b/multi-node-aio/playbooks/kvm/kvm-vm.xml.j2 index 5b0e50a9..20c29091 100644 --- a/multi-node-aio/playbooks/kvm/kvm-vm.xml.j2 +++ b/multi-node-aio/playbooks/kvm/kvm-vm.xml.j2 @@ -41,7 +41,7 @@ {% elif default_vm_disk_mode == "file" %} - + {% endif %}
diff --git a/multi-node-aio/playbooks/save-vms.yml b/multi-node-aio/playbooks/save-vms.yml index 61f063f1..7ef0782d 100644 --- a/multi-node-aio/playbooks/save-vms.yml +++ b/multi-node-aio/playbooks/save-vms.yml @@ -31,6 +31,11 @@ tags: - always + - name: Get info about the virt storage pools + virt_pool: + command: info + register: _virt_pools + - name: Stop running VMs command: "virsh destroy {{ hostvars[item]['server_hostname'] }}" failed_when: false @@ -41,8 +46,8 @@ - name: Save VM Disk Image command: >- mv - /var/lib/libvirt/images/{{ hostvars[item]['server_hostname'] }}.img - /var/lib/libvirt/images/{{ hostvars[item]['server_hostname'] }}-base.img + {{ _virt_pools.pools.default.path | default('/data') }}/{{ hostvars[item]['server_hostname'] }}.img + {{ _virt_pools.pools.default.path | default('/data') }}/{{ hostvars[item]['server_hostname'] }}-base.img when: - hostvars[item]['server_vm'] | default(false) | bool with_items: "{{ groups['pxe_servers'] }}" diff --git a/multi-node-aio/playbooks/setup-host.yml b/multi-node-aio/playbooks/setup-host.yml index 08b2cb4b..6d563139 100644 --- a/multi-node-aio/playbooks/setup-host.yml +++ b/multi-node-aio/playbooks/setup-host.yml @@ -242,77 +242,153 @@ with_dict: "{{ mnaio_host_networks }}" when: "item.value.iface not in vm_networks.list_nets" - - name: Locate data volume - command: "vgdisplay vg01" - failed_when: false + - name: Locate the largest writable data disk if mnaio_data_disk is not set + shell: > + lsblk -brndo NAME,TYPE,FSTYPE,RO,SIZE | awk '/d[b-z]+ disk +0/{ if ($4>m){m=$4; d=$1}}; END{print d}' + register: lsblk + changed_when: false when: - - default_vm_disk_mode == "lvm" - register: data_volume + - mnaio_data_disk is undefined - - name: Setup the data volume (LVM) + - name: Get info about existing virt storage pools + virt_pool: + command: info + register: _virt_pools + + - name: If an existing virt pool does not match default_vm_disk_mode, remove it when: - - default_vm_disk_mode == "lvm" - - data_volume.rc != 0 + - _virt_pools.pools.default is defined + - (default_vm_disk_mode == "file" and _virt_pools.pools.default.format is defined) or + (default_vm_disk_mode == "lvm" and _virt_pools.pools.default.format is not defined) block: - - name: Locate data disk - shell: > - lsblk -brndo NAME,TYPE,FSTYPE,RO,SIZE | awk '/d[b-z]+ disk +0/{ if ($4>m){m=$4; d=$1}}; END{print d}' - register: lsblk + - name: Dismount the mount point if default_vm_disk_mode is 'lvm' + mount: + path: /data + state: unmounted when: - - mnaio_data_disk is undefined + - default_vm_disk_mode == "lvm" - - name: Create data disk label - command: "parted --script /dev/{{ mnaio_data_disk | default(lsblk.stdout) }} mklabel gpt" + - name: Stop the pool + virt_pool: + command: destroy + name: default - - name: Create data disk partition - command: "parted --align optimal --script /dev/{{ mnaio_data_disk | default(lsblk.stdout) }} mkpart data1 ext4 0% 100%" + - name: Delete the pool, destroying its contents + virt_pool: + command: delete + name: default - - name: Create data volume group + - name: Undefine the pool + virt_pool: + command: undefine + name: default + + - name: Remove the mount point if default_vm_disk_mode is 'lvm' + mount: + path: /data + state: absent + when: + - default_vm_disk_mode == "lvm" + + - name: Reload systemd to remove generated unit files for mount + systemd: + daemon_reload: yes + when: + - default_vm_disk_mode == "lvm" + + - name: Remove the volume group if default_vm_disk_mode is 'file' + lvg: + vg: vg01 + state: absent + register: _remove_vg + when: + - default_vm_disk_mode == "file" + + - name: Remove the existing disk partition + parted: + device: "/dev/{{ mnaio_data_disk | default(lsblk.stdout) }}" + number: 1 + state: absent + + - name: Setup the data disk partition + parted: + device: "/dev/{{ mnaio_data_disk | default(lsblk.stdout) }}" + label: gpt + number: 1 + name: data1 + state: present + register: _add_partition + + - name: Prepare the data disk for 'lvm' default_vm_disk_mode + when: + - default_vm_disk_mode == "lvm" + block: + - name: Create the volume group lvg: vg: vg01 pvs: "/dev/{{ mnaio_data_disk | default(lsblk.stdout) }}1" - - name: Locate virt data volume - virt_pool: - name: "vg01" - command: info - failed_when: false + - name: Define the default virt storage pool + virt_pool: + name: default + state: present + xml: | + + default + + vg01 + + + + /dev/vg01 + + + + - name: Prepare the data disk for 'file' default_vm_disk_mode when: - - default_vm_disk_mode == "lvm" - register: virt_data_volume - - - name: Create /etc/libvirt/storage directory - file: - path: "/etc/libvirt/storage/" - state: "directory" - - - name: Create virt data volume + - default_vm_disk_mode == "file" block: - - name: Create virt pool - virt_pool: - command: create - name: vg01 + - name: Prepare the data disk file system + filesystem: + fstype: ext4 + dev: "/dev/{{ mnaio_data_disk | default(lsblk.stdout) }}1" + force: yes + when: + - _add_partition is changed - - name: Get virt pool xml - virt_pool: - command: get_xml - name: vg01 - register: virt_pool_xml + - name: Mount the data disk + mount: + src: "/dev/{{ mnaio_data_disk | default(lsblk.stdout) }}1" + path: /data + state: mounted + fstype: ext4 - - name: Write data volume xml - copy: - content: "{{ virt_pool_xml.get_xml }}" - dest: "/etc/libvirt/storage/vg01.xml" - - - name: Define virt data volume + - name: Define the default virt storage pool virt_pool: - command: define - name: vg01 - xml: "/etc/libvirt/storage/vg01.xml" - autostart: true - when: - - default_vm_disk_mode == "lvm" - - virt_data_volume.pools is not defined + name: default + state: present + xml: | + + default + + /data + + 0755 + 0 + 0 + + + + + - name: Set default virt storage pool to active + virt_pool: + name: default + state: active + + - name: Set default virt storage pool to autostart + virt_pool: + name: default + autostart: yes - name: Load virtio kernel modules shell: |