~harlowja/cloud-init/ds-openstack

« back to all changes in this revision

Viewing changes to cloudinit/sources/DataSourceNoCloud.py

  • Committer: Joshua Harlow
  • Date: 2014-02-07 23:14:26 UTC
  • mfrom: (913.1.22 trunk)
  • Revision ID: harlowja@yahoo-inc.com-20140207231426-2natgf64l4o055du
Remerged with trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
50
50
        }
51
51
 
52
52
        found = []
53
 
        md = {}
54
 
        ud = ""
 
53
        mydata = {'meta-data': {}, 'user-data': "", 'vendor-data': ""}
55
54
 
56
55
        try:
57
56
            # Parse the kernel command line, getting data passed in
 
57
            md = {}
58
58
            if parse_cmdline_data(self.cmdline_id, md):
59
59
                found.append("cmdline")
 
60
            mydata.update(md)
60
61
        except:
61
62
            util.logexc(LOG, "Unable to parse command line data")
62
63
            return False
63
64
 
64
65
        # Check to see if the seed dir has data.
65
 
        seedret = {}
66
 
        if util.read_optional_seed(seedret, base=self.seed_dir + "/"):
67
 
            md = util.mergemanydict([md, seedret['meta-data']])
68
 
            ud = seedret['user-data']
 
66
        pp2d_kwargs = {'required': ['user-data', 'meta-data'],
 
67
                       'optional': ['vendor-data']}
 
68
 
 
69
        try:
 
70
            seeded = util.pathprefix2dict(self.seed_dir, **pp2d_kwargs)
69
71
            found.append(self.seed_dir)
70
 
            LOG.debug("Using seeded cache data from %s", self.seed_dir)
 
72
            LOG.debug("Using seeded data from %s", self.seed_dir)
 
73
        except ValueError as e:
 
74
            pass
 
75
 
 
76
        if self.seed_dir in found:
 
77
            mydata = _merge_new_seed(mydata, seeded)
71
78
 
72
79
        # If the datasource config had a 'seedfrom' entry, then that takes
73
80
        # precedence over a 'seedfrom' that was found in a filesystem
74
81
        # but not over external media
75
 
        if 'seedfrom' in self.ds_cfg and self.ds_cfg['seedfrom']:
 
82
        if self.ds_cfg.get('seedfrom'):
 
83
            found.append("ds_config_seedfrom")
 
84
            mydata['meta-data']["seedfrom"] = self.ds_cfg['seedfrom']
 
85
 
 
86
        # fields appropriately named can also just come from the datasource
 
87
        # config (ie, 'user-data', 'meta-data', 'vendor-data' there)
 
88
        if 'user-data' in self.ds_cfg and 'meta-data' in self.ds_cfg:
 
89
            mydata = _merge_new_seed(mydata, self.ds_cfg)
76
90
            found.append("ds_config")
77
 
            md["seedfrom"] = self.ds_cfg['seedfrom']
78
91
 
79
 
        # if ds_cfg has 'user-data' and 'meta-data'
80
 
        if 'user-data' in self.ds_cfg and 'meta-data' in self.ds_cfg:
81
 
            if self.ds_cfg['user-data']:
82
 
                ud = self.ds_cfg['user-data']
83
 
            if self.ds_cfg['meta-data'] is not False:
84
 
                md = util.mergemanydict([md, self.ds_cfg['meta-data']])
85
 
            if 'ds_config' not in found:
86
 
                found.append("ds_config")
 
92
        def _pp2d_callback(mp, data):
 
93
            util.pathprefix2dict(mp, **data)
87
94
 
88
95
        label = self.ds_cfg.get('fs_label', "cidata")
89
96
        if label is not None:
102
109
                try:
103
110
                    LOG.debug("Attempting to use data from %s", dev)
104
111
 
105
 
                    (newmd, newud) = util.mount_cb(dev, util.read_seeded)
106
 
                    md = util.mergemanydict([newmd, md])
107
 
                    ud = newud
 
112
                    try:
 
113
                        seeded = util.mount_cb(dev, _pp2d_callback)
 
114
                    except ValueError as e:
 
115
                        if dev in label_list:
 
116
                            LOG.warn("device %s with label=%s not a"
 
117
                                     "valid seed.", dev, label)
 
118
                        continue
 
