From 072faed3f772a3736f898aa69c102e3e4c11f30f Mon Sep 17 00:00:00 2001 From: Eric Trombly Date: Mon, 21 Aug 2023 15:42:39 -0500 Subject: [PATCH 1/6] add template option to proxmox and proxmox_kvm --- plugins/modules/proxmox.py | 39 +++++++++++++++++++++++++--- plugins/modules/proxmox_kvm.py | 47 +++++++++++++++++++++++++++++++++- 2 files changed, 82 insertions(+), 4 deletions(-) diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index 5ef842a2a33..0e21ca5df38 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -145,7 +145,7 @@ description: - Indicate desired state of the instance type: str - choices: ['present', 'started', 'absent', 'stopped', 'restarted'] + choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'template'] default: present pubkey: description: @@ -419,6 +419,23 @@ api_host: node1 state: restarted +- name: Convert container to template + community.general.proxmox: + vmid: 100 + api_user: root@pam + api_password: 1q2w3e + api_host: node1 + state: template + +- name: Convert container to template(stop container if running) + community.general.proxmox: + vmid: 100 + api_user: root@pam + api_password: 1q2w3e + api_host: node1 + state: template + force: true + - name: Remove container community.general.proxmox: vmid: 100 @@ -581,6 +598,13 @@ def stop_instance(self, vm, vmid, timeout, force): time.sleep(1) return False + def convert_to_template(self, vm, vmid, timeout, force): + if getattr(self.proxmox_api.nodes(vm['node']), VZ_TYPE)(vmid).status.current.get()['status'] == 'running' and force: + self.stop_instance(vm, vmid, timeout, force) + # not sure why, but templating a container doesn't return a taskid + getattr(self.proxmox_api.nodes(vm['node']), VZ_TYPE)(vmid).template.post() + return True + def umount_instance(self, vm, vmid, timeout): taskid = getattr(self.proxmox_api.nodes(vm['node']), VZ_TYPE)(vmid).status.umount.post() while timeout: @@ -621,7 +645,7 @@ def main(): timeout=dict(type='int', default=30), force=dict(type='bool', default=False), purge=dict(type='bool', default=False), - state=dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted']), + state=dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted', 'template']), pubkey=dict(type='str'), unprivileged=dict(type='bool', default=True), description=dict(type='str'), @@ -789,7 +813,16 @@ def main(): if proxmox.stop_instance(vm, vmid, timeout, force=module.params['force']): module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid) except Exception as e: - module.fail_json(vmid=vmid, msg="stopping of VM %s failed with exception: %s" % (vmid, e)) + module.fail_json(msg="stopping of VM %s failed with exception: %s" % (vmid, e)) + + elif state == 'template': + try: + vm = proxmox.get_vm(vmid) + + if proxmox.convert_to_template(vm, vmid, timeout, force=module.params['force']): + module.exit_json(changed=True, msg="VM %s is converted to template" % vmid) + except Exception as e: + module.fail_json(msg="conversion of VM %s to template failed with exception: %s" % (vmid, e)) elif state == 'restarted': try: diff --git a/plugins/modules/proxmox_kvm.py b/plugins/modules/proxmox_kvm.py index 9efd818e64e..08f0577ad9b 100644 --- a/plugins/modules/proxmox_kvm.py +++ b/plugins/modules/proxmox_kvm.py @@ -792,6 +792,25 @@ node: sabrewulf state: restarted +- name: Convert VM to template + community.general.proxmox_kvm: + api_user: root@pam + api_password: secret + api_host: helldorado + name: spynal + node: sabrewulf + state: template + +- name: Convert VM to template (stop VM if running) + community.general.proxmox_kvm: + api_user: root@pam + api_password: secret + api_host: helldorado + name: spynal + node: sabrewulf + state: template + force: true + - name: Remove VM community.general.proxmox_kvm: api_user: root@pam @@ -1134,6 +1153,19 @@ def restart_vm(self, vm, force, **status): except Exception as e: self.module.fail_json(vmid=vmid, msg="restarting of VM %s failed with exception: %s" % (vmid, e)) return False + + def convert_to_template(self, vm, timeout, force): + vmid = vm['vmid'] + try: + proxmox_node = self.proxmox_api.nodes(vm['node']) + if proxmox_node.qemu(vmid).status.current.get()['status'] == 'running' and force: + self.stop_instance(vm, vmid, timeout, force) + # not sure why, but templating a container doesn't return a taskid + proxmox_node.qemu(vmid).template.post() + return True + except Exception as e: + self.module.fail_json(vmid=vmid, msg="conversion of VM %s to template failed with exception: %s" % (vmid, e)) + return False def migrate_vm(self, vm, target_node): vmid = vm['vmid'] @@ -1222,7 +1254,7 @@ def main(): sshkeys=dict(type='str', no_log=False), startdate=dict(type='str'), startup=dict(), - state=dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted', 'current']), + state=dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted', 'current', 'template']), storage=dict(type='str'), tablet=dict(type='bool'), tags=dict(type='list', elements='str'), @@ -1496,6 +1528,19 @@ def main(): module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid, **status) except Exception as e: module.fail_json(vmid=vmid, msg="stopping of VM %s failed with exception: %s" % (vmid, e), **status) + + elif state == 'template': + if not vmid: + module.fail_json(msg='VM with name = %s does not exist in cluster' % name) + + status = {} + try: + vm = proxmox.get_vm(vmid) + + if proxmox.convert_to_template(vm, force=module.params['force'], timeout=module.params['timeout']): + module.exit_json(changed=True, vmid=vmid, msg="VM %s is converting to template" % vmid, **status) + except Exception as e: + module.fail_json(vmid=vmid, msg="conversion of VM %s to template failed with exception: %s" % (vmid, e), **status) elif state == 'restarted': if not vmid: From f839d7fc076c828f7cd529008109f0e99f3cb076 Mon Sep 17 00:00:00 2001 From: Eric Trombly Date: Wed, 25 Oct 2023 14:18:35 -0500 Subject: [PATCH 2/6] make recommended updates --- plugins/modules/proxmox.py | 7 ++++--- plugins/modules/proxmox_kvm.py | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index 0e21ca5df38..bed081ae68a 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -144,6 +144,7 @@ state: description: - Indicate desired state of the instance + - V(template) was added in community.general 8.0.0. type: str choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'template'] default: present @@ -427,7 +428,7 @@ api_host: node1 state: template -- name: Convert container to template(stop container if running) +- name: Convert container to template (stop container if running) community.general.proxmox: vmid: 100 api_user: root@pam @@ -819,8 +820,8 @@ def main(): try: vm = proxmox.get_vm(vmid) - if proxmox.convert_to_template(vm, vmid, timeout, force=module.params['force']): - module.exit_json(changed=True, msg="VM %s is converted to template" % vmid) + proxmox.convert_to_template(vm, vmid, timeout, force=module.params['force']) + module.exit_json(changed=True, msg="VM %s is converted to template" % vmid) except Exception as e: module.fail_json(msg="conversion of VM %s to template failed with exception: %s" % (vmid, e)) diff --git a/plugins/modules/proxmox_kvm.py b/plugins/modules/proxmox_kvm.py index 08f0577ad9b..3ad6c6ae07b 100644 --- a/plugins/modules/proxmox_kvm.py +++ b/plugins/modules/proxmox_kvm.py @@ -453,8 +453,9 @@ description: - Indicates desired state of the instance. - If V(current), the current state of the VM will be fetched. You can access it with C(results.status) + - V(template) was added in community.general 8.0.0. type: str - choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'current'] + choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'current', 'template'] default: present storage: description: @@ -1524,8 +1525,8 @@ def main(): if vm['status'] == 'stopped': module.exit_json(changed=False, vmid=vmid, msg="VM %s is already stopped" % vmid, **status) - if proxmox.stop_vm(vm, force=module.params['force'], timeout=module.params['timeout']): - module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid, **status) + proxmox.stop_vm(vm, force=module.params['force'], timeout=module.params['timeout']) + module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid, **status) except Exception as e: module.fail_json(vmid=vmid, msg="stopping of VM %s failed with exception: %s" % (vmid, e), **status) From 9e32e6a39553725133546b2b3693eeab9c890c08 Mon Sep 17 00:00:00 2001 From: Eric Trombly Date: Wed, 25 Oct 2023 15:04:18 -0500 Subject: [PATCH 3/6] fix tests --- plugins/modules/proxmox.py | 2 +- plugins/modules/proxmox_kvm.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index bed081ae68a..ebba2ec78fd 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -815,7 +815,7 @@ def main(): module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid) except Exception as e: module.fail_json(msg="stopping of VM %s failed with exception: %s" % (vmid, e)) - + elif state == 'template': try: vm = proxmox.get_vm(vmid) diff --git a/plugins/modules/proxmox_kvm.py b/plugins/modules/proxmox_kvm.py index 3ad6c6ae07b..d88316a4cc9 100644 --- a/plugins/modules/proxmox_kvm.py +++ b/plugins/modules/proxmox_kvm.py @@ -1154,7 +1154,7 @@ def restart_vm(self, vm, force, **status): except Exception as e: self.module.fail_json(vmid=vmid, msg="restarting of VM %s failed with exception: %s" % (vmid, e)) return False - + def convert_to_template(self, vm, timeout, force): vmid = vm['vmid'] try: @@ -1529,7 +1529,7 @@ def main(): module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid, **status) except Exception as e: module.fail_json(vmid=vmid, msg="stopping of VM %s failed with exception: %s" % (vmid, e), **status) - + elif state == 'template': if not vmid: module.fail_json(msg='VM with name = %s does not exist in cluster' % name) From 8261bcde8f5e4ddb4314b3b491cbec540befcce8 Mon Sep 17 00:00:00 2001 From: Eric Trombly Date: Wed, 1 Nov 2023 09:17:09 -0500 Subject: [PATCH 4/6] resolve comments on PR --- changelogs/fragments/7143-proxmox-template.yml | 0 plugins/modules/proxmox.py | 6 +++--- plugins/modules/proxmox_kvm.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) create mode 100644 changelogs/fragments/7143-proxmox-template.yml diff --git a/changelogs/fragments/7143-proxmox-template.yml b/changelogs/fragments/7143-proxmox-template.yml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/plugins/modules/proxmox.py b/plugins/modules/proxmox.py index ebba2ec78fd..6178ea79d4f 100644 --- a/plugins/modules/proxmox.py +++ b/plugins/modules/proxmox.py @@ -144,7 +144,7 @@ state: description: - Indicate desired state of the instance - - V(template) was added in community.general 8.0.0. + - V(template) was added in community.general 8.1.0. type: str choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'template'] default: present @@ -814,7 +814,7 @@ def main(): if proxmox.stop_instance(vm, vmid, timeout, force=module.params['force']): module.exit_json(changed=True, vmid=vmid, msg="VM %s is shutting down" % vmid) except Exception as e: - module.fail_json(msg="stopping of VM %s failed with exception: %s" % (vmid, e)) + module.fail_json(vmid=vmid, msg="stopping of VM %s failed with exception: %s" % (vmid, e)) elif state == 'template': try: @@ -823,7 +823,7 @@ def main(): proxmox.convert_to_template(vm, vmid, timeout, force=module.params['force']) module.exit_json(changed=True, msg="VM %s is converted to template" % vmid) except Exception as e: - module.fail_json(msg="conversion of VM %s to template failed with exception: %s" % (vmid, e)) + module.fail_json(vmid=vmid, msg="conversion of VM %s to template failed with exception: %s" % (vmid, e)) elif state == 'restarted': try: diff --git a/plugins/modules/proxmox_kvm.py b/plugins/modules/proxmox_kvm.py index d88316a4cc9..7b057f01556 100644 --- a/plugins/modules/proxmox_kvm.py +++ b/plugins/modules/proxmox_kvm.py @@ -453,7 +453,7 @@ description: - Indicates desired state of the instance. - If V(current), the current state of the VM will be fetched. You can access it with C(results.status) - - V(template) was added in community.general 8.0.0. + - V(template) was added in community.general 8.1.0. type: str choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'current', 'template'] default: present From ee86379ce85cb11625607430e8c3976a32b56aed Mon Sep 17 00:00:00 2001 From: Eric Trombly Date: Wed, 1 Nov 2023 09:58:01 -0500 Subject: [PATCH 5/6] save changes to changelog fragment --- changelogs/fragments/7143-proxmox-template.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/changelogs/fragments/7143-proxmox-template.yml b/changelogs/fragments/7143-proxmox-template.yml index e69de29bb2d..414c9b52bc2 100644 --- a/changelogs/fragments/7143-proxmox-template.yml +++ b/changelogs/fragments/7143-proxmox-template.yml @@ -0,0 +1,3 @@ +minor_changes: + - proxmox - adds ``template`` parameter to state, allowing conversion of container to a template + - proxmox_kvm - adds ``template`` parameter to state, allowing conversion of a VM to a template From 0b89d140548005ca3acb35b461fad2a1b5399d9c Mon Sep 17 00:00:00 2001 From: Eric Trombly Date: Wed, 1 Nov 2023 15:56:36 -0500 Subject: [PATCH 6/6] Update changelogs/fragments/7143-proxmox-template.yml Co-authored-by: Felix Fontein --- changelogs/fragments/7143-proxmox-template.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/changelogs/fragments/7143-proxmox-template.yml b/changelogs/fragments/7143-proxmox-template.yml index 414c9b52bc2..89d44594d3b 100644 --- a/changelogs/fragments/7143-proxmox-template.yml +++ b/changelogs/fragments/7143-proxmox-template.yml @@ -1,3 +1,3 @@ minor_changes: - - proxmox - adds ``template`` parameter to state, allowing conversion of container to a template - - proxmox_kvm - adds ``template`` parameter to state, allowing conversion of a VM to a template + - proxmox - adds ``template`` value to the ``state`` parameter, allowing conversion of container to a template (https://github.com/ansible-collections/community.general/pull/7143). + - proxmox_kvm - adds ``template`` value to the ``state`` parameter, allowing conversion of a VM to a template (https://github.com/ansible-collections/community.general/pull/7143).