Revision 2a6469d5 lib/hypervisor.py
b/lib/hypervisor.py | ||
---|---|---|
31 | 31 |
from ganeti import logger |
32 | 32 |
from ganeti import ssconf |
33 | 33 |
from ganeti import constants |
34 |
from ganeti import errors |
|
34 | 35 |
from ganeti.errors import HypervisorError |
35 | 36 |
|
36 | 37 |
|
... | ... | |
46 | 47 |
cls = XenPvmHypervisor |
47 | 48 |
elif ht_kind == constants.HT_FAKE: |
48 | 49 |
cls = FakeHypervisor |
50 |
elif ht_kind == constants.HT_XEN_HVM31: |
|
51 |
cls = XenHvmHypervisor |
|
49 | 52 |
else: |
50 | 53 |
raise HypervisorError("Unknown hypervisor type '%s'" % ht_kind) |
51 | 54 |
return cls() |
... | ... | |
540 | 543 |
""" |
541 | 544 |
if not os.path.exists(self._ROOT_DIR): |
542 | 545 |
return "The required directory '%s' does not exist." % self._ROOT_DIR |
546 |
|
|
547 |
|
|
548 |
class XenHvmHypervisor(XenHypervisor): |
|
549 |
"""Xen HVM hypervisor interface""" |
|
550 |
|
|
551 |
@staticmethod |
|
552 |
def _WriteConfigFile(instance, block_devices, extra_args): |
|
553 |
"""Create a Xen 3.1 HVM config file. |
|
554 |
|
|
555 |
""" |
|
556 |
config = StringIO() |
|
557 |
config.write("# this is autogenerated by Ganeti, please do not edit\n#\n") |
|
558 |
config.write("kernel = '/usr/lib/xen/boot/hvmloader'\n") |
|
559 |
config.write("builder = 'hvm'\n") |
|
560 |
config.write("memory = %d\n" % instance.memory) |
|
561 |
config.write("vcpus = %d\n" % instance.vcpus) |
|
562 |
config.write("name = '%s'\n" % instance.name) |
|
563 |
config.write("pae = 1\n") |
|
564 |
config.write("acpi = 1\n") |
|
565 |
config.write("apic = 1\n") |
|
566 |
arch = os.uname()[4] |
|
567 |
if '64' in arch: |
|
568 |
config.write("device_model = '/usr/lib64/xen/bin/qemu-dm'\n") |
|
569 |
else: |
|
570 |
config.write("device_model = '/usr/lib/xen/bin/qemu-dm'\n") |
|
571 |
config.write("boot = 'dc'\n") |
|
572 |
config.write("sdl = 0\n") |
|
573 |
config.write("vnc = 1\n") |
|
574 |
config.write("vnclisten = '0.0.0.0'\n") |
|
575 |
|
|
576 |
if instance.network_port > constants.HT_HVM_VNC_BASE_PORT: |
|
577 |
display = instance.network_port - constants.HT_HVM_VNC_BASE_PORT |
|
578 |
config.write("vncdisplay = %s\n" % display) |
|
579 |
config.write("vncunused = 0\n") |
|
580 |
else: |
|
581 |
config.write("# vncdisplay = 1\n") |
|
582 |
config.write("vncunused = 1\n") |
|
583 |
|
|
584 |
try: |
|
585 |
password_file = open(constants.VNC_PASSWORD_FILE, "r") |
|
586 |
try: |
|
587 |
password = password_file.readline() |
|
588 |
finally: |
|
589 |
password_file.close() |
|
590 |
except IOError: |
|
591 |
raise errors.OpExecError("failed to open VNC password file %s " % |
|
592 |
constants.VNC_PASSWORD_FILE) |
|
593 |
|
|
594 |
config.write("vncpasswd = '%s'\n" % password.rstrip()) |
|
595 |
|
|
596 |
config.write("serial = 'pty'\n") |
|
597 |
config.write("localtime = 1\n") |
|
598 |
|
|
599 |
vif_data = [] |
|
600 |
for nic in instance.nics: |
|
601 |
nic_str = "mac=%s, bridge=%s, type=ioemu" % (nic.mac, nic.bridge) |
|
602 |
ip = getattr(nic, "ip", None) |
|
603 |
if ip is not None: |
|
604 |
nic_str += ", ip=%s" % ip |
|
605 |
vif_data.append("'%s'" % nic_str) |
|
606 |
|
|
607 |
config.write("vif = [%s]\n" % ",".join(vif_data)) |
|
608 |
|
|
609 |
disk_data = ["'phy:%s,%s,w'" % |
|
610 |
(rldev.dev_path, cfdev.iv_name.replace("sd", "ioemu:hd")) |
|
611 |
for cfdev, rldev in block_devices] |
|
612 |
iso = "'file:/srv/ganeti/iso/hvm-install.iso,hdc:cdrom,r'" |
|
613 |
config.write("disk = [%s, %s]\n" % (",".join(disk_data), iso) ) |
|
614 |
|
|
615 |
config.write("on_poweroff = 'destroy'\n") |
|
616 |
config.write("on_reboot = 'restart'\n") |
|
617 |
config.write("on_crash = 'restart'\n") |
|
618 |
if extra_args: |
|
619 |
config.write("extra = '%s'\n" % extra_args) |
|
620 |
# just in case it exists |
|
621 |
utils.RemoveFile("/etc/xen/auto/%s" % instance.name) |
|
622 |
try: |
|
623 |
f = open("/etc/xen/%s" % instance.name, "w") |
|
624 |
try: |
|
625 |
f.write(config.getvalue()) |
|
626 |
finally: |
|
627 |
f.close() |
|
628 |
except IOError, err: |
|
629 |
raise errors.OpExecError("Cannot write Xen instance confile" |
|
630 |
" file /etc/xen/%s: %s" % (instance.name, err)) |
|
631 |
return True |
|
632 |
|
|
633 |
@staticmethod |
|
634 |
def GetShellCommandForConsole(instance): |
|
635 |
"""Return a command for connecting to the console of an instance. |
|
636 |
|
|
637 |
""" |
|
638 |
if instance.network_port is None: |
|
639 |
raise errors.OpExecError("no console port defined for %s" |
|
640 |
% instance.name) |
|
641 |
else: |
|
642 |
raise errors.OpExecError("no PTY console, connect to %s:%s via VNC" |
|
643 |
% (instance.primary_node, |
|
644 |
instance.network_port)) |
Also available in: Unified diff