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
|
import os
from cloudinit import importer
from cloudinit import log as logging
from cloudinit.constants import (PER_INSTANCE, PER_ALWAYS)
LOG = logging.getLogger(__name__)
def handler_register(mod, part_handlers, data, frequency=per_instance):
if not hasattr(mod, "handler_version"):
setattr(mod, "handler_version", 1)
for mtype in mod.list_types():
part_handlers[mtype] = mod
handler_call_begin(mod, data, frequency)
return(mod)
def handler_call_begin(mod, data, frequency):
handler_handle_part(mod, data, "__begin__", None, None, frequency)
def handler_call_end(mod, data, frequency):
handler_handle_part(mod, data, "__end__", None, None, frequency)
def handler_handle_part(mod, data, ctype, filename, payload, frequency):
# only add the handler if the module should run
modfreq = getattr(mod, "frequency", per_instance)
if not (modfreq == per_always or
(frequency == per_instance and modfreq == per_instance)):
return
try:
if mod.handler_version == 1:
mod.handle_part(data, ctype, filename, payload)
else:
mod.handle_part(data, ctype, filename, payload, frequency)
except:
util.logexc(log)
traceback.print_exc(file=sys.stderr)
def partwalker_handle_handler(pdata, _ctype, _filename, payload):
curcount = pdata['handlercount']
modname = 'part-handler-%03d' % curcount
frequency = pdata['frequency']
modfname = modname + ".py"
util.write_file("%s/%s" % (pdata['handlerdir'], modfname), payload, 0600)
try:
mod = __import__(modname)
handler_register(mod, pdata['handlers'], pdata['data'], frequency)
pdata['handlercount'] = curcount + 1
except:
util.logexc(log)
traceback.print_exc(file=sys.stderr)
def partwalker_callback(pdata, ctype, filename, payload):
# data here is the part_handlers array and then the data to pass through
if ctype == "text/part-handler":
if 'handlercount' not in pdata:
pdata['handlercount'] = 0
partwalker_handle_handler(pdata, ctype, filename, payload)
return
if ctype not in pdata['handlers']:
if ctype == "text/x-not-multipart":
# Extract the first line or 24 bytes for displaying in the log
start = payload.split("\n", 1)[0][:24]
if start < payload:
details = "starting '%s...'" % start.encode("string-escape")
else:
details = repr(payload)
log.warning("Unhandled non-multipart userdata %s", details)
return
handler_handle_part(pdata['handlers'][ctype], pdata['data'],
ctype, filename, payload, pdata['frequency'])
class InternalPartHandler:
freq = per_instance
mtypes = []
handler_version = 1
handler = None
def __init__(self, handler, mtypes, frequency, version=2):
self.handler = handler
self.mtypes = mtypes
self.frequency = frequency
self.handler_version = version
def __repr__(self):
return("InternalPartHandler: [%s]" % self.mtypes)
def list_types(self):
return(self.mtypes)
def handle_part(self, data, ctype, filename, payload, frequency):
return(self.handler(data, ctype, filename, payload, frequency))
|