#!/usr/bin/python
#

# Copyright (C) 2006, 2007, 2011, 2012 Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
# IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


"""Program which configures LVM on the Ganeti nodes.

This program wipes disks and creates a volume group on top of them. It
can also show disk information to help you decide which disks you want
to wipe.

The error handling is done by raising our own exceptions from most of
the functions; these exceptions then handled globally in the main()
function. The exceptions that each function can raise are not
documented individually, since almost every error path ends in a
raise.

Another two exceptions that are handled globally are IOError and
OSError. The idea behind this is, since we run as root, we should
usually not get these errors, but if we do it's most probably a system
error, so they should be handled and the user instructed to report
them.

"""


import os
import sys
import optparse
import time
import errno
import re

from ganeti.utils import RunCmd, ReadFile
from ganeti import constants
from ganeti import cli
from ganeti import compat

USAGE = ("\tlvmstrap diskinfo\n"
         "\tlvmstrap [--vg-name=NAME] [--allow-removable]"
         " { --alldisks | --disks DISKLIST } [--use-sfdisk]"
         " create")

verbose_flag = False

#: Supported disk types (as prefixes)
SUPPORTED_TYPES = [
  "hd",
  "sd",
  "md",
  "ubd",
  ]

#: Excluded filesystem types
EXCLUDED_FS = compat.UniqueFrozenset([
  "nfs",
  "nfs4",
  "autofs",
  "tmpfs",
  "proc",
  "sysfs",
  "usbfs",
  "devpts",
  ])

#: A regular expression that matches partitions (must be kept in sync
# with L{SUPPORTED_TYPES}
PART_RE = re.compile("^((?:h|s|m|ub)d[a-z]{1,2})[0-9]+$")

#: Minimum partition size to be considered (1 GB)
PART_MINSIZE = 1024 * 1024 * 1024
MBR_MAX_SIZE = 2 * (10 ** 12)


class Error(Exception):
  """Generic exception"""
  pass


class ProgrammingError(Error):
  """Exception denoting invalid assumptions in programming.

  This should catch sysfs tree changes, or otherwise incorrect
  assumptions about the contents of the /sys/block/... directories.

  """
  pass


class SysconfigError(Error):
  """Exception denoting invalid system configuration.

  If the system configuration is somehow wrong (e.g. /dev files
  missing, or having mismatched major/minor numbers relative to
  /sys/block devices), this exception will be raised.

  This should usually mean that the installation of the Xen node
  failed in some steps.

  """
  pass


class PrereqError(Error):
  """Exception denoting invalid prerequisites.

  If the node does not meet the requirements for cluster membership, this
  exception will be raised. Things like wrong kernel version, or no
  free disks, etc. belong here.

  This should usually mean that the build steps for the Xen node were
  not followed correctly.

  """
  pass


class OperationalError(Error):
  """Exception denoting actual errors.

  Errors during the bootstrapping are signaled using this exception.

  """
  pass


class ParameterError(Error):
  """Exception denoting invalid input from user.

  Wrong disks given as parameters will be signaled using this
  exception.

  """
  pass


def Usage():
  """Shows program usage information and exits the program.

  """
  print >> sys.stderr, "Usage:"
  print >> sys.stderr, USAGE
  sys.exit(2)


def ParseOptions():
  """Parses the command line options.

  In case of command line errors, it will show the usage and exit the
  program.

  @rtype: tuple
  @return: a tuple of (options, args), as returned by
      OptionParser.parse_args

  """
  global verbose_flag # pylint: disable=W0603

  parser = optparse.OptionParser(usage="\n%s" % USAGE,
                                 version="%%prog (ganeti) %s" %
                                 constants.RELEASE_VERSION)

  parser.add_option("--alldisks", dest="alldisks",
                    help="erase ALL disks", action="store_true",
                    default=False)
  parser.add_option("-d", "--disks", dest="disks",
                    help="Choose disks (e.g. hda,hdg)",
                    metavar="DISKLIST")
  parser.add_option(cli.VERBOSE_OPT)
  parser.add_option("-r", "--allow-removable",
                    action="store_true", dest="removable_ok", default=False,
                    help="allow and use removable devices too")
  parser.add_option("-g", "--vg-name", type="string",
                    dest="vgname", default="xenvg", metavar="NAME",
                    help="the volume group to be created [default: xenvg]")
  parser.add_option("--use-sfdisk", dest="use_sfdisk",
                    action="store_true", default=False,
                    help="use sfdisk instead of parted")

  options, args = parser.parse_args()
  if len(args) != 1:
    Usage()

  verbose_flag = options.verbose

  return options, args


