nova-less-deploy: stop using glance for ironic-python-agent images

Ironic can use HTTP links or local files, and we already put the images to
a location accessible inside of ironic containers (for introspection).
This change switches to using file images for IPA. The existing Glance
images are not deleted since some nodes may be using them. Multi-arch
layout of [[PLATFORM-]ARCH/]agent.EXT is reused from the unit tests
of the `image upload` command, assuming that's what people are using.

Change-Id: Ie6fa04112e3348f429dc42b28442f8996ab03f29
Implements: blueprint nova-less-deploy
Depends-On: https://review.opendev.org/#/c/663897/
This commit is contained in:
Dmitry Tantsur 2019-06-07 12:53:07 +02:00
parent aa62e89e88
commit 7ad1b812fc
6 changed files with 155 additions and 242 deletions

View File

@ -1341,36 +1341,36 @@ class TestDeployNameScenarios(TestWithScenarios):
scenarios = [
('kernel_default',
dict(func=utils.deploy_kernel,
expected=('bm-deploy-kernel', '.kernel'))),
expected='agent.kernel')),
('kernel_arch',
dict(func=utils.deploy_kernel,
arch='x86_64',
expected=('x86_64-bm-deploy-kernel', '.kernel'))),
expected='x86_64/agent.kernel')),
('kernel_arch_platform',
dict(func=utils.deploy_kernel,
arch='x86_64',
platform='SNB',
expected=('SNB-x86_64-bm-deploy-kernel', '.kernel'))),
expected='SNB-x86_64/agent.kernel')),
('kernel_platform',
dict(func=utils.deploy_kernel,
platform='SNB',
expected=('bm-deploy-kernel', '.kernel'))),
expected='agent.kernel')),
('ramdisk_default',
dict(func=utils.deploy_ramdisk,
expected=('bm-deploy-ramdisk', '.initramfs'))),
expected='agent.ramdisk')),
('ramdisk_arch',
dict(func=utils.deploy_ramdisk,
arch='x86_64',
expected=('x86_64-bm-deploy-ramdisk', '.initramfs'))),
expected='x86_64/agent.ramdisk')),
('ramdisk_arch_platform',
dict(func=utils.deploy_ramdisk,
arch='x86_64',
platform='SNB',
expected=('SNB-x86_64-bm-deploy-ramdisk', '.initramfs'))),
expected='SNB-x86_64/agent.ramdisk')),
('ramdisk_platform',
dict(func=utils.deploy_ramdisk,
platform='SNB',
expected=('bm-deploy-ramdisk', '.initramfs'))),
expected='agent.ramdisk')),
]
def test_deploy_params(self):

View File

