~landscape/charms/precise/storage/multiple-units

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/python
import json

import common_util
import sys
import yaml
from yaml.constructor import ConstructorError
from charmhelpers.core import hookenv


instance_id = common_util.get_instance_id()
availability_zone = common_util.get_availability_zone()
config_data = hookenv.config()
volume_size = config_data.get("volume_size", None)
volume_map = config_data.get("volume_map", None)
volume_id = None
label = None
relids = hookenv.relation_ids("data")
for relid in relids:
    for unit in hookenv.related_units(relid):
        label = config_data.get("volume_label", None)
        if not label:
            label = "%s %s volume" % (unit, availability_zone)
        if volume_map is not None:
            # Grab the volume_label for our instance if it exists so we can
            # request that volume-id from the block-storage-broker
            try:
                volume_map = yaml.load(volume_map)
                if volume_map:
                    volume_id = volume_map.get(unit, None)
            except ConstructorError as e:
                hookenv.log(
                    "invalid YAML in 'volume-map': {}".format(e),
                    hookenv.WARNING)

if label is None:
    hookenv.log(
        "No data-relation-changed hook fired. Awaiting data-relation before "
        "updating block-storage-broker relation")
    sys.exit(0)

relation_type = hookenv.relation_type()
if relation_type == "block-storage":
    relation_settings = {"instance-id": instance_id, "size": volume_size,
                         "volume-label": label}
    if volume_id is not None:
        relation_settings["volume-id"] = volume_id
    hookenv.relation_set(relation_settings=relation_settings)

# Grab info from the block-storage relation regardless of whether we are in the
# data relation
device_path = common_util._get_from_relation(
    "block-storage", "block-device-path")

# Get the device path from block-device-path-map if it exists, since
# that works when multiple storage units exist. Older version of the
# block-storage-broker charm doesn't set it, though.
device_path_map = common_util._get_from_relation(
    "block-storage", "block-device-path-map")
if device_path_map is not None:
    device_path_map = json.loads(device_path_map)
    hookenv.log(
        "Getting device_path from block-device-path-map. " +
        repr(device_path_map))
    device_path = device_path_map.get(instance_id)

# Don't try to mount the volume before we set the instance id and the
# block-storage-broker service gives us back the device path, indicating
# that the volume has been attached.
if not device_path:
    hookenv.log("No block-device specified yet.")
    sys.exit(0)

common_util.mount_volume(device_path,  # Will wait for mountpoint
                         device_timeout=config_data.get('device_timeout'))