Browse Source

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
changes/77/755977/12
Gabriel Adrian Samfira 2 years ago
parent
commit
9883204a85
  1. 4
      .gitreview
  2. 4
      .zuul.yaml
  3. 9
      src/config.yaml
  4. 4
      src/layer.yaml
  5. 10
      src/lib/charm/openstack/ironic/api_utils.py
  6. 22
      src/lib/charm/openstack/ironic/controller_utils.py
  7. 203
      src/lib/charm/openstack/ironic/ironic.py
  8. 25
      src/templates/train/ironic.conf
  9. 5
      src/tests/00-setup
  10. 35
      src/tests/10-deploy
  11. 250
      src/tests/bundles/bionic-train.yaml
  12. 250
      src/tests/bundles/bionic-ussuri.yaml
  13. 284
      src/tests/bundles/focal-ussuri.yaml
  14. 284
      src/tests/bundles/focal-victoria.yaml
  15. 1
      src/tests/bundles/overlays/bionic-train.yaml.j2
  16. 1
      src/tests/bundles/overlays/bionic-ussuri.yaml.j2
  17. 1
      src/tests/bundles/overlays/focal-ussuri.yaml.j2
  18. 1
      src/tests/bundles/overlays/focal-victoria.yaml.j2
  19. 4
      src/tests/bundles/overlays/ironic.j2
  20. 29
      src/tests/tests.yaml
  21. 1
      src/wheelhouse.txt
  22. 12
      unit_tests/__init__.py
  23. 14
      unit_tests/test_api_utils.py
  24. 10
      unit_tests/test_controller_utils.py
  25. 145
      unit_tests/test_lib_charm_openstack_ironic.py

4
.gitreview

@ -0,0 +1,4 @@
[gerrit]
host=review.opendev.org
port=29418
project=openstack/charm-ironic-conductor.git

4
.zuul.yaml

@ -0,0 +1,4 @@
- project:
templates:
- openstack-python3-charm-jobs
- openstack-cover-jobs

9
src/config.yaml

@ -159,3 +159,12 @@ options:
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.
enabled-hw-types:
default: "ipmi"
type: string
description: |
Comma separated list of hardware types to enable.
Valid options are:
* ipmi
* redfish
* idrac

4
src/layer.yaml

@ -5,10 +5,10 @@ includes:
- interface:rabbitmq
- interface:keystone-credentials
- interface:ironic-api
repo: https://github.com/gabriel-samfira/charm-ironic-conductor
repo: https://opendev.org/openstack/charm-ironic-conductor.git
options:
basic:
use_venv: true
include_system_packages: False
packages: [ 'libffi-dev', 'libssl-dev', 'libpython3.6-dev' ]
packages: [ 'libffi-dev', 'libssl-dev', 'libpython3-dev' ]

10
src/lib/charm/openstack/ironic/api_utils.py

@ -6,8 +6,10 @@ import glanceclient
import swiftclient
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"
username = keystone.credentials_username()
password = keystone.credentials_password()
@ -41,17 +43,17 @@ def create_keystone_session(keystone, verify=True):
loader = loading.get_plugin_loader(plugin_name)
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):
def __init__(self, session, cacert=None):
def __init__(self, session):
self._session = session
self._img_cli = glanceclient.Client(
session=self._session, version=2)
self._obj_cli = swiftclient.Connection(
session=self._session, cacert=cacert)
session=self._session, cacert=SYSTEM_CA_BUNDLE)
self._ks = keystoneclient.v3.Client(
session=session)
self._stores = None

22
src/lib/charm/openstack/ironic/controller_utils.py

@ -25,7 +25,7 @@ class PXEBootBase(object):
"/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/shim.efi.signed": "bootx64.efi",
"/usr/lib/shim/shimx64.efi.signed": "bootx64.efi",
"/usr/lib/ipxe/undionly.kpxe": "undionly.kpxe",
"/usr/lib/ipxe/ipxe.efi": "ipxe.efi",
}
@ -65,7 +65,7 @@ class PXEBootBase(object):
for f in self.FILE_MAP:
if os.path.isfile(f) is False:
raise ValueError(
"Missing required file %s. Package not installes?" % f)
"Missing required file %s. Package not installed?" % f)
shutil.copy(
f, os.path.join(self.TFTP_ROOT, self.FILE_MAP[f]),
follow_symlinks=True)
@ -88,27 +88,9 @@ class PXEBootBase(object):
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):
# We may need to make slight adjustments to package names and/or
# configuration files, based on the version of Ubuntu we are installing
# 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.
series = ch_host.get_distrib_codename()
if series == "bionic":
return PXEBootBionic(charm_config)
return PXEBootBase(charm_config)

203
src/lib/charm/openstack/ironic/ironic.py