@ -234,7 +234,7 @@ class TestUploadOvercloudImage(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
5,
3,
self.app.client_manager.image.images.create.call_count
)
self.app.client_manager.image.images.create.assert_has_calls([
@ -250,14 +250,6 @@ class TestUploadOvercloudImage(TestPluginV1):
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public')
])
self.assertEqual(mock_subprocess_call.call_count, 2)
@ -285,7 +277,7 @@ class TestUploadOvercloudImage(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
5,
3,
self.app.client_manager.image.images.create.call_count
)
self.app.client_manager.image.images.create.assert_has_calls([
@ -306,16 +298,6 @@ class TestUploadOvercloudImage(TestPluginV1):
container_format='bare',
disk_format='qcow2',
is_public=True),
mock.call(properties={'hw_architecture': self._arch},
data=b'IMGDATA',
name='bm-deploy-kernel',
disk_format='aki',
is_public=True),
mock.call(properties={'hw_architecture': self._arch},
data=b'IMGDATA',
name='bm-deploy-ramdisk',
disk_format='ari',
is_public=True)
])
@mock.patch('os.path.isfile', autospec=True)
@ -335,7 +317,7 @@ class TestUploadOvercloudImage(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
5,
3,
self.app.client_manager.image.images.create.call_count
)
self.app.client_manager.image.images.create.assert_has_calls([
@ -356,16 +338,6 @@ class TestUploadOvercloudImage(TestPluginV1):
container_format='bare',
disk_format='qcow2',
is_public=True),
mock.call(properties={'hw_architecture': 'x86_64'},
data=b'IMGDATA',
name='x86_64-bm-deploy-kernel',
disk_format='aki',
is_public=True),
mock.call(properties={'hw_architecture': 'x86_64'},
data=b'IMGDATA',
name='x86_64-bm-deploy-ramdisk',
disk_format='ari',
is_public=True)
])
self.assertEqual(mock_subprocess_call.call_count, 2)
@ -395,11 +367,12 @@ class TestUploadOvercloudImage(TestPluginV1):
mock.ANY),
mock.call('overcloud-full', '/foo/overcloud-full.qcow2',
mock.ANY),
mock.call('bm-deploy-kernel', '/foo/ironic-python-agent.kernel',
mock.ANY),
mock.call('bm-deploy-ramdisk',
'/foo/ironic-python-agent.initramfs',
mock.ANY),
])
mock_subprocess_call.assert_has_calls([
mock.call('sudo cp -f "/foo/ironic-python-agent.kernel" '
'"/var/lib/ironic/httpboot/agent.kernel"', shell=True),
mock.call('sudo cp -f "/foo/ironic-python-agent.initramfs" '
'"/var/lib/ironic/httpboot/agent.ramdisk"', shell=True)
])
@mock.patch('os.path.isfile', autospec=True)
@ -455,11 +428,11 @@ class TestUploadOvercloudImage(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
5,
3,
self.app.client_manager.image.images.create.call_count
)
self.assertEqual(
10, # 5 for new uploads, 5 updating the existsing
6, # 3 for new uploads, 3 updating the existsing
self.app.client_manager.image.images.update.call_count
)
self.assertEqual(mock_subprocess_call.call_count, 2)
@ -498,7 +471,7 @@ class TestUploadOvercloudImageFull(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
3,
1,
self.app.client_manager.image.images.create.call_count
)
@ -507,20 +480,10 @@ class TestUploadOvercloudImageFull(TestPluginV1):
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public')
])
# properties are set by updating the image
self.app.client_manager.image.images.update.assert_has_calls([
mock.call(mock.ANY, hw_architecture=self._arch),
mock.call(mock.ANY, hw_architecture=self._arch),
mock.call(mock.ANY, hw_architecture=self._arch),
])
self.assertEqual(mock_subprocess_call.call_count, 2)
@ -549,7 +512,7 @@ class TestUploadOvercloudImageFull(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
3,
1,
self.app.client_manager.image.images.create.call_count
)
@ -558,20 +521,10 @@ class TestUploadOvercloudImageFull(TestPluginV1):
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='x86_64-bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='x86_64-bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public')
])
self.app.client_manager.image.images.update.assert_has_calls([
mock.call(mock.ANY, hw_architecture='x86_64'),
mock.call(mock.ANY, hw_architecture='x86_64'),
mock.call(mock.ANY, hw_architecture='x86_64'),
])
self.assertEqual(mock_subprocess_call.call_count, 2)
mock_subprocess_call.assert_has_calls([
@ -632,11 +585,11 @@ class TestUploadOvercloudImageFull(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
3,
1,
self.app.client_manager.image.images.create.call_count
)
self.assertEqual(
6, # update 3 images *and* add properties to 3 images
2, # update 1 image *and* add properties to 1 image
self.app.client_manager.image.images.update.call_count
)
self.assertEqual(mock_subprocess_call.call_count, 2)
@ -698,7 +651,7 @@ class TestUploadOvercloudImageFullMultiArch(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
6,
2,
self.app.client_manager.image.images.create.call_count
)
@ -707,32 +660,15 @@ class TestUploadOvercloudImageFullMultiArch(TestPluginV1):
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public'),
mock.call(name='ppc64le-overcloud-full',
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='ppc64le-bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='ppc64le-bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public')
])
self.app.client_manager.image.images.update.assert_has_calls([
mock.call(13, hw_architecture='ppc64le'),
mock.call(14, hw_architecture='ppc64le'),
mock.call(15, hw_architecture='ppc64le'),
mock.call(10, hw_architecture='x86_64'),
mock.call(11, hw_architecture='ppc64le'),
])
self.assertEqual(mock_subprocess_call.call_count, 4)
mock_subprocess_call.assert_has_calls([
@ -779,7 +715,7 @@ class TestUploadOvercloudImageFullMultiArch(TestPluginV1):
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
9,
3,
self.app.client_manager.image.images.create.call_count
)
@ -788,47 +724,20 @@ class TestUploadOvercloudImageFullMultiArch(TestPluginV1):
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public'),
mock.call(name='ppc64le-overcloud-full',
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='ppc64le-bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='ppc64le-bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public'),
mock.call(name='p9-ppc64le-overcloud-full',
disk_format='qcow2',
container_format='bare',
visibility='public'),
mock.call(name='p9-ppc64le-bm-deploy-kernel',
disk_format='aki',
container_format='bare',
visibility='public'),
mock.call(name='p9-ppc64le-bm-deploy-ramdisk',
disk_format='ari',
container_format='bare',
visibility='public')
])
self.app.client_manager.image.images.update.assert_has_calls([
mock.call(13, hw_architecture='ppc64le'),
mock.call(14, hw_architecture='ppc64le'),
mock.call(15, hw_architecture='ppc64le'),
mock.call(16, hw_architecture='ppc64le', tripleo_platform='p9'),
mock.call(17, hw_architecture='ppc64le', tripleo_platform='p9'),
mock.call(18, hw_architecture='ppc64le', tripleo_platform='p9'),
mock.call(10, hw_architecture='x86_64'),
mock.call(11, hw_architecture='ppc64le'),
mock.call(12, hw_architecture='ppc64le', tripleo_platform='p9'),
])
self.assertEqual(mock_subprocess.call_count, 6)
mock_subprocess.assert_has_calls([
@ -880,12 +789,7 @@ class TestUploadOnlyExisting(TestPluginV1):
[mock.call('./ironic-python-agent.initramfs'),
mock.call('./ironic-python-agent.kernel')])
# ensure try_update has been called just with ipa
files = []
for item in self.cmd._image_try_update.call_args_list:
files.append(item[0][1])
self.assertEqual(files, ['./ironic-python-agent.kernel',
'./ironic-python-agent.initramfs'])
self.assertFalse(self.cmd._image_try_update.called)
@mock.patch('subprocess.check_call', autospec=True)
@mock.patch('os.path.isfile', autospec=True)
@ -930,12 +834,7 @@ class TestUploadOnlyExisting(TestPluginV1):
[mock.call('./ironic-python-agent.initramfs'),
mock.call('./ironic-python-agent.kernel')])
# ensure try_update has been called just with ipa
files = []
for item in self.cmd._image_try_update.call_args_list:
files.append(item[0][1])
self.assertEqual(files, ['./ironic-python-agent.kernel',
'./ironic-python-agent.initramfs'])
self.assertFalse(self.cmd._image_try_update.called)
@mock.patch('subprocess.check_call', autospec=True)
@mock.patch('os.path.isfile', autospec=True)

View File

@ -20,6 +20,7 @@ import mock
import os
import tempfile
import fixtures
from osc_lib import exceptions as oscexc
from osc_lib.tests import utils as test_utils
import yaml
@ -486,11 +487,17 @@ class TestImportNode(fakes.TestOvercloudNode):
image = collections.namedtuple('image', ['id', 'name'])
self.app.client_manager.image = mock.Mock()
self.app.client_manager.image.images.list.return_value = [
image(id=1, name='bm-deploy-kernel'),
image(id=2, name='bm-deploy-ramdisk'),
image(id=3, name='overcloud-full'),
]
self.http_boot = '/var/lib/ironic/httpboot'
self.useFixture(fixtures.MockPatch(
'os.path.exists', autospec=True,
side_effect=lambda path: path in [os.path.join(self.http_boot, i)
for i in ('agent.kernel',
'agent.ramdisk')]))
def _check_workflow_call(self, parsed_args, introspect=False,
provide=False, local=None, no_deploy_image=False):
self.websocket.wait_for_messages.return_value = [{
@ -505,14 +512,17 @@ class TestImportNode(fakes.TestOvercloudNode):
self.cmd.take_action(parsed_args)
nodes_list = copy.deepcopy(self.nodes_list)
if not no_deploy_image:
for node in nodes_list:
node.update({
'kernel_id': 'file://%s/agent.kernel' % self.http_boot,
'ramdisk_id': 'file://%s/agent.ramdisk' % self.http_boot,
})
call_count = 1
call_list = [mock.call(
'tripleo.baremetal.v1.register_or_update', workflow_input={
'nodes_json': nodes_list,
'kernel_name': None if no_deploy_image else 'bm-deploy-kernel',
'ramdisk_name': (None
if no_deploy_image else 'bm-deploy-ramdisk'),
'instance_boot_option': ('local' if local is True else
'netboot' if local is False else None)
}
@ -637,17 +647,21 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
image = collections.namedtuple('image', ['id', 'name'])
self.app.client_manager.image = mock.Mock()
self.app.client_manager.image.images.list.return_value = [
image(id=1, name='bm-deploy-kernel'),
image(id=2, name='bm-deploy-ramdisk'),
image(id=3, name='overcloud-full'),
image(id=4, name='x86_64-bm-deploy-kernel'),
image(id=5, name='x86_64-bm-deploy-ramdisk'),
image(id=6, name='x86_64-overcloud-full'),
image(id=7, name='SNB-x86_64-bm-deploy-kernel'),
image(id=8, name='SNB-x86_64-bm-deploy-ramdisk'),
image(id=9, name='SNB-x86_64-overcloud-full'),
]
self.http_boot = '/var/lib/ironic/httpboot'
existing = ['agent', 'x86_64/agent', 'SNB-x86_64/agent']
existing = {os.path.join(self.http_boot, name + ext)
for name in existing for ext in ('.kernel', '.ramdisk')}
self.useFixture(fixtures.MockPatch(
'os.path.exists', autospec=True,
side_effect=lambda path: path in existing))
def _check_workflow_call(self, parsed_args, introspect=False,
provide=False, local=None, no_deploy_image=False):
self.websocket.wait_for_messages.return_value = [{
@ -662,20 +676,24 @@ class TestImportNodeMultiArch(fakes.TestOvercloudNode):
self.cmd.take_action(parsed_args)
nodes_list = copy.deepcopy(self.nodes_list)
# We expect update_nodes_deploy_data() to set these values for the
# nodes with an 'arch' field
nodes_list[1]['kernel_id'] = 4
nodes_list[1]['ramdisk_id'] = 5
nodes_list[2]['kernel_id'] = 7
nodes_list[2]['ramdisk_id'] = 8
if not no_deploy_image:
nodes_list[0]['kernel_id'] = (
'file://%s/agent.kernel' % self.http_boot)
nodes_list[0]['ramdisk_id'] = (
'file://%s/agent.ramdisk' % self.http_boot)
nodes_list[1]['kernel_id'] = (
'file://%s/x86_64/agent.kernel' % self.http_boot)
nodes_list[1]['ramdisk_id'] = (
'file://%s/x86_64/agent.ramdisk' % self.http_boot)
nodes_list[2]['kernel_id'] = (
'file://%s/SNB-x86_64/agent.kernel' % self.http_boot)
nodes_list[2]['ramdisk_id'] = (
'file://%s/SNB-x86_64/agent.ramdisk' % self.http_boot)
call_count = 1
call_list = [mock.call(
'tripleo.baremetal.v1.register_or_update', workflow_input={
'nodes_json': nodes_list,
'kernel_name': None if no_deploy_image else 'bm-deploy-kernel',
'ramdisk_name': (None
if no_deploy_image else 'bm-deploy-ramdisk'),
'instance_boot_option': ('local' if local is True else
'netboot' if local is False else None)
}
@ -768,12 +786,14 @@ class TestConfigureNode(fakes.TestOvercloudNode):
# Get the command object to test
self.cmd = overcloud_node.ConfigureNode(self.app, None)
self.workflow_input = {'kernel_name': 'bm-deploy-kernel',
'ramdisk_name': 'bm-deploy-ramdisk',
'instance_boot_option': None,
'root_device': None,
'root_device_minimum_size': 4,
'overwrite_root_device_hints': False}
self.workflow_input = {
'kernel_name': 'file:///var/lib/ironic/httpboot/agent.kernel',
'ramdisk_name': 'file:///var/lib/ironic/httpboot/agent.ramdisk',
'instance_boot_option': None,
'root_device': None,
'root_device_minimum_size': 4,
'overwrite_root_device_hints': False
}
def test_configure_all_manageable_nodes(self):
parsed_args = self.check_parser(self.cmd,

View File

@ -1456,14 +1456,19 @@ def configure_logging(log, level, log_file):
log.addHandler(fhandler)
def _name_helper(basename, arch=None, platform=None):
def _name_helper(basename, arch=None, platform=None, use_subdir=False):
# NOTE(tonyb): We don't accept a platform with an arch. This caught when
# import the nodes / process args, but lets be a little cautious here
# anyway.
if use_subdir:
delim = '/'
else:
delim = '-'
if arch and platform:
basename = platform + '-' + arch + '-' + basename
basename = platform + '-' + arch + delim + basename
elif arch:
basename = arch + '-' + basename
basename = arch + delim + basename
return basename
@ -1485,48 +1490,71 @@ def overcloud_image(basename, arch=None, platform=None):
def deploy_kernel(arch=None, platform=None):
return (_name_helper('bm-deploy-kernel', arch=arch, platform=platform),
'.kernel')
return _name_helper('agent', arch=arch, platform=platform,
use_subdir=True) + '.kernel'
def deploy_ramdisk(arch=None, platform=None):
return (_name_helper('bm-deploy-ramdisk', arch=arch, platform=platform),
'.initramfs')
return _name_helper('agent', arch=arch, platform=platform,
use_subdir=True) + '.ramdisk'
def update_nodes_deploy_data(imageclient, nodes):
def _candidate_files(node, call):
arch = node.get('arch')
platform = node.get('platform')
if arch:
if platform:
yield call(arch=arch, platform=platform)
yield call(arch=arch)
yield call()
def update_nodes_deploy_data(nodes,
http_boot=constants.IRONIC_HTTP_BOOT_BIND_MOUNT):
"""Add specific kernel and ramdisk IDs to a node.
Look at all images and update node data with the most specific
deploy_kernel and deploy_ramdisk for the architecture/platform comination
platform.
"""
img_map = {}
for image in imageclient.images.list():
name = image.name
# NOTE(tonyb): We don't want to include the default kernel or ramdisk
# in the map as that will short-circuit logic elesewhere.
if name != deploy_kernel()[0] and name != deploy_ramdisk()[0]:
img_map[image.name] = image.id
for node in nodes:
arch = node.get('arch')
platform = node.get('platform')
# NOTE(tonyb): Check to see if we have a specific kernel for this node
# and use that.
for kernel in [deploy_kernel(arch=arch, platform=platform)[0],
deploy_kernel(arch=arch)[0]]:
if 'kernel_id' not in node and kernel in img_map:
node['kernel_id'] = img_map[kernel]
break
# and use that. Fall back to the generic image.
if 'kernel_id' not in node:
kernel_locations = list(_candidate_files(node, deploy_kernel))
for kernel in kernel_locations:
path = os.path.join(http_boot, kernel)
if os.path.exists(path):
# NOTE(dtantsur): we don't use http_boot here since we
# assume that the path in containers is fixed
node['kernel_id'] = 'file://%s/%s' % (
constants.IRONIC_HTTP_BOOT_BIND_MOUNT,
kernel)
break
else:
raise RuntimeError('No kernel image provided and none of %s '
'found in %s' % (kernel_locations,
http_boot))
# NOTE(tonyb): As above except for ramdisks
for ramdisk in [deploy_ramdisk(arch=arch, platform=platform)[0],
deploy_ramdisk(arch=arch)[0]]:
if 'ramdisk_id' not in node and ramdisk in img_map:
node['ramdisk_id'] = img_map[ramdisk]
break
if 'ramdisk_id' not in node:
ramdisk_locations = list(_candidate_files(node, deploy_ramdisk))
for ramdisk in ramdisk_locations:
path = os.path.join(http_boot, ramdisk)
if os.path.exists(path):
node['ramdisk_id'] = 'file://%s/%s' % (
constants.IRONIC_HTTP_BOOT_BIND_MOUNT,
ramdisk)
break
else:
raise RuntimeError('No ramdisk image provided and none of %s '
'found in %s' % (ramdisk_locations,
http_boot))
def get_deployment_python_interpreter(parsed_args):

View File

@ -270,7 +270,7 @@ class UploadOvercloudImage(command.Command):
default=self._get_environment_var(
'HTTP_BOOT',
constants.IRONIC_HTTP_BOOT_BIND_MOUNT),
help=_("Root directory for the introspection image")
help=_("Root directory for the ironic-python-agent image")
)
parser.add_argument(
"--update-existing",
@ -458,44 +458,8 @@ class UploadOvercloudImage(command.Command):
if parsed_args.image_type is None or \
parsed_args.image_type == 'ironic-python-agent':
(deploy_kernel_name,
deploy_kernel_extension) = plugin_utils.deploy_kernel(
arch=arch, platform=platform)
deploy_kernel_file = os.path.join(parsed_args.image_path,
parsed_args.ipa_name +
deploy_kernel_extension)
self._image_try_update(deploy_kernel_name, deploy_kernel_file,
parsed_args) or \
glance_client_adaptor.upload_image(
name=deploy_kernel_name,
is_public=True,
disk_format='aki',
properties=properties,
data=self._read_image_file_pointer(
parsed_args.image_path,
deploy_kernel_file))
(deploy_ramdisk_name,
deploy_ramdisk_extension) = plugin_utils.deploy_ramdisk(
arch=arch, platform=platform)
deploy_ramdisk_file = os.path.join(parsed_args.image_path,
parsed_args.ipa_name +
deploy_ramdisk_extension)
self._image_try_update(deploy_ramdisk_name, deploy_ramdisk_file,
parsed_args) or \
glance_client_adaptor.upload_image(
name=deploy_ramdisk_name,
is_public=True,
disk_format='ari',
properties=properties,
data=self._read_image_file_pointer(parsed_args.image_path,
deploy_ramdisk_file))
self.log.debug("copy agent images to HTTP BOOT dir")
# TODO(tonyb) Decide how to handle platform specific httpboot
# files/names
self._file_create_or_update(
os.path.join(parsed_args.image_path,
'%s.kernel' % parsed_args.ipa_name),

View File

@ -269,6 +269,12 @@ class ImportNode(command.Command):
help=_('Whether to set instances for booting from '
'local hard drive (local) or network '
'(netboot).'))
parser.add_argument("--http-boot",
default=os.environ.get(
'HTTP_BOOT',
constants.IRONIC_HTTP_BOOT_BIND_MOUNT),
help=_("Root directory for the ironic-python-agent"
" image"))
parser.add_argument('env_file', type=argparse.FileType('r'))
return parser
@ -281,22 +287,14 @@ class ImportNode(command.Command):
return baremetal.validate_nodes(self.app.client_manager,
nodes_json=nodes_config)
if parsed_args.no_deploy_image:
deploy_kernel = None
deploy_ramdisk = None
else:
deploy_kernel = oooutils.deploy_kernel()[0]
deploy_ramdisk = oooutils.deploy_ramdisk()[0]
# Look for *specific* deploy images and update the node data if
# one is found.
oooutils.update_nodes_deploy_data(self.app.client_manager.image,
nodes_config)
if not parsed_args.no_deploy_image:
oooutils.update_nodes_deploy_data(nodes_config,
http_boot=parsed_args.http_boot)
nodes = baremetal.register_or_update(
self.app.client_manager,
nodes_json=nodes_config,
kernel_name=deploy_kernel,
ramdisk_name=deploy_ramdisk,
instance_boot_option=parsed_args.instance_boot_option
)
@ -332,12 +330,16 @@ class ConfigureNode(command.Command):
action='store_true',
help=_("Configure all nodes currently in "
"'manageable' state"))
parser.add_argument('--deploy-kernel',
default='bm-deploy-kernel',
help=_('Image with deploy kernel.'))
parser.add_argument('--deploy-ramdisk',
default='bm-deploy-ramdisk',
help=_('Image with deploy ramdisk.'))
parser.add_argument(
'--deploy-kernel',
default='file://%s/agent.kernel' %
constants.IRONIC_HTTP_BOOT_BIND_MOUNT,
help=_('Image with deploy kernel.'))
parser.add_argument(
'--deploy-ramdisk',
default='file://%s/agent.ramdisk' %
constants.IRONIC_HTTP_BOOT_BIND_MOUNT,
help=_('Image with deploy ramdisk.'))
parser.add_argument('--instance-boot-option',
choices=['local', 'netboot'],
help=_('Whether to set instances for booting from '