93
95
username = FLAGS.xenapi_connection_username
94
96
password = FLAGS.xenapi_connection_password
95
97
if not url or password is None:
96
raise Exception('Must specify xenapi_connection_url, '
97
'xenapi_connection_username (optionally), and '
98
'xenapi_connection_password to use '
99
'connection_type=xenapi')
98
raise Exception(_('Must specify xenapi_connection_url, '
99
'xenapi_connection_username (optionally), and '
100
'xenapi_connection_password to use '
101
'connection_type=xenapi'))
100
102
return XenAPIConnection(url, username, password)
103
105
class XenAPIConnection(object):
104
""" A connection to XenServer or Xen Cloud Platform """
106
"""A connection to XenServer or Xen Cloud Platform"""
105
108
def __init__(self, url, user, pw):
106
109
session = XenAPISession(url, user, pw)
107
110
self._vmops = VMOps(session)
108
111
self._volumeops = VolumeOps(session)
110
113
def list_instances(self):
111
""" List VM instances """
114
"""List VM instances"""
112
115
return self._vmops.list_instances()
114
117
def spawn(self, instance):
115
""" Create VM instance """
118
"""Create VM instance"""
116
119
self._vmops.spawn(instance)
118
121
def reboot(self, instance):
119
""" Reboot VM instance """
122
"""Reboot VM instance"""
120
123
self._vmops.reboot(instance)
122
125
def destroy(self, instance):
123
""" Destroy VM instance """
126
"""Destroy VM instance"""
124
127
self._vmops.destroy(instance)
129
def pause(self, instance, callback):
130
"""Pause VM instance"""
131
self._vmops.pause(instance, callback)
133
def unpause(self, instance, callback):
134
"""Unpause paused VM instance"""
135
self._vmops.unpause(instance, callback)
126
137
def get_info(self, instance_id):
127
""" Return data about VM instance """
138
"""Return data about VM instance"""
128
139
return self._vmops.get_info(instance_id)
130
141
def get_diagnostics(self, instance_id):
132
143
return self._vmops.get_diagnostics(instance_id)
134
145
def get_console_output(self, instance):
135
""" Return snapshot of console """
146
"""Return snapshot of console"""
136
147
return self._vmops.get_console_output(instance)
138
149
def attach_volume(self, instance_name, device_path, mountpoint):
139
""" Attach volume storage to VM instance """
150
"""Attach volume storage to VM instance"""
140
151
return self._volumeops.attach_volume(instance_name,
144
155
def detach_volume(self, instance_name, mountpoint):
145
""" Detach volume storage to VM instance """
156
"""Detach volume storage to VM instance"""
146
157
return self._volumeops.detach_volume(instance_name, mountpoint)
149
160
class XenAPISession(object):
150
""" The session to invoke XenAPI SDK calls """
161
"""The session to invoke XenAPI SDK calls"""
151
163
def __init__(self, url, user, pw):
152
164
self._session = XenAPI.Session(url)
153
165
self._session.login_with_password(user, pw)
155
167
def get_xenapi(self):
156
""" Return the xenapi object """
168
"""Return the xenapi object"""
157
169
return self._session.xenapi
159
171
def get_xenapi_host(self):
160
""" Return the xenapi host """
172
"""Return the xenapi host"""
161
173
return self._session.xenapi.session.get_this_host(self._session.handle)
163
175
def call_xenapi(self, method, *args):
173
185
self._session.xenapi.Async.host.call_plugin,
174
186
self.get_xenapi_host(), plugin, fn, args)
176
def wait_for_task(self, task):
188
def wait_for_task(self, instance_id, task):
177
189
"""Return a Deferred that will give the result of the given task.
178
190
The task is polled until it completes."""
180
192
done = event.Event()
181
loop = utils.LoopingCall(self._poll_task, task, done)
193
loop = utils.LoopingCall(self._poll_task, instance_id, task, done)
182
194
loop.start(FLAGS.xenapi_task_poll_interval, now=True)
187
def _poll_task(self, task, done):
199
def _poll_task(self, instance_id, task, done):
188
200
"""Poll the given XenAPI task, and fire the given Deferred if we
191
#logging.debug('Polling task %s...', task)
203
name = self._session.xenapi.task.get_name_label(task)
192
204
status = self._session.xenapi.task.get_status(task)
193
if status == 'pending':
206
instance_id=int(instance_id),
209
if status == "pending":
195
elif status == 'success':
211
elif status == "success":
196
212
result = self._session.xenapi.task.get_result(task)
197
logging.info('Task %s status: success. %s', task, result)
213
logging.info(_("Task [%s] %s status: success %s") % (
198
217
done.send(_parse_xmlrpc_value(result))
200
219
error_info = self._session.xenapi.task.get_error_info(task)
201
logging.warn('Task %s status: %s. %s', task, status,
220
action["error"] = str(error_info)
221
logging.warn(_("Task [%s] %s status: %s %s") % (
203
226
done.send_exception(XenAPI.Failure(error_info))
204
#logging.debug('Polling task %s done.', task)
227
db.instance_action_create(context.get_admin_context(), action)
205
228
except XenAPI.Failure, exc:
206
229
logging.warn(exc)
207
230
done.send_exception(*sys.exc_info())
210
233
def _unwrap_plugin_exceptions(func, *args, **kwargs):
211
""" Parse exception details """
234
"""Parse exception details"""
213
236
return func(*args, **kwargs)
214
237
except XenAPI.Failure, exc:
215
logging.debug("Got exception: %s", exc)
238
logging.debug(_("Got exception: %s"), exc)
216
239
if (len(exc.details) == 4 and
217
240
exc.details[0] == 'XENAPI_PLUGIN_EXCEPTION' and
218
241
exc.details[2] == 'Failure'):