Revision 2a6469d5
b/lib/cmdlib.py | ||
---|---|---|
499 | 499 |
if config.ConfigWriter.IsCluster(): |
500 | 500 |
raise errors.OpPrereqError("Cluster is already initialised") |
501 | 501 |
|
502 |
if self.op.hypervisor_type == constants.HT_XEN_HVM31: |
|
503 |
if not os.path.exists(constants.VNC_PASSWORD_FILE): |
|
504 |
raise errors.OpPrereqError("Please prepare the cluster VNC" |
|
505 |
"password file %s" % |
|
506 |
constants.VNC_PASSWORD_FILE) |
|
507 |
|
|
502 | 508 |
self.hostname = hostname = utils.HostInfo() |
503 | 509 |
|
504 | 510 |
if hostname.ip.startswith("127."): |
... | ... | |
1470 | 1476 |
primary_ip=primary_ip, |
1471 | 1477 |
secondary_ip=secondary_ip) |
1472 | 1478 |
|
1479 |
if self.sstore.GetHypervisorType() == constants.HT_XEN_HVM31: |
|
1480 |
if not os.path.exists(constants.VNC_PASSWORD_FILE): |
|
1481 |
raise errors.OpPrereqError("Cluster VNC password file %s missing" % |
|
1482 |
constants.VNC_PASSWORD_FILE) |
|
1483 |
|
|
1473 | 1484 |
def Exec(self, feedback_fn): |
1474 | 1485 |
"""Adds the new node to the cluster. |
1475 | 1486 |
|
... | ... | |
1589 | 1600 |
(fname, to_node)) |
1590 | 1601 |
|
1591 | 1602 |
to_copy = ss.GetFileList() |
1603 |
if self.sstore.GetHypervisorType() == constants.HT_XEN_HVM31: |
|
1604 |
to_copy.append(constants.VNC_PASSWORD_FILE) |
|
1592 | 1605 |
for fname in to_copy: |
1593 | 1606 |
if not ssh.CopyFileToNode(node, fname): |
1594 | 1607 |
logger.Error("could not copy file %s to node %s" % (fname, node)) |
... | ... | |
3028 | 3041 |
if self.inst_ip is not None: |
3029 | 3042 |
nic.ip = self.inst_ip |
3030 | 3043 |
|
3031 |
network_port = None # placeholder assignment for later |
|
3044 |
ht_kind = self.sstore.GetHypervisorType() |
|
3045 |
if ht_kind in constants.HTS_REQ_PORT: |
|
3046 |
network_port = self.cfg.AllocatePort() |
|
3047 |
else: |
|
3048 |
network_port = None |
|
3032 | 3049 |
|
3033 | 3050 |
disks = _GenerateDiskTemplate(self.cfg, |
3034 | 3051 |
self.op.disk_template, |
b/lib/constants.py | ||
---|---|---|
151 | 151 |
# Hypervisor constants |
152 | 152 |
HT_XEN_PVM30 = "xen-3.0" |
153 | 153 |
HT_FAKE = "fake" |
154 |
HT_XEN_HVM31 = "xen-hvm-3.1" |
|
155 |
HYPER_TYPES = frozenset([HT_XEN_PVM30, HT_FAKE, HT_XEN_HVM31]) |
|
156 |
HTS_REQ_PORT = frozenset([HT_XEN_HVM31]) |
|
154 | 157 |
|
155 |
HYPER_TYPES = frozenset([HT_XEN_PVM30, HT_FAKE]) |
|
158 |
HT_HVM_VNC_BASE_PORT = 5900 |
|
159 |
VNC_PASSWORD_FILE = _autoconf.SYSCONFDIR + "/ganeti/vnc-cluster-password" |
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)) |
b/scripts/gnt-cluster | ||
---|---|---|
257 | 257 |
" addresses", |
258 | 258 |
metavar="ADDRESS", default=None), |
259 | 259 |
make_option("-t", "--hypervisor-type", dest="hypervisor_type", |
260 |
help="Specify the hypervisor type (xen-3.0, fake)", |
|
261 |
metavar="TYPE", choices=["xen-3.0", "fake"], |
|
260 |
help="Specify the hypervisor type " |
|
261 |
"(xen-3.0, fake, xen-hvm-3.1)", |
|
262 |
metavar="TYPE", choices=["xen-3.0", |
|
263 |
"fake", |
|
264 |
"xen-hvm-3.1"], |
|
262 | 265 |
default="xen-3.0",), |
263 | 266 |
make_option("-m", "--mac-prefix", dest="mac_prefix", |
264 | 267 |
help="Specify the mac prefix for the instance IP" |
Also available in: Unified diff