~hazmat/pyjuju/proposed-support

« back to all changes in this revision

Viewing changes to juju/providers/orchestra/cobbler.py

  • Committer: kapil.thangavelu at canonical
  • Date: 2012-05-22 22:08:15 UTC
  • mfrom: (484.1.53 trunk)
  • Revision ID: kapil.thangavelu@canonical.com-20120522220815-acyt8m89i9ybe0w1
merge trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
7
7
from juju.errors import MachinesNotFound, ProviderError
8
8
 
9
9
 
 
10
def _get_arch(system):
 
11
    """Try to parse the system's profile field.
 
12
 
 
13
    Depends on the profile naming as set up on orchestra install.
 
14
    """
 
15
    parts = system.get("profile", "").split("-")
 
16
    if len(parts) >= 2:
 
17
        if parts[1] in ("x86_64", "i386"):
 
18
            return parts[1]
 
19
 
 
20
 
 
21
def _get_profile(series, arch):
 
22
    """Construct an appropriate profile for a system.
 
23
 
 
24
    Depends on the profile naming as set up on orchestra install.
 
25
    """
 
26
    return "%s-%s-juju" % (series, arch)
 
27
 
 
28
 
10
29
class CobblerCaller(object):
11
30
    """Handles the details of communicating with a Cobbler server"""
12
31
 
108
127
        return class_
109
128
 
110
129
    @inlineCallbacks
111
 
    def _get_available_system(self):
 
130
    def _get_available_system(self, required_mgmt_classes):
 
131
        mgmt_classes = [self._available_class]
 
132
        if required_mgmt_classes:
 
133
            mgmt_classes.extend(required_mgmt_classes)
112
134
        names = yield self._caller.call(
113
 
            "find_system", ({"mgmt_classes": self._available_class,
114
 
                             "netboot_enabled": "true"},))
 
135
            "find_system", ({
 
136
                "mgmt_classes": " ".join(mgmt_classes),
 
137
                "netboot_enabled": "true"},))
115
138
        if not names:
116
 
            raise ProviderError("Could not find any Cobbler systems marked as "
117
 
                                "available and configured for network boot.")
 
139
            raise ProviderError(
 
140
                "Could not find a suitable Cobbler system (set to netboot, "
 
141
                "and a member of the following management classes: %s)"
 
142
                % ", ".join(mgmt_classes))
118
143
 
119
144
        # It's possible that some systems could be marked both available and
120
145
        # acquired, so we check each one for sanity (but only complain when
125
150
            info = yield self._caller.call("get_system", (name,))
126
151
            if info == "~":
127
152
                continue
 
153
            if _get_arch(info) is None:
 
154
                # We can't tell how to set a profile to match the hardware.
 
155
                continue
128
156
            classes = info["mgmt_classes"]
129
157
            if self._acquired_class in classes:
130
158
                inconsistent_instance_ids.append(info["uid"])
131
159
                continue
132
160
            returnValue((info["uid"], map(self._class_swapper, classes)))
 
161
        if inconsistent_instance_ids:
 
162
            raise ProviderError(
 
163
                "All available Cobbler systems were also marked as acquired "
 
164
                "(instances: %s)."
 
165
                % ", ".join(inconsistent_instance_ids))
133
166
        raise ProviderError(
134
 
            "All available Cobbler systems were also marked as acquired "
135
 
            "(instances: %s)."
136
 
            % ", ".join(inconsistent_instance_ids))
 
167
            "No available Cobbler system had a detectable known architecture.")
137
168
 
138
169
    @inlineCallbacks
139
170
    def _update_system(self, instance_id, info):
195
226
        returnValue(result_systems)
196
227
 
197
228
    @inlineCallbacks
198
 
    def acquire_system(self):
 
229
    def acquire_system(self, require_classes):
199
230
        """Find a system marked as available and mark it as acquired.
200
231
 
 
232
        :param require_classes: required cobbler mgmt_classes for the machine.
 
233
        :type require_classes: list of str
 
234
 
201
235
        :return: the instance id (Cobbler uid) str of the acquired system.
202
236
        :rtype: :class:`twisted.internet.defer.Deferred`
203
237
 
204
238
        :raises: :exc:`juju.errors.ProviderError` if no suitable system can
205
239
            be found.
206
240
        """
207
 
        instance_id, new_classes = yield self._get_available_system()
 
241
        instance_id, new_classes = yield self._get_available_system(
 
242
            require_classes)
208
243
        yield self._update_system(instance_id, {"mgmt_classes": new_classes})
209
244
        returnValue(instance_id)
210
245
 
211
246
    @inlineCallbacks
212
 
    def start_system(self, instance_id, machine_id, user_data):
 
247
    def start_system(self, instance_id, machine_id, ubuntu_series, user_data):
213
248
        """Launch a cobbler system.
214
249
 
215
250
        :param str instance_id: The Cobbler uid of the desired system.
220
255
        :rtype: :class:`twisted.internet.defer.Deferred`
221
256
        """
222
257
        (system,) = yield self.describe_systems(instance_id)
 
258
        profile = _get_profile(ubuntu_series, _get_arch(system))
223
259
        ks_meta = system["ks_meta"]
224
260
        ks_meta["MACHINE_ID"] = machine_id
225
261
        ks_meta["USER_DATA_BASE64"] = b64encode(user_data)
226
262
        name = yield self._update_system(instance_id, {
227
 
            "netboot_enabled": True, "ks_meta": ks_meta})
 
263
            "netboot_enabled": True, "ks_meta": ks_meta, "profile": profile})
228
264
        yield self._power_call("on", [name])
229
265
        (info,) = yield self.describe_systems(instance_id)
230
266
        returnValue(info)