Merge "PXE: Pass root device hints via kernel cmdline"

This commit is contained in:
Jenkins
2015-01-05 19:52:07 +00:00
committed by Gerrit Code Review
7 changed files with 76 additions and 6 deletions

View File

@@ -3,7 +3,7 @@ default=deploy
image={{pxe_options.deployment_aki_path}}
label=deploy
initrd={{pxe_options.deployment_ari_path}}
append="rootfstype=ramfs selinux=0 disk={{ pxe_options.disk }} iscsi_target_iqn={{ pxe_options.iscsi_target_iqn }} deployment_id={{ pxe_options.deployment_id }} deployment_key={{ pxe_options.deployment_key }} ironic_api_url={{ pxe_options.ironic_api_url }} troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} ip=%I:{{pxe_options.tftp_server}}:%G:%M:%H::on"
append="rootfstype=ramfs selinux=0 disk={{ pxe_options.disk }} iscsi_target_iqn={{ pxe_options.iscsi_target_iqn }} deployment_id={{ pxe_options.deployment_id }} deployment_key={{ pxe_options.deployment_key }} ironic_api_url={{ pxe_options.ironic_api_url }} troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} ip=%I:{{pxe_options.tftp_server}}:%G:%M:%H::on" {% if pxe_options.root_device %}root_device={{ pxe_options.root_device }}{% endif %}
image={{pxe_options.aki_path}}
label=boot

View File

@@ -5,7 +5,7 @@ dhcp
goto deploy
:deploy
kernel {{ pxe_options.deployment_aki_path }} selinux=0 disk={{ pxe_options.disk }} iscsi_target_iqn={{ pxe_options.iscsi_target_iqn }} deployment_id={{ pxe_options.deployment_id }} deployment_key={{ pxe_options.deployment_key }} ironic_api_url={{ pxe_options.ironic_api_url }} troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} ip=${ip}:${next-server}:${gateway}:${netmask} BOOTIF=${mac}
kernel {{ pxe_options.deployment_aki_path }} selinux=0 disk={{ pxe_options.disk }} iscsi_target_iqn={{ pxe_options.iscsi_target_iqn }} deployment_id={{ pxe_options.deployment_id }} deployment_key={{ pxe_options.deployment_key }} ironic_api_url={{ pxe_options.ironic_api_url }} troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} ip=${ip}:${next-server}:${gateway}:${netmask} BOOTIF=${mac} {% if pxe_options.root_device %}root_device={{ pxe_options.root_device }}{% endif %}
initrd {{ pxe_options.deployment_ari_path }}
boot

View File