119
 
 
120
                    mydata = _merge_new_seed(mydata, seeded)
108
121
 
109
122
                    # For seed from a device, the default mode is 'net'.
110
123
                    # that is more likely to be what is desired.  If they want
111
124
                    # dsmode of local, then they must specify that.
112
 
                    if 'dsmode' not in md:
113
 
                        md['dsmode'] = "net"
 
125
                    if 'dsmode' not in mydata['meta-data']:
 
126
                        mydata['meta-data'] = "net"
114
127
 
115
128
                    LOG.debug("Using data from %s", dev)
116
129
                    found.append(dev)
133
146
        # attempt to seed the userdata / metadata from its value
134
147
        # its primarily value is in allowing the user to type less
135
148
        # on the command line, ie: ds=nocloud;s=http://bit.ly/abcdefg
136
 
        if "seedfrom" in md:
137
 
            seedfrom = md["seedfrom"]
 
149
        if "seedfrom" in mydata['meta-data']:
 
150
            seedfrom = mydata['meta-data']["seedfrom"]
138
151
            seedfound = False
139
152
            for proto in self.supported_seed_starts:
140
153
                if seedfrom.startswith(proto):
144
157
                LOG.debug("Seed from %s not supported by %s", seedfrom, self)
145
158
                return False
146
159
 
147
 
            if 'network-interfaces' in md:
 
160
            if 'network-interfaces' in mydata['meta-data']:
148
161
                seeded_interfaces = self.dsmode
149
162
 
150
163
            # This could throw errors, but the user told us to do it
153
166
            LOG.debug("Using seeded cache data from %s", seedfrom)
154
167
 
155
168
            # Values in the command line override those from the seed
156
 
            md = util.mergemanydict([md, md_seed])
 
169
            mydata['meta-data'] = util.mergemanydict([mydata['meta-data'],
 
170
                                                      md_seed])
 
171
            mydata['user-data'] = ud
157
172
            found.append(seedfrom)
158
173
 
159
174
        # Now that we have exhausted any other places merge in the defaults
160
 
        md = util.mergemanydict([md, defaults])
 
175
        mydata['meta-data'] = util.mergemanydict([mydata['meta-data'],
 
176
                                                  defaults])
161
177
 
162
178
        # Update the network-interfaces if metadata had 'network-interfaces'
163
179
        # entry and this is the local datasource, or 'seedfrom' was used
164
180
        # and the source of the seed was self.dsmode
165
181
        # ('local' for NoCloud, 'net' for NoCloudNet')
166
 
        if ('network-interfaces' in md and
 
182
        if ('network-interfaces' in mydata['meta-data'] and
167
183
            (self.dsmode in ("local", seeded_interfaces))):
168
184
            LOG.debug("Updating network interfaces from %s", self)
169
 
            self.distro.apply_network(md['network-interfaces'])
 
185
            self.distro.apply_network(
 
186
                mydata['meta-data']['network-interfaces'])
170
187
 
171
 
        if md['dsmode'] == self.dsmode:
 
188
        if mydata['meta-data']['dsmode'] == self.dsmode:
172
189
            self.seed = ",".join(found)
173
 
            self.metadata = md
174
 
            self.userdata_raw = ud
 
190
            self.metadata = mydata['meta-data']
 
191
            self.userdata_raw = mydata['user-data']
 
192
            self.vendordata = mydata['vendor-data']
175
193
            return True
176
194
 
177
195
        LOG.debug("%s: not claiming datasource, dsmode=%s", self, md['dsmode'])
222
240
    return True
223
241
 
224
242
 
 
243
def _merge_new_seed(cur, seeded):
 
244
    ret = cur.copy()
 
245
    ret['meta-data'] = util.mergemanydict([cur['meta-data'],
 
246
                                          util.load_yaml(seeded['meta-data'])])
 
247
    ret['user-data'] = seeded['user-data']
 
248
    if 'vendor-data' in seeded:
 
249
        ret['vendor-data'] = seeded['vendor-data']
 
250
    return ret
 
251
 
 
252
 
225
253
class DataSourceNoCloudNet(DataSourceNoCloud):
226
254
    def __init__(self, sys_cfg, distro, paths):
227
255
        DataSourceNoCloud.__init__(self, sys_cfg, distro, paths)