Skip to content

Commit 202b7db

Browse files
rfsmiRyan Smith
andauthored
Fix idempotency of mount strings (#193)
* Join mount strings correctly. Previously this function would prepend an extra comma to the front of the result in some cases. Now the function does a single join so avoids having to handle these edge cases. * Actually test the test --------- Co-authored-by: Ryan Smith <[email protected]>
1 parent d2f0ec5 commit 202b7db

File tree

2 files changed

+48
-17
lines changed

2 files changed

+48
-17
lines changed

plugins/modules/proxmox.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,9 +1559,10 @@ def build_volume(self, vmid, node, key, storage=None, volume=None, host_path=Non
15591559
volume=volume,
15601560
),
15611561
)
1562-
vol_string = "{storage}:{volume},size={size}".format(
1563-
storage=storage, volume=volume, size=size
1564-
)
1562+
vol_parts = [
1563+
"{storage}:{volume}".format(storage=storage, volume=volume),
1564+
"size={size}".format(size=size),
1565+
]
15651566
# 2. If volume not defined (but storage is), check if it exists
15661567
elif storage is not None:
15671568
proxmox_node = self.proxmox_api.nodes(
@@ -1570,9 +1571,10 @@ def build_volume(self, vmid, node, key, storage=None, volume=None, host_path=Non
15701571
try:
15711572
vol = proxmox_node.lxc(vmid).get("config").get(key)
15721573
volume = self.parse_disk_string(vol).get("volume")
1573-
vol_string = "{storage}:{volume},size={size}".format(
1574-
storage=storage, volume=volume, size=size
1575-
)
1574+
vol_parts = [
1575+
"{storage}:{volume}".format(storage=storage, volume=volume),
1576+
"size={size}".format(size=size),
1577+
]
15761578

15771579
# If not, we have proxmox create one using the special syntax
15781580
except Exception:
@@ -1582,36 +1584,32 @@ def build_volume(self, vmid, node, key, storage=None, volume=None, host_path=Non
15821584
)
15831585
elif size.endswith("G"):
15841586
size = size.rstrip("G")
1585-
vol_string = "{storage}:{size}".format(storage=storage, size=size)
1587+
vol_parts = ["{storage}:{size}".format(storage=storage, size=size)]
15861588
else:
15871589
raise ValueError(
15881590
"Size must be provided in GiB for storage-backed volume creation. Convert it to GiB or allocate a new storage manually."
15891591
)
15901592
# 3. If we have a host_path, we don't have storage, a volume, or a size
15911593
# Then we don't have to do anything, just build and return the vol_string
15921594
elif host_path is not None:
1593-
vol_string = ""
1595+
vol_parts = []
15941596
else:
15951597
raise ValueError(
15961598
"Could not build a valid volume string. One of volume, storage, or host_path must be provided."
15971599
)
15981600

15991601
if host_path is not None:
1600-
vol_string += "," + host_path
1602+
vol_parts += [host_path]
16011603

16021604
if mountpoint is not None:
1603-
vol_string += ",mp={}".format(mountpoint)
1605+
vol_parts += ["mp={}".format(mountpoint)]
16041606

16051607
if options is not None:
1606-
vol_string += "," + ",".join(
1607-
["{0}={1}".format(k, v) for k, v in options.items()]
1608-
)
1608+
vol_parts += ["{0}={1}".format(k, v) for k, v in options.items()]
16091609

16101610
if kwargs:
1611-
vol_string += "," + ",".join(
1612-
["{0}={1}".format(k, v) for k, v in kwargs.items()]
1613-
)
1614-
return {key: vol_string}
1611+
vol_parts += ["{0}={1}".format(k, v) for k, v in kwargs.items()]
1612+
return {key: ",".join(vol_parts)}
16151613

16161614
def get_lxc_resource(self, vmid, hostname):
16171615
if not vmid and not hostname:
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright (c) 2025, Ryan Smith <[email protected]>
4+
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
5+
# SPDX-License-Identifier: GPL-3.0-or-later
6+
7+
from unittest.mock import MagicMock, patch
8+
from ansible.module_utils.basic import AnsibleModule
9+
from ansible_collections.community.proxmox.plugins.modules import proxmox
10+
from ansible_collections.community.proxmox.plugins.module_utils.proxmox import ProxmoxAnsible
11+
from ansible.module_utils.compat.version import LooseVersion
12+
13+
14+
@patch.object(ProxmoxAnsible, "__init__", return_value=None)
15+
@patch.object(ProxmoxAnsible, "version", return_value=LooseVersion("4.0"))
16+
@patch.object(ProxmoxAnsible, "proxmox_api", create=True)
17+
@patch.object(ProxmoxAnsible, "module", create=True)
18+
def test_mount_formatting(mock_api, *_):
19+
"""Test the process_mount_keys method correctly formats mounts."""
20+
lxc_ansible = proxmox.ProxmoxLxcAnsible(MagicMock(spec=AnsibleModule))
21+
mount_volumes = [{
22+
'host_path': '/mnt/dir',
23+
'mountpoint': 'mnt/dir',
24+
'id': 'mp0',
25+
'storage': None,
26+
'volume': None,
27+
'size': None,
28+
'options': None,
29+
}]
30+
mounts = lxc_ansible.process_mount_keys(
31+
100, "my-node", None, mount_volumes
32+
)
33+
assert mounts == {'mp0': '/mnt/dir,mp=mnt/dir'}

0 commit comments

Comments
 (0)