Merge "support Ceph's --dmcrypt flag for OSD preparation"

This commit is contained in:
Jenkins 2016-03-04 16:10:21 +00:00 committed by Gerrit Code Review
commit 2014a12c2b
5 changed files with 88 additions and 10 deletions

View File

@ -54,6 +54,16 @@ options:
Specifying this option (any value) forces a reformat of any OSD devices
found which are not already mounted.
osd-encrypt:
type: boolean
default: False
description: |
By default, the charm will not encrypt Ceph OSD devices; however, by
setting osd-encrypt to True, Ceph's dmcrypt support will be used to
encrypt OSD devices.
Specifying this option on a running Ceph OSD node will have no effect
until new disks are added, at which point new disks will be encrypted.
ignore-device-errors:
type: boolean
default: False
@ -137,7 +147,7 @@ options:
kernel.threads-max: 2097152 }'
description: |
YAML-formatted associative array of sysctl key/value pairs to be set
persistently. By default we set pid_max, max_map_count and
persistently. By default we set pid_max, max_map_count and
threads-max to a high value to avoid problems with large numbers (>20)
of OSDs recovering. very large clusters should set those values even
higher (e.g. max for kernel.pid_max is 4194303).

View File

@ -172,6 +172,7 @@ DISK_FORMATS = [
]
CEPH_PARTITIONS = [
'4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D', # ceph encrypted osd data
'4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D', # ceph osd data
'45B0969E-9B03-4F30-B4C6-B4B80CEFF106', # ceph osd journal
]
@ -428,15 +429,16 @@ def find_least_used_journal(journal_devices):
def osdize(dev, osd_format, osd_journal, reformat_osd=False,
ignore_errors=False):
ignore_errors=False, encrypt=False):
if dev.startswith('/dev'):
osdize_dev(dev, osd_format, osd_journal, reformat_osd, ignore_errors)
osdize_dev(dev, osd_format, osd_journal,
reformat_osd, ignore_errors, encrypt)
else:
osdize_dir(dev)
osdize_dir(dev, encrypt)
def osdize_dev(dev, osd_format, osd_journal, reformat_osd=False,
ignore_errors=False):
ignore_errors=False, encrypt=False):
if not os.path.exists(dev):
log('Path {} does not exist - bailing'.format(dev))
return
@ -457,6 +459,9 @@ def osdize_dev(dev, osd_format, osd_journal, reformat_osd=False,
status_set('maintenance', 'Initializing device {}'.format(dev))
cmd = ['ceph-disk', 'prepare']
# Later versions of ceph support more options
if cmp_pkgrevno('ceph', '0.60') >= 0:
if encrypt:
cmd.append('--dmcrypt')
if cmp_pkgrevno('ceph', '0.48.3') >= 0:
if osd_format:
cmd.append('--fs-type')
@ -485,7 +490,7 @@ def osdize_dev(dev, osd_format, osd_journal, reformat_osd=False,
raise e
def osdize_dir(path):
def osdize_dir(path, encrypt=False):
if os.path.exists(os.path.join(path, 'upstart')):
log('Path {} is already configured as an OSD - bailing'.format(path))
return
@ -504,6 +509,10 @@ def osdize_dir(path):
'--data-dir',
path
]
if cmp_pkgrevno('ceph', '0.60') >= 0:
if encrypt:
cmd.append('--dmcrypt')
log("osdize dir cmd: {}".format(cmd))
subprocess.check_call(cmd)

View File

@ -181,7 +181,8 @@ def prepare_disks_and_activate():
for dev in get_devices():
ceph.osdize(dev, config('osd-format'),
osd_journal, config('osd-reformat'),
config('ignore-device-errors'))
config('ignore-device-errors'),
config('osd-encrypt'))
ceph.start_osds(get_devices())

View File

@ -57,13 +57,13 @@ All examples are run from the charm's root directory.
bzr branch lp:charms/trusty/foo
cd foo
juju test -v -p AMULET_HTTP_PROXY 015-basic-trusty-icehouse
juju test -v -p AMULET_HTTP_PROXY --timeout 2700 015-basic-trusty-icehouse
* To run tests and keep the juju environment deployed after a failure:
bzr branch lp:charms/trusty/foo
cd foo
juju test --set-e -v -p AMULET_HTTP_PROXY 015-basic-trusty-icehouse
juju test --set-e -v -p AMULET_HTTP_PROXY --timeout 2700 015-basic-trusty-icehouse
* To re-run a test module against an already deployed environment (one
that was deployed by a previous call to 'juju test --set-e'):

View File

@ -182,7 +182,7 @@ class CephOsdBasicDeployment(OpenStackAmuletDeployment):
self.ceph0_sentry: ceph_processes,
self.ceph1_sentry: ceph_processes,
self.ceph2_sentry: ceph_processes,
self.ceph_osd_sentry: {'ceph-osd': 2}
self.ceph_osd_sentry: {'ceph-osd': True}
}
actual_pids = u.get_unit_process_ids(expected_processes)
@ -572,3 +572,61 @@ class CephOsdBasicDeployment(OpenStackAmuletDeployment):
# FYI: No restart check as ceph services do not restart
# when charm config changes, unless monitor count increases.
def test_900_ceph_encryption(self):
"""Verify that the new disk is added with encryption by checking for
Ceph's encryption keys directory"""
sentry = self.ceph_osd_sentry
set_default = {
'osd-encrypt': 'False',
'osd-devices': '/dev/vdb /srv/ceph',
}
set_alternate = {
'osd-encrypt': 'True',
'osd-devices': '/dev/vdb /srv/ceph /srv/ceph_encrypted',
}
juju_service = 'ceph-osd'
u.log.debug('Making config change on {}...'.format(juju_service))
mtime = u.get_sentry_time(sentry)
self.d.configure(juju_service, set_alternate)
unit_name = sentry.info['unit_name']
sleep_time = 30
retry_count = 30
file_mtime = None
time.sleep(sleep_time)
filename = '/etc/ceph/dmcrypt-keys'
tries = 0
retry_sleep_time = 10
while tries <= retry_count and not file_mtime:
try:
stat = sentry.directory_stat(filename)
file_mtime = stat['mtime']
self.log.debug('Attempt {} to get {} mtime on {} '
'OK'.format(tries, filename, unit_name))
except IOError as e:
self.d.configure(juju_service, set_default)
self.log.debug('Attempt {} to get {} mtime on {} '
'failed\n{}'.format(tries, filename,
unit_name, e))
time.sleep(retry_sleep_time)
tries += 1
self.d.configure(juju_service, set_default)
if not file_mtime:
self.log.warn('Could not determine mtime, assuming '
'folder does not exist')
return False
if file_mtime >= mtime:
self.log.debug('Folder mtime is newer than provided mtime '
'(%s >= %s) on %s (OK)' % (file_mtime,
mtime, unit_name))
return True
else:
self.log.warn('Folder mtime is older than provided mtime'
'(%s < on %s) on %s' % (file_mtime,
mtime, unit_name))
return False