Add overcloud image create method

Adding overcloud image create method to replace instack
code (method instack-prepare-for-overcloud) and do overcloud
deployment via rdomanager commands.

Main functionality is to take locally stored image files and
upload them to glance.

Change-Id: Icc39744c511013d663242f5b544b0ac4a2fd6893
This commit is contained in:
Marek Aufart 2015-03-26 10:52:56 +01:00
parent bb804c6ce8
commit 937e848460
3 changed files with 191 additions and 6 deletions

View File

@ -13,6 +13,7 @@
# under the License.
#
import mock
from rdomanager_oscplugin.tests.v1.test_plugin import TestPluginV1
# Load the plugin init module for the plugin list and show commands
@ -39,4 +40,58 @@ class TestOvercloudImageCreate(TestPluginV1):
super(TestOvercloudImageCreate, self).setUp()
# Get the command object to test
self.cmd = overcloud_image.CreatePlugin(self.app, None)
self.cmd = overcloud_image.CreateOvercloud(self.app, None)
self.app.client_manager.image = mock.Mock()
self.app.client_manager.image.images.create.return_value = \
mock.Mock(id=10)
self.cmd._read_image_file_pointer = mock.Mock(return_value=b'IMGDATA')
self.cmd._check_file_exists = mock.Mock(return_value=True)
@mock.patch('subprocess.call')
def test_overcloud_create_images(self, mock_subprocess_call):
parsed_args = self.check_parser(self.cmd, [], [])
self.cmd.take_action(parsed_args)
self.assertEqual(
2,
self.app.client_manager.image.images.delete.call_count
)
self.assertEqual(
5,
self.app.client_manager.image.images.create.call_count
)
self.assertEqual(
[mock.call(data=b'IMGDATA',
name='overcloud-full-vmlinuz',
disk_format='aki',
is_public=True),
mock.call(data=b'IMGDATA',
name='overcloud-full-initrd',
disk_format='ari',
is_public=True),
mock.call(properties={'kernel_id': 10, 'ramdisk_id': 10},
name='overcloud-full',
data=b'IMGDATA',
container_format='bare',
disk_format='qcow2',
is_public=True),
mock.call(data=b'IMGDATA',
name='bm-deploy-kernel',
disk_format='aki',
is_public=True),
mock.call(data=b'IMGDATA',
name='bm-deploy-ramdisk',
disk_format='ari',
is_public=True)
], self.app.client_manager.image.images.create.call_args_list
)
self.assertEqual(mock_subprocess_call.call_count, 2)
self.assertEqual(
mock_subprocess_call.call_args_list, [
mock.call('sudo cp -f "./discovery-ramdisk.kernel" '
'"/tftpboot/discovery.kernel"', shell=True),
mock.call('sudo cp -f "./discovery-ramdisk.initramfs" '
'"/tftpboot/discovery.ramdisk"', shell=True)
])

View File

