Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting boot device order in virt.running and virt.defined #57545

Merged
merged 3 commits into from
Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog/57544.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Allow setting VM boot devices order in virt.running and virt.defined states
37 changes: 31 additions & 6 deletions salt/modules/virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,6 +650,7 @@ def _gen_xml(
arch,
graphics=None,
boot=None,
boot_dev=None,
**kwargs
):
"""
Expand Down Expand Up @@ -683,12 +684,7 @@ def _gen_xml(
graphics = None
context["graphics"] = graphics

if "boot_dev" in kwargs:
context["boot_dev"] = []
for dev in kwargs["boot_dev"].split():
context["boot_dev"].append(dev)
else:
context["boot_dev"] = ["hd"]
context["boot_dev"] = boot_dev.split() if boot_dev is not None else ["hd"]

context["boot"] = boot if boot else {}

Expand Down Expand Up @@ -1600,6 +1596,7 @@ def init(
os_type=None,
arch=None,
boot=None,
boot_dev=None,
**kwargs
):
"""
Expand Down Expand Up @@ -1684,6 +1681,12 @@ def init(
'nvram': '/usr/share/OVMF/OVMF_VARS.ms.fd'
}

:param boot_dev:
Space separated list of devices to boot from sorted by decreasing priority.
Values can be ``hd``, ``fd``, ``cdrom`` or ``network``.

By default, the value will ``"hd"``.

.. _init-boot-def:

