diff options
| author | Lucas Alvares Gomes <lucasagomes@gmail.com> | 2013-06-04 17:19:19 +0100 |
|---|---|---|
| committer | Lucas Alvares Gomes <lucasagomes@gmail.com> | 2013-06-18 16:39:09 +0100 |
| commit | 68e9b487bf6798efdb5146bcab7579c50bed0687 (patch) | |
| tree | 098515f7c356e085ba365db3e7c22ed897fb7af2 | |
| parent | ed6099d77ed1ee4a2c8c8b135d6ac18f70d48625 (diff) | |
| download | nova-68e9b487bf6798efdb5146bcab7579c50bed0687.tar.gz nova-68e9b487bf6798efdb5146bcab7579c50bed0687.tar.xz nova-68e9b487bf6798efdb5146bcab7579c50bed0687.zip | |
Setting static ip= for baremetal PXE boot.
This patch adds a new option "pxe_network_config" to baremetal PXE driver,
if set it tells the driver to append the network configuration to the
kernel cmdline. Initramfs built with network support could then benefit
from this option and avoid the injection of network configuration files
into the image.
DocImpact
Change-Id: I61dc946f42f8a86eaad0e73b033a0d8da4a74e40
| -rw-r--r-- | nova/tests/virt/baremetal/test_pxe.py | 26 | ||||
| -rwxr-xr-x | nova/tests/virt/baremetal/test_tilera.py | 7 | ||||
| -rw-r--r-- | nova/virt/baremetal/base.py | 2 | ||||
| -rwxr-xr-x | nova/virt/baremetal/driver.py | 3 | ||||
| -rw-r--r-- | nova/virt/baremetal/fake.py | 2 | ||||
| -rw-r--r-- | nova/virt/baremetal/pxe.py | 56 | ||||
| -rw-r--r-- | nova/virt/baremetal/pxe_config.template | 2 | ||||
| -rwxr-xr-x | nova/virt/baremetal/tilera.py | 28 | ||||
| -rw-r--r-- | nova/virt/baremetal/utils.py | 29 |
9 files changed, 89 insertions, 66 deletions
diff --git a/nova/tests/virt/baremetal/test_pxe.py b/nova/tests/virt/baremetal/test_pxe.py index 022f9c692..cd4e5c143 100644 --- a/nova/tests/virt/baremetal/test_pxe.py +++ b/nova/tests/virt/baremetal/test_pxe.py @@ -116,6 +116,7 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase): 'deployment_ari_path': 'eee', 'aki_path': 'fff', 'ari_path': 'ggg', + 'network_info': self.test_network_info, } config = pxe.build_pxe_config(**args) self.assertThat(config, matchers.StartsWith('default deploy')) @@ -140,6 +141,21 @@ class PXEClassMethodsTestCase(BareMetalPXETestCase): matchers.Not(matchers.Contains('kernel ddd')), )) + def test_build_pxe_network_config(self): + self.flags( + pxe_network_config=True, + group='baremetal', + ) + net = utils.get_test_network_info(1) + config = pxe.build_pxe_network_config(net) + self.assertIn('eth0:off', config) + self.assertNotIn('eth1', config) + + net = utils.get_test_network_info(2) + config = pxe.build_pxe_network_config(net) + self.assertIn('eth0:off', config) + self.assertIn('eth1:off', config) + def test_build_network_config(self): net = utils.get_test_network_info(1) config = pxe.build_network_config(net) @@ -458,7 +474,8 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase): bm_utils.random_alnum(32).AndReturn('alnum') pxe.build_pxe_config( self.node['id'], 'alnum', iqn, - 'aaaa', 'bbbb', 'cccc', 'dddd').AndReturn(pxe_config) + 'aaaa', 'bbbb', 'cccc', 'dddd', + self.test_network_info).AndReturn(pxe_config) bm_utils.write_to_file(pxe_path, pxe_config) for mac in macs: bm_utils.create_link_without_raise( @@ -466,7 +483,8 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase): self.mox.ReplayAll() - self.driver.activate_bootloader(self.context, self.node, self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) self.mox.VerifyAll() @@ -515,8 +533,8 @@ class PXEPublicMethodsTestCase(BareMetalPXETestCase): row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is None) - self.driver.activate_bootloader(self.context, self.node, - self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is not None) diff --git a/nova/tests/virt/baremetal/test_tilera.py b/nova/tests/virt/baremetal/test_tilera.py index 488cba4df..7ad5c4b6a 100755 --- a/nova/tests/virt/baremetal/test_tilera.py +++ b/nova/tests/virt/baremetal/test_tilera.py @@ -317,7 +317,8 @@ class TileraPublicMethodsTestCase(BareMetalTileraTestCase): self.mox.ReplayAll() - self.driver.activate_bootloader(self.context, self.node, self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) self.mox.VerifyAll() @@ -334,8 +335,8 @@ class TileraPublicMethodsTestCase(BareMetalTileraTestCase): row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is None) - self.driver.activate_bootloader(self.context, self.node, - self.instance) + self.driver.activate_bootloader(self.context, self.node, self.instance, + network_info=self.test_network_info) row = db.bm_node_get(self.context, 1) self.assertTrue(row['deploy_key'] is not None) diff --git a/nova/virt/baremetal/base.py b/nova/virt/baremetal/base.py index 2029400ba..876c70b23 100644 --- a/nova/virt/baremetal/base.py +++ b/nova/virt/baremetal/base.py @@ -30,7 +30,7 @@ class NodeDriver(object): def destroy_images(self, context, node, instance): raise NotImplementedError() - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, **kwargs): raise NotImplementedError() def deactivate_bootloader(self, context, node, instance): diff --git a/nova/virt/baremetal/driver.py b/nova/virt/baremetal/driver.py index 376921360..4e8543c3e 100755 --- a/nova/virt/baremetal/driver.py +++ b/nova/virt/baremetal/driver.py @@ -248,7 +248,8 @@ class BareMetalDriver(driver.ComputeDriver): injected_files=injected_files, network_info=network_info, ) - self.driver.activate_bootloader(context, node, instance) + self.driver.activate_bootloader(context, node, instance, + network_info=network_info) self.power_on(instance, node) self.driver.activate_node(context, node, instance) _update_state(context, node, instance, baremetal_states.ACTIVE) diff --git a/nova/virt/baremetal/fake.py b/nova/virt/baremetal/fake.py index b3f39fdc3..76586ab74 100644 --- a/nova/virt/baremetal/fake.py +++ b/nova/virt/baremetal/fake.py @@ -28,7 +28,7 @@ class FakeDriver(base.NodeDriver): def destroy_images(self, context, node, instance): pass - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, **kwargs): pass def deactivate_bootloader(self, context, node, instance): diff --git a/nova/virt/baremetal/pxe.py b/nova/virt/baremetal/pxe.py index 4c63f2b07..8bda1ac1d 100644 --- a/nova/virt/baremetal/pxe.py +++ b/nova/virt/baremetal/pxe.py @@ -54,6 +54,10 @@ pxe_opts = [ cfg.IntOpt('pxe_deploy_timeout', help='Timeout for PXE deployments. Default: 0 (unlimited)', default=0), + cfg.BoolOpt('pxe_network_config', + help='If set, pass the network configuration details to the ' + 'initramfs via cmdline.', + default=False), ] LOG = logging.getLogger(__name__) @@ -77,9 +81,22 @@ def _get_cheetah(): return CHEETAH +def build_pxe_network_config(network_info): + interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6) + template = None + if not CONF.use_ipv6: + template = "ip=%(address)s::%(gateway)s:%(netmask)s::%(name)s:off" + else: + template = ("ip=[%(address_v6)s]::[%(gateway_v6)s]:" + "[%(netmask_v6)s]::%(name)s:off") + + net_config = [template % iface for iface in interfaces] + return ' '.join(net_config) + + def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, deployment_aki_path, deployment_ari_path, - aki_path, ari_path): + aki_path, ari_path, network_info): """Build the PXE config file for a node This method builds the PXE boot configuration file for a node, @@ -90,6 +107,11 @@ def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, """ LOG.debug(_("Building PXE config for deployment %s.") % deployment_id) + + network_config = None + if network_info and CONF.baremetal.pxe_network_config: + network_config = build_pxe_network_config(network_info) + pxe_options = { 'deployment_id': deployment_id, 'deployment_key': deployment_key, @@ -99,6 +121,7 @@ def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, 'aki_path': aki_path, 'ari_path': ari_path, 'pxe_append_params': CONF.baremetal.pxe_append_params, + 'pxe_network_config': network_config, } cheetah = _get_cheetah() pxe_config = str(cheetah( @@ -110,33 +133,7 @@ def build_pxe_config(deployment_id, deployment_key, deployment_iscsi_iqn, def build_network_config(network_info): - # TODO(deva): fix assumption that device names begin with "eth" - # and fix assumption about ordering - try: - assert isinstance(network_info, list) - except AssertionError: - network_info = [network_info] - interfaces = [] - for id, (network, mapping) in enumerate(network_info): - address_v6 = None - gateway_v6 = None - netmask_v6 = None - if CONF.use_ipv6: - address_v6 = mapping['ip6s'][0]['ip'] - netmask_v6 = mapping['ip6s'][0]['netmask'] - gateway_v6 = mapping['gateway_v6'] - interface = { - 'name': 'eth%d' % id, - 'address': mapping['ips'][0]['ip'], - 'gateway': mapping['gateway'], - 'netmask': mapping['ips'][0]['netmask'], - 'dns': ' '.join(mapping['dns']), - 'address_v6': address_v6, - 'gateway_v6': gateway_v6, - 'netmask_v6': netmask_v6, - } - interfaces.append(interface) - + interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6) cheetah = _get_cheetah() network_config = str(cheetah( open(CONF.baremetal.net_config_template).read(), @@ -354,7 +351,7 @@ class PXE(base.NodeDriver): bm_utils.unlink_without_raise(get_image_file_path(instance)) bm_utils.rmtree_without_raise(get_image_dir_path(instance)) - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, network_info): """Configure PXE boot loader for an instance Kernel and ramdisk images are downloaded by cache_tftp_images, @@ -398,6 +395,7 @@ class PXE(base.NodeDriver): image_info['deploy_ramdisk'][1], image_info['kernel'][1], image_info['ramdisk'][1], + network_info, ) bm_utils.write_to_file(pxe_config_file_path, pxe_config) diff --git a/nova/virt/baremetal/pxe_config.template b/nova/virt/baremetal/pxe_config.template index f2fcc9b14..54dd98baf 100644 --- a/nova/virt/baremetal/pxe_config.template +++ b/nova/virt/baremetal/pxe_config.template @@ -8,4 +8,4 @@ ipappend 3 label boot kernel ${pxe_options.aki_path} -append initrd=${pxe_options.ari_path} root=${ROOT} ro ${pxe_options.pxe_append_params} +append initrd=${pxe_options.ari_path} root=${ROOT} ro ${pxe_options.pxe_append_params} ${pxe_options.pxe_network_config} diff --git a/nova/virt/baremetal/tilera.py b/nova/virt/baremetal/tilera.py index d9a065bf1..51a19910a 100755 --- a/nova/virt/baremetal/tilera.py +++ b/nova/virt/baremetal/tilera.py @@ -64,31 +64,7 @@ def _get_cheetah(): def build_network_config(network_info): - try: - assert isinstance(network_info, list) - except AssertionError: - network_info = [network_info] - interfaces = [] - for id, (network, mapping) in enumerate(network_info): - address_v6 = None - gateway_v6 = None - netmask_v6 = None - if CONF.use_ipv6: - address_v6 = mapping['ip6s'][0]['ip'] - netmask_v6 = mapping['ip6s'][0]['netmask'] - gateway_v6 = mapping['gateway_v6'] - interface = { - 'name': 'eth%d' % id, - 'address': mapping['ips'][0]['ip'], - 'gateway': mapping['gateway'], - 'netmask': mapping['ips'][0]['netmask'], - 'dns': ' '.join(mapping['dns']), - 'address_v6': address_v6, - 'gateway_v6': gateway_v6, - 'netmask_v6': netmask_v6, - } - interfaces.append(interface) - + interfaces = bm_utils.map_network_interfaces(network_info, CONF.use_ipv6) cheetah = _get_cheetah() network_config = str(cheetah( open(CONF.baremetal.net_config_template).read(), @@ -271,7 +247,7 @@ class Tilera(base.NodeDriver): bm_utils.unlink_without_raise(get_image_file_path(instance)) bm_utils.rmtree_without_raise(get_image_dir_path(instance)) - def activate_bootloader(self, context, node, instance): + def activate_bootloader(self, context, node, instance, network_info): """Configure Tilera boot loader for an instance Kernel and ramdisk images are downloaded by cache_tftp_images, diff --git a/nova/virt/baremetal/utils.py b/nova/virt/baremetal/utils.py index b18bfac85..96abcd41b 100644 --- a/nova/virt/baremetal/utils.py +++ b/nova/virt/baremetal/utils.py @@ -81,3 +81,32 @@ def random_alnum(count): import string chars = string.ascii_uppercase + string.digits return "".join(random.choice(chars) for _ in range(count)) + + +def map_network_interfaces(network_info, use_ipv6=False): + # TODO(deva): fix assumption that device names begin with "eth" + # and fix assumption about ordering + if not isinstance(network_info, list): + network_info = [network_info] + + interfaces = [] + for id, (network, mapping) in enumerate(network_info): + address_v6 = None + gateway_v6 = None + netmask_v6 = None + if use_ipv6: + address_v6 = mapping['ip6s'][0]['ip'] + netmask_v6 = mapping['ip6s'][0]['netmask'] + gateway_v6 = mapping['gateway_v6'] + interface = { + 'name': 'eth%d' % id, + 'address': mapping['ips'][0]['ip'], + 'gateway': mapping['gateway'], + 'netmask': mapping['ips'][0]['netmask'], + 'dns': ' '.join(mapping['dns']), + 'address_v6': address_v6, + 'gateway_v6': gateway_v6, + 'netmask_v6': netmask_v6, + } + interfaces.append(interface) + return interfaces |
