mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
* resolve #21056 - Add support for full cloning. Fix some issues. Update doc * Fix condition and update doc. Fixes #28585 * Using built-in helper for argspec, revert ansible metadata, add more control and remove type in documentation * PEP8 style compliance
This commit is contained in:
parent
7869b543fa
commit
c22fbdc831
1 changed files with 529 additions and 347 deletions
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# (c) 2016, Abdoul Bah (@helldorado) <abdoul.bah at alterway.fr>
|
# (c) 2016, Abdoul Bah (@helldorado) <bahabdoul at gmail.com>
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Ansible module to manage Qemu(KVM) instance in Proxmox VE cluster.
|
Ansible module to manage Qemu(KVM) instance in Proxmox VE cluster.
|
||||||
|
@ -28,7 +28,7 @@ short_description: Management of Qemu(KVM) Virtual Machines in Proxmox VE cluste
|
||||||
description:
|
description:
|
||||||
- Allows you to create/delete/stop Qemu(KVM) Virtual Machines in Proxmox VE cluster.
|
- Allows you to create/delete/stop Qemu(KVM) Virtual Machines in Proxmox VE cluster.
|
||||||
version_added: "2.3"
|
version_added: "2.3"
|
||||||
author: "Abdoul Bah (@helldorado) <abdoul.bah at alterway.fr>"
|
author: "Abdoul Bah (@helldorado) <bahabdoul at gmail.com>"
|
||||||
options:
|
options:
|
||||||
acpi:
|
acpi:
|
||||||
description:
|
description:
|
||||||
|
@ -36,21 +36,18 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: "yes"
|
default: "yes"
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
agent:
|
agent:
|
||||||
description:
|
description:
|
||||||
- Specify if the QEMU GuestAgent should be enabled/disabled.
|
- Specify if the QEMU GuestAgent should be enabled/disabled.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
args:
|
args:
|
||||||
description:
|
description:
|
||||||
- Pass arbitrary arguments to kvm.
|
- Pass arbitrary arguments to kvm.
|
||||||
- This option is for experts only!
|
- This option is for experts only!
|
||||||
default: "-serial unix:/var/run/qemu-server/VMID.serial,server,nowait"
|
default: "-serial unix:/var/run/qemu-server/VMID.serial,server,nowait"
|
||||||
required: false
|
required: false
|
||||||
type: string
|
|
||||||
api_host:
|
api_host:
|
||||||
description:
|
description:
|
||||||
- Specify the target host of the Proxmox VE cluster.
|
- Specify the target host of the Proxmox VE cluster.
|
||||||
|
@ -71,80 +68,73 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: "no"
|
default: "no"
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
balloon:
|
balloon:
|
||||||
description:
|
description:
|
||||||
- Specify the amount of RAM for the VM in MB.
|
- Specify the amount of RAM for the VM in MB.
|
||||||
- Using zero disables the balloon driver.
|
- Using zero disables the balloon driver.
|
||||||
required: false
|
required: false
|
||||||
default: 0
|
default: 0
|
||||||
type: integer
|
|
||||||
bios:
|
bios:
|
||||||
description:
|
description:
|
||||||
- Specify the BIOS implementation.
|
- Specify the BIOS implementation.
|
||||||
choices: ['seabios', 'ovmf']
|
choices: ['seabios', 'ovmf']
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
boot:
|
boot:
|
||||||
description:
|
description:
|
||||||
- Specify the boot order -> boot on floppy C(a), hard disk C(c), CD-ROM C(d), or network C(n).
|
- Specify the boot order -> boot on floppy C(a), hard disk C(c), CD-ROM C(d), or network C(n).
|
||||||
- You can combine to set order.
|
- You can combine to set order.
|
||||||
required: false
|
required: false
|
||||||
default: cnd
|
default: cnd
|
||||||
type: string
|
|
||||||
bootdisk:
|
bootdisk:
|
||||||
description:
|
description:
|
||||||
- Enable booting from specified disk. C((ide|sata|scsi|virtio)\d+)
|
- Enable booting from specified disk. C((ide|sata|scsi|virtio)\d+)
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
clone:
|
||||||
|
description:
|
||||||
|
- Name of VM to be cloned. If C(vmid) is setted, C(clone) can take arbitrary value but required for intiating the clone.
|
||||||
|
required: false
|
||||||
|
default: null
|
||||||
cores:
|
cores:
|
||||||
description:
|
description:
|
||||||
- Specify number of cores per socket.
|
- Specify number of cores per socket.
|
||||||
required: false
|
required: false
|
||||||
default: 1
|
default: 1
|
||||||
type: integer
|
|
||||||
cpu:
|
cpu:
|
||||||
description:
|
description:
|
||||||
- Specify emulated CPU type.
|
- Specify emulated CPU type.
|
||||||
required: false
|
required: false
|
||||||
default: kvm64
|
default: kvm64
|
||||||
type: string
|
|
||||||
cpulimit:
|
cpulimit:
|
||||||
description:
|
description:
|
||||||
- Specify if CPU usage will be limited. Value 0 indicates no CPU limit.
|
- Specify if CPU usage will be limited. Value 0 indicates no CPU limit.
|
||||||
- If the computer has 2 CPUs, it has total of '2' CPU time
|
- If the computer has 2 CPUs, it has total of '2' CPU time
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: integer
|
|
||||||
cpuunits:
|
cpuunits:
|
||||||
description:
|
description:
|
||||||
- Specify CPU weight for a VM.
|
- Specify CPU weight for a VM.
|
||||||
- You can disable fair-scheduler configuration by setting this to 0
|
- You can disable fair-scheduler configuration by setting this to 0
|
||||||
default: 1000
|
default: 1000
|
||||||
required: false
|
required: false
|
||||||
type: integer
|
|
||||||
delete:
|
delete:
|
||||||
description:
|
description:
|
||||||
- Specify a list of settings you want to delete.
|
- Specify a list of settings you want to delete.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
description:
|
description:
|
||||||
description:
|
description:
|
||||||
- Specify the description for the VM. Only used on the configuration web interface.
|
- Specify the description for the VM. Only used on the configuration web interface.
|
||||||
- This is saved as comment inside the configuration file.
|
- This is saved as comment inside the configuration file.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
digest:
|
digest:
|
||||||
description:
|
description:
|
||||||
- Specify if to prevent changes if current configuration file has different SHA1 digest.
|
- Specify if to prevent changes if current configuration file has different SHA1 digest.
|
||||||
- This can be used to prevent concurrent modifications.
|
- This can be used to prevent concurrent modifications.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
force:
|
force:
|
||||||
description:
|
description:
|
||||||
- Allow to force stop VM.
|
- Allow to force stop VM.
|
||||||
|
@ -152,14 +142,27 @@ options:
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
format:
|
||||||
|
description:
|
||||||
|
- Target drive’s backing file’s data format.
|
||||||
|
- Used only with clone
|
||||||
|
default: qcow2
|
||||||
|
choices: [ "cloop", "cow", "qcow", "qcow2", "qed", "raw", "vmdk" ]
|
||||||
|
required: false
|
||||||
freeze:
|
freeze:
|
||||||
description:
|
description:
|
||||||
- Specify if PVE should freeze CPU at startup (use 'c' monitor command to start execution).
|
- Specify if PVE should freeze CPU at startup (use 'c' monitor command to start execution).
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
full:
|
||||||
|
description:
|
||||||
|
- Create a full copy of all disk. This is always done when you clone a normal VM.
|
||||||
|
- For VM templates, we try to create a linked clone by default.
|
||||||
|
- Used only with clone
|
||||||
|
default: yes
|
||||||
|
choices: [ "yes", "no"]
|
||||||
|
required: false
|
||||||
hostpci:
|
hostpci:
|
||||||
description:
|
description:
|
||||||
- Specify a hash/dictionary of map host pci devices into guest. C(hostpci='{"key":"value", "key":"value"}').
|
- Specify a hash/dictionary of map host pci devices into guest. C(hostpci='{"key":"value", "key":"value"}').
|
||||||
|
@ -172,7 +175,6 @@ options:
|
||||||
- /!\ This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
|
- /!\ This option allows direct access to host hardware. So it is no longer possible to migrate such machines - use with special care.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: A hash/dictionary defining host pci devices
|
|
||||||
hotplug:
|
hotplug:
|
||||||
description:
|
description:
|
||||||
- Selectively enable hotplug features.
|
- Selectively enable hotplug features.
|
||||||
|
@ -180,14 +182,12 @@ options:
|
||||||
- Value 0 disables hotplug completely and value 1 is an alias for the default C('network,disk,usb').
|
- Value 0 disables hotplug completely and value 1 is an alias for the default C('network,disk,usb').
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
hugepages:
|
hugepages:
|
||||||
description:
|
description:
|
||||||
- Enable/disable hugepages memory.
|
- Enable/disable hugepages memory.
|
||||||
choices: ['any', '2', '1024']
|
choices: ['any', '2', '1024']
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
ide:
|
ide:
|
||||||
description:
|
description:
|
||||||
- A hash/dictionary of volume used as IDE hard disk or CD-ROM. C(ide='{"key":"value", "key":"value"}').
|
- A hash/dictionary of volume used as IDE hard disk or CD-ROM. C(ide='{"key":"value", "key":"value"}').
|
||||||
|
@ -198,20 +198,17 @@ options:
|
||||||
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: A hash/dictionary defining ide
|
|
||||||
keyboard:
|
keyboard:
|
||||||
description:
|
description:
|
||||||
- Sets the keyboard layout for VNC server.
|
- Sets the keyboard layout for VNC server.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
kvm:
|
kvm:
|
||||||
description:
|
description:
|
||||||
- Enable/disable KVM hardware virtualization.
|
- Enable/disable KVM hardware virtualization.
|
||||||
required: false
|
required: false
|
||||||
default: "yes"
|
default: "yes"
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
localtime:
|
localtime:
|
||||||
description:
|
description:
|
||||||
- Sets the real time clock to local time.
|
- Sets the real time clock to local time.
|
||||||
|
@ -219,40 +216,34 @@ options:
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
lock:
|
lock:
|
||||||
description:
|
description:
|
||||||
- Lock/unlock the VM.
|
- Lock/unlock the VM.
|
||||||
choices: ['migrate', 'backup', 'snapshot', 'rollback']
|
choices: ['migrate', 'backup', 'snapshot', 'rollback']
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
machine:
|
machine:
|
||||||
description:
|
description:
|
||||||
- Specifies the Qemu machine type.
|
- Specifies the Qemu machine type.
|
||||||
- type => C((pc|pc(-i440fx)?-\d+\.\d+(\.pxe)?|q35|pc-q35-\d+\.\d+(\.pxe)?))
|
- type => C((pc|pc(-i440fx)?-\d+\.\d+(\.pxe)?|q35|pc-q35-\d+\.\d+(\.pxe)?))
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
memory:
|
memory:
|
||||||
description:
|
description:
|
||||||
- Memory size in MB for instance.
|
- Memory size in MB for instance.
|
||||||
required: false
|
required: false
|
||||||
default: 512
|
default: 512
|
||||||
type: integer
|
|
||||||
migrate_downtime:
|
migrate_downtime:
|
||||||
description:
|
description:
|
||||||
- Sets maximum tolerated downtime (in seconds) for migrations.
|
- Sets maximum tolerated downtime (in seconds) for migrations.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: integer
|
|
||||||
migrate_speed:
|
migrate_speed:
|
||||||
description:
|
description:
|
||||||
- Sets maximum speed (in MB/s) for migrations.
|
- Sets maximum speed (in MB/s) for migrations.
|
||||||
- A value of 0 is no limit.
|
- A value of 0 is no limit.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: integer
|
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- Specifies the VM name. Only used on the configuration web interface.
|
- Specifies the VM name. Only used on the configuration web interface.
|
||||||
|
@ -271,7 +262,12 @@ options:
|
||||||
- If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services.
|
- If you specify no bridge, we create a kvm 'user' (NATed) network device, which provides DHCP and DNS services.
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: A hash/dictionary defining interfaces
|
newid:
|
||||||
|
description:
|
||||||
|
- VMID for the clone. Used only with clone.
|
||||||
|
- If newid is not set, the next available VM ID will be fetched from ProxmoxAPI.
|
||||||
|
default: null
|
||||||
|
required: false
|
||||||
node:
|
node:
|
||||||
description:
|
description:
|
||||||
- Proxmox VE node, where the new VM will be created.
|
- Proxmox VE node, where the new VM will be created.
|
||||||
|
@ -290,14 +286,12 @@ options:
|
||||||
- C(policy) NUMA allocation policy.
|
- C(policy) NUMA allocation policy.
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: A hash/dictionary defining NUMA topology
|
|
||||||
onboot:
|
onboot:
|
||||||
description:
|
description:
|
||||||
- Specifies whether a VM will be started during system bootup.
|
- Specifies whether a VM will be started during system bootup.
|
||||||
default: "yes"
|
default: "yes"
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
|
||||||
ostype:
|
ostype:
|
||||||
description:
|
description:
|
||||||
- Specifies guest operating system. This is used to enable special optimization/features for specific operating systems.
|
- Specifies guest operating system. This is used to enable special optimization/features for specific operating systems.
|
||||||
|
@ -305,7 +299,6 @@ options:
|
||||||
choices: ['other', 'wxp', 'w2k', 'w2k3', 'w2k8', 'wvista', 'win7', 'win8', 'l24', 'l26', 'solaris']
|
choices: ['other', 'wxp', 'w2k', 'w2k3', 'w2k8', 'wvista', 'win7', 'win8', 'l24', 'l26', 'solaris']
|
||||||
default: l26
|
default: l26
|
||||||
required: false
|
required: false
|
||||||
type: string
|
|
||||||
parallel:
|
parallel:
|
||||||
description:
|
description:
|
||||||
- A hash/dictionary of map host parallel devices. C(parallel='{"key":"value", "key":"value"}').
|
- A hash/dictionary of map host parallel devices. C(parallel='{"key":"value", "key":"value"}').
|
||||||
|
@ -313,27 +306,28 @@ options:
|
||||||
- Values allowed are - C("/dev/parport\d+|/dev/usb/lp\d+").
|
- Values allowed are - C("/dev/parport\d+|/dev/usb/lp\d+").
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: A hash/dictionary defining host parallel devices
|
pool:
|
||||||
|
description:
|
||||||
|
- Add the new VM to the specified pool.
|
||||||
|
default: null
|
||||||
|
required: false
|
||||||
protection:
|
protection:
|
||||||
description:
|
description:
|
||||||
- Enable/disable the protection flag of the VM. This will enable/disable the remove VM and remove disk operations.
|
- Enable/disable the protection flag of the VM. This will enable/disable the remove VM and remove disk operations.
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
|
||||||
reboot:
|
reboot:
|
||||||
description:
|
description:
|
||||||
- Allow reboot. If set to yes, the VM exit on reboot.
|
- Allow reboot. If set to yes, the VM exit on reboot.
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
|
||||||
revert:
|
revert:
|
||||||
description:
|
description:
|
||||||
- Revert a pending change.
|
- Revert a pending change.
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: string
|
|
||||||
sata:
|
sata:
|
||||||
description:
|
description:
|
||||||
- A hash/dictionary of volume used as sata hard disk or CD-ROM. C(sata='{"key":"value", "key":"value"}').
|
- A hash/dictionary of volume used as sata hard disk or CD-ROM. C(sata='{"key":"value", "key":"value"}').
|
||||||
|
@ -344,7 +338,6 @@ options:
|
||||||
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: A hash/dictionary defining sata
|
|
||||||
scsi:
|
scsi:
|
||||||
description:
|
description:
|
||||||
- A hash/dictionary of volume used as SCSI hard disk or CD-ROM. C(scsi='{"key":"value", "key":"value"}').
|
- A hash/dictionary of volume used as SCSI hard disk or CD-ROM. C(scsi='{"key":"value", "key":"value"}').
|
||||||
|
@ -355,14 +348,12 @@ options:
|
||||||
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: A hash/dictionary defining scsi
|
|
||||||
scsihw:
|
scsihw:
|
||||||
description:
|
description:
|
||||||
- Specifies the SCSI controller model.
|
- Specifies the SCSI controller model.
|
||||||
choices: ['lsi', 'lsi53c810', 'virtio-scsi-pci', 'virtio-scsi-single', 'megasas', 'pvscsi']
|
choices: ['lsi', 'lsi53c810', 'virtio-scsi-pci', 'virtio-scsi-single', 'megasas', 'pvscsi']
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
serial:
|
serial:
|
||||||
description:
|
description:
|
||||||
- A hash/dictionary of serial device to create inside the VM. C('{"key":"value", "key":"value"}').
|
- A hash/dictionary of serial device to create inside the VM. C('{"key":"value", "key":"value"}').
|
||||||
|
@ -371,7 +362,6 @@ options:
|
||||||
- /!\ If you pass through a host serial device, it is no longer possible to migrate such machines - use with special care.
|
- /!\ If you pass through a host serial device, it is no longer possible to migrate such machines - use with special care.
|
||||||
default: null
|
default: null
|
||||||
required: false
|
required: false
|
||||||
type: A hash/dictionary defining serial
|
|
||||||
shares:
|
shares:
|
||||||
description:
|
description:
|
||||||
- Rets amount of memory shares for auto-ballooning. (0 - 50000).
|
- Rets amount of memory shares for auto-ballooning. (0 - 50000).
|
||||||
|
@ -380,34 +370,33 @@ options:
|
||||||
- Using 0 disables auto-ballooning, this means no limit.
|
- Using 0 disables auto-ballooning, this means no limit.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: integer
|
|
||||||
skiplock:
|
skiplock:
|
||||||
description:
|
description:
|
||||||
- Ignore locks
|
- Ignore locks
|
||||||
- Only root is allowed to use this option.
|
- Only root is allowed to use this option.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
|
||||||
type: boolean
|
|
||||||
smbios:
|
smbios:
|
||||||
description:
|
description:
|
||||||
- Specifies SMBIOS type 1 fields.
|
- Specifies SMBIOS type 1 fields.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
snapname:
|
||||||
|
description:
|
||||||
|
- The name of the snapshot. Used only with clone.
|
||||||
|
default: null
|
||||||
|
required: false
|
||||||
sockets:
|
sockets:
|
||||||
description:
|
description:
|
||||||
- Sets the number of CPU sockets. (1 - N).
|
- Sets the number of CPU sockets. (1 - N).
|
||||||
required: false
|
required: false
|
||||||
default: 1
|
default: 1
|
||||||
type: integer
|
|
||||||
startdate:
|
startdate:
|
||||||
description:
|
description:
|
||||||
- Sets the initial date of the real time clock.
|
- Sets the initial date of the real time clock.
|
||||||
- Valid format for date are C('now') or C('2016-09-25T16:01:21') or C('2016-09-25').
|
- Valid format for date are C('now') or C('2016-09-25T16:01:21') or C('2016-09-25').
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
startup:
|
startup:
|
||||||
description:
|
description:
|
||||||
- Startup and shutdown behavior. C([[order=]\d+] [,up=\d+] [,down=\d+]).
|
- Startup and shutdown behavior. C([[order=]\d+] [,up=\d+] [,down=\d+]).
|
||||||
|
@ -415,7 +404,6 @@ options:
|
||||||
- Shutdown in done with reverse ordering.
|
- Shutdown in done with reverse ordering.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- Indicates desired state of the instance.
|
- Indicates desired state of the instance.
|
||||||
|
@ -423,46 +411,59 @@ options:
|
||||||
choices: ['present', 'started', 'absent', 'stopped', 'restarted','current']
|
choices: ['present', 'started', 'absent', 'stopped', 'restarted','current']
|
||||||
required: false
|
required: false
|
||||||
default: present
|
default: present
|
||||||
|
storage:
|
||||||
|
description:
|
||||||
|
- Target storage for full clone.
|
||||||
|
default: null
|
||||||
|
required: false
|
||||||
tablet:
|
tablet:
|
||||||
description:
|
description:
|
||||||
- Enables/disables the USB tablet device.
|
- Enables/disables the USB tablet device.
|
||||||
required: false
|
required: false
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
default: "no"
|
default: "no"
|
||||||
type: boolean
|
target:
|
||||||
|
description:
|
||||||
|
- Target node. Only allowed if the original VM is on shared storage.
|
||||||
|
- Used only with clone
|
||||||
|
default: null
|
||||||
|
required: false
|
||||||
tdf:
|
tdf:
|
||||||
description:
|
description:
|
||||||
- Enables/disables time drift fix.
|
- Enables/disables time drift fix.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
template:
|
template:
|
||||||
description:
|
description:
|
||||||
- Enables/disables the template.
|
- Enables/disables the template.
|
||||||
required: false
|
required: false
|
||||||
default: "no"
|
default: "no"
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
type: boolean
|
|
||||||
timeout:
|
timeout:
|
||||||
description:
|
description:
|
||||||
- Timeout for operations.
|
- Timeout for operations.
|
||||||
default: 30
|
default: 30
|
||||||
required: false
|
required: false
|
||||||
type: integer
|
update:
|
||||||
|
description:
|
||||||
|
- If C(yes), the VM will be update with new value.
|
||||||
|
- Cause of the operations of the API and security reasons, I have disabled the update of the following parameters
|
||||||
|
- C(net, virtio, ide, sata, scsi). Per example updating C(net) update the MAC address and C(virtio) create always new disk...
|
||||||
|
default: "no"
|
||||||
|
choices: [ "yes", "no" ]
|
||||||
|
required: false
|
||||||
validate_certs:
|
validate_certs:
|
||||||
description:
|
description:
|
||||||
- If C(no), SSL certificates will not be validated. This should only be used on personally controlled sites using self-signed certificates.
|
- If C(no), SSL certificates will not be validated. This should only be used on personally controlled sites using self-signed certificates.
|
||||||
default: "no"
|
default: "no"
|
||||||
choices: [ "yes", "no" ]
|
choices: [ "yes", "no" ]
|
||||||
required: false
|
required: false
|
||||||
type: boolean
|
|
||||||
vcpus:
|
vcpus:
|
||||||
description:
|
description:
|
||||||
- Sets number of hotplugged vcpus.
|
- Sets number of hotplugged vcpus.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: integer
|
|
||||||
vga:
|
vga:
|
||||||
description:
|
description:
|
||||||
- Select VGA type. If you want to use high resolution modes (>= 1280x1024x16) then you should use option 'std' or 'vmware'.
|
- Select VGA type. If you want to use high resolution modes (>= 1280x1024x16) then you should use option 'std' or 'vmware'.
|
||||||
|
@ -479,7 +480,6 @@ options:
|
||||||
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
- C(format) is the drive’s backing file’s data format. C(qcow2|raw|subvol).
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: A hash/dictionary defining virtio
|
|
||||||
vmid:
|
vmid:
|
||||||
description:
|
description:
|
||||||
- Specifies the VM ID. Instead use I(name) parameter.
|
- Specifies the VM ID. Instead use I(name) parameter.
|
||||||
|
@ -491,7 +491,6 @@ options:
|
||||||
- Creates a virtual hardware watchdog device.
|
- Creates a virtual hardware watchdog device.
|
||||||
required: false
|
required: false
|
||||||
default: null
|
default: null
|
||||||
type: string
|
|
||||||
Notes:
|
Notes:
|
||||||
- Requires proxmoxer and requests modules on host. This modules can be installed with pip.
|
- Requires proxmoxer and requests modules on host. This modules can be installed with pip.
|
||||||
requirements: [ "proxmoxer", "requests" ]
|
requirements: [ "proxmoxer", "requests" ]
|
||||||
|
@ -536,6 +535,32 @@ EXAMPLES = '''
|
||||||
cores : 4
|
cores : 4
|
||||||
vcpus : 2
|
vcpus : 2
|
||||||
|
|
||||||
|
# Clone VM with only source VM name
|
||||||
|
- proxmox_kvm:
|
||||||
|
api_user : root@pam
|
||||||
|
api_password: secret
|
||||||
|
api_host : helldorado
|
||||||
|
clone : spynal # The VM source
|
||||||
|
name : zavala # The target VM name
|
||||||
|
node : sabrewulf
|
||||||
|
storage : VMs
|
||||||
|
format : qcow2
|
||||||
|
timeout : 500 # Note: The task can take a while. Adapt
|
||||||
|
|
||||||
|
# Clone VM with source vmid and target newid and raw format
|
||||||
|
- proxmox_kvm:
|
||||||
|
api_user : root@pam
|
||||||
|
api_password: secret
|
||||||
|
api_host : helldorado
|
||||||
|
clone : arbitrary_name
|
||||||
|
vmid : 108
|
||||||
|
newid : 152
|
||||||
|
name : zavala # The target VM name
|
||||||
|
node : sabrewulf
|
||||||
|
storage : LVM_STO
|
||||||
|
format : raw
|
||||||
|
timeout : 300 # Note: The task can take a while. Adapt
|
||||||
|
|
||||||
# Create new VM and lock it for snapashot.
|
# Create new VM and lock it for snapashot.
|
||||||
- proxmox_kvm:
|
- proxmox_kvm:
|
||||||
api_user : root@pam
|
api_user : root@pam
|
||||||
|
@ -608,6 +633,35 @@ EXAMPLES = '''
|
||||||
name : spynal
|
name : spynal
|
||||||
node : sabrewulf
|
node : sabrewulf
|
||||||
state : current
|
state : current
|
||||||
|
|
||||||
|
# Update VM configuration
|
||||||
|
- proxmox_kvm:
|
||||||
|
api_user : root@pam
|
||||||
|
api_password: secret
|
||||||
|
api_host : helldorado
|
||||||
|
name : spynal
|
||||||
|
node : sabrewulf
|
||||||
|
cpu : 8
|
||||||
|
memory : 16384
|
||||||
|
update : yes
|
||||||
|
|
||||||
|
# Delete QEMU parameters
|
||||||
|
- proxmox_kvm:
|
||||||
|
api_user : root@pam
|
||||||
|
api_password: secret
|
||||||
|
api_host : helldorado
|
||||||
|
name : spynal
|
||||||
|
node : sabrewulf
|
||||||
|
delete : 'args,template,cpulimit'
|
||||||
|
|
||||||
|
# Revert a pending change
|
||||||
|
- proxmox_kvm:
|
||||||
|
api_user : root@pam
|
||||||
|
api_password: secret
|
||||||
|
api_host : helldorado
|
||||||
|
name : spynal
|
||||||
|
node : sabrewulf
|
||||||
|
revert : 'template,cpulimit'
|
||||||
'''
|
'''
|
||||||
|
|
||||||
RETURN = '''
|
RETURN = '''
|
||||||
|
@ -660,7 +714,8 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PROXMOXER = False
|
HAS_PROXMOXER = False
|
||||||
|
|
||||||
VZ_TYPE='qemu'
|
VZ_TYPE = 'qemu'
|
||||||
|
|
||||||
|
|
||||||
def get_nextvmid(proxmox):
|
def get_nextvmid(proxmox):
|
||||||
try:
|
try:
|
||||||
|
@ -669,14 +724,18 @@ def get_nextvmid(proxmox):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="Unable to get next vmid. Failed with exception: %s")
|
module.fail_json(msg="Unable to get next vmid. Failed with exception: %s")
|
||||||
|
|
||||||
|
|
||||||
def get_vmid(proxmox, name):
|
def get_vmid(proxmox, name):
|
||||||
return [ vm['vmid'] for vm in proxmox.cluster.resources.get(type='vm') if vm['name'] == name ]
|
return [vm['vmid'] for vm in proxmox.cluster.resources.get(type='vm') if vm['name'] == name]
|
||||||
|
|
||||||
|
|
||||||
def get_vm(proxmox, vmid):
|
def get_vm(proxmox, vmid):
|
||||||
return [ vm for vm in proxmox.cluster.resources.get(type='vm') if vm['vmid'] == int(vmid) ]
|
return [vm for vm in proxmox.cluster.resources.get(type='vm') if vm['vmid'] == int(vmid)]
|
||||||
|
|
||||||
|
|
||||||
def node_check(proxmox, node):
|
def node_check(proxmox, node):
|
||||||
return [ True for nd in proxmox.nodes.get() if nd['node'] == node ]
|
return [True for nd in proxmox.nodes.get() if nd['node'] == node]
|
||||||
|
|
||||||
|
|
||||||
def get_vminfo(module, proxmox, node, vmid, **kwargs):
|
def get_vminfo(module, proxmox, node, vmid, **kwargs):
|
||||||
global results
|
global results
|
||||||
|
@ -689,7 +748,7 @@ def get_vminfo(module, proxmox, node, vmid, **kwargs):
|
||||||
module.fail_json(msg='Getting information for VM with vmid = %s failed with exception: %s' % (vmid, e))
|
module.fail_json(msg='Getting information for VM with vmid = %s failed with exception: %s' % (vmid, e))
|
||||||
|
|
||||||
# Sanitize kwargs. Remove not defined args and ensure True and False converted to int.
|
# Sanitize kwargs. Remove not defined args and ensure True and False converted to int.
|
||||||
kwargs = dict((k,v) for k, v in kwargs.items() if v is not None)
|
kwargs = dict((k, v) for k, v in kwargs.items() if v is not None)
|
||||||
|
|
||||||
# Convert all dict in kwargs to elements. For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n]
|
# Convert all dict in kwargs to elements. For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n]
|
||||||
for k in kwargs.keys():
|
for k in kwargs.keys():
|
||||||
|
@ -714,9 +773,26 @@ def get_vminfo(module, proxmox, node, vmid, **kwargs):
|
||||||
results['devices'] = devices
|
results['devices'] = devices
|
||||||
results['vmid'] = int(vmid)
|
results['vmid'] = int(vmid)
|
||||||
|
|
||||||
def create_vm(module, proxmox, vmid, node, name, memory, cpu, cores, sockets, timeout, **kwargs):
|
|
||||||
|
def settings(module, proxmox, vmid, node, name, timeout, **kwargs):
|
||||||
|
proxmox_node = proxmox.nodes(node)
|
||||||
|
|
||||||
|
# Sanitize kwargs. Remove not defined args and ensure True and False converted to int.
|
||||||
|
kwargs = dict((k, v) for k, v in kwargs.items() if v is not None)
|
||||||
|
|
||||||
|
if getattr(proxmox_node, VZ_TYPE)(vmid).config.set(**kwargs) is None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def create_vm(module, proxmox, vmid, newid, node, name, memory, cpu, cores, sockets, timeout, update, **kwargs):
|
||||||
# Available only in PVE 4
|
# Available only in PVE 4
|
||||||
only_v4 = ['force','protection','skiplock']
|
only_v4 = ['force', 'protection', 'skiplock']
|
||||||
|
|
||||||
|
# valide clone parameters
|
||||||
|
valid_clone_params = ['format', 'full', 'pool', 'snapname', 'storage', 'target']
|
||||||
|
clone_params = {}
|
||||||
# Default args for vm. Note: -args option is for experts only. It allows you to pass arbitrary arguments to kvm.
|
# Default args for vm. Note: -args option is for experts only. It allows you to pass arbitrary arguments to kvm.
|
||||||
vm_args = "-serial unix:/var/run/qemu-server/{}.serial,server,nowait".format(vmid)
|
vm_args = "-serial unix:/var/run/qemu-server/{}.serial,server,nowait".format(vmid)
|
||||||
|
|
||||||
|
@ -732,14 +808,33 @@ def create_vm(module, proxmox, vmid, node, name, memory, cpu, cores, sockets, ti
|
||||||
if p in kwargs:
|
if p in kwargs:
|
||||||
del kwargs[p]
|
del kwargs[p]
|
||||||
|
|
||||||
|
# If update, don't update disk (virtio, ide, sata, scsi) and network interface
|
||||||
|
if update:
|
||||||
|
if 'virtio' in kwargs:
|
||||||
|
del kwargs['virtio']
|
||||||
|
if 'sata' in kwargs:
|
||||||
|
del kwargs['sata']
|
||||||
|
if 'scsi' in kwargs:
|
||||||
|
del kwargs['scsi']
|
||||||
|
if 'ide' in kwargs:
|
||||||
|
del kwargs['ide']
|
||||||
|
if 'net' in kwargs:
|
||||||
|
del kwargs['net']
|
||||||
|
|
||||||
# Convert all dict in kwargs to elements. For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n]
|
# Convert all dict in kwargs to elements. For hostpci[n], ide[n], net[n], numa[n], parallel[n], sata[n], scsi[n], serial[n], virtio[n]
|
||||||
for k in kwargs.keys():
|
for k in kwargs.keys():
|
||||||
if isinstance(kwargs[k], dict):
|
if isinstance(kwargs[k], dict):
|
||||||
kwargs.update(kwargs[k])
|
kwargs.update(kwargs[k])
|
||||||
del kwargs[k]
|
del kwargs[k]
|
||||||
|
|
||||||
|
# Rename numa_enabled to numa. According the API documentation
|
||||||
|
if 'numa_enabled' in kwargs:
|
||||||
|
kwargs['numa'] = kwargs['numa_enabled']
|
||||||
|
del kwargs['numa_enabled']
|
||||||
|
|
||||||
# -args and skiplock require root@pam user
|
# -args and skiplock require root@pam user
|
||||||
if module.params['api_user'] == "root@pam" and module.params['args'] is None:
|
if module.params['api_user'] == "root@pam" and module.params['args'] is None:
|
||||||
|
if not update:
|
||||||
kwargs['args'] = vm_args
|
kwargs['args'] = vm_args
|
||||||
elif module.params['api_user'] == "root@pam" and module.params['args'] is not None:
|
elif module.params['api_user'] == "root@pam" and module.params['args'] is not None:
|
||||||
kwargs['args'] = module.params['args']
|
kwargs['args'] = module.params['args']
|
||||||
|
@ -749,11 +844,23 @@ def create_vm(module, proxmox, vmid, node, name, memory, cpu, cores, sockets, ti
|
||||||
if module.params['api_user'] != "root@pam" and module.params['skiplock'] is not None:
|
if module.params['api_user'] != "root@pam" and module.params['skiplock'] is not None:
|
||||||
module.fail_json(msg='skiplock parameter require root@pam user. ')
|
module.fail_json(msg='skiplock parameter require root@pam user. ')
|
||||||
|
|
||||||
|
if update:
|
||||||
|
if getattr(proxmox_node, VZ_TYPE)(vmid).config.set(name=name, memory=memory, cpu=cpu, cores=cores, sockets=sockets, **kwargs) is None:
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
elif module.params['clone'] is not None:
|
||||||
|
for param in valid_clone_params:
|
||||||
|
if module.params[param] is not None:
|
||||||
|
clone_params[param] = module.params[param]
|
||||||
|
clone_params.update(dict([k, int(v)] for k, v in clone_params.items() if isinstance(v, bool)))
|
||||||
|
taskid = proxmox_node.qemu(vmid).clone.post(newid=newid, name=name, **clone_params)
|
||||||
|
else:
|
||||||
taskid = getattr(proxmox_node, VZ_TYPE).create(vmid=vmid, name=name, memory=memory, cpu=cpu, cores=cores, sockets=sockets, **kwargs)
|
taskid = getattr(proxmox_node, VZ_TYPE).create(vmid=vmid, name=name, memory=memory, cpu=cpu, cores=cores, sockets=sockets, **kwargs)
|
||||||
|
|
||||||
while timeout:
|
while timeout:
|
||||||
if ( proxmox_node.tasks(taskid).status.get()['status'] == 'stopped'
|
if (proxmox_node.tasks(taskid).status.get()['status'] == 'stopped'
|
||||||
and proxmox_node.tasks(taskid).status.get()['exitstatus'] == 'OK' ):
|
and proxmox_node.tasks(taskid).status.get()['exitstatus'] == 'OK'):
|
||||||
return True
|
return True
|
||||||
timeout = timeout - 1
|
timeout = timeout - 1
|
||||||
if timeout == 0:
|
if timeout == 0:
|
||||||
|
@ -762,10 +869,11 @@ def create_vm(module, proxmox, vmid, node, name, memory, cpu, cores, sockets, ti
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def start_vm(module, proxmox, vm, vmid, timeout):
|
def start_vm(module, proxmox, vm, vmid, timeout):
|
||||||
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.start.post()
|
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.start.post()
|
||||||
while timeout:
|
while timeout:
|
||||||
if ( proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['status'] == 'stopped'
|
if (proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['status'] == 'stopped'
|
||||||
and proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['exitstatus'] == 'OK' ):
|
and proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['exitstatus'] == 'OK' ):
|
||||||
return True
|
return True
|
||||||
timeout = timeout - 1
|
timeout = timeout - 1
|
||||||
|
@ -776,23 +884,24 @@ def start_vm(module, proxmox, vm, vmid, timeout):
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def stop_vm(module, proxmox, vm, vmid, timeout, force):
|
def stop_vm(module, proxmox, vm, vmid, timeout, force):
|
||||||
if force:
|
if force:
|
||||||
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.shutdown.post(forceStop=1)
|
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.shutdown.post(forceStop=1)
|
||||||
else:
|
else:
|
||||||
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.shutdown.post()
|
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.shutdown.post()
|
||||||
while timeout:
|
while timeout:
|
||||||
if ( proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['status'] == 'stopped'
|
if (proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['status'] == 'stopped'
|
||||||
and proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['exitstatus'] == 'OK' ):
|
and proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['exitstatus'] == 'OK'):
|
||||||
return True
|
return True
|
||||||
timeout = timeout - 1
|
timeout = timeout - 1
|
||||||
if timeout == 0:
|
if timeout == 0:
|
||||||
module.fail_json(msg='Reached timeout while waiting for stopping VM. Last line in task before timeout: %s'
|
module.fail_json(msg='Reached timeout while waiting for stopping VM. Last line in task before timeout: %s'
|
||||||
% proxmox.nodes(vm[0]['node']).tasks(taskid).log.get()[:1])
|
% proxmox.nodes(vm[0]['node']).tasks(taskid).log.get()[:1])
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec = dict(
|
argument_spec = dict(
|
||||||
|
@ -807,15 +916,18 @@ def main():
|
||||||
bios = dict(choices=['seabios', 'ovmf']),
|
bios = dict(choices=['seabios', 'ovmf']),
|
||||||
boot = dict(type='str', default='cnd'),
|
boot = dict(type='str', default='cnd'),
|
||||||
bootdisk = dict(type='str'),
|
bootdisk = dict(type='str'),
|
||||||
|
clone = dict(type='str', default=None),
|
||||||
cores = dict(type='int', default=1),
|
cores = dict(type='int', default=1),
|
||||||
cpu = dict(type='str', default='kvm64'),
|
cpu = dict(type='str', default='kvm64'),
|
||||||
cpulimit = dict(type='int'),
|
cpulimit = dict(type='int'),
|
||||||
cpuunits = dict(type='int', default=1000),
|
cpuunits = dict(type='int', default=1000),
|
||||||
delete = dict(type='str'),
|
delete = dict(type='str', default=None),
|
||||||
description = dict(type='str'),
|
description = dict(type='str'),
|
||||||
digest = dict(type='str'),
|
digest = dict(type='str'),
|
||||||
force = dict(type='bool', default=None),
|
force = dict(type='bool', default=None),
|
||||||
|
format = dict(type='str', default='qcow2', choices=['cloop', 'cow', 'qcow', 'qcow2', 'qed', 'raw', 'vmdk' ]),
|
||||||
freeze = dict(type='bool'),
|
freeze = dict(type='bool'),
|
||||||
|
full = dict(type='bool', default='yes'),
|
||||||
hostpci = dict(type='dict'),
|
hostpci = dict(type='dict'),
|
||||||
hotplug = dict(type='str'),
|
hotplug = dict(type='str'),
|
||||||
hugepages = dict(choices=['any', '2', '1024']),
|
hugepages = dict(choices=['any', '2', '1024']),
|
||||||
|
@ -830,14 +942,17 @@ def main():
|
||||||
migrate_speed = dict(type='int'),
|
migrate_speed = dict(type='int'),
|
||||||
name = dict(type='str'),
|
name = dict(type='str'),
|
||||||
net = dict(type='dict'),
|
net = dict(type='dict'),
|
||||||
|
newid = dict(type='int', default=None),
|
||||||
node = dict(),
|
node = dict(),
|
||||||
numa = dict(type='dict'),
|
numa = dict(type='dict'),
|
||||||
|
numa_enabled = dict(type='bool'),
|
||||||
onboot = dict(type='bool', default='yes'),
|
onboot = dict(type='bool', default='yes'),
|
||||||
ostype = dict(default='l26', choices=['other', 'wxp', 'w2k', 'w2k3', 'w2k8', 'wvista', 'win7', 'win8', 'l24', 'l26', 'solaris']),
|
ostype = dict(default='l26', choices=['other', 'wxp', 'w2k', 'w2k3', 'w2k8', 'wvista', 'win7', 'win8', 'l24', 'l26', 'solaris']),
|
||||||
parallel = dict(type='dict'),
|
parallel = dict(type='dict'),
|
||||||
|
pool = dict(type='str'),
|
||||||
protection = dict(type='bool'),
|
protection = dict(type='bool'),
|
||||||
reboot = dict(type='bool'),
|
reboot = dict(type='bool'),
|
||||||
revert = dict(),
|
revert = dict(type='str', default=None),
|
||||||
sata = dict(type='dict'),
|
sata = dict(type='dict'),
|
||||||
scsi = dict(type='dict'),
|
scsi = dict(type='dict'),
|
||||||
scsihw = dict(choices=['lsi', 'lsi53c810', 'virtio-scsi-pci', 'virtio-scsi-single', 'megasas', 'pvscsi']),
|
scsihw = dict(choices=['lsi', 'lsi53c810', 'virtio-scsi-pci', 'virtio-scsi-single', 'megasas', 'pvscsi']),
|
||||||
|
@ -845,21 +960,28 @@ def main():
|
||||||
shares = dict(type='int'),
|
shares = dict(type='int'),
|
||||||
skiplock = dict(type='bool'),
|
skiplock = dict(type='bool'),
|
||||||
smbios = dict(type='str'),
|
smbios = dict(type='str'),
|
||||||
|
snapname = dict(type='str'),
|
||||||
sockets = dict(type='int', default=1),
|
sockets = dict(type='int', default=1),
|
||||||
startdate = dict(type='str'),
|
startdate = dict(type='str'),
|
||||||
startup = dict(),
|
startup = dict(),
|
||||||
state = dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted', 'current']),
|
state = dict(default='present', choices=['present', 'absent', 'stopped', 'started', 'restarted', 'current']),
|
||||||
|
storage = dict(type='str'),
|
||||||
tablet = dict(type='bool', default='no'),
|
tablet = dict(type='bool', default='no'),
|
||||||
|
target = dict(type='str'),
|
||||||
tdf = dict(type='bool'),
|
tdf = dict(type='bool'),
|
||||||
template = dict(type='bool', default='no'),
|
template = dict(type='bool', default='no'),
|
||||||
timeout = dict(type='int', default=30),
|
timeout = dict(type='int', default=30),
|
||||||
|
update = dict(type='bool', default='no'),
|
||||||
validate_certs = dict(type='bool', default='no'),
|
validate_certs = dict(type='bool', default='no'),
|
||||||
vcpus = dict(type='int', default=None),
|
vcpus = dict(type='int', default=None),
|
||||||
vga = dict(default='std', choices=['std', 'cirrus', 'vmware', 'qxl', 'serial0', 'serial1', 'serial2', 'serial3', 'qxl2', 'qxl3', 'qxl4']),
|
vga = dict(default='std', choices=['std', 'cirrus', 'vmware', 'qxl', 'serial0', 'serial1', 'serial2', 'serial3', 'qxl2', 'qxl3', 'qxl4']),
|
||||||
virtio = dict(type='dict', default=None),
|
virtio = dict(type='dict', default=None),
|
||||||
vmid = dict(type='int', default=None),
|
vmid = dict(type='int', default=None),
|
||||||
watchdog = dict(),
|
watchdog = dict(),
|
||||||
)
|
),
|
||||||
|
mutually_exclusive = [('delete', 'revert'), ('delete','update'), ('revert','update'), ('clone', 'update'), ('clone', 'delete'), ('clone','revert')],
|
||||||
|
required_one_of=[('name','vmid',)],
|
||||||
|
required_if=[('state', 'present', ['node'])]
|
||||||
)
|
)
|
||||||
|
|
||||||
if not HAS_PROXMOXER:
|
if not HAS_PROXMOXER:
|
||||||
|
@ -868,14 +990,20 @@ def main():
|
||||||
api_user = module.params['api_user']
|
api_user = module.params['api_user']
|
||||||
api_host = module.params['api_host']
|
api_host = module.params['api_host']
|
||||||
api_password = module.params['api_password']
|
api_password = module.params['api_password']
|
||||||
|
clone = module.params['clone']
|
||||||
cpu = module.params['cpu']
|
cpu = module.params['cpu']
|
||||||
cores = module.params['cores']
|
cores = module.params['cores']
|
||||||
|
delete = module.params['delete']
|
||||||
memory = module.params['memory']
|
memory = module.params['memory']
|
||||||
name = module.params['name']
|
name = module.params['name']
|
||||||
|
newid = module.params['newid']
|
||||||
node = module.params['node']
|
node = module.params['node']
|
||||||
sockets = module.params['sockets'],
|
revert = module.params['revert']
|
||||||
|
sockets = module.params['sockets']
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
timeout = module.params['timeout']
|
timeout = module.params['timeout']
|
||||||
|
update = bool(module.params['update'])
|
||||||
|
vmid = module.params['vmid']
|
||||||
validate_certs = module.params['validate_certs']
|
validate_certs = module.params['validate_certs']
|
||||||
|
|
||||||
# If password not set get it from PROXMOX_PASSWORD env
|
# If password not set get it from PROXMOX_PASSWORD env
|
||||||
|
@ -893,28 +1021,68 @@ def main():
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg='authorization on proxmox cluster failed with exception: %s' % e)
|
module.fail_json(msg='authorization on proxmox cluster failed with exception: %s' % e)
|
||||||
|
|
||||||
|
|
||||||
# If vmid not set get the Next VM id from ProxmoxAPI
|
# If vmid not set get the Next VM id from ProxmoxAPI
|
||||||
# If vm name is set get the VM id from ProxmoxAPI
|
# If vm name is set get the VM id from ProxmoxAPI
|
||||||
if module.params['vmid'] is not None:
|
if not vmid:
|
||||||
vmid = module.params['vmid']
|
if state == 'present' and ( not update and not clone) and (not delete and not revert):
|
||||||
elif state == 'present':
|
try:
|
||||||
vmid = get_nextvmid(proxmox)
|
vmid = get_nextvmid(proxmox)
|
||||||
elif module.params['name'] is not None:
|
except Exception as e:
|
||||||
|
module.fail_json(msg="Can't get the next vimd for VM {} automatically. Ensure your cluster state is good".format(name))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
if not clone:
|
||||||
vmid = get_vmid(proxmox, name)[0]
|
vmid = get_vmid(proxmox, name)[0]
|
||||||
|
else:
|
||||||
|
vmid = get_vmid(proxmox, clone)[0]
|
||||||
|
except Exception as e:
|
||||||
|
if not clone:
|
||||||
|
module.fail_json(msg="VM {} does not exist in cluster.".format(name))
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="VM {} does not exist in cluster.".format(clone))
|
||||||
|
|
||||||
|
if clone is not None:
|
||||||
|
if get_vmid(proxmox, name):
|
||||||
|
module.exit_json(changed=False, msg="VM with name <%s> already exists" % name)
|
||||||
|
if vmid is not None:
|
||||||
|
vm = get_vm(proxmox, vmid)
|
||||||
|
if not vm:
|
||||||
|
module.fail_json(msg='VM with vmid = %s does not exist in cluster' % vmid)
|
||||||
|
if not newid:
|
||||||
|
try:
|
||||||
|
newid = get_nextvmid(proxmox)
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg="Can't get the next vimd for VM {} automatically. Ensure your cluster state is good".format(name))
|
||||||
|
else:
|
||||||
|
vm = get_vm(proxmox, newid)
|
||||||
|
if vm:
|
||||||
|
module.exit_json(changed=False, msg="vmid %s with VM name %s already exists" % (newid, name))
|
||||||
|
|
||||||
|
if delete is not None:
|
||||||
|
try:
|
||||||
|
settings(module, proxmox, vmid, node, name, timeout, delete=delete)
|
||||||
|
module.exit_json(changed=True, msg="Settings has deleted on VM {} with vmid {}".format(name, vmid))
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg='Unable to delete settings on VM {} with vimd {}: '.format(name, vmid) + str(e))
|
||||||
|
elif revert is not None:
|
||||||
|
try:
|
||||||
|
settings(module, proxmox, vmid, node, name, timeout, revert=revert)
|
||||||
|
module.exit_json(changed=True, msg="Settings has reverted on VM {} with vmid {}".format(name, vmid))
|
||||||
|
except Exception as e:
|
||||||
|
module.fail_json(msg='Unable to revert settings on VM {} with vimd {}: Maybe is not a pending task... '.format(name, vmid) + str(e))
|
||||||
|
|
||||||
if state == 'present':
|
if state == 'present':
|
||||||
try:
|
try:
|
||||||
if get_vm(proxmox, vmid) and not module.params['force']:
|
if get_vm(proxmox, vmid) and not (update or clone):
|
||||||
module.exit_json(changed=False, msg="VM with vmid <%s> already exists" % vmid)
|
module.exit_json(changed=False, msg="VM with vmid <%s> already exists" % vmid)
|
||||||
elif get_vmid(proxmox, name) and not module.params['force']:
|
elif get_vmid(proxmox, name) and not (update or clone):
|
||||||
module.exit_json(changed=False, msg="VM with name <%s> already exists" % name)
|
module.exit_json(changed=False, msg="VM with name <%s> already exists" % name)
|
||||||
elif not (node, module.params['name']):
|
elif not (node, name):
|
||||||
module.fail_json(msg='node, name is mandatory for creating vm')
|
module.fail_json(msg='node, name is mandatory for creating/updating vm')
|
||||||
elif not node_check(proxmox, node):
|
elif not node_check(proxmox, node):
|
||||||
module.fail_json(msg="node '%s' does not exist in cluster" % node)
|
module.fail_json(msg="node '%s' does not exist in cluster" % node)
|
||||||
|
|
||||||
create_vm(module, proxmox, vmid, node, name, memory, cpu, cores, sockets, timeout,
|
create_vm(module, proxmox, vmid, newid, node, name, memory, cpu, cores, sockets, timeout, update,
|
||||||
acpi = module.params['acpi'],
|
acpi = module.params['acpi'],
|
||||||
agent = module.params['agent'],
|
agent = module.params['agent'],
|
||||||
autostart = module.params['autostart'],
|
autostart = module.params['autostart'],
|
||||||
|
@ -924,7 +1092,6 @@ def main():
|
||||||
bootdisk = module.params['bootdisk'],
|
bootdisk = module.params['bootdisk'],
|
||||||
cpulimit = module.params['cpulimit'],
|
cpulimit = module.params['cpulimit'],
|
||||||
cpuunits = module.params['cpuunits'],
|
cpuunits = module.params['cpuunits'],
|
||||||
delete = module.params['delete'],
|
|
||||||
description = module.params['description'],
|
description = module.params['description'],
|
||||||
digest = module.params['digest'],
|
digest = module.params['digest'],
|
||||||
force = module.params['force'],
|
force = module.params['force'],
|
||||||
|
@ -942,12 +1109,13 @@ def main():
|
||||||
migrate_speed = module.params['migrate_speed'],
|
migrate_speed = module.params['migrate_speed'],
|
||||||
net = module.params['net'],
|
net = module.params['net'],
|
||||||
numa = module.params['numa'],
|
numa = module.params['numa'],
|
||||||
|
numa_enabled = module.params['numa_enabled'],
|
||||||
onboot = module.params['onboot'],
|
onboot = module.params['onboot'],
|
||||||
ostype = module.params['ostype'],
|
ostype = module.params['ostype'],
|
||||||
parallel = module.params['parallel'],
|
parallel = module.params['parallel'],
|
||||||
|
pool = module.params['pool'],
|
||||||
protection = module.params['protection'],
|
protection = module.params['protection'],
|
||||||
reboot = module.params['reboot'],
|
reboot = module.params['reboot'],
|
||||||
revert = module.params['revert'],
|
|
||||||
sata = module.params['sata'],
|
sata = module.params['sata'],
|
||||||
scsi = module.params['scsi'],
|
scsi = module.params['scsi'],
|
||||||
scsihw = module.params['scsihw'],
|
scsihw = module.params['scsihw'],
|
||||||
|
@ -955,9 +1123,11 @@ def main():
|
||||||
shares = module.params['shares'],
|
shares = module.params['shares'],
|
||||||
skiplock = module.params['skiplock'],
|
skiplock = module.params['skiplock'],
|
||||||
smbios1 = module.params['smbios'],
|
smbios1 = module.params['smbios'],
|
||||||
|
snapname = module.params['snapname'],
|
||||||
startdate = module.params['startdate'],
|
startdate = module.params['startdate'],
|
||||||
startup = module.params['startup'],
|
startup = module.params['startup'],
|
||||||
tablet = module.params['tablet'],
|
tablet = module.params['tablet'],
|
||||||
|
target = module.params['target'],
|
||||||
tdf = module.params['tdf'],
|
tdf = module.params['tdf'],
|
||||||
template = module.params['template'],
|
template = module.params['template'],
|
||||||
vcpus = module.params['vcpus'],
|
vcpus = module.params['vcpus'],
|
||||||
|
@ -965,15 +1135,26 @@ def main():
|
||||||
virtio = module.params['virtio'],
|
virtio = module.params['virtio'],
|
||||||
watchdog = module.params['watchdog'])
|
watchdog = module.params['watchdog'])
|
||||||
|
|
||||||
|
if not clone:
|
||||||
get_vminfo(module, proxmox, node, vmid,
|
get_vminfo(module, proxmox, node, vmid,
|
||||||
ide = module.params['ide'],
|
ide = module.params['ide'],
|
||||||
net = module.params['net'],
|
net = module.params['net'],
|
||||||
sata = module.params['sata'],
|
sata = module.params['sata'],
|
||||||
scsi = module.params['scsi'],
|
scsi = module.params['scsi'],
|
||||||
virtio = module.params['virtio'])
|
virtio = module.params['virtio'])
|
||||||
|
if update:
|
||||||
|
module.exit_json(changed=True, msg="VM %s with vmid %s updated" % (name, vmid))
|
||||||
|
elif clone is not None:
|
||||||
|
module.exit_json(changed=True, msg="VM %s with newid %s cloned from vm with vmid %s" % (name, newid, vmid))
|
||||||
|
else:
|
||||||
module.exit_json(changed=True, msg="VM %s with vmid %s deployed" % (name, vmid), **results)
|
module.exit_json(changed=True, msg="VM %s with vmid %s deployed" % (name, vmid), **results)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="creation of %s VM %s with vmid %s failed with exception: %s" % ( VZ_TYPE, name, vmid, e ))
|
if update:
|
||||||
|
module.fail_json(msg="Unable to update vm {} with vimd {}=".format(name, vmid) + str(e))
|
||||||
|
elif clone is not None:
|
||||||
|
module.fail_json(msg="Unable to clone vm {} from vimd {}=".format(name, vmid) + str(e))
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="creation of %s VM %s with vmid %s failed with exception=%s" % (VZ_TYPE, name, vmid, e))
|
||||||
|
|
||||||
elif state == 'started':
|
elif state == 'started':
|
||||||
try:
|
try:
|
||||||
|
@ -986,7 +1167,7 @@ def main():
|
||||||
if start_vm(module, proxmox, vm, vmid, timeout):
|
if start_vm(module, proxmox, vm, vmid, timeout):
|
||||||
module.exit_json(changed=True, msg="VM %s started" % vmid)
|
module.exit_json(changed=True, msg="VM %s started" % vmid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="starting of VM %s failed with exception: %s" % ( vmid, e ))
|
module.fail_json(msg="starting of VM %s failed with exception: %s" % (vmid, e))
|
||||||
|
|
||||||
elif state == 'stopped':
|
elif state == 'stopped':
|
||||||
try:
|
try:
|
||||||
|
@ -1000,7 +1181,7 @@ def main():
|
||||||
if stop_vm(module, proxmox, vm, vmid, timeout, force = module.params['force']):
|
if stop_vm(module, proxmox, vm, vmid, timeout, force = module.params['force']):
|
||||||
module.exit_json(changed=True, msg="VM %s is shutting down" % vmid)
|
module.exit_json(changed=True, msg="VM %s is shutting down" % vmid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(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 == 'restarted':
|
elif state == 'restarted':
|
||||||
try:
|
try:
|
||||||
|
@ -1010,8 +1191,8 @@ def main():
|
||||||
if getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.current.get()['status'] == 'stopped':
|
if getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE)(vmid).status.current.get()['status'] == 'stopped':
|
||||||
module.exit_json(changed=False, msg="VM %s is not running" % vmid)
|
module.exit_json(changed=False, msg="VM %s is not running" % vmid)
|
||||||
|
|
||||||
if ( stop_vm(module, proxmox, vm, vmid, timeout, force = module.params['force']) and
|
if (stop_vm(module, proxmox, vm, vmid, timeout, force = module.params['force'])
|
||||||
start_vm(module, proxmox, vm, vmid, timeout) ):
|
and start_vm(module, proxmox, vm, vmid, timeout)):
|
||||||
module.exit_json(changed=True, msg="VM %s is restarted" % vmid)
|
module.exit_json(changed=True, msg="VM %s is restarted" % vmid)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="restarting of VM %s failed with exception: %s" % ( vmid, e ))
|
module.fail_json(msg="restarting of VM %s failed with exception: %s" % ( vmid, e ))
|
||||||
|
@ -1027,7 +1208,7 @@ def main():
|
||||||
|
|
||||||
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE).delete(vmid)
|
taskid = getattr(proxmox.nodes(vm[0]['node']), VZ_TYPE).delete(vmid)
|
||||||
while timeout:
|
while timeout:
|
||||||
if ( proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['status'] == 'stopped'
|
if (proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['status'] == 'stopped'
|
||||||
and proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['exitstatus'] == 'OK' ):
|
and proxmox.nodes(vm[0]['node']).tasks(taskid).status.get()['exitstatus'] == 'OK' ):
|
||||||
module.exit_json(changed=True, msg="VM %s removed" % vmid)
|
module.exit_json(changed=True, msg="VM %s removed" % vmid)
|
||||||
timeout = timeout - 1
|
timeout = timeout - 1
|
||||||
|
@ -1037,7 +1218,7 @@ def main():
|
||||||
|
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="deletion of VM %s failed with exception: %s" % ( vmid, e ))
|
module.fail_json(msg="deletion of VM %s failed with exception: %s" % (vmid, e))
|
||||||
|
|
||||||
elif state == 'current':
|
elif state == 'current':
|
||||||
status = {}
|
status = {}
|
||||||
|
@ -1052,6 +1233,7 @@ def main():
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
module.fail_json(msg="Unable to get vm {} with vmid = {} status: ".format(name, vmid) + str(e))
|
module.fail_json(msg="Unable to get vm {} with vmid = {} status: ".format(name, vmid) + str(e))
|
||||||
|
|
||||||
|
|
||||||
# import module snippets
|
# import module snippets
|
||||||
from ansible.module_utils.basic import *
|
from ansible.module_utils.basic import *
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
Loading…
Reference in a new issue