~openstack-charmers-next/charms/xenial/nova-compute/trunk

« back to all changes in this revision

Viewing changes to hooks/charmhelpers/contrib/storage/linux/ceph.py

  • Committer: Edward Hope-Morley
  • Date: 2016-03-24 11:18:41 UTC
  • mto: This revision was merged to the branch mainline in revision 211.
  • Revision ID: edward.hope-morley@canonical.com-20160324111841-99ruo5hjzrpqktlx
Add hardening support

Add charmhelpers.contrib.hardening and calls to install,
config-changed, upgrade-charm and update-status hooks.
Also add new config option to allow one or more hardening
modules to be applied at runtime.

Change-Id: I525c15a14662175f2a68cdcd25a3ab2c92237850

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#  Adam Gandelman <adamg@ubuntu.com>
25
25
#
26
26
import bisect
 
27
import errno
 
28
import hashlib
27
29
import six
28
30
 
29
31
import os
163
165
        :return: None
164
166
        """
165
167
        # read-only is easy, writeback is much harder
166
 
        mode = get_cache_mode(cache_pool)
 
168
        mode = get_cache_mode(self.service, cache_pool)
167
169
        if mode == 'readonly':
168
170
            check_call(['ceph', '--id', self.service, 'osd', 'tier', 'cache-mode', cache_pool, 'none'])
169
171
            check_call(['ceph', '--id', self.service, 'osd', 'tier', 'remove', self.name, cache_pool])
171
173
        elif mode == 'writeback':
172
174
            check_call(['ceph', '--id', self.service, 'osd', 'tier', 'cache-mode', cache_pool, 'forward'])
173
175
            # Flush the cache and wait for it to return
174
 
            check_call(['ceph', '--id', self.service, '-p', cache_pool, 'cache-flush-evict-all'])
 
176
            check_call(['rados', '--id', self.service, '-p', cache_pool, 'cache-flush-evict-all'])
175
177
            check_call(['ceph', '--id', self.service, 'osd', 'tier', 'remove-overlay', self.name])
176
178
            check_call(['ceph', '--id', self.service, 'osd', 'tier', 'remove', self.name, cache_pool])
177
179
 
259
261
       Returns json formatted output"""
260
262
 
261
263
 
 
264
def get_mon_map(service):
 
265
    """
 
266
    Returns the current monitor map.
 
267
    :param service: six.string_types. The Ceph user name to run the command under
 
268
    :return: json string. :raise: ValueError if the monmap fails to parse.
 
269
      Also raises CalledProcessError if our ceph command fails
 
270
    """
 
271
    try:
 
272
        mon_status = check_output(
 
273
            ['ceph', '--id', service,
 
274
             'mon_status', '--format=json'])
 
275
        try:
 
276
            return json.loads(mon_status)
 
277
        except ValueError as v:
 
278
            log("Unable to parse mon_status json: {}. Error: {}".format(
 
279
                mon_status, v.message))
 
280
            raise
 
281
    except CalledProcessError as e:
 
282
        log("mon_status command failed with message: {}".format(
 
283
            e.message))
 
284
        raise
 
285
 
 
286
 
 
287
def hash_monitor_names(service):
 
288
    """
 
289
    Uses the get_mon_map() function to get information about the monitor
 
290
    cluster.
 
291
    Hash the name of each monitor.  Return a sorted list of monitor hashes
 
292
    in an ascending order.
 
293
    :param service: six.string_types. The Ceph user name to run the command under
 
294
    :rtype : dict.   json dict of monitor name, ip address and rank
 
295
    example: {
 
296
        'name': 'ip-172-31-13-165',
 
297
        'rank': 0,
 
298
        'addr': '172.31.13.165:6789/0'}
 
299
    """
 
300
    try:
 
301
        hash_list = []
 
302
        monitor_list = get_mon_map(service=service)
 
303
        if monitor_list['monmap']['mons']:
 
304
            for mon in monitor_list['monmap']['mons']:
 
305
                hash_list.append(
 
306
                    hashlib.sha224(mon['name'].encode('utf-8')).hexdigest())
 
307
            return sorted(hash_list)
 
308
        else:
 
309
            return None
 
310
    except (ValueError, CalledProcessError):
 
311
        raise
 
312
 
 
313
 
 
314
def monitor_key_delete(service, key):
 
315
    """
 
316
    Delete a key and value pair from the monitor cluster
 
317
    :param service: six.string_types. The Ceph user name to run the command under
 
318
    Deletes a key value pair on the monitor cluster.
 
319
    :param key: six.string_types.  The key to delete.
 
320
    """
 
321
    try:
 
322
        check_output(
 
323
            ['ceph', '--id', service,
 
324
             'config-key', 'del', str(key)])
 
325
    except CalledProcessError as e:
 
326
        log("Monitor config-key put failed with message: {}".format(
 
327
            e.output))
 
328
        raise
 
329
 
 
330
 
 
331
def monitor_key_set(service, key, value):
 
332
    """
 
333
    Sets a key value pair on the monitor cluster.
 
334
    :param service: six.string_types. The Ceph user name to run the command under
 
335
    :param key: six.string_types.  The key to set.
 
336
    :param value: The value to set.  This will be converted to a string
 
337
        before setting
 
338
    """
 
339
    try:
 
340
        check_output(
 
341
            ['ceph', '--id', service,
 
342
             'config-key', 'put', str(key), str(value)])
 
343
    except CalledProcessError as e:
 
344
        log("Monitor config-key put failed with message: {}".format(
 
345
            e.output))
 
346
        raise
 
347
 
 
348
 
 
349
def monitor_key_get(service, key):
 
350
    """
 
351
    Gets the value of an existing key in the monitor cluster.
 
352
    :param service: six.string_types. The Ceph user name to run the command under
 
353
    :param key: six.string_types.  The key to search for.
 
354
    :return: Returns the value of that key or None if not found.
 
355
    """
 
356
    try:
 
357
        output = check_output(
 
358
            ['ceph', '--id', service,
 
359
             'config-key', 'get', str(key)])
 
360
        return output
 
361
    except CalledProcessError as e:
 
362
        log("Monitor config-key get failed with message: {}".format(
 
363
            e.output))
 
364
        return None
 
365
 
 
366
 
 
367
def monitor_key_exists(service, key):
 
368
    """
 
369
    Searches for the existence of a key in the monitor cluster.
 
370
    :param service: six.string_types. The Ceph user name to run the command under
 
371
    :param key: six.string_types.  The key to search for
 
372
    :return: Returns True if the key exists, False if not and raises an
 
373
     exception if an unknown error occurs. :raise: CalledProcessError if
 
374
     an unknown error occurs
 
375
    """
 
376
    try:
 
377
        check_call(
 
378
            ['ceph', '--id', service,
 
379
             'config-key', 'exists', str(key)])
 
380
        # I can return true here regardless because Ceph returns
 
381
        # ENOENT if the key wasn't found
 
382
        return True
 
383
    except CalledProcessError as e:
 
384
        if e.returncode == errno.ENOENT:
 
385
            return False
 
386
        else:
 
387
            log("Unknown error from ceph config-get exists: {} {}".format(
 
388
                e.returncode, e.output))
 
389
            raise
 
390
 
 
391
 
262
392
def get_erasure_profile(service, name):
263
393
    """
264
394
    :param service: six.string_types. The Ceph user name to run the command under