# HG changeset patch # User Tero Marttila # Date 1425311904 -7200 # Node ID c258e3ff6d32d8c9d7d377e0bb9120fab6fef96d # Parent dfc5fcb6a06c00b6d05b61fb867a6dd889544511 pvl.hosts: update boot= to support split boot.next-server= boot.filename=, which enables inheriting defaults diff -r dfc5fcb6a06c -r c258e3ff6d32 pvl/hosts/dhcp.py --- a/pvl/hosts/dhcp.py Mon Mar 02 13:30:15 2015 +0200 +++ b/pvl/hosts/dhcp.py Mon Mar 02 17:58:24 2015 +0200 @@ -15,24 +15,9 @@ if host.ip: yield 'fixed-address', str(host.ip) - if not host.boot: - next_server = filename = None - elif host.boot.startswith('/'): - next_server = None - filename = host.boot[1:] - elif host.boot.endswith(':'): - next_server = host.boot[:-1] - filename = None - elif ':' in host.boot : - next_server, filename = host.boot.split(':', 1) - else : - raise HostError(host, "invalid boot={host.boot}".format(host=host)) - - if next_server: - yield 'next-server', next_server - - if filename: - yield 'filename', filename + for bootopt in ('next-server', 'filename'): + if bootopt in host.boot: + yield bootopt, host.boot[bootopt] def dhcp_host (host): """ diff -r dfc5fcb6a06c -r c258e3ff6d32 pvl/hosts/host.py --- a/pvl/hosts/host.py Mon Mar 02 13:30:15 2015 +0200 +++ b/pvl/hosts/host.py Mon Mar 02 17:58:24 2015 +0200 @@ -69,6 +69,50 @@ return ':'.join('%02x' % int(x, 16) for x in value.split(':')) +def parse_dhcp_boot(boot): + """ + Parse the dhcp boot=... option + + >>> print parse_dhcp_boot(None) + {} + >>> print parse_dhcp_boot({'filename': '/foo'}) + {'filename': '/foo'} + >>> print parse_dhcp_boot({'filename': '/foo', 'next-server': 'bar'}) + {'next-server': 'bar', 'filename': '/foo'} + >>> print parse_dhcp_boot('/foo') + {'filename': '/foo'} + >>> print parse_dhcp_boot('bar:/foo') + {'next-server': 'bar', 'filename': '/foo'} + >>> print parse_dhcp_boot('bar:') + {'next-server': 'bar'} + >>> print parse_dhcp_boot('foo') + Traceback (most recent call last): + ... + ValueError: invalid boot=foo + """ + + if not boot: + return { } + + elif isinstance(boot, dict): + if set(boot) <= set(('filename', 'next-server')): + return boot + else: + raise ValueError("invalid boot={boot}".format(boot=boot)) + + elif boot.startswith('/'): + return {'filename': boot} + + elif boot.endswith(':'): + return {'next-server': boot[:-1]} + + elif ':' in boot : + next_server, filename = boot.split(':', 1) + return {'next-server': next_server, 'filename': filename} + + else : + raise ValueError("invalid boot={boot}".format(boot=boot)) + def parse_str(value): """ Normalize optional string value. @@ -133,7 +177,7 @@ forward = parse_str(forward), reverse = parse_str(reverse), down = parse_bool(down), - boot = boot, + boot = parse_dhcp_boot(boot), extensions = extensions, ) diff -r dfc5fcb6a06c -r c258e3ff6d32 pvl/hosts/tests.py --- a/pvl/hosts/tests.py Mon Mar 02 13:30:15 2015 +0200 +++ b/pvl/hosts/tests.py Mon Mar 02 17:58:24 2015 +0200 @@ -137,6 +137,26 @@ ('bar@quux.test', dict(ip=ipaddr.IPAddress('127.0.0.2'))), ]) + def testHostsConfigDdefaults(self): + hosts = config.apply_hosts_config(self.options, ConfFile('test', """ +boot.next-server = boot.lan + +[foo] + ip = 192.0.2.1 + ethernet.eth0 = 00:11:22:33:44:55 + boot.filename = /pxelinux.0 + """)) + + self.assertHostsEqual(hosts, [ + ('foo@test', dict( + ip = ipaddr.IPAddress('192.0.2.1'), + ethernet = { 'eth0': '00:11:22:33:44:55' }, + boot = { 'next-server': 'boot.lan', 'filename': '/pxelinux.0' }, + )), + ]) + + + def testApplyIncludes(self): self.assertHostsEqual(config.apply_hosts_files(self.options, ['etc/hosts/test']), [ ('bar@test', dict( @@ -664,6 +684,10 @@ ethernet = '00:11:22:33:44:55', boot = '/debian/wheezy/pxelinux.0', ), + Host.build('foo4', 'test', + ethernet = '00:11:22:33:44:55', + boot = {'next-server': 'boot.lan', 'filename': '/debian/wheezy/pxelinux.0' }, + ), ] self.assertBlocksEqual(list(dhcp.dhcp_hosts(hosts)), [ @@ -681,10 +705,16 @@ (('host', 'foo3'), [ ('option', 'host-name', "foo3"), ('hardware', 'ethernet', '00:11:22:33:44:55'), - ('filename', 'debian/wheezy/pxelinux.0'), + ('filename', '/debian/wheezy/pxelinux.0'), + ], []), + (('host', 'foo4'), [ + ('option', 'host-name', "foo4"), + ('hardware', 'ethernet', '00:11:22:33:44:55'), + ('next-server', 'boot.lan'), + ('filename', '/debian/wheezy/pxelinux.0'), ], []), ]) - + def testHosts(self): hosts = [ Host.build('foo', 'test', diff -r dfc5fcb6a06c -r c258e3ff6d32 test.sh --- a/test.sh Mon Mar 02 13:30:15 2015 +0200 +++ b/test.sh Mon Mar 02 17:58:24 2015 +0200 @@ -5,6 +5,7 @@ pvl/dns/labels.py pvl/dns/reverse.py pvl/dns/generate.py + pvl/hosts/host.py ) UNITTEST=(