summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLucas Alvares Gomes <lucasagomes@gmail.com>2013-06-04 17:19:19 +0100
committerLucas Alvares Gomes <lucasagomes@gmail.com>2013-06-18 16:39:09 +0100
commit68e9b487bf6798efdb5146bcab7579c50bed0687 (patch)
tree098515f7c356e085ba365db3e7c22ed897fb7af2
parented6099d77ed1ee4a2c8c8b135d6ac18f70d48625 (diff)
downloadnova-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.py26
-rwxr-xr-xnova/tests/virt/baremetal/test_tilera.py7
-rw-r--r--nova/virt/baremetal/base.py2
-rwxr-xr-xnova/virt/baremetal/driver.py3
-rw-r--r--nova/virt/baremetal/fake.py2
-rw-r--r--nova/virt/baremetal/pxe.py56
-rw-r--r--nova/virt/baremetal/pxe_config.template2
-rwxr-xr-xnova/virt/baremetal/tilera.py28
-rw-r--r--nova/virt/baremetal/utils.py29
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