def IsPartitioned(disk):
  """Returns whether a given disk should be used partitioned or as-is.

  Currently only md devices are used as is.

  """
  return not (disk.startswith("md") or PART_RE.match(disk))


def DeviceName(disk):
  """Returns the appropriate device name for a disk.

  For non-partitioned devices, it returns the name as is, otherwise it
  returns the first partition.

  """
  if IsPartitioned(disk):
    device = "/dev/%s1" % disk
  else:
    device = "/dev/%s" % disk
  return device


def SysfsName(disk):
  """Returns the sysfs name for a disk or partition.

  """
  match = PART_RE.match(disk)
  if match:
    # this is a partition, which resides in /sys/block under a different name
    disk = "%s/%s" % (match.group(1), disk)
  return "/sys/block/%s" % disk


def ExecCommand(command):
  """Executes a command.

  This is just a wrapper around commands.getstatusoutput, with the
  difference that if the command line argument -v has been given, it
  will print the command line and the command output on stdout.

  @param command: the command line to be executed
  @rtype: tuple
  @return: a tuple of (status, output) where status is the exit status
      and output the stdout and stderr of the command together

  """
  if verbose_flag:
    print command
  result = RunCmd(command)
  if verbose_flag:
    print result.output
  return result


def CheckPrereq():
  """Check the prerequisites of this program.

  It check that it runs on Linux 2.6, and that /sys is mounted and the
  fact that /sys/block is a directory.

  """
  if os.getuid() != 0:
    raise PrereqError("This tool runs as root only. Really.")

  osname, _, release, _, _ = os.uname()
  if osname != "Linux":
    raise PrereqError("This tool only runs on Linux"
                      " (detected OS: %s)." % osname)

  if not (release.startswith("2.6.") or release.startswith("3.")):
    raise PrereqError("Wrong major kernel version (detected %s, needs"
                      " 2.6.* or 3.*)" % release)

  if not os.path.ismount("/sys"):
    raise PrereqError("Can't find a filesystem mounted at /sys."
                      " Please mount /sys.")

  if not os.path.isdir("/sys/block"):
    raise SysconfigError("Can't find /sys/block directory. Has the"
                         " layout of /sys changed?")

  if not os.path.ismount("/proc"):
    raise PrereqError("Can't find a filesystem mounted at /proc."
                      " Please mount /proc.")

  if not os.path.exists("/proc/mounts"):
    raise SysconfigError("Can't find /proc/mounts")


def CheckVGExists(vgname):
  """Checks to see if a volume group exists.

  @param vgname: the volume group name

  @return: a four-tuple (exists, lv_count, vg_size, vg_free), where:
      - exists: True if the volume exists, otherwise False; if False,
        all other members of the tuple are None
      - lv_count: The number of logical volumes in the volume group
      - vg_size: The total size of the volume group (in gibibytes)
      - vg_free: The available space in the volume group

  """
  result = ExecCommand("vgs --nohead -o lv_count,vg_size,vg_free"
                       " --nosuffix --units g"
                       " --ignorelockingfailure %s" % vgname)
  if not result.failed:
    try:
      lv_count, vg_size, vg_free = result.stdout.strip().split()
    except ValueError:
      # This means the output of vgdisplay can't be parsed
      raise PrereqError("cannot parse output of vgs (%s)" % result.stdout)
  else:
    lv_count = vg_size = vg_free = None

  return not result.failed, lv_count, vg_size, vg_free


