Skip to content

Commit

Permalink
add template option to proxmox and proxmox_kvm (#7143)
Browse files Browse the repository at this point in the history
* add template option to proxmox and proxmox_kvm

* make recommended updates

* fix tests

* resolve comments on PR

* save changes to changelog fragment

* Update changelogs/fragments/7143-proxmox-template.yml

Co-authored-by: Felix Fontein <[email protected]>

---------

Co-authored-by: Eric Trombly <[email protected]>
Co-authored-by: Felix Fontein <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2023
1 parent 567c7d1 commit 07a47c0
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 6 deletions.
3 changes: 3 additions & 0 deletions changelogs/fragments/7143-proxmox-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
minor_changes:
- 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).
38 changes: 36 additions & 2 deletions plugins/modules/proxmox.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@
state:
description:
- Indicate desired state of the instance
- V(template) was added in community.general 8.1.0.
type: str
choices: ['present', 'started', 'absent', 'stopped', 'restarted']
choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'template']
default: present
pubkey:
description:
Expand Down Expand Up @@ -419,6 +420,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
Expand Down Expand Up @@ -581,6 +599,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:
Expand Down Expand Up @@ -621,7 +646,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'),
Expand Down Expand Up @@ -791,6 +816,15 @@ def main():
except Exception as e:
module.fail_json(vmid=vmid, msg="stopping of VM %s failed with exception: %s" % (vmid, e))

elif state == 'template':
try:
vm = proxmox.get_vm(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(vmid=vmid, msg="conversion of VM %s to template failed with exception: %s" % (vmid, e))

elif state == 'restarted':
try:
vm = proxmox.get_vm(vmid)
Expand Down
54 changes: 50 additions & 4 deletions plugins/modules/proxmox_kvm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.1.0.
type: str
choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'current']
choices: ['present', 'started', 'absent', 'stopped', 'restarted', 'current', 'template']
default: present
storage:
description:
Expand Down Expand Up @@ -792,6 +793,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
Expand Down Expand Up @@ -1135,6 +1155,19 @@ def restart_vm(self, vm, force, **status):
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']
proxmox_node = self.proxmox_api.nodes(vm['node'])
Expand Down Expand Up @@ -1222,7 +1255,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'),
Expand Down Expand Up @@ -1492,11 +1525,24 @@ 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)

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:
module.fail_json(msg='VM with name = %s does not exist in cluster' % name)
Expand Down

0 comments on commit 07a47c0

Please sign in to comment.