I am trying to save the state of all running VM's before I can shut down the host.
virsh save <domain-name> <filetosave>
The idea is to restore the VM's when I bring back the host again.
I am using ansible virt module to determine the running VM's. There is no command available for saving the virtual machine using virt module hence using shell module like below
tasks:
- name: Gathering Facts
setup:
# Listing VMs
- name: list all VMs
virt:
command: list_vms
register: all_vms
- name: list only running VMs
virt:
command: list_vms
state: running
register: running_vms
- name: Print All VM'state
debug:
msg: |
VM's: {{ all_vms.list_vms }},
Active VM's: {{ running_vms.list_vms }}
- name: Save Running VM's
shell: >
virsh save {{ item }} ~/.mykvm/{{item}}.save
args:
chdir: /home/sharu
executable: /bin/bash
loop:
"{{ running_vms.list_vms }}"
register: save_result
- debug:
var: save_result
Output:
TASK [list all VMs]
*********
ok: [192.168.0.113]
TASK [list only running VMs]
*********
ok: [192.168.0.113]
TASK [Print All VM'state]
*********
ok: [192.168.0.113] => {
"msg": "VM's: [u'win10-2', u'ubuntu18.04', u'ubuntu18.04-2', u'win10'],\nActive VM's: [u'win10-2']\n"
}
TASK [Save Running VM's]
*********
failed: [192.168.0.113] (item=win10-2) => {"ansible_loop_var": "item", "changed": true, "cmd": "virsh save win10-2 ~/.mykvm/win10-2.save\n", "delta": "0:00:00.101916", "end": "2019-12-30 01:19:32.205584", "item": "win10-2", "msg": "non-zero return code", "rc": 1, "start": "2019-12-30 01:19:32.103668", "stderr": "error: failed to get domain 'win10-2'", "stderr_lines": ["error: failed to get domain 'win10-2'"], "stdout": "", "stdout_lines": []}
PLAY RECAP
******************
192.168.0.113 : ok=5 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
Notice the virt module was able to get the information regarding the running domain's(VM's) but the shell command failed to get the domain name. It seems like the VM's are not visible for Ansible's shell task
To debug further I executed the Ansible ad-hoc command below but got the blank result
$ ansible -i ../hosts.ini RIG3600 -m shell -a "virsh list --all"
192.168.0.113 | CHANGED | rc=0 >>
Id Name State
--------------------
The same command works fine in the Linux shell
$ virsh list --all
Id Name State
--------------------------------
3 win10-2 running
- ubuntu18.04 shut off
- ubuntu18.04-2 shut off
- win10 shut off
Am using Ansible version 2.8.3 Not sure am I missing something here, any help is much appreciated.
The virt
module, as documented, defaults to using the libvirt URI qemu:///system
.
The virsh
command, on the other hand, when run as a non-root user, defaults to qemu:///session
.
In other words, your virsh
command is not talking to the same libvirt instance as your virt
tasks.
You can provide an explicit URI to the virsh
command using the -c
(--connect
) option:
virsh -c qemu:///system ...
Or by setting the LIBVIRT_DEFAULT_URI
environment variable:
- name: Save Running VM's
shell: >
virsh save {{ item }} ~/.mykvm/{{item}}.save
args:
chdir: /home/sharu
executable: /bin/bash
environment:
LIBVIRT_DEFAULT_URI: qemu:///system
loop:
"{{ running_vms.list_vms }}"
register: save_result
(You can also set environment
on the play instead of on an individual task).