Merge "support Ceph's --dmcrypt flag for OSD preparation"
This commit is contained in:
commit
2014a12c2b
12
config.yaml
12
config.yaml
|
@ -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).
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
||||
|
|
|
@ -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'):
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue