~openstack-charmers/charms/trusty/ceph/next

« back to all changes in this revision

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

  • Committer: Edward Hope-Morley
  • Date: 2016-05-25 14:54:08 UTC
  • Revision ID: edward.hope-morley@canonical.com-20160525145408-rv2k9asnopo5404g
Add support for user-provided ceph config

Adds a new config-flags option to the charm that
supports setting a dictionary of ceph configuration
settings that will be applied to ceph.conf.

This implementation supports config sections so that
settings can be applied to any section supported by
the ceph.conf template in the charm.

Change-Id: I5ed2530b1e06a4565029d62124b469b97e17d342
Closes-Bug: 1522375

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2014-2015 Canonical Limited.
 
2
#
 
3
# This file is part of charm-helpers.
 
4
#
 
5
# charm-helpers is free software: you can redistribute it and/or modify
 
6
# it under the terms of the GNU Lesser General Public License version 3 as
 
7
# published by the Free Software Foundation.
 
8
#
 
9
# charm-helpers is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
# GNU Lesser General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU Lesser General Public License
 
15
# along with charm-helpers.  If not, see <http://www.gnu.org/licenses/>.
 
16
 
 
17
import os
 
18
import re
 
19
from subprocess import (
 
20
    check_call,
 
21
    check_output,
 
22
)
 
23
 
 
24
import six
 
25
 
 
26
 
 
27
##################################################
 
28
# loopback device helpers.
 
29
##################################################
 
30
def loopback_devices():
 
31
    '''
 
32
    Parse through 'losetup -a' output to determine currently mapped
 
33
    loopback devices. Output is expected to look like:
 
34
 
 
35
        /dev/loop0: [0807]:961814 (/tmp/my.img)
 
36
 
 
37
    :returns: dict: a dict mapping {loopback_dev: backing_file}
 
38
    '''
 
39
    loopbacks = {}
 
40
    cmd = ['losetup', '-a']
 
41
    devs = [d.strip().split(' ') for d in
 
42
            check_output(cmd).splitlines() if d != '']
 
43
    for dev, _, f in devs:
 
44
        loopbacks[dev.replace(':', '')] = re.search('\((\S+)\)', f).groups()[0]
 
45
    return loopbacks
 
46
 
 
47
 
 
48
def create_loopback(file_path):
 
49
    '''
 
50
    Create a loopback device for a given backing file.
 
51
 
 
52
    :returns: str: Full path to new loopback device (eg, /dev/loop0)
 
53
    '''
 
54
    file_path = os.path.abspath(file_path)
 
55
    check_call(['losetup', '--find', file_path])
 
56
    for d, f in six.iteritems(loopback_devices()):
 
57
        if f == file_path:
 
58
            return d
 
59
 
 
60
 
 
61
def ensure_loopback_device(path, size):
 
62
    '''
 
63
    Ensure a loopback device exists for a given backing file path and size.
 
64
    If it a loopback device is not mapped to file, a new one will be created.
 
65
 
 
66
    TODO: Confirm size of found loopback device.
 
67
 
 
68
    :returns: str: Full path to the ensured loopback device (eg, /dev/loop0)
 
69
    '''
 
70
    for d, f in six.iteritems(loopback_devices()):
 
71
        if f == path:
 
72
            return d
 
73
 
 
74
    if not os.path.exists(path):
 
75
        cmd = ['truncate', '--size', size, path]
 
76
        check_call(cmd)
 
77
 
 
78
    return create_loopback(path)
 
79
 
 
80
 
 
81
def is_mapped_loopback_device(device):
 
82
    """
 
83
    Checks if a given device name is an existing/mapped loopback device.
 
84
    :param device: str: Full path to the device (eg, /dev/loop1).
 
85
    :returns: str: Path to the backing file if is a loopback device
 
86
    empty string otherwise
 
87
    """
 
88
    return loopback_devices().get(device, "")