Make hardware types configurable, plus fixes
* Made hardware types configurable. IPMI, redfish and iDrac for now * Removed unnecessary class * Explicitly set python_version to 3 * Add functional tests Change-Id: Id774352487da05faa47dc953031b921df40d3ecc Func-Test-Pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/450
This commit is contained in:
parent
40b09a55e7
commit
9883204a85
|
@ -0,0 +1,4 @@
|
||||||
|
[gerrit]
|
||||||
|
host=review.opendev.org
|
||||||
|
port=29418
|
||||||
|
project=openstack/charm-ironic-conductor.git
|
|
@ -0,0 +1,4 @@
|
||||||
|
- project:
|
||||||
|
templates:
|
||||||
|
- openstack-python3-charm-jobs
|
||||||
|
- openstack-cover-jobs
|
|
@ -159,3 +159,12 @@ options:
|
||||||
|
|
||||||
Note: Automated cleaning can be toggled on a per node basis, via node properties.
|
Note: Automated cleaning can be toggled on a per node basis, via node properties.
|
||||||
Note: node cleaning may take a long time, especially if secure erase is enabled.
|
Note: node cleaning may take a long time, especially if secure erase is enabled.
|
||||||
|
enabled-hw-types:
|
||||||
|
default: "ipmi"
|
||||||
|
type: string
|
||||||
|
description: |
|
||||||
|
Comma separated list of hardware types to enable.
|
||||||
|
Valid options are:
|
||||||
|
* ipmi
|
||||||
|
* redfish
|
||||||
|
* idrac
|
||||||
|
|
|
@ -5,10 +5,10 @@ includes:
|
||||||
- interface:rabbitmq
|
- interface:rabbitmq
|
||||||
- interface:keystone-credentials
|
- interface:keystone-credentials
|
||||||
- interface:ironic-api
|
- interface:ironic-api
|
||||||
repo: https://github.com/gabriel-samfira/charm-ironic-conductor
|
repo: https://opendev.org/openstack/charm-ironic-conductor.git
|
||||||
options:
|
options:
|
||||||
basic:
|
basic:
|
||||||
use_venv: true
|
use_venv: true
|
||||||
include_system_packages: False
|
include_system_packages: False
|
||||||
packages: [ 'libffi-dev', 'libssl-dev', 'libpython3.6-dev' ]
|
packages: [ 'libffi-dev', 'libssl-dev', 'libpython3-dev' ]
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,10 @@ import glanceclient
|
||||||
import swiftclient
|
import swiftclient
|
||||||
import keystoneclient
|
import keystoneclient
|
||||||
|
|
||||||
|
SYSTEM_CA_BUNDLE = '/etc/ssl/certs/ca-certificates.crt'
|
||||||
|
|
||||||
def create_keystone_session(keystone, verify=True):
|
|
||||||
|
def create_keystone_session(keystone):
|
||||||
plugin_name = "password"
|
plugin_name = "password"
|
||||||
username = keystone.credentials_username()
|
username = keystone.credentials_username()
|
||||||
password = keystone.credentials_password()
|
password = keystone.credentials_password()
|
||||||
|
@ -41,17 +43,17 @@ def create_keystone_session(keystone, verify=True):
|
||||||
|
|
||||||
loader = loading.get_plugin_loader(plugin_name)
|
loader = loading.get_plugin_loader(plugin_name)
|
||||||
auth = loader.load_from_options(**plugin_args)
|
auth = loader.load_from_options(**plugin_args)
|
||||||
return ks_session.Session(auth=auth, verify=verify)
|
return ks_session.Session(auth=auth, verify=SYSTEM_CA_BUNDLE)
|
||||||
|
|
||||||
|
|
||||||
class OSClients(object):
|
class OSClients(object):
|
||||||
|
|
||||||
def __init__(self, session, cacert=None):
|
def __init__(self, session):
|
||||||
self._session = session
|
self._session = session
|
||||||
self._img_cli = glanceclient.Client(
|
self._img_cli = glanceclient.Client(
|
||||||
session=self._session, version=2)
|
session=self._session, version=2)
|
||||||
self._obj_cli = swiftclient.Connection(
|
self._obj_cli = swiftclient.Connection(
|
||||||
session=self._session, cacert=cacert)
|
session=self._session, cacert=SYSTEM_CA_BUNDLE)
|
||||||
self._ks = keystoneclient.v3.Client(
|
self._ks = keystoneclient.v3.Client(
|
||||||
session=session)
|
session=session)
|
||||||
self._stores = None
|
self._stores = None
|
||||||
|
|
|
@ -25,7 +25,7 @@ class PXEBootBase(object):
|
||||||
"/usr/lib/syslinux/modules/bios/chain.c32": "chain.c32",
|
"/usr/lib/syslinux/modules/bios/chain.c32": "chain.c32",
|
||||||
"/usr/lib/syslinux/modules/bios/ldlinux.c32": "ldlinux.c32",
|
"/usr/lib/syslinux/modules/bios/ldlinux.c32": "ldlinux.c32",
|
||||||
"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed": "grubx64.efi",
|
"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed": "grubx64.efi",
|
||||||
"/usr/lib/shim/shim.efi.signed": "bootx64.efi",
|
"/usr/lib/shim/shimx64.efi.signed": "bootx64.efi",
|
||||||
"/usr/lib/ipxe/undionly.kpxe": "undionly.kpxe",
|
"/usr/lib/ipxe/undionly.kpxe": "undionly.kpxe",
|
||||||
"/usr/lib/ipxe/ipxe.efi": "ipxe.efi",
|
"/usr/lib/ipxe/ipxe.efi": "ipxe.efi",
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ class PXEBootBase(object):
|
||||||
for f in self.FILE_MAP:
|
for f in self.FILE_MAP:
|
||||||
if os.path.isfile(f) is False:
|
if os.path.isfile(f) is False:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"Missing required file %s. Package not installes?" % f)
|
"Missing required file %s. Package not installed?" % f)
|
||||||
shutil.copy(
|
shutil.copy(
|
||||||
f, os.path.join(self.TFTP_ROOT, self.FILE_MAP[f]),
|
f, os.path.join(self.TFTP_ROOT, self.FILE_MAP[f]),
|
||||||
follow_symlinks=True)
|
follow_symlinks=True)
|
||||||
|
@ -88,27 +88,9 @@ class PXEBootBase(object):
|
||||||
self.HTTP_ROOT, _IRONIC_USER, _IRONIC_GROUP, chowntopdir=True)
|
self.HTTP_ROOT, _IRONIC_USER, _IRONIC_GROUP, chowntopdir=True)
|
||||||
|
|
||||||
|
|
||||||
class PXEBootBionic(PXEBootBase):
|
|
||||||
|
|
||||||
# This is a file map of source to destination. The destination is
|
|
||||||
# relative to self.TFTP_ROOT
|
|
||||||
FILE_MAP = {
|
|
||||||
"/usr/lib/PXELINUX/pxelinux.0": "pxelinux.0",
|
|
||||||
"/usr/lib/syslinux/modules/bios/chain.c32": "chain.c32",
|
|
||||||
"/usr/lib/syslinux/modules/bios/ldlinux.c32": "ldlinux.c32",
|
|
||||||
"/usr/lib/grub/x86_64-efi-signed/grubnetx64.efi.signed": "grubx64.efi",
|
|
||||||
"/usr/lib/shim/shimx64.efi.signed": "bootx64.efi",
|
|
||||||
"/usr/lib/ipxe/undionly.kpxe": "undionly.kpxe",
|
|
||||||
"/usr/lib/ipxe/ipxe.efi": "ipxe.efi",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def get_pxe_config_class(charm_config):
|
def get_pxe_config_class(charm_config):
|
||||||
# We may need to make slight adjustments to package names and/or
|
# We may need to make slight adjustments to package names and/or
|
||||||
# configuration files, based on the version of Ubuntu we are installing
|
# configuration files, based on the version of Ubuntu we are installing
|
||||||
# on. This function serves as a factory which will return an instance
|
# on. This function serves as a factory which will return an instance
|
||||||
# of the proper class to the charm. For now we only have one class.
|
# of the proper class to the charm. For now we only have one class.
|
||||||
series = ch_host.get_distrib_codename()
|
|
||||||
if series == "bionic":
|
|
||||||
return PXEBootBionic(charm_config)
|
|
||||||
return PXEBootBase(charm_config)
|
return PXEBootBase(charm_config)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from charms_openstack.adapters import (
|
||||||
DatabaseRelationAdapter,
|
DatabaseRelationAdapter,
|
||||||
OpenStackRelationAdapters,
|
OpenStackRelationAdapters,
|
||||||
)
|
)
|
||||||
|
from charmhelpers.contrib.openstack.utils import os_release
|
||||||
|
|
||||||
import charm.openstack.ironic.controller_utils as controller_utils
|
import charm.openstack.ironic.controller_utils as controller_utils
|
||||||
import charms_openstack.adapters as adapters
|
import charms_openstack.adapters as adapters
|
||||||
|
@ -19,15 +20,14 @@ import charms.reactive as reactive
|
||||||
|
|
||||||
PACKAGES = [
|
PACKAGES = [
|
||||||
'ironic-conductor',
|
'ironic-conductor',
|
||||||
|
'python3-dracclient',
|
||||||
'python3-keystoneauth1',
|
'python3-keystoneauth1',
|
||||||
'python3-keystoneclient',
|
'python3-keystoneclient',
|
||||||
'python3-glanceclient',
|
'python3-glanceclient',
|
||||||
'python3-swiftclient',
|
|
||||||
'python-mysqldb',
|
|
||||||
'python3-dracclient',
|
|
||||||
'python3-sushy',
|
'python3-sushy',
|
||||||
|
'python3-swiftclient',
|
||||||
|
'python3-mysqldb',
|
||||||
'python3-ironicclient',
|
'python3-ironicclient',
|
||||||
'python3-scciclient',
|
|
||||||
'shellinabox',
|
'shellinabox',
|
||||||
'openssl',
|
'openssl',
|
||||||
'socat',
|
'socat',
|
||||||
|
@ -50,6 +50,100 @@ VALID_DEPLOY_INTERFACES = ["direct", "iscsi"]
|
||||||
DEFAULT_DEPLOY_IFACE = "flat"
|
DEFAULT_DEPLOY_IFACE = "flat"
|
||||||
DEFAULT_NET_IFACE = "direct"
|
DEFAULT_NET_IFACE = "direct"
|
||||||
|
|
||||||
|
# The IPMI HW type requires only ipmitool to function. This HW type
|
||||||
|
# remains pretty much unchanged across OpenStack releases and *should*
|
||||||
|
# work
|
||||||
|
_NOOP_INTERFACES = {
|
||||||
|
'enabled_bios_interfaces': 'no-bios',
|
||||||
|
'enabled_management_interfaces': 'noop',
|
||||||
|
'enabled_inspect_interfaces': 'no-inspect',
|
||||||
|
'enabled_console_interfaces': 'no-console',
|
||||||
|
'enabled_raid_interfaces': 'no-raid',
|
||||||
|
'enabled_vendor_interfaces': 'no-vendor',
|
||||||
|
}
|
||||||
|
_IPMI_HARDWARE_TYPE = {
|
||||||
|
'needed_packages': ['ipmitool', 'shellinabox', 'socat'],
|
||||||
|
'config_options': {
|
||||||
|
'enabled_hardware_types': ['ipmi', 'intel-ipmi'],
|
||||||
|
'enabled_management_interfaces': [
|
||||||
|
'ipmitool', 'intel-ipmitool'],
|
||||||
|
'enabled_inspect_interfaces': [],
|
||||||
|
'enabled_power_interfaces': ['ipmitool'],
|
||||||
|
'enabled_console_interfaces': [
|
||||||
|
'ipmitool-socat',
|
||||||
|
'ipmitool-shellinabox'],
|
||||||
|
'enabled_raid_interfaces': [],
|
||||||
|
'enabled_vendor_interfaces': ['ipmitool'],
|
||||||
|
'enabled_boot_interfaces': ['pxe'],
|
||||||
|
'enabled_bios_interfaces': []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_HW_TYPES_MAP = collections.OrderedDict([
|
||||||
|
('train', {
|
||||||
|
'ipmi': _IPMI_HARDWARE_TYPE,
|
||||||
|
'redfish': {
|
||||||
|
'needed_packages': ['python3-sushy'],
|
||||||
|
'config_options': {
|
||||||
|
'enabled_hardware_types': ['redfish'],
|
||||||
|
'enabled_management_interfaces': ['redfish'],
|
||||||
|
'enabled_inspect_interfaces': ['redfish'],
|
||||||
|
'enabled_power_interfaces': ['redfish'],
|
||||||
|
'enabled_console_interfaces': [],
|
||||||
|
'enabled_raid_interfaces': [],
|
||||||
|
'enabled_vendor_interfaces': [],
|
||||||
|
'enabled_boot_interfaces': ['pxe'],
|
||||||
|
'enabled_bios_interfaces': []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'idrac': {
|
||||||
|
'needed_packages': ['python-dracclient', 'python3-sushy'],
|
||||||
|
'config_options': {
|
||||||
|
'enabled_hardware_types': ['idrac'],
|
||||||
|
'enabled_management_interfaces': ['idrac-redfish'],
|
||||||
|
'enabled_inspect_interfaces': ['idrac-redfish'],
|
||||||
|
'enabled_power_interfaces': ['idrac-redfish'],
|
||||||
|
'enabled_console_interfaces': [],
|
||||||
|
'enabled_raid_interfaces': ['idrac-wsman'],
|
||||||
|
'enabled_vendor_interfaces': ['idrac-wsman'],
|
||||||
|
'enabled_boot_interfaces': ['pxe'],
|
||||||
|
'enabled_bios_interfaces': []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
('ussuri', {
|
||||||
|
'ipmi': _IPMI_HARDWARE_TYPE,
|
||||||
|
'redfish': {
|
||||||
|
'needed_packages': ['python3-sushy'],
|
||||||
|
'config_options': {
|
||||||
|
'enabled_hardware_types': ['redfish'],
|
||||||
|
'enabled_management_interfaces': ['redfish'],
|
||||||
|
'enabled_inspect_interfaces': ['redfish'],
|
||||||
|
'enabled_power_interfaces': ['redfish'],
|
||||||
|
'enabled_console_interfaces': [],
|
||||||
|
'enabled_raid_interfaces': [],
|
||||||
|
'enabled_vendor_interfaces': [],
|
||||||
|
'enabled_boot_interfaces': ['pxe', 'redfish-virtual-media'],
|
||||||
|
'enabled_bios_interfaces': [],
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'idrac': {
|
||||||
|
'needed_packages': ['python-dracclient', 'python3-sushy'],
|
||||||
|
'config_options': {
|
||||||
|
'enabled_hardware_types': ['idrac'],
|
||||||
|
'enabled_management_interfaces': ['idrac-redfish'],
|
||||||
|
'enabled_inspect_interfaces': ['idrac-redfish'],
|
||||||
|
'enabled_power_interfaces': ['idrac-redfish'],
|
||||||
|
'enabled_console_interfaces': [],
|
||||||
|
'enabled_raid_interfaces': ['idrac-wsman'],
|
||||||
|
'enabled_vendor_interfaces': ['idrac-wsman'],
|
||||||
|
'enabled_boot_interfaces': ['pxe'],
|
||||||
|
'enabled_bios_interfaces': ['idrac-wsman']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
])
|
||||||
|
|
||||||
OPENSTACK_RELEASE_KEY = 'ironic-charm.openstack-release-version'
|
OPENSTACK_RELEASE_KEY = 'ironic-charm.openstack-release-version'
|
||||||
|
|
||||||
|
|
||||||
|
@ -89,6 +183,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
release = 'train'
|
release = 'train'
|
||||||
name = 'ironic'
|
name = 'ironic'
|
||||||
packages = PACKAGES
|
packages = PACKAGES
|
||||||
|
python_version = 3
|
||||||
|
|
||||||
service_type = 'ironic'
|
service_type = 'ironic'
|
||||||
default_service = 'ironic-conductor'
|
default_service = 'ironic-conductor'
|
||||||
|
@ -127,6 +222,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
self.pxe_config = controller_utils.get_pxe_config_class(
|
self.pxe_config = controller_utils.get_pxe_config_class(
|
||||||
self.config)
|
self.config)
|
||||||
self._setup_pxe_config(self.pxe_config)
|
self._setup_pxe_config(self.pxe_config)
|
||||||
|
self._setup_power_adapter_config()
|
||||||
self._configure_defaults()
|
self._configure_defaults()
|
||||||
if "neutron" in self.enabled_network_interfaces:
|
if "neutron" in self.enabled_network_interfaces:
|
||||||
self.mandatory_config.extend([
|
self.mandatory_config.extend([
|
||||||
|
@ -141,6 +237,65 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
if not iface:
|
if not iface:
|
||||||
self.config["default-deploy-interface"] = DEFAULT_DEPLOY_IFACE
|
self.config["default-deploy-interface"] = DEFAULT_DEPLOY_IFACE
|
||||||
|
|
||||||
|
def _get_hw_type_map(self):
|
||||||
|
release = os_release(self.release_pkg)
|
||||||
|
supported = list(_HW_TYPES_MAP.keys())
|
||||||
|
latest = supported[-1]
|
||||||
|
hw_type_map = _HW_TYPES_MAP.get(
|
||||||
|
release, _HW_TYPES_MAP[latest])
|
||||||
|
return hw_type_map
|
||||||
|
|
||||||
|
def _get_power_adapter_packages(self):
|
||||||
|
pkgs = []
|
||||||
|
hw_type_map = self._get_hw_type_map()
|
||||||
|
for hw_type in self.enabled_hw_types:
|
||||||
|
needed_pkgs = hw_type_map.get(
|
||||||
|
hw_type, {}).get("needed_packages", [])
|
||||||
|
pkgs.extend(needed_pkgs)
|
||||||
|
return list(set(pkgs))
|
||||||
|
|
||||||
|
def _get_hardware_types_config(self):
|
||||||
|
hw_type_map = self._get_hw_type_map()
|
||||||
|
configs = {}
|
||||||
|
for hw_type in self.enabled_hw_types:
|
||||||
|
details = hw_type_map.get(hw_type, None)
|
||||||
|
if details is None:
|
||||||
|
# Not a valid hardware type. No need to raise here,
|
||||||
|
# we will let the operator know when we validate the
|
||||||
|
# config in custom_assess_status_check()
|
||||||
|
continue
|
||||||
|
driver_cfg = details['config_options']
|
||||||
|
for cfg_opt in driver_cfg.items():
|
||||||
|
if not configs.get(cfg_opt[0], None):
|
||||||
|
configs[cfg_opt[0]] = cfg_opt[1]
|
||||||
|
else:
|
||||||
|
configs[cfg_opt[0]].extend(cfg_opt[1])
|
||||||
|
opt_list = list(set(configs[cfg_opt[0]]))
|
||||||
|
opt_list.sort()
|
||||||
|
configs[cfg_opt[0]] = opt_list
|
||||||
|
|
||||||
|
if self.config.get('use-ipxe', None):
|
||||||
|
configs["enabled_boot_interfaces"].append('ipxe')
|
||||||
|
|
||||||
|
# append the noop interfaces at the end
|
||||||
|
for noop in _NOOP_INTERFACES:
|
||||||
|
if configs.get(noop, None) is not None:
|
||||||
|
configs[noop].append(_NOOP_INTERFACES[noop])
|
||||||
|
|
||||||
|
for opt in configs:
|
||||||
|
if len(configs[opt]) > 0:
|
||||||
|
configs[opt] = ", ".join(configs[opt])
|
||||||
|
else:
|
||||||
|
configs[opt] = ""
|
||||||
|
return configs
|
||||||
|
|
||||||
|
def _setup_power_adapter_config(self):
|
||||||
|
pkgs = self._get_power_adapter_packages()
|
||||||
|
config = self._get_hardware_types_config()
|
||||||
|
self.packages.extend(pkgs)
|
||||||
|
self.packages = list(set(self.packages))
|
||||||
|
self.config["hardware_type_cfg"] = config
|
||||||
|
|
||||||
def _setup_pxe_config(self, cfg):
|
def _setup_pxe_config(self, cfg):
|
||||||
self.packages.extend(cfg.determine_packages())
|
self.packages.extend(cfg.determine_packages())
|
||||||
self.packages = list(set(self.packages))
|
self.packages = list(set(self.packages))
|
||||||
|
@ -178,7 +333,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
if interface not in valid_interfaces:
|
if interface not in valid_interfaces:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Network interface "%s" is not valid. Valid '
|
'Network interface %s is not valid. Valid '
|
||||||
'interfaces are: %s' % (
|
'interfaces are: %s' % (
|
||||||
interface, ", ".join(valid_interfaces)))
|
interface, ", ".join(valid_interfaces)))
|
||||||
|
|
||||||
|
@ -197,14 +352,14 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
if interface not in valid_interfaces:
|
if interface not in valid_interfaces:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'Deploy interface "%s" is not valid. Valid '
|
'Deploy interface %s is not valid. Valid '
|
||||||
'interfaces are: %s' % (
|
'interfaces are: %s' % (
|
||||||
interface, ", ".join(valid_interfaces)))
|
interface, ", ".join(valid_interfaces)))
|
||||||
if reactive.is_flag_set("config.complete"):
|
if reactive.is_flag_set("config.complete"):
|
||||||
if "direct" in interfaces and has_secret is False:
|
if "direct" in interfaces and has_secret is False:
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
'run "set-temp-url-secret" action on leader to '
|
'run set-temp-url-secret action on leader to '
|
||||||
'enable "direct" deploy method')
|
'enable direct deploy method')
|
||||||
|
|
||||||
def _validate_default_deploy_interface(self):
|
def _validate_default_deploy_interface(self):
|
||||||
iface = self.config["default-deploy-interface"]
|
iface = self.config["default-deploy-interface"]
|
||||||
|
@ -215,12 +370,29 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
iface, ", ".join(
|
iface, ", ".join(
|
||||||
self.enabled_deploy_interfaces)))
|
self.enabled_deploy_interfaces)))
|
||||||
|
|
||||||
|
def _validate_enabled_hw_type(self):
|
||||||
|
hw_types = self._get_hw_type_map()
|
||||||
|
unsupported = []
|
||||||
|
for hw_type in self.enabled_hw_types:
|
||||||
|
if hw_types.get(hw_type, None) is None:
|
||||||
|
unsupported.append(hw_type)
|
||||||
|
if len(unsupported) > 0:
|
||||||
|
raise ValueError(
|
||||||
|
'hardware type(s) %s not supported at '
|
||||||
|
'this time' % ", ".join(unsupported))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enabled_network_interfaces(self):
|
def enabled_network_interfaces(self):
|
||||||
network_interfaces = self.config.get(
|
network_interfaces = self.config.get(
|
||||||
'enabled-network-interfaces', "").replace(" ", "")
|
'enabled-network-interfaces', "").replace(" ", "")
|
||||||
return network_interfaces.split(",")
|
return network_interfaces.split(",")
|
||||||
|
|
||||||
|
@property
|
||||||
|
def enabled_hw_types(self):
|
||||||
|
hw_types = self.config.get(
|
||||||
|
'enabled-hw-types', "ipmi").replace(" ", "")
|
||||||
|
return hw_types.split(",")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def enabled_deploy_interfaces(self):
|
def enabled_deploy_interfaces(self):
|
||||||
network_interfaces = self.config.get(
|
network_interfaces = self.config.get(
|
||||||
|
@ -231,25 +403,32 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
|
||||||
try:
|
try:
|
||||||
self._validate_network_interfaces(self.enabled_network_interfaces)
|
self._validate_network_interfaces(self.enabled_network_interfaces)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
msg = ("invalid enabled-network-interfaces config: %s" % err)
|
msg = ("invalid enabled-network-interfaces config, %s" % err)
|
||||||
return ('blocked', msg)
|
return ('blocked', msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._validate_default_net_interface()
|
self._validate_default_net_interface()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
msg = ("invalid default-network-interface config: %s" % err)
|
msg = ("invalid default-network-interface config, %s" % err)
|
||||||
return ('blocked', msg)
|
return ('blocked', msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._validate_deploy_interfaces(
|
self._validate_deploy_interfaces(
|
||||||
self.enabled_deploy_interfaces)
|
self.enabled_deploy_interfaces)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
msg = ("invalid enabled-deploy-interfaces config: %s" % err)
|
msg = ("invalid enabled-deploy-interfaces config, %s" % err)
|
||||||
return ('blocked', msg)
|
return ('blocked', msg)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._validate_default_deploy_interface()
|
self._validate_default_deploy_interface()
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
msg = ("invalid default-deploy-interface config: %s" % err)
|
msg = ("invalid default-deploy-interface config, %s" % err)
|
||||||
return ('blocked', msg)
|
return ('blocked', msg)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self._validate_enabled_hw_type()
|
||||||
|
except Exception as err:
|
||||||
|
msg = ("invalid enabled-hw-types config, %s" % err)
|
||||||
|
return ('blocked', msg)
|
||||||
|
|
||||||
return (None, None)
|
return (None, None)
|
||||||
|
|
|
@ -5,20 +5,21 @@ auth_strategy=keystone
|
||||||
my_ip = {{ options.internal_interface_ip }}
|
my_ip = {{ options.internal_interface_ip }}
|
||||||
|
|
||||||
enabled_deploy_interfaces = {{ options.enabled_deploy_interfaces }}
|
enabled_deploy_interfaces = {{ options.enabled_deploy_interfaces }}
|
||||||
enabled_hardware_types = ipmi,ilo,idrac,redfish,irmc
|
enabled_hardware_types = {{ options.hardware_type_cfg.enabled_hardware_types }}
|
||||||
{% if options.use_ipxe -%}
|
enabled_boot_interfaces = {{ options.hardware_type_cfg.enabled_boot_interfaces }}
|
||||||
enabled_boot_interfaces = pxe,ipxe,ilo-pxe,ilo-ipxe,irmc-pxe
|
|
||||||
{% else -%}
|
enabled_management_interfaces = {{ options.hardware_type_cfg.enabled_management_interfaces }}
|
||||||
enabled_boot_interfaces = pxe,ilo-pxe,irmc-pxe
|
enabled_inspect_interfaces = {{ options.hardware_type_cfg.enabled_inspect_interfaces }}
|
||||||
{% endif -%}
|
|
||||||
enabled_management_interfaces = ipmitool,redfish,ilo,irmc,idrac,noop
|
|
||||||
enabled_inspect_interfaces = idrac,ilo,irmc,redfish,no-inspect
|
|
||||||
enabled_network_interfaces = {{ options.enabled_network_interfaces }}
|
enabled_network_interfaces = {{ options.enabled_network_interfaces }}
|
||||||
enabled_power_interfaces = ipmitool,redfish,ilo,irmc,idrac
|
|
||||||
|
enabled_power_interfaces = {{ options.hardware_type_cfg.enabled_power_interfaces }}
|
||||||
enabled_storage_interfaces = cinder,noop
|
enabled_storage_interfaces = cinder,noop
|
||||||
enabled_console_interfaces = ipmitool-socat,ipmitool-shellinabox,no-console
|
|
||||||
enabled_raid_interfaces = agent,idrac,irmc,no-raid
|
enabled_console_interfaces = {{ options.hardware_type_cfg.enabled_console_interfaces }}
|
||||||
enabled_vendor_interfaces = ipmitool,idrac,ilo,no-vendor
|
enabled_raid_interfaces = {{ options.hardware_type_cfg.enabled_raid_interfaces }}
|
||||||
|
enabled_vendor_interfaces = {{ options.hardware_type_cfg.enabled_vendor_interfaces }}
|
||||||
|
enabled_bios_interfaces = {{ options.hardware_type_cfg.enabled_bios_interfaces }}
|
||||||
|
|
||||||
default_deploy_interface = {{ options.default_deploy_interface }}
|
default_deploy_interface = {{ options.default_deploy_interface }}
|
||||||
default_network_interface = {{ options.default_network_interface }}
|
default_network_interface = {{ options.default_network_interface }}
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
sudo add-apt-repository ppa:juju/stable -y
|
|
||||||
sudo apt-get update
|
|
||||||
sudo apt-get install amulet python-requests -y
|
|
|
@ -1,35 +0,0 @@
|
||||||
#!/usr/bin/python3
|
|
||||||
|
|
||||||
import amulet
|
|
||||||
import requests
|
|
||||||
import unittest
|
|
||||||
|
|
||||||
|
|
||||||
class TestCharm(unittest.TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.d = amulet.Deployment()
|
|
||||||
|
|
||||||
self.d.add('charm-ironic')
|
|
||||||
self.d.expose('charm-ironic')
|
|
||||||
|
|
||||||
self.d.setup(timeout=900)
|
|
||||||
self.d.sentry.wait()
|
|
||||||
|
|
||||||
self.unit = self.d.sentry['charm-ironic'][0]
|
|
||||||
|
|
||||||
def test_service(self):
|
|
||||||
# test we can access over http
|
|
||||||
page = requests.get('http://{}'.format(self.unit.info['public-address']))
|
|
||||||
self.assertEqual(page.status_code, 200)
|
|
||||||
# Now you can use self.d.sentry[SERVICE][UNIT] to address each of the units and perform
|
|
||||||
# more in-depth steps. Each self.d.sentry[SERVICE][UNIT] has the following methods:
|
|
||||||
# - .info - An array of the information of that unit from Juju
|
|
||||||
# - .file(PATH) - Get the details of a file on that unit
|
|
||||||
# - .file_contents(PATH) - Get plain text output of PATH file from that unit
|
|
||||||
# - .directory(PATH) - Get details of directory
|
|
||||||
# - .directory_contents(PATH) - List files and folders in PATH on that unit
|
|
||||||
# - .relation(relation, service:rel) - Get relation data from return service
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
unittest.main()
|
|
|
@ -0,0 +1,250 @@
|
||||||
|
options:
|
||||||
|
source: &source cloud:bionic-train/proposed
|
||||||
|
series: bionic
|
||||||
|
local_overlay_enabled: false
|
||||||
|
relations:
|
||||||
|
- - nova-ironic
|
||||||
|
- ironic-api
|
||||||
|
- - ironic-conductor
|
||||||
|
- ironic-api
|
||||||
|
- - neutron-ironic-agent:identity-credentials
|
||||||
|
- keystone
|
||||||
|
- - neutron-ironic-agent
|
||||||
|
- neutron-api
|
||||||
|
- - neutron-openvswitch
|
||||||
|
- neutron-api
|
||||||
|
- - ironic-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-api
|
||||||
|
- keystone
|
||||||
|
- - ironic-api:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - ironic-conductor:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-conductor
|
||||||
|
- keystone
|
||||||
|
- - ironic-conductor:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - nova-ironic:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-ironic
|
||||||
|
- glance
|
||||||
|
- - nova-ironic
|
||||||
|
- keystone
|
||||||
|
- - nova-ironic
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - neutron-gateway:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - keystone:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - nova-cloud-controller:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - glance:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - neutron-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - neutron-gateway:neutron-plugin-api
|
||||||
|
- neutron-api:neutron-plugin-api
|
||||||
|
- - glance:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - glance:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - nova-cloud-controller:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:quantum-network-service
|
||||||
|
- neutron-gateway:quantum-network-service
|
||||||
|
- - nova-cloud-controller:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - nova-cloud-controller:neutron-api
|
||||||
|
- neutron-api:neutron-api
|
||||||
|
- - cinder:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - cinder:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - cinder:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - cinder:cinder-volume-service
|
||||||
|
- nova-cloud-controller:cinder-volume-service
|
||||||
|
- - cinder:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - placement
|
||||||
|
- mysql
|
||||||
|
- - placement
|
||||||
|
- keystone
|
||||||
|
- - placement
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - ceph-mon:client
|
||||||
|
- nova-ironic:ceph
|
||||||
|
- - ceph-mon:client
|
||||||
|
- glance:ceph
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:object-store
|
||||||
|
- glance
|
||||||
|
- - vault:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - vault:certificates
|
||||||
|
- ceph-radosgw
|
||||||
|
- - vault:certificates
|
||||||
|
- cinder
|
||||||
|
- - vault:certificates
|
||||||
|
- glance:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- keystone:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- neutron-api:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- nova-cloud-controller:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- placement:certificates
|
||||||
|
- - vault
|
||||||
|
- ironic-conductor
|
||||||
|
- - vault:certificates
|
||||||
|
- ironic-api:certificates
|
||||||
|
- - ironic-api
|
||||||
|
- hacluster-ironic
|
||||||
|
services:
|
||||||
|
cinder:
|
||||||
|
charm: cs:~openstack-charmers-next/cinder
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
block-device: vdb
|
||||||
|
glance-api-version: 2
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
storage:
|
||||||
|
block-devices: cinder,50G
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
expected-osd-count: 3
|
||||||
|
source: *source
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,30G'
|
||||||
|
glance:
|
||||||
|
charm: cs:~openstack-charmers-next/glance
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
keystone:
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
mysql:
|
||||||
|
charm: cs:percona-cluster
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=4G
|
||||||
|
options:
|
||||||
|
innodb-buffer-pool-size: 256M
|
||||||
|
max-connections: 1000
|
||||||
|
performance-schema: true
|
||||||
|
neutron-api:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
flat-network-providers: "physnet1"
|
||||||
|
neutron-security-groups: true
|
||||||
|
openstack-origin: *source
|
||||||
|
manage-neutron-plugin-legacy-mode: false
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
neutron-gateway:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
enable-isolated-metadata: true
|
||||||
|
enable-metadata-network: true
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
nova-cloud-controller:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
network-manager: Neutron
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
nova-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-compute
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
enable-live-migration: false
|
||||||
|
enable-resize: false
|
||||||
|
openstack-origin: *source
|
||||||
|
virt-type: ironic
|
||||||
|
placement:
|
||||||
|
charm: cs:placement
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
rabbitmq-server:
|
||||||
|
charm: cs:rabbitmq-server
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
hacluster-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/hacluster
|
||||||
|
num_units: 0
|
||||||
|
ironic-api:
|
||||||
|
charm: cs:~openstack-charmers-next/ironic-api
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
ironic-conductor:
|
||||||
|
charm: ../../../ironic-conductor
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
max-tftp-block-size: 1418
|
||||||
|
disable-secure-erase: true
|
||||||
|
use-ipxe: true
|
||||||
|
enabled-network-interfaces: "flat, noop"
|
||||||
|
neutron-openvswitch:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
neutron-ironic-agent:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
vault:
|
||||||
|
charm: cs:~openstack-charmers-next/vault
|
||||||
|
num_units: 1
|
|
@ -0,0 +1,250 @@
|
||||||
|
options:
|
||||||
|
source: &source cloud:bionic-ussuri/proposed
|
||||||
|
series: bionic
|
||||||
|
local_overlay_enabled: false
|
||||||
|
relations:
|
||||||
|
- - nova-ironic
|
||||||
|
- ironic-api
|
||||||
|
- - ironic-conductor
|
||||||
|
- ironic-api
|
||||||
|
- - neutron-ironic-agent:identity-credentials
|
||||||
|
- keystone
|
||||||
|
- - neutron-ironic-agent
|
||||||
|
- neutron-api
|
||||||
|
- - neutron-openvswitch
|
||||||
|
- neutron-api
|
||||||
|
- - ironic-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-api
|
||||||
|
- keystone
|
||||||
|
- - ironic-api:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - ironic-conductor:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-conductor
|
||||||
|
- keystone
|
||||||
|
- - ironic-conductor:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - nova-ironic:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-ironic
|
||||||
|
- glance
|
||||||
|
- - nova-ironic
|
||||||
|
- keystone
|
||||||
|
- - nova-ironic
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - neutron-gateway:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - keystone:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - nova-cloud-controller:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - glance:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - neutron-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - neutron-gateway:neutron-plugin-api
|
||||||
|
- neutron-api:neutron-plugin-api
|
||||||
|
- - glance:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - glance:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - nova-cloud-controller:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:quantum-network-service
|
||||||
|
- neutron-gateway:quantum-network-service
|
||||||
|
- - nova-cloud-controller:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - nova-cloud-controller:neutron-api
|
||||||
|
- neutron-api:neutron-api
|
||||||
|
- - cinder:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - cinder:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - cinder:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - cinder:cinder-volume-service
|
||||||
|
- nova-cloud-controller:cinder-volume-service
|
||||||
|
- - cinder:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - placement
|
||||||
|
- mysql
|
||||||
|
- - placement
|
||||||
|
- keystone
|
||||||
|
- - placement
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - ceph-mon:client
|
||||||
|
- nova-ironic:ceph
|
||||||
|
- - ceph-mon:client
|
||||||
|
- glance:ceph
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:object-store
|
||||||
|
- glance
|
||||||
|
- - vault:shared-db
|
||||||
|
- mysql:shared-db
|
||||||
|
- - vault:certificates
|
||||||
|
- ceph-radosgw
|
||||||
|
- - vault:certificates
|
||||||
|
- cinder
|
||||||
|
- - vault:certificates
|
||||||
|
- glance:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- keystone:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- neutron-api:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- nova-cloud-controller:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- placement:certificates
|
||||||
|
- - vault
|
||||||
|
- ironic-conductor
|
||||||
|
- - vault:certificates
|
||||||
|
- ironic-api:certificates
|
||||||
|
- - ironic-api
|
||||||
|
- hacluster-ironic
|
||||||
|
services:
|
||||||
|
cinder:
|
||||||
|
charm: cs:~openstack-charmers-next/cinder
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
block-device: vdb
|
||||||
|
glance-api-version: 2
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
storage:
|
||||||
|
block-devices: cinder,50G
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
expected-osd-count: 3
|
||||||
|
source: *source
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,30G'
|
||||||
|
glance:
|
||||||
|
charm: cs:~openstack-charmers-next/glance
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
keystone:
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
mysql:
|
||||||
|
charm: cs:percona-cluster
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=4G
|
||||||
|
options:
|
||||||
|
innodb-buffer-pool-size: 256M
|
||||||
|
max-connections: 1000
|
||||||
|
performance-schema: true
|
||||||
|
hacluster-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/hacluster
|
||||||
|
num_units: 0
|
||||||
|
neutron-api:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
flat-network-providers: "physnet1"
|
||||||
|
neutron-security-groups: true
|
||||||
|
openstack-origin: *source
|
||||||
|
manage-neutron-plugin-legacy-mode: false
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
neutron-gateway:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
enable-isolated-metadata: true
|
||||||
|
enable-metadata-network: true
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
nova-cloud-controller:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
network-manager: Neutron
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
nova-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-compute
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
enable-live-migration: false
|
||||||
|
enable-resize: false
|
||||||
|
openstack-origin: *source
|
||||||
|
virt-type: ironic
|
||||||
|
placement:
|
||||||
|
charm: cs:placement
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
rabbitmq-server:
|
||||||
|
charm: cs:rabbitmq-server
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
ironic-api:
|
||||||
|
charm: cs:~openstack-charmers-next/ironic-api
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
ironic-conductor:
|
||||||
|
charm: ../../../ironic-conductor
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
max-tftp-block-size: 1418
|
||||||
|
disable-secure-erase: true
|
||||||
|
use-ipxe: true
|
||||||
|
enabled-network-interfaces: "flat, noop"
|
||||||
|
neutron-openvswitch:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
neutron-ironic-agent:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
vault:
|
||||||
|
charm: cs:~openstack-charmers-next/vault
|
||||||
|
num_units: 1
|
|
@ -0,0 +1,284 @@
|
||||||
|
options:
|
||||||
|
source: &source distro
|
||||||
|
series: focal
|
||||||
|
local_overlay_enabled: false
|
||||||
|
relations:
|
||||||
|
- - nova-ironic
|
||||||
|
- ironic-api
|
||||||
|
- - ironic-conductor
|
||||||
|
- ironic-api
|
||||||
|
- - neutron-ironic-agent:identity-credentials
|
||||||
|
- keystone
|
||||||
|
- - neutron-ironic-agent
|
||||||
|
- neutron-api
|
||||||
|
- - neutron-openvswitch
|
||||||
|
- neutron-api
|
||||||
|
- - ironic-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-api
|
||||||
|
- keystone
|
||||||
|
- - ironic-api:shared-db
|
||||||
|
- ironic-api-mysql-router:shared-db
|
||||||
|
- - ironic-conductor:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-conductor
|
||||||
|
- keystone
|
||||||
|
- - ironic-conductor:shared-db
|
||||||
|
- ironic-conductor-mysql-router:shared-db
|
||||||
|
- - nova-ironic:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-ironic
|
||||||
|
- glance
|
||||||
|
- - nova-ironic
|
||||||
|
- keystone
|
||||||
|
- - nova-ironic
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - neutron-gateway:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - keystone:shared-db
|
||||||
|
- keystone-mysql-router:shared-db
|
||||||
|
- - nova-cloud-controller:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - glance:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:shared-db
|
||||||
|
- neutron-api-mysql-router:shared-db
|
||||||
|
- - neutron-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - neutron-gateway:neutron-plugin-api
|
||||||
|
- neutron-api:neutron-plugin-api
|
||||||
|
- - glance:shared-db
|
||||||
|
- glance-mysql-router:shared-db
|
||||||
|
- - glance:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - nova-cloud-controller:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:quantum-network-service
|
||||||
|
- neutron-gateway:quantum-network-service
|
||||||
|
- - nova-cloud-controller:shared-db
|
||||||
|
- nova-cloud-controller-mysql-router:shared-db
|
||||||
|
- - nova-cloud-controller:neutron-api
|
||||||
|
- neutron-api:neutron-api
|
||||||
|
- - cinder:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - cinder:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - cinder:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - cinder:cinder-volume-service
|
||||||
|
- nova-cloud-controller:cinder-volume-service
|
||||||
|
- - cinder:shared-db
|
||||||
|
- cinder-mysql-router:shared-db
|
||||||
|
- - placement:shared-db
|
||||||
|
- placement-mysql-router:shared-db
|
||||||
|
- - placement
|
||||||
|
- keystone
|
||||||
|
- - placement
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - ceph-mon:client
|
||||||
|
- nova-ironic:ceph
|
||||||
|
- - ceph-mon:client
|
||||||
|
- glance:ceph
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:object-store
|
||||||
|
- glance
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- nova-cloud-controller-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- keystone-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- glance-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- neutron-api-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- placement-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- cinder-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- ironic-api-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- ironic-conductor-mysql-router:db-router
|
||||||
|
- - vault-mysql-router:db-router
|
||||||
|
- mysql-innodb-cluster:db-router
|
||||||
|
- - vault:shared-db
|
||||||
|
- vault-mysql-router:shared-db
|
||||||
|
- - vault:certificates
|
||||||
|
- ceph-radosgw
|
||||||
|
- - vault:certificates
|
||||||
|
- cinder
|
||||||
|
- - vault:certificates
|
||||||
|
- glance:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- keystone:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- neutron-api:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- nova-cloud-controller:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- placement:certificates
|
||||||
|
- - vault
|
||||||
|
- ironic-conductor
|
||||||
|
- - vault:certificates
|
||||||
|
- ironic-api:certificates
|
||||||
|
- - ironic-api
|
||||||
|
- hacluster-ironic
|
||||||
|
services:
|
||||||
|
nova-cloud-controller-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
keystone-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
glance-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
neutron-api-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
placement-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
vault-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
cinder-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
ironic-api-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
ironic-conductor-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
mysql-innodb-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=4G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
cinder:
|
||||||
|
charm: cs:~openstack-charmers-next/cinder
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
block-device: vdb
|
||||||
|
glance-api-version: 2
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
storage:
|
||||||
|
block-devices: cinder,50G
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
expected-osd-count: 3
|
||||||
|
source: *source
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,30G'
|
||||||
|
glance:
|
||||||
|
charm: cs:~openstack-charmers-next/glance
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
keystone:
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
neutron-api:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
flat-network-providers: "physnet1"
|
||||||
|
neutron-security-groups: true
|
||||||
|
openstack-origin: *source
|
||||||
|
manage-neutron-plugin-legacy-mode: false
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
neutron-gateway:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
enable-isolated-metadata: true
|
||||||
|
enable-metadata-network: true
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
nova-cloud-controller:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
network-manager: Neutron
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
nova-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-compute
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
enable-live-migration: false
|
||||||
|
enable-resize: false
|
||||||
|
openstack-origin: *source
|
||||||
|
virt-type: ironic
|
||||||
|
placement:
|
||||||
|
charm: cs:placement
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
rabbitmq-server:
|
||||||
|
charm: cs:rabbitmq-server
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
hacluster-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/hacluster
|
||||||
|
num_units: 0
|
||||||
|
ironic-api:
|
||||||
|
charm: cs:~openstack-charmers-next/ironic-api
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
ironic-conductor:
|
||||||
|
charm: ../../../ironic-conductor
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
max-tftp-block-size: 1418
|
||||||
|
disable-secure-erase: true
|
||||||
|
use-ipxe: true
|
||||||
|
enabled-network-interfaces: "flat, noop"
|
||||||
|
neutron-openvswitch:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
neutron-ironic-agent:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
vault:
|
||||||
|
charm: cs:~openstack-charmers-next/vault
|
||||||
|
num_units: 1
|
|
@ -0,0 +1,284 @@
|
||||||
|
options:
|
||||||
|
source: &source cloud:focal-victoria/proposed
|
||||||
|
series: focal
|
||||||
|
local_overlay_enabled: false
|
||||||
|
relations:
|
||||||
|
- - nova-ironic
|
||||||
|
- ironic-api
|
||||||
|
- - ironic-conductor
|
||||||
|
- ironic-api
|
||||||
|
- - neutron-ironic-agent:identity-credentials
|
||||||
|
- keystone
|
||||||
|
- - neutron-ironic-agent
|
||||||
|
- neutron-api
|
||||||
|
- - neutron-openvswitch
|
||||||
|
- neutron-api
|
||||||
|
- - ironic-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-api
|
||||||
|
- keystone
|
||||||
|
- - ironic-api:shared-db
|
||||||
|
- ironic-api-mysql-router:shared-db
|
||||||
|
- - ironic-conductor:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - ironic-conductor
|
||||||
|
- keystone
|
||||||
|
- - ironic-conductor:shared-db
|
||||||
|
- ironic-conductor-mysql-router:shared-db
|
||||||
|
- - nova-ironic:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-ironic
|
||||||
|
- glance
|
||||||
|
- - nova-ironic
|
||||||
|
- keystone
|
||||||
|
- - nova-ironic
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - neutron-gateway:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - keystone:shared-db
|
||||||
|
- keystone-mysql-router:shared-db
|
||||||
|
- - nova-cloud-controller:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - glance:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - neutron-api:shared-db
|
||||||
|
- neutron-api-mysql-router:shared-db
|
||||||
|
- - neutron-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - neutron-gateway:neutron-plugin-api
|
||||||
|
- neutron-api:neutron-plugin-api
|
||||||
|
- - glance:shared-db
|
||||||
|
- glance-mysql-router:shared-db
|
||||||
|
- - glance:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - nova-cloud-controller:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - nova-cloud-controller:quantum-network-service
|
||||||
|
- neutron-gateway:quantum-network-service
|
||||||
|
- - nova-cloud-controller:shared-db
|
||||||
|
- nova-cloud-controller-mysql-router:shared-db
|
||||||
|
- - nova-cloud-controller:neutron-api
|
||||||
|
- neutron-api:neutron-api
|
||||||
|
- - cinder:image-service
|
||||||
|
- glance:image-service
|
||||||
|
- - cinder:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - cinder:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - cinder:cinder-volume-service
|
||||||
|
- nova-cloud-controller:cinder-volume-service
|
||||||
|
- - cinder:shared-db
|
||||||
|
- cinder-mysql-router:shared-db
|
||||||
|
- - placement:shared-db
|
||||||
|
- placement-mysql-router:shared-db
|
||||||
|
- - placement
|
||||||
|
- keystone
|
||||||
|
- - placement
|
||||||
|
- nova-cloud-controller
|
||||||
|
- - ceph-mon:client
|
||||||
|
- nova-ironic:ceph
|
||||||
|
- - ceph-mon:client
|
||||||
|
- glance:ceph
|
||||||
|
- - ceph-radosgw:mon
|
||||||
|
- ceph-mon:radosgw
|
||||||
|
- - ceph-radosgw:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- - ceph-osd:mon
|
||||||
|
- ceph-mon:osd
|
||||||
|
- - ceph-radosgw:object-store
|
||||||
|
- glance
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- nova-cloud-controller-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- keystone-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- glance-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- neutron-api-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- placement-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- cinder-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- ironic-api-mysql-router:db-router
|
||||||
|
- - mysql-innodb-cluster:db-router
|
||||||
|
- ironic-conductor-mysql-router:db-router
|
||||||
|
- - vault-mysql-router:db-router
|
||||||
|
- mysql-innodb-cluster:db-router
|
||||||
|
- - vault:shared-db
|
||||||
|
- vault-mysql-router:shared-db
|
||||||
|
- - vault:certificates
|
||||||
|
- ceph-radosgw
|
||||||
|
- - vault:certificates
|
||||||
|
- cinder
|
||||||
|
- - vault:certificates
|
||||||
|
- glance:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- keystone:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- neutron-api:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- nova-cloud-controller:certificates
|
||||||
|
- - vault:certificates
|
||||||
|
- placement:certificates
|
||||||
|
- - vault
|
||||||
|
- ironic-conductor
|
||||||
|
- - vault:certificates
|
||||||
|
- ironic-api:certificates
|
||||||
|
- - ironic-api
|
||||||
|
- hacluster-ironic
|
||||||
|
services:
|
||||||
|
nova-cloud-controller-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
keystone-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
glance-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
neutron-api-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
placement-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
vault-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
cinder-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
ironic-api-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
ironic-conductor-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
mysql-innodb-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=4G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
cinder:
|
||||||
|
charm: cs:~openstack-charmers-next/cinder
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
block-device: vdb
|
||||||
|
glance-api-version: 2
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
storage:
|
||||||
|
block-devices: cinder,50G
|
||||||
|
ceph-radosgw:
|
||||||
|
charm: cs:~openstack-charmers-next/ceph-radosgw
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
namespace-tenants: True
|
||||||
|
ceph-mon:
|
||||||
|
charm: cs:ceph-mon
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
expected-osd-count: 3
|
||||||
|
source: *source
|
||||||
|
ceph-osd:
|
||||||
|
charm: cs:ceph-osd
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
source: *source
|
||||||
|
storage:
|
||||||
|
osd-devices: 'cinder,30G'
|
||||||
|
glance:
|
||||||
|
charm: cs:~openstack-charmers-next/glance
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
keystone:
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
neutron-api:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
flat-network-providers: "physnet1"
|
||||||
|
neutron-security-groups: true
|
||||||
|
openstack-origin: *source
|
||||||
|
manage-neutron-plugin-legacy-mode: false
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
neutron-gateway:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-gateway
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
enable-isolated-metadata: true
|
||||||
|
enable-metadata-network: true
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
nova-cloud-controller:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-cloud-controller
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
network-manager: Neutron
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
nova-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/nova-compute
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
enable-live-migration: false
|
||||||
|
enable-resize: false
|
||||||
|
openstack-origin: *source
|
||||||
|
virt-type: ironic
|
||||||
|
placement:
|
||||||
|
charm: cs:placement
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
worker-multiplier: 0.25
|
||||||
|
rabbitmq-server:
|
||||||
|
charm: cs:rabbitmq-server
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
hacluster-ironic:
|
||||||
|
charm: cs:~openstack-charmers-next/hacluster
|
||||||
|
num_units: 0
|
||||||
|
ironic-api:
|
||||||
|
charm: cs:~openstack-charmers-next/ironic-api
|
||||||
|
num_units: 3
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
ironic-conductor:
|
||||||
|
charm: ../../../ironic-conductor
|
||||||
|
num_units: 1
|
||||||
|
constraints: mem=2G
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
max-tftp-block-size: 1418
|
||||||
|
disable-secure-erase: true
|
||||||
|
use-ipxe: true
|
||||||
|
enabled-network-interfaces: "flat, noop"
|
||||||
|
neutron-openvswitch:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-openvswitch
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
bridge-mappings: physnet1:br-ex
|
||||||
|
neutron-ironic-agent:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api-plugin-ironic
|
||||||
|
num_units: 0
|
||||||
|
options:
|
||||||
|
openstack-origin: *source
|
||||||
|
vault:
|
||||||
|
charm: cs:~openstack-charmers-next/vault
|
||||||
|
num_units: 1
|
|
@ -0,0 +1 @@
|
||||||
|
ironic.j2
|
|
@ -0,0 +1 @@
|
||||||
|
ironic.j2
|
|
@ -0,0 +1 @@
|
||||||
|
ironic.j2
|
|
@ -0,0 +1 @@
|
||||||
|
ironic.j2
|
|
@ -0,0 +1,4 @@
|
||||||
|
applications:
|
||||||
|
ironic-api:
|
||||||
|
options:
|
||||||
|
vip: '{{ OS_VIP00 }}'
|
|
@ -0,0 +1,29 @@
|
||||||
|
charm_name: ironic-api
|
||||||
|
gate_bundles:
|
||||||
|
- focal-ussuri
|
||||||
|
- bionic-train
|
||||||
|
- bionic-ussuri
|
||||||
|
smoke_bundles:
|
||||||
|
- bionic-ussuri
|
||||||
|
dev_bundles:
|
||||||
|
- focal-victoria
|
||||||
|
target_deploy_status:
|
||||||
|
vault:
|
||||||
|
workload-status: blocked
|
||||||
|
workload-status-message: Vault needs to be initialized
|
||||||
|
ironic-conductor:
|
||||||
|
workload-status: blocked
|
||||||
|
workload-status-message: invalid enabled-deploy-interfaces config
|
||||||
|
configure:
|
||||||
|
- zaza.openstack.charm_tests.vault.setup.auto_initialize
|
||||||
|
- zaza.openstack.charm_tests.ironic.setup.set_temp_url_secret
|
||||||
|
- zaza.openstack.charm_tests.ironic.setup.add_ironic_deployment_image
|
||||||
|
- zaza.openstack.charm_tests.ironic.setup.add_ironic_os_image
|
||||||
|
- zaza.openstack.charm_tests.ironic.setup.create_bm_flavors
|
||||||
|
# Ironic will require a flat network to test the flat network type. Once a proper
|
||||||
|
# testing environment will be available for Ironic, we will need to add the setup
|
||||||
|
# call to create that flat network
|
||||||
|
#- zaza.openstack.charm_tests.neutron.setup.basic_overcloud_network
|
||||||
|
- zaza.openstack.charm_tests.nova.setup.manage_ssh_key
|
||||||
|
tests:
|
||||||
|
- zaza.openstack.charm_tests.ironic.tests.IronicTest
|
|
@ -7,3 +7,4 @@ python-glanceclient
|
||||||
python-swiftclient
|
python-swiftclient
|
||||||
python-keystoneclient
|
python-keystoneclient
|
||||||
zipp < 2.0.0
|
zipp < 2.0.0
|
||||||
|
importlib-metadata>=2.0
|
||||||
|
|
|
@ -45,3 +45,15 @@ sys.modules['charms.reactive.bus'] = charms.reactive.bus
|
||||||
sys.modules['charms.reactive.bus'] = charms.reactive.decorators
|
sys.modules['charms.reactive.bus'] = charms.reactive.decorators
|
||||||
sys.modules['charms.reactive.flags'] = charms.reactive.flags
|
sys.modules['charms.reactive.flags'] = charms.reactive.flags
|
||||||
sys.modules['charms.reactive.relations'] = charms.reactive.relations
|
sys.modules['charms.reactive.relations'] = charms.reactive.relations
|
||||||
|
|
||||||
|
keystoneauth1 = mock.MagicMock()
|
||||||
|
sys.modules['keystoneauth1'] = keystoneauth1
|
||||||
|
|
||||||
|
glanceclient = mock.MagicMock()
|
||||||
|
sys.modules['glanceclient'] = glanceclient
|
||||||
|
|
||||||
|
swiftclient = mock.MagicMock()
|
||||||
|
sys.modules['swiftclient'] = swiftclient
|
||||||
|
|
||||||
|
keystoneclient = mock.MagicMock()
|
||||||
|
sys.modules['keystoneclient'] = keystoneclient
|
||||||
|
|
|
@ -20,6 +20,10 @@ from keystoneauth1 import exceptions as ks_exc
|
||||||
import charm.openstack.ironic.api_utils as api_utils
|
import charm.openstack.ironic.api_utils as api_utils
|
||||||
|
|
||||||
|
|
||||||
|
class _NotFoundException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TestGetKeystoneSession(test_utils.PatchHelper):
|
class TestGetKeystoneSession(test_utils.PatchHelper):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
|
@ -54,7 +58,8 @@ class TestGetKeystoneSession(test_utils.PatchHelper):
|
||||||
|
|
||||||
self.loading.get_plugin_loader.assert_called_with("v3password")
|
self.loading.get_plugin_loader.assert_called_with("v3password")
|
||||||
loader.load_from_options.assert_called_with(**self.ks_expect)
|
loader.load_from_options.assert_called_with(**self.ks_expect)
|
||||||
self.ks_session.Session.assert_called_with(auth=auth, verify=True)
|
self.ks_session.Session.assert_called_with(
|
||||||
|
auth=auth, verify=api_utils.SYSTEM_CA_BUNDLE)
|
||||||
|
|
||||||
def test_create_keystone_session_v2(self):
|
def test_create_keystone_session_v2(self):
|
||||||
self.patch_object(api_utils, 'loading')
|
self.patch_object(api_utils, 'loading')
|
||||||
|
@ -70,7 +75,8 @@ class TestGetKeystoneSession(test_utils.PatchHelper):
|
||||||
|
|
||||||
self.loading.get_plugin_loader.assert_called_with("password")
|
self.loading.get_plugin_loader.assert_called_with("password")
|
||||||
loader.load_from_options.assert_called_with(**self.ks_expect)
|
loader.load_from_options.assert_called_with(**self.ks_expect)
|
||||||
self.ks_session.Session.assert_called_with(auth=auth, verify=True)
|
self.ks_session.Session.assert_called_with(
|
||||||
|
auth=auth, verify=api_utils.SYSTEM_CA_BUNDLE)
|
||||||
|
|
||||||
|
|
||||||
class TestOSClients(test_utils.PatchHelper):
|
class TestOSClients(test_utils.PatchHelper):
|
||||||
|
@ -108,7 +114,8 @@ class TestOSClients(test_utils.PatchHelper):
|
||||||
|
|
||||||
self.target = api_utils.OSClients(self.session)
|
self.target = api_utils.OSClients(self.session)
|
||||||
self.glance_client.assert_called_with(session=self.session, version=2)
|
self.glance_client.assert_called_with(session=self.session, version=2)
|
||||||
self.swift_con.assert_called_with(session=self.session, cacert=None)
|
self.swift_con.assert_called_with(
|
||||||
|
session=self.session, cacert=api_utils.SYSTEM_CA_BUNDLE)
|
||||||
self.ks_client.assert_called_with(session=self.session)
|
self.ks_client.assert_called_with(session=self.session)
|
||||||
|
|
||||||
def test_stores_info(self):
|
def test_stores_info(self):
|
||||||
|
@ -173,6 +180,7 @@ class TestOSClients(test_utils.PatchHelper):
|
||||||
self.assertTrue(result)
|
self.assertTrue(result)
|
||||||
|
|
||||||
def test_does_not_have_service_type(self):
|
def test_does_not_have_service_type(self):
|
||||||
|
ks_exc.http.NotFound = _NotFoundException
|
||||||
self.ks_client.services.find.side_effect = ks_exc.http.NotFound()
|
self.ks_client.services.find.side_effect = ks_exc.http.NotFound()
|
||||||
self.target._ks = self.ks_client
|
self.target._ks = self.ks_client
|
||||||
|
|
||||||
|
|
|
@ -24,16 +24,6 @@ import charm.openstack.ironic.controller_utils as controller_utils
|
||||||
|
|
||||||
class TestGetPXEBootClass(test_utils.PatchHelper):
|
class TestGetPXEBootClass(test_utils.PatchHelper):
|
||||||
|
|
||||||
def test_get_pxe_config_class_bionic(self):
|
|
||||||
self.patch_object(
|
|
||||||
ch_host, 'get_distrib_codename')
|
|
||||||
self.get_distrib_codename.return_value = "bionic"
|
|
||||||
charm_config = {}
|
|
||||||
pxe_class = controller_utils.get_pxe_config_class(charm_config)
|
|
||||||
self.assertTrue(
|
|
||||||
isinstance(
|
|
||||||
pxe_class, controller_utils.PXEBootBionic))
|
|
||||||
|
|
||||||
def test_get_pxe_config_class(self):
|
def test_get_pxe_config_class(self):
|
||||||
self.patch_object(
|
self.patch_object(
|
||||||
ch_host, 'get_distrib_codename')
|
ch_host, 'get_distrib_codename')
|
||||||
|
|
|
@ -19,6 +19,8 @@ import charms.leadership as leadership
|
||||||
import charmhelpers.core.hookenv as hookenv
|
import charmhelpers.core.hookenv as hookenv
|
||||||
import charms.reactive as reactive
|
import charms.reactive as reactive
|
||||||
|
|
||||||
|
from charmhelpers.contrib.openstack.utils import os_release
|
||||||
|
|
||||||
from charm.openstack.ironic import ironic
|
from charm.openstack.ironic import ironic
|
||||||
from charm.openstack.ironic import controller_utils as ctrl_util
|
from charm.openstack.ironic import controller_utils as ctrl_util
|
||||||
|
|
||||||
|
@ -70,6 +72,118 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
|
|
||||||
self.get_pxe_config_class.return_value = self.mocked_pxe_cfg
|
self.get_pxe_config_class.return_value = self.mocked_pxe_cfg
|
||||||
|
|
||||||
|
def test_setup_power_adapter_config_train(self):
|
||||||
|
os_release.return_value = "train"
|
||||||
|
cfg_data = {
|
||||||
|
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||||
|
}
|
||||||
|
|
||||||
|
hookenv.config.return_value = cfg_data
|
||||||
|
|
||||||
|
target = ironic.IronicConductorCharm()
|
||||||
|
target._setup_power_adapter_config()
|
||||||
|
expected = {
|
||||||
|
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||||
|
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||||
|
"ipmitool, redfish, noop"),
|
||||||
|
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||||
|
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||||
|
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||||
|
"ipmitool-socat, no-console"),
|
||||||
|
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||||
|
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||||
|
"enabled_boot_interfaces": "pxe",
|
||||||
|
"enabled_bios_interfaces": "no-bios"
|
||||||
|
}
|
||||||
|
self.assertEqual(
|
||||||
|
target.config["hardware_type_cfg"],
|
||||||
|
expected)
|
||||||
|
|
||||||
|
def test_setup_power_adapter_config_train_ipxe(self):
|
||||||
|
os_release.return_value = "train"
|
||||||
|
cfg_data = {
|
||||||
|
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||||
|
"use-ipxe": True,
|
||||||
|
}
|
||||||
|
|
||||||
|
hookenv.config.return_value = cfg_data
|
||||||
|
|
||||||
|
target = ironic.IronicConductorCharm()
|
||||||
|
target._setup_power_adapter_config()
|
||||||
|
expected = {
|
||||||
|
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||||
|
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||||
|
"ipmitool, redfish, noop"),
|
||||||
|
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||||
|
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||||
|
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||||
|
"ipmitool-socat, no-console"),
|
||||||
|
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||||
|
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||||
|
"enabled_boot_interfaces": "pxe, ipxe",
|
||||||
|
"enabled_bios_interfaces": "no-bios"
|
||||||
|
}
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
target.config["hardware_type_cfg"],
|
||||||
|
expected)
|
||||||
|
|
||||||
|
def test_setup_power_adapter_config_unknown(self):
|
||||||
|
# test that it defaults to latest, in this case ussuri
|
||||||
|
os_release.return_value = "unknown"
|
||||||
|
cfg_data = {
|
||||||
|
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||||
|
}
|
||||||
|
|
||||||
|
hookenv.config.return_value = cfg_data
|
||||||
|
|
||||||
|
target = ironic.IronicConductorCharm()
|
||||||
|
target._setup_power_adapter_config()
|
||||||
|
expected = {
|
||||||
|
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||||
|
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||||
|
"ipmitool, redfish, noop"),
|
||||||
|
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||||
|
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||||
|
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||||
|
"ipmitool-socat, no-console"),
|
||||||
|
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||||
|
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||||
|
"enabled_boot_interfaces": "pxe, redfish-virtual-media",
|
||||||
|
"enabled_bios_interfaces": "idrac-wsman, no-bios"
|
||||||
|
}
|
||||||
|
self.assertEqual(
|
||||||
|
target.config["hardware_type_cfg"],
|
||||||
|
expected)
|
||||||
|
|
||||||
|
def test_setup_power_adapter_config_ussuri(self):
|
||||||
|
os_release.return_value = "ussuri"
|
||||||
|
cfg_data = {
|
||||||
|
"enabled-hw-types": "ipmi, redfish, idrac",
|
||||||
|
}
|
||||||
|
|
||||||
|
hookenv.config.return_value = cfg_data
|
||||||
|
|
||||||
|
target = ironic.IronicConductorCharm()
|
||||||
|
target._setup_power_adapter_config()
|
||||||
|
self.maxDiff = None
|
||||||
|
expected = {
|
||||||
|
"enabled_hardware_types": "idrac, intel-ipmi, ipmi, redfish",
|
||||||
|
"enabled_management_interfaces": ("idrac-redfish, intel-ipmitool, "
|
||||||
|
"ipmitool, redfish, noop"),
|
||||||
|
"enabled_inspect_interfaces": "idrac-redfish, redfish, no-inspect",
|
||||||
|
"enabled_power_interfaces": "idrac-redfish, ipmitool, redfish",
|
||||||
|
"enabled_console_interfaces": ("ipmitool-shellinabox, "
|
||||||
|
"ipmitool-socat, no-console"),
|
||||||
|
"enabled_raid_interfaces": "idrac-wsman, no-raid",
|
||||||
|
"enabled_vendor_interfaces": "idrac-wsman, ipmitool, no-vendor",
|
||||||
|
"enabled_boot_interfaces": "pxe, redfish-virtual-media",
|
||||||
|
"enabled_bios_interfaces": "idrac-wsman, no-bios"
|
||||||
|
}
|
||||||
|
self.assertEqual(
|
||||||
|
target.config["hardware_type_cfg"],
|
||||||
|
expected)
|
||||||
|
|
||||||
def test_get_amqp_credentials(self):
|
def test_get_amqp_credentials(self):
|
||||||
cfg_data = {
|
cfg_data = {
|
||||||
"rabbit-user": "ironic",
|
"rabbit-user": "ironic",
|
||||||
|
@ -159,11 +273,24 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
target = ironic.IronicConductorCharm()
|
target = ironic.IronicConductorCharm()
|
||||||
target._setup_pxe_config(self.mocked_pxe_cfg)
|
target._setup_pxe_config(self.mocked_pxe_cfg)
|
||||||
expected_pkgs = ironic.PACKAGES + ["fakepkg1", "fakepkg2"]
|
expected_pkgs = ironic.PACKAGES + ["fakepkg1", "fakepkg2"]
|
||||||
|
|
||||||
expected_cfg = {
|
expected_cfg = {
|
||||||
'tftpboot': ctrl_util.PXEBootBase.TFTP_ROOT,
|
'tftpboot': ctrl_util.PXEBootBase.TFTP_ROOT,
|
||||||
'httpboot': ctrl_util.PXEBootBase.HTTP_ROOT,
|
'httpboot': ctrl_util.PXEBootBase.HTTP_ROOT,
|
||||||
'ironic_user': ctrl_util.PXEBootBase.IRONIC_USER,
|
'ironic_user': ctrl_util.PXEBootBase.IRONIC_USER,
|
||||||
'ironic_group': ctrl_util.PXEBootBase.IRONIC_GROUP,
|
'ironic_group': ctrl_util.PXEBootBase.IRONIC_GROUP,
|
||||||
|
'hardware_type_cfg': {
|
||||||
|
'enabled_hardware_types': 'intel-ipmi, ipmi',
|
||||||
|
'enabled_management_interfaces': ('intel-ipmitool, ipmitool,'
|
||||||
|
' noop'),
|
||||||
|
'enabled_inspect_interfaces': 'no-inspect',
|
||||||
|
'enabled_power_interfaces': 'ipmitool',
|
||||||
|
'enabled_console_interfaces': ('ipmitool-shellinabox, '
|
||||||
|
'ipmitool-socat, no-console'),
|
||||||
|
'enabled_raid_interfaces': 'no-raid',
|
||||||
|
'enabled_vendor_interfaces': 'ipmitool, no-vendor',
|
||||||
|
'enabled_boot_interfaces': 'pxe',
|
||||||
|
'enabled_bios_interfaces': 'no-bios'},
|
||||||
'default-network-interface': 'fake_net',
|
'default-network-interface': 'fake_net',
|
||||||
'default-deploy-interface': 'fake_deploy'}
|
'default-deploy-interface': 'fake_deploy'}
|
||||||
|
|
||||||
|
@ -188,7 +315,7 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
target._validate_deploy_interfaces(["bogus"])
|
target._validate_deploy_interfaces(["bogus"])
|
||||||
|
|
||||||
expected_msg = (
|
expected_msg = (
|
||||||
'Deploy interface "bogus" is not valid.'
|
'Deploy interface bogus is not valid.'
|
||||||
' Valid interfaces are: direct, iscsi')
|
' Valid interfaces are: direct, iscsi')
|
||||||
|
|
||||||
self.assertIsNone(
|
self.assertIsNone(
|
||||||
|
@ -204,8 +331,8 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
with self.assertRaises(ValueError) as err:
|
with self.assertRaises(ValueError) as err:
|
||||||
target._validate_deploy_interfaces(["direct"])
|
target._validate_deploy_interfaces(["direct"])
|
||||||
expected_msg = (
|
expected_msg = (
|
||||||
'run "set-temp-url-secret" action on '
|
'run set-temp-url-secret action on '
|
||||||
'leader to enable "direct" deploy method')
|
'leader to enable direct deploy method')
|
||||||
self.assertEqual(str(err.exception), expected_msg)
|
self.assertEqual(str(err.exception), expected_msg)
|
||||||
|
|
||||||
def test_validate_default_net_interface(self):
|
def test_validate_default_net_interface(self):
|
||||||
|
@ -266,8 +393,8 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
target = ironic.IronicConductorCharm()
|
target = ironic.IronicConductorCharm()
|
||||||
expected_status = (
|
expected_status = (
|
||||||
'blocked',
|
'blocked',
|
||||||
'invalid enabled-network-interfaces config: Network interface '
|
'invalid enabled-network-interfaces config, Network interface '
|
||||||
'"bogus" is not valid. Valid interfaces are: neutron, flat, noop'
|
'bogus is not valid. Valid interfaces are: neutron, flat, noop'
|
||||||
)
|
)
|
||||||
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
||||||
|
|
||||||
|
@ -280,8 +407,8 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
target = ironic.IronicConductorCharm()
|
target = ironic.IronicConductorCharm()
|
||||||
expected_status = (
|
expected_status = (
|
||||||
'blocked',
|
'blocked',
|
||||||
'invalid enabled-deploy-interfaces config: Deploy interface '
|
'invalid enabled-deploy-interfaces config, Deploy interface '
|
||||||
'"bogus" is not valid. Valid interfaces are: direct, iscsi'
|
'bogus is not valid. Valid interfaces are: direct, iscsi'
|
||||||
)
|
)
|
||||||
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
||||||
|
|
||||||
|
@ -294,7 +421,7 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
target = ironic.IronicConductorCharm()
|
target = ironic.IronicConductorCharm()
|
||||||
expected_status = (
|
expected_status = (
|
||||||
'blocked',
|
'blocked',
|
||||||
'invalid default-network-interface config: '
|
'invalid default-network-interface config, '
|
||||||
'default-network-interface (bogus) is not enabled '
|
'default-network-interface (bogus) is not enabled '
|
||||||
'in enabled-network-interfaces: neutron, flat, noop'
|
'in enabled-network-interfaces: neutron, flat, noop'
|
||||||
)
|
)
|
||||||
|
@ -309,7 +436,7 @@ class TestIronicCharm(test_utils.PatchHelper):
|
||||||
target = ironic.IronicConductorCharm()
|
target = ironic.IronicConductorCharm()
|
||||||
expected_status = (
|
expected_status = (
|
||||||
'blocked',
|
'blocked',
|
||||||
'invalid default-deploy-interface config: default-deploy-interface'
|
'invalid default-deploy-interface config, default-deploy-interface'
|
||||||
' (bogus) is not enabled in enabled-deploy-interfaces: direct, '
|
' (bogus) is not enabled in enabled-deploy-interfaces: direct, '
|
||||||
'iscsi')
|
'iscsi')
|
||||||
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
self.assertEqual(target.custom_assess_status_check(), expected_status)
|
||||||
|
|
Loading…
Reference in New Issue