def CheckSysDev(name, devnum):
  """Checks consistency between /sys and /dev trees.

  In /sys/block/<name>/dev and /sys/block/<name>/<part>/dev are the
  kernel-known device numbers. The /dev/<name> block/char devices are
  created by userspace and thus could differ from the kernel
  view. This function checks the consistency between the device number
  read from /sys and the actual device number in /dev.

  Note that since the system could be using udev which removes and
  recreates the device nodes on partition table rescan, we need to do
  some retries here. Since we only do a stat, we can afford to do many
  short retries.

  @param name: the device name, e.g. 'sda'
  @param devnum: the device number, e.g. 0x803 (2051 in decimal) for sda3
  @raises SysconfigError: in case of failure of the check

  """
  path = "/dev/%s" % name
  for _ in range(40):
    if os.path.exists(path):
      break
    time.sleep(0.250)
  else:
    raise SysconfigError("the device file %s does not exist, but the block"
                         " device exists in the /sys/block tree" % path)
  rdev = os.stat(path).st_rdev
  if devnum != rdev:
    raise SysconfigError("For device %s, the major:minor in /dev is %04x"
                         " while the major:minor in sysfs is %s" %
                         (path, rdev, devnum))


def ReadDev(syspath):
  """Reads the device number from a sysfs path.

  The device number is given in sysfs under a block device directory
  in a file named 'dev' which contains major:minor (in ASCII). This
  function reads that file and converts the major:minor pair to a dev
  number.

  @type syspath: string
  @param syspath: the path to a block device dir in sysfs,
      e.g. C{/sys/block/sda}

  @return: the device number

  """
  if not os.path.exists("%s/dev" % syspath):
    raise ProgrammingError("Invalid path passed to ReadDev: %s" % syspath)
  f = open("%s/dev" % syspath)
  data = f.read().strip()
  f.close()
  major, minor = data.split(":", 1)
  major = int(major)
  minor = int(minor)
  dev = os.makedev(major, minor)
  return dev


def ReadSize(syspath):
  """Reads the size from a sysfs path.

  The size is given in sysfs under a block device directory in a file
  named 'size' which contains the number of sectors (in ASCII). This
  function reads that file and converts the number in sectors to the
  size in bytes.

  @type syspath: string
  @param syspath: the path to a block device dir in sysfs,
      e.g. C{/sys/block/sda}

  @rtype: int
  @return: the device size in bytes

  """

  if not os.path.exists("%s/size" % syspath):
    raise ProgrammingError("Invalid path passed to ReadSize: %s" % syspath)
  f = open("%s/size" % syspath)
  data = f.read().strip()
  f.close()
  size = 512L * int(data)
  return size


def ReadPV(name):
  """Reads physical volume information.

  This function tries to see if a block device is a physical volume.

  @type name: string
  @param name: the device name (e.g. sda)

  @return: the name of the volume group to which this PV belongs, or
      "" if this PV is not in use, or None if this is not a PV

  """
  result = ExecCommand("pvdisplay -c /dev/%s" % name)
  if result.failed:
    return None
  vgname = result.stdout.strip().split(":")[1]
  return vgname


