Update Amulet defs, series metadata and c-h sync

- Remove problematic tests from gate, place in dev-* re:
https://bugs.launchpad.net/bugs/1546577

- Sync charm helpers if applicable.

- Fix test executable hashbags for virtualenv prep.

- Add Yakkety-Newton Amulet test definitions.

- Prep Xenial-Ocata Amulet test definitions (not yet enabled).

- Prep Zesty-Ocata Amulet test definitions (not yet enabled).

- Remove Precise charm series metadata if present.

- Remove Precise Amulet test definitions if present.

- Add Newton tests.

Change-Id: I50e72c026fa3e62fcd29a04572c18b5bcaa59a85
This commit is contained in:
Ryan Beisner 2016-10-07 13:35:34 -05:00 committed by David Ames
parent 013e71aba1
commit 23a76721f9
22 changed files with 210 additions and 48 deletions

View File

@ -109,7 +109,7 @@ UBUNTU_OPENSTACK_RELEASE = OrderedDict([
('wily', 'liberty'),
('xenial', 'mitaka'),
('yakkety', 'newton'),
('zebra', 'ocata'), # TODO: upload with real Z name
('zesty', 'ocata'),
])
@ -152,6 +152,8 @@ SWIFT_CODENAMES = OrderedDict([
['2.5.0', '2.6.0', '2.7.0']),
('newton',
['2.8.0', '2.9.0', '2.10.0']),
('ocata',
['2.11.0']),
])
# >= Liberty version->codename mapping
@ -229,6 +231,7 @@ GIT_DEFAULT_REPOS = {
GIT_DEFAULT_BRANCHES = {
'liberty': 'stable/liberty',
'mitaka': 'stable/mitaka',
'newton': 'stable/newton',
'master': 'master',
}
@ -409,14 +412,26 @@ def get_os_version_package(pkg, fatal=True):
os_rel = None
def os_release(package, base='essex'):
def reset_os_release():
'''Unset the cached os_release version'''
global os_rel
os_rel = None
def os_release(package, base='essex', reset_cache=False):
'''
Returns OpenStack release codename from a cached global.
If reset_cache then unset the cached os_release version and return the
freshly determined version.
If the codename can not be determined from either an installed package or
the installation source, the earliest release supported by the charm should
be returned.
'''
global os_rel
if reset_cache:
reset_os_release()
if os_rel:
return os_rel
os_rel = (git_os_codename_install_source(config('openstack-origin-git')) or
@ -534,6 +549,9 @@ def configure_installation_source(rel):
'newton': 'xenial-updates/newton',
'newton/updates': 'xenial-updates/newton',
'newton/proposed': 'xenial-proposed/newton',
'zesty': 'zesty-updates/ocata',
'zesty/updates': 'xenial-updates/ocata',
'zesty/proposed': 'xenial-proposed/ocata',
}
try:
@ -667,6 +685,7 @@ def clean_storage(block_device):
else:
zap_disk(block_device)
is_ip = ip.is_ip
ns_query = ip.ns_query
get_host_ip = ip.get_host_ip
@ -735,12 +754,12 @@ def git_os_codename_install_source(projects_yaml):
if projects in GIT_DEFAULT_BRANCHES.keys():
if projects == 'master':
return 'newton'
return 'ocata'
return projects
if 'release' in projects:
if projects['release'] == 'master':
return 'newton'
return 'ocata'
return projects['release']
return None

View File

@ -332,6 +332,8 @@ def config(scope=None):
config_cmd_line = ['config-get']
if scope is not None:
config_cmd_line.append(scope)
else:
config_cmd_line.append('--all')
config_cmd_line.append('--format=json')
try:
config_data = json.loads(

View File

@ -732,3 +732,20 @@ def get_total_ram():
assert unit == 'kB', 'Unknown unit'
return int(value) * 1024 # Classic, not KiB.
raise NotImplementedError()
UPSTART_CONTAINER_TYPE = '/run/container_type'
def is_container():
"""Determine whether unit is running in a container
@return: boolean indicating if unit is in a container
"""
if init_is_systemd():
# Detect using systemd-detect-virt
return subprocess.call(['systemd-detect-virt',
'--container']) == 0
else:
# Detect using upstart container file marker
return os.path.exists(UPSTART_CONTAINER_TYPE)

View File

@ -5,7 +5,7 @@ def persistent_modprobe(module):
"""Load a kernel module and configure for auto-load on reboot."""
with open('/etc/modules', 'r+') as modules:
if module not in modules.read():
modules.write(module)
modules.write(module + "\n")
def update_initramfs(version='all'):

View File

@ -105,6 +105,14 @@ CLOUD_ARCHIVE_POCKETS = {
'newton/proposed': 'xenial-proposed/newton',
'xenial-newton/proposed': 'xenial-proposed/newton',
'xenial-proposed/newton': 'xenial-proposed/newton',
# Ocata
'ocata': 'xenial-updates/ocata',
'xenial-ocata': 'xenial-updates/ocata',
'xenial-ocata/updates': 'xenial-updates/ocata',
'xenial-updates/ocata': 'xenial-updates/ocata',
'ocata/proposed': 'xenial-proposed/ocata',
'xenial-ocata/proposed': 'xenial-proposed/ocata',
'xenial-ocata/newton': 'xenial-proposed/ocata',
}
APT_NO_LOCK = 100 # The return code for "couldn't acquire lock" in APT.

View File

@ -85,6 +85,7 @@ class BasicDeployment(OpenStackAmuletDeployment):
self._add_relations()
self._configure_services()
self._deploy()
self.d.sentry.wait()
if self.units > 1:
i = 0

View File

@ -546,7 +546,7 @@ class AmuletUtils(object):
raise if it is present.
:returns: List of process IDs
"""
cmd = 'pidof -x {}'.format(process_name)
cmd = 'pidof -x "{}"'.format(process_name)
if not expect_success:
cmd += " || exit 0 && exit 1"
output, code = sentry_unit.run(cmd)

View File

@ -69,9 +69,9 @@ class OpenStackAmuletDeployment(AmuletDeployment):
# Charms outside the ~openstack-charmers
base_charms = {
'mysql': ['precise', 'trusty'],
'mongodb': ['precise', 'trusty'],
'nrpe': ['precise', 'trusty', 'wily', 'xenial'],
'mysql': ['trusty'],
'mongodb': ['trusty'],
'nrpe': ['trusty', 'xenial'],
}
for svc in other_services:
@ -156,7 +156,7 @@ class OpenStackAmuletDeployment(AmuletDeployment):
use_source = list(set(
use_source + ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
'ceph-osd', 'ceph-radosgw', 'ceph-mon',
'ceph-proxy']))
'ceph-proxy', 'percona-cluster', 'lxd']))
# Charms which can not use openstack-origin, ie. many subordinates
no_origin = list(set(
@ -260,31 +260,20 @@ class OpenStackAmuletDeployment(AmuletDeployment):
release.
"""
# Must be ordered by OpenStack release (not by Ubuntu release):
(self.precise_essex, self.precise_folsom, self.precise_grizzly,
self.precise_havana, self.precise_icehouse,
self.trusty_icehouse, self.trusty_juno, self.utopic_juno,
self.trusty_kilo, self.vivid_kilo, self.trusty_liberty,
self.wily_liberty, self.trusty_mitaka,
self.xenial_mitaka, self.xenial_newton,
self.yakkety_newton) = range(16)
(self.trusty_icehouse, self.trusty_kilo, self.trusty_liberty,
self.trusty_mitaka, self.xenial_mitaka, self.xenial_newton,
self.yakkety_newton, self.xenial_ocata, self.zesty_ocata) = range(9)
releases = {
('precise', None): self.precise_essex,
('precise', 'cloud:precise-folsom'): self.precise_folsom,
('precise', 'cloud:precise-grizzly'): self.precise_grizzly,
('precise', 'cloud:precise-havana'): self.precise_havana,
('precise', 'cloud:precise-icehouse'): self.precise_icehouse,
('trusty', None): self.trusty_icehouse,
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo,
('trusty', 'cloud:trusty-liberty'): self.trusty_liberty,
('trusty', 'cloud:trusty-mitaka'): self.trusty_mitaka,
('utopic', None): self.utopic_juno,
('vivid', None): self.vivid_kilo,
('wily', None): self.wily_liberty,
('xenial', None): self.xenial_mitaka,
('xenial', 'cloud:xenial-newton'): self.xenial_newton,
('xenial', 'cloud:xenial-ocata'): self.xenial_ocata,
('yakkety', None): self.yakkety_newton,
('zesty', None): self.zesty_ocata,
}
return releases[(self.series, self.openstack)]
@ -294,16 +283,10 @@ class OpenStackAmuletDeployment(AmuletDeployment):
Return a string representing the openstack release.
"""
releases = OrderedDict([
('precise', 'essex'),
('quantal', 'folsom'),
('raring', 'grizzly'),
('saucy', 'havana'),
('trusty', 'icehouse'),
('utopic', 'juno'),
('vivid', 'kilo'),
('wily', 'liberty'),
('xenial', 'mitaka'),
('yakkety', 'newton'),
('zesty', 'ocata'),
])
if self.openstack:
os_origin = self.openstack.split(':')[1]

View File

@ -28,6 +28,7 @@ import keystoneclient.v2_0 as keystone_client
from keystoneclient.auth.identity import v3 as keystone_id_v3
from keystoneclient import session as keystone_session
from keystoneclient.v3 import client as keystone_client_v3
from novaclient import exceptions
import novaclient.client as nova_client
import pika
@ -306,10 +307,8 @@ class OpenStackAmuletUtils(AmuletUtils):
password, tenant):
"""Authenticates admin user with cinder."""
# NOTE(beisner): cinder python client doesn't accept tokens.
service_ip = \
keystone_sentry.relation('shared-db',
'mysql:shared-db')['private-address']
ept = "http://{}:5000/v2.0".format(service_ip.strip().decode('utf-8'))
keystone_ip = keystone_sentry.info['public-address']
ept = "http://{}:5000/v2.0".format(keystone_ip.strip().decode('utf-8'))
return cinder_client.Client(username, password, tenant, ept)
def authenticate_keystone_admin(self, keystone_sentry, user, password,
@ -317,10 +316,9 @@ class OpenStackAmuletUtils(AmuletUtils):
keystone_ip=None):
"""Authenticates admin user with the keystone admin endpoint."""
self.log.debug('Authenticating keystone admin...')
unit = keystone_sentry
if not keystone_ip:
keystone_ip = unit.relation('shared-db',
'mysql:shared-db')['private-address']
keystone_ip = keystone_sentry.info['public-address']
base_ep = "http://{}:35357".format(keystone_ip.strip().decode('utf-8'))
if not api_version or api_version == 2:
ep = base_ep + "/v2.0"
@ -380,6 +378,16 @@ class OpenStackAmuletUtils(AmuletUtils):
tenant_name=tenant,
auth_version='2.0')
def create_flavor(self, nova, name, ram, vcpus, disk, flavorid="auto",
ephemeral=0, swap=0, rxtx_factor=1.0, is_public=True):
"""Create the specified flavor."""
try:
nova.flavors.find(name=name)
except (exceptions.NotFound, exceptions.NoUniqueMatch):
self.log.debug('Creating flavor ({})'.format(name))
nova.flavors.create(name, ram, vcpus, disk, flavorid,
ephemeral, swap, rxtx_factor, is_public)
def create_cirros_image(self, glance, image_name):
"""Download the latest cirros image and upload it to glance,
validate and return a resource pointer.

View File

@ -332,6 +332,8 @@ def config(scope=None):
config_cmd_line = ['config-get']
if scope is not None:
config_cmd_line.append(scope)
else:
config_cmd_line.append('--all')
config_cmd_line.append('--format=json')
try:
config_data = json.loads(

View File

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python
# test percona-cluster (3 nodes)
import basic_deployment

View File

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python
# test percona-cluster (3 nodes)
import basic_deployment

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# test percona-cluster (1 node)
import basic_deployment

View File

@ -1,4 +1,4 @@
#!/usr/bin/env python3
#!/usr/bin/env python
# test percona-cluster (multi node)
import basic_deployment

View File

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python
# test percona-cluster pause and resume
import basic_deployment
@ -12,7 +12,7 @@ class PauseResume(basic_deployment.BasicDeployment):
def run(self):
super(PauseResume, self).run()
unit = self.d.sentry['percona-cluster'][0]
assert self.is_mysqld_running(unit), 'mysql not running: %s' % uid
assert self.is_mysqld_running(unit), 'mysql not running'
assert utils.status_get(unit)[0] == "active"
action_id = utils.run_action(unit, "pause")

View File

@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python
# test percona-cluster (3 nodes)
import basic_deployment

44
tests/gate-basic-yakkety-newton Executable file
View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
# test percona-cluster (multi node)
import basic_deployment
class MultiNode(basic_deployment.BasicDeployment):
def __init__(self):
super(MultiNode, self).__init__(units=3, series='yakkety')
def _get_configs(self):
"""Configure all of the services."""
cfg_percona = {'sst-password': 'ubuntu',
'root-password': 't00r',
'dataset-size': '512M',
'vip': self.vip,
'min-cluster-size': 3,
'ha-bindiface': 'ens2'}
cfg_ha = {'debug': True,
'corosync_mcastaddr': '226.94.1.4',
'corosync_key': ('xZP7GDWV0e8Qs0GxWThXirNNYlScgi3sRTdZk/IXKD'
'qkNFcwdCWfRQnqrHU/6mb6sz6OIoZzX2MtfMQIDcXu'
'PqQyvKuv7YbRyGHmQwAWDUA4ed759VWAO39kHkfWp9'
'y5RRk/wcHakTcWYMwm70upDGJEP00YT3xem3NQy27A'
'C1w=')}
configs = {'percona-cluster': cfg_percona}
if self.units > 1:
configs['hacluster'] = cfg_ha
return configs
def run(self):
super(MultiNode, self).run()
msg = "Percona cluster failed to bootstrap"
assert self.is_pxc_bootstrapped(), msg
got = self.get_cluster_size()
msg = "Percona cluster unexpected size (wanted=%s, got=%s)" % (3, got)
assert got == '3', msg
if __name__ == "__main__":
t = MultiNode()
t.run()

View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
# test percona-cluster (multi node)
import basic_deployment
class MultiNode(basic_deployment.BasicDeployment):
def __init__(self):
super(MultiNode, self).__init__(units=3, series='zesty')
def _get_configs(self):
"""Configure all of the services."""
cfg_percona = {'sst-password': 'ubuntu',
'root-password': 't00r',
'dataset-size': '512M',
'vip': self.vip,
'min-cluster-size': 3,
'ha-bindiface': 'ens2'}
cfg_ha = {'debug': True,
'corosync_mcastaddr': '226.94.1.4',
'corosync_key': ('xZP7GDWV0e8Qs0GxWThXirNNYlScgi3sRTdZk/IXKD'
'qkNFcwdCWfRQnqrHU/6mb6sz6OIoZzX2MtfMQIDcXu'
'PqQyvKuv7YbRyGHmQwAWDUA4ed759VWAO39kHkfWp9'
'y5RRk/wcHakTcWYMwm70upDGJEP00YT3xem3NQy27A'
'C1w=')}
configs = {'percona-cluster': cfg_percona}
if self.units > 1:
configs['hacluster'] = cfg_ha
return configs
def run(self):
super(MultiNode, self).run()
msg = "Percona cluster failed to bootstrap"
assert self.is_pxc_bootstrapped(), msg
got = self.get_cluster_size()
msg = "Percona cluster unexpected size (wanted=%s, got=%s)" % (3, got)
assert got == '3', msg
if __name__ == "__main__":
t = MultiNode()
t.run()

17
tests/gate-single-xenial Executable file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
# test percona-cluster (1 node)
import basic_deployment
class SingleNode(basic_deployment.BasicDeployment):
def __init__(self):
super(SingleNode, self).__init__(units=1, series='xenial')
def run(self):
super(SingleNode, self).run()
assert self.is_pxc_bootstrapped(), "Cluster not bootstrapped"
if __name__ == "__main__":
t = SingleNode()
t.run()

17
tests/gate-single-yakkety Executable file
View File

@ -0,0 +1,17 @@
#!/usr/bin/env python
# test percona-cluster (1 node)
import basic_deployment
class SingleNode(basic_deployment.BasicDeployment):
def __init__(self):
super(SingleNode, self).__init__(units=1, series='yakkety')
def run(self):
super(SingleNode, self).run()
assert self.is_pxc_bootstrapped(), "Cluster not bootstrapped"
if __name__ == "__main__":
t = SingleNode()
t.run()

View File

@ -1,6 +1,6 @@
# Bootstrap the model if necessary.
bootstrap: True
# Re-use bootstrap node instead of destroying/re-bootstrapping.
# Re-use bootstrap node.
reset: True
# Use tox/requirements to drive the venv instead of bundletester's venv feature.
virtualenv: False