Sync charm-helpers
This commit is contained in:
parent
d427a22a52
commit
aad107dad0
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Bootstrap charm-helpers, installing its dependencies if necessary using
|
# Bootstrap charm-helpers, installing its dependencies if necessary using
|
||||||
# only standard libraries.
|
# only standard libraries.
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""Compatibility with the nrpe-external-master charm"""
|
"""Compatibility with the nrpe-external-master charm"""
|
||||||
# Copyright 2012 Canonical Ltd.
|
# Copyright 2012 Canonical Ltd.
|
||||||
#
|
#
|
||||||
@ -8,6 +24,8 @@ import subprocess
|
|||||||
import pwd
|
import pwd
|
||||||
import grp
|
import grp
|
||||||
import os
|
import os
|
||||||
|
import glob
|
||||||
|
import shutil
|
||||||
import re
|
import re
|
||||||
import shlex
|
import shlex
|
||||||
import yaml
|
import yaml
|
||||||
@ -145,7 +163,7 @@ define service {{
|
|||||||
log('Check command not found: {}'.format(parts[0]))
|
log('Check command not found: {}'.format(parts[0]))
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
def write(self, nagios_context, hostname, nagios_servicegroups=None):
|
def write(self, nagios_context, hostname, nagios_servicegroups):
|
||||||
nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format(
|
nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format(
|
||||||
self.command)
|
self.command)
|
||||||
with open(nrpe_check_file, 'w') as nrpe_check_config:
|
with open(nrpe_check_file, 'w') as nrpe_check_config:
|
||||||
@ -161,14 +179,11 @@ define service {{
|
|||||||
nagios_servicegroups)
|
nagios_servicegroups)
|
||||||
|
|
||||||
def write_service_config(self, nagios_context, hostname,
|
def write_service_config(self, nagios_context, hostname,
|
||||||
nagios_servicegroups=None):
|
nagios_servicegroups):
|
||||||
for f in os.listdir(NRPE.nagios_exportdir):
|
for f in os.listdir(NRPE.nagios_exportdir):
|
||||||
if re.search('.*{}.cfg'.format(self.command), f):
|
if re.search('.*{}.cfg'.format(self.command), f):
|
||||||
os.remove(os.path.join(NRPE.nagios_exportdir, f))
|
os.remove(os.path.join(NRPE.nagios_exportdir, f))
|
||||||
|
|
||||||
if not nagios_servicegroups:
|
|
||||||
nagios_servicegroups = nagios_context
|
|
||||||
|
|
||||||
templ_vars = {
|
templ_vars = {
|
||||||
'nagios_hostname': hostname,
|
'nagios_hostname': hostname,
|
||||||
'nagios_servicegroup': nagios_servicegroups,
|
'nagios_servicegroup': nagios_servicegroups,
|
||||||
@ -195,10 +210,10 @@ class NRPE(object):
|
|||||||
super(NRPE, self).__init__()
|
super(NRPE, self).__init__()
|
||||||
self.config = config()
|
self.config = config()
|
||||||
self.nagios_context = self.config['nagios_context']
|
self.nagios_context = self.config['nagios_context']
|
||||||
if 'nagios_servicegroups' in self.config:
|
if 'nagios_servicegroups' in self.config and self.config['nagios_servicegroups']:
|
||||||
self.nagios_servicegroups = self.config['nagios_servicegroups']
|
self.nagios_servicegroups = self.config['nagios_servicegroups']
|
||||||
else:
|
else:
|
||||||
self.nagios_servicegroups = 'juju'
|
self.nagios_servicegroups = self.nagios_context
|
||||||
self.unit_name = local_unit().replace('/', '-')
|
self.unit_name = local_unit().replace('/', '-')
|
||||||
if hostname:
|
if hostname:
|
||||||
self.hostname = hostname
|
self.hostname = hostname
|
||||||
@ -306,3 +321,38 @@ def add_init_service_checks(nrpe, services, unit_name):
|
|||||||
check_cmd='check_status_file.py -f '
|
check_cmd='check_status_file.py -f '
|
||||||
'/var/lib/nagios/service-check-%s.txt' % svc,
|
'/var/lib/nagios/service-check-%s.txt' % svc,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def copy_nrpe_checks():
|
||||||
|
"""
|
||||||
|
Copy the nrpe checks into place
|
||||||
|
|
||||||
|
"""
|
||||||
|
NAGIOS_PLUGINS = '/usr/local/lib/nagios/plugins'
|
||||||
|
nrpe_files_dir = os.path.join(os.getenv('CHARM_DIR'), 'hooks',
|
||||||
|
'charmhelpers', 'contrib', 'openstack',
|
||||||
|
'files')
|
||||||
|
|
||||||
|
if not os.path.exists(NAGIOS_PLUGINS):
|
||||||
|
os.makedirs(NAGIOS_PLUGINS)
|
||||||
|
for fname in glob.glob(os.path.join(nrpe_files_dir, "check_*")):
|
||||||
|
if os.path.isfile(fname):
|
||||||
|
shutil.copy2(fname,
|
||||||
|
os.path.join(NAGIOS_PLUGINS, os.path.basename(fname)))
|
||||||
|
|
||||||
|
|
||||||
|
def add_haproxy_checks(nrpe, unit_name):
|
||||||
|
"""
|
||||||
|
Add checks for each service in list
|
||||||
|
|
||||||
|
:param NRPE nrpe: NRPE object to add check to
|
||||||
|
:param str unit_name: Unit name to use in check description
|
||||||
|
"""
|
||||||
|
nrpe.add_check(
|
||||||
|
shortname='haproxy_servers',
|
||||||
|
description='Check HAProxy {%s}' % unit_name,
|
||||||
|
check_cmd='check_haproxy.sh')
|
||||||
|
nrpe.add_check(
|
||||||
|
shortname='haproxy_queue',
|
||||||
|
description='Check HAProxy queue depth {%s}' % unit_name,
|
||||||
|
check_cmd='check_haproxy_queue_depth.sh')
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
'''
|
'''
|
||||||
Functions for managing volumes in juju units. One volume is supported per unit.
|
Functions for managing volumes in juju units. One volume is supported per unit.
|
||||||
Subordinates may have their own storage, provided it is on its own partition.
|
Subordinates may have their own storage, provided it is on its own partition.
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2012 Canonical Ltd.
|
# Copyright 2012 Canonical Ltd.
|
||||||
#
|
#
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2012 Canonical Ltd.
|
# Copyright 2012 Canonical Ltd.
|
||||||
#
|
#
|
||||||
@ -32,6 +48,9 @@ from charmhelpers.core.hookenv import (
|
|||||||
from charmhelpers.core.decorators import (
|
from charmhelpers.core.decorators import (
|
||||||
retry_on_exception,
|
retry_on_exception,
|
||||||
)
|
)
|
||||||
|
from charmhelpers.core.strutils import (
|
||||||
|
bool_from_string,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class HAIncompleteConfig(Exception):
|
class HAIncompleteConfig(Exception):
|
||||||
@ -148,7 +167,8 @@ def https():
|
|||||||
.
|
.
|
||||||
returns: boolean
|
returns: boolean
|
||||||
'''
|
'''
|
||||||
if config_get('use-https') == "yes":
|
use_https = config_get('use-https')
|
||||||
|
if use_https and bool_from_string(use_https):
|
||||||
return True
|
return True
|
||||||
if config_get('ssl_cert') and config_get('ssl_key'):
|
if config_get('ssl_cert') and config_get('ssl_key'):
|
||||||
return True
|
return True
|
||||||
@ -205,19 +225,23 @@ def determine_apache_port(public_port, singlenode_mode=False):
|
|||||||
return public_port - (i * 10)
|
return public_port - (i * 10)
|
||||||
|
|
||||||
|
|
||||||
def get_hacluster_config():
|
def get_hacluster_config(exclude_keys=None):
|
||||||
'''
|
'''
|
||||||
Obtains all relevant configuration from charm configuration required
|
Obtains all relevant configuration from charm configuration required
|
||||||
for initiating a relation to hacluster:
|
for initiating a relation to hacluster:
|
||||||
|
|
||||||
ha-bindiface, ha-mcastport, vip
|
ha-bindiface, ha-mcastport, vip
|
||||||
|
|
||||||
|
param: exclude_keys: list of setting key(s) to be excluded.
|
||||||
returns: dict: A dict containing settings keyed by setting name.
|
returns: dict: A dict containing settings keyed by setting name.
|
||||||
raises: HAIncompleteConfig if settings are missing.
|
raises: HAIncompleteConfig if settings are missing.
|
||||||
'''
|
'''
|
||||||
settings = ['ha-bindiface', 'ha-mcastport', 'vip']
|
settings = ['ha-bindiface', 'ha-mcastport', 'vip']
|
||||||
conf = {}
|
conf = {}
|
||||||
for setting in settings:
|
for setting in settings:
|
||||||
|
if exclude_keys and setting in exclude_keys:
|
||||||
|
continue
|
||||||
|
|
||||||
conf[setting] = config_get(setting)
|
conf[setting] = config_get(setting)
|
||||||
missing = []
|
missing = []
|
||||||
[missing.append(s) for s, v in six.iteritems(conf) if v is None]
|
[missing.append(s) for s, v in six.iteritems(conf) if v is None]
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,13 +1,32 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import glob
|
import glob
|
||||||
import re
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
|
import six
|
||||||
|
import socket
|
||||||
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import unit_get
|
from charmhelpers.core.hookenv import unit_get
|
||||||
from charmhelpers.fetch import apt_install
|
from charmhelpers.fetch import apt_install
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
log
|
log,
|
||||||
|
WARNING,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -349,3 +368,83 @@ def is_bridge_member(nic):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def is_ip(address):
|
||||||
|
"""
|
||||||
|
Returns True if address is a valid IP address.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
# Test to see if already an IPv4 address
|
||||||
|
socket.inet_aton(address)
|
||||||
|
return True
|
||||||
|
except socket.error:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def ns_query(address):
|
||||||
|
try:
|
||||||
|
import dns.resolver
|
||||||
|
except ImportError:
|
||||||
|
apt_install('python-dnspython')
|
||||||
|
import dns.resolver
|
||||||
|
|
||||||
|
if isinstance(address, dns.name.Name):
|
||||||
|
rtype = 'PTR'
|
||||||
|
elif isinstance(address, six.string_types):
|
||||||
|
rtype = 'A'
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
answers = dns.resolver.query(address, rtype)
|
||||||
|
if answers:
|
||||||
|
return str(answers[0])
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_host_ip(hostname, fallback=None):
|
||||||
|
"""
|
||||||
|
Resolves the IP for a given hostname, or returns
|
||||||
|
the input if it is already an IP.
|
||||||
|
"""
|
||||||
|
if is_ip(hostname):
|
||||||
|
return hostname
|
||||||
|
|
||||||
|
ip_addr = ns_query(hostname)
|
||||||
|
if not ip_addr:
|
||||||
|
try:
|
||||||
|
ip_addr = socket.gethostbyname(hostname)
|
||||||
|
except:
|
||||||
|
log("Failed to resolve hostname '%s'" % (hostname),
|
||||||
|
level=WARNING)
|
||||||
|
return fallback
|
||||||
|
return ip_addr
|
||||||
|
|
||||||
|
|
||||||
|
def get_hostname(address, fqdn=True):
|
||||||
|
"""
|
||||||
|
Resolves hostname for given IP, or returns the input
|
||||||
|
if it is already a hostname.
|
||||||
|
"""
|
||||||
|
if is_ip(address):
|
||||||
|
try:
|
||||||
|
import dns.reversename
|
||||||
|
except ImportError:
|
||||||
|
apt_install("python-dnspython")
|
||||||
|
import dns.reversename
|
||||||
|
|
||||||
|
rev = dns.reversename.from_address(address)
|
||||||
|
result = ns_query(rev)
|
||||||
|
if not result:
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
result = address
|
||||||
|
|
||||||
|
if fqdn:
|
||||||
|
# strip trailing .
|
||||||
|
if result.endswith('.'):
|
||||||
|
return result[:-1]
|
||||||
|
else:
|
||||||
|
return result
|
||||||
|
else:
|
||||||
|
return result.split('.')[0]
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
''' Helper for managing alternatives for file conflict resolution '''
|
''' Helper for managing alternatives for file conflict resolution '''
|
||||||
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from charmhelpers.contrib.amulet.deployment import (
|
from charmhelpers.contrib.amulet.deployment import (
|
||||||
AmuletDeployment
|
AmuletDeployment
|
||||||
@ -55,16 +71,19 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
services.append(this_service)
|
services.append(this_service)
|
||||||
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
|
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
|
||||||
'ceph-osd', 'ceph-radosgw']
|
'ceph-osd', 'ceph-radosgw']
|
||||||
|
# Openstack subordinate charms do not expose an origin option as that
|
||||||
|
# is controlled by the principle
|
||||||
|
ignore = ['neutron-openvswitch']
|
||||||
|
|
||||||
if self.openstack:
|
if self.openstack:
|
||||||
for svc in services:
|
for svc in services:
|
||||||
if svc['name'] not in use_source:
|
if svc['name'] not in use_source + ignore:
|
||||||
config = {'openstack-origin': self.openstack}
|
config = {'openstack-origin': self.openstack}
|
||||||
self.d.configure(svc['name'], config)
|
self.d.configure(svc['name'], config)
|
||||||
|
|
||||||
if self.source:
|
if self.source:
|
||||||
for svc in services:
|
for svc in services:
|
||||||
if svc['name'] in use_source:
|
if svc['name'] in use_source and svc['name'] not in ignore:
|
||||||
config = {'source': self.source}
|
config = {'source': self.source}
|
||||||
self.d.configure(svc['name'], config)
|
self.d.configure(svc['name'], config)
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
@ -5,6 +21,7 @@ from base64 import b64decode
|
|||||||
from subprocess import check_call
|
from subprocess import check_call
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
import yaml
|
||||||
|
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
apt_install,
|
apt_install,
|
||||||
@ -88,9 +105,41 @@ def context_complete(ctxt):
|
|||||||
def config_flags_parser(config_flags):
|
def config_flags_parser(config_flags):
|
||||||
"""Parses config flags string into dict.
|
"""Parses config flags string into dict.
|
||||||
|
|
||||||
|
This parsing method supports a few different formats for the config
|
||||||
|
flag values to be parsed:
|
||||||
|
|
||||||
|
1. A string in the simple format of key=value pairs, with the possibility
|
||||||
|
of specifying multiple key value pairs within the same string. For
|
||||||
|
example, a string in the format of 'key1=value1, key2=value2' will
|
||||||
|
return a dict of:
|
||||||
|
{'key1': 'value1',
|
||||||
|
'key2': 'value2'}.
|
||||||
|
|
||||||
|
2. A string in the above format, but supporting a comma-delimited list
|
||||||
|
of values for the same key. For example, a string in the format of
|
||||||
|
'key1=value1, key2=value3,value4,value5' will return a dict of:
|
||||||
|
{'key1', 'value1',
|
||||||
|
'key2', 'value2,value3,value4'}
|
||||||
|
|
||||||
|
3. A string containing a colon character (:) prior to an equal
|
||||||
|
character (=) will be treated as yaml and parsed as such. This can be
|
||||||
|
used to specify more complex key value pairs. For example,
|
||||||
|
a string in the format of 'key1: subkey1=value1, subkey2=value2' will
|
||||||
|
return a dict of:
|
||||||
|
{'key1', 'subkey1=value1, subkey2=value2'}
|
||||||
|
|
||||||
The provided config_flags string may be a list of comma-separated values
|
The provided config_flags string may be a list of comma-separated values
|
||||||
which themselves may be comma-separated list of values.
|
which themselves may be comma-separated list of values.
|
||||||
"""
|
"""
|
||||||
|
# If we find a colon before an equals sign then treat it as yaml.
|
||||||
|
# Note: limit it to finding the colon first since this indicates assignment
|
||||||
|
# for inline yaml.
|
||||||
|
colon = config_flags.find(':')
|
||||||
|
equals = config_flags.find('=')
|
||||||
|
if colon > 0:
|
||||||
|
if colon < equals or equals < 0:
|
||||||
|
return yaml.safe_load(config_flags)
|
||||||
|
|
||||||
if config_flags.find('==') >= 0:
|
if config_flags.find('==') >= 0:
|
||||||
log("config_flags is not in expected format (key=value)", level=ERROR)
|
log("config_flags is not in expected format (key=value)", level=ERROR)
|
||||||
raise OSContextError
|
raise OSContextError
|
||||||
@ -175,7 +224,7 @@ class SharedDBContext(OSContextGenerator):
|
|||||||
unit=local_unit())
|
unit=local_unit())
|
||||||
if set_hostname != access_hostname:
|
if set_hostname != access_hostname:
|
||||||
relation_set(relation_settings={hostname_key: access_hostname})
|
relation_set(relation_settings={hostname_key: access_hostname})
|
||||||
return ctxt # Defer any further hook execution for now....
|
return None # Defer any further hook execution for now....
|
||||||
|
|
||||||
password_setting = 'password'
|
password_setting = 'password'
|
||||||
if self.relation_prefix:
|
if self.relation_prefix:
|
||||||
@ -263,9 +312,25 @@ def db_ssl(rdata, ctxt, ssl_dir):
|
|||||||
class IdentityServiceContext(OSContextGenerator):
|
class IdentityServiceContext(OSContextGenerator):
|
||||||
interfaces = ['identity-service']
|
interfaces = ['identity-service']
|
||||||
|
|
||||||
|
def __init__(self, service=None, service_user=None):
|
||||||
|
self.service = service
|
||||||
|
self.service_user = service_user
|
||||||
|
|
||||||
def __call__(self):
|
def __call__(self):
|
||||||
log('Generating template context for identity-service', level=DEBUG)
|
log('Generating template context for identity-service', level=DEBUG)
|
||||||
ctxt = {}
|
ctxt = {}
|
||||||
|
|
||||||
|
if self.service and self.service_user:
|
||||||
|
# This is required for pki token signing if we don't want /tmp to
|
||||||
|
# be used.
|
||||||
|
cachedir = '/var/cache/%s' % (self.service)
|
||||||
|
if not os.path.isdir(cachedir):
|
||||||
|
log("Creating service cache dir %s" % (cachedir), level=DEBUG)
|
||||||
|
mkdir(path=cachedir, owner=self.service_user,
|
||||||
|
group=self.service_user, perms=0o700)
|
||||||
|
|
||||||
|
ctxt['signing_dir'] = cachedir
|
||||||
|
|
||||||
for rid in relation_ids('identity-service'):
|
for rid in relation_ids('identity-service'):
|
||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
rdata = relation_get(rid=rid, unit=unit)
|
rdata = relation_get(rid=rid, unit=unit)
|
||||||
@ -275,15 +340,16 @@ class IdentityServiceContext(OSContextGenerator):
|
|||||||
auth_host = format_ipv6_addr(auth_host) or auth_host
|
auth_host = format_ipv6_addr(auth_host) or auth_host
|
||||||
svc_protocol = rdata.get('service_protocol') or 'http'
|
svc_protocol = rdata.get('service_protocol') or 'http'
|
||||||
auth_protocol = rdata.get('auth_protocol') or 'http'
|
auth_protocol = rdata.get('auth_protocol') or 'http'
|
||||||
ctxt = {'service_port': rdata.get('service_port'),
|
ctxt.update({'service_port': rdata.get('service_port'),
|
||||||
'service_host': serv_host,
|
'service_host': serv_host,
|
||||||
'auth_host': auth_host,
|
'auth_host': auth_host,
|
||||||
'auth_port': rdata.get('auth_port'),
|
'auth_port': rdata.get('auth_port'),
|
||||||
'admin_tenant_name': rdata.get('service_tenant'),
|
'admin_tenant_name': rdata.get('service_tenant'),
|
||||||
'admin_user': rdata.get('service_username'),
|
'admin_user': rdata.get('service_username'),
|
||||||
'admin_password': rdata.get('service_password'),
|
'admin_password': rdata.get('service_password'),
|
||||||
'service_protocol': svc_protocol,
|
'service_protocol': svc_protocol,
|
||||||
'auth_protocol': auth_protocol}
|
'auth_protocol': auth_protocol})
|
||||||
|
|
||||||
if context_complete(ctxt):
|
if context_complete(ctxt):
|
||||||
# NOTE(jamespage) this is required for >= icehouse
|
# NOTE(jamespage) this is required for >= icehouse
|
||||||
# so a missing value just indicates keystone needs
|
# so a missing value just indicates keystone needs
|
||||||
@ -1005,6 +1071,8 @@ class ZeroMQContext(OSContextGenerator):
|
|||||||
for unit in related_units(rid):
|
for unit in related_units(rid):
|
||||||
ctxt['zmq_nonce'] = relation_get('nonce', unit, rid)
|
ctxt['zmq_nonce'] = relation_get('nonce', unit, rid)
|
||||||
ctxt['zmq_host'] = relation_get('host', unit, rid)
|
ctxt['zmq_host'] = relation_get('host', unit, rid)
|
||||||
|
ctxt['zmq_redis_address'] = relation_get(
|
||||||
|
'zmq_redis_address', unit, rid)
|
||||||
|
|
||||||
return ctxt
|
return ctxt
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
config,
|
config,
|
||||||
unit_get,
|
unit_get,
|
||||||
@ -10,6 +26,8 @@ from charmhelpers.contrib.network.ip import (
|
|||||||
)
|
)
|
||||||
from charmhelpers.contrib.hahelpers.cluster import is_clustered
|
from charmhelpers.contrib.hahelpers.cluster import is_clustered
|
||||||
|
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
PUBLIC = 'public'
|
PUBLIC = 'public'
|
||||||
INTERNAL = 'int'
|
INTERNAL = 'int'
|
||||||
ADMIN = 'admin'
|
ADMIN = 'admin'
|
||||||
@ -91,3 +109,38 @@ def resolve_address(endpoint_type=PUBLIC):
|
|||||||
"clustered=%s)" % (net_type, clustered))
|
"clustered=%s)" % (net_type, clustered))
|
||||||
|
|
||||||
return resolved_address
|
return resolved_address
|
||||||
|
|
||||||
|
|
||||||
|
def endpoint_url(configs, url_template, port, endpoint_type=PUBLIC,
|
||||||
|
override=None):
|
||||||
|
"""Returns the correct endpoint URL to advertise to Keystone.
|
||||||
|
|
||||||
|
This method provides the correct endpoint URL which should be advertised to
|
||||||
|
the keystone charm for endpoint creation. This method allows for the url to
|
||||||
|
be overridden to force a keystone endpoint to have specific URL for any of
|
||||||
|
the defined scopes (admin, internal, public).
|
||||||
|
|
||||||
|
:param configs: OSTemplateRenderer config templating object to inspect
|
||||||
|
for a complete https context.
|
||||||
|
:param url_template: str format string for creating the url template. Only
|
||||||
|
two values will be passed - the scheme+hostname
|
||||||
|
returned by the canonical_url and the port.
|
||||||
|
:param endpoint_type: str endpoint type to resolve.
|
||||||
|
:param override: str the name of the config option which overrides the
|
||||||
|
endpoint URL defined by the charm itself. None will
|
||||||
|
disable any overrides (default).
|
||||||
|
"""
|
||||||
|
if override:
|
||||||
|
# Return any user-defined overrides for the keystone endpoint URL.
|
||||||
|
user_value = config(override)
|
||||||
|
if user_value:
|
||||||
|
return user_value.strip()
|
||||||
|
|
||||||
|
return url_template % (canonical_url(configs, endpoint_type), port)
|
||||||
|
|
||||||
|
|
||||||
|
public_endpoint = partial(endpoint_url, endpoint_type=PUBLIC)
|
||||||
|
|
||||||
|
internal_endpoint = partial(endpoint_url, endpoint_type=INTERNAL)
|
||||||
|
|
||||||
|
admin_endpoint = partial(endpoint_url, endpoint_type=ADMIN)
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Various utilies for dealing with Neutron and the renaming from Quantum.
|
# Various utilies for dealing with Neutron and the renaming from Quantum.
|
||||||
|
|
||||||
from subprocess import check_output
|
from subprocess import check_output
|
||||||
|
@ -1,2 +1,18 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# dummy __init__.py to fool syncer into thinking this is a syncable python
|
# dummy __init__.py to fool syncer into thinking this is a syncable python
|
||||||
# module
|
# module
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import six
|
import six
|
||||||
|
@ -1,18 +1,37 @@
|
|||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Common python helper functions used for OpenStack charms.
|
# Common python helper functions used for OpenStack charms.
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
|
import errno
|
||||||
import subprocess
|
import subprocess
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
import socket
|
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
import six
|
import six
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
|
from charmhelpers.contrib.network import ip
|
||||||
|
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
config,
|
config,
|
||||||
log as juju_log,
|
log as juju_log,
|
||||||
@ -87,6 +106,7 @@ SWIFT_CODENAMES = OrderedDict([
|
|||||||
('2.1.0', 'juno'),
|
('2.1.0', 'juno'),
|
||||||
('2.2.0', 'juno'),
|
('2.2.0', 'juno'),
|
||||||
('2.2.1', 'kilo'),
|
('2.2.1', 'kilo'),
|
||||||
|
('2.2.2', 'kilo'),
|
||||||
])
|
])
|
||||||
|
|
||||||
DEFAULT_LOOPBACK_SIZE = '5G'
|
DEFAULT_LOOPBACK_SIZE = '5G'
|
||||||
@ -404,77 +424,10 @@ def clean_storage(block_device):
|
|||||||
else:
|
else:
|
||||||
zap_disk(block_device)
|
zap_disk(block_device)
|
||||||
|
|
||||||
|
is_ip = ip.is_ip
|
||||||
def is_ip(address):
|
ns_query = ip.ns_query
|
||||||
"""
|
get_host_ip = ip.get_host_ip
|
||||||
Returns True if address is a valid IP address.
|
get_hostname = ip.get_hostname
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# Test to see if already an IPv4 address
|
|
||||||
socket.inet_aton(address)
|
|
||||||
return True
|
|
||||||
except socket.error:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
def ns_query(address):
|
|
||||||
try:
|
|
||||||
import dns.resolver
|
|
||||||
except ImportError:
|
|
||||||
apt_install('python-dnspython')
|
|
||||||
import dns.resolver
|
|
||||||
|
|
||||||
if isinstance(address, dns.name.Name):
|
|
||||||
rtype = 'PTR'
|
|
||||||
elif isinstance(address, six.string_types):
|
|
||||||
rtype = 'A'
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
answers = dns.resolver.query(address, rtype)
|
|
||||||
if answers:
|
|
||||||
return str(answers[0])
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def get_host_ip(hostname):
|
|
||||||
"""
|
|
||||||
Resolves the IP for a given hostname, or returns
|
|
||||||
the input if it is already an IP.
|
|
||||||
"""
|
|
||||||
if is_ip(hostname):
|
|
||||||
return hostname
|
|
||||||
|
|
||||||
return ns_query(hostname)
|
|
||||||
|
|
||||||
|
|
||||||
def get_hostname(address, fqdn=True):
|
|
||||||
"""
|
|
||||||
Resolves hostname for given IP, or returns the input
|
|
||||||
if it is already a hostname.
|
|
||||||
"""
|
|
||||||
if is_ip(address):
|
|
||||||
try:
|
|
||||||
import dns.reversename
|
|
||||||
except ImportError:
|
|
||||||
apt_install('python-dnspython')
|
|
||||||
import dns.reversename
|
|
||||||
|
|
||||||
rev = dns.reversename.from_address(address)
|
|
||||||
result = ns_query(rev)
|
|
||||||
if not result:
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
result = address
|
|
||||||
|
|
||||||
if fqdn:
|
|
||||||
# strip trailing .
|
|
||||||
if result.endswith('.'):
|
|
||||||
return result[:-1]
|
|
||||||
else:
|
|
||||||
return result
|
|
||||||
else:
|
|
||||||
return result.split('.')[0]
|
|
||||||
|
|
||||||
|
|
||||||
def get_matchmaker_map(mm_file='/etc/oslo/matchmaker_ring.json'):
|
def get_matchmaker_map(mm_file='/etc/oslo/matchmaker_ring.json'):
|
||||||
@ -519,89 +472,115 @@ def os_requires_version(ostack_release, pkg):
|
|||||||
|
|
||||||
def git_install_requested():
|
def git_install_requested():
|
||||||
"""Returns true if openstack-origin-git is specified."""
|
"""Returns true if openstack-origin-git is specified."""
|
||||||
return config('openstack-origin-git') != "None"
|
return config('openstack-origin-git') != None
|
||||||
|
|
||||||
|
|
||||||
requirements_dir = None
|
requirements_dir = None
|
||||||
|
|
||||||
|
|
||||||
def git_clone_and_install(file_name, core_project):
|
def git_clone_and_install(projects, core_project,
|
||||||
"""Clone/install all OpenStack repos specified in yaml config file."""
|
parent_dir='/mnt/openstack-git'):
|
||||||
|
"""Clone/install all OpenStack repos specified in projects dictionary."""
|
||||||
global requirements_dir
|
global requirements_dir
|
||||||
|
update_reqs = True
|
||||||
|
|
||||||
if file_name == "None":
|
if not projects:
|
||||||
return
|
return
|
||||||
|
|
||||||
yaml_file = os.path.join(charm_dir(), file_name)
|
|
||||||
|
|
||||||
# clone/install the requirements project first
|
# clone/install the requirements project first
|
||||||
installed = _git_clone_and_install_subset(yaml_file,
|
installed = _git_clone_and_install_subset(projects, parent_dir,
|
||||||
whitelist=['requirements'])
|
whitelist=['requirements'])
|
||||||
if 'requirements' not in installed:
|
if 'requirements' not in installed:
|
||||||
error_out('requirements git repository must be specified')
|
update_reqs = False
|
||||||
|
|
||||||
# clone/install all other projects except requirements and the core project
|
# clone/install all other projects except requirements and the core project
|
||||||
blacklist = ['requirements', core_project]
|
blacklist = ['requirements', core_project]
|
||||||
_git_clone_and_install_subset(yaml_file, blacklist=blacklist,
|
_git_clone_and_install_subset(projects, parent_dir, blacklist=blacklist,
|
||||||
update_requirements=True)
|
update_requirements=update_reqs)
|
||||||
|
|
||||||
# clone/install the core project
|
# clone/install the core project
|
||||||
whitelist = [core_project]
|
whitelist = [core_project]
|
||||||
installed = _git_clone_and_install_subset(yaml_file, whitelist=whitelist,
|
installed = _git_clone_and_install_subset(projects, parent_dir,
|
||||||
update_requirements=True)
|
whitelist=whitelist,
|
||||||
|
update_requirements=update_reqs)
|
||||||
if core_project not in installed:
|
if core_project not in installed:
|
||||||
error_out('{} git repository must be specified'.format(core_project))
|
error_out('{} git repository must be specified'.format(core_project))
|
||||||
|
|
||||||
|
|
||||||
def _git_clone_and_install_subset(yaml_file, whitelist=[], blacklist=[],
|
def _git_clone_and_install_subset(projects, parent_dir, whitelist=[],
|
||||||
update_requirements=False):
|
blacklist=[], update_requirements=False):
|
||||||
"""Clone/install subset of OpenStack repos specified in yaml config file."""
|
"""Clone/install subset of OpenStack repos specified in projects dict."""
|
||||||
global requirements_dir
|
global requirements_dir
|
||||||
installed = []
|
installed = []
|
||||||
|
|
||||||
with open(yaml_file, 'r') as fd:
|
for proj, val in projects.items():
|
||||||
projects = yaml.load(fd)
|
# The project subset is chosen based on the following 3 rules:
|
||||||
for proj, val in projects.items():
|
# 1) If project is in blacklist, we don't clone/install it, period.
|
||||||
# The project subset is chosen based on the following 3 rules:
|
# 2) If whitelist is empty, we clone/install everything else.
|
||||||
# 1) If project is in blacklist, we don't clone/install it, period.
|
# 3) If whitelist is not empty, we clone/install everything in the
|
||||||
# 2) If whitelist is empty, we clone/install everything else.
|
# whitelist.
|
||||||
# 3) If whitelist is not empty, we clone/install everything in the
|
if proj in blacklist:
|
||||||
# whitelist.
|
continue
|
||||||
if proj in blacklist:
|
if whitelist and proj not in whitelist:
|
||||||
continue
|
continue
|
||||||
if whitelist and proj not in whitelist:
|
repo = val['repository']
|
||||||
continue
|
branch = val['branch']
|
||||||
repo = val['repository']
|
repo_dir = _git_clone_and_install_single(repo, branch, parent_dir,
|
||||||
branch = val['branch']
|
update_requirements)
|
||||||
repo_dir = _git_clone_and_install_single(repo, branch,
|
if proj == 'requirements':
|
||||||
update_requirements)
|
requirements_dir = repo_dir
|
||||||
if proj == 'requirements':
|
installed.append(proj)
|
||||||
requirements_dir = repo_dir
|
|
||||||
installed.append(proj)
|
|
||||||
return installed
|
return installed
|
||||||
|
|
||||||
|
|
||||||
def _git_clone_and_install_single(repo, branch, update_requirements=False):
|
def _git_clone_and_install_single(repo, branch, parent_dir,
|
||||||
|
update_requirements=False):
|
||||||
"""Clone and install a single git repository."""
|
"""Clone and install a single git repository."""
|
||||||
dest_parent_dir = "/mnt/openstack-git/"
|
dest_dir = os.path.join(parent_dir, os.path.basename(repo))
|
||||||
dest_dir = os.path.join(dest_parent_dir, os.path.basename(repo))
|
lock_dir = os.path.join(parent_dir, os.path.basename(repo) + '.lock')
|
||||||
|
|
||||||
if not os.path.exists(dest_parent_dir):
|
# Note(coreycb): The parent directory for storing git repositories can be
|
||||||
juju_log('Host dir not mounted at {}. '
|
# shared by multiple charms via bind mount, etc, so we use exception
|
||||||
'Creating directory there instead.'.format(dest_parent_dir))
|
# handling to ensure the test for existence and mkdir are atomic.
|
||||||
os.mkdir(dest_parent_dir)
|
try:
|
||||||
|
os.mkdir(parent_dir)
|
||||||
if not os.path.exists(dest_dir):
|
except OSError as e:
|
||||||
juju_log('Cloning git repo: {}, branch: {}'.format(repo, branch))
|
if e.errno == errno.EEXIST:
|
||||||
repo_dir = install_remote(repo, dest=dest_parent_dir, branch=branch)
|
juju_log('Directory already exists at {}. '
|
||||||
|
'No need to create directory.'.format(parent_dir))
|
||||||
|
pass
|
||||||
else:
|
else:
|
||||||
repo_dir = dest_dir
|
juju_log('Host directory not mounted at {}. '
|
||||||
|
'Directory created.'.format(parent_dir))
|
||||||
|
|
||||||
if update_requirements:
|
# Note(coreycb): Similar to above, the cloned git repositories can be shared
|
||||||
if not requirements_dir:
|
# by multiple charms via bind mount, etc, so we use exception handling and
|
||||||
error_out('requirements repo must be cloned before '
|
# special lock directories to ensure that a repository clone is only
|
||||||
'updating from global requirements.')
|
# attempted once.
|
||||||
_git_update_requirements(repo_dir, requirements_dir)
|
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)
|
||||||
|
|
||||||
juju_log('Installing git repo from dir: {}'.format(repo_dir))
|
juju_log('Installing git repo from dir: {}'.format(repo_dir))
|
||||||
pip_install(repo_dir)
|
pip_install(repo_dir)
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from charmhelpers.core.hookenv import relation_id as current_relation_id
|
from charmhelpers.core.hookenv import relation_id as current_relation_id
|
||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,7 +1,21 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# coding: utf-8
|
# coding: utf-8
|
||||||
|
|
||||||
__author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from charmhelpers.fetch import apt_install, apt_update
|
from charmhelpers.fetch import apt_install, apt_update
|
||||||
from charmhelpers.core.hookenv import log
|
from charmhelpers.core.hookenv import log
|
||||||
@ -13,6 +27,8 @@ except ImportError:
|
|||||||
apt_install('python-pip')
|
apt_install('python-pip')
|
||||||
from pip import main as pip_execute
|
from pip import main as pip_execute
|
||||||
|
|
||||||
|
__author__ = "Jorge Niedbalski <jorge.niedbalski@canonical.com>"
|
||||||
|
|
||||||
|
|
||||||
def parse_options(given, available):
|
def parse_options(given, available):
|
||||||
"""Given a set of options, check if available"""
|
"""Given a set of options, check if available"""
|
||||||
@ -35,7 +51,7 @@ def pip_install_requirements(requirements, **options):
|
|||||||
pip_execute(command)
|
pip_execute(command)
|
||||||
|
|
||||||
|
|
||||||
def pip_install(package, fatal=False, **options):
|
def pip_install(package, fatal=False, upgrade=False, **options):
|
||||||
"""Install a python package"""
|
"""Install a python package"""
|
||||||
command = ["install"]
|
command = ["install"]
|
||||||
|
|
||||||
@ -43,6 +59,9 @@ def pip_install(package, fatal=False, **options):
|
|||||||
for option in parse_options(options, available_options):
|
for option in parse_options(options, available_options):
|
||||||
command.append(option)
|
command.append(option)
|
||||||
|
|
||||||
|
if upgrade:
|
||||||
|
command.append('--upgrade')
|
||||||
|
|
||||||
if isinstance(package, list):
|
if isinstance(package, list):
|
||||||
command.extend(package)
|
command.extend(package)
|
||||||
else:
|
else:
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2012 Canonical Ltd.
|
# Copyright 2012 Canonical Ltd.
|
||||||
#
|
#
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from subprocess import (
|
from subprocess import (
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from subprocess import (
|
from subprocess import (
|
||||||
CalledProcessError,
|
CalledProcessError,
|
||||||
check_call,
|
check_call,
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from stat import S_ISBLK
|
from stat import S_ISBLK
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Easy file synchronization among peer units using ssh + unison.
|
# Easy file synchronization among peer units using ssh + unison.
|
||||||
#
|
#
|
||||||
# From *both* peer relation -joined and -changed, add a call to
|
# From *both* peer relation -joined and -changed, add a call to
|
||||||
@ -57,6 +73,7 @@ from charmhelpers.core.hookenv import (
|
|||||||
relation_set,
|
relation_set,
|
||||||
relation_get,
|
relation_get,
|
||||||
unit_private_ip,
|
unit_private_ip,
|
||||||
|
INFO,
|
||||||
ERROR,
|
ERROR,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -70,7 +87,7 @@ def get_homedir(user):
|
|||||||
user = pwd.getpwnam(user)
|
user = pwd.getpwnam(user)
|
||||||
return user.pw_dir
|
return user.pw_dir
|
||||||
except KeyError:
|
except KeyError:
|
||||||
log('Could not get homedir for user %s: user exists?', ERROR)
|
log('Could not get homedir for user %s: user exists?' % (user), ERROR)
|
||||||
raise Exception
|
raise Exception
|
||||||
|
|
||||||
|
|
||||||
@ -217,14 +234,15 @@ def collect_authed_hosts(peer_interface):
|
|||||||
rid=r_id, unit=unit)
|
rid=r_id, unit=unit)
|
||||||
|
|
||||||
if not authed_hosts:
|
if not authed_hosts:
|
||||||
log('Peer %s has not authorized *any* hosts yet, skipping.')
|
log('Peer %s has not authorized *any* hosts yet, skipping.' %
|
||||||
|
(unit), level=INFO)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if unit_private_ip() in authed_hosts.split(':'):
|
if unit_private_ip() in authed_hosts.split(':'):
|
||||||
hosts.append(private_addr)
|
hosts.append(private_addr)
|
||||||
else:
|
else:
|
||||||
log('Peer %s has not authorized *this* host yet, skipping.')
|
log('Peer %s has not authorized *this* host yet, skipping.' %
|
||||||
|
(unit), level=INFO)
|
||||||
return hosts
|
return hosts
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#
|
#
|
||||||
# Copyright 2014 Canonical Ltd.
|
# Copyright 2014 Canonical Ltd.
|
||||||
#
|
#
|
||||||
|
@ -1,11 +1,27 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__author__ = 'Jorge Niedbalski R. <jorge.niedbalski@canonical.com>'
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
__author__ = 'Jorge Niedbalski R. <jorge.niedbalski@canonical.com>'
|
||||||
|
|
||||||
|
|
||||||
class Fstab(io.FileIO):
|
class Fstab(io.FileIO):
|
||||||
"""This class extends file in order to implement a file reader/writer
|
"""This class extends file in order to implement a file reader/writer
|
||||||
@ -61,7 +77,7 @@ class Fstab(io.FileIO):
|
|||||||
for line in self.readlines():
|
for line in self.readlines():
|
||||||
line = line.decode('us-ascii')
|
line = line.decode('us-ascii')
|
||||||
try:
|
try:
|
||||||
if line.strip() and not line.startswith("#"):
|
if line.strip() and not line.strip().startswith("#"):
|
||||||
yield self._hydrate_entry(line)
|
yield self._hydrate_entry(line)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
@ -88,7 +104,7 @@ class Fstab(io.FileIO):
|
|||||||
|
|
||||||
found = False
|
found = False
|
||||||
for index, line in enumerate(lines):
|
for index, line in enumerate(lines):
|
||||||
if not line.startswith("#"):
|
if line.strip() and not line.strip().startswith("#"):
|
||||||
if self._hydrate_entry(line) == entry:
|
if self._hydrate_entry(line) == entry:
|
||||||
found = True
|
found = True
|
||||||
break
|
break
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"Interactions with the Juju environment"
|
"Interactions with the Juju environment"
|
||||||
# Copyright 2013 Canonical Ltd.
|
# Copyright 2013 Canonical Ltd.
|
||||||
#
|
#
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"""Tools for working with the host system"""
|
"""Tools for working with the host system"""
|
||||||
# Copyright 2012 Canonical Ltd.
|
# Copyright 2012 Canonical Ltd.
|
||||||
#
|
#
|
||||||
@ -168,18 +184,18 @@ def mkdir(path, owner='root', group='root', perms=0o555, force=False):
|
|||||||
log("Removing non-directory file {} prior to mkdir()".format(path))
|
log("Removing non-directory file {} prior to mkdir()".format(path))
|
||||||
os.unlink(realpath)
|
os.unlink(realpath)
|
||||||
os.makedirs(realpath, perms)
|
os.makedirs(realpath, perms)
|
||||||
os.chown(realpath, uid, gid)
|
|
||||||
elif not path_exists:
|
elif not path_exists:
|
||||||
os.makedirs(realpath, perms)
|
os.makedirs(realpath, perms)
|
||||||
os.chown(realpath, uid, gid)
|
os.chown(realpath, uid, gid)
|
||||||
|
os.chmod(realpath, perms)
|
||||||
|
|
||||||
|
|
||||||
def write_file(path, content, owner='root', group='root', perms=0o444):
|
def write_file(path, content, owner='root', group='root', perms=0o444):
|
||||||
"""Create or overwrite a file with the contents of a string"""
|
"""Create or overwrite a file with the contents of a byte string."""
|
||||||
log("Writing file {} {}:{} {:o}".format(path, owner, group, perms))
|
log("Writing file {} {}:{} {:o}".format(path, owner, group, perms))
|
||||||
uid = pwd.getpwnam(owner).pw_uid
|
uid = pwd.getpwnam(owner).pw_uid
|
||||||
gid = grp.getgrnam(group).gr_gid
|
gid = grp.getgrnam(group).gr_gid
|
||||||
with open(path, 'w') as target:
|
with open(path, 'wb') as target:
|
||||||
os.fchown(target.fileno(), uid, gid)
|
os.fchown(target.fileno(), uid, gid)
|
||||||
os.fchmod(target.fileno(), perms)
|
os.fchmod(target.fileno(), perms)
|
||||||
target.write(content)
|
target.write(content)
|
||||||
@ -289,11 +305,11 @@ def restart_on_change(restart_map, stopstart=False):
|
|||||||
ceph_client_changed function.
|
ceph_client_changed function.
|
||||||
"""
|
"""
|
||||||
def wrap(f):
|
def wrap(f):
|
||||||
def wrapped_f(*args):
|
def wrapped_f(*args, **kwargs):
|
||||||
checksums = {}
|
checksums = {}
|
||||||
for path in restart_map:
|
for path in restart_map:
|
||||||
checksums[path] = file_hash(path)
|
checksums[path] = file_hash(path)
|
||||||
f(*args)
|
f(*args, **kwargs)
|
||||||
restarts = []
|
restarts = []
|
||||||
for path in restart_map:
|
for path in restart_map:
|
||||||
if checksums[path] != file_hash(path):
|
if checksums[path] != file_hash(path):
|
||||||
@ -345,7 +361,7 @@ def list_nics(nic_type):
|
|||||||
ip_output = (line for line in ip_output if line)
|
ip_output = (line for line in ip_output if line)
|
||||||
for line in ip_output:
|
for line in ip_output:
|
||||||
if line.split()[1].startswith(int_type):
|
if line.split()[1].startswith(int_type):
|
||||||
matched = re.search('.*: (bond[0-9]+\.[0-9]+)@.*', line)
|
matched = re.search('.*: (' + int_type + r'[0-9]+\.[0-9]+)@.*', line)
|
||||||
if matched:
|
if matched:
|
||||||
interface = matched.groups()[0]
|
interface = matched.groups()[0]
|
||||||
else:
|
else:
|
||||||
@ -389,6 +405,9 @@ def cmp_pkgrevno(package, revno, pkgcache=None):
|
|||||||
* 0 => Installed revno is the same as supplied arg
|
* 0 => Installed revno is the same as supplied arg
|
||||||
* -1 => Installed revno is less than supplied arg
|
* -1 => Installed revno is less than supplied arg
|
||||||
|
|
||||||
|
This function imports apt_cache function from charmhelpers.fetch if
|
||||||
|
the pkgcache argument is None. Be sure to add charmhelpers.fetch if
|
||||||
|
you call this function, or pass an apt_pkg.Cache() instance.
|
||||||
'''
|
'''
|
||||||
import apt_pkg
|
import apt_pkg
|
||||||
if not pkgcache:
|
if not pkgcache:
|
||||||
@ -407,13 +426,21 @@ def chdir(d):
|
|||||||
os.chdir(cur)
|
os.chdir(cur)
|
||||||
|
|
||||||
|
|
||||||
def chownr(path, owner, group):
|
def chownr(path, owner, group, follow_links=True):
|
||||||
uid = pwd.getpwnam(owner).pw_uid
|
uid = pwd.getpwnam(owner).pw_uid
|
||||||
gid = grp.getgrnam(group).gr_gid
|
gid = grp.getgrnam(group).gr_gid
|
||||||
|
if follow_links:
|
||||||
|
chown = os.chown
|
||||||
|
else:
|
||||||
|
chown = os.lchown
|
||||||
|
|
||||||
for root, dirs, files in os.walk(path):
|
for root, dirs, files in os.walk(path):
|
||||||
for name in dirs + files:
|
for name in dirs + files:
|
||||||
full = os.path.join(root, name)
|
full = os.path.join(root, name)
|
||||||
broken_symlink = os.path.lexists(full) and not os.path.exists(full)
|
broken_symlink = os.path.lexists(full) and not os.path.exists(full)
|
||||||
if not broken_symlink:
|
if not broken_symlink:
|
||||||
os.chown(full, uid, gid)
|
chown(full, uid, gid)
|
||||||
|
|
||||||
|
|
||||||
|
def lchownr(path, owner, group):
|
||||||
|
chownr(path, owner, group, follow_links=False)
|
||||||
|
@ -1,2 +1,18 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from .base import * # NOQA
|
from .base import * # NOQA
|
||||||
from .helpers import * # NOQA
|
from .helpers import * # NOQA
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import json
|
import json
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import yaml
|
import yaml
|
||||||
from charmhelpers.core import hookenv
|
from charmhelpers.core import hookenv
|
||||||
@ -29,12 +45,14 @@ class RelationContext(dict):
|
|||||||
"""
|
"""
|
||||||
name = None
|
name = None
|
||||||
interface = None
|
interface = None
|
||||||
required_keys = []
|
|
||||||
|
|
||||||
def __init__(self, name=None, additional_required_keys=None):
|
def __init__(self, name=None, additional_required_keys=None):
|
||||||
|
if not hasattr(self, 'required_keys'):
|
||||||
|
self.required_keys = []
|
||||||
|
|
||||||
if name is not None:
|
if name is not None:
|
||||||
self.name = name
|
self.name = name
|
||||||
if additional_required_keys is not None:
|
if additional_required_keys:
|
||||||
self.required_keys.extend(additional_required_keys)
|
self.required_keys.extend(additional_required_keys)
|
||||||
self.get_data()
|
self.get_data()
|
||||||
|
|
||||||
@ -118,7 +136,10 @@ class MysqlRelation(RelationContext):
|
|||||||
"""
|
"""
|
||||||
name = 'db'
|
name = 'db'
|
||||||
interface = 'mysql'
|
interface = 'mysql'
|
||||||
required_keys = ['host', 'user', 'password', 'database']
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.required_keys = ['host', 'user', 'password', 'database']
|
||||||
|
super(HttpRelation).__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class HttpRelation(RelationContext):
|
class HttpRelation(RelationContext):
|
||||||
@ -130,7 +151,10 @@ class HttpRelation(RelationContext):
|
|||||||
"""
|
"""
|
||||||
name = 'website'
|
name = 'website'
|
||||||
interface = 'http'
|
interface = 'http'
|
||||||
required_keys = ['host', 'port']
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.required_keys = ['host', 'port']
|
||||||
|
super(HttpRelation).__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
def provide_data(self):
|
def provide_data(self):
|
||||||
return {
|
return {
|
||||||
|
@ -1,7 +1,21 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
__author__ = 'Jorge Niedbalski R. <jorge.niedbalski@canonical.com>'
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
@ -10,25 +24,33 @@ from subprocess import check_call
|
|||||||
from charmhelpers.core.hookenv import (
|
from charmhelpers.core.hookenv import (
|
||||||
log,
|
log,
|
||||||
DEBUG,
|
DEBUG,
|
||||||
|
ERROR,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
__author__ = 'Jorge Niedbalski R. <jorge.niedbalski@canonical.com>'
|
||||||
|
|
||||||
|
|
||||||
def create(sysctl_dict, sysctl_file):
|
def create(sysctl_dict, sysctl_file):
|
||||||
"""Creates a sysctl.conf file from a YAML associative array
|
"""Creates a sysctl.conf file from a YAML associative array
|
||||||
|
|
||||||
:param sysctl_dict: a dict of sysctl options eg { 'kernel.max_pid': 1337 }
|
:param sysctl_dict: a YAML-formatted string of sysctl options eg "{ 'kernel.max_pid': 1337 }"
|
||||||
:type sysctl_dict: dict
|
:type sysctl_dict: str
|
||||||
:param sysctl_file: path to the sysctl file to be saved
|
:param sysctl_file: path to the sysctl file to be saved
|
||||||
:type sysctl_file: str or unicode
|
:type sysctl_file: str or unicode
|
||||||
:returns: None
|
:returns: None
|
||||||
"""
|
"""
|
||||||
sysctl_dict = yaml.load(sysctl_dict)
|
try:
|
||||||
|
sysctl_dict_parsed = yaml.safe_load(sysctl_dict)
|
||||||
|
except yaml.YAMLError:
|
||||||
|
log("Error parsing YAML sysctl_dict: {}".format(sysctl_dict),
|
||||||
|
level=ERROR)
|
||||||
|
return
|
||||||
|
|
||||||
with open(sysctl_file, "w") as fd:
|
with open(sysctl_file, "w") as fd:
|
||||||
for key, value in sysctl_dict.items():
|
for key, value in sysctl_dict_parsed.items():
|
||||||
fd.write("{}={}\n".format(key, value))
|
fd.write("{}={}\n".format(key, value))
|
||||||
|
|
||||||
log("Updating sysctl_file: %s values: %s" % (sysctl_file, sysctl_dict),
|
log("Updating sysctl_file: %s values: %s" % (sysctl_file, sysctl_dict_parsed),
|
||||||
level=DEBUG)
|
level=DEBUG)
|
||||||
|
|
||||||
check_call(["sysctl", "-p", sysctl_file])
|
check_call(["sysctl", "-p", sysctl_file])
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
from charmhelpers.core import host
|
from charmhelpers.core import host
|
||||||
@ -5,7 +21,7 @@ from charmhelpers.core import hookenv
|
|||||||
|
|
||||||
|
|
||||||
def render(source, target, context, owner='root', group='root',
|
def render(source, target, context, owner='root', group='root',
|
||||||
perms=0o444, templates_dir=None):
|
perms=0o444, templates_dir=None, encoding='UTF-8'):
|
||||||
"""
|
"""
|
||||||
Render a template.
|
Render a template.
|
||||||
|
|
||||||
@ -48,5 +64,5 @@ def render(source, target, context, owner='root', group='root',
|
|||||||
level=hookenv.ERROR)
|
level=hookenv.ERROR)
|
||||||
raise e
|
raise e
|
||||||
content = template.render(context)
|
content = template.render(context)
|
||||||
host.mkdir(os.path.dirname(target), owner, group)
|
host.mkdir(os.path.dirname(target), owner, group, perms=0o755)
|
||||||
host.write_file(target, content, owner, group, perms)
|
host.write_file(target, content.encode(encoding), owner, group, perms)
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
import time
|
import time
|
||||||
|
@ -1,7 +1,33 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import hashlib
|
import hashlib
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
from charmhelpers.fetch import (
|
||||||
|
BaseFetchHandler,
|
||||||
|
UnhandledSource
|
||||||
|
)
|
||||||
|
from charmhelpers.payload.archive import (
|
||||||
|
get_archive_handler,
|
||||||
|
extract,
|
||||||
|
)
|
||||||
|
from charmhelpers.core.host import mkdir, check_hash
|
||||||
|
|
||||||
import six
|
import six
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
from urllib.request import (
|
from urllib.request import (
|
||||||
@ -19,16 +45,6 @@ else:
|
|||||||
)
|
)
|
||||||
from urlparse import urlparse, urlunparse, parse_qs
|
from urlparse import urlparse, urlunparse, parse_qs
|
||||||
|
|
||||||
from charmhelpers.fetch import (
|
|
||||||
BaseFetchHandler,
|
|
||||||
UnhandledSource
|
|
||||||
)
|
|
||||||
from charmhelpers.payload.archive import (
|
|
||||||
get_archive_handler,
|
|
||||||
extract,
|
|
||||||
)
|
|
||||||
from charmhelpers.core.host import mkdir, check_hash
|
|
||||||
|
|
||||||
|
|
||||||
def splituser(host):
|
def splituser(host):
|
||||||
'''urllib.splituser(), but six's support of this seems broken'''
|
'''urllib.splituser(), but six's support of this seems broken'''
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
BaseFetchHandler,
|
BaseFetchHandler,
|
||||||
@ -11,10 +27,12 @@ if six.PY3:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
from bzrlib.branch import Branch
|
from bzrlib.branch import Branch
|
||||||
|
from bzrlib import bzrdir, workingtree, errors
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from charmhelpers.fetch import apt_install
|
from charmhelpers.fetch import apt_install
|
||||||
apt_install("python-bzrlib")
|
apt_install("python-bzrlib")
|
||||||
from bzrlib.branch import Branch
|
from bzrlib.branch import Branch
|
||||||
|
from bzrlib import bzrdir, workingtree, errors
|
||||||
|
|
||||||
|
|
||||||
class BzrUrlFetchHandler(BaseFetchHandler):
|
class BzrUrlFetchHandler(BaseFetchHandler):
|
||||||
@ -34,9 +52,15 @@ class BzrUrlFetchHandler(BaseFetchHandler):
|
|||||||
if url_parts.scheme == "lp":
|
if url_parts.scheme == "lp":
|
||||||
from bzrlib.plugin import load_plugins
|
from bzrlib.plugin import load_plugins
|
||||||
load_plugins()
|
load_plugins()
|
||||||
|
try:
|
||||||
|
local_branch = bzrdir.BzrDir.create_branch_convenience(dest)
|
||||||
|
except errors.AlreadyControlDirError:
|
||||||
|
local_branch = Branch.open(dest)
|
||||||
try:
|
try:
|
||||||
remote_branch = Branch.open(source)
|
remote_branch = Branch.open(source)
|
||||||
remote_branch.bzrdir.sprout(dest).open_branch()
|
remote_branch.push(local_branch)
|
||||||
|
tree = workingtree.WorkingTree.open(dest)
|
||||||
|
tree.update()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
BaseFetchHandler,
|
BaseFetchHandler,
|
||||||
@ -16,6 +32,8 @@ except ImportError:
|
|||||||
apt_install("python-git")
|
apt_install("python-git")
|
||||||
from git import Repo
|
from git import Repo
|
||||||
|
|
||||||
|
from git.exc import GitCommandError # noqa E402
|
||||||
|
|
||||||
|
|
||||||
class GitUrlFetchHandler(BaseFetchHandler):
|
class GitUrlFetchHandler(BaseFetchHandler):
|
||||||
"""Handler for git branches via generic and github URLs"""
|
"""Handler for git branches via generic and github URLs"""
|
||||||
@ -46,6 +64,8 @@ class GitUrlFetchHandler(BaseFetchHandler):
|
|||||||
mkdir(dest_dir, perms=0o755)
|
mkdir(dest_dir, perms=0o755)
|
||||||
try:
|
try:
|
||||||
self.clone(source, dest_dir, branch)
|
self.clone(source, dest_dir, branch)
|
||||||
|
except GitCommandError as e:
|
||||||
|
raise UnhandledSource(e.message)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise UnhandledSource(e.strerror)
|
raise UnhandledSource(e.strerror)
|
||||||
return dest_dir
|
return dest_dir
|
||||||
|
@ -1 +1,17 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
"Tools for working with files injected into a charm just before deployment."
|
"Tools for working with files injected into a charm just before deployment."
|
||||||
|
@ -1,5 +1,21 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
# Bootstrap charm-helpers, installing its dependencies if necessary using
|
# Bootstrap charm-helpers, installing its dependencies if necessary using
|
||||||
# only standard libraries.
|
# only standard libraries.
|
||||||
import subprocess
|
import subprocess
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import amulet
|
import amulet
|
||||||
import os
|
import os
|
||||||
import six
|
import six
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import ConfigParser
|
import ConfigParser
|
||||||
import io
|
import io
|
||||||
import logging
|
import logging
|
||||||
@ -153,8 +169,13 @@ class AmuletUtils(object):
|
|||||||
cmd = 'pgrep -o -f {}'.format(service)
|
cmd = 'pgrep -o -f {}'.format(service)
|
||||||
else:
|
else:
|
||||||
cmd = 'pgrep -o {}'.format(service)
|
cmd = 'pgrep -o {}'.format(service)
|
||||||
proc_dir = '/proc/{}'.format(sentry_unit.run(cmd)[0].strip())
|
cmd = cmd + ' | grep -v pgrep || exit 0'
|
||||||
return self._get_dir_mtime(sentry_unit, proc_dir)
|
cmd_out = sentry_unit.run(cmd)
|
||||||
|
self.log.debug('CMDout: ' + str(cmd_out))
|
||||||
|
if cmd_out[0]:
|
||||||
|
self.log.debug('Pid for %s %s' % (service, str(cmd_out[0])))
|
||||||
|
proc_dir = '/proc/{}'.format(cmd_out[0].strip())
|
||||||
|
return self._get_dir_mtime(sentry_unit, proc_dir)
|
||||||
|
|
||||||
def service_restarted(self, sentry_unit, service, filename,
|
def service_restarted(self, sentry_unit, service, filename,
|
||||||
pgrep_full=False, sleep_time=20):
|
pgrep_full=False, sleep_time=20):
|
||||||
@ -171,6 +192,121 @@ class AmuletUtils(object):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def service_restarted_since(self, sentry_unit, mtime, service,
|
||||||
|
pgrep_full=False, sleep_time=20,
|
||||||
|
retry_count=2):
|
||||||
|
"""Check if service was been started after a given time.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sentry_unit (sentry): The sentry unit to check for the service on
|
||||||
|
mtime (float): The epoch time to check against
|
||||||
|
service (string): service name to look for in process table
|
||||||
|
pgrep_full (boolean): Use full command line search mode with pgrep
|
||||||
|
sleep_time (int): Seconds to sleep before looking for process
|
||||||
|
retry_count (int): If service is not found, how many times to retry
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if service found and its start time it newer than mtime,
|
||||||
|
False if service is older than mtime or if service was
|
||||||
|
not found.
|
||||||
|
"""
|
||||||
|
self.log.debug('Checking %s restarted since %s' % (service, mtime))
|
||||||
|
time.sleep(sleep_time)
|
||||||
|
proc_start_time = self._get_proc_start_time(sentry_unit, service,
|
||||||
|
pgrep_full)
|
||||||
|
while retry_count > 0 and not proc_start_time:
|
||||||
|
self.log.debug('No pid file found for service %s, will retry %i '
|
||||||
|
'more times' % (service, retry_count))
|
||||||
|
time.sleep(30)
|
||||||
|
proc_start_time = self._get_proc_start_time(sentry_unit, service,
|
||||||
|
pgrep_full)
|
||||||
|
retry_count = retry_count - 1
|
||||||
|
|
||||||
|
if not proc_start_time:
|
||||||
|
self.log.warn('No proc start time found, assuming service did '
|
||||||
|
'not start')
|
||||||
|
return False
|
||||||
|
if proc_start_time >= mtime:
|
||||||
|
self.log.debug('proc start time is newer than provided mtime'
|
||||||
|
'(%s >= %s)' % (proc_start_time, mtime))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.log.warn('proc start time (%s) is older than provided mtime '
|
||||||
|
'(%s), service did not restart' % (proc_start_time,
|
||||||
|
mtime))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def config_updated_since(self, sentry_unit, filename, mtime,
|
||||||
|
sleep_time=20):
|
||||||
|
"""Check if file was modified after a given time.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sentry_unit (sentry): The sentry unit to check the file mtime on
|
||||||
|
filename (string): The file to check mtime of
|
||||||
|
mtime (float): The epoch time to check against
|
||||||
|
sleep_time (int): Seconds to sleep before looking for process
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if file was modified more recently than mtime, False if
|
||||||
|
file was modified before mtime,
|
||||||
|
"""
|
||||||
|
self.log.debug('Checking %s updated since %s' % (filename, mtime))
|
||||||
|
time.sleep(sleep_time)
|
||||||
|
file_mtime = self._get_file_mtime(sentry_unit, filename)
|
||||||
|
if file_mtime >= mtime:
|
||||||
|
self.log.debug('File mtime is newer than provided mtime '
|
||||||
|
'(%s >= %s)' % (file_mtime, mtime))
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.log.warn('File mtime %s is older than provided mtime %s'
|
||||||
|
% (file_mtime, mtime))
|
||||||
|
return False
|
||||||
|
|
||||||
|
def validate_service_config_changed(self, sentry_unit, mtime, service,
|
||||||
|
filename, pgrep_full=False,
|
||||||
|
sleep_time=20, retry_count=2):
|
||||||
|
"""Check service and file were updated after mtime
|
||||||
|
|
||||||
|
Args:
|
||||||
|
sentry_unit (sentry): The sentry unit to check for the service on
|
||||||
|
mtime (float): The epoch time to check against
|
||||||
|
service (string): service name to look for in process table
|
||||||
|
filename (string): The file to check mtime of
|
||||||
|
pgrep_full (boolean): Use full command line search mode with pgrep
|
||||||
|
sleep_time (int): Seconds to sleep before looking for process
|
||||||
|
retry_count (int): If service is not found, how many times to retry
|
||||||
|
|
||||||
|
Typical Usage:
|
||||||
|
u = OpenStackAmuletUtils(ERROR)
|
||||||
|
...
|
||||||
|
mtime = u.get_sentry_time(self.cinder_sentry)
|
||||||
|
self.d.configure('cinder', {'verbose': 'True', 'debug': 'True'})
|
||||||
|
if not u.validate_service_config_changed(self.cinder_sentry,
|
||||||
|
mtime,
|
||||||
|
'cinder-api',
|
||||||
|
'/etc/cinder/cinder.conf')
|
||||||
|
amulet.raise_status(amulet.FAIL, msg='update failed')
|
||||||
|
Returns:
|
||||||
|
bool: True if both service and file where updated/restarted after
|
||||||
|
mtime, False if service is older than mtime or if service was
|
||||||
|
not found or if filename was modified before mtime.
|
||||||
|
"""
|
||||||
|
self.log.debug('Checking %s restarted since %s' % (service, mtime))
|
||||||
|
time.sleep(sleep_time)
|
||||||
|
service_restart = self.service_restarted_since(sentry_unit, mtime,
|
||||||
|
service,
|
||||||
|
pgrep_full=pgrep_full,
|
||||||
|
sleep_time=0,
|
||||||
|
retry_count=retry_count)
|
||||||
|
config_update = self.config_updated_since(sentry_unit, filename, mtime,
|
||||||
|
sleep_time=0)
|
||||||
|
return service_restart and config_update
|
||||||
|
|
||||||
|
def get_sentry_time(self, sentry_unit):
|
||||||
|
"""Return current epoch time on a sentry"""
|
||||||
|
cmd = "date +'%s'"
|
||||||
|
return float(sentry_unit.run(cmd)[0])
|
||||||
|
|
||||||
def relation_error(self, name, data):
|
def relation_error(self, name, data):
|
||||||
return 'unexpected relation data in {} - {}'.format(name, data)
|
return 'unexpected relation data in {} - {}'.format(name, data)
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -0,0 +1,15 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import six
|
import six
|
||||||
from charmhelpers.contrib.amulet.deployment import (
|
from charmhelpers.contrib.amulet.deployment import (
|
||||||
AmuletDeployment
|
AmuletDeployment
|
||||||
@ -55,16 +71,19 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
services.append(this_service)
|
services.append(this_service)
|
||||||
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
|
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
|
||||||
'ceph-osd', 'ceph-radosgw']
|
'ceph-osd', 'ceph-radosgw']
|
||||||
|
# Openstack subordinate charms do not expose an origin option as that
|
||||||
|
# is controlled by the principle
|
||||||
|
ignore = ['neutron-openvswitch']
|
||||||
|
|
||||||
if self.openstack:
|
if self.openstack:
|
||||||
for svc in services:
|
for svc in services:
|
||||||
if svc['name'] not in use_source:
|
if svc['name'] not in use_source + ignore:
|
||||||
config = {'openstack-origin': self.openstack}
|
config = {'openstack-origin': self.openstack}
|
||||||
self.d.configure(svc['name'], config)
|
self.d.configure(svc['name'], config)
|
||||||
|
|
||||||
if self.source:
|
if self.source:
|
||||||
for svc in services:
|
for svc in services:
|
||||||
if svc['name'] in use_source:
|
if svc['name'] in use_source and svc['name'] not in ignore:
|
||||||
config = {'source': self.source}
|
config = {'source': self.source}
|
||||||
self.d.configure(svc['name'], config)
|
self.d.configure(svc['name'], config)
|
||||||
|
|
||||||
|
@ -1,3 +1,19 @@
|
|||||||
|
# Copyright 2014-2015 Canonical Limited.
|
||||||
|
#
|
||||||
|
# This file is part of charm-helpers.
|
||||||
|
#
|
||||||
|
# charm-helpers is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU Lesser General Public License version 3 as
|
||||||
|
# published by the Free Software Foundation.
|
||||||
|
#
|
||||||
|
# charm-helpers is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
|
Loading…
Reference in New Issue
Block a user