Initial lpar create for the spawn operation

Add code to spawn to create the lpar.
Remove calls to _get_host_uuid() and use cached value instead.

Change-Id: I16184aa9bf10e562f4bf2ccded09a95757ef8307
This commit is contained in:
Kyle L. Henderson 2015-01-08 12:12:23 -06:00
parent c99453bcab
commit 53606fc79a
6 changed files with 102 additions and 17 deletions

View File

@ -1,4 +1,4 @@
# Copyright 2014 IBM Corp.
# Copyright 2014, 2015 IBM Corp.
#
# All Rights Reserved.
#
@ -38,6 +38,14 @@ logging.basicConfig()
class FakeInstance(object):
def __init__(self):
self.name = 'fake_instance'
self.instance_type_id = 'instance_type_id'
class FakeFlavor(object):
def __init__(self):
self.name = 'fake_flavor'
self.memory_mb = 256
self.vcpus = 1
class TestPowerVMDriver(test.TestCase):
@ -80,10 +88,15 @@ class TestPowerVMDriver(test.TestCase):
@mock.patch('pypowervm.adapter.Adapter')
@mock.patch('nova_powervm.virt.powervm.host.find_entry_by_mtm_serial')
@mock.patch('nova_powervm.virt.powervm.vm.UUIDCache')
def test_driver_ops(self, mock_uuidcache, mock_find, mock_apt, mock_sess):
@mock.patch('nova.context.get_admin_context')
@mock.patch('nova.objects.flavor.Flavor.get_by_id')
def test_driver_ops(self, mock_get_flv, mock_get_ctx,
mock_uuidcache, mock_find,
mock_apt, mock_sess):
"""Validates the PowerVM driver operations."""
drv = driver.PowerVMDriver(fake.FakeVirtAPI())
drv.init_host('FakeHost')
drv.adapter = mock_apt
# get_info()
inst = FakeInstance()
@ -100,6 +113,15 @@ class TestPowerVMDriver(test.TestCase):
inst_list = drv.list_instances()
self.assertEqual(fake_lpar_list, inst_list)
# spawn()
with mock.patch('nova_powervm.virt.powervm.vm.crt_lpar') as mock_crt:
my_flavor = FakeFlavor()
mock_get_flv.return_value = my_flavor
drv.spawn('context', inst, 'image_meta',
'injected_files', 'admin_password')
mock_crt.assert_called_with(mock_apt, drv.host_uuid,
inst, my_flavor)
def test_host_resources(self):
stats = pvm_host.build_host_resource_from_entry(self.wrapper)
self.assertIsNotNone(stats)

View File

@ -1,4 +1,4 @@
# Copyright 2014 IBM Corp.
# Copyright 2014, 2015 IBM Corp.
#
# All Rights Reserved.
#
@ -43,6 +43,18 @@ class FakeAdapterResponse(object):
self.status = status
class FakeInstance(object):
def __init__(self):
self.name = 'fake_instance'
class FakeFlavor(object):
def __init__(self):
self.name = 'fake_flavor'
self.memory_mb = 256
self.vcpus = 1
class TestVM(test.TestCase):
def setUp(self):
super(TestVM, self).setUp()
@ -148,3 +160,10 @@ class TestVM(test.TestCase):
# Check the first one in the feed and the length of the feed
self.assertEqual(lpar_list[0], 'nova-z3-9-5-126-127-00000001')
self.assertEqual(len(lpar_list), 21)
@mock.patch('pypowervm.adapter.Adapter')
def test_crt_lpar(self, mock_adr):
instance = FakeInstance()
flavor = FakeFlavor()
vm.crt_lpar(mock_adr, 'host_uuid', instance, flavor)
self.assertTrue(mock_adr.create.called)

View File

