From 993bac94f5007b37d36134b34a9f927ae44d00b2 Mon Sep 17 00:00:00 2001 From: Jesse Pretorius Date: Wed, 15 Aug 2018 19:25:12 +0100 Subject: [PATCH] MNAIO: Extend image saving to include manifest In order to more successfully reproduce an environment using saved images, we include the VM XML definition files and the output from 'pip freeze'. We capture the list of files, their checksums and the SHA for the git repo into a json manifest file. Change-Id: Ia0bf74d509b4acb10b0dd832a4cfe1bb2afb2503 --- multi-node-aio/playbooks/deploy-vms.yml | 17 ++++++- multi-node-aio/playbooks/save-vms.yml | 63 +++++++++++++++++++++++-- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/multi-node-aio/playbooks/deploy-vms.yml b/multi-node-aio/playbooks/deploy-vms.yml index c7a2256f..b6ce90d8 100644 --- a/multi-node-aio/playbooks/deploy-vms.yml +++ b/multi-node-aio/playbooks/deploy-vms.yml @@ -83,7 +83,7 @@ - default_vm_disk_mode == "lvm" with_items: "{{ groups['pxe_servers'] }}" - - name: Setup file-based disk images + - name: Setup/clean-up file-based disk images when: - default_vm_disk_mode == "file" block: @@ -99,6 +99,14 @@ when: - vm_use_snapshot is not defined + - name: Clean up base image files if they are not being used + file: + path: "{{ item.path }}" + state: absent + with_items: "{{ _base_images.files }}" + when: + - not (vm_use_snapshot | bool) + - name: Create VM Disk Image command: >- qemu-img create @@ -123,7 +131,12 @@ virt: name: "{{ hostvars[item]['server_hostname'] }}" command: define - xml: "{{ lookup('template', 'kvm/kvm-vm.xml.j2') }}" + xml: >- + {%- if vm_use_snapshot | bool %} + {{ lookup('file', _virt_pools.pools.default.path | default('/data') ~ '/' ~ hostvars[item]['server_hostname'] ~ '.xml') }} + {%- else %} + {{ lookup('template', 'kvm/kvm-vm.xml.j2') }} + {%- endif %} failed_when: false when: - hostvars[item]['server_vm'] | default(false) | bool diff --git a/multi-node-aio/playbooks/save-vms.yml b/multi-node-aio/playbooks/save-vms.yml index d7303b09..1c3fef9e 100644 --- a/multi-node-aio/playbooks/save-vms.yml +++ b/multi-node-aio/playbooks/save-vms.yml @@ -35,6 +35,8 @@ virt_pool: command: info register: _virt_pools + tags: + - always - name: Stop running VMs virt: @@ -45,10 +47,63 @@ with_items: "{{ groups['pxe_servers'] }}" - name: Save VM Disk Image - command: >- - mv - {{ _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 + shell: | + if [[ -e {{ hostvars[item]['server_hostname'] }}.img ]]; then + if [[ -e {{ hostvars[item]['server_hostname'] }}-base.img ]]; then + qemu-img commit {{ hostvars[item]['server_hostname'] }}.img + else + mv {{ hostvars[item]['server_hostname'] }}.img {{ hostvars[item]['server_hostname'] }}-base.img + fi + exit 2 + fi + args: + executable: /bin/bash + chdir: "{{ _virt_pools.pools.default.path | default('/data') }}" when: - hostvars[item]['server_vm'] | default(false) | bool with_items: "{{ groups['pxe_servers'] }}" + register: _save_disk_image + changed_when: _save_disk_image.rc == 2 + + - name: Save VM definition + copy: + src: "/etc/libvirt/qemu/{{ hostvars[item]['server_hostname'] }}.xml" + dest: "{{ _virt_pools.pools.default.path | default('/data') }}/" + remote_src: yes + when: + - hostvars[item]['server_vm'] | default(false) | bool + with_items: "{{ groups['pxe_servers'] }}" + + - name: Get the current SHA1 for the manifest + command: "git rev-parse HEAD" + args: + chdir: "{{ playbook_dir }}" + register: _repo_sha + changed_when: false + + - name: Add pip freeze results to the data + shell: "pip --disable-pip-version-check freeze > pip-requirements.txt" + args: + executable: /bin/bash + chdir: "{{ _virt_pools.pools.default.path | default('/data') }}" + changed_when: false + + - name: Find all the files for the manifest + find: + paths: "{{ _virt_pools.pools.default.path | default('/data') }}" + patterns: + - "*-base.img" + - "*.xml" + - "*.txt" + get_checksum: yes + register: _manifest_files + + - name: Prepare the manifest file content + set_fact: + _manifest_content: >- + { 'openstack-ansible-ops_SHA1': '{{ _repo_sha.stdout }}', 'files': {{ _manifest_files.files | json_query('[*].{path: path, checksum: checksum}') | sort(attribute='path') }} } + + - name: Write out the manifest file + copy: + content: "{{ _manifest_content | to_nice_json }}" + dest: "{{ _virt_pools.pools.default.path | default('/data') }}/manifest.json"