def GetDiskList(opts):
  """Computes the block device list for this system.

  This function examines the /sys/block tree and using information
  therein, computes the status of the block device.

  @return: a list like [(name, size, dev, partitions, inuse), ...], where:
      - name is the block device name (e.g. sda)
      - size the size in bytes
      - dev is the device number (e.g. 8704 for hdg)
      - partitions is [(name, size, dev), ...] mirroring the disk list
        data inuse is a boolean showing the in-use status of the disk,
        computed as the possibility of re-reading the partition table
        (the meaning of the operation varies with the kernel version,
        but is usually accurate; a mounted disk/partition or swap-area
        or PV with active LVs on it is busy)

  """
  dlist = []
  for name in os.listdir("/sys/block"):
    if not compat.any([name.startswith(pfx) for pfx in SUPPORTED_TYPES]):
      continue

    disksysfsname = "/sys/block/%s" % name
    size = ReadSize(disksysfsname)

    f = open("/sys/block/%s/removable" % name)
    removable = int(f.read().strip())
    f.close()

    if removable and not opts.removable_ok:
      continue

    dev = ReadDev(disksysfsname)
    CheckSysDev(name, dev)
    inuse = InUse(name)
    # Enumerate partitions of the block device
    partitions = []
    for partname in os.listdir(disksysfsname):
      if not partname.startswith(name):
        continue
      partsysfsname = "%s/%s" % (disksysfsname, partname)
      partdev = ReadDev(partsysfsname)
      partsize = ReadSize(partsysfsname)
      if partsize >= PART_MINSIZE:
        CheckSysDev(partname, partdev)
        partinuse = InUse(partname)
        partitions.append((partname, partsize, partdev, partinuse))
    partitions.sort()
    dlist.append((name, size, dev, partitions, inuse))
  dlist.sort()
  return dlist


def GetMountInfo():
  """Reads /proc/mounts and computes the mountpoint-devnum mapping.

  This function reads /proc/mounts, finds the mounted filesystems
  (excepting a hard-coded blacklist of network and virtual
  filesystems) and does a stat on these mountpoints. The st_dev number
  of the results is memorised for later matching against the
  /sys/block devices.

  @rtype: dict
  @return: a {mountpoint: device number} dictionary

  """
  mountlines = ReadFile("/proc/mounts").splitlines()
  mounts = {}
  for line in mountlines:
    _, mountpoint, fstype, _ = line.split(None, 3)
    # fs type blacklist
    if fstype in EXCLUDED_FS:
      continue
    try:
      dev = os.stat(mountpoint).st_dev
    except OSError, err:
      # this should be a fairly rare error, since we are blacklisting
      # network filesystems; with this in mind, we'll ignore it,
      # since the rereadpt check catches in-use filesystems,
      # and this is used for disk information only
      print >> sys.stderr, ("Can't stat mountpoint '%s': %s" %
                            (mountpoint, err))
      print >> sys.stderr, "Ignoring."
      continue
    mounts[dev] = mountpoint
  return mounts


def GetSwapInfo():
  """Reads /proc/swaps and returns the list of swap backing stores.

  """
  swaplines = ReadFile("/proc/swaps").splitlines()[1:]
  return [line.split(None, 1)[0] for line in swaplines]


def DevInfo(name, dev, mountinfo):
  """Computes miscellaneous information about a block device.

  @type name: string
  @param name: the device name, e.g. sda

  @return: a tuple (mpath, whatvg, fileinfo), where:
      - mpath is the mount path where this device is mounted or None
      - whatvg is the result of the ReadPV function
      - fileinfo is the output of file -bs on the device

  """
  if dev in mountinfo:
    mpath = mountinfo[dev]
  else:
    mpath = None

  whatvg = ReadPV(name)

  result = ExecCommand("file -bs /dev/%s" % name)
  if result.failed:
    fileinfo = "<error: %s>" % result.stderr
  fileinfo = result.stdout[:45]
  return mpath, whatvg, fileinfo