.. rubric:: Boot parameters definition
Expand Down Expand Up @@ -2005,6 +2008,7 @@ def seeder(path):
arch,
graphics,
boot,
boot_dev,
**kwargs
)
conn.defineXML(vm_xml)
Expand Down Expand Up @@ -2221,6 +2225,7 @@ def update(
live=True,
boot=None,
test=False,
boot_dev=None,
**kwargs
):
"""
Expand Down Expand Up @@ -2277,6 +2282,14 @@ def update(

.. versionadded:: 3000

:param boot_dev:
Space separated list of devices to boot from sorted by decreasing priority.
Values can be ``hd``, ``fd``, ``cdrom`` or ``network``.

By default, the value will ``"hd"``.

.. versionadded:: Magnesium

:param test: run in dry-run mode if set to True

.. versionadded:: 3001
Expand Down Expand Up @@ -2408,6 +2421,18 @@ def update(

need_update = True

# Check the os/boot tags
if boot_dev is not None:
boot_nodes = parent_tag.findall("boot")
old_boot_devs = [node.get("dev") for node in boot_nodes]
new_boot_devs = boot_dev.split()
if old_boot_devs != new_boot_devs:
for boot_node in boot_nodes:
parent_tag.remove(boot_node)
for dev in new_boot_devs:
ElementTree.SubElement(parent_tag, "boot", attrib={"dev": dev})
need_update = True

# Update the memory, note that libvirt outputs all memory sizes in KiB
for mem_node_name in ["memory", "currentMemory"]:
mem_node = desc.find(mem_node_name)
Expand Down
23 changes: 23 additions & 0 deletions salt/states/virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,7 @@ def defined(
arch=None,
boot=None,
update=True,
boot_dev=None,
):
"""
Starts an existing guest, or defines and starts a new VM with specified arguments.
Expand Down Expand Up @@ -347,6 +348,14 @@ def defined(

.. deprecated:: 3001

:param boot_dev:
Space separated list of devices to boot from sorted by decreasing priority.
Values can be ``hd``, ``fd``, ``cdrom`` or ``network``.

By default, the value will ``"hd"``.

.. versionadded:: Magnesium

.. rubric:: Example States

Make sure a virtual machine called ``domain_name`` is defined:
Expand All @@ -357,6 +366,7 @@ def defined(
virt.defined:
- cpu: 2
- mem: 2048
- boot_dev: network hd
- disk_profile: prod
- disks:
- name: system
Expand Down Expand Up @@ -409,6 +419,7 @@ def defined(
password=password,
boot=boot,
test=__opts__["test"],
boot_dev=boot_dev,
)
ret["changes"][name] = status
if not status.get("definition"):
Expand Down Expand Up @@ -443,6 +454,7 @@ def defined(
password=password,
boot=boot,
start=False,
boot_dev=boot_dev,
)
ret["changes"][name] = {"definition": True}
ret["comment"] = "Domain {} defined".format(name)
Expand Down Expand Up @@ -475,6 +487,7 @@ def running(
os_type=None,
arch=None,
boot=None,
boot_dev=None,
):
"""
Starts an existing guest, or defines and starts a new VM with specified arguments.
Expand Down Expand Up @@ -569,6 +582,14 @@ def running(

.. versionadded:: 3000

:param boot_dev:
Space separated list of devices to boot from sorted by decreasing priority.
Values can be ``hd``, ``fd``, ``cdrom`` or ``network``.

By default, the value will ``"hd"``.

.. versionadded:: Magnesium

.. rubric:: Example States

Make sure an already-defined virtual machine called ``domain_name`` is running:
Expand All @@ -587,6 +608,7 @@ def running(
- cpu: 2
- mem: 2048
- disk_profile: prod
- boot_dev: network hd
- disks:
- name: system
size: 8192
Expand Down Expand Up @@ -635,6 +657,7 @@ def running(
arch=arch,
boot=boot,
update=update,
boot_dev=boot_dev,
connection=connection,
username=username,
password=password,
Expand Down
30 changes: 30 additions & 0 deletions tests/unit/modules/test_virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -1700,6 +1700,7 @@ def test_update(self):
<vcpu placement='auto'>1</vcpu>
<os>
<type arch='x86_64' machine='pc-i440fx-2.6'>hvm</type>
<boot dev="hd"/>
</os>
<devices>
<disk type='file' device='disk'>
Expand Down Expand Up @@ -1831,7 +1832,36 @@ def test_update(self):
"initrd": "/root/f8-i386-initrd",
}

# Update boot devices case
define_mock.reset_mock()
self.assertEqual(
{
"definition": True,
"disk": {"attached": [], "detached": [], "updated": []},
"interface": {"attached": [], "detached": []},
},
virt.update("my_vm", boot_dev="cdrom network hd"),
)
setxml = ET.fromstring(define_mock.call_args[0][0])
self.assertEqual(
["cdrom", "network", "hd"],
[node.get("dev") for node in setxml.findall("os/boot")],
)

# Update unchanged boot devices case
define_mock.reset_mock()
self.assertEqual(
{
"definition": False,
"disk": {"attached": [], "detached": [], "updated": []},
"interface": {"attached": [], "detached": []},
},
virt.update("my_vm", boot_dev="hd"),
)
define_mock.assert_not_called()

# Update with boot parameter case
define_mock.reset_mock()
self.assertEqual(
{
"definition": True,
Expand Down
15 changes: 14 additions & 1 deletion tests/unit/states/test_virt.py
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ def test_defined(self):
"myvm",
cpu=2,
mem=2048,
boot_dev="cdrom hd",
os_type="linux",
arch="i686",
vm_type="qemu",
Expand All @@ -360,6 +361,7 @@ def test_defined(self):
"myvm",
cpu=2,
mem=2048,
boot_dev="cdrom hd",
os_type="linux",
arch="i686",
disk="prod",
Expand Down Expand Up @@ -468,10 +470,13 @@ def test_defined(self):
"comment": "Domain myvm updated with live update(s) failures",
}
)
self.assertDictEqual(virt.defined("myvm", cpu=2), ret)
self.assertDictEqual(
virt.defined("myvm", cpu=2, boot_dev="cdrom hd"), ret
)
update_mock.assert_called_with(
"myvm",
cpu=2,
boot_dev="cdrom hd",
mem=None,
disk_profile=None,
disks=None,
Expand Down Expand Up @@ -595,6 +600,7 @@ def test_defined(self):
password=None,
boot=None,
test=True,
boot_dev=None,
)

# No changes case
Expand Down Expand Up @@ -629,6 +635,7 @@ def test_defined(self):
password=None,
boot=None,
test=True,
boot_dev=None,
)

def test_running(self):
Expand Down Expand Up @@ -705,6 +712,7 @@ def test_running(self):
install=True,
pub_key=None,
priv_key=None,
boot_dev=None,
connection=None,
username=None,
password=None,
Expand Down Expand Up @@ -766,6 +774,7 @@ def test_running(self):
install=False,
pub_key="/path/to/key.pub",
priv_key="/path/to/key",
boot_dev="network hd",
connection="someconnection",
username="libvirtuser",
password="supersecret",
Expand All @@ -790,6 +799,7 @@ def test_running(self):
start=False,
pub_key="/path/to/key.pub",
priv_key="/path/to/key",
boot_dev="network hd",
connection="someconnection",
username="libvirtuser",
password="supersecret",
Expand Down Expand Up @@ -934,6 +944,7 @@ def test_running(self):
password=None,
boot=None,
test=False,
boot_dev=None,
)

# Failed definition update case
Expand Down Expand Up @@ -1052,6 +1063,7 @@ def test_running(self):
password=None,
boot=None,
test=True,
boot_dev=None,
)
start_mock.assert_not_called()

Expand Down Expand Up @@ -1088,6 +1100,7 @@ def test_running(self):
password=None,
boot=None,
test=True,
boot_dev=None,
)

def test_stopped(self):
Expand Down