mirror of
https://github.com/ceph/ceph
synced 2025-03-29 15:03:39 +00:00
Merge pull request #1032 from dachary/wip-ceph-disk-activate-data-dir
ceph-disk : fixes and improvements for the --data-dir code path and associated tests Reviewed-by: Sage Weil <sage@inktank.com>
This commit is contained in:
commit
312107876c
355
src/ceph-disk
355
src/ceph-disk
@ -1,4 +1,20 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2014 Inktank <info@inktank.com>
|
||||
# Copyright (C) 2014 Cloudwatt <libre.licensing@cloudwatt.com>
|
||||
#
|
||||
# Author: Loic Dachary <loic@dachary.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Library Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 Library Public License for more details.
|
||||
#
|
||||
|
||||
import argparse
|
||||
import errno
|
||||
@ -55,7 +71,6 @@ knew the GPT partition type.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
CEPH_OSD_ONDISK_MAGIC = 'ceph osd volume v026'
|
||||
|
||||
JOURNAL_UUID = '45b0969e-9b03-4f30-b4c6-b4b80ceff106'
|
||||
@ -97,8 +112,13 @@ INIT_SYSTEMS = [
|
||||
'sysvinit',
|
||||
'systemd',
|
||||
'auto',
|
||||
'none',
|
||||
]
|
||||
|
||||
STATEDIR = '/var/lib/ceph'
|
||||
|
||||
SYSCONFDIR = '/etc/ceph'
|
||||
|
||||
# Nuke the TERM variable to avoid confusing any subprocesses we call.
|
||||
# For example, libreadline will print weird control sequences for some
|
||||
# TERM values.
|
||||
@ -130,11 +150,6 @@ class filelock(object):
|
||||
fcntl.lockf(self.fd, fcntl.LOCK_UN)
|
||||
self.fd = None
|
||||
|
||||
|
||||
prepare_lock = filelock('/var/lib/ceph/tmp/ceph-disk.prepare.lock')
|
||||
activate_lock = filelock('/var/lib/ceph/tmp/ceph-disk.activate.lock')
|
||||
|
||||
|
||||
###### exceptions ########
|
||||
|
||||
class Error(Exception):
|
||||
@ -212,14 +227,20 @@ def maybe_mkdir(*a, **kw):
|
||||
|
||||
def which(executable):
|
||||
"""find the location of an executable"""
|
||||
locations = (
|
||||
if 'PATH' in os.environ:
|
||||
envpath = os.environ['PATH']
|
||||
else:
|
||||
envpath = os.defpath
|
||||
PATH = envpath.split(os.pathsep)
|
||||
|
||||
locations = PATH + [
|
||||
'/usr/local/bin',
|
||||
'/bin',
|
||||
'/usr/bin',
|
||||
'/usr/local/sbin',
|
||||
'/usr/sbin',
|
||||
'/sbin',
|
||||
)
|
||||
]
|
||||
|
||||
for location in locations:
|
||||
executable_path = os.path.join(location, executable)
|
||||
@ -514,7 +535,7 @@ def check_osd_id(osd_id):
|
||||
Ensures osd id is numeric.
|
||||
"""
|
||||
if not re.match(r'^[0-9]+$', osd_id):
|
||||
raise Error('osd id is not numeric')
|
||||
raise Error('osd id is not numeric', osd_id)
|
||||
|
||||
|
||||
def allocate_osd_id(
|
||||
@ -533,7 +554,7 @@ def allocate_osd_id(
|
||||
try:
|
||||
osd_id = _check_output(
|
||||
args=[
|
||||
'/usr/bin/ceph',
|
||||
'ceph',
|
||||
'--cluster', cluster,
|
||||
'--name', 'client.bootstrap-osd',
|
||||
'--keyring', keyring,
|
||||
@ -542,7 +563,7 @@ def allocate_osd_id(
|
||||
],
|
||||
)
|
||||
except subprocess.CalledProcessError as e:
|
||||
raise Error('ceph osd create failed', e)
|
||||
raise Error('ceph osd create failed', e, e.output)
|
||||
osd_id = must_be_one_line(osd_id)
|
||||
check_osd_id(osd_id)
|
||||
return osd_id
|
||||
@ -585,7 +606,7 @@ def get_conf(cluster, variable):
|
||||
try:
|
||||
process = subprocess.Popen(
|
||||
args=[
|
||||
'/usr/bin/ceph-conf',
|
||||
'ceph-conf',
|
||||
'--cluster={cluster}'.format(
|
||||
cluster=cluster,
|
||||
),
|
||||
@ -648,7 +669,7 @@ def get_fsid(cluster):
|
||||
|
||||
:return: The fsid or raises Error.
|
||||
"""
|
||||
fsid = get_conf(cluster=cluster, variable='fsid')
|
||||
fsid = get_conf_with_default(cluster=cluster, variable='fsid')
|
||||
if fsid is None:
|
||||
raise Error('getting cluster uuid from configuration failed')
|
||||
return fsid.lower()
|
||||
@ -745,7 +766,7 @@ def mount(
|
||||
# mount
|
||||
path = tempfile.mkdtemp(
|
||||
prefix='mnt.',
|
||||
dir='/var/lib/ceph/tmp',
|
||||
dir=STATEDIR + '/tmp',
|
||||
)
|
||||
try:
|
||||
LOG.debug('Mounting %s on %s with options %s', dev, path, options)
|
||||
@ -1013,7 +1034,7 @@ def prepare_journal(
|
||||
raise Error('Journal is not a regular file', journal)
|
||||
return prepare_journal_dev(data, journal, journal_size, journal_uuid, journal_dm_keypath)
|
||||
|
||||
raise Error('Journal %s is neither a block device nor regular file', journal)
|
||||
raise Error('Journal %s is neither a block device nor regular file' % journal)
|
||||
|
||||
|
||||
def adjust_symlink(target, path):
|
||||
@ -1210,7 +1231,10 @@ def main_prepare(args):
|
||||
try:
|
||||
prepare_lock.acquire()
|
||||
if not os.path.exists(args.data):
|
||||
raise Error('data path does not exist', args.data)
|
||||
if args.data_dev:
|
||||
raise Error('data path does not exist', args.data)
|
||||
else:
|
||||
os.mkdir(args.data)
|
||||
|
||||
# in use?
|
||||
dmode = os.stat(args.data).st_mode
|
||||
@ -1374,7 +1398,7 @@ def mkfs(
|
||||
monmap = os.path.join(path, 'activate.monmap')
|
||||
subprocess.check_call(
|
||||
args=[
|
||||
'/usr/bin/ceph',
|
||||
'ceph',
|
||||
'--cluster', cluster,
|
||||
'--name', 'client.bootstrap-osd',
|
||||
'--keyring', keyring,
|
||||
@ -1384,7 +1408,7 @@ def mkfs(
|
||||
|
||||
subprocess.check_call(
|
||||
args=[
|
||||
'/usr/bin/ceph-osd',
|
||||
'ceph-osd',
|
||||
'--cluster', cluster,
|
||||
'--mkfs',
|
||||
'--mkkey',
|
||||
@ -1410,7 +1434,7 @@ def auth_key(
|
||||
# try dumpling+ cap scheme
|
||||
subprocess.check_call(
|
||||
args=[
|
||||
'/usr/bin/ceph',
|
||||
'ceph',
|
||||
'--cluster', cluster,
|
||||
'--name', 'client.bootstrap-osd',
|
||||
'--keyring', keyring,
|
||||
@ -1421,11 +1445,11 @@ def auth_key(
|
||||
],
|
||||
)
|
||||
except subprocess.CalledProcessError as err:
|
||||
if err.errno == errno.EACCES:
|
||||
if err.returncode == errno.EACCES:
|
||||
# try old cap scheme
|
||||
subprocess.check_call(
|
||||
args=[
|
||||
'/usr/bin/ceph',
|
||||
'ceph',
|
||||
'--cluster', cluster,
|
||||
'--name', 'client.bootstrap-osd',
|
||||
'--keyring', keyring,
|
||||
@ -1448,7 +1472,7 @@ def move_mount(
|
||||
mount_options,
|
||||
):
|
||||
LOG.debug('Moving mount to final location...')
|
||||
parent = '/var/lib/ceph/osd'
|
||||
parent = STATEDIR + '/osd'
|
||||
osd_data = os.path.join(
|
||||
parent,
|
||||
'{cluster}-{osd_id}'.format(cluster=cluster, osd_id=osd_id),
|
||||
@ -1492,7 +1516,7 @@ def start_daemon(
|
||||
):
|
||||
LOG.debug('Starting %s osd.%s...', cluster, osd_id)
|
||||
|
||||
path = '/var/lib/ceph/osd/{cluster}-{osd_id}'.format(
|
||||
path = (STATEDIR + '/osd/{cluster}-{osd_id}').format(
|
||||
cluster=cluster, osd_id=osd_id)
|
||||
|
||||
# upstart?
|
||||
@ -1603,16 +1627,16 @@ def mount_activate(
|
||||
other = False
|
||||
src_dev = os.stat(path).st_dev
|
||||
try:
|
||||
dst_dev = os.stat('/var/lib/ceph/osd/{cluster}-{osd_id}'.format(
|
||||
dst_dev = os.stat((STATEDIR + '/osd/{cluster}-{osd_id}').format(
|
||||
cluster=cluster,
|
||||
osd_id=osd_id)).st_dev
|
||||
if src_dev == dst_dev:
|
||||
active = True
|
||||
else:
|
||||
parent_dev = os.stat('/var/lib/ceph/osd').st_dev
|
||||
parent_dev = os.stat(STATEDIR + '/osd').st_dev
|
||||
if dst_dev != parent_dev:
|
||||
other = True
|
||||
elif os.listdir('/var/lib/ceph/osd/{cluster}-{osd_id}'.format(
|
||||
elif os.listdir((STATEDIR + '/osd/{cluster}-{osd_id}').format(
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
)):
|
||||
@ -1659,28 +1683,30 @@ def activate_dir(
|
||||
)
|
||||
|
||||
(osd_id, cluster) = activate(path, activate_key_template, init)
|
||||
canonical = '/var/lib/ceph/osd/{cluster}-{osd_id}'.format(
|
||||
cluster=cluster,
|
||||
osd_id=osd_id)
|
||||
if path != canonical:
|
||||
# symlink it from the proper location
|
||||
create = True
|
||||
if os.path.lexists(canonical):
|
||||
old = os.readlink(canonical)
|
||||
if old != path:
|
||||
LOG.debug('Removing old symlink %s -> %s', canonical, old)
|
||||
|
||||
if init not in ( None, 'none' ):
|
||||
canonical = (STATEDIR + '/osd/{cluster}-{osd_id}').format(
|
||||
cluster=cluster,
|
||||
osd_id=osd_id)
|
||||
if path != canonical:
|
||||
# symlink it from the proper location
|
||||
create = True
|
||||
if os.path.lexists(canonical):
|
||||
old = os.readlink(canonical)
|
||||
if old != path:
|
||||
LOG.debug('Removing old symlink %s -> %s', canonical, old)
|
||||
try:
|
||||
os.unlink(canonical)
|
||||
except:
|
||||
raise Error('unable to remove old symlink', canonical)
|
||||
else:
|
||||
create = False
|
||||
if create:
|
||||
LOG.debug('Creating symlink %s -> %s', canonical, path)
|
||||
try:
|
||||
os.unlink(canonical)
|
||||
os.symlink(path, canonical)
|
||||
except:
|
||||
raise Error('unable to remove old symlink %s', canonical)
|
||||
else:
|
||||
create = False
|
||||
if create:
|
||||
LOG.debug('Creating symlink %s -> %s', canonical, path)
|
||||
try:
|
||||
os.symlink(path, canonical)
|
||||
except:
|
||||
raise Error('unable to create symlink %s -> %s', canonical, path)
|
||||
raise Error('unable to create symlink %s -> %s' % (canonical, path))
|
||||
|
||||
return (cluster, osd_id)
|
||||
|
||||
@ -1692,9 +1718,9 @@ def find_cluster_by_uuid(_uuid):
|
||||
"""
|
||||
_uuid = _uuid.lower()
|
||||
no_fsid = []
|
||||
if not os.path.exists('/etc/ceph'):
|
||||
if not os.path.exists(SYSCONFDIR):
|
||||
return None
|
||||
for conf_file in os.listdir('/etc/ceph'):
|
||||
for conf_file in os.listdir(SYSCONFDIR):
|
||||
if not conf_file.endswith('.conf'):
|
||||
continue
|
||||
cluster = conf_file[:-5]
|
||||
@ -1709,7 +1735,7 @@ def find_cluster_by_uuid(_uuid):
|
||||
return cluster
|
||||
# be tolerant of /etc/ceph/ceph.conf without an fsid defined.
|
||||
if len(no_fsid) == 1 and no_fsid[0] == 'ceph':
|
||||
LOG.warning('No fsid defined in /etc/ceph/ceph.conf; using anyway')
|
||||
LOG.warning('No fsid defined in ' + SYSCONFDIR + '/ceph.conf; using anyway')
|
||||
return 'ceph'
|
||||
return None
|
||||
|
||||
@ -1719,88 +1745,84 @@ def activate(
|
||||
init,
|
||||
):
|
||||
|
||||
try:
|
||||
check_osd_magic(path)
|
||||
check_osd_magic(path)
|
||||
|
||||
ceph_fsid = read_one_line(path, 'ceph_fsid')
|
||||
if ceph_fsid is None:
|
||||
raise Error('No cluster uuid assigned.')
|
||||
LOG.debug('Cluster uuid is %s', ceph_fsid)
|
||||
ceph_fsid = read_one_line(path, 'ceph_fsid')
|
||||
if ceph_fsid is None:
|
||||
raise Error('No cluster uuid assigned.')
|
||||
LOG.debug('Cluster uuid is %s', ceph_fsid)
|
||||
|
||||
cluster = find_cluster_by_uuid(ceph_fsid)
|
||||
if cluster is None:
|
||||
raise Error('No cluster conf found in /etc/ceph with fsid %s' % ceph_fsid)
|
||||
LOG.debug('Cluster name is %s', cluster)
|
||||
cluster = find_cluster_by_uuid(ceph_fsid)
|
||||
if cluster is None:
|
||||
raise Error('No cluster conf found in ' + SYSCONFDIR + ' with fsid %s' % ceph_fsid)
|
||||
LOG.debug('Cluster name is %s', cluster)
|
||||
|
||||
fsid = read_one_line(path, 'fsid')
|
||||
if fsid is None:
|
||||
raise Error('No OSD uuid assigned.')
|
||||
LOG.debug('OSD uuid is %s', fsid)
|
||||
fsid = read_one_line(path, 'fsid')
|
||||
if fsid is None:
|
||||
raise Error('No OSD uuid assigned.')
|
||||
LOG.debug('OSD uuid is %s', fsid)
|
||||
|
||||
keyring = activate_key_template.format(cluster=cluster)
|
||||
keyring = activate_key_template.format(cluster=cluster)
|
||||
|
||||
osd_id = get_osd_id(path)
|
||||
if osd_id is None:
|
||||
osd_id = allocate_osd_id(
|
||||
osd_id = get_osd_id(path)
|
||||
if osd_id is None:
|
||||
osd_id = allocate_osd_id(
|
||||
cluster=cluster,
|
||||
fsid=fsid,
|
||||
keyring=keyring,
|
||||
)
|
||||
write_one_line(path, 'whoami', osd_id)
|
||||
LOG.debug('OSD id is %s', osd_id)
|
||||
|
||||
if not os.path.exists(os.path.join(path, 'ready')):
|
||||
LOG.debug('Initializing OSD...')
|
||||
# re-running mkfs is safe, so just run until it completes
|
||||
mkfs(
|
||||
path=path,
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
fsid=fsid,
|
||||
keyring=keyring,
|
||||
)
|
||||
|
||||
if init not in ( None, 'none' ):
|
||||
if init == 'auto':
|
||||
conf_val = get_conf(
|
||||
cluster=cluster,
|
||||
fsid=fsid,
|
||||
keyring=keyring,
|
||||
variable='init'
|
||||
)
|
||||
write_one_line(path, 'whoami', osd_id)
|
||||
LOG.debug('OSD id is %s', osd_id)
|
||||
|
||||
if not os.path.exists(os.path.join(path, 'ready')):
|
||||
LOG.debug('Initializing OSD...')
|
||||
# re-running mkfs is safe, so just run until it completes
|
||||
mkfs(
|
||||
path=path,
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
fsid=fsid,
|
||||
keyring=keyring,
|
||||
)
|
||||
|
||||
if init is not None:
|
||||
if init == 'auto':
|
||||
conf_val = get_conf(
|
||||
cluster=cluster,
|
||||
variable='init'
|
||||
)
|
||||
if conf_val is not None:
|
||||
init = conf_val
|
||||
if conf_val is not None:
|
||||
init = conf_val
|
||||
else:
|
||||
(distro, release, codename) = platform.dist()
|
||||
if distro == 'Ubuntu':
|
||||
init = 'upstart'
|
||||
else:
|
||||
(distro, release, codename) = platform.dist()
|
||||
if distro == 'Ubuntu':
|
||||
init = 'upstart'
|
||||
else:
|
||||
init = 'sysvinit'
|
||||
init = 'sysvinit'
|
||||
|
||||
LOG.debug('Marking with init system %s', init)
|
||||
with file(os.path.join(path, init), 'w'):
|
||||
LOG.debug('Marking with init system %s', init)
|
||||
with file(os.path.join(path, init), 'w'):
|
||||
pass
|
||||
|
||||
# remove markers for others, just in case.
|
||||
for other in INIT_SYSTEMS:
|
||||
if other != init:
|
||||
try:
|
||||
os.unlink(os.path.join(path, other))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# remove markers for others, just in case.
|
||||
for other in INIT_SYSTEMS:
|
||||
if other != init:
|
||||
try:
|
||||
os.unlink(os.path.join(path, other))
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if not os.path.exists(os.path.join(path, 'active')):
|
||||
LOG.debug('Authorizing OSD key...')
|
||||
auth_key(
|
||||
path=path,
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
keyring=keyring,
|
||||
)
|
||||
write_one_line(path, 'active', 'ok')
|
||||
LOG.debug('%s osd.%s data dir is ready at %s', cluster, osd_id, path)
|
||||
return (osd_id, cluster)
|
||||
except:
|
||||
raise
|
||||
|
||||
if not os.path.exists(os.path.join(path, 'active')):
|
||||
LOG.debug('Authorizing OSD key...')
|
||||
auth_key(
|
||||
path=path,
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
keyring=keyring,
|
||||
)
|
||||
write_one_line(path, 'active', 'ok')
|
||||
LOG.debug('%s osd.%s data dir is ready at %s', cluster, osd_id, path)
|
||||
return (osd_id, cluster)
|
||||
|
||||
|
||||
def main_activate(args):
|
||||
@ -1808,7 +1830,7 @@ def main_activate(args):
|
||||
osd_id = None
|
||||
|
||||
if not os.path.exists(args.path):
|
||||
raise Error('%s does not exist', args.path)
|
||||
raise Error('%s does not exist' % args.path)
|
||||
|
||||
if is_suppressed(args.path):
|
||||
LOG.info('suppressed activate request on %s', args.path)
|
||||
@ -1823,22 +1845,36 @@ def main_activate(args):
|
||||
activate_key_template=args.activate_key_template,
|
||||
init=args.mark_init,
|
||||
)
|
||||
|
||||
elif stat.S_ISDIR(mode):
|
||||
(cluster, osd_id) = activate_dir(
|
||||
path=args.path,
|
||||
activate_key_template=args.activate_key_template,
|
||||
init=args.mark_init,
|
||||
)
|
||||
|
||||
if args.mark_init == 'none':
|
||||
command_check_call(
|
||||
[
|
||||
'ceph-osd',
|
||||
'--cluster={cluster}'.format(cluster=cluster),
|
||||
'--id={osd_id}'.format(osd_id=osd_id),
|
||||
'--osd-data={path}'.format(path=args.path),
|
||||
'--osd-journal={path}/journal'.format(path=args.path),
|
||||
],
|
||||
)
|
||||
|
||||
else:
|
||||
raise Error('%s is not a directory or block device', args.path)
|
||||
raise Error('%s is not a directory or block device' % args.path)
|
||||
|
||||
start_daemon(
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
if args.mark_init not in ( None, 'none' ):
|
||||
|
||||
start_daemon(
|
||||
cluster=cluster,
|
||||
osd_id=osd_id,
|
||||
)
|
||||
activate_lock.release()
|
||||
|
||||
except:
|
||||
finally:
|
||||
activate_lock.release()
|
||||
|
||||
|
||||
@ -1846,11 +1882,11 @@ def main_activate(args):
|
||||
|
||||
def get_journal_osd_uuid(path):
|
||||
if not os.path.exists(path):
|
||||
raise Error('%s does not exist', path)
|
||||
raise Error('%s does not exist' % path)
|
||||
|
||||
mode = os.stat(path).st_mode
|
||||
if not stat.S_ISBLK(mode):
|
||||
raise Error('%s is not a block device', path)
|
||||
raise Error('%s is not a block device' % path)
|
||||
|
||||
try:
|
||||
out = _check_output(
|
||||
@ -1874,7 +1910,7 @@ def get_journal_osd_uuid(path):
|
||||
|
||||
def main_activate_journal(args):
|
||||
if not os.path.exists(args.dev):
|
||||
raise Error('%s does not exist', args.dev)
|
||||
raise Error('%s does not exist' % args.dev)
|
||||
|
||||
cluster = None
|
||||
osd_id = None
|
||||
@ -1895,12 +1931,9 @@ def main_activate_journal(args):
|
||||
osd_id=osd_id,
|
||||
)
|
||||
|
||||
finally:
|
||||
activate_lock.release()
|
||||
|
||||
except:
|
||||
activate_lock.release()
|
||||
raise
|
||||
|
||||
###########################
|
||||
|
||||
def main_activate_all(args):
|
||||
@ -2129,8 +2162,6 @@ def main_list(args):
|
||||
# means suppressing sdb will stop activate on sdb1, sdb2, etc.
|
||||
#
|
||||
|
||||
SUPPRESS_PREFIX = '/var/lib/ceph/tmp/suppress-activate.'
|
||||
|
||||
def is_suppressed(path):
|
||||
disk = os.path.realpath(path)
|
||||
try:
|
||||
@ -2188,6 +2219,27 @@ def main_zap(args):
|
||||
|
||||
###########################
|
||||
|
||||
def setup_statedir(dir):
|
||||
global STATEDIR
|
||||
STATEDIR = dir
|
||||
|
||||
if not os.path.exists(STATEDIR):
|
||||
os.mkdir(STATEDIR)
|
||||
if not os.path.exists(STATEDIR + "/tmp"):
|
||||
os.mkdir(STATEDIR + "/tmp")
|
||||
|
||||
global prepare_lock
|
||||
prepare_lock = filelock(STATEDIR + '/tmp/ceph-disk.prepare.lock')
|
||||
|
||||
global activate_lock
|
||||
activate_lock = filelock(STATEDIR + '/tmp/ceph-disk.activate.lock')
|
||||
|
||||
global SUPPRESS_PREFIX
|
||||
SUPPRESS_PREFIX = STATEDIR + '/tmp/suppress-activate.'
|
||||
|
||||
def setup_sysconfdir(dir):
|
||||
global SYSCONFDIR
|
||||
SYSCONFDIR = dir
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
@ -2198,6 +2250,24 @@ def parse_args():
|
||||
action='store_true', default=None,
|
||||
help='be more verbose',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--prepend-to-path',
|
||||
metavar='PATH',
|
||||
default='/usr/bin',
|
||||
help='prepend PATH to $PATH for backward compatibility (default /usr/bin)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--statedir',
|
||||
metavar='PATH',
|
||||
default='/var/lib/ceph',
|
||||
help='directory in which ceph state is preserved (default /var/lib/ceph)',
|
||||
)
|
||||
parser.add_argument(
|
||||
'--sysconfdir',
|
||||
metavar='PATH',
|
||||
default='/etc/ceph',
|
||||
help='directory in which ceph configuration files are found (default /etc/ceph)',
|
||||
)
|
||||
parser.set_defaults(
|
||||
# we want to hold on to this, for later
|
||||
prog=parser.prog,
|
||||
@ -2313,7 +2383,7 @@ def parse_args():
|
||||
help='path to block device or directory',
|
||||
)
|
||||
activate_parser.set_defaults(
|
||||
activate_key_template='/var/lib/ceph/bootstrap-osd/{cluster}.keyring',
|
||||
activate_key_template=STATEDIR + '/bootstrap-osd/{cluster}.keyring',
|
||||
func=main_activate,
|
||||
)
|
||||
|
||||
@ -2337,7 +2407,7 @@ def parse_args():
|
||||
choices=INIT_SYSTEMS,
|
||||
)
|
||||
activate_journal_parser.set_defaults(
|
||||
activate_key_template='/var/lib/ceph/bootstrap-osd/{cluster}.keyring',
|
||||
activate_key_template=STATEDIR + '/bootstrap-osd/{cluster}.keyring',
|
||||
func=main_activate_journal,
|
||||
)
|
||||
|
||||
@ -2356,7 +2426,7 @@ def parse_args():
|
||||
choices=INIT_SYSTEMS,
|
||||
)
|
||||
activate_all_parser.set_defaults(
|
||||
activate_key_template='/var/lib/ceph/bootstrap-osd/{cluster}.keyring',
|
||||
activate_key_template=STATEDIR + '/bootstrap-osd/{cluster}.keyring',
|
||||
func=main_activate_all,
|
||||
)
|
||||
|
||||
@ -2413,6 +2483,13 @@ def main():
|
||||
level=loglevel,
|
||||
)
|
||||
|
||||
if args.prepend_to_path != '':
|
||||
path = os.environ.get('PATH', '')
|
||||
os.environ['PATH'] = args.prepend_to_path + ":" + path
|
||||
|
||||
setup_statedir(args.statedir)
|
||||
setup_sysconfdir(args.sysconfdir)
|
||||
|
||||
try:
|
||||
args.func(args)
|
||||
|
||||
|
@ -243,6 +243,7 @@ check_SCRIPTS += \
|
||||
test/encoding/check-generated.sh \
|
||||
test/mon/osd-pool-create.sh \
|
||||
test/mon/mkfs.sh \
|
||||
test/ceph-disk.sh \
|
||||
test/vstart_wrapped_tests.sh
|
||||
|
||||
# target to build but not run the unit tests
|
||||
|
227
src/test/ceph-disk.sh
Executable file
227
src/test/ceph-disk.sh
Executable file
@ -0,0 +1,227 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2014 Cloudwatt <libre.licensing@cloudwatt.com>
|
||||
#
|
||||
# Author: Loic Dachary <loic@dachary.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Library Public License as published by
|
||||
# the Free Software Foundation; either version 2, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# This program 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 Library Public License for more details.
|
||||
#
|
||||
set -xe
|
||||
PS4='${FUNCNAME[0]}: $LINENO: '
|
||||
|
||||
export PATH=:$PATH # make sure program from sources are prefered
|
||||
DIR=test-ceph-disk
|
||||
MON_ID=a
|
||||
MONA=127.0.0.1:7451
|
||||
FSID=$(uuidgen)
|
||||
export CEPH_CONF=/dev/null
|
||||
export CEPH_ARGS="--fsid $FSID"
|
||||
CEPH_ARGS+=" --chdir="
|
||||
CEPH_ARGS+=" --run-dir=$DIR"
|
||||
CEPH_ARGS+=" --mon-host=$MONA"
|
||||
CEPH_ARGS+=" --log-file=$DIR/\$name.log"
|
||||
CEPH_ARGS+=" --pid-file=$DIR/\$name.pidfile"
|
||||
CEPH_ARGS+=" --auth-supported=none"
|
||||
CEPH_DISK_ARGS=
|
||||
CEPH_DISK_ARGS+=" --statedir=$DIR"
|
||||
CEPH_DISK_ARGS+=" --sysconfdir=$DIR"
|
||||
CEPH_DISK_ARGS+=" --prepend-to-path="
|
||||
CEPH_DISK_ARGS+=" --verbose"
|
||||
|
||||
function setup() {
|
||||
teardown
|
||||
mkdir $DIR
|
||||
touch $DIR/ceph.conf
|
||||
}
|
||||
|
||||
function teardown() {
|
||||
kill_daemons
|
||||
rm -fr $DIR
|
||||
}
|
||||
|
||||
function run_mon() {
|
||||
local mon_dir=$DIR/$MON_ID
|
||||
|
||||
./ceph-mon \
|
||||
--id $MON_ID \
|
||||
--mkfs \
|
||||
--mon-data=$mon_dir \
|
||||
--mon-initial-members=$MON_ID \
|
||||
"$@"
|
||||
|
||||
./ceph-mon \
|
||||
--id $MON_ID \
|
||||
--mon-data=$mon_dir \
|
||||
--mon-cluster-log-file=$mon_dir/log \
|
||||
--public-addr $MONA \
|
||||
"$@"
|
||||
}
|
||||
|
||||
function kill_daemons() {
|
||||
for pidfile in $(find $DIR | grep pidfile) ; do
|
||||
for try in 0 1 1 1 2 3 ; do
|
||||
kill $(cat $pidfile) || break
|
||||
sleep $try
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
function command_fixture() {
|
||||
local command=$1
|
||||
|
||||
[ $(which $command) = ./$command ] || return 1
|
||||
|
||||
cat > $DIR/$command <<EOF
|
||||
#!/bin/bash
|
||||
touch $DIR/used-$command
|
||||
exec ./$command "\$@"
|
||||
EOF
|
||||
chmod +x $DIR/$command
|
||||
}
|
||||
|
||||
function tweak_path() {
|
||||
local tweaker=$1
|
||||
|
||||
setup
|
||||
|
||||
command_fixture ceph-conf || return 1
|
||||
command_fixture ceph-osd || return 1
|
||||
|
||||
test_activate_dir
|
||||
|
||||
[ ! -f $DIR/used-ceph-conf ] || return 1
|
||||
[ ! -f $DIR/used-ceph-osd ] || return 1
|
||||
|
||||
teardown
|
||||
|
||||
setup
|
||||
|
||||
command_fixture ceph-conf || return 1
|
||||
command_fixture ceph-osd || return 1
|
||||
|
||||
$tweaker test_activate_dir || return 1
|
||||
|
||||
[ -f $DIR/used-ceph-conf ] || return 1
|
||||
[ -f $DIR/used-ceph-osd ] || return 1
|
||||
|
||||
teardown
|
||||
}
|
||||
|
||||
function use_prepend_to_path() {
|
||||
local ceph_disk_args
|
||||
ceph_disk_args+=" --statedir=$DIR"
|
||||
ceph_disk_args+=" --sysconfdir=$DIR"
|
||||
ceph_disk_args+=" --prepend-to-path=$DIR"
|
||||
ceph_disk_args+=" --verbose"
|
||||
CEPH_DISK_ARGS="$ceph_disk_args" \
|
||||
"$@" || return 1
|
||||
}
|
||||
|
||||
function test_prepend_to_path() {
|
||||
tweak_path use_prepend_to_path || return 1
|
||||
}
|
||||
|
||||
function use_path() {
|
||||
PATH="$DIR:$PATH" \
|
||||
"$@" || return 1
|
||||
}
|
||||
|
||||
function test_path() {
|
||||
tweak_path use_path || return 1
|
||||
}
|
||||
|
||||
# ceph-disk prepare returns immediately on success if the magic file
|
||||
# exists on the --osd-data directory.
|
||||
function test_activate_dir_magic() {
|
||||
local uuid=$(uuidgen)
|
||||
local osd_data=$DIR/osd
|
||||
|
||||
echo a failure to create the fsid file implies the magic file is not created
|
||||
|
||||
mkdir -p $osd_data/fsid
|
||||
CEPH_ARGS="--fsid $uuid" \
|
||||
./ceph-disk $CEPH_DISK_ARGS prepare $osd_data 2>&1 | tee $DIR/out
|
||||
grep --quiet 'Is a directory' $DIR/out || return 1
|
||||
! [ -f $osd_data/magic ] || return 1
|
||||
rmdir $osd_data/fsid
|
||||
|
||||
echo successfully prepare the OSD
|
||||
|
||||
CEPH_ARGS="--fsid $uuid" \
|
||||
./ceph-disk $CEPH_DISK_ARGS prepare $osd_data 2>&1 | tee $DIR/out
|
||||
grep --quiet 'Preparing osd data dir' $DIR/out || return 1
|
||||
grep --quiet $uuid $osd_data/ceph_fsid || return 1
|
||||
[ -f $osd_data/magic ] || return 1
|
||||
|
||||
echo will not override an existing OSD
|
||||
|
||||
CEPH_ARGS="--fsid $(uuidgen)" \
|
||||
./ceph-disk $CEPH_DISK_ARGS prepare $osd_data 2>&1 | tee $DIR/out
|
||||
grep --quiet 'ceph-disk:Data dir .* already exists' $DIR/out || return 1
|
||||
grep --quiet $uuid $osd_data/ceph_fsid || return 1
|
||||
}
|
||||
|
||||
function test_activate_dir() {
|
||||
run_mon
|
||||
|
||||
local osd_data=$DIR/osd
|
||||
|
||||
./ceph-disk $CEPH_DISK_ARGS \
|
||||
prepare $osd_data || return 1
|
||||
|
||||
CEPH_ARGS="$CEPH_ARGS --osd-journal-size=100 --osd-data=$osd_data" \
|
||||
timeout 5 ./ceph-disk $CEPH_DISK_ARGS \
|
||||
activate \
|
||||
--mark-init=none \
|
||||
$osd_data || return 1
|
||||
timeout 5 ./ceph osd pool set data size 1 || return 1
|
||||
local id=$(cat $osd_data/whoami)
|
||||
local weight=1
|
||||
./ceph osd crush add osd.$id $weight root=default host=localhost || return 1
|
||||
echo FOO > $DIR/BAR
|
||||
timeout 10 ./rados --pool data put BAR $DIR/BAR || return 1
|
||||
timeout 10 ./rados --pool data get BAR $DIR/BAR.copy || return 1
|
||||
diff $DIR/BAR $DIR/BAR.copy || return 1
|
||||
}
|
||||
|
||||
function test_find_cluster_by_uuid() {
|
||||
setup
|
||||
test_activate_dir 2>&1 | tee $DIR/test_find
|
||||
! grep "No cluster conf found in $DIR" $DIR/test_find || return 1
|
||||
teardown
|
||||
|
||||
setup
|
||||
rm $DIR/ceph.conf
|
||||
test_activate_dir 2>&1 | tee $DIR/test_find
|
||||
grep "No cluster conf found in $DIR" $DIR/test_find || return 1
|
||||
teardown
|
||||
}
|
||||
|
||||
function run() {
|
||||
local default_actions
|
||||
default_actions+="test_path "
|
||||
default_actions+="test_find_cluster_by_uuid "
|
||||
default_actions+="test_prepend_to_path "
|
||||
default_actions+="test_activate_dir_magic "
|
||||
default_actions+="test_activate_dir "
|
||||
local actions=${@:-$default_actions}
|
||||
for action in $actions ; do
|
||||
setup
|
||||
$action || return 1
|
||||
teardown
|
||||
done
|
||||
}
|
||||
|
||||
run $@
|
||||
|
||||
# Local Variables:
|
||||
# compile-command: "cd .. ; test/ceph-disk.sh # test_activate_dir"
|
||||
# End:
|
Loading…
Reference in New Issue
Block a user