def ShowDiskInfo(opts):
  """Shows a nicely formatted block device list for this system.

  This function shows the user a table with the information gathered
  by the other functions defined, in order to help the user make a
  choice about which disks should be allocated to our volume group.

  """
  def _inuse(inuse):
    if inuse:
      return "yes"
    else:
      return "no"

  mounts = GetMountInfo()
  dlist = GetDiskList(opts)

  print "------- Disk information -------"
  headers = {
    "name": "Name",
    "size": "Size[M]",
    "used": "Used",
    "mount": "Mount",
    "lvm": "LVM?",
    "info": "Info",
    }
  fields = ["name", "size", "used", "mount", "lvm", "info"]

  flatlist = []
  # Flatten the [(disk, [partition,...]), ...] list
  for name, size, dev, parts, inuse in dlist:
    flatlist.append((name, size, dev, _inuse(inuse)))
    for partname, partsize, partdev, partinuse in parts:
      flatlist.append((partname, partsize, partdev, _inuse(partinuse)))

  strlist = []
  for name, size, dev, in_use in flatlist:
    mp, vgname, fileinfo = DevInfo(name, dev, mounts)
    if mp is None:
      mp = "-"
    if vgname is None:
      lvminfo = "-"
    elif vgname == "":
      lvminfo = "yes,free"
    else:
      lvminfo = "in %s" % vgname

    if len(name) > 3:
      # Indent partitions
      name = " %s" % name

    strlist.append([name, "%.2f" % (float(size) / 1024 / 1024),
                    in_use, mp, lvminfo, fileinfo])

  data = cli.GenerateTable(headers, fields, None,
                           strlist, numfields=["size"])

  for line in data:
    print line


def CheckSysfsHolders(name):
  """Check to see if a device is 'hold' at sysfs level.

  This is usually the case for Physical Volumes under LVM.

  @rtype: boolean
  @return: true if the device is available according to sysfs

  """
  try:
    contents = os.listdir("%s/holders/" % SysfsName(name))
  except OSError, err:
    if err.errno == errno.ENOENT:
      contents = []
    else:
      raise
  return not bool(contents)


def CheckReread(name):
  """Check to see if a block device is in use.

  Uses blockdev to reread the partition table of a block device (or
  fuser if the device is not partitionable), and thus compute the
  in-use status.  See the discussion in GetDiskList about the meaning
  of 'in use'.

  @rtype: boolean
  @return: the in-use status of the device

  """
  use_blockdev = IsPartitioned(name)
  if use_blockdev:
    cmd = "blockdev --rereadpt /dev/%s" % name
  else:
    cmd = "fuser -vam /dev/%s" % name

  for _ in range(3):
    result = ExecCommand(cmd)
    if not use_blockdev and result.failed:
      break
    elif use_blockdev and not result.failed:
      break
    time.sleep(2)

  if use_blockdev:
    return not result.failed
  else:
    return result.failed


def CheckMounted(name):
  """Check to see if a block device is a mountpoint.

  In recent distros/kernels, this is reported directly via fuser, but
  on older ones not, so we do an additional check here (manually).

  """
  minfo = GetMountInfo()
  dev = ReadDev(SysfsName(name))
  return dev not in minfo


def CheckSwap(name):
  """Check to see if a block device is being used as swap.

  """
  name = "/dev/%s" % name
  return name not in GetSwapInfo()


def InUse(name):
  """Returns if a disk is in use or not.

  """
  return not (CheckSysfsHolders(name) and CheckReread(name) and
              CheckMounted(name) and CheckSwap(name))


def WipeDisk(name):
  """Wipes a block device.

  This function wipes a block device, by clearing and re-reading the
  partition table. If not successful, it writes back the old partition
  data, and leaves the cleanup to the user.

  @param name: the device name (e.g. sda)

  """

  if InUse(name):
    raise OperationalError("CRITICAL: disk %s you selected seems to be in"
                           " use. ABORTING!" % name)

  fd = os.open("/dev/%s" % name, os.O_RDWR | os.O_SYNC)
  olddata = os.read(fd, 512)
  if len(olddata) != 512:
    raise OperationalError("CRITICAL: Can't read partition table information"
                           " from /dev/%s (needed 512 bytes, got %d" %
                           (name, len(olddata)))
  newdata = chr(0) * 512
  os.lseek(fd, 0, 0)
  bytes_written = os.write(fd, newdata)
  os.close(fd)
  if bytes_written != 512:
    raise OperationalError("CRITICAL: Can't write partition table information"
                           " to /dev/%s (tried to write 512 bytes, written"
                           " %d. I don't know how to cleanup. Sorry." %
                           (name, bytes_written))

  if InUse(name):
    # try to restore the data
    fd = os.open("/dev/%s" % name, os.O_RDWR | os.O_SYNC)
    os.write(fd, olddata)
    os.close(fd)
    raise OperationalError("CRITICAL: disk %s which I have just wiped cannot"
                           " reread partition table. Most likely, it is"
                           " in use. You have to clean after this yourself."
                           " I tried to restore the old partition table,"
                           " but I cannot guarantee nothing has broken." %
                           name)


