62
63
vms.append(rec["name_label"])
65
def spawn(self, instance):
66
def _start(self, instance, vm_ref=None):
67
"""Power on a VM instance"""
69
vm_ref = VMHelper.lookup(self._session, instance.name)
71
raise exception(_('Attempted to power on non-existent instance'
72
' bad instance id %s') % instance.id)
73
LOG.debug(_("Starting instance %s"), instance.name)
74
self._session.call_xenapi('VM.start', vm_ref, False, False)
76
def spawn(self, instance, disk):
66
77
"""Create VM instance"""
67
78
instance_name = instance.name
68
79
vm = VMHelper.lookup(self._session, instance_name)
82
93
user = AuthManager().get_user(instance.user_id)
83
94
project = AuthManager().get_project(instance.project_id)
85
disk_image_type = VMHelper.determine_disk_image_type(instance)
87
vdi_uuid = VMHelper.fetch_image(self._session, instance.id,
88
instance.image_id, user, project, disk_image_type)
90
vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)
96
vdi_ref = kernel = ramdisk = pv_kernel = None
98
# Are we building from a pre-existing disk?
100
#if kernel is not present we must download a raw disk
102
disk_image_type = VMHelper.determine_disk_image_type(instance)
103
vdi_uuid = VMHelper.fetch_image(self._session, instance.id,
104
instance.image_id, user, project, disk_image_type)
105
vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid)
108
vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', disk)
93
110
if disk_image_type == ImageType.DISK_RAW:
94
#Have a look at the VDI and see if it has a PV kernel
111
# Have a look at the VDI and see if it has a PV kernel
95
112
pv_kernel = VMHelper.lookup_image(self._session, instance.id,
97
114
elif disk_image_type == ImageType.DISK_VHD:
99
116
# configurable as Windows will use HVM.
103
119
if instance.kernel_id:
104
120
kernel = VMHelper.fetch_image(self._session, instance.id,
105
121
instance.kernel_id, user, project, ImageType.KERNEL_RAMDISK)
108
123
if instance.ramdisk_id:
109
124
ramdisk = VMHelper.fetch_image(self._session, instance.id,
110
125
instance.ramdisk_id, user, project, ImageType.KERNEL_RAMDISK)
112
127
vm_ref = VMHelper.create_vm(self._session,
113
128
instance, kernel, ramdisk, pv_kernel)
114
VMHelper.create_vbd(self._session, vm_ref, vdi_ref, 0, True)
129
VMHelper.create_vbd(session=self._session, vm_ref=vm_ref,
130
vdi_ref=vdi_ref, userdevice=0, bootable=True)
116
132
# Alter the image before VM start for, e.g. network injection
117
133
if FLAGS.xenapi_inject_image:
177
193
"""Refactored out the common code of many methods that receive either
178
194
a vm name or a vm instance, and want a vm instance in return.
181
#assume instance_or_vm is an instance object
196
# if instance_or_vm is a string it must be opaque ref or instance name
197
if isinstance(instance_or_vm, basestring):
200
# check for opaque ref
201
obj = self._session.get_xenapi().VM.get_record(instance_or_vm)
202
return instance_or_vm
203
except self.XenAPI.Failure:
204
# wasn't an opaque ref, can be an instance name
205
instance_name = instance_or_vm
207
# if instance_or_vm is an int/long it must be instance id
208
elif isinstance(instance_or_vm, (int, long)):
209
ctx = context.get_admin_context()
210
instance_obj = db.instance_get(ctx, instance_or_vm)
211
instance_name = instance_obj.name
183
213
instance_name = instance_or_vm.name
184
except (AttributeError, KeyError):
185
if isinstance(instance_or_vm, (int, long)):
186
ctx = context.get_admin_context()
187
instance_obj = db.instance_get(ctx, instance_or_vm)
188
instance_name = instance_obj.name
190
instance_name = instance_or_vm
191
#try to lookup instance
192
vm = VMHelper.lookup(self._session, instance_name)
193
#if vm=None might be a VM ref
195
vm_rec = self._session.get_xenapi().VM.get_record(instance_or_vm)
197
#found - it is a vm ref
198
return instance_or_vm
201
#if we end up here instance_or_vm is neither an instance id or VM ref
202
raise exception.NotFound(
203
_('Instance not present %s') % instance_name)
214
vm_ref = VMHelper.lookup(self._session, instance_name)
216
raise exception.NotFound(
217
_('Instance not present %s') % instance_name)
205
220
def _acquire_bootlock(self, vm):
206
221
"""Prevent an instance from booting"""
250
278
template_vm_ref, template_vdi_uuids = VMHelper.create_snapshot(
251
279
self._session, instance.id, vm_ref, label)
280
return template_vm_ref, template_vdi_uuids
252
281
except self.XenAPI.Failure, exc:
253
282
logging.error(_("Unable to Snapshot %(vm_ref)s: %(exc)s")
286
def migrate_disk_and_power_off(self, instance, dest):
287
"""Copies a VHD from one host machine to another
289
:param instance: the instance that owns the VHD in question
290
:param dest: the destination host machine
291
:param disk_type: values are 'primary' or 'cow'
293
vm_ref = VMHelper.lookup(self._session, instance.name)
295
# The primary VDI becomes the COW after the snapshot, and we can
296
# identify it via the VBD. The base copy is the parent_uuid returned
297
# from the snapshot creation
299
base_copy_uuid = cow_uuid = None
300
template_vdi_uuids = template_vm_ref = None
258
# call plugin to ship snapshot off to glance
259
VMHelper.upload_image(
260
self._session, instance.id, template_vdi_uuids, image_id)
302
# transfer the base copy
303
template_vm_ref, template_vdi_uuids = self._get_snapshot(instance)
304
base_copy_uuid = template_vdi_uuids[1]
305
vdi_ref, vm_vdi_rec = \
306
VMHelper.get_vdi_for_vm_safely(self._session, vm_ref)
307
cow_uuid = vm_vdi_rec['uuid']
309
params = {'host': dest,
310
'vdi_uuid': base_copy_uuid,
311
'instance_id': instance.id,
312
'sr_path': VMHelper.get_sr_path(self._session)}
314
task = self._session.async_call_plugin('migration', 'transfer_vhd',
315
{'params': pickle.dumps(params)})
316
self._session.wait_for_task(task, instance.id)
318
# Now power down the instance and transfer the COW VHD
319
self._shutdown(instance, vm_ref, method='clean')
321
params = {'host': dest,
322
'vdi_uuid': cow_uuid,
323
'instance_id': instance.id,
324
'sr_path': VMHelper.get_sr_path(self._session), }
326
task = self._session.async_call_plugin('migration', 'transfer_vhd',
327
{'params': pickle.dumps(params)})
328
self._session.wait_for_task(task, instance.id)
262
self._destroy(instance, template_vm_ref, shutdown=False,
263
destroy_kernel_ramdisk=False)
265
logging.debug(_("Finished snapshot and upload for VM %s"), instance)
332
self._destroy(instance, template_vm_ref,
333
shutdown=False, destroy_kernel_ramdisk=False)
335
# TODO(mdietz): we could also consider renaming these to something
336
# sensible so we don't need to blindly pass around dictionaries
337
return {'base_copy': base_copy_uuid, 'cow': cow_uuid}
339
def attach_disk(self, instance, disk_info):
340
"""Links the base copy VHD to the COW via the XAPI plugin"""
341
vm_ref = VMHelper.lookup(self._session, instance.name)
342
new_base_copy_uuid = str(uuid.uuid4())
343
new_cow_uuid = str(uuid.uuid4())
344
params = {'instance_id': instance.id,
345
'old_base_copy_uuid': disk_info['base_copy'],
346
'old_cow_uuid': disk_info['cow'],
347
'new_base_copy_uuid': new_base_copy_uuid,
348
'new_cow_uuid': new_cow_uuid,
349
'sr_path': VMHelper.get_sr_path(self._session), }
351
task = self._session.async_call_plugin('migration',
352
'move_vhds_into_sr', {'params': pickle.dumps(params)})
353
self._session.wait_for_task(task, instance.id)
355
# Now we rescan the SR so we find the VHDs
356
VMHelper.scan_default_sr(self._session)
360
def resize(self, instance, flavor):
361
"""Resize a running instance by changing it's RAM and disk size """
362
raise NotImplementedError()
267
364
def reboot(self, instance):
268
365
"""Reboot VM instance"""