@ -16,8 +16,12 @@
"""Plugin action implementation"""
import logging
import os
import subprocess
from cliff import command
from openstackclient.common import exceptions
from openstackclient.common import utils
class BuildPlugin(command.Command):
@ -31,11 +35,137 @@ class BuildPlugin(command.Command):
pass
class CreatePlugin(command.Command):
"""Overcloud Image Create plugin"""
class CreateOvercloud(command.Command):
"""Create overcloud glance images from existing image files."""
auth_required = False
log = logging.getLogger(__name__ + ".CreatePlugin")
log = logging.getLogger(__name__ + ".CreateOvercloud")
def _env_variable_or_set(self, key_name, default_value):
os.environ[key_name] = os.environ.get(key_name, default_value)
def _delete_image_if_exists(self, image_client, name):
try:
image = utils.find_resource(image_client.images, name)
image_client.images.delete(image.id)
except exceptions.CommandError:
self.log.debug('Image "%s" have already not existed, '
'no problem.' % name)
def _check_file_exists(self, file_path):
if not os.path.isfile(file_path):
print('ERROR: Required file "%s" does not exist' % file_path)
exit(1)
def _read_image_file_pointer(self, dirname, filename):
filepath = os.path.join(dirname, filename)
self._check_file_exists(filepath)
return open(filepath, 'rb')
def _copy_file(self, src, dest):
subprocess.call('sudo cp -f "{0}" "{1}"'.format(src, dest), shell=True)
def _load_image(self, image_path, image_name, image_client):
self.log.debug("uploading images to glance")
kernel_id = image_client.images.create(
name='%s-vmlinuz' % image_name,
is_public=True,
disk_format='aki',
data=self._read_image_file_pointer(image_path,
'%s.vmlinuz' % image_name)
).id
ramdisk_id = image_client.images.create(
name='%s-initrd' % image_name,
is_public=True,
disk_format='ari',
data=self._read_image_file_pointer(image_path,
'%s.initrd' % image_name)
).id
image_client.images.create(
name=image_name,
is_public=True,
disk_format='qcow2',
container_format='bare',
properties={'kernel_id': kernel_id, 'ramdisk_id': ramdisk_id},
data=self._read_image_file_pointer(image_path,
'%s.qcow2' % image_name)
)
def get_parser(self, prog_name):
parser = super(CreateOvercloud, self).get_parser(prog_name)
parser.add_argument(
"--image-path",
default='./',
help="Path to directory containing image files",
)
parser.add_argument(
"--os-image",
default='overcloud-full.qcow2',
help="OpenStack disk image filename",
)
return parser
def take_action(self, parsed_args):
self.log.debug("take_action(%s)" % parsed_args)
pass
image_client = self.app.client_manager.image
self._env_variable_or_set('DEPLOY_NAME', 'deploy-ramdisk-ironic')
self._env_variable_or_set('DISCOVERY_NAME', 'discovery-ramdisk')
self._env_variable_or_set('TFTP_ROOT', '/tftpboot')
self.log.debug("check image files")
image_files = [
'%s.initramfs' % os.environ['DEPLOY_NAME'],
'%s.kernel' % os.environ['DEPLOY_NAME'],
'%s.initramfs' % os.environ['DISCOVERY_NAME'],
'%s.kernel' % os.environ['DISCOVERY_NAME'],
parsed_args.os_image
]
for image in image_files:
self._check_file_exists(os.path.join(parsed_args.image_path,
image))
self.log.debug("prepare glance images")
self._load_image(parsed_args.image_path,
parsed_args.os_image.split('.')[0],
image_client)
self._delete_image_if_exists(image_client, 'bm_deploy_kernel')
self._delete_image_if_exists(image_client, 'bm_deploy_ramdisk')
image_client.images.create(
name='bm-deploy-kernel',
is_public=True,
disk_format='aki',
data=self._read_image_file_pointer(parsed_args.image_path,
'%s.kernel' %
os.environ['DEPLOY_NAME'])
)
image_client.images.create(
name='bm-deploy-ramdisk',
is_public=True,
disk_format='ari',
data=self._read_image_file_pointer(parsed_args.image_path,
'%s.initramfs' %
os.environ['DEPLOY_NAME'])
)
self.log.debug("copy discovery images to TFTP")
self._copy_file(
os.path.join(parsed_args.image_path,
'%s.kernel' % os.environ['DISCOVERY_NAME']),
os.path.join(os.environ['TFTP_ROOT'], 'discovery.kernel')
)
self._copy_file(
os.path.join(parsed_args.image_path,
'%s.initramfs' % os.environ['DISCOVERY_NAME']),
os.path.join(os.environ['TFTP_ROOT'], 'discovery.ramdisk')
)

View File

@ -60,5 +60,5 @@ openstack.rdomanager_oscplugin.v1 =
baremetal_configure_boot = rdomanager_oscplugin.v1.baremetal:ConfigureBootPlugin
overcloud_deploy = rdomanager_oscplugin.v1.overcloud_deploy:DeployPlugin
overcloud_image_build = rdomanager_oscplugin.v1.overcloud_image:BuildPlugin
overcloud_image_create = rdomanager_oscplugin.v1.overcloud_image:CreatePlugin
overcloud_image_create = rdomanager_oscplugin.v1.overcloud_image:CreateOvercloud
undercloud_install = rdomanager_oscplugin.v1.undercloud:InstallPlugin