def PartitionDisk(name, use_sfdisk):
  """Partitions a disk.

  This function creates a single partition spanning the entire disk,
  by means of fdisk.

  @param name: the device name, e.g. sda

  """

  # Check that parted exists
  result = ExecCommand("parted --help")
  if result.failed:
    use_sfdisk = True
    print >> sys.stderr, ("Unable to execute \"parted --help\","
                          " falling back to sfdisk.")

  # Check disk size - over 2TB means we need to use GPT
  size = ReadSize("/sys/block/%s" % name)
  if size > MBR_MAX_SIZE:
    label_type = "gpt"
    if use_sfdisk:
      raise OperationalError("Critical: Disk larger than 2TB detected, but"
                             " parted is either not installed or --use-sfdisk"
                             " has been specified")
  else:
    label_type = "msdos"

  if use_sfdisk:
    result = ExecCommand(
        "echo ,,8e, | sfdisk /dev/%s" % name)
    if result.failed:
      raise OperationalError("CRITICAL: disk %s which I have just partitioned"
                             " cannot reread its partition table, or there"
                             " is some other sfdisk error. Likely, it is in"
                             " use. You have to clean this yourself. Error"
                             " message from sfdisk: %s" %
                             (name, result.output))

  else:
    result = ExecCommand("parted -s /dev/%s mklabel %s" % (name, label_type))
    if result.failed:
      raise OperationalError("Critical: failed to create %s label on %s" %
                             (label_type, name))
    result = ExecCommand("parted -s /dev/%s mkpart pri ext2 1 100%%" % name)
    if result.failed:
      raise OperationalError("Critical: failed to create partition on %s" %
                             name)
    result = ExecCommand("parted -s /dev/%s set 1 lvm on" % name)
    if result.failed:
      raise OperationalError("Critical: failed to set partition on %s to LVM" %
                             name)


def CreatePVOnDisk(name):
  """Creates a physical volume on a block device.

  This function creates a physical volume on a block device, overriding
  all warnings. So it can wipe existing PVs and PVs which are in a VG.

  @param name: the device name, e.g. sda

  """
  device = DeviceName(name)
  result = ExecCommand("pvcreate -yff %s" % device)
  if result.failed:
    raise OperationalError("I cannot create a physical volume on"
                           " %s. Error message: %s."
                           " Please clean up yourself." %
                           (device, result.output))


def CreateVG(vgname, disks):
  """Creates the volume group.

  This function creates a volume group named `vgname` on the disks
  given as parameters. The physical extent size is set to 64MB.

  @param disks: a list of disk names, e.g. ['sda','sdb']

  """
  pnames = [DeviceName(d) for d in disks]
  result = ExecCommand("vgcreate -s 64MB '%s' %s" % (vgname, " ".join(pnames)))
  if result.failed:
    raise OperationalError("I cannot create the volume group %s from"
                           " disks %s. Error message: %s. Please clean up"
                           " yourself." %
                           (vgname, " ".join(disks), result.output))


def _ComputeSysdFreeUsed(sysdisks):
  sysd_free = []
  sysd_used = []
  for name, _, _, parts, used in sysdisks:
    if used:
      sysd_used.append(name)
      for partname, _, _, partused in parts:
        if partused:
          sysd_used.append(partname)
        else:
          sysd_free.append(partname)
    else:
      sysd_free.append(name)

  if not sysd_free:
    raise PrereqError("no free disks found! (%d in-use disks)" %
                      len(sysd_used))

  return (sysd_free, sysd_used)


