Add Ironic virt type
Adds support for the Ironic virt driver. Change-Id: I72a7fb65395e4ceddc77a92bccc7b4563af0750a
This commit is contained in:
parent
eeaee2a094
commit
7ff7001982
1
hooks/ironic-api-relation-changed
Symbolic link
1
hooks/ironic-api-relation-changed
Symbolic link
@ -0,0 +1 @@
|
||||
nova_compute_hooks.py
|
@ -341,6 +341,21 @@ class NovaComputeVirtContext(context.OSContextGenerator):
|
||||
return ctxt
|
||||
|
||||
|
||||
class IronicAPIContext(context.OSContextGenerator):
|
||||
interfaces = ["ironic-api"]
|
||||
|
||||
def __call__(self):
|
||||
ctxt = {}
|
||||
for rid in relation_ids('ironic-api'):
|
||||
for unit in related_units(rid):
|
||||
is_ready = relation_get(
|
||||
'ironic-api-ready', rid=rid, unit=unit)
|
||||
if is_ready:
|
||||
ctxt["ironic_api_ready"] = is_ready
|
||||
return ctxt
|
||||
return ctxt
|
||||
|
||||
|
||||
def assert_libvirt_rbd_imagebackend_allowed():
|
||||
os_rel = "Juno"
|
||||
os_ver = get_os_version_package('nova-common')
|
||||
|
@ -364,6 +364,12 @@ def compute_changed():
|
||||
import_keystone_ca_cert()
|
||||
|
||||
|
||||
@hooks.hook('ironic-api-relation-changed')
|
||||
@restart_on_change(restart_map())
|
||||
def ironic_api_changed():
|
||||
CONFIGS.write(NOVA_CONF)
|
||||
|
||||
|
||||
@hooks.hook('ceph-access-relation-joined')
|
||||
@hooks.hook('ceph-relation-joined')
|
||||
@restart_on_change(restart_map())
|
||||
|
@ -96,6 +96,7 @@ from nova_compute_context import (
|
||||
NovaComputeCephContext,
|
||||
NeutronComputeContext,
|
||||
InstanceConsoleContext,
|
||||
IronicAPIContext,
|
||||
CEPH_CONF,
|
||||
ceph_config_file,
|
||||
HostIPContext,
|
||||
@ -170,6 +171,7 @@ LIBVIRTD_CONF = '/etc/libvirt/libvirtd.conf'
|
||||
LIBVIRT_BIN = '/etc/default/libvirt-bin'
|
||||
LIBVIRT_BIN_OVERRIDES = '/etc/init/libvirt-bin.override'
|
||||
NOVA_CONF = '%s/nova.conf' % NOVA_CONF_DIR
|
||||
NOVA_COMPUTE_CONF = '%s/nova-compute.conf' % NOVA_CONF_DIR
|
||||
VENDORDATA_FILE = '%s/vendor_data.json' % NOVA_CONF_DIR
|
||||
QEMU_KVM = '/etc/default/qemu-kvm'
|
||||
NOVA_API_AA_PROFILE_PATH = ('/etc/apparmor.d/{}'.format(NOVA_API_AA_PROFILE))
|
||||
@ -203,6 +205,7 @@ BASE_RESOURCE_MAP = {
|
||||
context.OSConfigFlagContext(),
|
||||
CloudComputeContext(),
|
||||
LxdContext(),
|
||||
IronicAPIContext(),
|
||||
NovaComputeLibvirtContext(),
|
||||
NovaComputeCephContext(),
|
||||
context.SyslogContext(),
|
||||
@ -292,6 +295,7 @@ VIRT_TYPES = {
|
||||
'uml': ['nova-compute-uml'],
|
||||
'lxc': ['nova-compute-lxc'],
|
||||
'lxd': ['nova-compute-lxd'],
|
||||
'ironic': ['nova-compute-ironic'],
|
||||
}
|
||||
|
||||
|
||||
@ -332,7 +336,8 @@ def resource_map():
|
||||
hook execution.
|
||||
'''
|
||||
# TODO: Cache this on first call?
|
||||
if config('virt-type').lower() == 'lxd':
|
||||
virt_type = config('virt-type').lower()
|
||||
if virt_type in ('lxd', 'ironic'):
|
||||
resource_map = deepcopy(BASE_RESOURCE_MAP)
|
||||
else:
|
||||
resource_map = deepcopy(LIBVIRT_RESOURCE_MAP)
|
||||
@ -363,6 +368,16 @@ def resource_map():
|
||||
resource_map.pop(NOVA_API_AA_PROFILE_PATH)
|
||||
resource_map.pop(NOVA_NETWORK_AA_PROFILE_PATH)
|
||||
|
||||
if virt_type == 'ironic':
|
||||
# NOTE(gsamfira): OpenStack versions prior to Victoria do not have a
|
||||
# dedicated nova-compute-ironic package which provides a suitable
|
||||
# nova-compute.conf file. We use a template to compensate for that.
|
||||
if cmp_os_release < 'victoria':
|
||||
resource_map[NOVA_COMPUTE_CONF] = {
|
||||
"services": ["nova-compute"],
|
||||
"contexts": [],
|
||||
}
|
||||
|
||||
cmp_distro_codename = CompareHostReleases(
|
||||
lsb_release()['DISTRIB_CODENAME'].lower())
|
||||
if (cmp_distro_codename >= 'yakkety' or cmp_os_release >= 'ocata'):
|
||||
@ -391,7 +406,8 @@ def resource_map():
|
||||
# NOTE(james-page): If not on an upstart based system, don't write
|
||||
# and override file for libvirt-bin.
|
||||
if not os.path.exists('/etc/init'):
|
||||
del resource_map[LIBVIRT_BIN_OVERRIDES]
|
||||
if LIBVIRT_BIN_OVERRIDES in resource_map:
|
||||
del resource_map[LIBVIRT_BIN_OVERRIDES]
|
||||
|
||||
return resource_map
|
||||
|
||||
@ -463,6 +479,18 @@ def determine_packages():
|
||||
packages.append('ceph-common')
|
||||
|
||||
virt_type = config('virt-type')
|
||||
if virt_type == 'ironic' and release < 'victoria':
|
||||
# ironic compute driver is part of nova and
|
||||
# gets installed allong with python3-nova
|
||||
# The nova-compute-ironic metapackage that satisfies
|
||||
# nova-compute-hypervisor does not exist for versions of
|
||||
# OpenStack prior to Victoria. Use nova-compute-vmware,
|
||||
# as that package has the least amount of dependencies.
|
||||
# We also add python3-ironicclient here. This is a dependency
|
||||
# which gets installed by nova-compute-ironic in Victoria and later.
|
||||
VIRT_TYPES[virt_type] = [
|
||||
'nova-compute-vmware',
|
||||
'python3-ironicclient']
|
||||
try:
|
||||
packages.extend(VIRT_TYPES[virt_type])
|
||||
except KeyError:
|
||||
@ -876,6 +904,8 @@ def get_optional_relations():
|
||||
optional_interfaces['neutron-plugin'] = ['neutron-plugin']
|
||||
if config('encrypt'):
|
||||
optional_interfaces['vault'] = ['secrets-storage']
|
||||
if config('virt-type').lower() == 'ironic':
|
||||
optional_interfaces['baremetal'] = ['ironic-api']
|
||||
|
||||
return optional_interfaces
|
||||
|
||||
|
@ -53,6 +53,8 @@ requires:
|
||||
interface: keystone-credentials
|
||||
secrets-storage:
|
||||
interface: vault-kv
|
||||
ironic-api:
|
||||
interface: baremetal
|
||||
peers:
|
||||
compute-peer:
|
||||
interface: nova
|
||||
|
15
templates/parts/section-ironic
Normal file
15
templates/parts/section-ironic
Normal file
@ -0,0 +1,15 @@
|
||||
{% if virt_type == 'ironic' and auth_host and ironic_api_ready -%}
|
||||
{% if api_version and api_version == "3" -%}
|
||||
{% set auth_ver = "v3" -%}
|
||||
{% else -%}
|
||||
{% set auth_ver = "v2.0" -%}
|
||||
{% endif -%}
|
||||
[ironic]
|
||||
auth_type = password
|
||||
auth_url = {{auth_protocol}}://{{auth_host}}:{{auth_port}}/{{auth_ver}}
|
||||
project_name = {{ admin_tenant_name }}
|
||||
username = {{ admin_user }}
|
||||
password = {{ admin_password }}
|
||||
project_domain_name = {{ admin_domain_name }}
|
||||
user_domain_name = {{ admin_domain_name }}
|
||||
{% endif -%}
|
2
templates/train/nova-compute.conf
Normal file
2
templates/train/nova-compute.conf
Normal file
@ -0,0 +1,2 @@
|
||||
[DEFAULT]
|
||||
compute_driver=ironic.IronicDriver
|
@ -316,6 +316,8 @@ disable_libvirt_livesnapshot = False
|
||||
|
||||
{% include "parts/section-placement" %}
|
||||
|
||||
{% include "parts/section-ironic" %}
|
||||
|
||||
[compute]
|
||||
{% if cpu_shared_set -%}
|
||||
cpu_shared_set = {{ cpu_shared_set }}
|
||||
|
@ -767,6 +767,37 @@ class NovaComputeContextTests(CharmTestCase):
|
||||
'pcid, vmx, pdpe1gb')
|
||||
|
||||
|
||||
class IronicAPIContextTests(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(IronicAPIContextTests, self).setUp(context, TO_PATCH)
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
|
||||
def test_ironic_api_ready_no_relation(self):
|
||||
self.relation_ids.return_value = []
|
||||
self.assertEqual(
|
||||
context.IronicAPIContext()(), {})
|
||||
|
||||
def test_ironic_api_ready(self):
|
||||
self.relation_ids.return_value = ['ironic-api:0']
|
||||
self.related_units.return_value = 'ironic-api/0'
|
||||
self.test_relation.set({
|
||||
'ironic-api-ready': True,
|
||||
})
|
||||
self.assertEqual(
|
||||
context.IronicAPIContext()(),
|
||||
{'ironic_api_ready': True})
|
||||
|
||||
def test_ironic_api_not_ready(self):
|
||||
self.relation_ids.return_value = ['ironic-api:0']
|
||||
self.related_units.return_value = 'ironic-api/0'
|
||||
self.test_relation.set({
|
||||
'ready': False,
|
||||
})
|
||||
self.assertEqual(
|
||||
context.IronicAPIContext()(), {})
|
||||
|
||||
|
||||
class SerialConsoleContextTests(CharmTestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
@ -101,6 +101,31 @@ class NovaComputeUtilsTests(CharmTestCase):
|
||||
]
|
||||
self.assertTrue(ex == result)
|
||||
|
||||
@patch.object(utils, 'nova_metadata_requirement')
|
||||
def test_determine_packages_ironic(self, en_meta):
|
||||
self.os_release.return_value = 'victoria'
|
||||
self.test_config.set('virt-type', 'ironic')
|
||||
en_meta.return_value = (False, None)
|
||||
self.relation_ids.return_value = []
|
||||
result = utils.determine_packages()
|
||||
ex = utils.BASE_PACKAGES + [
|
||||
'nova-compute-ironic'
|
||||
]
|
||||
self.assertTrue(ex.sort() == result.sort())
|
||||
|
||||
@patch.object(utils, 'nova_metadata_requirement')
|
||||
def test_determine_packages_ironic_pre_victoria(self, en_meta):
|
||||
self.os_release.return_value = 'train'
|
||||
self.test_config.set('virt-type', 'ironic')
|
||||
en_meta.return_value = (False, None)
|
||||
self.relation_ids.return_value = []
|
||||
result = utils.determine_packages()
|
||||
ex = utils.BASE_PACKAGES + [
|
||||
'nova-compute-vmware',
|
||||
'python3-ironicclient'
|
||||
]
|
||||
self.assertTrue(ex.sort() == result.sort())
|
||||
|
||||
@patch.object(utils, 'nova_metadata_requirement')
|
||||
@patch.object(utils, 'network_manager')
|
||||
@patch('platform.machine')
|
||||
@ -526,6 +551,28 @@ class NovaComputeUtilsTests(CharmTestCase):
|
||||
result = utils.resource_map()['/etc/nova/nova.conf']['services']
|
||||
self.assertTrue('nova-api-metadata' in result)
|
||||
|
||||
@patch.object(utils, 'nova_metadata_requirement')
|
||||
def test_resource_map_ironic_pre_victoria(self, _metadata):
|
||||
_metadata.return_value = (True, None)
|
||||
self.relation_ids.return_value = []
|
||||
self.os_release.return_value = 'train'
|
||||
self.test_config.set('virt-type', 'ironic')
|
||||
result = utils.resource_map()
|
||||
self.assertTrue(utils.NOVA_COMPUTE_CONF in result)
|
||||
self.assertEqual(
|
||||
result[utils.NOVA_COMPUTE_CONF]["services"], ["nova-compute"])
|
||||
self.assertEqual(
|
||||
result[utils.NOVA_COMPUTE_CONF]["contexts"], [])
|
||||
|
||||
@patch.object(utils, 'nova_metadata_requirement')
|
||||
def test_resource_map_ironic(self, _metadata):
|
||||
_metadata.return_value = (True, None)
|
||||
self.relation_ids.return_value = []
|
||||
self.os_release.return_value = 'victoria'
|
||||
self.test_config.set('virt-type', 'ironic')
|
||||
result = utils.resource_map()
|
||||
self.assertTrue(utils.NOVA_COMPUTE_CONF not in result)
|
||||
|
||||
def fake_user(self, username='foo'):
|
||||
user = MagicMock()
|
||||
user.pw_dir = '/home/' + username
|
||||
|
Loading…
x
Reference in New Issue
Block a user