@ -1,4 +1,4 @@
# Copyright 2014 IBM Corp.
# Copyright 2014, 2015 IBM Corp.
#
# All Rights Reserved.
#
@ -17,6 +17,10 @@
from oslo.config import cfg
hmc_opts = [
cfg.FloatOpt('proc_units_factor',
default=0.1,
help='Factor used to calculate the processor units per vcpu.'
' Valid values are: 0.05 - 1.0'),
# TODO(kyleh) Temporary - Only needed since we're using an HMC
cfg.StrOpt('hmc_host_id',
default='',

View File

@ -1,4 +1,4 @@
# Copyright 2014 IBM Corp.
# Copyright 2014, 2015 IBM Corp.
#
# All Rights Reserved.
#
@ -15,7 +15,9 @@
# under the License.
from nova import context as ctx
from nova.i18n import _LI
from nova.objects import flavor as flavor_obj
from nova.openstack.common import log as logging
from nova.virt import driver
from nova.virt import fake # TODO(IBM): Remove this in the future
@ -108,7 +110,7 @@ class PowerVMDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None,
instance_type=None):
flavor=None):
"""Create a new instance/VM/domain on the virtualization platform.
Once this successfully completes, the instance should be
@ -130,11 +132,17 @@ class PowerVMDriver(driver.ComputeDriver):
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param block_device_info: Information about block devices to be
attached to the instance.
:param instance_type: The instance_type for the instance to be spawned.
:param flavor: The flavor for the instance to be spawned.
"""
return self._fake.spawn(context, instance, image_meta, injected_files,
admin_password, network_info,
block_device_info)
if not flavor:
admin_ctx = ctx.get_admin_context(read_deleted='yes')
flavor = (
flavor_obj.Flavor.get_by_id(admin_ctx,
instance.instance_type_id))
# Create the lpar on the host
vm.crt_lpar(self.adapter, self.host_uuid, instance, flavor)
def destroy(self, instance, network_info, block_device_info=None,
destroy_disks=True):
@ -180,7 +188,7 @@ class PowerVMDriver(driver.ComputeDriver):
vm.get_instance_wrapper(self.adapter,
instance,
self.pvm_uuids,
self._get_host_uuid()),
self.host_uuid),
self.host_uuid)
def power_on(self, instance):
@ -189,7 +197,7 @@ class PowerVMDriver(driver.ComputeDriver):
vm.get_instance_wrapper(self.adapter,
instance,
self.pvm_uuids,
self._get_host_uuid()),
self.host_uuid),
self.host_uuid)
def get_available_resource(self, nodename):

View File

@ -1,4 +1,4 @@
# Copyright 2014 IBM Corp.
# Copyright 2014, 2015 IBM Corp.
#
# All Rights Reserved.
#
@ -67,7 +67,7 @@ class FakePowerVMDriver(driver.ComputeDriver):
def spawn(self, context, instance, image_meta, injected_files,
admin_password, network_info=None, block_device_info=None,
instance_type=None):
flavor=None):
"""Create a new instance/VM/domain on the virtualization platform.
Once this successfully completes, the instance should be
@ -89,7 +89,7 @@ class FakePowerVMDriver(driver.ComputeDriver):
:py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info`
:param block_device_info: Information about block devices to be
attached to the instance.
:param instance_type: The instance_type for the instance to be spawned.
:param flavor: The flavor for the instance to be spawned.
"""
return self._fake.spawn(context, instance, image_meta, injected_files,
admin_password, network_info,

View File

@ -1,4 +1,4 @@
# Copyright 2014 IBM Corp.
# Copyright 2014, 2015 IBM Corp.
#
# All Rights Reserved.
#
@ -14,6 +14,8 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo.config import cfg
from nova.compute import power_state
from nova import exception
from nova.openstack.common import log as logging
@ -23,7 +25,7 @@ from pypowervm.wrappers import constants as pvm_consts
from pypowervm.wrappers import logical_partition as pvm_lpar
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
POWERVM_TO_NOVA_STATE = {
"migrating running": power_state.RUNNING,
@ -190,6 +192,36 @@ def get_instance_wrapper(adapter, instance, pvm_uuids, host_uuid):
return pvm_lpar.LogicalPartition(entry)
def calc_proc_units(vcpu):
return (vcpu * CONF.proc_units_factor)
def crt_lpar(adapter, host_uuid, instance, flavor):
"""Create an LPAR based on the host based on the instance
:param adapter: The adapter for the pypowervm API
:param host_uuid: (TEMPORARY) The host UUID
:param instance: The nova instance.
:param flavor: The nova flavor.
"""
mem = str(flavor.memory_mb)
vcpus = str(flavor.vcpus)
proc_units = '%.2f' % calc_proc_units(flavor.vcpus)
sprocs = pvm_lpar.crt_shared_procs(proc_units, vcpus)
lpar_elem = pvm_lpar.crt_lpar(instance.name,
pvm_lpar.LPAR_TYPE_AIXLINUX,
sprocs,
mem,
min_mem=mem,
max_mem=mem,
max_io_slots='64')
adapter.create(lpar_elem, pvm_consts.MGT_SYS,
rootId=host_uuid, childType=pvm_lpar.LPAR)
class UUIDCache(object):
"""Cache of instance names to PVM UUID value