Add unit status support
This commit is contained in:
commit
81842c17d5
|
@ -752,7 +752,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||||
self.log.debug('SSL is enabled @{}:{} '
|
self.log.debug('SSL is enabled @{}:{} '
|
||||||
'({})'.format(host, port, unit_name))
|
'({})'.format(host, port, unit_name))
|
||||||
return True
|
return True
|
||||||
elif not port and not conf_ssl:
|
elif not conf_ssl:
|
||||||
self.log.debug('SSL not enabled @{}:{} '
|
self.log.debug('SSL not enabled @{}:{} '
|
||||||
'({})'.format(host, port, unit_name))
|
'({})'.format(host, port, unit_name))
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
# You should have received a copy of the GNU Lesser General Public License
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import glob
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
@ -1363,7 +1364,7 @@ class DataPortContext(NeutronPortContext):
|
||||||
normalized.update({port: port for port in resolved
|
normalized.update({port: port for port in resolved
|
||||||
if port in ports})
|
if port in ports})
|
||||||
if resolved:
|
if resolved:
|
||||||
return {bridge: normalized[port] for port, bridge in
|
return {normalized[port]: bridge for port, bridge in
|
||||||
six.iteritems(portmap) if port in normalized.keys()}
|
six.iteritems(portmap) if port in normalized.keys()}
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
@ -1374,12 +1375,22 @@ class PhyNICMTUContext(DataPortContext):
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
mappings = super(PhyNICMTUContext, self).__call__()
|
mappings = super(PhyNICMTUContext, self).__call__()
|
||||||
if mappings and mappings.values():
|
if mappings and mappings.keys():
|
||||||
ports = mappings.values()
|
ports = sorted(mappings.keys())
|
||||||
napi_settings = NeutronAPIContext()()
|
napi_settings = NeutronAPIContext()()
|
||||||
mtu = napi_settings.get('network_device_mtu')
|
mtu = napi_settings.get('network_device_mtu')
|
||||||
|
all_ports = set()
|
||||||
|
# If any of ports is a vlan device, its underlying device must have
|
||||||
|
# mtu applied first.
|
||||||
|
for port in ports:
|
||||||
|
for lport in glob.glob("/sys/class/net/%s/lower_*" % port):
|
||||||
|
lport = os.path.basename(lport)
|
||||||
|
all_ports.add(lport.split('_')[1])
|
||||||
|
|
||||||
|
all_ports = list(all_ports)
|
||||||
|
all_ports.extend(ports)
|
||||||
if mtu:
|
if mtu:
|
||||||
ctxt["devs"] = '\\n'.join(ports)
|
ctxt["devs"] = '\\n'.join(all_ports)
|
||||||
ctxt['mtu'] = mtu
|
ctxt['mtu'] = mtu
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
|
@ -310,10 +310,10 @@ def parse_bridge_mappings(mappings):
|
||||||
def parse_data_port_mappings(mappings, default_bridge='br-data'):
|
def parse_data_port_mappings(mappings, default_bridge='br-data'):
|
||||||
"""Parse data port mappings.
|
"""Parse data port mappings.
|
||||||
|
|
||||||
Mappings must be a space-delimited list of port:bridge mappings.
|
Mappings must be a space-delimited list of bridge:port.
|
||||||
|
|
||||||
Returns dict of the form {port:bridge} where port may be an mac address or
|
Returns dict of the form {port:bridge} where ports may be mac addresses or
|
||||||
interface name.
|
interface names.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# NOTE(dosaboy): we use rvalue for key to allow multiple values to be
|
# NOTE(dosaboy): we use rvalue for key to allow multiple values to be
|
||||||
|
|
|
@ -13,3 +13,9 @@ log to syslog = {{ use_syslog }}
|
||||||
err to syslog = {{ use_syslog }}
|
err to syslog = {{ use_syslog }}
|
||||||
clog to syslog = {{ use_syslog }}
|
clog to syslog = {{ use_syslog }}
|
||||||
|
|
||||||
|
[client]
|
||||||
|
{% if rbd_client_cache_settings -%}
|
||||||
|
{% for key, value in rbd_client_cache_settings.iteritems() -%}
|
||||||
|
{{ key }} = {{ value }}
|
||||||
|
{% endfor -%}
|
||||||
|
{%- endif %}
|
|
@ -81,7 +81,20 @@ class NovaCellContext(context.OSContextGenerator):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
|
|
||||||
|
class CloudComputeContext(context.OSContextGenerator):
|
||||||
|
"Dummy context used by service status to check relation exists"
|
||||||
|
interfaces = ['nova-compute']
|
||||||
|
|
||||||
|
def __call__(self):
|
||||||
|
ctxt = {}
|
||||||
|
rids = [rid for rid in relation_ids('cloud-compute')]
|
||||||
|
if rids:
|
||||||
|
ctxt['rids'] = rids
|
||||||
|
return ctxt
|
||||||
|
|
||||||
|
|
||||||
class NeutronAPIContext(context.OSContextGenerator):
|
class NeutronAPIContext(context.OSContextGenerator):
|
||||||
|
interfaces = ['neutron-api']
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
log('Generating template context from neutron api relation')
|
log('Generating template context from neutron api relation')
|
||||||
|
@ -102,7 +115,7 @@ class NeutronAPIContext(context.OSContextGenerator):
|
||||||
|
|
||||||
|
|
||||||
class VolumeServiceContext(context.OSContextGenerator):
|
class VolumeServiceContext(context.OSContextGenerator):
|
||||||
interfaces = []
|
interfaces = ['nova-volume-service', 'cinder-volume-service']
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
|
@ -228,7 +241,7 @@ def use_local_neutron_api():
|
||||||
|
|
||||||
|
|
||||||
class NeutronCCContext(context.NeutronContext):
|
class NeutronCCContext(context.NeutronContext):
|
||||||
interfaces = []
|
interfaces = ['quantum-network-service', 'neutron-network-service']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def plugin(self):
|
def plugin(self):
|
||||||
|
|
|
@ -26,6 +26,7 @@ from charmhelpers.core.hookenv import (
|
||||||
related_units,
|
related_units,
|
||||||
open_port,
|
open_port,
|
||||||
unit_get,
|
unit_get,
|
||||||
|
status_set,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.core.host import (
|
from charmhelpers.core.host import (
|
||||||
|
@ -49,7 +50,8 @@ from charmhelpers.contrib.openstack.utils import (
|
||||||
openstack_upgrade_available,
|
openstack_upgrade_available,
|
||||||
os_release,
|
os_release,
|
||||||
os_requires_version,
|
os_requires_version,
|
||||||
sync_db_with_multi_ipv6_addresses
|
sync_db_with_multi_ipv6_addresses,
|
||||||
|
set_os_workload_status,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.openstack.neutron import (
|
from charmhelpers.contrib.openstack.neutron import (
|
||||||
|
@ -101,6 +103,8 @@ from nova_cc_utils import (
|
||||||
guard_map,
|
guard_map,
|
||||||
get_topics,
|
get_topics,
|
||||||
setup_ipv6,
|
setup_ipv6,
|
||||||
|
REQUIRED_INTERFACES,
|
||||||
|
check_optional_relations,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.hahelpers.cluster import (
|
from charmhelpers.contrib.hahelpers.cluster import (
|
||||||
|
@ -146,9 +150,11 @@ NOVA_CONSOLEAUTH_OVERRIDE = '/etc/init/nova-consoleauth.override'
|
||||||
|
|
||||||
@hooks.hook('install.real')
|
@hooks.hook('install.real')
|
||||||
def install():
|
def install():
|
||||||
|
status_set('maintenance', 'Executing pre-install')
|
||||||
execd_preinstall()
|
execd_preinstall()
|
||||||
configure_installation_source(config('openstack-origin'))
|
configure_installation_source(config('openstack-origin'))
|
||||||
|
|
||||||
|
status_set('maintenance', 'Installing apt packages')
|
||||||
apt_update()
|
apt_update()
|
||||||
apt_install(determine_packages(), fatal=True)
|
apt_install(determine_packages(), fatal=True)
|
||||||
|
|
||||||
|
@ -162,7 +168,9 @@ def install():
|
||||||
log('Installing %s to /usr/bin' % f)
|
log('Installing %s to /usr/bin' % f)
|
||||||
shutil.copy2(f, '/usr/bin')
|
shutil.copy2(f, '/usr/bin')
|
||||||
[open_port(port) for port in determine_ports()]
|
[open_port(port) for port in determine_ports()]
|
||||||
log('Disabling services into db relation joined')
|
msg = 'Disabling services into db relation joined'
|
||||||
|
log(msg)
|
||||||
|
status_set('maintenance', msg)
|
||||||
disable_services()
|
disable_services()
|
||||||
cmd_all_services('stop')
|
cmd_all_services('stop')
|
||||||
|
|
||||||
|
@ -173,6 +181,7 @@ def install():
|
||||||
@restart_on_change(restart_map(), stopstart=True)
|
@restart_on_change(restart_map(), stopstart=True)
|
||||||
def config_changed():
|
def config_changed():
|
||||||
if config('prefer-ipv6'):
|
if config('prefer-ipv6'):
|
||||||
|
status_set('maintenance', 'configuring ipv6')
|
||||||
setup_ipv6()
|
setup_ipv6()
|
||||||
sync_db_with_multi_ipv6_addresses(config('database'),
|
sync_db_with_multi_ipv6_addresses(config('database'),
|
||||||
config('database-user'),
|
config('database-user'),
|
||||||
|
@ -180,10 +189,12 @@ def config_changed():
|
||||||
|
|
||||||
global CONFIGS
|
global CONFIGS
|
||||||
if git_install_requested():
|
if git_install_requested():
|
||||||
|
status_set('maintenance', 'Running Git install')
|
||||||
if config_value_changed('openstack-origin-git'):
|
if config_value_changed('openstack-origin-git'):
|
||||||
git_install(config('openstack-origin-git'))
|
git_install(config('openstack-origin-git'))
|
||||||
elif not config('action-managed-upgrade'):
|
elif not config('action-managed-upgrade'):
|
||||||
if openstack_upgrade_available('nova-common'):
|
if openstack_upgrade_available('nova-common'):
|
||||||
|
status_set('maintenance', 'Running openstack upgrade')
|
||||||
CONFIGS = do_openstack_upgrade(CONFIGS)
|
CONFIGS = do_openstack_upgrade(CONFIGS)
|
||||||
[neutron_api_relation_joined(rid=rid, remote_restart=True)
|
[neutron_api_relation_joined(rid=rid, remote_restart=True)
|
||||||
for rid in relation_ids('neutron-api')]
|
for rid in relation_ids('neutron-api')]
|
||||||
|
@ -192,6 +203,7 @@ def config_changed():
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
if console_attributes('protocol'):
|
if console_attributes('protocol'):
|
||||||
if not git_install_requested():
|
if not git_install_requested():
|
||||||
|
status_set('maintenance', 'Configuring guest console access')
|
||||||
apt_update()
|
apt_update()
|
||||||
packages = console_attributes('packages') or []
|
packages = console_attributes('packages') or []
|
||||||
filtered = filter_installed_packages(packages)
|
filtered = filter_installed_packages(packages)
|
||||||
|
@ -244,6 +256,7 @@ def conditional_neutron_migration():
|
||||||
log('Not running neutron database migration as migrations are by '
|
log('Not running neutron database migration as migrations are by '
|
||||||
'the neutron-api charm.')
|
'the neutron-api charm.')
|
||||||
else:
|
else:
|
||||||
|
status_set('maintenance', 'Running neutron db migration')
|
||||||
migrate_neutron_database()
|
migrate_neutron_database()
|
||||||
# neutron-api service may have appeared while the migration was
|
# neutron-api service may have appeared while the migration was
|
||||||
# running so prod it just in case
|
# running so prod it just in case
|
||||||
|
@ -330,6 +343,7 @@ def db_changed():
|
||||||
# permitted units then check if we're in the list.
|
# permitted units then check if we're in the list.
|
||||||
allowed_units = relation_get('nova_allowed_units')
|
allowed_units = relation_get('nova_allowed_units')
|
||||||
if allowed_units and local_unit() in allowed_units.split():
|
if allowed_units and local_unit() in allowed_units.split():
|
||||||
|
status_set('maintenance', 'Running nova db migration')
|
||||||
migrate_nova_database()
|
migrate_nova_database()
|
||||||
log('Triggering remote cloud-compute restarts.')
|
log('Triggering remote cloud-compute restarts.')
|
||||||
[compute_joined(rid=rid, remote_restart=True)
|
[compute_joined(rid=rid, remote_restart=True)
|
||||||
|
@ -354,6 +368,7 @@ def postgresql_nova_db_changed():
|
||||||
CONFIGS.write_all()
|
CONFIGS.write_all()
|
||||||
|
|
||||||
if is_elected_leader(CLUSTER_RES):
|
if is_elected_leader(CLUSTER_RES):
|
||||||
|
status_set('maintenance', 'Running nova db migration')
|
||||||
migrate_nova_database()
|
migrate_nova_database()
|
||||||
log('Triggering remote cloud-compute restarts.')
|
log('Triggering remote cloud-compute restarts.')
|
||||||
[compute_joined(rid=rid, remote_restart=True)
|
[compute_joined(rid=rid, remote_restart=True)
|
||||||
|
@ -578,6 +593,7 @@ def compute_changed(rid=None, unit=None):
|
||||||
if 'migration_auth_type' not in rel_settings:
|
if 'migration_auth_type' not in rel_settings:
|
||||||
return
|
return
|
||||||
if rel_settings['migration_auth_type'] == 'ssh':
|
if rel_settings['migration_auth_type'] == 'ssh':
|
||||||
|
status_set('maintenance', 'configuring live migration')
|
||||||
key = rel_settings.get('ssh_public_key')
|
key = rel_settings.get('ssh_public_key')
|
||||||
if not key:
|
if not key:
|
||||||
log('SSH migration set but peer did not publish key.')
|
log('SSH migration set but peer did not publish key.')
|
||||||
|
@ -1039,7 +1055,8 @@ def main():
|
||||||
hooks.execute(sys.argv)
|
hooks.execute(sys.argv)
|
||||||
except UnregisteredHookError as e:
|
except UnregisteredHookError as e:
|
||||||
log('Unknown hook {} - skipping.'.format(e))
|
log('Unknown hook {} - skipping.'.format(e))
|
||||||
|
set_os_workload_status(CONFIGS, REQUIRED_INTERFACES,
|
||||||
|
charm_func=check_optional_relations)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -11,7 +11,10 @@ from charmhelpers.contrib.openstack import context, templating
|
||||||
from charmhelpers.contrib.openstack.neutron import (
|
from charmhelpers.contrib.openstack.neutron import (
|
||||||
network_manager, neutron_plugin_attribute)
|
network_manager, neutron_plugin_attribute)
|
||||||
|
|
||||||
from charmhelpers.contrib.hahelpers.cluster import is_elected_leader
|
from charmhelpers.contrib.hahelpers.cluster import (
|
||||||
|
is_elected_leader,
|
||||||
|
get_hacluster_config,
|
||||||
|
)
|
||||||
|
|
||||||
from charmhelpers.contrib.peerstorage import peer_store
|
from charmhelpers.contrib.peerstorage import peer_store
|
||||||
|
|
||||||
|
@ -31,7 +34,9 @@ from charmhelpers.contrib.openstack.utils import (
|
||||||
git_yaml_value,
|
git_yaml_value,
|
||||||
is_ip,
|
is_ip,
|
||||||
os_release,
|
os_release,
|
||||||
save_script_rc as _save_script_rc)
|
save_script_rc as _save_script_rc,
|
||||||
|
set_os_workload_status,
|
||||||
|
)
|
||||||
|
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
apt_upgrade,
|
apt_upgrade,
|
||||||
|
@ -50,6 +55,7 @@ from charmhelpers.core.hookenv import (
|
||||||
is_relation_made,
|
is_relation_made,
|
||||||
INFO,
|
INFO,
|
||||||
ERROR,
|
ERROR,
|
||||||
|
status_get,
|
||||||
)
|
)
|
||||||
|
|
||||||
from charmhelpers.core.host import (
|
from charmhelpers.core.host import (
|
||||||
|
@ -80,6 +86,16 @@ TEMPLATES = 'templates/'
|
||||||
|
|
||||||
CLUSTER_RES = 'grp_nova_vips'
|
CLUSTER_RES = 'grp_nova_vips'
|
||||||
|
|
||||||
|
# The interface is said to be satisfied if anyone of the interfaces in the
|
||||||
|
# list has a complete context.
|
||||||
|
REQUIRED_INTERFACES = {
|
||||||
|
'database': ['shared-db', 'pgsql-db'],
|
||||||
|
'messaging': ['amqp', 'zeromq-configuration'],
|
||||||
|
'identity': ['identity-service'],
|
||||||
|
'image': ['image-service'],
|
||||||
|
'compute': ['nova-compute'],
|
||||||
|
}
|
||||||
|
|
||||||
# removed from original: charm-helper-sh
|
# removed from original: charm-helper-sh
|
||||||
BASE_PACKAGES = [
|
BASE_PACKAGES = [
|
||||||
'apache2',
|
'apache2',
|
||||||
|
@ -195,7 +211,8 @@ BASE_RESOURCE_MAP = OrderedDict([
|
||||||
nova_cc_context.NeutronCCContext(),
|
nova_cc_context.NeutronCCContext(),
|
||||||
nova_cc_context.NovaConfigContext(),
|
nova_cc_context.NovaConfigContext(),
|
||||||
nova_cc_context.InstanceConsoleContext(),
|
nova_cc_context.InstanceConsoleContext(),
|
||||||
nova_cc_context.ConsoleSSLContext()],
|
nova_cc_context.ConsoleSSLContext(),
|
||||||
|
nova_cc_context.CloudComputeContext()],
|
||||||
}),
|
}),
|
||||||
(NOVA_API_PASTE, {
|
(NOVA_API_PASTE, {
|
||||||
'services': [s for s in BASE_SERVICES if 'api' in s],
|
'services': [s for s in BASE_SERVICES if 'api' in s],
|
||||||
|
@ -1328,3 +1345,26 @@ def git_post_install(projects_yaml):
|
||||||
|
|
||||||
apt_update()
|
apt_update()
|
||||||
apt_install(LATE_GIT_PACKAGES, fatal=True)
|
apt_install(LATE_GIT_PACKAGES, fatal=True)
|
||||||
|
|
||||||
|
|
||||||
|
def check_optional_relations(configs):
|
||||||
|
required_interfaces = {}
|
||||||
|
if relation_ids('ha'):
|
||||||
|
required_interfaces['ha'] = ['cluster']
|
||||||
|
try:
|
||||||
|
get_hacluster_config()
|
||||||
|
except:
|
||||||
|
return ('blocked',
|
||||||
|
'hacluster missing configuration: '
|
||||||
|
'vip, vip_iface, vip_cidr')
|
||||||
|
if relation_ids('quantum-network-service'):
|
||||||
|
required_interfaces['quantum'] = ['quantum-network-service']
|
||||||
|
if relation_ids('cinder-volume-service'):
|
||||||
|
required_interfaces['cinder'] = ['cinder-volume-service']
|
||||||
|
if relation_ids('neutron-api'):
|
||||||
|
required_interfaces['neutron-api'] = ['neutron-api']
|
||||||
|
if required_interfaces:
|
||||||
|
set_os_workload_status(configs, required_interfaces)
|
||||||
|
return status_get()
|
||||||
|
else:
|
||||||
|
return 'unknown', 'No optional relations'
|
||||||
|
|
|
@ -752,7 +752,7 @@ class OpenStackAmuletUtils(AmuletUtils):
|
||||||
self.log.debug('SSL is enabled @{}:{} '
|
self.log.debug('SSL is enabled @{}:{} '
|
||||||
'({})'.format(host, port, unit_name))
|
'({})'.format(host, port, unit_name))
|
||||||
return True
|
return True
|
||||||
elif not port and not conf_ssl:
|
elif not conf_ssl:
|
||||||
self.log.debug('SSL not enabled @{}:{} '
|
self.log.debug('SSL not enabled @{}:{} '
|
||||||
'({})'.format(host, port, unit_name))
|
'({})'.format(host, port, unit_name))
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -73,6 +73,7 @@ TO_PATCH = [
|
||||||
'update_nrpe_config',
|
'update_nrpe_config',
|
||||||
'git_install',
|
'git_install',
|
||||||
'git_install_requested',
|
'git_install_requested',
|
||||||
|
'status_set',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue