fix: avoid recreation of storage devices during VM update
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
1c62ad049e
commit
22e6546396
@ -439,8 +439,6 @@ options:
|
||||
update:
|
||||
description:
|
||||
- If C(yes), the VM will be updated 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...
|
||||
- Update of C(pool) is disabled. It needs an additional API endpoint not covered by this module.
|
||||
type: bool
|
||||
default: 'no'
|
||||
@ -734,10 +732,12 @@ msg:
|
||||
"""
|
||||
|
||||
import re
|
||||
import string
|
||||
import time
|
||||
import traceback
|
||||
from distutils.version import LooseVersion
|
||||
from ansible.module_utils.six.moves.urllib.parse import quote
|
||||
from collections import defaultdict
|
||||
|
||||
try:
|
||||
from proxmoxer import ProxmoxAPI
|
||||
@ -778,7 +778,6 @@ def get_vminfo(module, proxmox, node, vmid, **kwargs):
|
||||
global results # noqa
|
||||
results = {}
|
||||
mac = {}
|
||||
devices = {}
|
||||
try:
|
||||
vm = proxmox.nodes(node).qemu(vmid).config.get()
|
||||
except Exception as e:
|
||||
@ -796,25 +795,10 @@ def get_vminfo(module, proxmox, node, vmid, **kwargs):
|
||||
kwargs.update(kwargs[k])
|
||||
del kwargs[k]
|
||||
|
||||
# Split information by type
|
||||
for k, v in kwargs.items():
|
||||
if re.match(r"net[0-9]", k) is not None:
|
||||
interface = k
|
||||
k = vm[k]
|
||||
k = re.search("=(.*?),", k).group(1)
|
||||
mac[interface] = k
|
||||
if (
|
||||
re.match(r"virtio[0-9]", k) is not None or re.match(r"ide[0-9]", k) is not None
|
||||
or re.match(r"scsi[0-9]", k) is not None or re.match(r"sata[0-9]", k) is not None
|
||||
):
|
||||
device = k
|
||||
k = vm[k]
|
||||
k = re.search("(.*?),", k).group(1)
|
||||
devices[device] = k
|
||||
|
||||
results["mac"] = mac
|
||||
results["devices"] = devices
|
||||
results["devices"] = _extract_devices(vm)
|
||||
results["vmid"] = int(vmid)
|
||||
results["_raw"] = vm
|
||||
|
||||
|
||||
def settings(module, proxmox, vmid, node, name, **kwargs):
|
||||
@ -882,18 +866,17 @@ def create_vm(
|
||||
urlencoded_ssh_keys = quote(kwargs["sshkeys"], safe="")
|
||||
kwargs["sshkeys"] = str(urlencoded_ssh_keys)
|
||||
|
||||
# If update, don't update disk (virtio, ide, sata, scsi) and network interface.
|
||||
# Pool parameter not supported by qemu/<vmid>/config endpoint on "update" (PVE 6.2),
|
||||
# only with "create"
|
||||
for item in [kwargs[i] for i in ["scsi", "virtio", "ide", "sata"] if i in kwargs]:
|
||||
devices = _extract_devices(item)
|
||||
|
||||
# If update, ensure existing disks are not recreated.
|
||||
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"]
|
||||
for k, v in devices.items():
|
||||
if results["devices"].get(k):
|
||||
kwargs[k.rstrip(string.digits)][k] = "{0}:{1},{2}".format(
|
||||
results["devices"][k]["storage_id"], results["devices"][k]["storage_opts"],
|
||||
",".join(devices[k]["opts"])
|
||||
)
|
||||
|
||||
# Convert all dict in kwargs to elements.
|
||||
for k in list(kwargs.keys()):
|
||||
@ -1281,6 +1264,19 @@ def main():
|
||||
elif not node_check(proxmox, node):
|
||||
module.fail_json(msg="node '{}' does not exist in cluster".format(node))
|
||||
|
||||
if not clone:
|
||||
get_vminfo(
|
||||
module,
|
||||
proxmox,
|
||||
node,
|
||||
vmid,
|
||||
ide=module.params["ide"],
|
||||
net=module.params["net"],
|
||||
sata=module.params["sata"],
|
||||
scsi=module.params["scsi"],
|
||||
virtio=module.params["virtio"]
|
||||
)
|
||||
|
||||
create_vm(
|
||||
module,
|
||||
proxmox,
|
||||
@ -1353,18 +1349,6 @@ def main():
|
||||
watchdog=module.params["watchdog"]
|
||||
)
|
||||
|
||||
if not clone:
|
||||
get_vminfo(
|
||||
module,
|
||||
proxmox,
|
||||
node,
|
||||
vmid,
|
||||
ide=module.params["ide"],
|
||||
net=module.params["net"],
|
||||
sata=module.params["sata"],
|
||||
scsi=module.params["scsi"],
|
||||
virtio=module.params["virtio"]
|
||||
)
|
||||
if update:
|
||||
module.exit_json(
|
||||
changed=True, vmid=vmid, msg="VM {} with vmid {} updated".format(name, vmid)
|
||||
@ -1544,5 +1528,21 @@ def main():
|
||||
)
|
||||
|
||||
|
||||
def _extract_devices(item):
|
||||
devices = defaultdict(dict)
|
||||
for k, v in item.items():
|
||||
if re.match(r"(scsi|virtio|ide|sata)[0-9]", k):
|
||||
devices[k]["opts"] = []
|
||||
for val in v.split(","):
|
||||
if len(val.split(":")) == 2:
|
||||
storage = val.split(":")
|
||||
devices[k]["storage_id"] = storage[0]
|
||||
devices[k]["storage_opts"] = storage[1]
|
||||
else:
|
||||
devices[k]["opts"].append(val)
|
||||
|
||||
return devices
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
Loading…
Reference in New Issue
Block a user