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

« back to all changes in this revision

Viewing changes to cloudinit/handlers/__init__.py

  • Committer: Scott Moser
  • Date: 2013-03-07 22:26:14 UTC
  • mto: (1.3.1) (245.2.5 raring)
  • mto: This revision was merged to the branch mainline in revision 246.
  • Revision ID: smoser@ubuntu.com-20130307222614-uol8g3za9u8q4958
Tags: upstream-0.7.2~bzr795
ImportĀ upstreamĀ versionĀ 0.7.2~bzr795

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
from cloudinit import importer
29
29
from cloudinit import log as logging
 
30
from cloudinit import type_utils
30
31
from cloudinit import util
31
32
 
32
33
LOG = logging.getLogger(__name__)
69
70
 
70
71
 
71
72
class Handler(object):
72
 
 
73
73
    __metaclass__ = abc.ABCMeta
74
74
 
75
75
    def __init__(self, frequency, version=2):
77
77
        self.frequency = frequency
78
78
 
79
79
    def __repr__(self):
80
 
        return "%s: [%s]" % (util.obj_name(self), self.list_types())
 
80
        return "%s: [%s]" % (type_utils.obj_name(self), self.list_types())
81
81
 
82
82
    @abc.abstractmethod
83
83
    def list_types(self):
84
84
        raise NotImplementedError()
85
85
 
86
 
    def handle_part(self, data, ctype, filename, payload, frequency):
87
 
        return self._handle_part(data, ctype, filename, payload, frequency)
88
 
 
89
86
    @abc.abstractmethod
90
 
    def _handle_part(self, data, ctype, filename, payload, frequency):
 
87
    def handle_part(self, *args, **kwargs):
91
88
        raise NotImplementedError()
92
89
 
93
90
 
94
 
def run_part(mod, data, ctype, filename, payload, frequency):
 
91
def run_part(mod, data, filename, payload, frequency, headers):
95
92
    mod_freq = mod.frequency
96
93
    if not (mod_freq == PER_ALWAYS or
97
94
            (frequency == PER_INSTANCE and mod_freq == PER_INSTANCE)):
98
95
        return
99
 
    mod_ver = mod.handler_version
100
96
    # Sanity checks on version (should be an int convertable)
101
97
    try:
 
98
        mod_ver = mod.handler_version
102
99
        mod_ver = int(mod_ver)
103
 
    except:
 
100
    except (TypeError, ValueError, AttributeError):
104
101
        mod_ver = 1
 
102
    content_type = headers['Content-Type']
105
103
    try:
106
104
        LOG.debug("Calling handler %s (%s, %s, %s) with frequency %s",
107
 
                  mod, ctype, filename, mod_ver, frequency)
108
 
        if mod_ver >= 2:
 
105
                  mod, content_type, filename, mod_ver, frequency)
 
106
        if mod_ver == 3:
 
107
            # Treat as v. 3 which does get a frequency + headers
 
108
            mod.handle_part(data, content_type, filename,
 
109
                            payload, frequency, headers)
 
110
        elif mod_ver == 2:
109
111
            # Treat as v. 2 which does get a frequency
110
 
            mod.handle_part(data, ctype, filename, payload, frequency)
111
 
        else:
 
112
            mod.handle_part(data, content_type, filename,
 
113
                            payload, frequency)
 
114
        elif mod_ver == 1:
112
115
            # Treat as v. 1 which gets no frequency
113
 
            mod.handle_part(data, ctype, filename, payload)
 
116
            mod.handle_part(data, content_type, filename, payload)
 
117
        else:
 
118
            raise ValueError("Unknown module version %s" % (mod_ver))
114
119
    except:
115
120
        util.logexc(LOG, ("Failed calling handler %s (%s, %s, %s)"
116
121
                         " with frequency %s"),
117
 
                    mod, ctype, filename,
 
122
                    mod, content_type, filename,
118
123
                    mod_ver, frequency)
119
124
 
120
125
 
121
126
def call_begin(mod, data, frequency):
122
 
    run_part(mod, data, CONTENT_START, None, None, frequency)
 
127
    # Create a fake header set
 
128
    headers = {
 
129
        'Content-Type': CONTENT_START,
 
130
    }
 
131
    run_part(mod, data, None, None, frequency, headers)
123
132
 
124
133
 
125
134
def call_end(mod, data, frequency):
126
 
    run_part(mod, data, CONTENT_END, None, None, frequency)
 
135
    # Create a fake header set
 
136
    headers = {
 
137
        'Content-Type': CONTENT_END,
 
138
    }
 
139
    run_part(mod, data, None, None, frequency, headers)
127
140
 
128
141
 
129
142
def walker_handle_handler(pdata, _ctype, _filename, payload):
173
186
    return text
174
187
 
175
188
 
176
 
def walker_callback(pdata, ctype, filename, payload):
177
 
    if ctype in PART_CONTENT_TYPES:
178
 
        walker_handle_handler(pdata, ctype, filename, payload)
 
189
def walker_callback(data, filename, payload, headers):
 
190
    content_type = headers['Content-Type']
 
191
    if content_type in PART_CONTENT_TYPES:
 
192
        walker_handle_handler(data, content_type, filename, payload)
179
193
        return
180
 
    handlers = pdata['handlers']
181
 
    if ctype in pdata['handlers']:
182
 
        run_part(handlers[ctype], pdata['data'], ctype, filename,
183
 
                 payload, pdata['frequency'])
 
194
    handlers = data['handlers']
 
195
    if content_type in handlers:
 
196
        run_part(handlers[content_type], data['data'], filename,
 
197
                 payload, data['frequency'], headers)
184
198
    elif payload:
185
199
        # Extract the first line or 24 bytes for displaying in the log
186
200
        start = _extract_first_or_bytes(payload, 24)
187
201
        details = "'%s...'" % (_escape_string(start))
188
 
        if ctype == NOT_MULTIPART_TYPE:
 
202
        if content_type == NOT_MULTIPART_TYPE:
189
203
            LOG.warning("Unhandled non-multipart (%s) userdata: %s",
190
 
                        ctype, details)
 
204
                        content_type, details)
191
205
        else:
192
206
            LOG.warning("Unhandled unknown content-type (%s) userdata: %s",
193
 
                        ctype, details)
 
207
                        content_type, details)
194
208
    else:
195
 
        LOG.debug("empty payload of type %s" % ctype)
 
209
        LOG.debug("Empty payload of type %s", content_type)
196
210
 
197
211
 
198
212
# Callback is a function that will be called with
212
226
        if not filename:
213
227
            filename = PART_FN_TPL % (partnum)
214
228
 
215
 
        callback(data, ctype, filename, part.get_payload(decode=True))
 
229
        headers = dict(part)
 
230
        LOG.debug(headers)
 
231
        headers['Content-Type'] = ctype
 
232
        callback(data, filename, part.get_payload(decode=True), headers)
216
233
        partnum = partnum + 1
217
234
 
218
235