@@ -17,6 +17,8 @@ import os
from oslo.config import cfg
from oslo.utils import strutils
import six
from six.moves.urllib import parse
from ironic.common import exception
from ironic.common.i18n import _
@@ -284,6 +286,36 @@ def continue_deploy(task, **kwargs):
return root_uuid
def parse_root_device_hints(node):
"""Parse the root_device property of a node.
Parse the root_device property of a node and make it a flat string
to be passed via the PXE config.
:param node: a single Node.
:returns: A flat string with the following format
opt1=value1,opt2=value2. Or None if the
Node contains no hints.
"""
root_device = node.properties.get('root_device')
if not root_device:
return
hints = []
for key, value in root_device.items():
# NOTE(lucasagomes): We can't have spaces in the PXE config
# file, so we are going to url/percent encode the value here
# and decode on the other end.
if isinstance(value, six.string_types):
value = value.strip()
value = parse.quote(value)
hints.append("%s=%s" % (key, value))
return ','.join(hints)
def build_deploy_ramdisk_options(node):
"""Build the ramdisk config options for a node
@@ -312,6 +344,11 @@ def build_deploy_ramdisk_options(node):
'ironic_api_url': ironic_api,
'disk': CONF.pxe.disk_devices,
}
root_device = parse_root_device_hints(node)
if root_device:
deploy_options['root_device'] = root_device
return deploy_options

View File

@@ -2,7 +2,7 @@ default deploy
label deploy
kernel {{ pxe_options.deployment_aki_path }}
append initrd={{ pxe_options.deployment_ari_path }} rootfstype=ramfs selinux=0 disk={{ pxe_options.disk }} iscsi_target_iqn={{ pxe_options.iscsi_target_iqn }} deployment_id={{ pxe_options.deployment_id }} deployment_key={{ pxe_options.deployment_key }} ironic_api_url={{ pxe_options.ironic_api_url }} troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }}
append initrd={{ pxe_options.deployment_ari_path }} rootfstype=ramfs selinux=0 disk={{ pxe_options.disk }} iscsi_target_iqn={{ pxe_options.iscsi_target_iqn }} deployment_id={{ pxe_options.deployment_id }} deployment_key={{ pxe_options.deployment_key }} ironic_api_url={{ pxe_options.ironic_api_url }} troubleshoot=0 text {{ pxe_options.pxe_append_params|default("", true) }} {% if pxe_options.root_device %}root_device={{ pxe_options.root_device }}{% endif %}
ipappend 3

View File

@@ -2,7 +2,7 @@ default deploy
label deploy
kernel /tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_kernel
append initrd=/tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_ramdisk rootfstype=ramfs selinux=0 disk=cciss/c0d0,sda,hda,vda iscsi_target_iqn=iqn-1be26c0b-03f2-4d2e-ae87-c02d7f33c123 deployment_id=1be26c0b-03f2-4d2e-ae87-c02d7f33c123 deployment_key=0123456789ABCDEFGHIJKLMNOPQRSTUV ironic_api_url=http://192.168.122.184:6385 troubleshoot=0 text test_param
append initrd=/tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7f33c123/deploy_ramdisk rootfstype=ramfs selinux=0 disk=cciss/c0d0,sda,hda,vda iscsi_target_iqn=iqn-1be26c0b-03f2-4d2e-ae87-c02d7f33c123 deployment_id=1be26c0b-03f2-4d2e-ae87-c02d7f33c123 deployment_key=0123456789ABCDEFGHIJKLMNOPQRSTUV ironic_api_url=http://192.168.122.184:6385 troubleshoot=0 text test_param root_device=vendor=fake,size=123
ipappend 3

View File

@@ -205,7 +205,8 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase):
mock_unlink.assert_called_once_with('/path/uuid/disk')
mock_rmtree.assert_called_once_with('/path/uuid')
def _test_build_deploy_ramdisk_options(self, mock_alnum, api_url):
def _test_build_deploy_ramdisk_options(self, mock_alnum, api_url,
expected_root_device=None):
fake_key = '0123456789ABCDEFGHIJKLMNOPQRSTUV'
fake_disk = 'fake-disk'
@@ -219,6 +220,9 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase):
'disk': fake_disk,
'ironic_api_url': api_url}
if expected_root_device:
expected_opts['root_device'] = expected_root_device
opts = iscsi_deploy.build_deploy_ramdisk_options(self.node)
self.assertEqual(expected_opts, opts)
@@ -248,3 +252,31 @@ class IscsiDeployMethodsTestCase(db_base.DbTestCase):
# As the Ironic api url is not specified in the config file
# assert we are getting it from keystone
mock_get_url.assert_called_once_with()
@mock.patch.object(keystone, 'get_service_url')
@mock.patch.object(utils, 'random_alnum')
def test_build_deploy_ramdisk_options_root_device(self, mock_alnum,
mock_get_url):
self.node.properties['root_device'] = {'wwn': 123456}
expected = 'wwn=123456'
fake_api_url = 'http://127.0.0.1:6385'
self.config(api_url=fake_api_url, group='conductor')
self._test_build_deploy_ramdisk_options(mock_alnum, fake_api_url,
expected_root_device=expected)
def test_parse_root_device_hints(self):
self.node.properties['root_device'] = {'wwn': 123456}
expected = 'wwn=123456'
result = iscsi_deploy.parse_root_device_hints(self.node)
self.assertEqual(expected, result)
def test_parse_root_device_hints_string_space(self):
self.node.properties['root_device'] = {'model': 'fake model'}
expected = 'model=fake%20model'
result = iscsi_deploy.parse_root_device_hints(self.node)
self.assertEqual(expected, result)
def test_parse_root_device_hints_no_hints(self):
self.node.properties = {}
result = iscsi_deploy.parse_root_device_hints(self.node)
self.assertIsNone(result)

View File

@@ -48,7 +48,8 @@ class TestPXEUtils(db_base.DbTestCase):
'ironic_api_url': 'http://192.168.122.184:6385',
'deployment_aki_path': u'/tftpboot/1be26c0b-03f2-4d2e-ae87-'
u'c02d7f33c123/deploy_kernel',
'disk': 'cciss/c0d0,sda,hda,vda'
'disk': 'cciss/c0d0,sda,hda,vda',
'root_device': 'vendor=fake,size=123'
}
self.agent_pxe_options = {
'deployment_ari_path': u'/tftpboot/1be26c0b-03f2-4d2e-ae87-c02d7'