287 |
287 |
class XenPvmHypervisor(XenHypervisor):
|
288 |
288 |
"""Xen PVM hypervisor interface"""
|
289 |
289 |
|
|
290 |
PARAMETERS = [
|
|
291 |
constants.HV_KERNEL_PATH,
|
|
292 |
constants.HV_INITRD_PATH,
|
|
293 |
]
|
|
294 |
|
|
295 |
@classmethod
|
|
296 |
def CheckParameterSyntax(cls, hvparams):
|
|
297 |
"""Check the given parameters for validity.
|
|
298 |
|
|
299 |
For the PVM hypervisor, this only check the existence of the
|
|
300 |
kernel.
|
|
301 |
|
|
302 |
@type hvparams: dict
|
|
303 |
@param hvparams: dictionary with parameter names/value
|
|
304 |
@raise errors.HypervisorError: when a parameter is not valid
|
|
305 |
|
|
306 |
"""
|
|
307 |
super(XenPvmHypervisor, cls).CheckParameterSyntax(hvparams)
|
|
308 |
|
|
309 |
if not hvparams[constants.HV_KERNEL_PATH]:
|
|
310 |
raise errors.HypervisorError("Need a kernel for the instance")
|
|
311 |
|
|
312 |
if not os.path.isabs(hvparams[constants.HV_KERNEL_PATH]):
|
|
313 |
raise errors.HypervisorError("The kernel path must an absolute path")
|
|
314 |
|
|
315 |
if hvparams[constants.HV_INITRD_PATH]:
|
|
316 |
if not os.path.isabs(hvparams[constants.HV_INITRD_PATH]):
|
|
317 |
raise errors.HypervisorError("The initrd path must an absolute path"
|
|
318 |
", if defined")
|
|
319 |
|
|
320 |
def ValidateParameters(self, hvparams):
|
|
321 |
"""Check the given parameters for validity.
|
|
322 |
|
|
323 |
For the PVM hypervisor, this only check the existence of the
|
|
324 |
kernel.
|
|
325 |
|
|
326 |
"""
|
|
327 |
super(XenPvmHypervisor, self).ValidateParameters(hvparams)
|
|
328 |
|
|
329 |
kernel_path = hvparams[constants.HV_KERNEL_PATH]
|
|
330 |
if not os.path.isfile(kernel_path):
|
|
331 |
raise errors.HypervisorError("Instance kernel '%s' not found or"
|
|
332 |
" not a file" % kernel_path)
|
|
333 |
initrd_path = hvparams[constants.HV_INITRD_PATH]
|
|
334 |
if initrd_path and not os.path.isfile(initrd_path):
|
|
335 |
raise errors.HypervisorError("Instance initrd '%s' not found or"
|
|
336 |
" not a file" % initrd_path)
|
|
337 |
|
290 |
338 |
@classmethod
|
291 |
339 |
def _WriteConfigFile(cls, instance, block_devices, extra_args):
|
292 |
340 |
"""Write the Xen config file for the instance.
|
... | ... | |
296 |
344 |
config.write("# this is autogenerated by Ganeti, please do not edit\n#\n")
|
297 |
345 |
|
298 |
346 |
# kernel handling
|
299 |
|
if instance.kernel_path in (None, constants.VALUE_DEFAULT):
|
300 |
|
kpath = constants.XEN_KERNEL
|
301 |
|
else:
|
302 |
|
if not os.path.exists(instance.kernel_path):
|
303 |
|
raise errors.HypervisorError("The kernel %s for instance %s is"
|
304 |
|
" missing" % (instance.kernel_path,
|
305 |
|
instance.name))
|
306 |
|
kpath = instance.kernel_path
|
|
347 |
kpath = instance.hvparams[constants.HV_KERNEL_PATH]
|
307 |
348 |
config.write("kernel = '%s'\n" % kpath)
|
308 |
349 |
|
309 |
350 |
# initrd handling
|
310 |
|
if instance.initrd_path in (None, constants.VALUE_DEFAULT):
|
311 |
|
if os.path.exists(constants.XEN_INITRD):
|
312 |
|
initrd_path = constants.XEN_INITRD
|
313 |
|
else:
|
314 |
|
initrd_path = None
|
315 |
|
elif instance.initrd_path == constants.VALUE_NONE:
|
316 |
|
initrd_path = None
|
317 |
|
else:
|
318 |
|
if not os.path.exists(instance.initrd_path):
|
319 |
|
raise errors.HypervisorError("The initrd %s for instance %s is"
|
320 |
|
" missing" % (instance.initrd_path,
|
321 |
|
instance.name))
|
322 |
|
initrd_path = instance.initrd_path
|
323 |
|
|
|
351 |
initrd_path = instance.hvparams[constants.HV_INITRD_PATH]
|
324 |
352 |
if initrd_path:
|
325 |
353 |
config.write("ramdisk = '%s'\n" % initrd_path)
|
326 |
354 |
|
... | ... | |
364 |
392 |
class XenHvmHypervisor(XenHypervisor):
|
365 |
393 |
"""Xen HVM hypervisor interface"""
|
366 |
394 |
|
|
395 |
PARAMETERS = [
|
|
396 |
constants.HV_ACPI,
|
|
397 |
constants.HV_BOOT_ORDER,
|
|
398 |
constants.HV_CDROM_IMAGE_PATH,
|
|
399 |
constants.HV_DISK_TYPE,
|
|
400 |
constants.HV_NIC_TYPE,
|
|
401 |
constants.HV_PAE,
|
|
402 |
constants.HV_VNC_BIND_ADDRESS,
|
|
403 |
]
|
|
404 |
|
|
405 |
@classmethod
|
|
406 |
def CheckParameterSyntax(cls, hvparams):
|
|
407 |
"""Check the given parameter syntax.
|
|
408 |
|
|
409 |
"""
|
|
410 |
super(XenHvmHypervisor, cls).CheckParameterSyntax(hvparams)
|
|
411 |
# boot order verification
|
|
412 |
boot_order = hvparams[constants.HV_BOOT_ORDER]
|
|
413 |
if len(boot_order.strip("acdn")) != 0:
|
|
414 |
raise errors.HypervisorError("Invalid boot order '%s' specified,"
|
|
415 |
" must be one or more of [acdn]" %
|
|
416 |
boot_order)
|
|
417 |
# device type checks
|
|
418 |
nic_type = hvparams[constants.HV_NIC_TYPE]
|
|
419 |
if nic_type not in constants.HT_HVM_VALID_NIC_TYPES:
|
|
420 |
raise errors.HypervisorError("Invalid NIC type %s specified for Xen HVM"
|
|
421 |
" hypervisor" % nic_type)
|
|
422 |
disk_type = hvparams[constants.HV_DISK_TYPE]
|
|
423 |
if disk_type not in constants.HT_HVM_VALID_DISK_TYPES:
|
|
424 |
raise errors.HypervisorError("Invalid disk type %s specified for Xen HVM"
|
|
425 |
" hypervisor" % disk_type)
|
|
426 |
# vnc_bind_address verification
|
|
427 |
vnc_bind_address = hvparams[constants.HV_VNC_BIND_ADDRESS]
|
|
428 |
if vnc_bind_address is not None:
|
|
429 |
if not utils.IsValidIP(vnc_bind_address):
|
|
430 |
raise errors.OpPrereqError("given VNC bind address '%s' doesn't look"
|
|
431 |
" like a valid IP address" %
|
|
432 |
vnc_bind_address)
|
|
433 |
|
|
434 |
iso_path = hvparams[constants.HV_CDROM_IMAGE_PATH]
|
|
435 |
if iso_path and not os.path.isabs(iso_path):
|
|
436 |
raise errors.HypervisorError("The path to the HVM CDROM image must"
|
|
437 |
" be an absolute path or None, not %s" %
|
|
438 |
iso_path)
|
|
439 |
|
|
440 |
def ValidateParameters(self, hvparams):
|
|
441 |
"""Check the given parameters for validity.
|
|
442 |
|
|
443 |
For the PVM hypervisor, this only check the existence of the
|
|
444 |
kernel.
|
|
445 |
|
|
446 |
@type hvparams: dict
|
|
447 |
@param hvparams: dictionary with parameter names/value
|
|
448 |
@raise errors.HypervisorError: when a parameter is not valid
|
|
449 |
|
|
450 |
"""
|
|
451 |
super(XenHvmHypervisor, self).ValidateParameters(hvparams)
|
|
452 |
|
|
453 |
# hvm_cdrom_image_path verification
|
|
454 |
iso_path = hvparams[constants.HV_CDROM_IMAGE_PATH]
|
|
455 |
if iso_path and not os.path.isfile(iso_path):
|
|
456 |
raise errors.HypervisorError("The HVM CDROM image must either be a"
|
|
457 |
" regular file or a symlink pointing to"
|
|
458 |
" an existing regular file, not %s" %
|
|
459 |
iso_path)
|
|
460 |
|
367 |
461 |
@classmethod
|
368 |
462 |
def _WriteConfigFile(cls, instance, block_devices, extra_args):
|
369 |
463 |
"""Create a Xen 3.1 HVM config file.
|
... | ... | |
376 |
470 |
config.write("memory = %d\n" % instance.memory)
|
377 |
471 |
config.write("vcpus = %d\n" % instance.vcpus)
|
378 |
472 |
config.write("name = '%s'\n" % instance.name)
|
379 |
|
if instance.hvm_pae:
|
|
473 |
if instance.hvparams[constants.HV_PAE]:
|
380 |
474 |
config.write("pae = 1\n")
|
381 |
475 |
else:
|
382 |
476 |
config.write("pae = 0\n")
|
383 |
|
if instance.hvm_acpi:
|
|
477 |
if instance.hvparams[constants.HV_ACPI]:
|
384 |
478 |
config.write("acpi = 1\n")
|
385 |
479 |
else:
|
386 |
480 |
config.write("acpi = 0\n")
|
... | ... | |
390 |
484 |
config.write("device_model = '/usr/lib64/xen/bin/qemu-dm'\n")
|
391 |
485 |
else:
|
392 |
486 |
config.write("device_model = '/usr/lib/xen/bin/qemu-dm'\n")
|
393 |
|
if instance.hvm_boot_order is None:
|
|
487 |
if instance.hvparams[constants.HV_BOOT_ORDER] is None:
|
394 |
488 |
config.write("boot = '%s'\n" % constants.HT_HVM_DEFAULT_BOOT_ORDER)
|
395 |
489 |
else:
|
396 |
|
config.write("boot = '%s'\n" % instance.hvm_boot_order)
|
|
490 |
config.write("boot = '%s'\n" % instance.hvparams["boot_order"])
|
397 |
491 |
config.write("sdl = 0\n")
|
398 |
492 |
config.write("usb = 1\n")
|
399 |
493 |
config.write("usbdevice = 'tablet'\n")
|
400 |
494 |
config.write("vnc = 1\n")
|
401 |
|
if instance.vnc_bind_address is None:
|
|
495 |
if instance.hvparams[constants.HV_VNC_BIND_ADDRESS] is None:
|
402 |
496 |
config.write("vnclisten = '%s'\n" % constants.VNC_DEFAULT_BIND_ADDRESS)
|
403 |
497 |
else:
|
404 |
|
config.write("vnclisten = '%s'\n" % instance.vnc_bind_address)
|
|
498 |
config.write("vnclisten = '%s'\n" %
|
|
499 |
instance.hvparams["vnc_bind_address"])
|
405 |
500 |
|
406 |
501 |
if instance.network_port > constants.HT_HVM_VNC_BASE_PORT:
|
407 |
502 |
display = instance.network_port - constants.HT_HVM_VNC_BASE_PORT
|
... | ... | |
427 |
522 |
config.write("localtime = 1\n")
|
428 |
523 |
|
429 |
524 |
vif_data = []
|
|
525 |
nic_type = instance.hvparams[constants.HV_NIC_TYPE]
|
|
526 |
if nic_type is None:
|
|
527 |
# ensure old instances don't change
|
|
528 |
nic_type_str = ", type=ioemu"
|
|
529 |
elif nic_type == constants.HT_HVM_DEV_PARAVIRTUAL:
|
|
530 |
nic_type_str = ", type=paravirtualized"
|
|
531 |
else:
|
|
532 |
nic_type_str = ", model=%s, type=ioemu" % nic_type
|
430 |
533 |
for nic in instance.nics:
|
431 |
|
if instance.hvm_nic_type is None: # ensure old instances don't change
|
432 |
|
nic_type = ", type=ioemu"
|
433 |
|
elif instance.hvm_nic_type == constants.HT_HVM_DEV_PARAVIRTUAL:
|
434 |
|
nic_type = ", type=paravirtualized"
|
435 |
|
else:
|
436 |
|
nic_type = ", model=%s, type=ioemu" % instance.hvm_nic_type
|
437 |
|
|
438 |
|
nic_str = "mac=%s, bridge=%s%s" % (nic.mac, nic.bridge, nic_type)
|
|
534 |
nic_str = "mac=%s, bridge=%s%s" % (nic.mac, nic.bridge, nic_type_str)
|
439 |
535 |
ip = getattr(nic, "ip", None)
|
440 |
536 |
if ip is not None:
|
441 |
537 |
nic_str += ", ip=%s" % ip
|
... | ... | |
444 |
540 |
config.write("vif = [%s]\n" % ",".join(vif_data))
|
445 |
541 |
disk_data = cls._GetConfigFileDiskData(instance.disk_template,
|
446 |
542 |
block_devices)
|
447 |
|
if ((instance.hvm_disk_type is None) or
|
448 |
|
(instance.hvm_disk_type == constants.HT_HVM_DEV_IOEMU)):
|
|
543 |
disk_type = instance.hvparams[constants.HV_DISK_TYPE]
|
|
544 |
if disk_type in (None, constants.HT_HVM_DEV_IOEMU):
|
449 |
545 |
replacement = ",ioemu:hd"
|
450 |
546 |
else:
|
451 |
547 |
replacement = ",hd"
|
452 |
548 |
disk_data = [line.replace(",sd", replacement) for line in disk_data]
|
453 |
|
if instance.hvm_cdrom_image_path is not None:
|
454 |
|
iso = "'file:%s,hdc:cdrom,r'" % (instance.hvm_cdrom_image_path)
|
|
549 |
iso_path = instance.hvparams[constants.HV_CDROM_IMAGE_PATH]
|
|
550 |
if iso_path:
|
|
551 |
iso = "'file:%s,hdc:cdrom,r'" % iso_path
|
455 |
552 |
disk_data.append(iso)
|
456 |
553 |
|
457 |
554 |
config.write("disk = [%s]\n" % (",".join(disk_data)))
|