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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188 | === modified file 'bin/cloud-init'
--- bin/cloud-init 2016-03-22 02:31:15 +0000
+++ bin/cloud-init 2016-03-22 05:56:36 +0000
@@ -263,6 +263,17 @@
return (None, [])
else:
return (None, ["No instance datasource found."])
+
+ if args.local:
+ init.apply_networking()
+
+ if args.local and init.is_transfer():
+ init.store_transfer()
+ return (init.datasource, [])
+ elif init.is_transfer():
+ raise Exception("Transfer datasource returned in network search: %s",
+ init.datasource)
+
# Stage 6
iid = init.instancify()
LOG.debug("%s will now be targeting instance id: %s", name, iid)
=== modified file 'cloudinit/helpers.py'
--- cloudinit/helpers.py 2016-03-04 06:45:58 +0000
+++ cloudinit/helpers.py 2016-03-22 05:10:27 +0000
@@ -335,6 +335,9 @@
# This one isn't joined, since it should just be read-only
template_dir = path_cfgs.get('templates_dir', '/etc/cloud/templates/')
self.template_tpl = os.path.join(template_dir, '%s.tmpl')
+ self.run_dir = path_cfgs.get('run', '/run/cloud-init')
+ self.local_transfer_dir = os.path.join(self.run_dir, ".ltransfer")
+
self.lookups = {
"handlers": "handlers",
"scripts": "scripts",
=== modified file 'cloudinit/stages.py'
--- cloudinit/stages.py 2016-03-22 01:47:24 +0000
+++ cloudinit/stages.py 2016-03-22 06:25:02 +0000
@@ -42,6 +42,7 @@
from cloudinit import distros
from cloudinit import helpers
from cloudinit import importer
+from cloudinit import net
from cloudinit import log as logging
from cloudinit import sources
from cloudinit import type_utils
@@ -193,40 +194,12 @@
# We try to restore from a current link and static path
# by using the instance link, if purge_cache was called
# the file wont exist.
- pickled_fn = self.paths.get_ipath_cur('obj_pkl')
- pickle_contents = None
- try:
- pickle_contents = util.load_file(pickled_fn, decode=False)
- except Exception as e:
- if os.path.isfile(pickled_fn):
- LOG.warn("failed loading pickle in %s: %s" % (pickled_fn, e))
- pass
-
- # This is expected so just return nothing
- # successfully loaded...
- if not pickle_contents:
- return None
- try:
- return pickle.loads(pickle_contents)
- except Exception:
- util.logexc(LOG, "Failed loading pickled blob from %s", pickled_fn)
- return None
+ return _pkl_load(self.paths.get_ipath_cur('obj_pkl'))
def _write_to_cache(self):
if self.datasource is NULL_DATA_SOURCE:
return False
- pickled_fn = self.paths.get_ipath_cur("obj_pkl")
- try:
- pk_contents = pickle.dumps(self.datasource)
- except Exception:
- util.logexc(LOG, "Failed pickling datasource %s", self.datasource)
- return False
- try:
- util.write_file(pickled_fn, pk_contents, omode="wb", mode=0o400)
- except Exception:
- util.logexc(LOG, "Failed pickling datasource to %s", pickled_fn)
- return False
- return True
+ return _pkl_store(self.datasource, self.paths.get_ipath_cur("obj_pkl"))
def _get_datasources(self):
# Any config provided???
@@ -341,7 +314,11 @@
return iid
def fetch(self, existing="check"):
- return self._get_data_source(existing=existing)
+ transfer_pkl = os.path.join(self.paths.local_transfer_dir, "ds.pkl")
+ if os.path.exists(transfer_pkl):
+ return self.un_transfer(transfer_pkl)
+ else:
+ return self._get_data_source(existing=existing)
def instancify(self):
return self._reflect_cur_instance()
@@ -595,6 +572,47 @@
# Run the handlers
self._do_handlers(user_data_msg, c_handlers_list, frequency)
+ def store_transfer(self)
+ transfer_pkl = os.path.join(self.paths.local_transfer_dir, "ds.pkl")
+ return _pkl_store(self.datasource, transfer_pkl)
+
+ def un_transfer(self, fname):
+ tranobj = _pkl_load(fname)
+ if not tranobj:
+ raise RuntimeError("failed to load untransfer pkl from %s" % fname)
+ self.datasource = tranobj
+ tranobj.un_transfer()
+ self._reset()
+
+ def is_transfer(self):
+ if hasattr(self.datasource, 'is_transfer')
+ return self.datasource.is_transfer()
+ return False
+
+ def find_networking_config(self)
+ cmdline_cfg = ('cmdline', net.read_cmdline_cfg())
+ dscfg = ('ds', None)
+ if self.datasource and hasattr(self.datasource, 'network_config'):
+ dscfg = ('ds', self.datasource.network_config)
+ sys_cfg = ('system_cfg', self.cfg.get('network'))
+
+ for loc, ncfg in (cmdline_cfg, dscfg, sys_cfg):
+ if net.is_disabled_cfg(ncfg)
+ LOG.debug("network config disabled by %s", loc)
+ return None
+ if ncfg:
+ return ncfg
+ return net.fallback_config()
+
+
+ def apply_networking(self):
+ netcfg = self.find_networking_config()
+ if netcfg is None:
+ LOG.info("network config is disabled")
+ return
+
+ return self.distro.apply_networking(networking_config)
+
class Modules(object):
def __init__(self, init, cfg_files=None, reporter=None):
@@ -796,3 +814,36 @@
base_cfgs.append(default_cfg)
return util.mergemanydict(base_cfgs)
+
+
+def _pkl_store(obj, fname):
+ try:
+ pk_contents = pickle.dumps(obj)
+ except Exception:
+ util.logexc(LOG, "Failed pickling datasource %s", obj)
+ return False
+ try:
+ util.write_file(fname, pk_contents, omode="wb", mode=0o400)
+ except Exception:
+ util.logexc(LOG, "Failed pickling datasource to %s", fname)
+ return False
+ return True
+
+
+def _pkl_load(fname):
+ pickle_contents = None
+ try:
+ pickle_contents = util.load_file(fname, decode=False)
+ except Exception as e:
+ if os.path.isfile(fname):
+ LOG.warn("failed loading pickle in %s: %s" % (fname, e))
+ pass
+
+ # This is allowed so just return nothing successfully loaded...
+ if not pickle_contents:
+ return None
+ try:
+ return pickle.loads(pickle_contents)
+ except Exception:
+ util.logexc(LOG, "Failed loading pickled blob from %s", fname)
+ return None
|