Add xena bundles
- add non-voting focal-xena bundle - add non-voting impish-xena bundle - charm-helpers sync for new charm-helpers changes - update tox/pip.sh to ensure setuptools<50.0.0 Change-Id: Iace3419aa0cc1791d4642f15aa5e4826d3629c59
This commit is contained in:
parent
c7d8ee4c86
commit
f7d248e6e6
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2012-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -13,7 +13,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
"""Compatibility with the nrpe-external-master charm"""
|
"""Compatibility with the nrpe-external-master charm"""
|
||||||
# Copyright 2012 Canonical Ltd.
|
|
||||||
#
|
#
|
||||||
# Authors:
|
# Authors:
|
||||||
# Matthew Wedgwood <matthew.wedgwood@canonical.com>
|
# Matthew Wedgwood <matthew.wedgwood@canonical.com>
|
||||||
@ -511,7 +510,7 @@ def add_haproxy_checks(nrpe, unit_name):
|
|||||||
|
|
||||||
def remove_deprecated_check(nrpe, deprecated_services):
|
def remove_deprecated_check(nrpe, deprecated_services):
|
||||||
"""
|
"""
|
||||||
Remove checks fro deprecated services in list
|
Remove checks for deprecated services in list
|
||||||
|
|
||||||
:param nrpe: NRPE object to remove check from
|
:param nrpe: NRPE object to remove check from
|
||||||
:type nrpe: NRPE
|
:type nrpe: NRPE
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -22,7 +22,7 @@ Configuration stanzas::
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: true
|
default: true
|
||||||
description: >
|
description: >
|
||||||
If false, a volume is mounted as sepecified in "volume-map"
|
If false, a volume is mounted as specified in "volume-map"
|
||||||
If true, ephemeral storage will be used, meaning that log data
|
If true, ephemeral storage will be used, meaning that log data
|
||||||
will only exist as long as the machine. YOU HAVE BEEN WARNED.
|
will only exist as long as the machine. YOU HAVE BEEN WARNED.
|
||||||
volume-map:
|
volume-map:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -86,7 +86,7 @@ def is_elected_leader(resource):
|
|||||||
2. If the charm is part of a corosync cluster, call corosync to
|
2. If the charm is part of a corosync cluster, call corosync to
|
||||||
determine leadership.
|
determine leadership.
|
||||||
3. If the charm is not part of a corosync cluster, the leader is
|
3. If the charm is not part of a corosync cluster, the leader is
|
||||||
determined as being "the alive unit with the lowest unit numer". In
|
determined as being "the alive unit with the lowest unit number". In
|
||||||
other words, the oldest surviving unit.
|
other words, the oldest surviving unit.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@ -418,7 +418,7 @@ def get_managed_services_and_ports(services, external_ports,
|
|||||||
|
|
||||||
Return only the services and corresponding ports that are managed by this
|
Return only the services and corresponding ports that are managed by this
|
||||||
charm. This excludes haproxy when there is a relation with hacluster. This
|
charm. This excludes haproxy when there is a relation with hacluster. This
|
||||||
is because this charm passes responsability for stopping and starting
|
is because this charm passes responsibility for stopping and starting
|
||||||
haproxy to hacluster.
|
haproxy to hacluster.
|
||||||
|
|
||||||
Similarly, if a relation with hacluster exists then the ports returned by
|
Similarly, if a relation with hacluster exists then the ports returned by
|
||||||
|
@ -187,7 +187,7 @@ SYS_GID_MAX {{ sys_gid_max }}
|
|||||||
|
|
||||||
#
|
#
|
||||||
# Max number of login retries if password is bad. This will most likely be
|
# Max number of login retries if password is bad. This will most likely be
|
||||||
# overriden by PAM, since the default pam_unix module has it's own built
|
# overridden by PAM, since the default pam_unix module has it's own built
|
||||||
# in of 3 retries. However, this is a safe fallback in case you are using
|
# in of 3 retries. However, this is a safe fallback in case you are using
|
||||||
# an authentication module that does not enforce PAM_MAXTRIES.
|
# an authentication module that does not enforce PAM_MAXTRIES.
|
||||||
#
|
#
|
||||||
@ -235,7 +235,7 @@ USERGROUPS_ENAB yes
|
|||||||
#
|
#
|
||||||
# Instead of the real user shell, the program specified by this parameter
|
# Instead of the real user shell, the program specified by this parameter
|
||||||
# will be launched, although its visible name (argv[0]) will be the shell's.
|
# will be launched, although its visible name (argv[0]) will be the shell's.
|
||||||
# The program may do whatever it wants (logging, additional authentification,
|
# The program may do whatever it wants (logging, additional authentication,
|
||||||
# banner, ...) before running the actual shell.
|
# banner, ...) before running the actual shell.
|
||||||
#
|
#
|
||||||
# FAKE_SHELL /bin/fakeshell
|
# FAKE_SHELL /bin/fakeshell
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2016 Canonical Limited.
|
# Copyright 2016-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -85,7 +85,7 @@ def _get_user_provided_overrides(modules):
|
|||||||
|
|
||||||
|
|
||||||
def _apply_overrides(settings, overrides, schema):
|
def _apply_overrides(settings, overrides, schema):
|
||||||
"""Get overrides config overlayed onto modules defaults.
|
"""Get overrides config overlaid onto modules defaults.
|
||||||
|
|
||||||
:param modules: require stack modules config.
|
:param modules: require stack modules config.
|
||||||
:returns: dictionary of modules config with user overrides applied.
|
:returns: dictionary of modules config with user overrides applied.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -578,7 +578,7 @@ def get_relation_ip(interface, cidr_network=None):
|
|||||||
@returns IPv6 or IPv4 address
|
@returns IPv6 or IPv4 address
|
||||||
"""
|
"""
|
||||||
# Select the interface address first
|
# Select the interface address first
|
||||||
# For possible use as a fallback bellow with get_address_in_network
|
# For possible use as a fallback below with get_address_in_network
|
||||||
try:
|
try:
|
||||||
# Get the interface specific IP
|
# Get the interface specific IP
|
||||||
address = network_get_primary_address(interface)
|
address = network_get_primary_address(interface)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -655,7 +655,7 @@ def patch_ports_on_bridge(bridge):
|
|||||||
yield(Patch(this_end, other_end))
|
yield(Patch(this_end, other_end))
|
||||||
# We expect one result and it is ok if it turns out to be a port
|
# We expect one result and it is ok if it turns out to be a port
|
||||||
# for a different bridge. However we need a break here to satisfy
|
# for a different bridge. However we need a break here to satisfy
|
||||||
# the for/else check which is in place to detect interface refering
|
# the for/else check which is in place to detect interface referring
|
||||||
# to non-existent port.
|
# to non-existent port.
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
@ -663,7 +663,7 @@ def patch_ports_on_bridge(bridge):
|
|||||||
'not exist.'.format(interface['name']))
|
'not exist.'.format(interface['name']))
|
||||||
else:
|
else:
|
||||||
# Allow our caller to handle no patch ports found gracefully, in
|
# Allow our caller to handle no patch ports found gracefully, in
|
||||||
# reference to PEP479 just doing a return will provide a emtpy iterator
|
# reference to PEP479 just doing a return will provide a empty iterator
|
||||||
# and not None.
|
# and not None.
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2018 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# Common python helper functions used for OpenStack charm certificats.
|
# Common python helper functions used for OpenStack charm certificates.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
@ -71,7 +71,7 @@ class CertRequest(object):
|
|||||||
def add_entry(self, net_type, cn, addresses):
|
def add_entry(self, net_type, cn, addresses):
|
||||||
"""Add a request to the batch
|
"""Add a request to the batch
|
||||||
|
|
||||||
:param net_type: str netwrok space name request is for
|
:param net_type: str network space name request is for
|
||||||
:param cn: str Canonical Name for certificate
|
:param cn: str Canonical Name for certificate
|
||||||
:param addresses: [] List of addresses to be used as SANs
|
:param addresses: [] List of addresses to be used as SANs
|
||||||
"""
|
"""
|
||||||
@ -85,7 +85,7 @@ class CertRequest(object):
|
|||||||
addresses = [ip]
|
addresses = [ip]
|
||||||
# If a vip is being used without os-hostname config or
|
# If a vip is being used without os-hostname config or
|
||||||
# network spaces then we need to ensure the local units
|
# network spaces then we need to ensure the local units
|
||||||
# cert has the approriate vip in the SAN list
|
# cert has the appropriate vip in the SAN list
|
||||||
vip = get_vip_in_network(resolve_network_cidr(ip))
|
vip = get_vip_in_network(resolve_network_cidr(ip))
|
||||||
if vip:
|
if vip:
|
||||||
addresses.append(vip)
|
addresses.append(vip)
|
||||||
@ -178,7 +178,7 @@ def get_certificate_request(json_encode=True, bindings=None):
|
|||||||
except NoNetworkBinding:
|
except NoNetworkBinding:
|
||||||
log("Skipping request for certificate for ip in {} space, no "
|
log("Skipping request for certificate for ip in {} space, no "
|
||||||
"local address found".format(binding), WARNING)
|
"local address found".format(binding), WARNING)
|
||||||
# Gurantee all SANs are covered
|
# Guarantee all SANs are covered
|
||||||
# These are network addresses with no corresponding hostname.
|
# These are network addresses with no corresponding hostname.
|
||||||
# Add the ips to the hostname cert to allow for this.
|
# Add the ips to the hostname cert to allow for this.
|
||||||
req.add_hostname_cn_ip(_sans)
|
req.add_hostname_cn_ip(_sans)
|
||||||
@ -357,7 +357,7 @@ def process_certificates(service_name, relation_id, unit,
|
|||||||
bindings=None):
|
bindings=None):
|
||||||
"""Process the certificates supplied down the relation
|
"""Process the certificates supplied down the relation
|
||||||
|
|
||||||
:param service_name: str Name of service the certifcates are for.
|
:param service_name: str Name of service the certificates are for.
|
||||||
:param relation_id: str Relation id providing the certs
|
:param relation_id: str Relation id providing the certs
|
||||||
:param unit: str Unit providing the certs
|
:param unit: str Unit providing the certs
|
||||||
:param custom_hostname_link: str Name of custom link to create
|
:param custom_hostname_link: str Name of custom link to create
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -1367,7 +1367,7 @@ class NeutronPortContext(OSContextGenerator):
|
|||||||
mac_regex = re.compile(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})', re.I)
|
mac_regex = re.compile(r'([0-9A-F]{2}[:-]){5}([0-9A-F]{2})', re.I)
|
||||||
for entry in ports:
|
for entry in ports:
|
||||||
if re.match(mac_regex, entry):
|
if re.match(mac_regex, entry):
|
||||||
# NIC is in known NICs and does NOT hace an IP address
|
# NIC is in known NICs and does NOT have an IP address
|
||||||
if entry in hwaddr_to_nic and not hwaddr_to_ip[entry]:
|
if entry in hwaddr_to_nic and not hwaddr_to_ip[entry]:
|
||||||
# If the nic is part of a bridge then don't use it
|
# If the nic is part of a bridge then don't use it
|
||||||
if is_bridge_member(hwaddr_to_nic[entry]):
|
if is_bridge_member(hwaddr_to_nic[entry]):
|
||||||
@ -2397,6 +2397,12 @@ class DHCPAgentContext(OSContextGenerator):
|
|||||||
ctxt['enable_metadata_network'] = True
|
ctxt['enable_metadata_network'] = True
|
||||||
ctxt['enable_isolated_metadata'] = True
|
ctxt['enable_isolated_metadata'] = True
|
||||||
|
|
||||||
|
ctxt['append_ovs_config'] = False
|
||||||
|
cmp_release = CompareOpenStackReleases(
|
||||||
|
os_release('neutron-common', base='icehouse'))
|
||||||
|
if cmp_release >= 'queens' and config('enable-dpdk'):
|
||||||
|
ctxt['append_ovs_config'] = True
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -2588,12 +2594,30 @@ class OVSDPDKDeviceContext(OSContextGenerator):
|
|||||||
:returns: hex formatted CPU mask
|
:returns: hex formatted CPU mask
|
||||||
:rtype: str
|
:rtype: str
|
||||||
"""
|
"""
|
||||||
num_cores = config('dpdk-socket-cores')
|
return self.cpu_masks()['dpdk_lcore_mask']
|
||||||
mask = 0
|
|
||||||
|
def cpu_masks(self):
|
||||||
|
"""Get hex formatted CPU masks
|
||||||
|
|
||||||
|
The mask is based on using the first config:dpdk-socket-cores
|
||||||
|
cores of each NUMA node in the unit, followed by the
|
||||||
|
next config:pmd-socket-cores
|
||||||
|
|
||||||
|
:returns: Dict of hex formatted CPU masks
|
||||||
|
:rtype: Dict[str, str]
|
||||||
|
"""
|
||||||
|
num_lcores = config('dpdk-socket-cores')
|
||||||
|
pmd_cores = config('pmd-socket-cores')
|
||||||
|
lcore_mask = 0
|
||||||
|
pmd_mask = 0
|
||||||
for cores in self._numa_node_cores().values():
|
for cores in self._numa_node_cores().values():
|
||||||
for core in cores[:num_cores]:
|
for core in cores[:num_lcores]:
|
||||||
mask = mask | 1 << core
|
lcore_mask = lcore_mask | 1 << core
|
||||||
return format(mask, '#04x')
|
for core in cores[num_lcores:][:pmd_cores]:
|
||||||
|
pmd_mask = pmd_mask | 1 << core
|
||||||
|
return {
|
||||||
|
'pmd_cpu_mask': format(pmd_mask, '#04x'),
|
||||||
|
'dpdk_lcore_mask': format(lcore_mask, '#04x')}
|
||||||
|
|
||||||
def socket_memory(self):
|
def socket_memory(self):
|
||||||
"""Formatted list of socket memory configuration per socket.
|
"""Formatted list of socket memory configuration per socket.
|
||||||
@ -2676,7 +2700,7 @@ class OVSDPDKDeviceContext(OSContextGenerator):
|
|||||||
|
|
||||||
|
|
||||||
class BridgePortInterfaceMap(object):
|
class BridgePortInterfaceMap(object):
|
||||||
"""Build a map of bridge ports and interaces from charm configuration.
|
"""Build a map of bridge ports and interfaces from charm configuration.
|
||||||
|
|
||||||
NOTE: the handling of this detail in the charm is pre-deprecated.
|
NOTE: the handling of this detail in the charm is pre-deprecated.
|
||||||
|
|
||||||
@ -3125,7 +3149,7 @@ class SRIOVContext(OSContextGenerator):
|
|||||||
actual = min(int(requested), int(device.sriov_totalvfs))
|
actual = min(int(requested), int(device.sriov_totalvfs))
|
||||||
if actual < int(requested):
|
if actual < int(requested):
|
||||||
log('Requested VFs ({}) too high for device {}. Falling back '
|
log('Requested VFs ({}) too high for device {}. Falling back '
|
||||||
'to value supprted by device: {}'
|
'to value supported by device: {}'
|
||||||
.format(requested, device.interface_name,
|
.format(requested, device.interface_name,
|
||||||
device.sriov_totalvfs),
|
device.sriov_totalvfs),
|
||||||
level=WARNING)
|
level=WARNING)
|
||||||
|
@ -244,7 +244,7 @@ def get_deferred_restarts():
|
|||||||
|
|
||||||
|
|
||||||
def clear_deferred_restarts(services):
|
def clear_deferred_restarts(services):
|
||||||
"""Clear deferred restart events targetted at `services`.
|
"""Clear deferred restart events targeted at `services`.
|
||||||
|
|
||||||
:param services: Services with deferred actions to clear.
|
:param services: Services with deferred actions to clear.
|
||||||
:type services: List[str]
|
:type services: List[str]
|
||||||
@ -253,7 +253,7 @@ def clear_deferred_restarts(services):
|
|||||||
|
|
||||||
|
|
||||||
def process_svc_restart(service):
|
def process_svc_restart(service):
|
||||||
"""Respond to a service restart having occured.
|
"""Respond to a service restart having occurred.
|
||||||
|
|
||||||
:param service: Services that the action was performed against.
|
:param service: Services that the action was performed against.
|
||||||
:type service: str
|
:type service: str
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
"""This script is an implemenation of policy-rc.d
|
"""This script is an implementation of policy-rc.d
|
||||||
|
|
||||||
For further information on policy-rc.d see *1
|
For further information on policy-rc.d see *1
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,7 +12,7 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# Various utilies for dealing with Neutron and the renaming from Quantum.
|
# Various utilities for dealing with Neutron and the renaming from Quantum.
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
@ -251,7 +251,7 @@ def neutron_plugin_attribute(plugin, attr, net_manager=None):
|
|||||||
def network_manager():
|
def network_manager():
|
||||||
'''
|
'''
|
||||||
Deals with the renaming of Quantum to Neutron in H and any situations
|
Deals with the renaming of Quantum to Neutron in H and any situations
|
||||||
that require compatability (eg, deploying H with network-manager=quantum,
|
that require compatibility (eg, deploying H with network-manager=quantum,
|
||||||
upgrading from G).
|
upgrading from G).
|
||||||
'''
|
'''
|
||||||
release = os_release('nova-common')
|
release = os_release('nova-common')
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2019 Canonical Ltd
|
# Copyright 2019-2021 Canonical Ltd
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -59,7 +59,7 @@ provided:
|
|||||||
The functions should be called from the install and upgrade hooks in the charm.
|
The functions should be called from the install and upgrade hooks in the charm.
|
||||||
The `maybe_do_policyd_overrides_on_config_changed` function is designed to be
|
The `maybe_do_policyd_overrides_on_config_changed` function is designed to be
|
||||||
called on the config-changed hook, in that it does an additional check to
|
called on the config-changed hook, in that it does an additional check to
|
||||||
ensure that an already overriden policy.d in an upgrade or install hooks isn't
|
ensure that an already overridden policy.d in an upgrade or install hooks isn't
|
||||||
repeated.
|
repeated.
|
||||||
|
|
||||||
In order the *enable* this functionality, the charm's install, config_changed,
|
In order the *enable* this functionality, the charm's install, config_changed,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -660,7 +660,7 @@ def import_key(keyid):
|
|||||||
def get_source_and_pgp_key(source_and_key):
|
def get_source_and_pgp_key(source_and_key):
|
||||||
"""Look for a pgp key ID or ascii-armor key in the given input.
|
"""Look for a pgp key ID or ascii-armor key in the given input.
|
||||||
|
|
||||||
:param source_and_key: Sting, "source_spec|keyid" where '|keyid' is
|
:param source_and_key: String, "source_spec|keyid" where '|keyid' is
|
||||||
optional.
|
optional.
|
||||||
:returns (source_spec, key_id OR None) as a tuple. Returns None for key_id
|
:returns (source_spec, key_id OR None) as a tuple. Returns None for key_id
|
||||||
if there was no '|' in the source_and_key string.
|
if there was no '|' in the source_and_key string.
|
||||||
@ -680,7 +680,7 @@ def configure_installation_source(source_plus_key):
|
|||||||
The functionality is provided by charmhelpers.fetch.add_source()
|
The functionality is provided by charmhelpers.fetch.add_source()
|
||||||
The difference between the two functions is that add_source() signature
|
The difference between the two functions is that add_source() signature
|
||||||
requires the key to be passed directly, whereas this function passes an
|
requires the key to be passed directly, whereas this function passes an
|
||||||
optional key by appending '|<key>' to the end of the source specificiation
|
optional key by appending '|<key>' to the end of the source specification
|
||||||
'source'.
|
'source'.
|
||||||
|
|
||||||
Another difference from add_source() is that the function calls sys.exit(1)
|
Another difference from add_source() is that the function calls sys.exit(1)
|
||||||
@ -767,7 +767,7 @@ def get_endpoint_notifications(service_names, rel_name='identity-service'):
|
|||||||
|
|
||||||
|
|
||||||
def endpoint_changed(service_name, rel_name='identity-service'):
|
def endpoint_changed(service_name, rel_name='identity-service'):
|
||||||
"""Whether a new notification has been recieved for an endpoint.
|
"""Whether a new notification has been received for an endpoint.
|
||||||
|
|
||||||
:param service_name: Service name eg nova, neutron, placement etc
|
:param service_name: Service name eg nova, neutron, placement etc
|
||||||
:type service_name: str
|
:type service_name: str
|
||||||
@ -793,7 +793,7 @@ def endpoint_changed(service_name, rel_name='identity-service'):
|
|||||||
|
|
||||||
|
|
||||||
def save_endpoint_changed_triggers(service_names, rel_name='identity-service'):
|
def save_endpoint_changed_triggers(service_names, rel_name='identity-service'):
|
||||||
"""Save the enpoint triggers in db so it can be tracked if they changed.
|
"""Save the endpoint triggers in db so it can be tracked if they changed.
|
||||||
|
|
||||||
:param service_names: List of service name.
|
:param service_names: List of service name.
|
||||||
:type service_name: List
|
:type service_name: List
|
||||||
@ -1461,9 +1461,9 @@ def remote_restart(rel_name, remote_service=None):
|
|||||||
if remote_service:
|
if remote_service:
|
||||||
trigger['remote-service'] = remote_service
|
trigger['remote-service'] = remote_service
|
||||||
for rid in relation_ids(rel_name):
|
for rid in relation_ids(rel_name):
|
||||||
# This subordinate can be related to two seperate services using
|
# This subordinate can be related to two separate services using
|
||||||
# different subordinate relations so only issue the restart if
|
# different subordinate relations so only issue the restart if
|
||||||
# the principle is conencted down the relation we think it is
|
# the principle is connected down the relation we think it is
|
||||||
if related_units(relid=rid):
|
if related_units(relid=rid):
|
||||||
relation_set(relation_id=rid,
|
relation_set(relation_id=rid,
|
||||||
relation_settings=trigger,
|
relation_settings=trigger,
|
||||||
@ -1580,7 +1580,7 @@ def manage_payload_services(action, services=None, charm_func=None):
|
|||||||
"""Run an action against all services.
|
"""Run an action against all services.
|
||||||
|
|
||||||
An optional charm_func() can be called. It should raise an Exception to
|
An optional charm_func() can be called. It should raise an Exception to
|
||||||
indicate that the function failed. If it was succesfull it should return
|
indicate that the function failed. If it was successful it should return
|
||||||
None or an optional message.
|
None or an optional message.
|
||||||
|
|
||||||
The signature for charm_func is:
|
The signature for charm_func is:
|
||||||
@ -1839,7 +1839,7 @@ def pausable_restart_on_change(restart_map, stopstart=False,
|
|||||||
:param post_svc_restart_f: A function run after a service has
|
:param post_svc_restart_f: A function run after a service has
|
||||||
restarted.
|
restarted.
|
||||||
:type post_svc_restart_f: Callable[[str], None]
|
:type post_svc_restart_f: Callable[[str], None]
|
||||||
:param pre_restarts_wait_f: A function callled before any restarts.
|
:param pre_restarts_wait_f: A function called before any restarts.
|
||||||
:type pre_restarts_wait_f: Callable[None, None]
|
:type pre_restarts_wait_f: Callable[None, None]
|
||||||
:returns: decorator to use a restart_on_change with pausability
|
:returns: decorator to use a restart_on_change with pausability
|
||||||
:rtype: decorator
|
:rtype: decorator
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2018 Canonical Limited.
|
# Copyright 2018-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -48,7 +48,7 @@ class VaultKVContext(context.OSContextGenerator):
|
|||||||
"but it's not available. Is secrets-stroage relation "
|
"but it's not available. Is secrets-stroage relation "
|
||||||
"made, but encrypt option not set?",
|
"made, but encrypt option not set?",
|
||||||
level=hookenv.WARNING)
|
level=hookenv.WARNING)
|
||||||
# return an emptry context on hvac import error
|
# return an empty context on hvac import error
|
||||||
return {}
|
return {}
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
# NOTE(hopem): see https://bugs.launchpad.net/charm-helpers/+bug/1849323
|
# NOTE(hopem): see https://bugs.launchpad.net/charm-helpers/+bug/1849323
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -12,9 +12,6 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
#
|
|
||||||
# Copyright 2012 Canonical Ltd.
|
|
||||||
#
|
|
||||||
# This file is sourced from lp:openstack-charm-helpers
|
# This file is sourced from lp:openstack-charm-helpers
|
||||||
#
|
#
|
||||||
# Authors:
|
# Authors:
|
||||||
@ -605,7 +602,7 @@ class BasePool(object):
|
|||||||
|
|
||||||
|
|
||||||
class Pool(BasePool):
|
class Pool(BasePool):
|
||||||
"""Compability shim for any descendents external to this library."""
|
"""Compatibility shim for any descendents external to this library."""
|
||||||
|
|
||||||
@deprecate(
|
@deprecate(
|
||||||
'The ``Pool`` baseclass has been replaced by ``BasePool`` class.')
|
'The ``Pool`` baseclass has been replaced by ``BasePool`` class.')
|
||||||
@ -1535,7 +1532,7 @@ def map_block_storage(service, pool, image):
|
|||||||
|
|
||||||
|
|
||||||
def filesystem_mounted(fs):
|
def filesystem_mounted(fs):
|
||||||
"""Determine whether a filesytems is already mounted."""
|
"""Determine whether a filesystem is already mounted."""
|
||||||
return fs in [f for f, m in mounts()]
|
return fs in [f for f, m in mounts()]
|
||||||
|
|
||||||
|
|
||||||
@ -1904,7 +1901,7 @@ class CephBrokerRq(object):
|
|||||||
set the ceph-mon unit handling the broker
|
set the ceph-mon unit handling the broker
|
||||||
request will set its default value.
|
request will set its default value.
|
||||||
:type erasure_profile: str
|
:type erasure_profile: str
|
||||||
:param allow_ec_overwrites: allow EC pools to be overriden
|
:param allow_ec_overwrites: allow EC pools to be overridden
|
||||||
:type allow_ec_overwrites: bool
|
:type allow_ec_overwrites: bool
|
||||||
:raises: AssertionError if provided data is of invalid type/range
|
:raises: AssertionError if provided data is of invalid type/range
|
||||||
"""
|
"""
|
||||||
@ -1949,7 +1946,7 @@ class CephBrokerRq(object):
|
|||||||
:param lrc_locality: Group the coding and data chunks into sets of size locality
|
:param lrc_locality: Group the coding and data chunks into sets of size locality
|
||||||
(lrc plugin)
|
(lrc plugin)
|
||||||
:type lrc_locality: int
|
:type lrc_locality: int
|
||||||
:param durability_estimator: The number of parity chuncks each of which includes
|
:param durability_estimator: The number of parity chunks each of which includes
|
||||||
a data chunk in its calculation range (shec plugin)
|
a data chunk in its calculation range (shec plugin)
|
||||||
:type durability_estimator: int
|
:type durability_estimator: int
|
||||||
:param helper_chunks: The number of helper chunks to use for recovery operations
|
:param helper_chunks: The number of helper chunks to use for recovery operations
|
||||||
@ -2327,7 +2324,7 @@ class CephOSDConfContext(CephConfContext):
|
|||||||
settings are in conf['osd_from_client'] and finally settings which do
|
settings are in conf['osd_from_client'] and finally settings which do
|
||||||
clash are in conf['osd_from_client_conflict']. Rather than silently drop
|
clash are in conf['osd_from_client_conflict']. Rather than silently drop
|
||||||
the conflicting settings they are provided in the context so they can be
|
the conflicting settings they are provided in the context so they can be
|
||||||
rendered commented out to give some visability to the admin.
|
rendered commented out to give some visibility to the admin.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, permitted_sections=None):
|
def __init__(self, permitted_sections=None):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -27,7 +27,7 @@ from subprocess import (
|
|||||||
##################################################
|
##################################################
|
||||||
def deactivate_lvm_volume_group(block_device):
|
def deactivate_lvm_volume_group(block_device):
|
||||||
'''
|
'''
|
||||||
Deactivate any volume gruop associated with an LVM physical volume.
|
Deactivate any volume group associated with an LVM physical volume.
|
||||||
|
|
||||||
:param block_device: str: Full path to LVM physical volume
|
:param block_device: str: Full path to LVM physical volume
|
||||||
'''
|
'''
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2013-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -13,7 +13,6 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
"Interactions with the Juju environment"
|
"Interactions with the Juju environment"
|
||||||
# Copyright 2013 Canonical Ltd.
|
|
||||||
#
|
#
|
||||||
# Authors:
|
# Authors:
|
||||||
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
# Charm Helpers Developers <juju@lists.ubuntu.com>
|
||||||
@ -610,7 +609,7 @@ def expected_related_units(reltype=None):
|
|||||||
relation_type()))
|
relation_type()))
|
||||||
|
|
||||||
:param reltype: Relation type to list data for, default is to list data for
|
:param reltype: Relation type to list data for, default is to list data for
|
||||||
the realtion type we are currently executing a hook for.
|
the relation type we are currently executing a hook for.
|
||||||
:type reltype: str
|
:type reltype: str
|
||||||
:returns: iterator
|
:returns: iterator
|
||||||
:rtype: types.GeneratorType
|
:rtype: types.GeneratorType
|
||||||
@ -627,7 +626,7 @@ def expected_related_units(reltype=None):
|
|||||||
|
|
||||||
@cached
|
@cached
|
||||||
def relation_for_unit(unit=None, rid=None):
|
def relation_for_unit(unit=None, rid=None):
|
||||||
"""Get the json represenation of a unit's relation"""
|
"""Get the json representation of a unit's relation"""
|
||||||
unit = unit or remote_unit()
|
unit = unit or remote_unit()
|
||||||
relation = relation_get(unit=unit, rid=rid)
|
relation = relation_get(unit=unit, rid=rid)
|
||||||
for key in relation:
|
for key in relation:
|
||||||
@ -1614,11 +1613,11 @@ def env_proxy_settings(selected_settings=None):
|
|||||||
def _contains_range(addresses):
|
def _contains_range(addresses):
|
||||||
"""Check for cidr or wildcard domain in a string.
|
"""Check for cidr or wildcard domain in a string.
|
||||||
|
|
||||||
Given a string comprising a comma seperated list of ip addresses
|
Given a string comprising a comma separated list of ip addresses
|
||||||
and domain names, determine whether the string contains IP ranges
|
and domain names, determine whether the string contains IP ranges
|
||||||
or wildcard domains.
|
or wildcard domains.
|
||||||
|
|
||||||
:param addresses: comma seperated list of domains and ip addresses.
|
:param addresses: comma separated list of domains and ip addresses.
|
||||||
:type addresses: str
|
:type addresses: str
|
||||||
"""
|
"""
|
||||||
return (
|
return (
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -217,7 +217,7 @@ def service_resume(service_name, init_dir="/etc/init",
|
|||||||
initd_dir="/etc/init.d", **kwargs):
|
initd_dir="/etc/init.d", **kwargs):
|
||||||
"""Resume a system service.
|
"""Resume a system service.
|
||||||
|
|
||||||
Reenable starting again at boot. Start the service.
|
Re-enable starting again at boot. Start the service.
|
||||||
|
|
||||||
:param service_name: the name of the service to resume
|
:param service_name: the name of the service to resume
|
||||||
:param init_dir: the path to the init dir
|
:param init_dir: the path to the init dir
|
||||||
@ -727,7 +727,7 @@ class restart_on_change(object):
|
|||||||
:param post_svc_restart_f: A function run after a service has
|
:param post_svc_restart_f: A function run after a service has
|
||||||
restarted.
|
restarted.
|
||||||
:type post_svc_restart_f: Callable[[str], None]
|
:type post_svc_restart_f: Callable[[str], None]
|
||||||
:param pre_restarts_wait_f: A function callled before any restarts.
|
:param pre_restarts_wait_f: A function called before any restarts.
|
||||||
:type pre_restarts_wait_f: Callable[None, None]
|
:type pre_restarts_wait_f: Callable[None, None]
|
||||||
"""
|
"""
|
||||||
self.restart_map = restart_map
|
self.restart_map = restart_map
|
||||||
@ -828,7 +828,7 @@ def restart_on_change_helper(lambda_f, restart_map, stopstart=False,
|
|||||||
:param post_svc_restart_f: A function run after a service has
|
:param post_svc_restart_f: A function run after a service has
|
||||||
restarted.
|
restarted.
|
||||||
:type post_svc_restart_f: Callable[[str], None]
|
:type post_svc_restart_f: Callable[[str], None]
|
||||||
:param pre_restarts_wait_f: A function callled before any restarts.
|
:param pre_restarts_wait_f: A function called before any restarts.
|
||||||
:type pre_restarts_wait_f: Callable[None, None]
|
:type pre_restarts_wait_f: Callable[None, None]
|
||||||
:returns: result of lambda_f()
|
:returns: result of lambda_f()
|
||||||
:rtype: ANY
|
:rtype: ANY
|
||||||
@ -880,7 +880,7 @@ def _post_restart_on_change_helper(checksums,
|
|||||||
:param post_svc_restart_f: A function run after a service has
|
:param post_svc_restart_f: A function run after a service has
|
||||||
restarted.
|
restarted.
|
||||||
:type post_svc_restart_f: Callable[[str], None]
|
:type post_svc_restart_f: Callable[[str], None]
|
||||||
:param pre_restarts_wait_f: A function callled before any restarts.
|
:param pre_restarts_wait_f: A function called before any restarts.
|
||||||
:type pre_restarts_wait_f: Callable[None, None]
|
:type pre_restarts_wait_f: Callable[None, None]
|
||||||
"""
|
"""
|
||||||
if restart_functions is None:
|
if restart_functions is None:
|
||||||
@ -914,7 +914,7 @@ def _post_restart_on_change_helper(checksums,
|
|||||||
|
|
||||||
|
|
||||||
def pwgen(length=None):
|
def pwgen(length=None):
|
||||||
"""Generate a random pasword."""
|
"""Generate a random password."""
|
||||||
if length is None:
|
if length is None:
|
||||||
# A random length is ok to use a weak PRNG
|
# A random length is ok to use a weak PRNG
|
||||||
length = random.choice(range(35, 45))
|
length = random.choice(range(35, 45))
|
||||||
|
@ -28,6 +28,7 @@ UBUNTU_RELEASES = (
|
|||||||
'focal',
|
'focal',
|
||||||
'groovy',
|
'groovy',
|
||||||
'hirsute',
|
'hirsute',
|
||||||
|
'impish',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,8 +18,11 @@
|
|||||||
import six
|
import six
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
TRUTHY_STRINGS = {'y', 'yes', 'true', 't', 'on'}
|
||||||
|
FALSEY_STRINGS = {'n', 'no', 'false', 'f', 'off'}
|
||||||
|
|
||||||
def bool_from_string(value):
|
|
||||||
|
def bool_from_string(value, truthy_strings=TRUTHY_STRINGS, falsey_strings=FALSEY_STRINGS, assume_false=False):
|
||||||
"""Interpret string value as boolean.
|
"""Interpret string value as boolean.
|
||||||
|
|
||||||
Returns True if value translates to True otherwise False.
|
Returns True if value translates to True otherwise False.
|
||||||
@ -32,9 +35,9 @@ def bool_from_string(value):
|
|||||||
|
|
||||||
value = value.strip().lower()
|
value = value.strip().lower()
|
||||||
|
|
||||||
if value in ['y', 'yes', 'true', 't', 'on']:
|
if value in truthy_strings:
|
||||||
return True
|
return True
|
||||||
elif value in ['n', 'no', 'false', 'f', 'off']:
|
elif value in falsey_strings or assume_false:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
msg = "Unable to interpret string value '%s' as boolean" % (value)
|
msg = "Unable to interpret string value '%s' as boolean" % (value)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -61,7 +61,7 @@ Here's a fully worked integration example using hookenv.Hooks::
|
|||||||
'previous value', prev,
|
'previous value', prev,
|
||||||
'current value', cur)
|
'current value', cur)
|
||||||
|
|
||||||
# Get some unit specific bookeeping
|
# Get some unit specific bookkeeping
|
||||||
if not db.get('pkg_key'):
|
if not db.get('pkg_key'):
|
||||||
key = urllib.urlopen('https://example.com/pkg_key').read()
|
key = urllib.urlopen('https://example.com/pkg_key').read()
|
||||||
db.set('pkg_key', key)
|
db.set('pkg_key', key)
|
||||||
@ -449,7 +449,7 @@ class HookData(object):
|
|||||||
'previous value', prev,
|
'previous value', prev,
|
||||||
'current value', cur)
|
'current value', cur)
|
||||||
|
|
||||||
# Get some unit specific bookeeping
|
# Get some unit specific bookkeeping
|
||||||
if not db.get('pkg_key'):
|
if not db.get('pkg_key'):
|
||||||
key = urllib.urlopen('https://example.com/pkg_key').read()
|
key = urllib.urlopen('https://example.com/pkg_key').read()
|
||||||
db.set('pkg_key', key)
|
db.set('pkg_key', key)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -205,7 +205,7 @@ def plugins(fetch_handlers=None):
|
|||||||
classname)
|
classname)
|
||||||
plugin_list.append(handler_class())
|
plugin_list.append(handler_class())
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
# Skip missing plugins so that they can be ommitted from
|
# Skip missing plugins so that they can be omitted from
|
||||||
# installation if desired
|
# installation if desired
|
||||||
log("FetchHandler {} not found, skipping plugin".format(
|
log("FetchHandler {} not found, skipping plugin".format(
|
||||||
handler_name))
|
handler_name))
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -27,7 +27,7 @@ __author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
|
|||||||
|
|
||||||
|
|
||||||
def pip_execute(*args, **kwargs):
|
def pip_execute(*args, **kwargs):
|
||||||
"""Overriden pip_execute() to stop sys.path being changed.
|
"""Overridden pip_execute() to stop sys.path being changed.
|
||||||
|
|
||||||
The act of importing main from the pip module seems to cause add wheels
|
The act of importing main from the pip module seems to cause add wheels
|
||||||
from the /usr/share/python-wheels which are installed by various tools.
|
from the /usr/share/python-wheels which are installed by various tools.
|
||||||
@ -142,8 +142,10 @@ def pip_create_virtualenv(path=None):
|
|||||||
"""Create an isolated Python environment."""
|
"""Create an isolated Python environment."""
|
||||||
if six.PY2:
|
if six.PY2:
|
||||||
apt_install('python-virtualenv')
|
apt_install('python-virtualenv')
|
||||||
|
extra_flags = []
|
||||||
else:
|
else:
|
||||||
apt_install('python3-virtualenv')
|
apt_install(['python3-virtualenv', 'virtualenv'])
|
||||||
|
extra_flags = ['--python=python3']
|
||||||
|
|
||||||
if path:
|
if path:
|
||||||
venv_path = path
|
venv_path = path
|
||||||
@ -151,4 +153,4 @@ def pip_create_virtualenv(path=None):
|
|||||||
venv_path = os.path.join(charm_dir(), 'venv')
|
venv_path = os.path.join(charm_dir(), 'venv')
|
||||||
|
|
||||||
if not os.path.exists(venv_path):
|
if not os.path.exists(venv_path):
|
||||||
subprocess.check_call(['virtualenv', venv_path])
|
subprocess.check_call(['virtualenv', venv_path] + extra_flags)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2017 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -65,7 +65,7 @@ def _snap_exec(commands):
|
|||||||
retry_count += + 1
|
retry_count += + 1
|
||||||
if retry_count > SNAP_NO_LOCK_RETRY_COUNT:
|
if retry_count > SNAP_NO_LOCK_RETRY_COUNT:
|
||||||
raise CouldNotAcquireLockException(
|
raise CouldNotAcquireLockException(
|
||||||
'Could not aquire lock after {} attempts'
|
'Could not acquire lock after {} attempts'
|
||||||
.format(SNAP_NO_LOCK_RETRY_COUNT))
|
.format(SNAP_NO_LOCK_RETRY_COUNT))
|
||||||
return_code = e.returncode
|
return_code = e.returncode
|
||||||
log('Snap failed to acquire lock, trying again in {} seconds.'
|
log('Snap failed to acquire lock, trying again in {} seconds.'
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2014-2015 Canonical Limited.
|
# Copyright 2014-2021 Canonical Limited.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -313,9 +313,9 @@ def filter_missing_packages(packages):
|
|||||||
def apt_cache(*_, **__):
|
def apt_cache(*_, **__):
|
||||||
"""Shim returning an object simulating the apt_pkg Cache.
|
"""Shim returning an object simulating the apt_pkg Cache.
|
||||||
|
|
||||||
:param _: Accept arguments for compability, not used.
|
:param _: Accept arguments for compatibility, not used.
|
||||||
:type _: any
|
:type _: any
|
||||||
:param __: Accept keyword arguments for compability, not used.
|
:param __: Accept keyword arguments for compatibility, not used.
|
||||||
:type __: any
|
:type __: any
|
||||||
:returns:Object used to interrogate the system apt and dpkg databases.
|
:returns:Object used to interrogate the system apt and dpkg databases.
|
||||||
:rtype:ubuntu_apt_pkg.Cache
|
:rtype:ubuntu_apt_pkg.Cache
|
||||||
@ -350,7 +350,7 @@ def apt_install(packages, options=None, fatal=False, quiet=False):
|
|||||||
:param fatal: Whether the command's output should be checked and
|
:param fatal: Whether the command's output should be checked and
|
||||||
retried.
|
retried.
|
||||||
:type fatal: bool
|
:type fatal: bool
|
||||||
:param quiet: if True (default), supress log message to stdout/stderr
|
:param quiet: if True (default), suppress log message to stdout/stderr
|
||||||
:type quiet: bool
|
:type quiet: bool
|
||||||
:raises: subprocess.CalledProcessError
|
:raises: subprocess.CalledProcessError
|
||||||
"""
|
"""
|
||||||
@ -464,7 +464,7 @@ def import_key(key):
|
|||||||
A Radix64 format keyid is also supported for backwards
|
A Radix64 format keyid is also supported for backwards
|
||||||
compatibility. In this case Ubuntu keyserver will be
|
compatibility. In this case Ubuntu keyserver will be
|
||||||
queried for a key via HTTPS by its keyid. This method
|
queried for a key via HTTPS by its keyid. This method
|
||||||
is less preferrable because https proxy servers may
|
is less preferable because https proxy servers may
|
||||||
require traffic decryption which is equivalent to a
|
require traffic decryption which is equivalent to a
|
||||||
man-in-the-middle attack (a proxy server impersonates
|
man-in-the-middle attack (a proxy server impersonates
|
||||||
keyserver TLS certificates and has to be explicitly
|
keyserver TLS certificates and has to be explicitly
|
||||||
@ -663,7 +663,7 @@ def add_source(source, key=None, fail_invalid=False):
|
|||||||
id may also be used, but be aware that only insecure protocols are
|
id may also be used, but be aware that only insecure protocols are
|
||||||
available to retrieve the actual public key from a public keyserver
|
available to retrieve the actual public key from a public keyserver
|
||||||
placing your Juju environment at risk. ppa and cloud archive keys
|
placing your Juju environment at risk. ppa and cloud archive keys
|
||||||
are securely added automtically, so sould not be provided.
|
are securely added automatically, so should not be provided.
|
||||||
|
|
||||||
@param fail_invalid: (boolean) if True, then the function raises a
|
@param fail_invalid: (boolean) if True, then the function raises a
|
||||||
SourceConfigError is there is no matching installation source.
|
SourceConfigError is there is no matching installation source.
|
||||||
@ -720,7 +720,7 @@ def _add_proposed():
|
|||||||
Uses get_distrib_codename to determine the correct stanza for
|
Uses get_distrib_codename to determine the correct stanza for
|
||||||
the deb line.
|
the deb line.
|
||||||
|
|
||||||
For intel architecutres PROPOSED_POCKET is used for the release, but for
|
For Intel architectures PROPOSED_POCKET is used for the release, but for
|
||||||
other architectures PROPOSED_PORTS_POCKET is used for the release.
|
other architectures PROPOSED_PORTS_POCKET is used for the release.
|
||||||
"""
|
"""
|
||||||
release = get_distrib_codename()
|
release = get_distrib_codename()
|
||||||
@ -881,7 +881,7 @@ def __add_bare_helper(openstack_release, pocket_format, final_function):
|
|||||||
.format(ubuntu_version))
|
.format(ubuntu_version))
|
||||||
except AssertionError:
|
except AssertionError:
|
||||||
raise SourceConfigError(
|
raise SourceConfigError(
|
||||||
'Invalid OpenStack release specificed: {} for ubuntu version {}'
|
'Invalid OpenStack release specified: {} for Ubuntu version {}'
|
||||||
.format(openstack_release, ubuntu_version))
|
.format(openstack_release, ubuntu_version))
|
||||||
final_function()
|
final_function()
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright 2019 Canonical Ltd
|
# Copyright 2019-2021 Canonical Ltd
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
# you may not use this file except in compliance with the License.
|
# you may not use this file except in compliance with the License.
|
||||||
@ -209,7 +209,7 @@ sys.modules[__name__].config = Config()
|
|||||||
|
|
||||||
|
|
||||||
def init():
|
def init():
|
||||||
"""Compability shim that does nothing."""
|
"""Compatibility shim that does nothing."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,3 +2,12 @@
|
|||||||
templates:
|
templates:
|
||||||
- charm-unit-jobs
|
- charm-unit-jobs
|
||||||
- charm-functional-jobs
|
- charm-functional-jobs
|
||||||
|
check:
|
||||||
|
jobs:
|
||||||
|
- focal-xena:
|
||||||
|
voting: false
|
||||||
|
- impish-xena:
|
||||||
|
voting: false
|
||||||
|
# https://bugs.launchpad.net/charm-neutron-api/+bug/1933338
|
||||||
|
- hirsute-wallaby:
|
||||||
|
voting: false
|
||||||
|
18
pip.sh
Executable file
18
pip.sh
Executable file
@ -0,0 +1,18 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# This file is managed centrally by release-tools and should not be modified
|
||||||
|
# within individual charm repos. See the 'global' dir contents for available
|
||||||
|
# choices of tox.ini for OpenStack Charms:
|
||||||
|
# https://github.com/openstack-charmers/release-tools
|
||||||
|
#
|
||||||
|
# setuptools 58.0 dropped the support for use_2to3=true which is needed to
|
||||||
|
# install blessings (an indirect dependency of charm-tools).
|
||||||
|
#
|
||||||
|
# More details on the beahvior of tox and virtualenv creation can be found at
|
||||||
|
# https://github.com/tox-dev/tox/issues/448
|
||||||
|
#
|
||||||
|
# This script is wrapper to force the use of the pinned versions early in the
|
||||||
|
# process when the virtualenv was created and upgraded before installing the
|
||||||
|
# depedencies declared in the target.
|
||||||
|
pip install 'pip<20.3' 'setuptools<50.0.0'
|
||||||
|
pip "$@"
|
43
tests/bundles/focal-xena.yaml
Normal file
43
tests/bundles/focal-xena.yaml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
variables:
|
||||||
|
openstack-origin: &openstack-origin cloud:focal-xena
|
||||||
|
|
||||||
|
series: &series focal
|
||||||
|
|
||||||
|
applications:
|
||||||
|
keystone-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
neutron-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
mysql-innodb-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
rabbitmq-server:
|
||||||
|
charm: cs:~openstack-charmers-next/rabbitmq-server
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
neutron-api:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api
|
||||||
|
series: *series
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
manage-neutron-plugin-legacy-mode: True
|
||||||
|
flat-network-providers: physnet1
|
||||||
|
neutron-security-groups: true
|
||||||
|
openstack-origin: *openstack-origin
|
||||||
|
keystone:
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
openstack-origin: *openstack-origin
|
||||||
|
relations:
|
||||||
|
- - neutron-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - neutron-api:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- ["keystone:shared-db", "keystone-mysql-router:shared-db"]
|
||||||
|
- ["neutron-api:shared-db", "neutron-mysql-router:shared-db"]
|
||||||
|
- ["keystone-mysql-router:db-router", "mysql-innodb-cluster:db-router"]
|
||||||
|
- ["neutron-mysql-router:db-router", "mysql-innodb-cluster:db-router"]
|
43
tests/bundles/impish-xena.yaml
Normal file
43
tests/bundles/impish-xena.yaml
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
variables:
|
||||||
|
openstack-origin: &openstack-origin distro
|
||||||
|
|
||||||
|
series: &series impish
|
||||||
|
|
||||||
|
applications:
|
||||||
|
keystone-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
neutron-mysql-router:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-router
|
||||||
|
mysql-innodb-cluster:
|
||||||
|
charm: cs:~openstack-charmers-next/mysql-innodb-cluster
|
||||||
|
num_units: 3
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
rabbitmq-server:
|
||||||
|
charm: cs:~openstack-charmers-next/rabbitmq-server
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
source: *openstack-origin
|
||||||
|
neutron-api:
|
||||||
|
charm: cs:~openstack-charmers-next/neutron-api
|
||||||
|
series: *series
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
manage-neutron-plugin-legacy-mode: True
|
||||||
|
flat-network-providers: physnet1
|
||||||
|
neutron-security-groups: true
|
||||||
|
openstack-origin: *openstack-origin
|
||||||
|
keystone:
|
||||||
|
charm: cs:~openstack-charmers-next/keystone
|
||||||
|
num_units: 1
|
||||||
|
options:
|
||||||
|
openstack-origin: *openstack-origin
|
||||||
|
relations:
|
||||||
|
- - neutron-api:amqp
|
||||||
|
- rabbitmq-server:amqp
|
||||||
|
- - neutron-api:identity-service
|
||||||
|
- keystone:identity-service
|
||||||
|
- ["keystone:shared-db", "keystone-mysql-router:shared-db"]
|
||||||
|
- ["neutron-api:shared-db", "neutron-mysql-router:shared-db"]
|
||||||
|
- ["keystone-mysql-router:db-router", "mysql-innodb-cluster:db-router"]
|
||||||
|
- ["neutron-mysql-router:db-router", "mysql-innodb-cluster:db-router"]
|
@ -20,7 +20,9 @@ dev_bundles:
|
|||||||
- xenial-pike
|
- xenial-pike
|
||||||
- xenial-queens
|
- xenial-queens
|
||||||
- bionic-rocky
|
- bionic-rocky
|
||||||
|
- focal-xena
|
||||||
- hirsute-wallaby
|
- hirsute-wallaby
|
||||||
|
- impish-xena
|
||||||
|
|
||||||
tests:
|
tests:
|
||||||
- zaza.openstack.charm_tests.neutron.tests.NeutronApiTest
|
- zaza.openstack.charm_tests.neutron.tests.NeutronApiTest
|
||||||
@ -35,4 +37,5 @@ tests_options:
|
|||||||
policyd:
|
policyd:
|
||||||
service: neutron
|
service: neutron
|
||||||
force_deploy:
|
force_deploy:
|
||||||
- hirsute-wallaby
|
- groovy-victoria
|
||||||
|
- impish-xena
|
||||||
|
13
tox.ini
13
tox.ini
@ -22,19 +22,22 @@ skip_missing_interpreters = False
|
|||||||
# * It is also necessary to pin virtualenv as a newer virtualenv would still
|
# * It is also necessary to pin virtualenv as a newer virtualenv would still
|
||||||
# lead to fetching the latest pip in the func* tox targets, see
|
# lead to fetching the latest pip in the func* tox targets, see
|
||||||
# https://stackoverflow.com/a/38133283
|
# https://stackoverflow.com/a/38133283
|
||||||
requires = pip < 20.3
|
requires =
|
||||||
virtualenv < 20.0
|
pip < 20.3
|
||||||
|
virtualenv < 20.0
|
||||||
|
setuptools < 50.0.0
|
||||||
|
|
||||||
# NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci
|
# NOTE: https://wiki.canonical.com/engineering/OpenStack/InstallLatestToxOnOsci
|
||||||
minversion = 3.2.0
|
minversion = 3.18.0
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
setenv = VIRTUAL_ENV={envdir}
|
setenv = VIRTUAL_ENV={envdir}
|
||||||
PYTHONHASHSEED=0
|
PYTHONHASHSEED=0
|
||||||
CHARM_DIR={envdir}
|
CHARM_DIR={envdir}
|
||||||
install_command =
|
install_command =
|
||||||
pip install {opts} {packages}
|
{toxinidir}/pip.sh install {opts} {packages}
|
||||||
commands = stestr run --slowest {posargs}
|
commands = stestr run --slowest {posargs}
|
||||||
whitelist_externals = juju
|
allowlist_externals = juju
|
||||||
passenv = HOME TERM CS_* OS_* TEST_*
|
passenv = HOME TERM CS_* OS_* TEST_*
|
||||||
deps = -r{toxinidir}/test-requirements.txt
|
deps = -r{toxinidir}/test-requirements.txt
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user