From 4ea9d6a4276317b08055c69cc266d36349c7e198 Mon Sep 17 00:00:00 2001 From: James Page Date: Mon, 8 Jan 2018 12:37:06 +0000 Subject: [PATCH] Remove deploy from source support Drop support for deployment from Git repositories, as deprecated in the 17.02 charm release. This feature is unmaintained and has no known users. Change-Id: Icd464e950c6f53470311e3c110b530a69bff6e2f --- README.md | 3 - actions.yaml | 2 - actions/git_reinstall.py | 60 --- config.yaml | 24 - .../charmhelpers/contrib/openstack/context.py | 74 ++- .../templates/wsgi-openstack-api.conf | 15 +- hooks/charmhelpers/contrib/openstack/utils.py | 476 +----------------- .../contrib/storage/linux/ceph.py | 17 +- hooks/cinder_hooks.py | 11 +- hooks/cinder_utils.py | 231 --------- templates/git/cinder-api.init.in.template | 22 - templates/git/cinder-backup.init.in.template | 21 - .../git/cinder-scheduler.init.in.template | 22 - templates/git/cinder-volume.init.in.template | 22 - templates/git/cinder_sudoers | 4 - templates/git/cinder_tgt.conf | 1 - templates/git/logging.conf | 76 --- tests/basic_deployment.py | 38 +- tests/dfs-basic-trusty-icehouse | 23 - tests/dfs-basic-trusty-kilo | 26 - unit_tests/__init__.py | 6 + unit_tests/test_actions_git_reinstall.py | 120 ----- unit_tests/test_actions_openstack_upgrade.py | 8 +- unit_tests/test_cinder_hooks.py | 99 +--- unit_tests/test_cinder_utils.py | 202 +------- 25 files changed, 122 insertions(+), 1481 deletions(-) delete mode 100755 actions/git_reinstall.py delete mode 100644 templates/git/cinder-api.init.in.template delete mode 100644 templates/git/cinder-backup.init.in.template delete mode 100644 templates/git/cinder-scheduler.init.in.template delete mode 100644 templates/git/cinder-volume.init.in.template delete mode 100644 templates/git/cinder_sudoers delete mode 100644 templates/git/cinder_tgt.conf delete mode 100644 templates/git/logging.conf delete mode 100755 tests/dfs-basic-trusty-icehouse delete mode 100755 tests/dfs-basic-trusty-kilo delete mode 100644 unit_tests/test_actions_git_reinstall.py diff --git a/README.md b/README.md index f0eb1885..7dd12c50 100644 --- a/README.md +++ b/README.md @@ -107,9 +107,6 @@ Users should be aware of three options, in particular: openstack-origin: Allows Cinder to be installed from a specific apt repository. See config.yaml for a list of supported sources. -openstack-origin-git: Allows Cinder to be installed from source. - See config.yaml for a list of supported sources. - block-device: When using local storage, a block device should be specified to back a LVM volume group. It's important this device exists on all nodes that the service may be deployed to. diff --git a/actions.yaml b/actions.yaml index bdd2536f..4f14b5c3 100644 --- a/actions.yaml +++ b/actions.yaml @@ -2,8 +2,6 @@ pause: description: Pause the cinder unit. This action will stop cinder services. resume: descrpition: Resume the cinder unit. This action will start cinder services. -git-reinstall: - description: Reinstall cinder from the openstack-origin-git repositories. openstack-upgrade: description: Perform openstack upgrades. Config option action-managed-upgrade must be set to True. remove-services: diff --git a/actions/git_reinstall.py b/actions/git_reinstall.py deleted file mode 100755 index eab37176..00000000 --- a/actions/git_reinstall.py +++ /dev/null @@ -1,60 +0,0 @@ -#!/usr/bin/python -# -# Copyright 2016 Canonical Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import sys -import traceback - -sys.path.append('hooks/') - -from charmhelpers.contrib.openstack.utils import ( - git_install_requested, -) - -from charmhelpers.core.hookenv import ( - action_set, - action_fail, - config, -) - -from cinder_utils import ( - git_install, -) - -from cinder_hooks import ( - config_changed, -) - - -def git_reinstall(): - """Reinstall from source and restart services. - - If the openstack-origin-git config option was used to install openstack - from source git repositories, then this action can be used to reinstall - from updated git repositories, followed by a restart of services.""" - if not git_install_requested(): - action_fail('openstack-origin-git is not configured') - return - - try: - git_install(config('openstack-origin-git')) - config_changed() - except: - action_set({'traceback': traceback.format_exc()}) - action_fail('git-reinstall resulted in an unexpected error') - - -if __name__ == '__main__': - git_reinstall() diff --git a/config.yaml b/config.yaml index 9a1ee14c..e937281b 100644 --- a/config.yaml +++ b/config.yaml @@ -31,30 +31,6 @@ options: NOTE: updating this setting to a source that is known to provide a later version of OpenStack will trigger a software upgrade unless action-managed-upgrade is set to True. - openstack-origin-git: - type: string - default: - description: | - Specifies a default OpenStack release name, or a YAML dictionary - listing the git repositories to install from. - . - The default Openstack release name may be one of the following, where - the corresponding OpenStack github branch will be used: - * liberty - * mitaka - * newton - * master - . - The YAML must minimally include requirements and cinder repositories, - and may also include repositories for other dependencies: - repositories: - - {name: requirements, - repository: 'git://github.com/openstack/requirements', - branch: master} - - {name: cinder, - repository: 'git://github.com/openstack/cinder', - branch: master} - release: master action-managed-upgrade: type: boolean default: False diff --git a/hooks/charmhelpers/contrib/openstack/context.py b/hooks/charmhelpers/contrib/openstack/context.py index 70850c1b..161be128 100644 --- a/hooks/charmhelpers/contrib/openstack/context.py +++ b/hooks/charmhelpers/contrib/openstack/context.py @@ -97,8 +97,6 @@ from charmhelpers.contrib.network.ip import ( from charmhelpers.contrib.openstack.utils import ( config_flags_parser, get_host_ip, - git_determine_usr_bin, - git_determine_python_path, enable_memcache, snap_install_requested, CompareOpenStackReleases, @@ -334,10 +332,7 @@ class IdentityServiceContext(OSContextGenerator): self.rel_name = rel_name self.interfaces = [self.rel_name] - def __call__(self): - log('Generating template context for ' + self.rel_name, level=DEBUG) - ctxt = {} - + def _setup_pki_cache(self): if self.service and self.service_user: # This is required for pki token signing if we don't want /tmp to # be used. @@ -347,6 +342,15 @@ class IdentityServiceContext(OSContextGenerator): mkdir(path=cachedir, owner=self.service_user, group=self.service_user, perms=0o700) + return cachedir + return None + + def __call__(self): + log('Generating template context for ' + self.rel_name, level=DEBUG) + ctxt = {} + + cachedir = self._setup_pki_cache() + if cachedir: ctxt['signing_dir'] = cachedir for rid in relation_ids(self.rel_name): @@ -385,6 +389,62 @@ class IdentityServiceContext(OSContextGenerator): return {} +class IdentityCredentialsContext(IdentityServiceContext): + '''Context for identity-credentials interface type''' + + def __init__(self, + service=None, + service_user=None, + rel_name='identity-credentials'): + super(IdentityCredentialsContext, self).__init__(service, + service_user, + rel_name) + + def __call__(self): + log('Generating template context for ' + self.rel_name, level=DEBUG) + ctxt = {} + + cachedir = self._setup_pki_cache() + if cachedir: + ctxt['signing_dir'] = cachedir + + for rid in relation_ids(self.rel_name): + self.related = True + for unit in related_units(rid): + rdata = relation_get(rid=rid, unit=unit) + credentials_host = rdata.get('credentials_host') + credentials_host = ( + format_ipv6_addr(credentials_host) or credentials_host + ) + auth_host = rdata.get('auth_host') + auth_host = format_ipv6_addr(auth_host) or auth_host + svc_protocol = rdata.get('credentials_protocol') or 'http' + auth_protocol = rdata.get('auth_protocol') or 'http' + api_version = rdata.get('api_version') or '2.0' + ctxt.update({ + 'service_port': rdata.get('credentials_port'), + 'service_host': credentials_host, + 'auth_host': auth_host, + 'auth_port': rdata.get('auth_port'), + 'admin_tenant_name': rdata.get('credentials_project'), + 'admin_tenant_id': rdata.get('credentials_project_id'), + 'admin_user': rdata.get('credentials_username'), + 'admin_password': rdata.get('credentials_password'), + 'service_protocol': svc_protocol, + 'auth_protocol': auth_protocol, + 'api_version': api_version + }) + + if float(api_version) > 2: + ctxt.update({'admin_domain_name': + rdata.get('domain')}) + + if self.context_complete(ctxt): + return ctxt + + return {} + + class AMQPContext(OSContextGenerator): def __init__(self, ssl_dir=None, rel_name='amqp', relation_prefix=None): @@ -1323,8 +1383,6 @@ class WSGIWorkerConfigContext(WorkerConfigContext): "public_processes": int(math.ceil(self.public_process_weight * total_processes)), "threads": 1, - "usr_bin": git_determine_usr_bin(), - "python_path": git_determine_python_path(), } return ctxt diff --git a/hooks/charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf b/hooks/charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf index 315b2a3f..e2e73b2c 100644 --- a/hooks/charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf +++ b/hooks/charmhelpers/contrib/openstack/templates/wsgi-openstack-api.conf @@ -15,9 +15,6 @@ Listen {{ public_port }} {% if port -%} WSGIDaemonProcess {{ service_name }} processes={{ processes }} threads={{ threads }} user={{ service_name }} group={{ service_name }} \ -{% if python_path -%} - python-path={{ python_path }} \ -{% endif -%} display-name=%{GROUP} WSGIProcessGroup {{ service_name }} WSGIScriptAlias / {{ script }} @@ -29,7 +26,7 @@ Listen {{ public_port }} ErrorLog /var/log/apache2/{{ service_name }}_error.log CustomLog /var/log/apache2/{{ service_name }}_access.log combined - + = 2.4> Require all granted @@ -44,9 +41,6 @@ Listen {{ public_port }} {% if admin_port -%} WSGIDaemonProcess {{ service_name }}-admin processes={{ admin_processes }} threads={{ threads }} user={{ service_name }} group={{ service_name }} \ -{% if python_path -%} - python-path={{ python_path }} \ -{% endif -%} display-name=%{GROUP} WSGIProcessGroup {{ service_name }}-admin WSGIScriptAlias / {{ admin_script }} @@ -58,7 +52,7 @@ Listen {{ public_port }} ErrorLog /var/log/apache2/{{ service_name }}_error.log CustomLog /var/log/apache2/{{ service_name }}_access.log combined - + = 2.4> Require all granted @@ -73,9 +67,6 @@ Listen {{ public_port }} {% if public_port -%} WSGIDaemonProcess {{ service_name }}-public processes={{ public_processes }} threads={{ threads }} user={{ service_name }} group={{ service_name }} \ -{% if python_path -%} - python-path={{ python_path }} \ -{% endif -%} display-name=%{GROUP} WSGIProcessGroup {{ service_name }}-public WSGIScriptAlias / {{ public_script }} @@ -87,7 +78,7 @@ Listen {{ public_port }} ErrorLog /var/log/apache2/{{ service_name }}_error.log CustomLog /var/log/apache2/{{ service_name }}_access.log combined - + = 2.4> Require all granted diff --git a/hooks/charmhelpers/contrib/openstack/utils.py b/hooks/charmhelpers/contrib/openstack/utils.py index e1d852db..0e867310 100644 --- a/hooks/charmhelpers/contrib/openstack/utils.py +++ b/hooks/charmhelpers/contrib/openstack/utils.py @@ -23,7 +23,6 @@ import sys import re import itertools import functools -import shutil import six import traceback @@ -47,7 +46,6 @@ from charmhelpers.core.hookenv import ( related_units, relation_ids, relation_set, - service_name, status_set, hook_name, application_version_set, @@ -68,11 +66,6 @@ from charmhelpers.contrib.network.ip import ( port_has_listener, ) -from charmhelpers.contrib.python.packages import ( - pip_create_virtualenv, - pip_install, -) - from charmhelpers.core.host import ( lsb_release, mounts, @@ -84,7 +77,6 @@ from charmhelpers.core.host import ( ) from charmhelpers.fetch import ( apt_cache, - install_remote, import_key as fetch_import_key, add_source as fetch_add_source, SourceConfigError, @@ -278,27 +270,6 @@ PACKAGE_CODENAMES = { ]), } -GIT_DEFAULT_REPOS = { - 'requirements': 'git://github.com/openstack/requirements', - 'cinder': 'git://github.com/openstack/cinder', - 'glance': 'git://github.com/openstack/glance', - 'horizon': 'git://github.com/openstack/horizon', - 'keystone': 'git://github.com/openstack/keystone', - 'networking-hyperv': 'git://github.com/openstack/networking-hyperv', - 'neutron': 'git://github.com/openstack/neutron', - 'neutron-fwaas': 'git://github.com/openstack/neutron-fwaas', - 'neutron-lbaas': 'git://github.com/openstack/neutron-lbaas', - 'neutron-vpnaas': 'git://github.com/openstack/neutron-vpnaas', - 'nova': 'git://github.com/openstack/nova', -} - -GIT_DEFAULT_BRANCHES = { - 'liberty': 'stable/liberty', - 'mitaka': 'stable/mitaka', - 'newton': 'stable/newton', - 'master': 'master', -} - DEFAULT_LOOPBACK_SIZE = '5G' @@ -530,7 +501,6 @@ def os_release(package, base='essex', reset_cache=False): if _os_rel: return _os_rel _os_rel = ( - git_os_codename_install_source(config('openstack-origin-git')) or get_os_codename_package(package, fatal=False) or get_os_codename_install_source(config('openstack-origin')) or base) @@ -771,417 +741,6 @@ def os_requires_version(ostack_release, pkg): return wrap -def git_install_requested(): - """ - Returns true if openstack-origin-git is specified. - """ - return config('openstack-origin-git') is not None - - -def git_os_codename_install_source(projects_yaml): - """ - Returns OpenStack codename of release being installed from source. - """ - if git_install_requested(): - projects = _git_yaml_load(projects_yaml) - - if projects in GIT_DEFAULT_BRANCHES.keys(): - if projects == 'master': - return 'ocata' - return projects - - if 'release' in projects: - if projects['release'] == 'master': - return 'ocata' - return projects['release'] - - return None - - -def git_default_repos(projects_yaml): - """ - Returns default repos if a default openstack-origin-git value is specified. - """ - service = service_name() - core_project = service - - for default, branch in six.iteritems(GIT_DEFAULT_BRANCHES): - if projects_yaml == default: - - # add the requirements repo first - repo = { - 'name': 'requirements', - 'repository': GIT_DEFAULT_REPOS['requirements'], - 'branch': branch, - } - repos = [repo] - - # neutron-* and nova-* charms require some additional repos - if service in ['neutron-api', 'neutron-gateway', - 'neutron-openvswitch']: - core_project = 'neutron' - if service == 'neutron-api': - repo = { - 'name': 'networking-hyperv', - 'repository': GIT_DEFAULT_REPOS['networking-hyperv'], - 'branch': branch, - } - repos.append(repo) - for project in ['neutron-fwaas', 'neutron-lbaas', - 'neutron-vpnaas', 'nova']: - repo = { - 'name': project, - 'repository': GIT_DEFAULT_REPOS[project], - 'branch': branch, - } - repos.append(repo) - - elif service in ['nova-cloud-controller', 'nova-compute']: - core_project = 'nova' - repo = { - 'name': 'neutron', - 'repository': GIT_DEFAULT_REPOS['neutron'], - 'branch': branch, - } - repos.append(repo) - elif service == 'openstack-dashboard': - core_project = 'horizon' - - # finally add the current service's core project repo - repo = { - 'name': core_project, - 'repository': GIT_DEFAULT_REPOS[core_project], - 'branch': branch, - } - repos.append(repo) - - return yaml.dump(dict(repositories=repos, release=default)) - - return projects_yaml - - -def _git_yaml_load(projects_yaml): - """ - Load the specified yaml into a dictionary. - """ - if not projects_yaml: - return None - - return yaml.load(projects_yaml) - - -requirements_dir = None - - -def git_clone_and_install(projects_yaml, core_project): - """ - Clone/install all specified OpenStack repositories. - - The expected format of projects_yaml is: - - repositories: - - {name: keystone, - repository: 'git://git.openstack.org/openstack/keystone.git', - branch: 'stable/icehouse'} - - {name: requirements, - repository: 'git://git.openstack.org/openstack/requirements.git', - branch: 'stable/icehouse'} - - directory: /mnt/openstack-git - http_proxy: squid-proxy-url - https_proxy: squid-proxy-url - - The directory, http_proxy, and https_proxy keys are optional. - - """ - global requirements_dir - parent_dir = '/mnt/openstack-git' - http_proxy = None - - projects = _git_yaml_load(projects_yaml) - _git_validate_projects_yaml(projects, core_project) - - old_environ = dict(os.environ) - - if 'http_proxy' in projects.keys(): - http_proxy = projects['http_proxy'] - os.environ['http_proxy'] = projects['http_proxy'] - if 'https_proxy' in projects.keys(): - os.environ['https_proxy'] = projects['https_proxy'] - - if 'directory' in projects.keys(): - parent_dir = projects['directory'] - - pip_create_virtualenv(os.path.join(parent_dir, 'venv')) - - # Upgrade setuptools and pip from default virtualenv versions. The default - # versions in trusty break master OpenStack branch deployments. - for p in ['pip', 'setuptools']: - pip_install(p, upgrade=True, proxy=http_proxy, - venv=os.path.join(parent_dir, 'venv')) - - constraints = None - for p in projects['repositories']: - repo = p['repository'] - branch = p['branch'] - depth = '1' - if 'depth' in p.keys(): - depth = p['depth'] - if p['name'] == 'requirements': - repo_dir = _git_clone_and_install_single(repo, branch, depth, - parent_dir, http_proxy, - update_requirements=False) - requirements_dir = repo_dir - constraints = os.path.join(repo_dir, "upper-constraints.txt") - # upper-constraints didn't exist until after icehouse - if not os.path.isfile(constraints): - constraints = None - # use constraints unless project yaml sets use_constraints to false - if 'use_constraints' in projects.keys(): - if not projects['use_constraints']: - constraints = None - else: - repo_dir = _git_clone_and_install_single(repo, branch, depth, - parent_dir, http_proxy, - update_requirements=True, - constraints=constraints) - - os.environ = old_environ - - -def _git_validate_projects_yaml(projects, core_project): - """ - Validate the projects yaml. - """ - _git_ensure_key_exists('repositories', projects) - - for project in projects['repositories']: - _git_ensure_key_exists('name', project.keys()) - _git_ensure_key_exists('repository', project.keys()) - _git_ensure_key_exists('branch', project.keys()) - - if projects['repositories'][0]['name'] != 'requirements': - error_out('{} git repo must be specified first'.format('requirements')) - - if projects['repositories'][-1]['name'] != core_project: - error_out('{} git repo must be specified last'.format(core_project)) - - _git_ensure_key_exists('release', projects) - - -def _git_ensure_key_exists(key, keys): - """ - Ensure that key exists in keys. - """ - if key not in keys: - error_out('openstack-origin-git key \'{}\' is missing'.format(key)) - - -def _git_clone_and_install_single(repo, branch, depth, parent_dir, http_proxy, - update_requirements, constraints=None): - """ - Clone and install a single git repository. - """ - if not os.path.exists(parent_dir): - juju_log('Directory already exists at {}. ' - 'No need to create directory.'.format(parent_dir)) - os.mkdir(parent_dir) - - juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch)) - repo_dir = install_remote( - repo, dest=parent_dir, branch=branch, depth=depth) - - venv = os.path.join(parent_dir, 'venv') - - if update_requirements: - if not requirements_dir: - error_out('requirements repo must be cloned before ' - 'updating from global requirements.') - _git_update_requirements(venv, repo_dir, requirements_dir) - - juju_log('Installing git repo from dir: {}'.format(repo_dir)) - if http_proxy: - pip_install(repo_dir, proxy=http_proxy, venv=venv, - constraints=constraints) - else: - pip_install(repo_dir, venv=venv, constraints=constraints) - - return repo_dir - - -def _git_update_requirements(venv, package_dir, reqs_dir): - """ - Update from global requirements. - - Update an OpenStack git directory's requirements.txt and - test-requirements.txt from global-requirements.txt. - """ - orig_dir = os.getcwd() - os.chdir(reqs_dir) - python = os.path.join(venv, 'bin/python') - cmd = [python, 'update.py', package_dir] - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - package = os.path.basename(package_dir) - error_out("Error updating {} from " - "global-requirements.txt".format(package)) - os.chdir(orig_dir) - - -def git_pip_venv_dir(projects_yaml): - """ - Return the pip virtualenv path. - """ - parent_dir = '/mnt/openstack-git' - - projects = _git_yaml_load(projects_yaml) - - if 'directory' in projects.keys(): - parent_dir = projects['directory'] - - return os.path.join(parent_dir, 'venv') - - -def git_src_dir(projects_yaml, project): - """ - Return the directory where the specified project's source is located. - """ - parent_dir = '/mnt/openstack-git' - - projects = _git_yaml_load(projects_yaml) - - if 'directory' in projects.keys(): - parent_dir = projects['directory'] - - for p in projects['repositories']: - if p['name'] == project: - return os.path.join(parent_dir, os.path.basename(p['repository'])) - - return None - - -def git_yaml_value(projects_yaml, key): - """ - Return the value in projects_yaml for the specified key. - """ - projects = _git_yaml_load(projects_yaml) - - if key in projects.keys(): - return projects[key] - - return None - - -def git_generate_systemd_init_files(templates_dir): - """ - Generate systemd init files. - - Generates and installs systemd init units and script files based on the - *.init.in files contained in the templates_dir directory. - - This code is based on the openstack-pkg-tools package and its init - script generation, which is used by the OpenStack packages. - """ - for f in os.listdir(templates_dir): - # Create the init script and systemd unit file from the template - if f.endswith(".init.in"): - init_in_file = f - init_file = f[:-8] - service_file = "{}.service".format(init_file) - - init_in_source = os.path.join(templates_dir, init_in_file) - init_source = os.path.join(templates_dir, init_file) - service_source = os.path.join(templates_dir, service_file) - - init_dest = os.path.join('/etc/init.d', init_file) - service_dest = os.path.join('/lib/systemd/system', service_file) - - shutil.copyfile(init_in_source, init_source) - with open(init_source, 'a') as outfile: - template = ('/usr/share/openstack-pkg-tools/' - 'init-script-template') - with open(template) as infile: - outfile.write('\n\n{}'.format(infile.read())) - - cmd = ['pkgos-gen-systemd-unit', init_in_source] - subprocess.check_call(cmd) - - if os.path.exists(init_dest): - os.remove(init_dest) - if os.path.exists(service_dest): - os.remove(service_dest) - shutil.copyfile(init_source, init_dest) - shutil.copyfile(service_source, service_dest) - os.chmod(init_dest, 0o755) - - for f in os.listdir(templates_dir): - # If there's a service.in file, use it instead of the generated one - if f.endswith(".service.in"): - service_in_file = f - service_file = f[:-3] - - service_in_source = os.path.join(templates_dir, service_in_file) - service_source = os.path.join(templates_dir, service_file) - service_dest = os.path.join('/lib/systemd/system', service_file) - - shutil.copyfile(service_in_source, service_source) - - if os.path.exists(service_dest): - os.remove(service_dest) - shutil.copyfile(service_source, service_dest) - - for f in os.listdir(templates_dir): - # Generate the systemd unit if there's no existing .service.in - if f.endswith(".init.in"): - init_in_file = f - init_file = f[:-8] - service_in_file = "{}.service.in".format(init_file) - service_file = "{}.service".format(init_file) - - init_in_source = os.path.join(templates_dir, init_in_file) - service_in_source = os.path.join(templates_dir, service_in_file) - service_source = os.path.join(templates_dir, service_file) - service_dest = os.path.join('/lib/systemd/system', service_file) - - if not os.path.exists(service_in_source): - cmd = ['pkgos-gen-systemd-unit', init_in_source] - subprocess.check_call(cmd) - - if os.path.exists(service_dest): - os.remove(service_dest) - shutil.copyfile(service_source, service_dest) - - -def git_determine_usr_bin(): - """Return the /usr/bin path for Apache2 config. - - The /usr/bin path will be located in the virtualenv if the charm - is configured to deploy from source. - """ - if git_install_requested(): - projects_yaml = config('openstack-origin-git') - projects_yaml = git_default_repos(projects_yaml) - return os.path.join(git_pip_venv_dir(projects_yaml), 'bin') - else: - return '/usr/bin' - - -def git_determine_python_path(): - """Return the python-path for Apache2 config. - - Returns 'None' unless the charm is configured to deploy from source, - in which case the path of the virtualenv's site-packages is returned. - """ - if git_install_requested(): - projects_yaml = config('openstack-origin-git') - projects_yaml = git_default_repos(projects_yaml) - return os.path.join(git_pip_venv_dir(projects_yaml), - 'lib/python2.7/site-packages') - else: - return None - - def os_workload_status(configs, required_interfaces, charm_func=None): """ Decorator to set workload status based on complete contexts @@ -1615,27 +1174,24 @@ def do_action_openstack_upgrade(package, upgrade_callback, configs): """ ret = False - if git_install_requested(): - action_set({'outcome': 'installed from source, skipped upgrade.'}) - else: - if openstack_upgrade_available(package): - if config('action-managed-upgrade'): - juju_log('Upgrading OpenStack release') + if openstack_upgrade_available(package): + if config('action-managed-upgrade'): + juju_log('Upgrading OpenStack release') - try: - upgrade_callback(configs=configs) - action_set({'outcome': 'success, upgrade completed.'}) - ret = True - except Exception: - action_set({'outcome': 'upgrade failed, see traceback.'}) - action_set({'traceback': traceback.format_exc()}) - action_fail('do_openstack_upgrade resulted in an ' - 'unexpected error') - else: - action_set({'outcome': 'action-managed-upgrade config is ' - 'False, skipped upgrade.'}) + try: + upgrade_callback(configs=configs) + action_set({'outcome': 'success, upgrade completed.'}) + ret = True + except Exception: + action_set({'outcome': 'upgrade failed, see traceback.'}) + action_set({'traceback': traceback.format_exc()}) + action_fail('do_openstack_upgrade resulted in an ' + 'unexpected error') else: - action_set({'outcome': 'no upgrade available.'}) + action_set({'outcome': 'action-managed-upgrade config is ' + 'False, skipped upgrade.'}) + else: + action_set({'outcome': 'no upgrade available.'}) return ret diff --git a/hooks/charmhelpers/contrib/storage/linux/ceph.py b/hooks/charmhelpers/contrib/storage/linux/ceph.py index 87621c47..e13e60a6 100644 --- a/hooks/charmhelpers/contrib/storage/linux/ceph.py +++ b/hooks/charmhelpers/contrib/storage/linux/ceph.py @@ -113,7 +113,7 @@ def validator(value, valid_type, valid_range=None): assert isinstance(valid_range, list), \ "valid_range must be a list, was given {}".format(valid_range) # If we're dealing with strings - if valid_type is six.string_types: + if isinstance(value, six.string_types): assert value in valid_range, \ "{} is not in the list {}".format(value, valid_range) # Integer, float should have a min and max @@ -517,7 +517,8 @@ def pool_set(service, pool_name, key, value): :param value: :return: None. Can raise CalledProcessError """ - cmd = ['ceph', '--id', service, 'osd', 'pool', 'set', pool_name, key, value] + cmd = ['ceph', '--id', service, 'osd', 'pool', 'set', pool_name, key, + str(value).lower()] try: check_call(cmd) except CalledProcessError: @@ -621,16 +622,24 @@ def create_erasure_profile(service, profile_name, erasure_plugin_name='jerasure' :param durability_estimator: int :return: None. Can raise CalledProcessError """ + version = ceph_version() + # Ensure this failure_domain is allowed by Ceph validator(failure_domain, six.string_types, ['chassis', 'datacenter', 'host', 'osd', 'pdu', 'pod', 'rack', 'region', 'room', 'root', 'row']) cmd = ['ceph', '--id', service, 'osd', 'erasure-code-profile', 'set', profile_name, - 'plugin=' + erasure_plugin_name, 'k=' + str(data_chunks), 'm=' + str(coding_chunks), - 'ruleset_failure_domain=' + failure_domain] + 'plugin=' + erasure_plugin_name, 'k=' + str(data_chunks), 'm=' + str(coding_chunks) + ] if locality is not None and durability_estimator is not None: raise ValueError("create_erasure_profile should be called with k, m and one of l or c but not both.") + # failure_domain changed in luminous + if version and version >= '12.0.0': + cmd.append('crush-failure-domain=' + failure_domain) + else: + cmd.append('ruleset-failure-domain=' + failure_domain) + # Add plugin specific information if locality is not None: # For local erasure codes diff --git a/hooks/cinder_hooks.py b/hooks/cinder_hooks.py index 0a67ebe5..36b9702e 100755 --- a/hooks/cinder_hooks.py +++ b/hooks/cinder_hooks.py @@ -26,7 +26,6 @@ from cinder_utils import ( determine_packages, disable_package_apache_site, do_openstack_upgrade, - git_install, juju_log, migrate_database, configure_lvm_storage, @@ -78,7 +77,6 @@ from charmhelpers.core.host import ( from charmhelpers.contrib.openstack.utils import ( config_value_changed, configure_installation_source, - git_install_requested, openstack_upgrade_available, sync_db_with_multi_ipv6_addresses, os_release, @@ -145,9 +143,6 @@ def install(): if run_in_apache(): disable_package_apache_site() - status_set('maintenance', 'Git install') - git_install(config('openstack-origin-git')) - @hooks.hook('config-changed') @restart_on_change(restart_map(), stopstart=True) @@ -175,11 +170,7 @@ def config_changed(): conf['remove-missing'], conf['remove-missing-force']) - if git_install_requested(): - if config_value_changed('openstack-origin-git'): - status_set('maintenance', 'Running Git install') - git_install(config('openstack-origin-git')) - elif not config('action-managed-upgrade'): + if not config('action-managed-upgrade'): if openstack_upgrade_available('cinder-common'): status_set('maintenance', 'Running openstack upgrade') do_openstack_upgrade(configs=CONFIGS) diff --git a/hooks/cinder_utils.py b/hooks/cinder_utils.py index c0c3fe9b..0b3c0195 100644 --- a/hooks/cinder_utils.py +++ b/hooks/cinder_utils.py @@ -13,7 +13,6 @@ # limitations under the License. import os -import shutil import subprocess import uuid @@ -21,16 +20,11 @@ from copy import deepcopy from collections import OrderedDict from copy import copy -from charmhelpers.contrib.python.packages import ( - pip_install, -) - from charmhelpers.core.strutils import ( bytes_from_string ) from charmhelpers.core.hookenv import ( - charm_dir, config, local_unit, relation_get, @@ -50,9 +44,6 @@ from charmhelpers.fetch import ( ) from charmhelpers.core.host import ( - adduser, - add_group, - add_user_to_group, CompareHostReleases, lsb_release, mkdir, @@ -61,7 +52,6 @@ from charmhelpers.core.host import ( service_restart, service_stop, service_start, - write_file, ) from charmhelpers.contrib.openstack.alternatives import install_alternative @@ -99,13 +89,6 @@ from charmhelpers.contrib.openstack import ( from charmhelpers.contrib.openstack.utils import ( configure_installation_source, get_os_codename_install_source, - git_clone_and_install, - git_default_repos, - git_generate_systemd_init_files, - git_install_requested, - git_pip_venv_dir, - git_src_dir, - git_yaml_value, os_release, reset_os_release, make_assess_status_func, @@ -121,7 +104,6 @@ from charmhelpers.contrib.openstack.utils import ( from charmhelpers.core.decorators import ( retry_on_exception, ) -from charmhelpers.core.templating import render import cinder_contexts @@ -143,30 +125,6 @@ API_PACKAGES = ['cinder-api'] VOLUME_PACKAGES = ['cinder-volume'] SCHEDULER_PACKAGES = ['cinder-scheduler'] -BASE_GIT_PACKAGES = [ - 'libffi-dev', - 'libmysqlclient-dev', - 'libssl-dev', - 'libxml2-dev', - 'libxslt1-dev', - 'libyaml-dev', - 'lvm2', - 'openstack-pkg-tools', - 'python-dev', - 'python-pip', - 'python-setuptools', - 'zlib1g-dev', -] - -# ubuntu packages that should not be installed when deploying from source -GIT_PACKAGE_BLACKLIST = [ - 'cinder-api', - 'cinder-common', - 'cinder-scheduler', - 'cinder-volume', - 'python-keystoneclient', -] - DEFAULT_LOOPBACK_SIZE = '5G' # Cluster resource used to determine leadership when hacluster'd @@ -381,12 +339,6 @@ def determine_packages(): if service_enabled(s): pkgs += p - if git_install_requested(): - pkgs.extend(BASE_GIT_PACKAGES) - # don't include packages that will be installed from git - for p in GIT_PACKAGE_BLACKLIST: - pkgs.remove(p) - pkgs.extend(token_cache_pkgs(source=config()['openstack-origin'])) return pkgs @@ -810,189 +762,6 @@ def setup_ipv6(): apt_install('haproxy/trusty-backports', fatal=True) -def git_install(projects_yaml): - """Perform setup, and install git repos specified in yaml parameter.""" - if git_install_requested(): - git_pre_install() - projects_yaml = git_default_repos(projects_yaml) - git_clone_and_install(projects_yaml, core_project='cinder') - git_post_install(projects_yaml) - - -def git_pre_install(): - """Perform cinder pre-install setup.""" - dirs = [{'path': '/etc/tgt', - 'owner': 'cinder', - 'group': 'cinder', - 'perms': 0750, - }, - {'path': '/var/lib/cinder', - 'owner': 'cinder', - 'group': 'cinder', - 'perms': 0755, - }, - {'path': '/var/lib/cinder/volumes', - 'owner': 'cinder', - 'group': 'cinder', - 'perms': 0750, - }, - {'path': '/var/lock/cinder', - 'owner': 'cinder', - 'group': 'root', - 'perms': 0750, - }, - {'path': '/var/log/cinder', - 'owner': 'cinder', - 'group': 'cinder', - 'perms': 0750, - }] - - logs = [ - '/var/log/cinder/cinder-api.log', - '/var/log/cinder/cinder-backup.log', - '/var/log/cinder/cinder-scheduler.log', - '/var/log/cinder/cinder-volume.log', - ] - - adduser('cinder', shell='/bin/bash', system_user=True) - add_group('cinder', system_group=True) - add_user_to_group('cinder', 'cinder') - - for d in dirs: - mkdir(d['path'], owner=d['owner'], group=d['group'], perms=d['perms'], - force=False) - - for l in logs: - write_file(l, '', owner='cinder', group='cinder', perms=0600) - - -def git_post_install(projects_yaml): - """Perform cinder post-install setup.""" - http_proxy = git_yaml_value(projects_yaml, 'http_proxy') - base_packages = ['mysql-python', 'python-cephlibs'] - for pkg in base_packages: - if http_proxy: - pip_install(pkg, proxy=http_proxy, - venv=git_pip_venv_dir(projects_yaml)) - else: - pip_install(pkg, - venv=git_pip_venv_dir(projects_yaml)) - - src_etc = os.path.join(git_src_dir(projects_yaml, 'cinder'), 'etc/cinder') - configs = { - 'src': src_etc, - 'dest': '/etc/cinder', - } - - if os.path.exists(configs['dest']): - shutil.rmtree(configs['dest']) - shutil.copytree(configs['src'], configs['dest']) - - # NOTE(coreycb): Need to find better solution than bin symlinks. - symlinks = [ - {'src': os.path.join(git_pip_venv_dir(projects_yaml), - 'bin/cinder-manage'), - 'link': '/usr/local/bin/cinder-manage'}, - {'src': os.path.join(git_pip_venv_dir(projects_yaml), - 'bin/cinder-rootwrap'), - 'link': '/usr/local/bin/cinder-rootwrap'}, - ] - - for s in symlinks: - if os.path.lexists(s['link']): - os.remove(s['link']) - os.symlink(s['src'], s['link']) - - render('git/cinder_tgt.conf', '/etc/tgt/conf.d', {}, owner='cinder', - group='cinder', perms=0o644) - render('git/logging.conf', '/etc/cinder/logging.conf', {}, owner='cinder', - group='cinder', perms=0o644) - render('git/cinder_sudoers', '/etc/sudoers.d/cinder_sudoers', {}, - owner='root', group='root', perms=0o440) - - os.chmod('/etc/sudoers.d', 0o750) - - bin_dir = os.path.join(git_pip_venv_dir(projects_yaml), 'bin') - # Use systemd init units/scripts from ubuntu wily onward - if lsb_release()['DISTRIB_RELEASE'] >= '15.10': - templates_dir = os.path.join(charm_dir(), 'templates/git') - daemons = ['cinder-api', 'cinder-backup', 'cinder-scheduler', - 'cinder-volume'] - for daemon in daemons: - cinder_context = { - 'daemon_path': os.path.join(bin_dir, daemon), - } - template_file = 'git/{}.init.in.template'.format(daemon) - init_in_file = '{}.init.in'.format(daemon) - render(template_file, os.path.join(templates_dir, init_in_file), - cinder_context, perms=0o644) - git_generate_systemd_init_files(templates_dir) - else: - cinder_api_context = { - 'service_description': 'Cinder API server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-api', - 'executable_name': os.path.join(bin_dir, 'cinder-api'), - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-api.log', - } - - cinder_backup_context = { - 'service_description': 'Cinder backup server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-backup', - 'executable_name': os.path.join(bin_dir, 'cinder-backup'), - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-backup.log', - } - - cinder_scheduler_context = { - 'service_description': 'Cinder scheduler server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-scheduler', - 'executable_name': os.path.join(bin_dir, 'cinder-scheduler'), - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-scheduler.log', - } - - cinder_volume_context = { - 'service_description': 'Cinder volume server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-volume', - 'executable_name': os.path.join(bin_dir, 'cinder-volume'), - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-volume.log', - } - - templates_dir = 'hooks/charmhelpers/contrib/openstack/templates' - templates_dir = os.path.join(charm_dir(), templates_dir) - render('git.upstart', '/etc/init/cinder-api.conf', - cinder_api_context, perms=0o644, - templates_dir=templates_dir) - render('git.upstart', '/etc/init/cinder-backup.conf', - cinder_backup_context, perms=0o644, - templates_dir=templates_dir) - render('git.upstart', '/etc/init/cinder-scheduler.conf', - cinder_scheduler_context, perms=0o644, - templates_dir=templates_dir) - render('git.upstart', '/etc/init/cinder-volume.conf', - cinder_volume_context, perms=0o644, - templates_dir=templates_dir) - - if not is_unit_paused_set(): - service_restart('tgtd') - - [service_restart(s) for s in services()] - - def filesystem_mounted(fs): return subprocess.call(['grep', '-wqs', fs, '/proc/mounts']) == 0 diff --git a/templates/git/cinder-api.init.in.template b/templates/git/cinder-api.init.in.template deleted file mode 100644 index 39eef1ca..00000000 --- a/templates/git/cinder-api.init.in.template +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: cinder-api -# Required-Start: $network $local_fs $remote_fs $syslog -# Required-Stop: $remote_fs -# Should-Start: postgresql mysql keystone rabbitmq-server ntp -# Should-Stop: postgresql mysql keystone rabbitmq-server ntp -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Cinder Api -# Description: Provides EBS like storage for your -# virtual machine instances -### END INIT INFO - -# Author: Julien Danjou , Thomas Goirand - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="OpenStack Cinder Api" -PROJECT_NAME=cinder -NAME=${PROJECT_NAME}-api -DAEMON={{ daemon_path }} diff --git a/templates/git/cinder-backup.init.in.template b/templates/git/cinder-backup.init.in.template deleted file mode 100644 index 10da61e2..00000000 --- a/templates/git/cinder-backup.init.in.template +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: cinder-backup -# Required-Start: $network $local_fs $remote_fs $syslog -# Required-Stop: $remote_fs -# Should-Start: postgresql mysql keystone rabbitmq-server ntp -# Should-Stop: postgresql mysql keystone rabbitmq-server ntp -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Cinder Backup -# Description: Provides Cinder Backup -### END INIT INFO - -# Author: Thomas Goirand - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="OpenStack Cinder Backup" -PROJECT_NAME=cinder -NAME=${PROJECT_NAME}-backup -DAEMON={{ daemon_path }} diff --git a/templates/git/cinder-scheduler.init.in.template b/templates/git/cinder-scheduler.init.in.template deleted file mode 100644 index e30fd306..00000000 --- a/templates/git/cinder-scheduler.init.in.template +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: cinder-scheduler -# Required-Start: $network $local_fs $remote_fs $syslog -# Required-Stop: $remote_fs -# Should-Start: postgresql mysql keystone rabbitmq-server ntp -# Should-Stop: postgresql mysql keystone rabbitmq-server ntp -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Cinder Scheduler -# Description: Provides EBS like storage for your -# virtual machine instances -### END INIT INFO - -# Author: Julien Danjou , Thomas Goirand - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="OpenStack Cinder Scheduler" -PROJECT_NAME=cinder -NAME=${PROJECT_NAME}-scheduler -DAEMON={{ daemon_path }} diff --git a/templates/git/cinder-volume.init.in.template b/templates/git/cinder-volume.init.in.template deleted file mode 100644 index 54eebf8f..00000000 --- a/templates/git/cinder-volume.init.in.template +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: cinder-volume -# Required-Start: $network $local_fs $remote_fs $syslog -# Required-Stop: $remote_fs -# Should-Start: postgresql mysql keystone rabbitmq-server ntp -# Should-Stop: postgresql mysql keystone rabbitmq-server ntp -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Cinder Volume -# Description: Provides EBS like storage for your -# virtual machine instances -### END INIT INFO - -# Author: Julien Danjou - -# PATH should only include /usr/* if it runs after the mountnfs.sh script -PATH=/sbin:/usr/sbin:/bin:/usr/bin -DESC="OpenStack Cinder Volume" -PROJECT_NAME=cinder -NAME=${PROJECT_NAME}-volume -DAEMON={{ daemon_path }} diff --git a/templates/git/cinder_sudoers b/templates/git/cinder_sudoers deleted file mode 100644 index 0a84240d..00000000 --- a/templates/git/cinder_sudoers +++ /dev/null @@ -1,4 +0,0 @@ -Defaults:cinder !requiretty - -cinder ALL = (root) NOPASSWD: /usr/local/bin/cinder-rootwrap /etc/cinder/rootwrap.conf * - diff --git a/templates/git/cinder_tgt.conf b/templates/git/cinder_tgt.conf deleted file mode 100644 index 444eb00e..00000000 --- a/templates/git/cinder_tgt.conf +++ /dev/null @@ -1 +0,0 @@ -include /var/lib/cinder/volumes/* diff --git a/templates/git/logging.conf b/templates/git/logging.conf deleted file mode 100644 index 476425b8..00000000 --- a/templates/git/logging.conf +++ /dev/null @@ -1,76 +0,0 @@ -[loggers] -keys = root, cinder - -[handlers] -keys = stderr, stdout, watchedfile, syslog, null - -[formatters] -keys = legacycinder, default - -[logger_root] -level = WARNING -handlers = null - -[logger_cinder] -level = INFO -handlers = stderr -qualname = cinder - -[logger_amqplib] -level = WARNING -handlers = stderr -qualname = amqplib - -[logger_sqlalchemy] -level = WARNING -handlers = stderr -qualname = sqlalchemy -# "level = INFO" logs SQL queries. -# "level = DEBUG" logs SQL queries and results. -# "level = WARNING" logs neither. (Recommended for production systems.) - -[logger_boto] -level = WARNING -handlers = stderr -qualname = boto - -[logger_suds] -level = INFO -handlers = stderr -qualname = suds - -[logger_eventletwsgi] -level = WARNING -handlers = stderr -qualname = eventlet.wsgi.server - -[handler_stderr] -class = StreamHandler -args = (sys.stderr,) -formatter = legacycinder - -[handler_stdout] -class = StreamHandler -args = (sys.stdout,) -formatter = legacycinder - -[handler_watchedfile] -class = handlers.WatchedFileHandler -args = ('cinder.log',) -formatter = legacycinder - -[handler_syslog] -class = handlers.SysLogHandler -args = ('/dev/log', handlers.SysLogHandler.LOG_USER) -formatter = legacycinder - -[handler_null] -class = cinder.log.NullHandler -formatter = default -args = () - -[formatter_legacycinder] -class = cinder.log.LegacyCinderFormatter - -[formatter_default] -format = %(message)s diff --git a/tests/basic_deployment.py b/tests/basic_deployment.py index 7e006af7..9c4fd6f0 100644 --- a/tests/basic_deployment.py +++ b/tests/basic_deployment.py @@ -15,8 +15,6 @@ # limitations under the License. import amulet -import os -import yaml from charmhelpers.contrib.openstack.amulet.deployment import ( OpenStackAmuletDeployment @@ -38,12 +36,11 @@ class CinderBasicDeployment(OpenStackAmuletDeployment): Create, clone, delete volumes. Create volume from glance image. Create volume snapshot. Create volume from snapshot.""" - def __init__(self, series=None, openstack=None, source=None, git=False, + def __init__(self, series=None, openstack=None, source=None, stable=False): """Deploy the entire test environment.""" super(CinderBasicDeployment, self).__init__(series, openstack, source, stable) - self.git = git self._add_services() self._add_relations() self._configure_services() @@ -119,35 +116,6 @@ class CinderBasicDeployment(OpenStackAmuletDeployment): 'glance-api-version': '2', 'overwrite': 'true', 'ephemeral-unmount': '/mnt'} - if self.git: - amulet_http_proxy = os.environ.get('AMULET_HTTP_PROXY') - - reqs_repo = 'git://github.com/openstack/requirements' - cinder_repo = 'git://github.com/openstack/cinder' - if self._get_openstack_release() == self.trusty_icehouse: - reqs_repo = 'git://github.com/coreycb/requirements' - cinder_repo = 'git://github.com/coreycb/cinder' - - branch = 'stable/' + self._get_openstack_release_string() - - openstack_origin_git = { - 'repositories': [ - {'name': 'requirements', - 'repository': reqs_repo, - 'branch': branch}, - {'name': 'cinder', - 'repository': cinder_repo, - 'branch': branch}, - ], - # Most tests use /mnt/openstack-git but cinder's using /dev/vdb - # to store block devices so leave /mnt alone. - 'directory': '/tmp/openstack-git', - 'http_proxy': amulet_http_proxy, - 'https_proxy': amulet_http_proxy, - } - cinder_config['openstack-origin-git'] = \ - yaml.dump(openstack_origin_git) - keystone_config = { 'admin-password': 'openstack', 'admin-token': 'ubuntutesting' @@ -365,7 +333,7 @@ class CinderBasicDeployment(OpenStackAmuletDeployment): }] else: expected = [{ - 'name': 'cinderv3_cinderv2', + 'name': 'cinderv2_cinderv3', 'enabled': True, 'tenantId': u.not_null, 'id': u.not_null, @@ -515,7 +483,7 @@ class CinderBasicDeployment(OpenStackAmuletDeployment): expected['service_username'] = 'cinder_cinderv2' else: # Pike and later - expected['service_username'] = 'cinderv3_cinderv2' + expected['service_username'] = 'cinderv2_cinderv3' ret = u.validate_relation_data(unit, relation, expected) if ret: diff --git a/tests/dfs-basic-trusty-icehouse b/tests/dfs-basic-trusty-icehouse deleted file mode 100755 index 56948745..00000000 --- a/tests/dfs-basic-trusty-icehouse +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2016 Canonical Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Amulet tests on a basic Cinder git deployment on trusty-icehouse.""" - -from basic_deployment import CinderBasicDeployment - -if __name__ == '__main__': - deployment = CinderBasicDeployment(series='trusty', git=True) - deployment.run_tests() diff --git a/tests/dfs-basic-trusty-kilo b/tests/dfs-basic-trusty-kilo deleted file mode 100755 index 29b1d00b..00000000 --- a/tests/dfs-basic-trusty-kilo +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python -# -# Copyright 2016 Canonical Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Amulet tests on a basic cinder git deployment on trusty-kilo.""" - -from basic_deployment import CinderBasicDeployment - -if __name__ == '__main__': - deployment = CinderBasicDeployment(series='trusty', - openstack='cloud:trusty-kilo', - source='cloud:trusty-updates/kilo', - git=True) - deployment.run_tests() diff --git a/unit_tests/__init__.py b/unit_tests/__init__.py index ce0d1e74..a18d4bfc 100644 --- a/unit_tests/__init__.py +++ b/unit_tests/__init__.py @@ -25,3 +25,9 @@ sys.modules['cinder.context'] = cinder.context sys.modules['cinder.db'] = cinder.db sys.modules['cinder.db.sqlalchemy'] = cinder.db.sqlalchemy sys.modules['cinder.db.sqlalchemy.api'] = cinder.db.sqlalchemy.api + +# python-apt is not installed as part of test-requirements but is imported by +# some charmhelpers modules so create a fake import. +mock_apt = mock.MagicMock() +sys.modules['apt'] = mock_apt +mock_apt.apt_pkg = mock.MagicMock() diff --git a/unit_tests/test_actions_git_reinstall.py b/unit_tests/test_actions_git_reinstall.py deleted file mode 100644 index 25d441bf..00000000 --- a/unit_tests/test_actions_git_reinstall.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright 2016 Canonical Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import os -import sys - -from mock import patch, MagicMock - -os.environ['JUJU_UNIT_NAME'] = 'cinder' - -# python-apt is not installed as part of test-requirements but is imported by -# some charmhelpers modules so create a fake import. -mock_apt = MagicMock() -sys.modules['apt'] = mock_apt -mock_apt.apt_pkg = MagicMock() - -from test_utils import RESTART_MAP, CharmTestCase - -with patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec: - mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f: - lambda *args, **kwargs: f(*args, **kwargs)) - with patch('cinder_utils.register_configs') as register_configs: - with patch('cinder_utils.restart_map') as restart_map: - restart_map.return_value = RESTART_MAP - import git_reinstall - -TO_PATCH = [ - 'config', -] - - -openstack_origin_git = \ - """repositories: - - {name: requirements, - repository: 'git://git.openstack.org/openstack/requirements', - branch: stable/juno} - - {name: cinder, - repository: 'git://git.openstack.org/openstack/cinder', - branch: stable/juno}""" - - -class TestCinderActions(CharmTestCase): - - def setUp(self): - super(TestCinderActions, self).setUp(git_reinstall, TO_PATCH) - self.config.side_effect = self.test_config.get - - @patch.object(git_reinstall, 'action_set') - @patch.object(git_reinstall, 'action_fail') - @patch.object(git_reinstall, 'git_install') - @patch.object(git_reinstall, 'config_changed') - @patch('charmhelpers.contrib.openstack.utils.config') - def test_git_reinstall(self, _config, config_changed, git_install, - action_fail, action_set): - _config.return_value = openstack_origin_git - self.test_config.set('openstack-origin-git', openstack_origin_git) - - git_reinstall.git_reinstall() - - git_install.assert_called_with(openstack_origin_git) - self.assertTrue(git_install.called) - self.assertTrue(config_changed.called) - self.assertFalse(action_set.called) - self.assertFalse(action_fail.called) - - @patch.object(git_reinstall, 'action_set') - @patch.object(git_reinstall, 'action_fail') - @patch.object(git_reinstall, 'git_install') - @patch.object(git_reinstall, 'config_changed') - @patch('charmhelpers.contrib.openstack.utils.config') - def test_git_reinstall_not_configured(self, _config, config_changed, - git_install, action_fail, - action_set): - _config.return_value = None - - git_reinstall.git_reinstall() - - msg = 'openstack-origin-git is not configured' - action_fail.assert_called_with(msg) - self.assertFalse(git_install.called) - self.assertFalse(action_set.called) - - @patch.object(git_reinstall, 'action_set') - @patch.object(git_reinstall, 'action_fail') - @patch.object(git_reinstall, 'git_install') - @patch.object(git_reinstall, 'config_changed') - @patch('traceback.format_exc') - @patch('charmhelpers.contrib.openstack.utils.config') - def test_git_reinstall_exception(self, _config, format_exc, config_changed, - git_install, action_fail, action_set): - _config.return_value = openstack_origin_git - e = OSError('something bad happened') - git_install.side_effect = e - traceback = ( - "Traceback (most recent call last):\n" - " File \"actions/git_reinstall.py\", line 37, in git_reinstall\n" - " git_install(config(\'openstack-origin-git\'))\n" - " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 964, in __call__\n" # noqa - " return _mock_self._mock_call(*args, **kwargs)\n" - " File \"/usr/lib/python2.7/dist-packages/mock.py\", line 1019, in _mock_call\n" # noqa - " raise effect\n" - "OSError: something bad happened\n") - format_exc.return_value = traceback - - git_reinstall.git_reinstall() - - msg = 'git-reinstall resulted in an unexpected error' - action_fail.assert_called_with(msg) - action_set.assert_called_with({'traceback': traceback}) diff --git a/unit_tests/test_actions_openstack_upgrade.py b/unit_tests/test_actions_openstack_upgrade.py index 0a31a930..d7765ef1 100644 --- a/unit_tests/test_actions_openstack_upgrade.py +++ b/unit_tests/test_actions_openstack_upgrade.py @@ -45,13 +45,11 @@ class TestCinderUpgradeActions(CharmTestCase): @patch('charmhelpers.contrib.openstack.utils.juju_log') @patch('charmhelpers.contrib.openstack.utils.config') @patch('charmhelpers.contrib.openstack.utils.action_set') - @patch('charmhelpers.contrib.openstack.utils.git_install_requested') @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available') - def test_openstack_upgrade_true(self, upgrade_avail, git_requested, + def test_openstack_upgrade_true(self, upgrade_avail, action_set, config, log, mock_cinder_hooks): mock_cinder_hooks.config_changed = MagicMock() - git_requested.return_value = False upgrade_avail.return_value = True config.return_value = True self.relation_ids.return_value = ['relid1'] @@ -69,13 +67,11 @@ class TestCinderUpgradeActions(CharmTestCase): @patch('charmhelpers.contrib.openstack.utils.juju_log') @patch('charmhelpers.contrib.openstack.utils.config') @patch('charmhelpers.contrib.openstack.utils.action_set') - @patch('charmhelpers.contrib.openstack.utils.git_install_requested') @patch('charmhelpers.contrib.openstack.utils.openstack_upgrade_available') - def test_openstack_upgrade_false(self, upgrade_avail, git_requested, + def test_openstack_upgrade_false(self, upgrade_avail, action_set, config, log, mock_cinder_hooks): mock_cinder_hooks.config_changed = MagicMock() - git_requested.return_value = False upgrade_avail.return_value = True config.return_value = False diff --git a/unit_tests/test_cinder_hooks.py b/unit_tests/test_cinder_hooks.py index bf7ee01e..c40601d0 100644 --- a/unit_tests/test_cinder_hooks.py +++ b/unit_tests/test_cinder_hooks.py @@ -13,11 +13,8 @@ # limitations under the License. import json -import sys -import yaml from mock import ( - MagicMock, patch, call ) @@ -27,13 +24,6 @@ from test_utils import ( RESTART_MAP, ) -# python-apt is not installed as part of test-requirements but is imported by -# some charmhelpers modules so create a fake import. -mock_apt = MagicMock() -sys.modules['apt'] = mock_apt -mock_apt.apt_pkg = MagicMock() - - with patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec: mock_dec.side_effect = (lambda *dargs, **dkwargs: lambda f: lambda *args, **kwargs: f(*args, **kwargs)) @@ -41,6 +31,7 @@ with patch('charmhelpers.contrib.hardening.harden.harden') as mock_dec: with patch('cinder_utils.restart_map') as restart_map: restart_map.return_value = RESTART_MAP import cinder_hooks as hooks + reload(hooks) hooks.hooks._config_save = False import cinder_utils as utils @@ -54,7 +45,6 @@ TO_PATCH = [ 'determine_packages', 'do_openstack_upgrade', 'ensure_ceph_keyring', - 'git_install', 'is_clustered', 'juju_log', 'log', @@ -105,45 +95,15 @@ class TestInstallHook(CharmTestCase): super(TestInstallHook, self).setUp(hooks, TO_PATCH) self.config.side_effect = self.test_config.get - @patch.object(utils, 'git_install_requested') - def test_install_precise_distro(self, git_requested): + def test_install_precise_distro(self): 'It redirects to cloud archive if setup to install precise+distro' - git_requested.return_value = False self.lsb_release.return_value = {'DISTRIB_CODENAME': 'precise'} hooks.hooks.execute(['hooks/install.real']) ca = 'cloud:precise-folsom' self.configure_installation_source.assert_called_with(ca) - @patch.object(utils, 'git_install_requested') - def test_install_git(self, git_requested): - git_requested.return_value = True - self.determine_packages.return_value = ['foo', 'bar', 'baz'] - repo = 'cloud:trusty-juno' - openstack_origin_git = { - 'repositories': [ - {'name': 'requirements', - 'repository': 'git://git.openstack.org/openstack/requirements', # noqa - 'branch': 'stable/juno'}, - {'name': 'cinder', - 'repository': 'git://git.openstack.org/openstack/cinder', - 'branch': 'stable/juno'} - ], - 'directory': '/mnt/openstack-git', - } - projects_yaml = yaml.dump(openstack_origin_git) - self.test_config.set('openstack-origin', repo) - self.test_config.set('openstack-origin-git', projects_yaml) - hooks.hooks.execute(['hooks/install.real']) - self.assertTrue(self.execd_preinstall.called) - self.configure_installation_source.assert_called_with(repo) - self.apt_update.assert_called_with() - self.apt_install.assert_called_with(['foo', 'bar', 'baz'], fatal=True) - self.git_install.assert_called_with(projects_yaml) - - @patch.object(utils, 'git_install_requested') - def test_correct_install_packages(self, git_requested): + def test_correct_install_packages(self): 'It installs the correct packages based on what is determined' - git_requested.return_value = False self.determine_packages.return_value = ['foo', 'bar', 'baz'] hooks.hooks.execute(['hooks/install.real']) self.apt_install.assert_called_with(['foo', 'bar', 'baz'], fatal=True) @@ -168,12 +128,10 @@ class TestChangedHooks(CharmTestCase): _joined.assert_called_with(relation_id='amqp:1') @patch.object(hooks, 'configure_https') - @patch.object(hooks, 'git_install_requested') @patch.object(hooks, 'config_value_changed') def test_config_changed(self, config_val_changed, - git_requested, conf_https): + conf_https): 'It writes out all config' - git_requested.return_value = False self.openstack_upgrade_available.return_value = False hooks.hooks.execute(['hooks/config-changed']) self.assertTrue(self.CONFIGS.write_all.called) @@ -184,12 +142,10 @@ class TestChangedHooks(CharmTestCase): self.open_port.assert_called_with(8776) @patch.object(hooks, 'configure_https') - @patch.object(hooks, 'git_install_requested') @patch.object(hooks, 'config_value_changed') def test_config_changed_block_devices(self, config_val_changed, - git_requested, conf_https): + conf_https): 'It writes out all config' - git_requested.return_value = False self.openstack_upgrade_available.return_value = False self.test_config.set('block-device', 'sdb /dev/sdc sde') self.test_config.set('volume-group', 'cinder-new') @@ -204,14 +160,11 @@ class TestChangedHooks(CharmTestCase): True, True, False) @patch.object(hooks, 'configure_https') - @patch.object(hooks, 'git_install_requested') @patch.object(hooks, 'config_value_changed') def test_config_changed_uses_remove_missing_force(self, config_val_changed, - git_requested, conf_https): 'It uses the remove-missing-force config option' - git_requested.return_value = False self.openstack_upgrade_available.return_value = False self.test_config.set('block-device', 'sdb') self.test_config.set('remove-missing-force', True) @@ -222,51 +175,21 @@ class TestChangedHooks(CharmTestCase): False, False, True) @patch.object(hooks, 'configure_https') - @patch.object(hooks, 'git_install_requested') @patch.object(hooks, 'config_value_changed') def test_config_changed_upgrade_available(self, config_val_changed, - git_requested, conf_https): + conf_https): 'It writes out all config with an available OS upgrade' - git_requested.return_value = False self.openstack_upgrade_available.return_value = True hooks.hooks.execute(['hooks/config-changed']) self.do_openstack_upgrade.assert_called_with(configs=self.CONFIGS) - @patch.object(hooks, 'configure_https') - @patch.object(hooks, 'git_install_requested') - @patch.object(hooks, 'config_value_changed') - def test_config_changed_git_updated(self, config_val_changed, - git_requested, conf_https): - git_requested.return_value = True - repo = 'cloud:trusty-juno' - openstack_origin_git = { - 'repositories': [ - {'name': 'requirements', - 'repository': 'git://git.openstack.org/openstack/requirements', # noqa - 'branch': 'stable/juno'}, - {'name': 'cinder', - 'repository': 'git://git.openstack.org/openstack/', - 'branch': 'stable/juno'} - ], - 'directory': '/mnt/openstack-git', - } - projects_yaml = yaml.dump(openstack_origin_git) - self.test_config.set('openstack-origin', repo) - self.test_config.set('openstack-origin-git', projects_yaml) - hooks.hooks.execute(['hooks/config-changed']) - self.git_install.assert_called_with(projects_yaml) - self.assertFalse(self.do_openstack_upgrade.called) - self.assertTrue(conf_https.called) - @patch('charmhelpers.core.host.service') @patch.object(hooks, 'configure_https') - @patch.object(hooks, 'git_install_requested') @patch.object(hooks, 'config_value_changed') def test_config_changed_overwrite_changed(self, config_val_changed, - git_requested, conf_https, + conf_https, _services): 'It uses the overwrite config option' - git_requested.return_value = False self.openstack_upgrade_available.return_value = False config_val_changed.return_value = True hooks.hooks.execute(['hooks/config-changed']) @@ -277,12 +200,10 @@ class TestChangedHooks(CharmTestCase): False, False, False) self.service_restart.assert_called_with('cinder-volume') - @patch.object(hooks, 'git_install_requested') @patch.object(hooks, 'config_value_changed') - def test_config_changed_with_openstack_upgrade_action(self, - config_value_changed, - git_requested): - git_requested.return_value = False + def test_config_changed_with_openstack_upgrade_action( + self, + config_value_changed): self.openstack_upgrade_available.return_value = True self.test_config.set('action-managed-upgrade', True) diff --git a/unit_tests/test_cinder_utils.py b/unit_tests/test_cinder_utils.py index d937027f..285528d8 100644 --- a/unit_tests/test_cinder_utils.py +++ b/unit_tests/test_cinder_utils.py @@ -37,13 +37,6 @@ TO_PATCH = [ 'umount', 'mkdir', 'service_restart', - # helpers.core.templating - 'render', - # helpers.contrib.openstack.utils - 'git_generate_systemd_init_files', - 'git_src_dir', - # helpers.contrib.python.packages - 'pip_install', # ceph utils # storage_utils 'create_lvm_physical_volume', @@ -98,15 +91,6 @@ FDISKDISPLAY = """ """ -openstack_origin_git = \ - """repositories: - - {name: requirements, - repository: 'git://git.openstack.org/openstack/requirements', - branch: stable/juno} - - {name: cinder, - repository: 'git://git.openstack.org/openstack/cinder', - branch: stable/juno}""" - class TestCinderUtils(CharmTestCase): @@ -140,10 +124,8 @@ class TestCinderUtils(CharmTestCase): self.assertFalse(cinder_utils.service_enabled('volume')) @patch('cinder_utils.service_enabled') - @patch('cinder_utils.git_install_requested') - def test_determine_packages_all(self, git_requested, service_enabled): + def test_determine_packages_all(self, service_enabled): 'It determines all packages required when all services enabled' - git_requested.return_value = False service_enabled.return_value = True pkgs = cinder_utils.determine_packages() self.assertEqual(sorted(pkgs), @@ -153,10 +135,8 @@ class TestCinderUtils(CharmTestCase): cinder_utils.SCHEDULER_PACKAGES)) @patch('cinder_utils.service_enabled') - @patch('cinder_utils.git_install_requested') - def test_determine_packages_subset(self, git_requested, service_enabled): + def test_determine_packages_subset(self, service_enabled): 'It determines packages required for a subset of enabled services' - git_requested.return_value = False service_enabled.side_effect = self.svc_enabled self.test_config.set('openstack-origin', 'cloud:xenial-newton') self.token_cache_pkgs.return_value = ['memcached'] @@ -790,184 +770,6 @@ class TestCinderUtils(CharmTestCase): configs.set_release.assert_called_with(openstack_release='havana') self.assertFalse(migrate.called) - @patch.object(cinder_utils, 'git_install_requested') - @patch.object(cinder_utils, 'git_clone_and_install') - @patch.object(cinder_utils, 'git_post_install') - @patch.object(cinder_utils, 'git_pre_install') - def test_git_install(self, git_pre, git_post, git_clone_and_install, - git_requested): - projects_yaml = openstack_origin_git - git_requested.return_value = True - cinder_utils.git_install(projects_yaml) - self.assertTrue(git_pre.called) - git_clone_and_install.assert_called_with(openstack_origin_git, - core_project='cinder') - self.assertTrue(git_post.called) - - @patch.object(cinder_utils, 'mkdir') - @patch.object(cinder_utils, 'write_file') - @patch.object(cinder_utils, 'add_user_to_group') - @patch.object(cinder_utils, 'add_group') - @patch.object(cinder_utils, 'adduser') - def test_git_pre_install(self, adduser, add_group, add_user_to_group, - write_file, mkdir): - cinder_utils.git_pre_install() - adduser.assert_called_with('cinder', shell='/bin/bash', - system_user=True) - add_group.assert_called_with('cinder', system_group=True) - add_user_to_group.assert_called_with('cinder', 'cinder') - expected = [ - call('/etc/tgt', owner='cinder', perms=488, force=False, - group='cinder'), - call('/var/lib/cinder', owner='cinder', perms=493, force=False, - group='cinder'), - call('/var/lib/cinder/volumes', owner='cinder', perms=488, - force=False, group='cinder'), - call('/var/lock/cinder', owner='cinder', perms=488, force=False, - group='root'), - call('/var/log/cinder', owner='cinder', perms=488, force=False, - group='cinder'), - ] - self.assertEqual(mkdir.call_args_list, expected) - expected = [ - call('/var/log/cinder/cinder-api.log', '', perms=0600, - owner='cinder', group='cinder'), - call('/var/log/cinder/cinder-backup.log', '', perms=0600, - owner='cinder', group='cinder'), - call('/var/log/cinder/cinder-scheduler.log', '', perms=0600, - owner='cinder', group='cinder'), - call('/var/log/cinder/cinder-volume.log', '', perms=0600, - owner='cinder', group='cinder'), - ] - self.assertEqual(write_file.call_args_list, expected) - - @patch.object(cinder_utils, 'services') - @patch('os.path.join') - @patch('os.path.exists') - @patch('shutil.copytree') - @patch('shutil.rmtree') - @patch('os.chown') - @patch('os.chmod') - @patch('os.symlink') - def test_git_post_install_upstart(self, symlink, chmod, chown, rmtree, - copytree, exists, join, services): - services.return_value = ['svc1'] - projects_yaml = openstack_origin_git - join.return_value = 'joined-string' - self.lsb_release.return_value = {'DISTRIB_RELEASE': '15.04'} - cinder_utils.git_post_install(projects_yaml) - self.pip_install('mysql-python', venv='joined-string') - expected = [ - call('joined-string', '/etc/cinder'), - ] - copytree.assert_has_calls(expected) - - expected = [ - call('joined-string', '/usr/local/bin/cinder-manage'), - ] - symlink.assert_has_calls(expected, any_order=True) - - cinder_api_context = { - 'service_description': 'Cinder API server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-api', - 'executable_name': 'joined-string', - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-api.log', - } - - cinder_backup_context = { - 'service_description': 'Cinder backup server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-backup', - 'executable_name': 'joined-string', - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-backup.log', - } - - cinder_scheduler_context = { - 'service_description': 'Cinder scheduler server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-scheduler', - 'executable_name': 'joined-string', - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-scheduler.log', - } - - cinder_volume_context = { - 'service_description': 'Cinder volume server', - 'service_name': 'Cinder', - 'user_name': 'cinder', - 'start_dir': '/var/lib/cinder', - 'process_name': 'cinder-volume', - 'executable_name': 'joined-string', - 'config_files': ['/etc/cinder/cinder.conf'], - 'log_file': '/var/log/cinder/cinder-volume.log', - } - expected = [ - call('git/cinder_tgt.conf', '/etc/tgt/conf.d', {}, owner='cinder', - group='cinder', perms=0o644), - call('git/logging.conf', '/etc/cinder/logging.conf', {}, - owner='cinder', group='cinder', perms=0o644), - call('git/cinder_sudoers', '/etc/sudoers.d/cinder_sudoers', {}, - owner='root', group='root', perms=0o440), - call('git.upstart', '/etc/init/cinder-api.conf', - cinder_api_context, perms=0o644, - templates_dir='joined-string'), - call('git.upstart', '/etc/init/cinder-backup.conf', - cinder_backup_context, perms=0o644, - templates_dir='joined-string'), - call('git.upstart', '/etc/init/cinder-scheduler.conf', - cinder_scheduler_context, perms=0o644, - templates_dir='joined-string'), - call('git.upstart', '/etc/init/cinder-volume.conf', - cinder_volume_context, perms=0o644, - templates_dir='joined-string'), - ] - self.assertEqual(self.render.call_args_list, expected) - expected = [call('tgtd'), call('svc1')] - self.assertEqual(self.service_restart.call_args_list, expected) - - @patch.object(cinder_utils, 'services') - @patch('os.path.join') - @patch('shutil.copytree') - @patch('shutil.rmtree') - @patch('pwd.getpwnam') - @patch('grp.getgrnam') - @patch('os.chown') - @patch('os.chmod') - @patch('os.symlink') - def test_git_post_install_systemd(self, symlink, chmod, chown, grp, pwd, - rmtree, copytree, join, services): - projects_yaml = openstack_origin_git - join.return_value = 'joined-string' - self.lsb_release.return_value = {'DISTRIB_RELEASE': '15.10'} - cinder_utils.git_post_install(projects_yaml) - - expected = [ - call('git/cinder_tgt.conf', '/etc/tgt/conf.d', {}, - group='cinder', owner='cinder', perms=420), - call('git/logging.conf', '/etc/cinder/logging.conf', {}, - group='cinder', owner='cinder', perms=420), - call('git/cinder_sudoers', '/etc/sudoers.d/cinder_sudoers', {}, - group='root', owner='root', perms=288), - call('git/cinder-api.init.in.template', 'joined-string', - {'daemon_path': 'joined-string'}, perms=420), - call('git/cinder-backup.init.in.template', 'joined-string', - {'daemon_path': 'joined-string'}, perms=420), - call('git/cinder-scheduler.init.in.template', 'joined-string', - {'daemon_path': 'joined-string'}, perms=420), - call('git/cinder-volume.init.in.template', 'joined-string', - {'daemon_path': 'joined-string'}, perms=420), - ] - self.assertEqual(self.render.call_args_list, expected) - @patch.object(cinder_utils, 'local_unit', lambda *args: 'unit/0') def test_check_local_db_actions_complete_by_self(self): self.relation_get.return_value = {}