feat(pxe): Add support for PXE config per host/os

This commit is contained in:
nikolark committed 2016-03-25 15:00:25 +01:00
1 parent 3659215a2f
commit 257b00be1b
7 files changed
+89 -7

No files matched your search

+1 -1
View File
@@ -192,7 +192,7 @@ class HostTypeAdmin(admin.ModelAdmin):
class OperatingSystemAdmin(admin.ModelAdmin):
list_display = ['name', 'version', 'arch']
list_display = ['name', 'version', 'arch', 'pxe_kernel', 'pxe_initrd', 'pxe_preseed_config_url']
admin.site.register(Domain, DomainAdmin)
+12
View File
@@ -2738,6 +2738,18 @@
"model": "mdb.operatingsystem",
"pk": 1
},
{
"fields": {
"pxe_initrd": "path-to-initrd-for-os",
"pxe_kernel": "path-to-kernel-for-os",
"pxe_preseed_config_url": "http://url-to-preseed.config",
"arch": "x86_64",
"name": "Ubuntu",
"version": "16.04-beta-final"
},
"model": "mdb.operatingsystem",
"pk": 2
},
{
"fields": {
"kerberos_principal_name": "",
+29
View File
@@ -0,0 +1,29 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mdb', '0010_auto_20151004_1709'),
]
operations = [
migrations.AddField(
model_name='operatingsystem',
name='pxe_initrd',
field=models.CharField(null=True, blank=True, max_length=255),
),
migrations.AddField(
model_name='operatingsystem',
name='pxe_kernel',
field=models.CharField(null=True, blank=True, max_length=255),
),
migrations.AddField(
model_name='operatingsystem',
name='pxe_preseed_config_url',
field=models.URLField(null=True, blank=True),
),
]
+4
View File
@@ -477,6 +477,10 @@ class OperatingSystem(models.Model):
version = models.CharField(max_length=64)
arch = models.CharField(max_length=255, choices=OS_ARCHITECTURES, blank=True, null=True)
pxe_kernel = models.CharField(max_length=255, blank=True, null=True)
pxe_initrd = models.CharField(max_length=255, blank=True, null=True)
pxe_preseed_config_url = models.URLField(blank=True, null=True)
def __str__(self):
return self.name + " " + self.version + " (" + self.arch + ")"
+16 -5
View File
@@ -4,11 +4,21 @@ import ipaddress
def render_pxelinux_cfg(_if, host):
# TODO add fields to os model and make dynamic per host
distro = 'ubuntu/14_04/amd64/alternate/'
kernel = distro + 'linux'
initrd = distro + 'initrd.gz'
"""Renders pxelinux.cfg based on a host and the set of host interfaces.
If the host is tied to an OS with PXE fields set, it will use these instead of defaults."""
# Default config
kernel = settings.MDB_PXE_KERNEL
initrd = settings.MDB_PXE_INITRD
preseed_config_url = settings.MDB_PXE_PRESEED_URL
# Per host config (via OS model)
_os = host.operating_system
pxe_attrs = [_os.pxe_initrd, _os.pxe_kernel, _os.pxe_preseed_config_url]
if None not in pxe_attrs and '' not in pxe_attrs:
kernel = _os.pxe_kernel
initrd = _os.pxe_initrd
preseed_config_url = _os.pxe_preseed_config_url
context = {
'kernel': kernel,
'initrd': initrd,
@@ -16,6 +26,7 @@ def render_pxelinux_cfg(_if, host):
'host': host,
'interface': _if
}
return render_to_string('pxelinux.cfg', context=context)
@@ -34,7 +45,7 @@ def get_pxe_filename(interface, filename_format='mac_addr'):
def host_as_pxe_files(host):
""" Returns a list of filename,content for each host interface with an IPv4 address """
"""Returns a list of filename,content for each host interface with an IPv4 address."""
from mdb.models import Host
assert isinstance(host, Host)
+25 -1
View File
@@ -1,12 +1,15 @@
import io
from django.conf import settings
from django.contrib.auth.models import User
from django.core.management import call_command
from django.core.urlresolvers import reverse
from django.test import TestCase
from mdb.pxe import render_pxelinux_cfg
from rest_framework.authtoken.models import Token
from rest_framework.test import APITestCase
from mdb.models import Host
from mdb.models import Host, OperatingSystem
class MyAPITestCases(APITestCase):
@@ -35,6 +38,27 @@ class MyAPITestCases(APITestCase):
class UnitTests(TestCase):
fixtures = ['test_data']
def test_render_pxeconfig(self):
host = Host.objects.first()
interface = host.interface_set.exclude(ip4address__isnull=True).first()
config = render_pxelinux_cfg(interface, host)
self.assertIn(settings.MDB_PXE_INITRD, config)
self.assertIn(settings.MDB_PXE_KERNEL, config)
self.assertIn(settings.MDB_PXE_PRESEED_URL, config)
def test_render_pxeconfig_with_os_pxe_config(self):
_os = OperatingSystem.objects.get(pk=2) # OS with all pxe vars set
Host.objects.filter(pk=Host.objects.first().pk).update(operating_system=_os)
host = Host.objects.first()
interface = host.interface_set.exclude(ip4address__isnull=True).first()
config = render_pxelinux_cfg(interface, host)
self.assertIn(_os.pxe_initrd, config)
self.assertIn(_os.pxe_kernel, config)
self.assertIn(_os.pxe_preseed_config_url, config)
def test_host_as_pxe_files(self):
host = Host.objects.first()
self.assertEqual(len(host.as_pxe_files()), 1)
+2
View File
@@ -124,6 +124,8 @@ REST_FRAMEWORK = {
}
MDB_PXE_TFTP_ROOT = '/var/lib/tftpboot/pxelinux/pxelinux.cfg/'
MDB_PXE_KERNEL = 'ubuntu/14_04/amd64/alternate/linux'
MDB_PXE_INITRD = 'ubuntu/14_04/amd64/alternate/initrd.gz'
MDB_PXE_PRESEED_URL = 'http://158.36.190.194/ubuntu/preseed_1404.cfg'
try: