feat(pxe): one menu for every installable host, no per-host pxelinux configs
This commit is contained in:
10 files changed
+69
-183
No files matched your search
+23
-62
@@ -1,11 +1,9 @@
|
||||
import pytest
|
||||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
from django.core.management import call_command
|
||||
from django.urls import reverse
|
||||
|
||||
from mdb.models import Host, Interface, OperatingSystem
|
||||
from mdb.pxe import get_pxe_filename, render_pxelinux_cfg
|
||||
from mdb.models import Host, Interface
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@@ -18,85 +16,48 @@ def host(db_with_fixtures):
|
||||
return Host.objects.first()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_render_pxeconfig(host):
|
||||
interface = host.interface_set.exclude(ip4address__isnull=True).first()
|
||||
config = render_pxelinux_cfg(interface, host)
|
||||
|
||||
assert settings.MDB_PXE_INITRD in config
|
||||
assert settings.MDB_PXE_KERNEL in config
|
||||
assert settings.MDB_PXE_PRESEED_URL in config
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_render_pxeconfig_with_os_pxe_config(host):
|
||||
_os = OperatingSystem.objects.get(pk=2) # OS with all pxe vars set
|
||||
Host.objects.filter(pk=host.pk).update(operating_system=_os)
|
||||
host = Host.objects.first()
|
||||
|
||||
interface = host.interface_set.exclude(ip4address__isnull=True).first()
|
||||
config = render_pxelinux_cfg(interface, host)
|
||||
|
||||
assert _os.pxe_initrd in config
|
||||
assert _os.pxe_kernel in config
|
||||
assert _os.pxe_preseed_config_url in config
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_host_as_pxe_files(host):
|
||||
assert len(host.as_pxe_files()) == 1
|
||||
|
||||
|
||||
PXE_FILE = "01-f0-de-f1-58-be-1a" # from the fixture interface's MAC address
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def tftp_root(settings, tmp_path):
|
||||
settings.MDB_PXE_TFTP_ROOT = str(tmp_path)
|
||||
return tmp_path
|
||||
|
||||
|
||||
def test_saving_installable_host_writes_pxe_file(host, tftp_root):
|
||||
def test_saving_installable_host_boots_it_from_the_network(host):
|
||||
Interface.objects.update(pxe_filename="", dhcp_client=False)
|
||||
host.save()
|
||||
|
||||
path = tftp_root / PXE_FILE
|
||||
assert host.pxe_key in path.read_text()
|
||||
assert path.stat().st_mode & 0o777 == 0o644
|
||||
# The interface is set up to boot from the network.
|
||||
interface = host.interface_set.get()
|
||||
assert interface.pxe_filename == "pxelinux.0"
|
||||
assert interface.dhcp_client
|
||||
|
||||
|
||||
def test_saving_host_keeps_custom_pxe_filename(host, tftp_root):
|
||||
def test_saving_host_keeps_custom_pxe_filename(host):
|
||||
Interface.objects.update(pxe_filename="custom.efi")
|
||||
host.save()
|
||||
assert host.interface_set.get().pxe_filename == "custom.efi"
|
||||
|
||||
|
||||
def test_saving_non_installable_host_deletes_pxe_file(host, tftp_root):
|
||||
(tftp_root / PXE_FILE).write_text("old")
|
||||
def test_saving_non_installable_host_stops_netboot(host):
|
||||
Interface.objects.update(pxe_filename="pxelinux.0", dhcp_client=True)
|
||||
host.pxe_installable = False
|
||||
host.save()
|
||||
assert not (tftp_root / PXE_FILE).exists()
|
||||
|
||||
interface = host.interface_set.get()
|
||||
assert interface.pxe_filename == ""
|
||||
# The host keeps its address.
|
||||
assert interface.dhcp_client
|
||||
|
||||
|
||||
def test_saving_host_without_key_generates_one(host, tftp_root):
|
||||
def test_saving_non_installable_host_keeps_custom_pxe_filename(host):
|
||||
Interface.objects.update(pxe_filename="custom.efi")
|
||||
host.pxe_installable = False
|
||||
host.save()
|
||||
assert host.interface_set.get().pxe_filename == "custom.efi"
|
||||
|
||||
|
||||
def test_saving_host_without_key_generates_one(host):
|
||||
host.pxe_key = ""
|
||||
host.save()
|
||||
key = Host.objects.get(pk=host.pk).pxe_key
|
||||
assert len(key) == 32
|
||||
assert key in (tftp_root / PXE_FILE).read_text()
|
||||
assert len(Host.objects.get(pk=host.pk).pxe_key) == 32
|
||||
|
||||
|
||||
def test_pxe_filename_by_ip_address(host):
|
||||
interface = host.interface_set.get() # 10.0.3.2
|
||||
assert get_pxe_filename(interface, "ip_addr") == "0A000302"
|
||||
|
||||
|
||||
def test_admin_marks_hosts_installable(host, tftp_root, admin_client):
|
||||
def test_admin_marks_hosts_installable(host, admin_client):
|
||||
Host.objects.update(pxe_installable=False)
|
||||
Interface.objects.update(pxe_filename="")
|
||||
|
||||
res = admin_client.post(
|
||||
reverse("admin:mdb_host_changelist"),
|
||||
@@ -106,11 +67,11 @@ def test_admin_marks_hosts_installable(host, tftp_root, admin_client):
|
||||
|
||||
assert res.status_code == 200
|
||||
assert Host.objects.get(pk=host.pk).pxe_installable
|
||||
assert (tftp_root / PXE_FILE).exists()
|
||||
assert host.interface_set.get().pxe_filename == "pxelinux.0"
|
||||
assert not [m for m in res.context["messages"] if m.level == messages.WARNING]
|
||||
|
||||
|
||||
def test_admin_warns_about_interfaces_without_ip(host, tftp_root, admin_client):
|
||||
def test_admin_warns_about_interfaces_without_ip(host, admin_client):
|
||||
Host.objects.update(pxe_installable=False)
|
||||
Interface.objects.create(
|
||||
name="eth1", macaddr="00:11:22:33:44:55", host=host, domain_id=1
|
||||
|
||||
Reference in new issue
Block a user