@ -10,6 +10,7 @@ from charms_openstack.adapters import (
DatabaseRelationAdapter,
OpenStackRelationAdapters,
)
from charmhelpers.contrib.openstack.utils import os_release
import charm.openstack.ironic.controller_utils as controller_utils
import charms_openstack.adapters as adapters
@ -19,15 +20,14 @@ import charms.reactive as reactive
PACKAGES = [
'ironic-conductor',
'python3-dracclient',
'python3-keystoneauth1',
'python3-keystoneclient',
'python3-glanceclient',
'python3-swiftclient',
'python-mysqldb',
'python3-dracclient',
'python3-sushy',
'python3-swiftclient',
'python3-mysqldb',
'python3-ironicclient',
'python3-scciclient',
'shellinabox',
'openssl',
'socat',
@ -50,6 +50,100 @@ VALID_DEPLOY_INTERFACES = ["direct", "iscsi"]
DEFAULT_DEPLOY_IFACE = "flat"
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'
@ -89,6 +183,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
release = 'train'
name = 'ironic'
packages = PACKAGES
python_version = 3
service_type = 'ironic'
default_service = 'ironic-conductor'
@ -127,6 +222,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
self.pxe_config = controller_utils.get_pxe_config_class(
self.config)
self._setup_pxe_config(self.pxe_config)
self._setup_power_adapter_config()
self._configure_defaults()
if "neutron" in self.enabled_network_interfaces:
self.mandatory_config.extend([
@ -141,6 +237,65 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
if not 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):
self.packages.extend(cfg.determine_packages())
self.packages = list(set(self.packages))
@ -178,7 +333,7 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
for interface in interfaces:
if interface not in valid_interfaces:
raise ValueError(
'Network interface "%s" is not valid. Valid '
'Network interface %s is not valid. Valid '
'interfaces are: %s' % (
interface, ", ".join(valid_interfaces)))
@ -197,14 +352,14 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
for interface in interfaces:
if interface not in valid_interfaces:
raise ValueError(
'Deploy interface "%s" is not valid. Valid '
'Deploy interface %s is not valid. Valid '
'interfaces are: %s' % (
interface, ", ".join(valid_interfaces)))
if reactive.is_flag_set("config.complete"):
if "direct" in interfaces and has_secret is False:
raise ValueError(
'run "set-temp-url-secret" action on leader to '
'enable "direct" deploy method')
'run set-temp-url-secret action on leader to '
'enable direct deploy method')
def _validate_default_deploy_interface(self):
iface = self.config["default-deploy-interface"]
@ -215,12 +370,29 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
iface, ", ".join(
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
def enabled_network_interfaces(self):
network_interfaces = self.config.get(
'enabled-network-interfaces', "").replace(" ", "")
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
def enabled_deploy_interfaces(self):
network_interfaces = self.config.get(
@ -231,25 +403,32 @@ class IronicConductorCharm(charms_openstack.charm.OpenStackCharm):
try:
self._validate_network_interfaces(self.enabled_network_interfaces)
except Exception as err:
msg = ("invalid enabled-network-interfaces config: %s" % err)
msg = ("invalid enabled-network-interfaces config, %s" % err)
return ('blocked', msg)
try:
self._validate_default_net_interface()
except Exception as err:
msg = ("invalid default-network-interface config: %s" % err)
msg = ("invalid default-network-interface config, %s" % err)
return ('blocked', msg)
try:
self._validate_deploy_interfaces(
self.enabled_deploy_interfaces)
except Exception as err:
msg = ("invalid enabled-deploy-interfaces config: %s" % err)
msg = ("invalid enabled-deploy-interfaces config, %s" % err)
return ('blocked', msg)
try:
self._validate_default_deploy_interface()
except Exception as err:
msg = ("invalid default-deploy-interface config: %s" % err)
msg = ("invalid default-deploy-interface config, %s" % err)
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)

25
src/templates/train/ironic.conf

@ -5,20 +5,21 @@ auth_strategy=keystone
my_ip = {{ options.internal_interface_ip }}
enabled_deploy_interfaces = {{ options.enabled_deploy_interfaces }}
enabled_hardware_types = ipmi,ilo,idrac,redfish,irmc
{% if options.use_ipxe -%}
enabled_boot_interfaces = pxe,ipxe,ilo-pxe,ilo-ipxe,irmc-pxe
{% else -%}
enabled_boot_interfaces = pxe,ilo-pxe,irmc-pxe
{% endif -%}
enabled_management_interfaces = ipmitool,redfish,ilo,irmc,idrac,noop
enabled_inspect_interfaces = idrac,ilo,irmc,redfish,no-inspect
enabled_hardware_types = {{ options.hardware_type_cfg.enabled_hardware_types }}
enabled_boot_interfaces = {{ options.hardware_type_cfg.enabled_boot_interfaces }}
enabled_management_interfaces = {{ options.hardware_type_cfg.enabled_management_interfaces }}
enabled_inspect_interfaces = {{ options.hardware_type_cfg.enabled_inspect_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_console_interfaces = ipmitool-socat,ipmitool-shellinabox,no-console
enabled_raid_interfaces = agent,idrac,irmc,no-raid
enabled_vendor_interfaces = ipmitool,idrac,ilo,no-vendor
enabled_console_interfaces = {{ options.hardware_type_cfg.enabled_console_interfaces }}
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_network_interface = {{ options.default_network_interface }}

5
src/tests/00-setup

@ -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

35
src/tests/10-deploy

@ -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()

250
src/tests/bundles/bionic-train.yaml

@ -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

250
src/tests/bundles/bionic-ussuri.yaml

@ -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

284
src/tests/bundles/focal-ussuri.yaml

@ -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

284
src/tests/bundles/focal-victoria.yaml

@ -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:<