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