def ValidateDiskList(options):
  """Validates or computes the disk list for create.

  This function either computes the available disk list (if the user
  gave --alldisks option), or validates the user-given disk list (by
  using the --disks option) such that all given disks are present and
  not in use.

  @param options: the options returned from OptParser.parse_options

  @return: a list of disk names, e.g. ['sda', 'sdb']

  """
  sysdisks = GetDiskList(options)
  if not sysdisks:
    raise PrereqError("no disks found (I looked for"
                      " non-removable block devices).")

  (sysd_free, sysd_used) = _ComputeSysdFreeUsed(sysdisks)

  if options.alldisks:
    disklist = sysd_free
  elif options.disks:
    disklist = options.disks.split(",")
    for name in disklist:
      if name in sysd_used:
        raise ParameterError("disk %s is in use, cannot wipe!" % name)
      if name not in sysd_free:
        raise ParameterError("cannot find disk %s!" % name)
  else:
    raise ParameterError("Please use either --alldisks or --disks!")

  return disklist


def BootStrap():
  """Actual main routine.

  """
  CheckPrereq()

  options, args = ParseOptions()
  vgname = options.vgname
  command = args.pop(0)
  if command == "diskinfo":
    ShowDiskInfo(options)
    return
  if command != "create":
    Usage()

  exists, lv_count, vg_size, vg_free = CheckVGExists(vgname)
  if exists:
    raise PrereqError("It seems volume group '%s' already exists:\n"
                      "  LV count: %s, size: %s, free: %s." %
                      (vgname, lv_count, vg_size, vg_free))

  disklist = ValidateDiskList(options)

  for disk in disklist:
    WipeDisk(disk)
    if IsPartitioned(disk):
      PartitionDisk(disk, options.use_sfdisk)
  for disk in disklist:
    CreatePVOnDisk(disk)
  CreateVG(vgname, disklist)

  status, lv_count, size, _ = CheckVGExists(vgname)
  if status:
    print "Done! %s: size %s GiB, disks: %s" % (vgname, size,
                                                ",".join(disklist))
  else:
    raise OperationalError("Although everything seemed ok, the volume"
                           " group did not get created.")


def main():
  """Application entry point.

  This is just a wrapper over BootStrap, to handle our own exceptions.

  """
  try:
    BootStrap()
  except PrereqError, err:
    print >> sys.stderr, "The prerequisites for running this tool are not met."
    print >> sys.stderr, ("Please make sure you followed all the steps in"
                          " the build document.")
    print >> sys.stderr, "Description: %s" % str(err)
    sys.exit(1)
  except SysconfigError, err:
    print >> sys.stderr, ("This system's configuration seems wrong, at"
                          " least is not what I expect.")
    print >> sys.stderr, ("Please check that the installation didn't fail"
                          " at some step.")
    print >> sys.stderr, "Description: %s" % str(err)
    sys.exit(1)
  except ParameterError, err:
    print >> sys.stderr, ("Some parameters you gave to the program or the"
                          " invocation is wrong. ")
    print >> sys.stderr, "Description: %s" % str(err)
    Usage()
  except OperationalError, err:
    print >> sys.stderr, ("A serious error has happened while modifying"
                          " the system's configuration.")
    print >> sys.stderr, ("Please review the error message below and make"
                          " sure you clean up yourself.")
    print >> sys.stderr, ("It is most likely that the system configuration"
                          " has been partially altered.")
    print >> sys.stderr, str(err)
    sys.exit(1)
  except ProgrammingError, err:
    print >> sys.stderr, ("Internal application error. Please report this"
                          " to the Ganeti developer list.")
    print >> sys.stderr, "Error description: %s" % str(err)
    sys.exit(1)
  except Error, err:
    print >> sys.stderr, "Unhandled application error: %s" % err
    sys.exit(1)
  except (IOError, OSError), err:
    print >> sys.stderr, "I/O error detected, please report."
    print >> sys.stderr, "Description: %s" % str(err)
    sys.exit(1)


if __name__ == "__main__":
  main()
