Sync charm-helpers for Ussuri/Focal release and version details
Change-Id: I4e9ca451157527ca0f19ef981970c5447d510e92
This commit is contained in:
parent
8ec35986df
commit
0496ab77ed
|
@ -484,3 +484,17 @@ def add_haproxy_checks(nrpe, unit_name):
|
|||
shortname='haproxy_queue',
|
||||
description='Check HAProxy queue depth {%s}' % unit_name,
|
||||
check_cmd='check_haproxy_queue_depth.sh')
|
||||
|
||||
|
||||
def remove_deprecated_check(nrpe, deprecated_services):
|
||||
"""
|
||||
Remove checks fro deprecated services in list
|
||||
|
||||
:param nrpe: NRPE object to remove check from
|
||||
:type nrpe: NRPE
|
||||
:param deprecated_services: List of deprecated services that are removed
|
||||
:type deprecated_services: list
|
||||
"""
|
||||
for dep_svc in deprecated_services:
|
||||
log('Deprecated service: {}'.format(dep_svc))
|
||||
nrpe.remove_check(shortname=dep_svc)
|
||||
|
|
|
@ -295,9 +295,11 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||
('bionic', 'cloud:bionic-rocky'): self.bionic_rocky,
|
||||
('bionic', 'cloud:bionic-stein'): self.bionic_stein,
|
||||
('bionic', 'cloud:bionic-train'): self.bionic_train,
|
||||
('bionic', 'cloud:bionic-ussuri'): self.bionic_ussuri,
|
||||
('cosmic', None): self.cosmic_rocky,
|
||||
('disco', None): self.disco_stein,
|
||||
('eoan', None): self.eoan_train,
|
||||
('focal', None): self.focal_ussuri,
|
||||
}
|
||||
return releases[(self.series, self.openstack)]
|
||||
|
||||
|
@ -316,6 +318,7 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||
('cosmic', 'rocky'),
|
||||
('disco', 'stein'),
|
||||
('eoan', 'train'),
|
||||
('focal', 'ussuri'),
|
||||
])
|
||||
if self.openstack:
|
||||
os_origin = self.openstack.split(':')[1]
|
||||
|
|
|
@ -62,6 +62,7 @@ OPENSTACK_RELEASES_PAIRS = [
|
|||
'bionic_rocky', 'cosmic_rocky',
|
||||
'bionic_stein', 'disco_stein',
|
||||
'bionic_train', 'eoan_train',
|
||||
'bionic_ussuri', 'focal_ussuri',
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -244,8 +244,8 @@ def validate_file_permissions(config):
|
|||
@audit(is_audit_type(AuditType.OpenStackSecurityGuide))
|
||||
def validate_uses_keystone(audit_options):
|
||||
"""Validate that the service uses Keystone for authentication."""
|
||||
section = _config_section(audit_options, 'DEFAULT')
|
||||
assert section is not None, "Missing section 'DEFAULT'"
|
||||
section = _config_section(audit_options, 'api') or _config_section(audit_options, 'DEFAULT')
|
||||
assert section is not None, "Missing section 'api / DEFAULT'"
|
||||
assert section.get('auth_strategy') == "keystone", \
|
||||
"Application is not using Keystone"
|
||||
|
||||
|
|
|
@ -730,6 +730,10 @@ class AMQPContext(OSContextGenerator):
|
|||
if notification_format:
|
||||
ctxt['notification_format'] = notification_format
|
||||
|
||||
notification_topics = conf.get('notification-topics', None)
|
||||
if notification_topics:
|
||||
ctxt['notification_topics'] = notification_topics
|
||||
|
||||
send_notifications_to_logs = conf.get('send-notifications-to-logs', None)
|
||||
if send_notifications_to_logs:
|
||||
ctxt['send_notifications_to_logs'] = send_notifications_to_logs
|
||||
|
@ -2177,9 +2181,66 @@ class LogrotateContext(OSContextGenerator):
|
|||
class HostInfoContext(OSContextGenerator):
|
||||
"""Context to provide host information."""
|
||||
|
||||
def __init__(self, use_fqdn_hint_cb=None):
|
||||
"""Initialize HostInfoContext
|
||||
|
||||
:param use_fqdn_hint_cb: Callback whose return value used to populate
|
||||
`use_fqdn_hint`
|
||||
:type use_fqdn_hint_cb: Callable[[], bool]
|
||||
"""
|
||||
# Store callback used to get hint for whether FQDN should be used
|
||||
|
||||
# Depending on the workload a charm manages, the use of FQDN vs.
|
||||
# shortname may be a deploy-time decision, i.e. behaviour can not
|
||||
# change on charm upgrade or post-deployment configuration change.
|
||||
|
||||
# The hint is passed on as a flag in the context to allow the decision
|
||||
# to be made in the Jinja2 configuration template.
|
||||
self.use_fqdn_hint_cb = use_fqdn_hint_cb
|
||||
|
||||
def _get_canonical_name(self, name=None):
|
||||
"""Get the official FQDN of the host
|
||||
|
||||
The implementation of ``socket.getfqdn()`` in the standard Python
|
||||
library does not exhaust all methods of getting the official name
|
||||
of a host ref Python issue https://bugs.python.org/issue5004
|
||||
|
||||
This function mimics the behaviour of a call to ``hostname -f`` to
|
||||
get the official FQDN but returns an empty string if it is
|
||||
unsuccessful.
|
||||
|
||||
:param name: Shortname to get FQDN on
|
||||
:type name: Optional[str]
|
||||
:returns: The official FQDN for host or empty string ('')
|
||||
:rtype: str
|
||||
"""
|
||||
name = name or socket.gethostname()
|
||||
fqdn = ''
|
||||
|
||||
if six.PY2:
|
||||
exc = socket.error
|
||||
else:
|
||||
exc = OSError
|
||||
|
||||
try:
|
||||
addrs = socket.getaddrinfo(
|
||||
name, None, 0, socket.SOCK_DGRAM, 0, socket.AI_CANONNAME)
|
||||
except exc:
|
||||
pass
|
||||
else:
|
||||
for addr in addrs:
|
||||
if addr[3]:
|
||||
if '.' in addr[3]:
|
||||
fqdn = addr[3]
|
||||
break
|
||||
return fqdn
|
||||
|
||||
def __call__(self):
|
||||
name = socket.gethostname()
|
||||
ctxt = {
|
||||
'host_fqdn': socket.getfqdn(),
|
||||
'host': socket.gethostname(),
|
||||
'host_fqdn': self._get_canonical_name(name) or name,
|
||||
'host': name,
|
||||
'use_fqdn_hint': (
|
||||
self.use_fqdn_hint_cb() if self.use_fqdn_hint_cb else False)
|
||||
}
|
||||
return ctxt
|
||||
|
|
|
@ -157,10 +157,11 @@ def generate_ha_relation_data(service,
|
|||
_relation_data = {'resources': {}, 'resource_params': {}}
|
||||
|
||||
if haproxy_enabled:
|
||||
_meta = 'meta migration-threshold="INFINITY" failure-timeout="5s"'
|
||||
_haproxy_res = 'res_{}_haproxy'.format(service)
|
||||
_relation_data['resources'] = {_haproxy_res: 'lsb:haproxy'}
|
||||
_relation_data['resource_params'] = {
|
||||
_haproxy_res: 'op monitor interval="5s"'
|
||||
_haproxy_res: '{} op monitor interval="5s"'.format(_meta)
|
||||
}
|
||||
_relation_data['init_services'] = {_haproxy_res: 'haproxy'}
|
||||
_relation_data['clones'] = {
|
||||
|
|
|
@ -307,9 +307,9 @@ def maybe_do_policyd_overrides(openstack_release,
|
|||
blacklist_paths,
|
||||
user=_user,
|
||||
group=_group)
|
||||
if (os.path.isfile(_policy_success_file())
|
||||
and restart_handler is not None
|
||||
and callable(restart_handler)):
|
||||
if (os.path.isfile(_policy_success_file()) and
|
||||
restart_handler is not None and
|
||||
callable(restart_handler)):
|
||||
restart_handler()
|
||||
remove_policy_success_file()
|
||||
return
|
||||
|
@ -685,9 +685,9 @@ def process_policy_resource_file(resource_file,
|
|||
black list.
|
||||
|
||||
The yaml filename can be modified in two ways. If the `preserve_topdir`
|
||||
param is True, then files will be flattened to the this top dir. This
|
||||
allows for creating sets of files that can be grouped into a single level
|
||||
tree structure.
|
||||
param is True, then files will be flattened to the top dir. This allows
|
||||
for creating sets of files that can be grouped into a single level tree
|
||||
structure.
|
||||
|
||||
Secondly, if the `preprocess_filename` param is not None and callable()
|
||||
then the name is passed to that function for preprocessing before being
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
[placement]
|
||||
{% if auth_host -%}
|
||||
auth_url = {{ auth_protocol }}://{{ auth_host }}:{{ auth_port }}
|
||||
auth_type = password
|
||||
{% if api_version == "3" -%}
|
||||
project_domain_name = {{ admin_domain_name }}
|
||||
user_domain_name = {{ admin_domain_name }}
|
||||
{% else -%}
|
||||
project_domain_name = default
|
||||
user_domain_name = default
|
||||
{% endif -%}
|
||||
project_name = {{ admin_tenant_name }}
|
||||
username = {{ admin_user }}
|
||||
password = {{ admin_password }}
|
||||
{% endif -%}
|
||||
{% if region -%}
|
||||
os_region_name = {{ region }}
|
||||
{% endif -%}
|
||||
randomize_allocation_candidates = true
|
|
@ -50,9 +50,14 @@ from charmhelpers.core.hookenv import (
|
|||
hook_name,
|
||||
application_version_set,
|
||||
cached,
|
||||
leader_set,
|
||||
leader_get,
|
||||
)
|
||||
|
||||
from charmhelpers.core.strutils import BasicStringComparator
|
||||
from charmhelpers.core.strutils import (
|
||||
BasicStringComparator,
|
||||
bool_from_string,
|
||||
)
|
||||
|
||||
from charmhelpers.contrib.storage.linux.lvm import (
|
||||
deactivate_lvm_volume_group,
|
||||
|
@ -126,6 +131,7 @@ OPENSTACK_RELEASES = (
|
|||
'rocky',
|
||||
'stein',
|
||||
'train',
|
||||
'ussuri',
|
||||
)
|
||||
|
||||
UBUNTU_OPENSTACK_RELEASE = OrderedDict([
|
||||
|
@ -146,6 +152,7 @@ UBUNTU_OPENSTACK_RELEASE = OrderedDict([
|
|||
('cosmic', 'rocky'),
|
||||
('disco', 'stein'),
|
||||
('eoan', 'train'),
|
||||
('focal', 'ussuri'),
|
||||
])
|
||||
|
||||
|
||||
|
@ -167,6 +174,7 @@ OPENSTACK_CODENAMES = OrderedDict([
|
|||
('2018.2', 'rocky'),
|
||||
('2019.1', 'stein'),
|
||||
('2019.2', 'train'),
|
||||
('2020.1', 'ussuri'),
|
||||
])
|
||||
|
||||
# The ugly duckling - must list releases oldest to newest
|
||||
|
@ -204,7 +212,9 @@ SWIFT_CODENAMES = OrderedDict([
|
|||
('stein',
|
||||
['2.20.0', '2.21.0']),
|
||||
('train',
|
||||
['2.22.0']),
|
||||
['2.22.0', '2.23.0']),
|
||||
('ussuri',
|
||||
['2.24.0']),
|
||||
])
|
||||
|
||||
# >= Liberty version->codename mapping
|
||||
|
@ -219,6 +229,7 @@ PACKAGE_CODENAMES = {
|
|||
('18', 'rocky'),
|
||||
('19', 'stein'),
|
||||
('20', 'train'),
|
||||
('21', 'ussuri'),
|
||||
]),
|
||||
'neutron-common': OrderedDict([
|
||||
('7', 'liberty'),
|
||||
|
@ -230,6 +241,7 @@ PACKAGE_CODENAMES = {
|
|||
('13', 'rocky'),
|
||||
('14', 'stein'),
|
||||
('15', 'train'),
|
||||
('16', 'ussuri'),
|
||||
]),
|
||||
'cinder-common': OrderedDict([
|
||||
('7', 'liberty'),
|
||||
|
@ -241,6 +253,7 @@ PACKAGE_CODENAMES = {
|
|||
('13', 'rocky'),
|
||||
('14', 'stein'),
|
||||
('15', 'train'),
|
||||
('16', 'ussuri'),
|
||||
]),
|
||||
'keystone': OrderedDict([
|
||||
('8', 'liberty'),
|
||||
|
@ -252,6 +265,7 @@ PACKAGE_CODENAMES = {
|
|||
('14', 'rocky'),
|
||||
('15', 'stein'),
|
||||
('16', 'train'),
|
||||
('17', 'ussuri'),
|
||||
]),
|
||||
'horizon-common': OrderedDict([
|
||||
('8', 'liberty'),
|
||||
|
@ -263,6 +277,7 @@ PACKAGE_CODENAMES = {
|
|||
('14', 'rocky'),
|
||||
('15', 'stein'),
|
||||
('16', 'train'),
|
||||
('17', 'ussuri'),
|
||||
]),
|
||||
'ceilometer-common': OrderedDict([
|
||||
('5', 'liberty'),
|
||||
|
@ -274,6 +289,7 @@ PACKAGE_CODENAMES = {
|
|||
('11', 'rocky'),
|
||||
('12', 'stein'),
|
||||
('13', 'train'),
|
||||
('14', 'ussuri'),
|
||||
]),
|
||||
'heat-common': OrderedDict([
|
||||
('5', 'liberty'),
|
||||
|
@ -285,6 +301,7 @@ PACKAGE_CODENAMES = {
|
|||
('11', 'rocky'),
|
||||
('12', 'stein'),
|
||||
('13', 'train'),
|
||||
('14', 'ussuri'),
|
||||
]),
|
||||
'glance-common': OrderedDict([
|
||||
('11', 'liberty'),
|
||||
|
@ -296,6 +313,7 @@ PACKAGE_CODENAMES = {
|
|||
('17', 'rocky'),
|
||||
('18', 'stein'),
|
||||
('19', 'train'),
|
||||
('20', 'ussuri'),
|
||||
]),
|
||||
'openstack-dashboard': OrderedDict([
|
||||
('8', 'liberty'),
|
||||
|
@ -307,6 +325,7 @@ PACKAGE_CODENAMES = {
|
|||
('14', 'rocky'),
|
||||
('15', 'stein'),
|
||||
('16', 'train'),
|
||||
('17', 'ussuri'),
|
||||
]),
|
||||
}
|
||||
|
||||
|
@ -674,7 +693,7 @@ def openstack_upgrade_available(package):
|
|||
else:
|
||||
try:
|
||||
avail_vers = get_os_version_install_source(src)
|
||||
except:
|
||||
except Exception:
|
||||
avail_vers = cur_vers
|
||||
apt.init()
|
||||
return apt.version_compare(avail_vers, cur_vers) >= 1
|
||||
|
@ -1868,3 +1887,28 @@ def series_upgrade_complete(resume_unit_helper=None, configs=None):
|
|||
configs.write_all()
|
||||
if resume_unit_helper:
|
||||
resume_unit_helper(configs)
|
||||
|
||||
|
||||
def is_db_initialised():
|
||||
"""Check leader storage to see if database has been initialised.
|
||||
|
||||
:returns: Whether DB has been initialised
|
||||
:rtype: bool
|
||||
"""
|
||||
db_initialised = None
|
||||
if leader_get('db-initialised') is None:
|
||||
juju_log(
|
||||
'db-initialised key missing, assuming db is not initialised',
|
||||
'DEBUG')
|
||||
db_initialised = False
|
||||
else:
|
||||
db_initialised = bool_from_string(leader_get('db-initialised'))
|
||||
juju_log('Database initialised: {}'.format(db_initialised), 'DEBUG')
|
||||
return db_initialised
|
||||
|
||||
|
||||
def set_db_initialised():
|
||||
"""Add flag to leader storage to indicate database has been initialised.
|
||||
"""
|
||||
juju_log('Setting db-initialised to True', 'DEBUG')
|
||||
leader_set({'db-initialised': True})
|
||||
|
|
|
@ -37,9 +37,13 @@ class VaultKVContext(context.OSContextGenerator):
|
|||
)
|
||||
|
||||
def __call__(self):
|
||||
import hvac
|
||||
ctxt = {}
|
||||
# NOTE(hopem): see https://bugs.launchpad.net/charm-helpers/+bug/1849323
|
||||
db = unitdata.kv()
|
||||
last_token = db.get('last-token')
|
||||
# currently known-good secret-id
|
||||
secret_id = db.get('secret-id')
|
||||
|
||||
for relation_id in hookenv.relation_ids(self.interfaces[0]):
|
||||
for unit in hookenv.related_units(relation_id):
|
||||
data = hookenv.relation_get(unit=unit,
|
||||
|
@ -54,27 +58,48 @@ class VaultKVContext(context.OSContextGenerator):
|
|||
|
||||
# Tokens may change when secret_id's are being
|
||||
# reissued - if so use token to get new secret_id
|
||||
if token != last_token:
|
||||
token_success = False
|
||||
try:
|
||||
secret_id = retrieve_secret_id(
|
||||
url=vault_url,
|
||||
token=token
|
||||
)
|
||||
token_success = True
|
||||
except hvac.exceptions.InvalidRequest:
|
||||
# Try next
|
||||
pass
|
||||
|
||||
if token_success:
|
||||
db.set('secret-id', secret_id)
|
||||
db.set('last-token', token)
|
||||
db.flush()
|
||||
|
||||
ctxt = {
|
||||
'vault_url': vault_url,
|
||||
'role_id': json.loads(role_id),
|
||||
'secret_id': secret_id,
|
||||
'secret_backend': self.secret_backend,
|
||||
}
|
||||
vault_ca = data.get('vault_ca')
|
||||
if vault_ca:
|
||||
ctxt['vault_ca'] = json.loads(vault_ca)
|
||||
self.complete = True
|
||||
return ctxt
|
||||
return {}
|
||||
ctxt['vault_url'] = vault_url
|
||||
ctxt['role_id'] = json.loads(role_id)
|
||||
ctxt['secret_id'] = secret_id
|
||||
ctxt['secret_backend'] = self.secret_backend
|
||||
vault_ca = data.get('vault_ca')
|
||||
if vault_ca:
|
||||
ctxt['vault_ca'] = json.loads(vault_ca)
|
||||
|
||||
self.complete = True
|
||||
break
|
||||
else:
|
||||
if secret_id:
|
||||
ctxt['vault_url'] = vault_url
|
||||
ctxt['role_id'] = json.loads(role_id)
|
||||
ctxt['secret_id'] = secret_id
|
||||
ctxt['secret_backend'] = self.secret_backend
|
||||
vault_ca = data.get('vault_ca')
|
||||
if vault_ca:
|
||||
ctxt['vault_ca'] = json.loads(vault_ca)
|
||||
|
||||
if self.complete:
|
||||
break
|
||||
|
||||
if ctxt:
|
||||
self.complete = True
|
||||
|
||||
return ctxt
|
||||
|
||||
|
||||
def write_vaultlocker_conf(context, priority=100):
|
||||
|
|
|
@ -34,6 +34,8 @@ import errno
|
|||
import tempfile
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
from charmhelpers import deprecate
|
||||
|
||||
import six
|
||||
if not six.PY3:
|
||||
from UserDict import UserDict
|
||||
|
@ -119,19 +121,19 @@ def log(message, level=None):
|
|||
raise
|
||||
|
||||
|
||||
def action_log(message):
|
||||
"""Write an action progress message"""
|
||||
command = ['action-log']
|
||||
def function_log(message):
|
||||
"""Write a function progress message"""
|
||||
command = ['function-log']
|
||||
if not isinstance(message, six.string_types):
|
||||
message = repr(message)
|
||||
command += [message[:SH_MAX_ARG]]
|
||||
# Missing action-log should not cause failures in unit tests
|
||||
# Send action_log output to stderr
|
||||
# Missing function-log should not cause failures in unit tests
|
||||
# Send function_log output to stderr
|
||||
try:
|
||||
subprocess.call(command)
|
||||
except OSError as e:
|
||||
if e.errno == errno.ENOENT:
|
||||
message = "action-log: {}".format(message)
|
||||
message = "function-log: {}".format(message)
|
||||
print(message, file=sys.stderr)
|
||||
else:
|
||||
raise
|
||||
|
@ -964,9 +966,23 @@ def charm_dir():
|
|||
return os.environ.get('CHARM_DIR')
|
||||
|
||||
|
||||
def cmd_exists(cmd):
|
||||
"""Return True if the specified cmd exists in the path"""
|
||||
return any(
|
||||
os.access(os.path.join(path, cmd), os.X_OK)
|
||||
for path in os.environ["PATH"].split(os.pathsep)
|
||||
)
|
||||
|
||||
|
||||
@cached
|
||||
@deprecate("moved to function_get()", log=log)
|
||||
def action_get(key=None):
|
||||
"""Gets the value of an action parameter, or all key/value param pairs"""
|
||||
"""
|
||||
.. deprecated:: 0.20.7
|
||||
Alias for :func:`function_get`.
|
||||
|
||||
Gets the value of an action parameter, or all key/value param pairs.
|
||||
"""
|
||||
cmd = ['action-get']
|
||||
if key is not None:
|
||||
cmd.append(key)
|
||||
|
@ -975,36 +991,103 @@ def action_get(key=None):
|
|||
return action_data
|
||||
|
||||
|
||||
@cached
|
||||
def function_get(key=None):
|
||||
"""Gets the value of an action parameter, or all key/value param pairs"""
|
||||
cmd = ['function-get']
|
||||
# Fallback for older charms.
|
||||
if not cmd_exists('function-get'):
|
||||
cmd = ['action-get']
|
||||
|
||||
if key is not None:
|
||||
cmd.append(key)
|
||||
cmd.append('--format=json')
|
||||
function_data = json.loads(subprocess.check_output(cmd).decode('UTF-8'))
|
||||
return function_data
|
||||
|
||||
|
||||
@deprecate("moved to function_set()", log=log)
|
||||
def action_set(values):
|
||||
"""Sets the values to be returned after the action finishes"""
|
||||
"""
|
||||
.. deprecated:: 0.20.7
|
||||
Alias for :func:`function_set`.
|
||||
|
||||
Sets the values to be returned after the action finishes.
|
||||
"""
|
||||
cmd = ['action-set']
|
||||
for k, v in list(values.items()):
|
||||
cmd.append('{}={}'.format(k, v))
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def action_fail(message):
|
||||
"""Sets the action status to failed and sets the error message.
|
||||
def function_set(values):
|
||||
"""Sets the values to be returned after the function finishes"""
|
||||
cmd = ['function-set']
|
||||
# Fallback for older charms.
|
||||
if not cmd_exists('function-get'):
|
||||
cmd = ['action-set']
|
||||
|
||||
The results set by action_set are preserved."""
|
||||
for k, v in list(values.items()):
|
||||
cmd.append('{}={}'.format(k, v))
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
@deprecate("moved to function_fail()", log=log)
|
||||
def action_fail(message):
|
||||
"""
|
||||
.. deprecated:: 0.20.7
|
||||
Alias for :func:`function_fail`.
|
||||
|
||||
Sets the action status to failed and sets the error message.
|
||||
|
||||
The results set by action_set are preserved.
|
||||
"""
|
||||
subprocess.check_call(['action-fail', message])
|
||||
|
||||
|
||||
def function_fail(message):
|
||||
"""Sets the function status to failed and sets the error message.
|
||||
|
||||
The results set by function_set are preserved."""
|
||||
cmd = ['function-fail']
|
||||
# Fallback for older charms.
|
||||
if not cmd_exists('function-fail'):
|
||||
cmd = ['action-fail']
|
||||
cmd.append(message)
|
||||
|
||||
subprocess.check_call(cmd)
|
||||
|
||||
|
||||
def action_name():
|
||||
"""Get the name of the currently executing action."""
|
||||
return os.environ.get('JUJU_ACTION_NAME')
|
||||
|
||||
|
||||
def function_name():
|
||||
"""Get the name of the currently executing function."""
|
||||
return os.environ.get('JUJU_FUNCTION_NAME') or action_name()
|
||||
|
||||
|
||||
def action_uuid():
|
||||
"""Get the UUID of the currently executing action."""
|
||||
return os.environ.get('JUJU_ACTION_UUID')
|
||||
|
||||
|
||||
def function_id():
|
||||
"""Get the ID of the currently executing function."""
|
||||
return os.environ.get('JUJU_FUNCTION_ID') or action_uuid()
|
||||
|
||||
|
||||
def action_tag():
|
||||
"""Get the tag for the currently executing action."""
|
||||
return os.environ.get('JUJU_ACTION_TAG')
|
||||
|
||||
|
||||
def function_tag():
|
||||
"""Get the tag for the currently executing function."""
|
||||
return os.environ.get('JUJU_FUNCTION_TAG') or action_tag()
|
||||
|
||||
|
||||
def status_set(workload_state, message):
|
||||
"""Set the workload state with a message
|
||||
|
||||
|
|
|
@ -182,6 +182,14 @@ CLOUD_ARCHIVE_POCKETS = {
|
|||
'train/proposed': 'bionic-proposed/train',
|
||||
'bionic-train/proposed': 'bionic-proposed/train',
|
||||
'bionic-proposed/train': 'bionic-proposed/train',
|
||||
# Ussuri
|
||||
'ussuri': 'bionic-updates/ussuri',
|
||||
'bionic-ussuri': 'bionic-updates/ussuri',
|
||||
'bionic-ussuri/updates': 'bionic-updates/ussuri',
|
||||
'bionic-updates/ussuri': 'bionic-updates/ussuri',
|
||||
'ussuri/proposed': 'bionic-proposed/ussuri',
|
||||
'bionic-ussuri/proposed': 'bionic-proposed/ussuri',
|
||||
'bionic-proposed/ussuri': 'bionic-proposed/ussuri',
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue