~ubuntu-branches/ubuntu/saucy/cloud-init/saucy

« back to all changes in this revision

Viewing changes to cloudinit/config/cc_mounts.py

  • Committer: Scott Moser
  • Date: 2013-10-05 01:08:03 UTC
  • mfrom: (1.4.8)
  • Revision ID: smoser@ubuntu.com-20131005010803-8mdenwz6q7pwwo74
* New upstream snapshot.
  * allow disabling of growpart via file /etc/growroot-disabled
    (LP: #1234331)
  * add default user to sudo group (LP: #1228228)
  * fix disk creation on azure (LP: #1233698)
  * DatasourceSmartOS: allow availabiltity-zone to be fed from the
    datasource via 'region' (which allows 'mirrors' and other things
    to make use of it).

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
 
21
21
from string import whitespace  # pylint: disable=W0402
22
22
 
 
23
import logging
 
24
import os.path
23
25
import re
24
26
 
25
27
from cloudinit import type_utils
31
33
WS = re.compile("[%s]+" % (whitespace))
32
34
FSTAB_PATH = "/etc/fstab"
33
35
 
 
36
LOG = logging.getLogger(__name__)
 
37
 
34
38
 
35
39
def is_mdname(name):
36
40
    # return true if this is a metadata service name
44
48
    return False
45
49
 
46
50
 
 
51
def sanitize_devname(startname, transformer, log):
 
52
    log.debug("Attempting to determine the real name of %s", startname)
 
53
 
 
54
    # workaround, allow user to specify 'ephemeral'
 
55
    # rather than more ec2 correct 'ephemeral0'
 
56
    devname = startname
 
57
    if devname == "ephemeral":
 
58
        devname = "ephemeral0"
 
59
        log.debug("Adjusted mount option from ephemeral to ephemeral0")
 
60
 
 
61
    (blockdev, part) = util.expand_dotted_devname(devname)
 
62
 
 
63
    if is_mdname(blockdev):
 
64
        orig = blockdev
 
65
        blockdev = transformer(blockdev)
 
66
        if not blockdev:
 
67
            return None
 
68
        if not blockdev.startswith("/"):
 
69
            blockdev = "/dev/%s" % blockdev
 
70
        log.debug("Mapped metadata name %s to %s", orig, blockdev)
 
71
    else:
 
72
        if SHORTNAME.match(startname):
 
73
            blockdev = "/dev/%s" % blockdev
 
74
 
 
75
    return devnode_for_dev_part(blockdev, part)
 
76
 
 
77
 
47
78
def handle(_name, cfg, cloud, log, _args):
48
79
    # fs_spec, fs_file, fs_vfstype, fs_mntops, fs-freq, fs_passno
49
80
    defvals = [None, None, "auto", "defaults,nobootwait", "0", "2"]
64
95
                     (i + 1), type_utils.obj_name(cfgmnt[i]))
65
96
            continue
66
97
 
67
 
        startname = str(cfgmnt[i][0])
68
 
        log.debug("Attempting to determine the real name of %s", startname)
69
 
 
70
 
        # workaround, allow user to specify 'ephemeral'
71
 
        # rather than more ec2 correct 'ephemeral0'
72
 
        if startname == "ephemeral":
73
 
            cfgmnt[i][0] = "ephemeral0"
74
 
            log.debug(("Adjusted mount option %s "
75
 
                       "name from ephemeral to ephemeral0"), (i + 1))
76
 
 
77
 
        if is_mdname(startname):
78
 
            newname = cloud.device_name_to_device(startname)
79
 
            if not newname:
80
 
                log.debug("Ignoring nonexistant named mount %s", startname)
81
 
                cfgmnt[i][1] = None
82
 
            else:
83
 
                renamed = newname
84
 
                if not newname.startswith("/"):
85
 
                    renamed = "/dev/%s" % newname
86
 
                cfgmnt[i][0] = renamed
87
 
                log.debug("Mapped metadata name %s to %s", startname, renamed)
88
 
        else:
89
 
            if SHORTNAME.match(startname):
90
 
                renamed = "/dev/%s" % startname
91
 
                log.debug("Mapped shortname name %s to %s", startname, renamed)
92
 
                cfgmnt[i][0] = renamed
 
98
        start = str(cfgmnt[i][0])
 
99
        sanitized = sanitize_devname(start, cloud.device_name_to_device, log)
 
100
        if sanitized is None:
 
101
            log.debug("Ignorming nonexistant named mount %s", start)
 
102
            continue
 
103
 
 
104
        if sanitized != start:
 
105
            log.debug("changed %s => %s" % (start, sanitized))
 
106
        cfgmnt[i][0] = sanitized
93
107
 
94
108
        # in case the user did not quote a field (likely fs-freq, fs_passno)
95
109
        # but do not convert None to 'None' (LP: #898365)
118
132
    # for each of the "default" mounts, add them only if no other
119
133
    # entry has the same device name
120
134
    for defmnt in defmnts:
121
 
        startname = defmnt[0]
122
 
        devname = cloud.device_name_to_device(startname)
123
 
        if devname is None:
124
 
            log.debug("Ignoring nonexistant named default mount %s", startname)
 
135
        start = defmnt[0]
 
136
        sanitized = sanitize_devname(start, cloud.device_name_to_device, log)
 
137
        if sanitized is None:
 
138
            log.debug("Ignoring nonexistant default named mount %s", start)
125
139
            continue
126
 
        if devname.startswith("/"):
127
 
            defmnt[0] = devname
128
 
        else:
129
 
            defmnt[0] = "/dev/%s" % devname
130
 
 
131
 
        log.debug("Mapped default device %s to %s", startname, defmnt[0])
 
140
        if sanitized != start:
 
141
            log.debug("changed default device %s => %s" % (start, sanitized))
 
142
        defmnt[0] = sanitized
132
143
 
133
144
        cfgmnt_has = False
134
145
        for cfgm in cfgmnt:
138
149
 
139
150
        if cfgmnt_has:
140
151
            log.debug(("Not including %s, already"
141
 
                       " previously included"), startname)
 
152
                       " previously included"), start)
142
153
            continue
143
154
        cfgmnt.append(defmnt)
144
155
 
198
209
        util.subp(("mount", "-a"))
199
210
    except:
200
211
        util.logexc(log, "Activating mounts via 'mount -a' failed")
 
212
 
 
213
 
 
214
def devnode_for_dev_part(device, partition):
 
215
    """
 
216
    Find the name of the partition. While this might seem rather
 
217
    straight forward, its not since some devices are '<device><partition>'
 
218
    while others are '<device>p<partition>'. For example, /dev/xvda3 on EC2
 
219
    will present as /dev/xvda3p1 for the first partition since /dev/xvda3 is
 
220
    a block device.
 
221
    """
 
222
    if not os.path.exists(device):
 
223
        return None
 
224
 
 
225
    if not partition:
 
226
        return device
 
227
 
 
228
    short_name = os.path.basename(device)
 
229
    sys_path = "/sys/block/%s" % short_name
 
230
 
 
231
    if not os.path.exists(sys_path):
 
232
        LOG.debug("did not find entry for %s in /sys/block", short_name)
 
233
        return None
 
234
 
 
235
    sys_long_path = sys_path + "/" + short_name
 
236
 
 
237
    if partition is not None:
 
238
        partition = str(partition)
 
239
 
 
240
    if partition is None:
 
241
        valid_mappings = [sys_long_path + "1",
 
242
                          sys_long_path + "p1" % partition]
 
243
    elif partition != "0":
 
244
        valid_mappings = [sys_long_path + "%s" % partition,
 
245
                          sys_long_path + "p%s" % partition]
 
246
    else:
 
247
        valid_mappings = []
 
248
 
 
249
    for cdisk in valid_mappings:
 
250
        if not os.path.exists(cdisk):
 
251
            continue
 
252
 
 
253
        dev_path = "/dev/%s" % os.path.basename(cdisk)
 
254
        if os.path.exists(dev_path):
 
255
            return dev_path
 
256
 
 
257
    if partition is None or partition == "0":
 
258
        return device
 
259
 
 
260
    LOG.debug("Did not fine partition %s for device %s", partition, device)
 
261
    return None