charmhelpers sync
This commit is contained in:
parent
f3803cb60d
commit
de98010f6f
@ -456,3 +456,18 @@ def get_hostname(address, fqdn=True):
|
|||||||
return result
|
return result
|
||||||
else:
|
else:
|
||||||
return result.split('.')[0]
|
return result.split('.')[0]
|
||||||
|
|
||||||
|
|
||||||
|
def port_has_listener(address, port):
|
||||||
|
"""
|
||||||
|
Returns True if the address:port is open and being listened to,
|
||||||
|
else False.
|
||||||
|
|
||||||
|
@param address: an IP address or hostname
|
||||||
|
@param port: integer port
|
||||||
|
|
||||||
|
Note calls 'zc' via a subprocess shell
|
||||||
|
"""
|
||||||
|
cmd = ['nc', '-z', address, str(port)]
|
||||||
|
result = subprocess.call(cmd)
|
||||||
|
return not(bool(result))
|
||||||
|
@ -61,7 +61,7 @@ from charmhelpers.fetch import (
|
|||||||
apt_install,
|
apt_install,
|
||||||
)
|
)
|
||||||
|
|
||||||
# from charmhelpers.core.kernel import modprobe
|
from charmhelpers.core.kernel import modprobe
|
||||||
|
|
||||||
KEYRING = '/etc/ceph/ceph.client.{}.keyring'
|
KEYRING = '/etc/ceph/ceph.client.{}.keyring'
|
||||||
KEYFILE = '/etc/ceph/ceph.client.{}.key'
|
KEYFILE = '/etc/ceph/ceph.client.{}.key'
|
||||||
@ -120,6 +120,7 @@ class PoolCreationError(Exception):
|
|||||||
"""
|
"""
|
||||||
A custom error to inform the caller that a pool creation failed. Provides an error message
|
A custom error to inform the caller that a pool creation failed. Provides an error message
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, message):
|
def __init__(self, message):
|
||||||
super(PoolCreationError, self).__init__(message)
|
super(PoolCreationError, self).__init__(message)
|
||||||
|
|
||||||
@ -129,6 +130,7 @@ class Pool(object):
|
|||||||
An object oriented approach to Ceph pool creation. This base class is inherited by ReplicatedPool and ErasurePool.
|
An object oriented approach to Ceph pool creation. This base class is inherited by ReplicatedPool and ErasurePool.
|
||||||
Do not call create() on this base class as it will not do anything. Instantiate a child class and call create().
|
Do not call create() on this base class as it will not do anything. Instantiate a child class and call create().
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, service, name):
|
def __init__(self, service, name):
|
||||||
self.service = service
|
self.service = service
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -186,15 +188,16 @@ class Pool(object):
|
|||||||
# which don't support OSD query from cli
|
# which don't support OSD query from cli
|
||||||
return 200
|
return 200
|
||||||
|
|
||||||
|
osd_list_length = len(osd_list)
|
||||||
# Calculate based on Ceph best practices
|
# Calculate based on Ceph best practices
|
||||||
if len(osd_list) < 5:
|
if osd_list_length < 5:
|
||||||
return 128
|
return 128
|
||||||
elif 5 < len(osd_list) < 10:
|
elif 5 < osd_list_length < 10:
|
||||||
return 512
|
return 512
|
||||||
elif 10 < len(osd_list) < 50:
|
elif 10 < osd_list_length < 50:
|
||||||
return 4096
|
return 4096
|
||||||
else:
|
else:
|
||||||
estimate = (len(osd_list) * 100) / pool_size
|
estimate = (osd_list_length * 100) / pool_size
|
||||||
# Return the next nearest power of 2
|
# Return the next nearest power of 2
|
||||||
index = bisect.bisect_right(powers_of_two, estimate)
|
index = bisect.bisect_right(powers_of_two, estimate)
|
||||||
return powers_of_two[index]
|
return powers_of_two[index]
|
||||||
@ -212,7 +215,8 @@ class ReplicatedPool(Pool):
|
|||||||
def create(self):
|
def create(self):
|
||||||
if not pool_exists(self.service, self.name):
|
if not pool_exists(self.service, self.name):
|
||||||
# Create it
|
# Create it
|
||||||
cmd = ['ceph', '--id', self.service, 'osd', 'pool', 'create', self.name, str(self.pg_num)]
|
cmd = ['ceph', '--id', self.service, 'osd', 'pool', 'create',
|
||||||
|
self.name, str(self.pg_num)]
|
||||||
try:
|
try:
|
||||||
check_call(cmd)
|
check_call(cmd)
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
@ -325,7 +329,8 @@ def set_pool_quota(service, pool_name, max_bytes):
|
|||||||
:return: None. Can raise CalledProcessError
|
:return: None. Can raise CalledProcessError
|
||||||
"""
|
"""
|
||||||
# Set a byte quota on a RADOS pool in ceph.
|
# Set a byte quota on a RADOS pool in ceph.
|
||||||
cmd = ['ceph', '--id', service, 'osd', 'pool', 'set-quota', pool_name, 'max_bytes', str(max_bytes)]
|
cmd = ['ceph', '--id', service, 'osd', 'pool', 'set-quota', pool_name,
|
||||||
|
'max_bytes', str(max_bytes)]
|
||||||
try:
|
try:
|
||||||
check_call(cmd)
|
check_call(cmd)
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
@ -355,14 +360,16 @@ def remove_erasure_profile(service, profile_name):
|
|||||||
:param profile_name: six.string_types
|
:param profile_name: six.string_types
|
||||||
:return: None. Can raise CalledProcessError
|
:return: None. Can raise CalledProcessError
|
||||||
"""
|
"""
|
||||||
cmd = ['ceph', '--id', service, 'osd', 'erasure-code-profile', 'rm', profile_name]
|
cmd = ['ceph', '--id', service, 'osd', 'erasure-code-profile', 'rm',
|
||||||
|
profile_name]
|
||||||
try:
|
try:
|
||||||
check_call(cmd)
|
check_call(cmd)
|
||||||
except CalledProcessError:
|
except CalledProcessError:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def create_erasure_profile(service, profile_name, erasure_plugin_name='jerasure', failure_domain='host',
|
def create_erasure_profile(service, profile_name, erasure_plugin_name='jerasure',
|
||||||
|
failure_domain='host',
|
||||||
data_chunks=2, coding_chunks=1,
|
data_chunks=2, coding_chunks=1,
|
||||||
locality=None, durability_estimator=None):
|
locality=None, durability_estimator=None):
|
||||||
"""
|
"""
|
||||||
@ -615,7 +622,7 @@ def configure(service, key, auth, use_syslog):
|
|||||||
keyring=_keyring_path(service),
|
keyring=_keyring_path(service),
|
||||||
mon_hosts=",".join(map(str, hosts)),
|
mon_hosts=",".join(map(str, hosts)),
|
||||||
use_syslog=use_syslog))
|
use_syslog=use_syslog))
|
||||||
# modprobe('rbd')
|
modprobe('rbd')
|
||||||
|
|
||||||
|
|
||||||
def image_mapped(name):
|
def image_mapped(name):
|
||||||
|
@ -138,7 +138,8 @@ def service_running(service_name):
|
|||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
if ("start/running" in output or "is running" in output):
|
if ("start/running" in output or "is running" in output or
|
||||||
|
"up and running" in output):
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@ -160,13 +161,13 @@ SYSTEMD_SYSTEM = '/run/systemd/system'
|
|||||||
|
|
||||||
|
|
||||||
def init_is_systemd():
|
def init_is_systemd():
|
||||||
|
"""Return True if the host system uses systemd, False otherwise."""
|
||||||
return os.path.isdir(SYSTEMD_SYSTEM)
|
return os.path.isdir(SYSTEMD_SYSTEM)
|
||||||
|
|
||||||
|
|
||||||
def adduser(username, password=None, shell='/bin/bash', system_user=False,
|
def adduser(username, password=None, shell='/bin/bash', system_user=False,
|
||||||
primary_group=None, secondary_groups=None):
|
primary_group=None, secondary_groups=None):
|
||||||
"""
|
"""Add a user to the system.
|
||||||
Add a user to the system.
|
|
||||||
|
|
||||||
Will log but otherwise succeed if the user already exists.
|
Will log but otherwise succeed if the user already exists.
|
||||||
|
|
||||||
@ -174,7 +175,7 @@ def adduser(username, password=None, shell='/bin/bash', system_user=False,
|
|||||||
:param str password: Password for user; if ``None``, create a system user
|
:param str password: Password for user; if ``None``, create a system user
|
||||||
:param str shell: The default shell for the user
|
:param str shell: The default shell for the user
|
||||||
:param bool system_user: Whether to create a login or system user
|
:param bool system_user: Whether to create a login or system user
|
||||||
:param str primary_group: Primary group for user; defaults to their username
|
:param str primary_group: Primary group for user; defaults to username
|
||||||
:param list secondary_groups: Optional list of additional groups
|
:param list secondary_groups: Optional list of additional groups
|
||||||
|
|
||||||
:returns: The password database entry struct, as returned by `pwd.getpwnam`
|
:returns: The password database entry struct, as returned by `pwd.getpwnam`
|
||||||
@ -300,14 +301,12 @@ def write_file(path, content, owner='root', group='root', perms=0o444):
|
|||||||
|
|
||||||
|
|
||||||
def fstab_remove(mp):
|
def fstab_remove(mp):
|
||||||
"""Remove the given mountpoint entry from /etc/fstab
|
"""Remove the given mountpoint entry from /etc/fstab"""
|
||||||
"""
|
|
||||||
return Fstab.remove_by_mountpoint(mp)
|
return Fstab.remove_by_mountpoint(mp)
|
||||||
|
|
||||||
|
|
||||||
def fstab_add(dev, mp, fs, options=None):
|
def fstab_add(dev, mp, fs, options=None):
|
||||||
"""Adds the given device entry to the /etc/fstab file
|
"""Adds the given device entry to the /etc/fstab file"""
|
||||||
"""
|
|
||||||
return Fstab.add(dev, mp, fs, options=options)
|
return Fstab.add(dev, mp, fs, options=options)
|
||||||
|
|
||||||
|
|
||||||
@ -363,8 +362,7 @@ def fstab_mount(mountpoint):
|
|||||||
|
|
||||||
|
|
||||||
def file_hash(path, hash_type='md5'):
|
def file_hash(path, hash_type='md5'):
|
||||||
"""
|
"""Generate a hash checksum of the contents of 'path' or None if not found.
|
||||||
Generate a hash checksum of the contents of 'path' or None if not found.
|
|
||||||
|
|
||||||
:param str hash_type: Any hash alrgorithm supported by :mod:`hashlib`,
|
:param str hash_type: Any hash alrgorithm supported by :mod:`hashlib`,
|
||||||
such as md5, sha1, sha256, sha512, etc.
|
such as md5, sha1, sha256, sha512, etc.
|
||||||
@ -379,10 +377,9 @@ def file_hash(path, hash_type='md5'):
|
|||||||
|
|
||||||
|
|
||||||
def path_hash(path):
|
def path_hash(path):
|
||||||
"""
|
"""Generate a hash checksum of all files matching 'path'. Standard
|
||||||
Generate a hash checksum of all files matching 'path'. Standard wildcards
|
wildcards like '*' and '?' are supported, see documentation for the 'glob'
|
||||||
like '*' and '?' are supported, see documentation for the 'glob' module for
|
module for more information.
|
||||||
more information.
|
|
||||||
|
|
||||||
:return: dict: A { filename: hash } dictionary for all matched files.
|
:return: dict: A { filename: hash } dictionary for all matched files.
|
||||||
Empty if none found.
|
Empty if none found.
|
||||||
@ -394,8 +391,7 @@ def path_hash(path):
|
|||||||
|
|
||||||
|
|
||||||
def check_hash(path, checksum, hash_type='md5'):
|
def check_hash(path, checksum, hash_type='md5'):
|
||||||
"""
|
"""Validate a file using a cryptographic checksum.
|
||||||
Validate a file using a cryptographic checksum.
|
|
||||||
|
|
||||||
:param str checksum: Value of the checksum used to validate the file.
|
:param str checksum: Value of the checksum used to validate the file.
|
||||||
:param str hash_type: Hash algorithm used to generate `checksum`.
|
:param str hash_type: Hash algorithm used to generate `checksum`.
|
||||||
@ -410,6 +406,7 @@ def check_hash(path, checksum, hash_type='md5'):
|
|||||||
|
|
||||||
|
|
||||||
class ChecksumError(ValueError):
|
class ChecksumError(ValueError):
|
||||||
|
"""A class derived from Value error to indicate the checksum failed."""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
@ -515,7 +512,7 @@ def get_bond_master(interface):
|
|||||||
|
|
||||||
|
|
||||||
def list_nics(nic_type=None):
|
def list_nics(nic_type=None):
|
||||||
'''Return a list of nics of given type(s)'''
|
"""Return a list of nics of given type(s)"""
|
||||||
if isinstance(nic_type, six.string_types):
|
if isinstance(nic_type, six.string_types):
|
||||||
int_types = [nic_type]
|
int_types = [nic_type]
|
||||||
else:
|
else:
|
||||||
@ -557,12 +554,13 @@ def list_nics(nic_type=None):
|
|||||||
|
|
||||||
|
|
||||||
def set_nic_mtu(nic, mtu):
|
def set_nic_mtu(nic, mtu):
|
||||||
'''Set MTU on a network interface'''
|
"""Set the Maximum Transmission Unit (MTU) on a network interface."""
|
||||||
cmd = ['ip', 'link', 'set', nic, 'mtu', mtu]
|
cmd = ['ip', 'link', 'set', nic, 'mtu', mtu]
|
||||||
subprocess.check_call(cmd)
|
subprocess.check_call(cmd)
|
||||||
|
|
||||||
|
|
||||||
def get_nic_mtu(nic):
|
def get_nic_mtu(nic):
|
||||||
|
"""Return the Maximum Transmission Unit (MTU) for a network interface."""
|
||||||
cmd = ['ip', 'addr', 'show', nic]
|
cmd = ['ip', 'addr', 'show', nic]
|
||||||
ip_output = subprocess.check_output(cmd).decode('UTF-8').split('\n')
|
ip_output = subprocess.check_output(cmd).decode('UTF-8').split('\n')
|
||||||
mtu = ""
|
mtu = ""
|
||||||
@ -574,6 +572,7 @@ def get_nic_mtu(nic):
|
|||||||
|
|
||||||
|
|
||||||
def get_nic_hwaddr(nic):
|
def get_nic_hwaddr(nic):
|
||||||
|
"""Return the Media Access Control (MAC) for a network interface."""
|
||||||
cmd = ['ip', '-o', '-0', 'addr', 'show', nic]
|
cmd = ['ip', '-o', '-0', 'addr', 'show', nic]
|
||||||
ip_output = subprocess.check_output(cmd).decode('UTF-8')
|
ip_output = subprocess.check_output(cmd).decode('UTF-8')
|
||||||
hwaddr = ""
|
hwaddr = ""
|
||||||
@ -584,7 +583,7 @@ def get_nic_hwaddr(nic):
|
|||||||
|
|
||||||
|
|
||||||
def cmp_pkgrevno(package, revno, pkgcache=None):
|
def cmp_pkgrevno(package, revno, pkgcache=None):
|
||||||
'''Compare supplied revno with the revno of the installed package
|
"""Compare supplied revno with the revno of the installed package
|
||||||
|
|
||||||
* 1 => Installed revno is greater than supplied arg
|
* 1 => Installed revno is greater than supplied arg
|
||||||
* 0 => Installed revno is the same as supplied arg
|
* 0 => Installed revno is the same as supplied arg
|
||||||
@ -593,7 +592,7 @@ def cmp_pkgrevno(package, revno, pkgcache=None):
|
|||||||
This function imports apt_cache function from charmhelpers.fetch if
|
This function imports apt_cache function from charmhelpers.fetch if
|
||||||
the pkgcache argument is None. Be sure to add 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.
|
you call this function, or pass an apt_pkg.Cache() instance.
|
||||||
'''
|
"""
|
||||||
import apt_pkg
|
import apt_pkg
|
||||||
if not pkgcache:
|
if not pkgcache:
|
||||||
from charmhelpers.fetch import apt_cache
|
from charmhelpers.fetch import apt_cache
|
||||||
@ -603,19 +602,27 @@ def cmp_pkgrevno(package, revno, pkgcache=None):
|
|||||||
|
|
||||||
|
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def chdir(d):
|
def chdir(directory):
|
||||||
|
"""Change the current working directory to a different directory for a code
|
||||||
|
block and return the previous directory after the block exits. Useful to
|
||||||
|
run commands from a specificed directory.
|
||||||
|
|
||||||
|
:param str directory: The directory path to change to for this context.
|
||||||
|
"""
|
||||||
cur = os.getcwd()
|
cur = os.getcwd()
|
||||||
try:
|
try:
|
||||||
yield os.chdir(d)
|
yield os.chdir(directory)
|
||||||
finally:
|
finally:
|
||||||
os.chdir(cur)
|
os.chdir(cur)
|
||||||
|
|
||||||
|
|
||||||
def chownr(path, owner, group, follow_links=True, chowntopdir=False):
|
def chownr(path, owner, group, follow_links=True, chowntopdir=False):
|
||||||
"""
|
"""Recursively change user and group ownership of files and directories
|
||||||
Recursively change user and group ownership of files and directories
|
|
||||||
in given path. Doesn't chown path itself by default, only its children.
|
in given path. Doesn't chown path itself by default, only its children.
|
||||||
|
|
||||||
|
:param str path: The string path to start changing ownership.
|
||||||
|
:param str owner: The owner string to use when looking up the uid.
|
||||||
|
:param str group: The group string to use when looking up the gid.
|
||||||
:param bool follow_links: Also Chown links if True
|
:param bool follow_links: Also Chown links if True
|
||||||
:param bool chowntopdir: Also chown path itself if True
|
:param bool chowntopdir: Also chown path itself if True
|
||||||
"""
|
"""
|
||||||
@ -639,15 +646,23 @@ def chownr(path, owner, group, follow_links=True, chowntopdir=False):
|
|||||||
|
|
||||||
|
|
||||||
def lchownr(path, owner, group):
|
def lchownr(path, owner, group):
|
||||||
|
"""Recursively change user and group ownership of files and directories
|
||||||
|
in a given path, not following symbolic links. See the documentation for
|
||||||
|
'os.lchown' for more information.
|
||||||
|
|
||||||
|
:param str path: The string path to start changing ownership.
|
||||||
|
:param str owner: The owner string to use when looking up the uid.
|
||||||
|
:param str group: The group string to use when looking up the gid.
|
||||||
|
"""
|
||||||
chownr(path, owner, group, follow_links=False)
|
chownr(path, owner, group, follow_links=False)
|
||||||
|
|
||||||
|
|
||||||
def get_total_ram():
|
def get_total_ram():
|
||||||
'''The total amount of system RAM in bytes.
|
"""The total amount of system RAM in bytes.
|
||||||
|
|
||||||
This is what is reported by the OS, and may be overcommitted when
|
This is what is reported by the OS, and may be overcommitted when
|
||||||
there are multiple containers hosted on the same machine.
|
there are multiple containers hosted on the same machine.
|
||||||
'''
|
"""
|
||||||
with open('/proc/meminfo', 'r') as f:
|
with open('/proc/meminfo', 'r') as f:
|
||||||
for line in f.readlines():
|
for line in f.readlines():
|
||||||
if line:
|
if line:
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
# along with charm-helpers. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import os
|
import os
|
||||||
from subprocess import check_call
|
from subprocess import check_call, CalledProcessError
|
||||||
from charmhelpers.fetch import (
|
from charmhelpers.fetch import (
|
||||||
BaseFetchHandler,
|
BaseFetchHandler,
|
||||||
UnhandledSource,
|
UnhandledSource,
|
||||||
@ -23,9 +23,9 @@ from charmhelpers.fetch import (
|
|||||||
apt_install,
|
apt_install,
|
||||||
)
|
)
|
||||||
|
|
||||||
if filter_installed_packages(['git']):
|
if filter_installed_packages(['git']) != []:
|
||||||
apt_install(['git'])
|
apt_install(['git'])
|
||||||
if filter_installed_packages(['git']):
|
if filter_installed_packages(['git']) != []:
|
||||||
raise NotImplementedError('Unable to install git')
|
raise NotImplementedError('Unable to install git')
|
||||||
|
|
||||||
|
|
||||||
@ -63,6 +63,8 @@ class GitUrlFetchHandler(BaseFetchHandler):
|
|||||||
branch_name)
|
branch_name)
|
||||||
try:
|
try:
|
||||||
self.clone(source, dest_dir, branch, depth)
|
self.clone(source, dest_dir, branch, depth)
|
||||||
|
except CalledProcessError as e:
|
||||||
|
raise UnhandledSource(e)
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
raise UnhandledSource(e.strerror)
|
raise UnhandledSource(e.strerror)
|
||||||
return dest_dir
|
return dest_dir
|
||||||
|
@ -121,11 +121,12 @@ class OpenStackAmuletDeployment(AmuletDeployment):
|
|||||||
|
|
||||||
# Charms which should use the source config option
|
# Charms which should use the source config option
|
||||||
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
|
use_source = ['mysql', 'mongodb', 'rabbitmq-server', 'ceph',
|
||||||
'ceph-osd', 'ceph-radosgw']
|
'ceph-osd', 'ceph-radosgw', 'ceph-mon']
|
||||||
|
|
||||||
# Charms which can not use openstack-origin, ie. many subordinates
|
# Charms which can not use openstack-origin, ie. many subordinates
|
||||||
no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
|
no_origin = ['cinder-ceph', 'hacluster', 'neutron-openvswitch', 'nrpe',
|
||||||
'openvswitch-odl', 'neutron-api-odl', 'odl-controller']
|
'openvswitch-odl', 'neutron-api-odl', 'odl-controller',
|
||||||
|
'cinder-backup']
|
||||||
|
|
||||||
if self.openstack:
|
if self.openstack:
|
||||||
for svc in services:
|
for svc in services:
|
||||||
|
Loading…
Reference in New Issue
Block a user