Skip to content
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

proxmox_kvm: allow suspending and hibernation as vm state and resuming of vms #9620

Open
1 task done
ff05 opened this issue Jan 24, 2025 · 4 comments
Open
1 task done
Labels
feature This issue/PR relates to a feature request has_pr module module plugins plugin (any type)

Comments

@ff05
Copy link

ff05 commented Jan 24, 2025

Summary

I try to bulk hibernate all VMs on a node, rather than shutting them down to reboot this node.
That would save the vmstates.

Issue Type

Feature Idea

Component Name

proxmox_kvm

Additional Information

    - name: hibernate all vms
      community.general.proxmox_kvm:
        api_host: "{{ proxmox_api_host }}"
        api_user: "{{ proxmox_api_user }}"
        api_token_id: "{{ proxmox_api_token_id }}"
        api_token_secret: "{{ proxmox_api_token_secret }}"
        vmid: "{{ vmid }}"
        state: hibernate

possible solution could be:

[...]
    def suspend_vm(self, vm, timeout, todisk):
        vmid = vm['vmid']
        proxmox_node = self.proxmox_api.nodes(vm['node'])
        taskid = proxmox_node.qemu(vmid).status.suspend.post(todisk=(1 if todisk else 0), timeout=timeout)
        if not self.wait_for_task(vm['node'], taskid):
            self.module.fail_json(msg='Reached timeout while waiting for suspending VM. Last line in task before timeout: %s' %
                                  proxmox_node.tasks(taskid).log.get()[:1])
            return False
        return True
    
    def resume_vm(self, vm):
        vmid = vm['vmid']
        proxmox_node = self.proxmox_api.nodes(vm['node'])
        taskid = proxmox_node.qemu(vmid).status.resume.post()
        if not self.wait_for_task(vm['node'], taskid):
            self.module.fail_json(msg='Reached timeout while waiting for suspending VM. Last line in task before timeout: %s' %
                                  proxmox_node.tasks(taskid).log.get()[:1])
            return False
        return True
[...]
def main():
    module_args = proxmox_auth_argument_spec()
    kvm_args = dict(
[...]
        state=dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted', 'current', 'template', 'paused', 'hibernated']),
[...]
    elif state == 'started':
        if not vmid:
            module.fail_json(msg='VM with name = %s does not exist in cluster' % name)

        status = {}
        try:
            vm = proxmox.get_vm(vmid)
            current = proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).status.current.get()['status']
            status['status'] = current
            if current == 'running' and status['qmpstatus'] == 'running':
                module.exit_json(changed=False, vmid=vmid, msg="VM %s is already running" % vmid, **status)

            if status['qmpstatus'] == 'paused' or \
                (current == 'stopped' and status['qmpstatus'] == 'stopped' and status['lock'] == 'suspended'):
                proxmox.resume_vm(vm)
                module.exit_json(changed=True, vmid=vmid, msg="VM %s resumed" % vmid, **status)

            if proxmox.start_vm(vm):
                module.exit_json(changed=True, vmid=vmid, msg="VM %s started" % vmid, **status)
        except Exception as e:
            module.fail_json(vmid=vmid, msg="starting of VM %s failed with exception: %s" % (vmid, e), **status)
[...]
    elif state in ['paused', 'hibernated']:
        if not vmid:
            module.fail_json(msg='VM with name = %s does not exist in cluster' % name)

        status = {}
        try:
            vm = proxmox.get_vm(vmid)
            current = proxmox.proxmox_api.nodes(vm['node']).qemu(vmid).status.current.get()['status']
            status['status'] = current
            if current != 'running':
                module.exit_json(changed=False, vmid=vmid, msg="VM %s is not running" % vmid, **status)

            proxmox.suspend_vm(vm, force=module.params['force'], timeout=module.params['timeout'], todisk=(state == 'hibernated'))
            module.exit_json(changed=True, vmid=vmid, msg="VM %s is suspending" % vmid, **status)
        except Exception as e:
            module.fail_json(vmid=vmid, msg="suspending of VM %s failed with exception: %s" % (vmid, e), **status)

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibullbot
Copy link
Collaborator

@ansibullbot ansibullbot added feature This issue/PR relates to a feature request module module plugins plugin (any type) labels Jan 24, 2025
@russoz
Copy link
Collaborator

russoz commented Jan 30, 2025

Hi @ff05 thanks for your contribution!

Would you be willing to raise a Pull Request with your suggested change?

@ff05
Copy link
Author

ff05 commented Jan 31, 2025

Hi @russoz
I raised the request here #9653

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature This issue/PR relates to a feature request has_pr module module plugins plugin (any type)
Projects
None yet
Development

No branches or pull requests

3 participants