Sync charm-helpers
This commit is contained in:
parent
ece7c05e39
commit
94465e2b81
@ -15,6 +15,7 @@
|
||||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import six
|
||||
from collections import OrderedDict
|
||||
from charmhelpers.contrib.amulet.deployment import (
|
||||
AmuletDeployment
|
||||
)
|
||||
@ -111,3 +112,23 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
||||
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
||||
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo}
|
||||
return releases[(self.series, self.openstack)]
|
||||
|
||||
def _get_openstack_release_string(self):
|
||||
"""Get openstack release string.
|
||||
|
||||
Return a string representing the openstack release.
|
||||
"""
|
||||
releases = OrderedDict([
|
||||
('precise', 'essex'),
|
||||
('quantal', 'folsom'),
|
||||
('raring', 'grizzly'),
|
||||
('saucy', 'havana'),
|
||||
('trusty', 'icehouse'),
|
||||
('utopic', 'juno'),
|
||||
('vivid', 'kilo'),
|
||||
])
|
||||
if self.openstack:
|
||||
os_origin = self.openstack.split(':')[1]
|
||||
return os_origin.split('%s-' % self.series)[1].split('/')[0]
|
||||
else:
|
||||
return releases[self.series]
|
||||
|
@ -20,12 +20,10 @@
|
||||
from collections import OrderedDict
|
||||
from functools import wraps
|
||||
|
||||
import errno
|
||||
import subprocess
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
|
||||
import six
|
||||
import yaml
|
||||
@ -478,109 +476,87 @@ def git_install_requested():
|
||||
requirements_dir = None
|
||||
|
||||
|
||||
def git_clone_and_install(projects, core_project,
|
||||
parent_dir='/mnt/openstack-git'):
|
||||
"""Clone/install all OpenStack repos specified in projects dictionary."""
|
||||
global requirements_dir
|
||||
update_reqs = True
|
||||
def git_clone_and_install(projects_yaml, core_project):
|
||||
"""Clone/install all specified OpenStack repositories.
|
||||
|
||||
if not projects:
|
||||
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
|
||||
|
||||
The directory key is optional.
|
||||
"""
|
||||
global requirements_dir
|
||||
parent_dir = '/mnt/openstack-git'
|
||||
|
||||
if not projects_yaml:
|
||||
return
|
||||
|
||||
# clone/install the requirements project first
|
||||
installed = _git_clone_and_install_subset(projects, parent_dir,
|
||||
whitelist=['requirements'])
|
||||
if 'requirements' not in installed:
|
||||
update_reqs = False
|
||||
projects = yaml.load(projects_yaml)
|
||||
_git_validate_projects_yaml(projects, core_project)
|
||||
|
||||
# clone/install all other projects except requirements and the core project
|
||||
blacklist = ['requirements', core_project]
|
||||
_git_clone_and_install_subset(projects, parent_dir, blacklist=blacklist,
|
||||
update_requirements=update_reqs)
|
||||
if 'directory' in projects.keys():
|
||||
parent_dir = projects['directory']
|
||||
|
||||
# clone/install the core project
|
||||
whitelist = [core_project]
|
||||
installed = _git_clone_and_install_subset(projects, parent_dir,
|
||||
whitelist=whitelist,
|
||||
update_requirements=update_reqs)
|
||||
if core_project not in installed:
|
||||
error_out('{} git repository must be specified'.format(core_project))
|
||||
|
||||
|
||||
def _git_clone_and_install_subset(projects, parent_dir, whitelist=[],
|
||||
blacklist=[], update_requirements=False):
|
||||
"""Clone/install subset of OpenStack repos specified in projects dict."""
|
||||
global requirements_dir
|
||||
installed = []
|
||||
|
||||
for proj, val in projects.items():
|
||||
# The project subset is chosen based on the following 3 rules:
|
||||
# 1) If project is in blacklist, we don't clone/install it, period.
|
||||
# 2) If whitelist is empty, we clone/install everything else.
|
||||
# 3) If whitelist is not empty, we clone/install everything in the
|
||||
# whitelist.
|
||||
if proj in blacklist:
|
||||
continue
|
||||
if whitelist and proj not in whitelist:
|
||||
continue
|
||||
repo = val['repository']
|
||||
branch = val['branch']
|
||||
repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
|
||||
update_requirements)
|
||||
if proj == 'requirements':
|
||||
for p in projects['repositories']:
|
||||
repo = p['repository']
|
||||
branch = p['branch']
|
||||
if p['name'] == 'requirements':
|
||||
repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
|
||||
update_requirements=False)
|
||||
requirements_dir = repo_dir
|
||||
installed.append(proj)
|
||||
return installed
|
||||
else:
|
||||
repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
|
||||
update_requirements=True)
|
||||
|
||||
|
||||
def _git_clone_and_install_single(repo, branch, parent_dir,
|
||||
update_requirements=False):
|
||||
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))
|
||||
|
||||
|
||||
def _git_ensure_key_exists(key, keys):
|
||||
"""Ensure that the 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, parent_dir, update_requirements):
|
||||
"""Clone and install a single git repository."""
|
||||
dest_dir = os.path.join(parent_dir, os.path.basename(repo))
|
||||
lock_dir = os.path.join(parent_dir, os.path.basename(repo) + '.lock')
|
||||
|
||||
# Note(coreycb): The parent directory for storing git repositories can be
|
||||
# shared by multiple charms via bind mount, etc, so we use exception
|
||||
# handling to ensure the test for existence and mkdir are atomic.
|
||||
try:
|
||||
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)
|
||||
except OSError as e:
|
||||
if e.errno == errno.EEXIST:
|
||||
juju_log('Directory already exists at {}. '
|
||||
'No need to create directory.'.format(parent_dir))
|
||||
pass
|
||||
|
||||
if not os.path.exists(dest_dir):
|
||||
juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch))
|
||||
repo_dir = install_remote(repo, dest=parent_dir, branch=branch)
|
||||
else:
|
||||
juju_log('Host directory not mounted at {}. '
|
||||
'Directory created.'.format(parent_dir))
|
||||
repo_dir = dest_dir
|
||||
|
||||
# Note(coreycb): Similar to above, the cloned git repositories can be shared
|
||||
# by multiple charms via bind mount, etc, so we use exception handling and
|
||||
# special lock directories to ensure that a repository clone is only
|
||||
# attempted once.
|
||||
try:
|
||||
os.mkdir(lock_dir)
|
||||
except OSError as e:
|
||||
if e.errno == errno.EEXIST:
|
||||
juju_log('Lock directory exists at {}. Skip git clone and wait '
|
||||
'for lock removal before installing.'.format(lock_dir))
|
||||
while os.path.exists(lock_dir):
|
||||
juju_log('Waiting for git clone to complete before installing.')
|
||||
time.sleep(1)
|
||||
pass
|
||||
else:
|
||||
if not os.path.exists(dest_dir):
|
||||
juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch))
|
||||
repo_dir = install_remote(repo, dest=parent_dir, branch=branch)
|
||||
else:
|
||||
repo_dir = dest_dir
|
||||
|
||||
if update_requirements:
|
||||
if not requirements_dir:
|
||||
error_out('requirements repo must be cloned before '
|
||||
'updating from global requirements.')
|
||||
_git_update_requirements(repo_dir, requirements_dir)
|
||||
|
||||
os.rmdir(lock_dir)
|
||||
if update_requirements:
|
||||
if not requirements_dir:
|
||||
error_out('requirements repo must be cloned before '
|
||||
'updating from global requirements.')
|
||||
_git_update_requirements(repo_dir, requirements_dir)
|
||||
|
||||
juju_log('Installing git repo from dir: {}'.format(repo_dir))
|
||||
pip_install(repo_dir)
|
||||
@ -595,10 +571,29 @@ def _git_update_requirements(package_dir, reqs_dir):
|
||||
test-requirements.txt from global-requirements.txt."""
|
||||
orig_dir = os.getcwd()
|
||||
os.chdir(reqs_dir)
|
||||
cmd = "python update.py {}".format(package_dir)
|
||||
cmd = ['python', 'update.py', package_dir]
|
||||
try:
|
||||
subprocess.check_call(cmd.split(' '))
|
||||
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_src_dir(projects_yaml, project):
|
||||
"""Return the directory where the specified project's source is located"""
|
||||
parent_dir = '/mnt/openstack-git'
|
||||
|
||||
if not projects_yaml:
|
||||
return
|
||||
|
||||
projects = 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
|
||||
|
@ -15,6 +15,7 @@
|
||||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import six
|
||||
from collections import OrderedDict
|
||||
from charmhelpers.contrib.amulet.deployment import (
|
||||
AmuletDeployment
|
||||
)
|
||||
@ -111,3 +112,23 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
||||
('trusty', 'cloud:trusty-juno'): self.trusty_juno,
|
||||
('trusty', 'cloud:trusty-kilo'): self.trusty_kilo}
|
||||
return releases[(self.series, self.openstack)]
|
||||
|
||||
def _get_openstack_release_string(self):
|
||||
"""Get openstack release string.
|
||||
|
||||
Return a string representing the openstack release.
|
||||
"""
|
||||
releases = OrderedDict([
|
||||
('precise', 'essex'),
|
||||
('quantal', 'folsom'),
|
||||
('raring', 'grizzly'),
|
||||
('saucy', 'havana'),
|
||||
('trusty', 'icehouse'),
|
||||
('utopic', 'juno'),
|
||||
('vivid', 'kilo'),
|
||||
])
|
||||
if self.openstack:
|
||||
os_origin = self.openstack.split(':')[1]
|
||||
return os_origin.split('%s-' % self.series)[1].split('/')[0]
|
||||
else:
|
||||
return releases[self.series]
|
||||
|
Loading…
Reference in New Issue
Block a user