#
#

# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 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.


"""Module dealing with command line parsing"""


import sys
import textwrap
import os.path
import time
import logging
import errno
import itertools
import shlex
from cStringIO import StringIO

from ganeti import utils
from ganeti import errors
from ganeti import constants
from ganeti import opcodes
import ganeti.rpc.errors as rpcerr
import ganeti.rpc.node as rpc
from ganeti import ssh
from ganeti import compat
from ganeti import netutils
from ganeti import qlang
from ganeti import objects
from ganeti import pathutils
from ganeti import serializer
import ganeti.cli_opts
# Import constants
from ganeti.cli_opts import *  # pylint: disable=W0401

from ganeti.runtime import (GetClient)

from optparse import (OptionParser, TitledHelpFormatter)


__all__ = [
  # Generic functions for CLI programs
  "ConfirmOperation",
  "CreateIPolicyFromOpts",
  "GenericMain",
  "GenericInstanceCreate",
  "GenericList",
  "GenericListFields",
  "GetClient",
  "GetOnlineNodes",
  "GetNodesSshPorts",
  "GetNodeUUIDs",
  "JobExecutor",
  "JobSubmittedException",
  "ParseTimespec",
  "RunWhileClusterStopped",
  "RunWhileDaemonsStopped",
  "SubmitOpCode",
  "SubmitOpCodeToDrainedQueue",
  "SubmitOrSend",
  "UsesRPC",
  # Formatting functions
  "ToStderr", "ToStdout",
  "ToStdoutAndLoginfo",
  "FormatError",
  "FormatQueryResult",
  "FormatParamsDictInfo",
  "FormatPolicyInfo",
  "PrintIPolicyCommand",
  "PrintGenericInfo",
  "GenerateTable",
  "AskUser",
  "FormatTimestamp",
  "FormatLogMessage",
  # Tags functions
  "ListTags",
  "AddTags",
  "RemoveTags",
  # command line options support infrastructure
  "ARGS_MANY_INSTANCES",
  "ARGS_MANY_NODES",
  "ARGS_MANY_GROUPS",
  "ARGS_MANY_NETWORKS",
  "ARGS_MANY_FILTERS",
  "ARGS_NONE",
  "ARGS_ONE_INSTANCE",
  "ARGS_ONE_NODE",
  "ARGS_ONE_GROUP",
  "ARGS_ONE_OS",
  "ARGS_ONE_NETWORK",
  "ARGS_ONE_FILTER",
  "ArgChoice",
  "ArgCommand",
  "ArgFile",
  "ArgGroup",
  "ArgHost",
  "ArgInstance",
  "ArgJobId",
  "ArgNetwork",
  "ArgNode",
  "ArgOs",
  "ArgExtStorage",
  "ArgFilter",
  "ArgSuggest",
  "ArgUnknown",
  "FixHvParams",
  "SplitNodeOption",
  "CalculateOSNames",
  "ParseFields",
  ] + ganeti.cli_opts.__all__ # Command line options

# Query result status for clients
(QR_NORMAL,
 QR_UNKNOWN,
 QR_INCOMPLETE) = range(3)

#: Maximum batch size for ChooseJob
_CHOOSE_BATCH = 25


# constants used to create InstancePolicy dictionary
TISPECS_GROUP_TYPES = {
  constants.ISPECS_MIN: constants.VTYPE_INT,
  constants.ISPECS_MAX: constants.VTYPE_INT,
  }

TISPECS_CLUSTER_TYPES = {
  constants.ISPECS_MIN: constants.VTYPE_INT,
  constants.ISPECS_MAX: constants.VTYPE_INT,
  constants.ISPECS_STD: constants.VTYPE_INT,
  }

#: User-friendly names for query2 field types
_QFT_NAMES = {
  constants.QFT_UNKNOWN: "Unknown",
  constants.QFT_TEXT: "Text",
  constants.QFT_BOOL: "Boolean",
  constants.QFT_NUMBER: "Number",
  constants.QFT_NUMBER_FLOAT: "Floating-point number",
  constants.QFT_UNIT: "Storage size",
  constants.QFT_TIMESTAMP: "Timestamp",
  constants.QFT_OTHER: "Custom",
  }


class _Argument(object):
  def __init__(self, min=0, max=None): # pylint: disable=W0622
    self.min = min
    self.max = max

  def __repr__(self):
    return ("<%s min=%s max=%s>" %
            (self.__class__.__name__, self.min, self.max))


class ArgSuggest(_Argument):
  """Suggesting argument.

  Value can be any of the ones passed to the constructor.

  """
  # pylint: disable=W0622
  def __init__(self, min=0, max=None, choices=None):
    _Argument.__init__(self, min=min, max=max)
    self.choices = choices

  def __repr__(self):
    return ("<%s min=%s max=%s choices=%r>" %
            (self.__class__.__name__, self.min, self.max, self.choices))


class ArgChoice(ArgSuggest):
  """Choice argument.

  Value can be any of the ones passed to the constructor. Like L{ArgSuggest},
  but value must be one of the choices.

  """


class ArgUnknown(_Argument):
  """Unknown argument to program (e.g. determined at runtime).

  """


class ArgInstance(_Argument):
  """Instances argument.

  """


class ArgNode(_Argument):
  """Node argument.

  """


class ArgNetwork(_Argument):
  """Network argument.

  """


class ArgGroup(_Argument):
  """Node group argument.

  """


class ArgJobId(_Argument):
  """Job ID argument.

  """


class ArgFile(_Argument):
  """File path argument.

  """


class ArgCommand(_Argument):
  """Command argument.

  """


class ArgHost(_Argument):
  """Host argument.

  """


class ArgOs(_Argument):
  """OS argument.

  """


class ArgExtStorage(_Argument):
  """ExtStorage argument.

  """


class ArgFilter(_Argument):
  """Filter UUID argument.

  """


ARGS_NONE = []
ARGS_MANY_INSTANCES = [ArgInstance()]
ARGS_MANY_NETWORKS = [ArgNetwork()]
ARGS_MANY_NODES = [ArgNode()]
ARGS_MANY_GROUPS = [ArgGroup()]
ARGS_MANY_FILTERS = [ArgFilter()]
ARGS_ONE_INSTANCE = [ArgInstance(min=1, max=1)]
ARGS_ONE_NETWORK = [ArgNetwork(min=1, max=1)]
ARGS_ONE_NODE = [ArgNode(min=1, max=1)]
ARGS_ONE_GROUP = [ArgGroup(min=1, max=1)]
ARGS_ONE_OS = [ArgOs(min=1, max=1)]
ARGS_ONE_FILTER = [ArgFilter(min=1, max=1)]


def _ExtractTagsObject(opts, args):
  """Extract the tag type object.

  Note that this function will modify its args parameter.

  """
  if not hasattr(opts, "tag_type"):
    raise errors.ProgrammerError("tag_type not passed to _ExtractTagsObject")
  kind = opts.tag_type
  if kind == constants.TAG_CLUSTER:
    retval = kind, ""
  elif kind in (constants.TAG_NODEGROUP,
                constants.TAG_NODE,
                constants.TAG_NETWORK,
                constants.TAG_INSTANCE):
    if not args:
      raise errors.OpPrereqError("no arguments passed to the command",
                                 errors.ECODE_INVAL)
    name = args.pop(0)
    retval = kind, name
  else:
    raise errors.ProgrammerError("Unhandled tag type '%s'" % kind)
  return retval


def _ExtendTags(opts, args):
  """Extend the args if a source file has been given.

  This function will extend the tags with the contents of the file
  passed in the 'tags_source' attribute of the opts parameter. A file
  named '-' will be replaced by stdin.

  """
  fname = opts.tags_source
  if fname is None:
    return
  if fname == "-":
    new_fh = sys.stdin
  else:
    new_fh = open(fname, "r")
  new_data = []
  try:
    # we don't use the nice 'new_data = [line.strip() for line in fh]'
    # because of python bug 1633941
    while True:
      line = new_fh.readline()
      if not line:
        break
      new_data.append(line.strip())
  finally:
    new_fh.close()
  args.extend(new_data)


def ListTags(opts, args):
  """List the tags on a given object.

  This is a generic implementation that knows how to deal with all
  three cases of tag objects (cluster, node, instance). The opts
  argument is expected to contain a tag_type field denoting what
  object type we work on.

  """
  kind, name = _ExtractTagsObject(opts, args)
  cl = GetClient()
  result = cl.QueryTags(kind, name)
  result = list(result)
  result.sort()
  for tag in result:
    ToStdout(tag)


def AddTags(opts, args):
  """Add tags on a given object.

  This is a generic implementation that knows how to deal with all
  three cases of tag objects (cluster, node, instance). The opts
  argument is expected to contain a tag_type field denoting what
  object type we work on.

  """
  kind, name = _ExtractTagsObject(opts, args)
  _ExtendTags(opts, args)
  if not args:
    raise errors.OpPrereqError("No tags to be added", errors.ECODE_INVAL)
  op = opcodes.OpTagsSet(kind=kind, name=name, tags=args)
  SubmitOrSend(op, opts)


def RemoveTags(opts, args):
  """Remove tags from a given object.

  This is a generic implementation that knows how to deal with all
  three cases of tag objects (cluster, node, instance). The opts
  argument is expected to contain a tag_type field denoting what
  object type we work on.

  """
  kind, name = _ExtractTagsObject(opts, args)
  _ExtendTags(opts, args)
  if not args:
    raise errors.OpPrereqError("No tags to be removed", errors.ECODE_INVAL)
  op = opcodes.OpTagsDel(kind=kind, name=name, tags=args)
  SubmitOrSend(op, opts)


class _ShowUsage(Exception):
  """Exception class for L{_ParseArgs}.

  """
  def __init__(self, exit_error):
    """Initializes instances of this class.

    @type exit_error: bool
    @param exit_error: Whether to report failure on exit

    """
    Exception.__init__(self)
    self.exit_error = exit_error


class _ShowVersion(Exception):
  """Exception class for L{_ParseArgs}.

  """


def _ParseArgs(binary, argv, commands, aliases, env_override):
  """Parser for the command line arguments.

  This function parses the arguments and returns the function which
  must be executed together with its (modified) arguments.

  @param binary: Script name
  @param argv: Command line arguments
  @param commands: Dictionary containing command definitions
  @param aliases: dictionary with command aliases {"alias": "target", ...}
  @param env_override: list of env variables allowed for default args
  @raise _ShowUsage: If usage description should be shown
  @raise _ShowVersion: If version should be shown

  """
  assert not (env_override - set(commands))
  assert not (set(aliases.keys()) & set(commands.keys()))

  if len(argv) > 1:
    cmd = argv[1]
  else:
    # No option or command given
    raise _ShowUsage(exit_error=True)

  if cmd == "--version":
    raise _ShowVersion()
  elif cmd == "--help":
    raise _ShowUsage(exit_error=False)
  elif not (cmd in commands or cmd in aliases):
    raise _ShowUsage(exit_error=True)

  # get command, unalias it, and look it up in commands
  if cmd in aliases:
    if aliases[cmd] not in commands:
      raise errors.ProgrammerError("Alias '%s' maps to non-existing"
                                   " command '%s'" % (cmd, aliases[cmd]))

    cmd = aliases[cmd]

  if cmd in env_override:
    args_env_name = ("%s_%s" % (binary.replace("-", "_"), cmd)).upper()
    env_args = os.environ.get(args_env_name)
    if env_args:
      argv = utils.InsertAtPos(argv, 2, shlex.split(env_args))

  func, args_def, parser_opts, usage, description = commands[cmd]
  parser = OptionParser(option_list=parser_opts + COMMON_OPTS,
                        description=description,
                        formatter=TitledHelpFormatter(),
                        usage="%%prog %s %s" % (cmd, usage))
  parser.disable_interspersed_args()
  options, args = parser.parse_args(args=argv[2:])

  if not _CheckArguments(cmd, args_def, args):
    return None, None, None

  return func, options, args


def _FormatUsage(binary, commands):
  """Generates a nice description of all commands.

  @param binary: Script name
  @param commands: Dictionary containing command definitions

  """
  # compute the max line length for cmd + usage
  mlen = min(60, max(map(len, commands)))

  yield "Usage: %s {command} [options...] [argument...]" % binary
  yield "%s <command> --help to see details, or man %s" % (binary, binary)
  yield ""
  yield "Commands:"

  # and format a nice command list
  for (cmd, (_, _, _, _, help_text)) in sorted(commands.items()):
    help_lines = textwrap.wrap(help_text, 79 - 3 - mlen)
    yield " %-*s - %s" % (mlen, cmd, help_lines.pop(0))
    for line in help_lines:
      yield " %-*s   %s" % (mlen, "", line)

  yield ""


def _CheckArguments(cmd, args_def, args):
  """Verifies the arguments using the argument definition.

  Algorithm:

    1. Abort with error if values specified by user but none expected.

    1. For each argument in definition

      1. Keep running count of minimum number of values (min_count)
      1. Keep running count of maximum number of values (max_count)
      1. If it has an unlimited number of values

        1. Abort with error if it's not the last argument in the definition

    1. If last argument has limited number of values

      1. Abort with error if number of values doesn't match or is too large

    1. Abort with error if user didn't pass enough values (min_count)

  """
  if args and not args_def:
    ToStderr("Error: Command %s expects no arguments", cmd)
    return False

  min_count = None
  max_count = None
  check_max = None

  last_idx = len(args_def) - 1

  for idx, arg in enumerate(args_def):
    if min_count is None:
      min_count = arg.min
    elif arg.min is not None:
      min_count += arg.min

    if max_count is None:
      max_count = arg.max
    elif arg.max is not None:
      max_count += arg.max

    if idx == last_idx:
      check_max = (arg.max is not None)

    elif arg.max is None:
      raise errors.ProgrammerError("Only the last argument can have max=None")

  if check_max:
    # Command with exact number of arguments
    if (min_count is not None and max_count is not None and
        min_count == max_count and len(args) != min_count):
      ToStderr("Error: Command %s expects %d argument(s)", cmd, min_count)
      return False

    # Command with limited number of arguments
    if max_count is not None and len(args) > max_count:
      ToStderr("Error: Command %s expects only %d argument(s)",
               cmd, max_count)
      return False

  # Command with some required arguments
  if min_count is not None and len(args) < min_count:
    ToStderr("Error: Command %s expects at least %d argument(s)",
             cmd, min_count)
    return False

  return True


def SplitNodeOption(value):
  """Splits the value of a --node option.

  """
  if value and ":" in value:
    return value.split(":", 1)
  else:
    return (value, None)


def CalculateOSNames(os_name, os_variants):
  """Calculates all the names an OS can be called, according to its variants.

  @type os_name: string
  @param os_name: base name of the os
  @type os_variants: list or None
  @param os_variants: list of supported variants
  @rtype: list
  @return: list of valid names

  """
  if os_variants:
    return ["%s+%s" % (os_name, v) for v in os_variants]
  else:
    return [os_name]


def ParseFields(selected, default):
  """Parses the values of "--field"-like options.

  @type selected: string or None
  @param selected: User-selected options
  @type default: list
  @param default: Default fields

  """
  if selected is None:
    return default

  if selected.startswith("+"):
    return default + selected[1:].split(",")

  return selected.split(",")


UsesRPC = rpc.RunWithRPC


def AskUser(text, choices=None):
  """Ask the user a question.

  @param text: the question to ask

  @param choices: list with elements tuples (input_char, return_value,
      description); if not given, it will default to: [('y', True,
      'Perform the operation'), ('n', False, 'Do no do the operation')];
      note that the '?' char is reserved for help

  @return: one of the return values from the choices list; if input is
      not possible (i.e. not running with a tty, we return the last
      entry from the list

  """
  if choices is None:
    choices = [("y", True, "Perform the operation"),
               ("n", False, "Do not perform the operation")]
  if not choices or not isinstance(choices, list):
    raise errors.ProgrammerError("Invalid choices argument to AskUser")
  for entry in choices:
    if not isinstance(entry, tuple) or len(entry) < 3 or entry[0] == "?":
      raise errors.ProgrammerError("Invalid choices element to AskUser")

  answer = choices[-1][1]
  new_text = []
  for line in text.splitlines():
    new_text.append(textwrap.fill(line, 70, replace_whitespace=False))
  text = "\n".join(new_text)
  try:
    f = file("/dev/tty", "a+")
  except IOError:
    return answer
  try:
    chars = [entry[0] for entry in choices]
    chars[-1] = "[%s]" % chars[-1]
    chars.append("?")
    maps = dict([(entry[0], entry[1]) for entry in choices])
    while True:
      f.write(text)
      f.write("\n")
      f.write("/".join(chars))
      f.write(": ")
      line = f.readline(2).strip().lower()
      if line in maps:
        answer = maps[line]
        break
      elif line == "?":
        for entry in choices:
          f.write(" %s - %s\n" % (entry[0], entry[2]))
        f.write("\n")
        continue
  finally:
    f.close()
  return answer


class JobSubmittedException(Exception):
  """Job was submitted, client should exit.

  This exception has one argument, the ID of the job that was
  submitted. The handler should print this ID.

  This is not an error, just a structured way to exit from clients.

  """


def SendJob(ops, cl=None):
  """Function to submit an opcode without waiting for the results.

  @type ops: list
  @param ops: list of opcodes
  @type cl: luxi.Client
  @param cl: the luxi client to use for communicating with the master;
             if None, a new client will be created

  """
  if cl is None:
    cl = GetClient()

  job_id = cl.SubmitJob(ops)

  return job_id


def GenericPollJob(job_id, cbs, report_cbs, cancel_fn=None,
                   update_freq=constants.DEFAULT_WFJC_TIMEOUT):
  """Generic job-polling function.

  @type job_id: number
  @param job_id: Job ID
  @type cbs: Instance of L{JobPollCbBase}
  @param cbs: Data callbacks
  @type report_cbs: Instance of L{JobPollReportCbBase}
  @param report_cbs: Reporting callbacks
  @type cancel_fn: Function returning a boolean
  @param cancel_fn: Function to check if we should cancel the running job
  @type update_freq: int/long
  @param update_freq: number of seconds between each WFJC reports
  @return: the opresult of the job
  @raise errors.JobLost: If job can't be found
  @raise errors.JobCanceled: If job is canceled
  @raise errors.OpExecError: If job didn't succeed

  """
  prev_job_info = None
  prev_logmsg_serial = None

  status = None
  should_cancel = False

  if update_freq <= 0:
    raise errors.ParameterError("Update frequency must be a positive number")

  while True:
    if cancel_fn:
      timer = 0
      while timer < update_freq:
        result = cbs.WaitForJobChangeOnce(job_id, ["status"], prev_job_info,
                                          prev_logmsg_serial,
                                          timeout=constants.CLI_WFJC_FREQUENCY)
        should_cancel = cancel_fn()
        if should_cancel or not result or result != constants.JOB_NOTCHANGED:
          break
        timer += constants.CLI_WFJC_FREQUENCY
    else:
      result = cbs.WaitForJobChangeOnce(job_id, ["status"], prev_job_info,
                                      prev_logmsg_serial, timeout=update_freq)
    if not result:
      # job not found, go away!
      raise errors.JobLost("Job with id %s lost" % job_id)

    if should_cancel:
      logging.info("Job %s canceled because the client timed out.", job_id)
      cbs.CancelJob(job_id)
      raise errors.JobCanceled("Job was canceled")

    if result == constants.JOB_NOTCHANGED:
      report_cbs.ReportNotChanged(job_id, status)
      # Wait again
      continue

    # Split result, a tuple of (field values, log entries)
    (job_info, log_entries) = result
    (status, ) = job_info

    if log_entries:
      for log_entry in log_entries:
        (serial, timestamp, log_type, message) = log_entry
        report_cbs.ReportLogMessage(job_id, serial, timestamp,
                                    log_type, message)
        prev_logmsg_serial = max(prev_logmsg_serial, serial)

    # TODO: Handle canceled and archived jobs
    elif status in (constants.JOB_STATUS_SUCCESS,
                    constants.JOB_STATUS_ERROR,
                    constants.JOB_STATUS_CANCELING,
                    constants.JOB_STATUS_CANCELED):
      break

    prev_job_info = job_info

  jobs = cbs.QueryJobs([job_id], ["status", "opstatus", "opresult"])
  if not jobs:
    raise errors.JobLost("Job with id %s lost" % job_id)

  status, opstatus, result = jobs[0]

  if status == constants.JOB_STATUS_SUCCESS:
    return result

  if status in (constants.JOB_STATUS_CANCELING, constants.JOB_STATUS_CANCELED):
    raise errors.JobCanceled("Job was canceled")

  has_ok = False
  for idx, (status, msg) in enumerate(zip(opstatus, result)):
    if status == constants.OP_STATUS_SUCCESS:
      has_ok = True
    elif status == constants.OP_STATUS_ERROR:
      errors.MaybeRaise(msg)

      if has_ok:
        raise errors.OpExecError("partial failure (opcode %d): %s" %
                                 (idx, msg))

      raise errors.OpExecError(str(msg))

  # default failure mode
  raise errors.OpExecError(result)


class JobPollCbBase(object):
  """Base class for L{GenericPollJob} callbacks.

  """
  def __init__(self):
    """Initializes this class.

    """

  def WaitForJobChangeOnce(self, job_id, fields,
                           prev_job_info, prev_log_serial,
                           timeout=constants.DEFAULT_WFJC_TIMEOUT):
    """Waits for changes on a job.

    """
    raise NotImplementedError()

  def QueryJobs(self, job_ids, fields):
    """Returns the selected fields for the selected job IDs.

    @type job_ids: list of numbers
    @param job_ids: Job IDs
    @type fields: list of strings
    @param fields: Fields

    """
    raise NotImplementedError()

  def CancelJob(self, job_id):
    """Cancels a currently running job.

    @type job_id: number
    @param job_id: The ID of the Job we want to cancel

    """
    raise NotImplementedError()


class JobPollReportCbBase(object):
  """Base class for L{GenericPollJob} reporting callbacks.

  """
  def __init__(self):
    """Initializes this class.

    """

  def ReportLogMessage(self, job_id, serial, timestamp, log_type, log_msg):
    """Handles a log message.

    """
    raise NotImplementedError()

  def ReportNotChanged(self, job_id, status):
    """Called for if a job hasn't changed in a while.

    @type job_id: number
    @param job_id: Job ID
    @type status: string or None
    @param status: Job status if available

    """
    raise NotImplementedError()


class _LuxiJobPollCb(JobPollCbBase):
  def __init__(self, cl):
    """Initializes this class.

    """
    JobPollCbBase.__init__(self)
    self.cl = cl

  def WaitForJobChangeOnce(self, job_id, fields,
                           prev_job_info, prev_log_serial,
                           timeout=constants.DEFAULT_WFJC_TIMEOUT):
    """Waits for changes on a job.

    """
    return self.cl.WaitForJobChangeOnce(job_id, fields,
                                        prev_job_info, prev_log_serial,
                                        timeout=timeout)

  def QueryJobs(self, job_ids, fields):
    """Returns the selected fields for the selected job IDs.

    """
    return self.cl.QueryJobs(job_ids, fields)

  def CancelJob(self, job_id):
    """Cancels a currently running job.

    """
    return self.cl.CancelJob(job_id)

class FeedbackFnJobPollReportCb(JobPollReportCbBase):
  def __init__(self, feedback_fn):
    """Initializes this class.

    """
    JobPollReportCbBase.__init__(self)

    self.feedback_fn = feedback_fn

    assert callable(feedback_fn)

  def ReportLogMessage(self, job_id, serial, timestamp, log_type, log_msg):
    """Handles a log message.

    """
    self.feedback_fn((timestamp, log_type, log_msg))

  def ReportNotChanged(self, job_id, status):
    """Called if a job hasn't changed in a while.

    """
    # Ignore


class StdioJobPollReportCb(JobPollReportCbBase):
  def __init__(self):
    """Initializes this class.

    """
    JobPollReportCbBase.__init__(self)

    self.notified_queued = False
    self.notified_waitlock = False

  def ReportLogMessage(self, job_id, serial, timestamp, log_type, log_msg):
    """Handles a log message.

    """
    ToStdout("%s %s", time.ctime(utils.MergeTime(timestamp)),
             FormatLogMessage(log_type, log_msg))

  def ReportNotChanged(self, job_id, status):
    """Called if a job hasn't changed in a while.

    """
    if status is None:
      return

    if status == constants.JOB_STATUS_QUEUED and not self.notified_queued:
      ToStderr("Job %s is waiting in queue", job_id)
      self.notified_queued = True

    elif status == constants.JOB_STATUS_WAITING and not self.notified_waitlock:
      ToStderr("Job %s is trying to acquire all necessary locks", job_id)
      self.notified_waitlock = True


def FormatLogMessage(log_type, log_msg):
  """Formats a job message according to its type.

  """
  if log_type != constants.ELOG_MESSAGE:
    log_msg = str(log_msg)

  return utils.SafeEncode(log_msg)


def PollJob(job_id, cl=None, feedback_fn=None, reporter=None, cancel_fn=None,
            update_freq=constants.DEFAULT_WFJC_TIMEOUT):
  """Function to poll for the result of a job.

  @type job_id: job identified
  @param job_id: the job to poll for results
  @type cl: luxi.Client
  @param cl: the luxi client to use for communicating with the master;
             if None, a new client will be created
  @type cancel_fn: Function returning a boolean
  @param cancel_fn: Function to check if we should cancel the running job
  @type update_freq: int/long
  @param update_freq: number of seconds between each WFJC report

  """
  if cl is None:
    cl = GetClient()

  if reporter is None:
    if feedback_fn:
      reporter = FeedbackFnJobPollReportCb(feedback_fn)
    else:
      reporter = StdioJobPollReportCb()
  elif feedback_fn:
    raise errors.ProgrammerError("Can't specify reporter and feedback function")

  return GenericPollJob(job_id, _LuxiJobPollCb(cl), reporter,
                        cancel_fn=cancel_fn, update_freq=update_freq)


def SubmitOpCode(op, cl=None, feedback_fn=None, opts=None, reporter=None):
  """Legacy function to submit an opcode.

  This is just a simple wrapper over the construction of the processor
  instance. It should be extended to better handle feedback and
  interaction functions.

  """
  if cl is None:
    cl = GetClient()

  SetGenericOpcodeOpts([op], opts)

  job_id = SendJob([op], cl=cl)
  if hasattr(opts, "print_jobid") and opts.print_jobid:
    ToStdout("%d" % job_id)

  op_results = PollJob(job_id, cl=cl, feedback_fn=feedback_fn,
                       reporter=reporter)

  return op_results[0]


def SubmitOpCodeToDrainedQueue(op):
  """Forcefully insert a job in the queue, even if it is drained.

  """
  cl = GetClient()
  job_id = cl.SubmitJobToDrainedQueue([op])
  op_results = PollJob(job_id, cl=cl)
  return op_results[0]


def SubmitOrSend(op, opts, cl=None, feedback_fn=None):
  """Wrapper around SubmitOpCode or SendJob.

  This function will decide, based on the 'opts' parameter, whether to
  submit and wait for the result of the opcode (and return it), or
  whether to just send the job and print its identifier. It is used in
  order to simplify the implementation of the '--submit' option.

  It will also process the opcodes if we're sending the via SendJob
  (otherwise SubmitOpCode does it).

  """
  if opts and opts.submit_only:
    job = [op]
    SetGenericOpcodeOpts(job, opts)
    job_id = SendJob(job, cl=cl)
    if opts.print_jobid:
      ToStdout("%d" % job_id)
    raise JobSubmittedException(job_id)
  else:
    return SubmitOpCode(op, cl=cl, feedback_fn=feedback_fn, opts=opts)


def _InitReasonTrail(op, opts):
  """Builds the first part of the reason trail

  Builds the initial part of the reason trail, adding the user provided reason
  (if it exists) and the name of the command starting the operation.

  @param op: the opcode the reason trail will be added to
  @param opts: the command line options selected by the user

  """
  assert len(sys.argv) >= 2
  trail = []

  if opts.reason:
    trail.append((constants.OPCODE_REASON_SRC_USER,
                  opts.reason,
                  utils.EpochNano()))

  binary = os.path.basename(sys.argv[0])
  source = "%s:%s" % (constants.OPCODE_REASON_SRC_CLIENT, binary)
  command = sys.argv[1]
  trail.append((source, command, utils.EpochNano()))
  op.reason = trail


def SetGenericOpcodeOpts(opcode_list, options):
  """Processor for generic options.

  This function updates the given opcodes based on generic command
  line options (like debug, dry-run, etc.).

  @param opcode_list: list of opcodes
  @param options: command line options or None
  @return: None (in-place modification)

  """
  if not options:
    return
  for op in opcode_list:
    op.debug_level = options.debug
    if hasattr(options, "dry_run"):
      op.dry_run = options.dry_run
    if getattr(options, "priority", None) is not None:
      op.priority = options.priority
    _InitReasonTrail(op, options)


def FormatError(err):
  """Return a formatted error message for a given error.

  This function takes an exception instance and returns a tuple
  consisting of two values: first, the recommended exit code, and
  second, a string describing the error message (not
  newline-terminated).

  """
  retcode = 1
  obuf = StringIO()
  msg = str(err)
  if isinstance(err, errors.ConfigurationError):
    txt = "Corrupt configuration file: %s" % msg
    logging.error(txt)
    obuf.write(txt + "\n")
    obuf.write("Aborting.")
    retcode = 2
  elif isinstance(err, errors.HooksAbort):
    obuf.write("Failure: hooks execution failed:\n")
    for node, script, out in err.args[0]:
      if out:
        obuf.write("  node: %s, script: %s, output: %s\n" %
                   (node, script, out))
      else:
        obuf.write("  node: %s, script: %s (no output)\n" %
                   (node, script))
  elif isinstance(err, errors.HooksFailure):
    obuf.write("Failure: hooks general failure: %s" % msg)
  elif isinstance(err, errors.ResolverError):
    this_host = netutils.Hostname.GetSysName()
    if err.args[0] == this_host:
      msg = "Failure: can't resolve my own hostname ('%s')"
    else:
      msg = "Failure: can't resolve hostname '%s'"
    obuf.write(msg % err.args[0])
  elif isinstance(err, errors.OpPrereqError):
    if len(err.args) == 2:
      obuf.write("Failure: prerequisites not met for this"
                 " operation:\nerror type: %s, error details:\n%s" %
                 (err.args[1], err.args[0]))
    else:
      obuf.write("Failure: prerequisites not met for this"
                 " operation:\n%s" % msg)
  elif isinstance(err, errors.OpExecError):
    obuf.write("Failure: command execution error:\n%s" % msg)
  elif isinstance(err, errors.TagError):
    obuf.write("Failure: invalid tag(s) given:\n%s" % msg)
  elif isinstance(err, errors.JobQueueDrainError):
    obuf.write("Failure: the job queue is marked for drain and doesn't"
               " accept new requests\n")
  elif isinstance(err, errors.JobQueueFull):
    obuf.write("Failure: the job queue is full and doesn't accept new"
               " job submissions until old jobs are archived\n")
  elif isinstance(err, errors.TypeEnforcementError):
    obuf.write("Parameter Error: %s" % msg)
  elif isinstance(err, errors.ParameterError):
    obuf.write("Failure: unknown/wrong parameter name '%s'" % msg)
  elif isinstance(err, rpcerr.NoMasterError):
    if err.args[0] == pathutils.MASTER_SOCKET:
      daemon = "the master daemon"
    elif err.args[0] == pathutils.QUERY_SOCKET:
      daemon = "the config daemon"
    else:
      daemon = "socket '%s'" % str(err.args[0])
    obuf.write("Cannot communicate with %s.\nIs the process running"
               " and listening for connections?" % daemon)
  elif isinstance(err, rpcerr.TimeoutError):
    obuf.write("Timeout while talking to the master daemon. Jobs might have"
               " been submitted and will continue to run even if the call"
               " timed out. Useful commands in this situation are \"gnt-job"
               " list\", \"gnt-job cancel\" and \"gnt-job watch\". Error:\n")
    obuf.write(msg)
  elif isinstance(err, rpcerr.PermissionError):
    obuf.write("It seems you don't have permissions to connect to the"
               " master daemon.\nPlease retry as a different user.")
  elif isinstance(err, rpcerr.ProtocolError):
    obuf.write("Unhandled protocol error while talking to the master daemon:\n"
               "%s" % msg)
  elif isinstance(err, errors.JobLost):
    obuf.write("Error checking job status: %s" % msg)
  elif isinstance(err, errors.QueryFilterParseError):
    obuf.write("Error while parsing query filter: %s\n" % err.args[0])
    obuf.write("\n".join(err.GetDetails()))
  elif isinstance(err, errors.GenericError):
    obuf.write("Unhandled Ganeti error: %s" % msg)
  elif isinstance(err, JobSubmittedException):
    obuf.write("JobID: %s\n" % err.args[0])
    retcode = 0
  else:
    obuf.write("Unhandled exception: %s" % msg)
  return retcode, obuf.getvalue().rstrip("\n")


def GenericMain(commands, override=None, aliases=None,
                env_override=frozenset()):
  """Generic main function for all the gnt-* commands.

  @param commands: a dictionary with a special structure, see the design doc
                   for command line handling.
  @param override: if not None, we expect a dictionary with keys that will
                   override command line options; this can be used to pass
                   options from the scripts to generic functions
  @param aliases: dictionary with command aliases {'alias': 'target, ...}
  @param env_override: list of environment names which are allowed to submit
                       default args for commands

  """
  # save the program name and the entire command line for later logging
  if sys.argv:
    binary = os.path.basename(sys.argv[0])
    if not binary:
      binary = sys.argv[0]

    if len(sys.argv) >= 2:
      logname = utils.ShellQuoteArgs([binary, sys.argv[1]])
    else:
      logname = binary

    cmdline = utils.ShellQuoteArgs([binary] + sys.argv[1:])
  else:
    binary = "<unknown program>"
    cmdline = "<unknown>"

  if aliases is None:
    aliases = {}

  try:
    (func, options, args) = _ParseArgs(binary, sys.argv, commands, aliases,
                                       env_override)
  except _ShowVersion:
    ToStdout("%s (ganeti %s) %s", binary, constants.VCS_VERSION,
             constants.RELEASE_VERSION)
    return constants.EXIT_SUCCESS
  except _ShowUsage, err:
    for line in _FormatUsage(binary, commands):
      ToStdout(line)

    if err.exit_error:
      return constants.EXIT_FAILURE
    else:
      return constants.EXIT_SUCCESS
  except errors.ParameterError, err:
    result, err_msg = FormatError(err)
    ToStderr(err_msg)
    return 1

  if func is None: # parse error
    return 1

  if override is not None:
    for key, val in override.iteritems():
      setattr(options, key, val)

  utils.SetupLogging(pathutils.LOG_COMMANDS, logname, debug=options.debug,
                     stderr_logging=True)

  logging.debug("Command line: %s", cmdline)

  try:
    result = func(options, args)
  except (errors.GenericError, rpcerr.ProtocolError,
          JobSubmittedException), err:
    result, err_msg = FormatError(err)
    logging.exception("Error during command processing")
    ToStderr(err_msg)
  except KeyboardInterrupt:
    result = constants.EXIT_FAILURE
    ToStderr("Aborted. Note that if the operation created any jobs, they"
             " might have been submitted and"
             " will continue to run in the background.")
  except IOError, err:
    if err.errno == errno.EPIPE:
      # our terminal went away, we'll exit
      sys.exit(constants.EXIT_FAILURE)
    else:
      raise

  return result


def ParseNicOption(optvalue):
  """Parses the value of the --net option(s).

  """
  try:
    nic_max = max(int(nidx[0]) + 1 for nidx in optvalue)
  except (TypeError, ValueError), err:
    raise errors.OpPrereqError("Invalid NIC index passed: %s" % str(err),
                               errors.ECODE_INVAL)

  nics = [{}] * nic_max
  for nidx, ndict in optvalue:
    nidx = int(nidx)

    if not isinstance(ndict, dict):
      raise errors.OpPrereqError("Invalid nic/%d value: expected dict,"
                                 " got %s" % (nidx, ndict), errors.ECODE_INVAL)

    utils.ForceDictType(ndict, constants.INIC_PARAMS_TYPES)

    nics[nidx] = ndict

  return nics


def FixHvParams(hvparams):
  # In Ganeti 2.8.4 the separator for the usb_devices hvparam was changed from
  # comma to space because commas cannot be accepted on the command line
  # (they already act as the separator between different hvparams). Still,
  # RAPI should be able to accept commas for backwards compatibility.
  # Therefore, we convert spaces into commas here, and we keep the old
  # parsing logic everywhere else.
  try:
    new_usb_devices = hvparams[constants.HV_USB_DEVICES].replace(" ", ",")
    hvparams[constants.HV_USB_DEVICES] = new_usb_devices
  except KeyError:
    #No usb_devices, no modification required
    pass


def GenericInstanceCreate(mode, opts, args):
  """Add an instance to the cluster via either creation or import.

  @param mode: constants.INSTANCE_CREATE or constants.INSTANCE_IMPORT
  @param opts: the command line options selected by the user
  @type args: list
  @param args: should contain only one element, the new instance name
  @rtype: int
  @return: the desired exit code

  """
  instance = args[0]
  forthcoming = opts.ensure_value("forthcoming", False)
  commit = opts.ensure_value("commit", False)

  if forthcoming and commit:
    raise errors.OpPrereqError("Creating an instance only forthcoming and"
                               " commiting it are mutally exclusive",
                               errors.ECODE_INVAL)

  (pnode, snode) = SplitNodeOption(opts.node)

  hypervisor = None
  hvparams = {}
  if opts.hypervisor:
    hypervisor, hvparams = opts.hypervisor

  if opts.nics:
    nics = ParseNicOption(opts.nics)
  elif opts.no_nics:
    # no nics
    nics = []
  elif mode == constants.INSTANCE_CREATE:
    # default of one nic, all auto
    nics = [{}]
  else:
    # mode == import
    nics = []

  if opts.disk_template == constants.DT_DISKLESS:
    if opts.disks or opts.sd_size is not None:
      raise errors.OpPrereqError("Diskless instance but disk"
                                 " information passed", errors.ECODE_INVAL)
    disks = []
  else:
    if (not opts.disks and not opts.sd_size
        and mode == constants.INSTANCE_CREATE):
      raise errors.OpPrereqError("No disk information specified",
                                 errors.ECODE_INVAL)
    if opts.disks and opts.sd_size is not None:
      raise errors.OpPrereqError("Please use either the '--disk' or"
                                 " '-s' option", errors.ECODE_INVAL)
    if opts.sd_size is not None:
      opts.disks = [(0, {constants.IDISK_SIZE: opts.sd_size})]

    if opts.disks:
      try:
        disk_max = max(int(didx[0]) + 1 for didx in opts.disks)
      except ValueError, err:
        raise errors.OpPrereqError("Invalid disk index passed: %s" % str(err),
                                   errors.ECODE_INVAL)
      disks = [{}] * disk_max
    else:
      disks = []
    for didx, ddict in opts.disks:
      didx = int(didx)
      if not isinstance(ddict, dict):
        msg = "Invalid disk/%d value: expected dict, got %s" % (didx, ddict)
        raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
      elif constants.IDISK_SIZE in ddict:
        if constants.IDISK_ADOPT in ddict:
          raise errors.OpPrereqError("Only one of 'size' and 'adopt' allowed"
                                     " (disk %d)" % didx, errors.ECODE_INVAL)
        try:
          ddict[constants.IDISK_SIZE] = \
            utils.ParseUnit(ddict[constants.IDISK_SIZE])
        except ValueError, err:
          raise errors.OpPrereqError("Invalid disk size for disk %d: %s" %
                                     (didx, err), errors.ECODE_INVAL)
      elif constants.IDISK_ADOPT in ddict:
        if constants.IDISK_SPINDLES in ddict:
          raise errors.OpPrereqError("spindles is not a valid option when"
                                     " adopting a disk", errors.ECODE_INVAL)
        if mode == constants.INSTANCE_IMPORT:
          raise errors.OpPrereqError("Disk adoption not allowed for instance"
                                     " import", errors.ECODE_INVAL)
        ddict[constants.IDISK_SIZE] = 0
      else:
        raise errors.OpPrereqError("Missing size or adoption source for"
                                   " disk %d" % didx, errors.ECODE_INVAL)
      if constants.IDISK_SPINDLES in ddict:
        ddict[constants.IDISK_SPINDLES] = int(ddict[constants.IDISK_SPINDLES])

      disks[didx] = ddict

  if opts.tags is not None:
    tags = opts.tags.split(",")
  else:
    tags = []

  utils.ForceDictType(opts.beparams, constants.BES_PARAMETER_COMPAT)
  utils.ForceDictType(hvparams, constants.HVS_PARAMETER_TYPES)
  FixHvParams(hvparams)

  osparams_private = opts.osparams_private or serializer.PrivateDict()
  osparams_secret = opts.osparams_secret or serializer.PrivateDict()

  helper_startup_timeout = opts.helper_startup_timeout
  helper_shutdown_timeout = opts.helper_shutdown_timeout

  if mode == constants.INSTANCE_CREATE:
    start = opts.start
    os_type = opts.os
    force_variant = opts.force_variant
    src_node = None
    src_path = None
    no_install = opts.no_install
    identify_defaults = False
    compress = constants.IEC_NONE
    if opts.instance_communication is None:
      instance_communication = False
    else:
      instance_communication = opts.instance_communication
  elif mode == constants.INSTANCE_IMPORT:
    if forthcoming:
      raise errors.OpPrereqError("forthcoming instances can only be created,"
                                 " not imported")
    start = False
    os_type = None
    force_variant = False
    src_node = opts.src_node
    src_path = opts.src_dir
    no_install = None
    identify_defaults = opts.identify_defaults
    compress = opts.compress
    instance_communication = False
  else:
    raise errors.ProgrammerError("Invalid creation mode %s" % mode)

  op = opcodes.OpInstanceCreate(
    forthcoming=forthcoming,
    commit=commit,
    instance_name=instance,
    disks=disks,
    disk_template=opts.disk_template,
    group_name=opts.nodegroup,
    nics=nics,
    conflicts_check=opts.conflicts_check,
    pnode=pnode, snode=snode,
    ip_check=opts.ip_check,
    name_check=opts.name_check,
    wait_for_sync=opts.wait_for_sync,
    file_storage_dir=opts.file_storage_dir,
    file_driver=opts.file_driver,
    iallocator=opts.iallocator,
    hypervisor=hypervisor,
    hvparams=hvparams,
    beparams=opts.beparams,
    osparams=opts.osparams,
    osparams_private=osparams_private,
    osparams_secret=osparams_secret,
    mode=mode,
    opportunistic_locking=opts.opportunistic_locking,
    start=start,
    os_type=os_type,
    force_variant=force_variant,
    src_node=src_node,
    src_path=src_path,
    compress=compress,
    tags=tags,
    no_install=no_install,
    identify_defaults=identify_defaults,
    ignore_ipolicy=opts.ignore_ipolicy,
    instance_communication=instance_communication,
    helper_startup_timeout=helper_startup_timeout,
    helper_shutdown_timeout=helper_shutdown_timeout)

  SubmitOrSend(op, opts)
  return 0


class _RunWhileDaemonsStoppedHelper(object):
  """Helper class for L{RunWhileDaemonsStopped} to simplify state management

  """
  def __init__(self, feedback_fn, cluster_name, master_node,
               online_nodes, ssh_ports, exclude_daemons, debug,
               verbose):
    """Initializes this class.

    @type feedback_fn: callable
    @param feedback_fn: Feedback function
    @type cluster_name: string
    @param cluster_name: Cluster name
    @type master_node: string
    @param master_node Master node name
    @type online_nodes: list
    @param online_nodes: List of names of online nodes
    @type ssh_ports: list
    @param ssh_ports: List of SSH ports of online nodes
    @type exclude_daemons: list of string
    @param exclude_daemons: list of daemons that will be restarted on master
                            after all others are shutdown
    @type debug: boolean
    @param debug: show debug output
    @type verbose: boolesn
    @param verbose: show verbose output

    """
    self.feedback_fn = feedback_fn
    self.cluster_name = cluster_name
    self.master_node = master_node
    self.online_nodes = online_nodes
    self.ssh_ports = dict(zip(online_nodes, ssh_ports))

    self.ssh = ssh.SshRunner(self.cluster_name)

    self.nonmaster_nodes = [name for name in online_nodes
                            if name != master_node]

    self.exclude_daemons = exclude_daemons
    self.debug = debug
    self.verbose = verbose

    assert self.master_node not in self.nonmaster_nodes

  def _RunCmd(self, node_name, cmd):
    """Runs a command on the local or a remote machine.

    @type node_name: string
    @param node_name: Machine name
    @type cmd: list
    @param cmd: Command

    """
    if node_name is None or node_name == self.master_node:
      # No need to use SSH
      result = utils.RunCmd(cmd)
    else:
      result = self.ssh.Run(node_name, constants.SSH_LOGIN_USER,
                            utils.ShellQuoteArgs(cmd),
                            port=self.ssh_ports[node_name])

    if result.failed:
      errmsg = ["Failed to run command %s" % result.cmd]
      if node_name:
        errmsg.append("on node %s" % node_name)
      errmsg.append(": exitcode %s and error %s" %
                    (result.exit_code, result.output))
      raise errors.OpExecError(" ".join(errmsg))

  def Call(self, fn, *args):
    """Call function while all daemons are stopped.

    @type fn: callable
    @param fn: Function to be called

    """
    # Pause watcher by acquiring an exclusive lock on watcher state file
    self.feedback_fn("Blocking watcher")
    watcher_block = utils.FileLock.Open(pathutils.WATCHER_LOCK_FILE)
    try:
      # TODO: Currently, this just blocks. There's no timeout.
      # TODO: Should it be a shared lock?
      watcher_block.Exclusive(blocking=True)

      # Stop master daemons, so that no new jobs can come in and all running
      # ones are finished
      self.feedback_fn("Stopping master daemons")
      self._RunCmd(None, [pathutils.DAEMON_UTIL, "stop-master"])
      try:
        # Stop daemons on all nodes
        online_nodes = [self.master_node] + [n for n in self.online_nodes
                                             if n != self.master_node]
        for node_name in online_nodes:
          self.feedback_fn("Stopping daemons on %s" % node_name)
          self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "stop-all"])
          # Starting any daemons listed as exception
          if node_name == self.master_node:
            for daemon in self.exclude_daemons:
              self.feedback_fn("Starting daemon '%s' on %s" % (daemon,
                                                               node_name))
              self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "start", daemon])

        # All daemons are shut down now
        try:
          return fn(self, *args)
        except Exception, err:
          _, errmsg = FormatError(err)
          logging.exception("Caught exception")
          self.feedback_fn(errmsg)
          raise
      finally:
        # Start cluster again, master node last
        for node_name in self.nonmaster_nodes + [self.master_node]:
          # Stopping any daemons listed as exception.
          # This might look unnecessary, but it makes sure that daemon-util
          # starts all daemons in the right order.
          if node_name == self.master_node:
            self.exclude_daemons.reverse()
            for daemon in self.exclude_daemons:
              self.feedback_fn("Stopping daemon '%s' on %s" % (daemon,
                                                               node_name))
              self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "stop", daemon])
          self.feedback_fn("Starting daemons on %s" % node_name)
          self._RunCmd(node_name, [pathutils.DAEMON_UTIL, "start-all"])

    finally:
      # Resume watcher
      watcher_block.Close()


def RunWhileDaemonsStopped(feedback_fn, exclude_daemons, fn, *args, **kwargs):
  """Calls a function while all cluster daemons are stopped.

  @type feedback_fn: callable
  @param feedback_fn: Feedback function
  @type exclude_daemons: list of string
  @param exclude_daemons: list of daemons that stopped, but immediately
                          restarted on the master to be available when calling
                          'fn'. If None, all daemons will be stopped and none
                          will be started before calling 'fn'.
  @type fn: callable
  @param fn: Function to be called when daemons are stopped

  """
  feedback_fn("Gathering cluster information")

  # This ensures we're running on the master daemon
  cl = GetClient()

  (cluster_name, master_node) = \
    cl.QueryConfigValues(["cluster_name", "master_node"])

  online_nodes = GetOnlineNodes([], cl=cl)
  ssh_ports = GetNodesSshPorts(online_nodes, cl)

  # Don't keep a reference to the client. The master daemon will go away.
  del cl

  assert master_node in online_nodes
  if exclude_daemons is None:
    exclude_daemons = []

  debug = kwargs.get("debug", False)
  verbose = kwargs.get("verbose", False)

  return _RunWhileDaemonsStoppedHelper(
      feedback_fn, cluster_name, master_node, online_nodes, ssh_ports,
      exclude_daemons, debug, verbose).Call(fn, *args)


def RunWhileClusterStopped(feedback_fn, fn, *args):
  """Calls a function while all cluster daemons are stopped.

  @type feedback_fn: callable
  @param feedback_fn: Feedback function
  @type fn: callable
  @param fn: Function to be called when daemons are stopped

  """
  RunWhileDaemonsStopped(feedback_fn, None, fn, *args)


def GenerateTable(headers, fields, separator, data,
                  numfields=None, unitfields=None,
                  units=None):
  """Prints a table with headers and different fields.

  @type headers: dict
  @param headers: dictionary mapping field names to headers for
      the table
  @type fields: list
  @param fields: the field names corresponding to each row in
      the data field
  @param separator: the separator to be used; if this is None,
      the default 'smart' algorithm is used which computes optimal
      field width, otherwise just the separator is used between
      each field
  @type data: list
  @param data: a list of lists, each sublist being one row to be output
  @type numfields: list
  @param numfields: a list with the fields that hold numeric
      values and thus should be right-aligned
  @type unitfields: list
  @param unitfields: a list with the fields that hold numeric
      values that should be formatted with the units field
  @type units: string or None
  @param units: the units we should use for formatting, or None for
      automatic choice (human-readable for non-separator usage, otherwise
      megabytes); this is a one-letter string

  """
  if units is None:
    if separator:
      units = "m"
    else:
      units = "h"

  if numfields is None:
    numfields = []
  if unitfields is None:
    unitfields = []

  numfields = utils.FieldSet(*numfields)   # pylint: disable=W0142
  unitfields = utils.FieldSet(*unitfields) # pylint: disable=W0142

  format_fields = []
  for field in fields:
    if headers and field not in headers:
      # TODO: handle better unknown fields (either revert to old
      # style of raising exception, or deal more intelligently with
      # variable fields)
      headers[field] = field
    if separator is not None:
      format_fields.append("%s")
    elif numfields.Matches(field):
      format_fields.append("%*s")
    else:
      format_fields.append("%-*s")

  if separator is None:
    mlens = [0 for name in fields]
    format_str = " ".join(format_fields)
  else:
    format_str = separator.replace("%", "%%").join(format_fields)

  for row in data:
    if row is None:
      continue
    for idx, val in enumerate(row):
      if unitfields.Matches(fields[idx]):
        try:
          val = int(val)
        except (TypeError, ValueError):
          pass
        else:
          val = row[idx] = utils.FormatUnit(val, units)
      val = row[idx] = str(val)
      if separator is None:
        mlens[idx] = max(mlens[idx], len(val))

  result = []
  if headers:
    args = []
    for idx, name in enumerate(fields):
      hdr = headers[name]
      if separator is None:
        mlens[idx] = max(mlens[idx], len(hdr))
        args.append(mlens[idx])
      args.append(hdr)
    result.append(format_str % tuple(args))

  if separator is None:
    assert len(mlens) == len(fields)

    if fields and not numfields.Matches(fields[-1]):
      mlens[-1] = 0

  for line in data:
    args = []
    if line is None:
      line = ["-" for _ in fields]
    for idx in range(len(fields)):
      if separator is None:
        args.append(mlens[idx])
      args.append(line[idx])
    result.append(format_str % tuple(args))

  return result


def _FormatBool(value):
  """Formats a boolean value as a string.

  """
  if value:
    return "Y"
  return "N"


#: Default formatting for query results; (callback, align right)
_DEFAULT_FORMAT_QUERY = {
  constants.QFT_TEXT: (str, False),
  constants.QFT_BOOL: (_FormatBool, False),
  constants.QFT_NUMBER: (str, True),
  constants.QFT_NUMBER_FLOAT: (str, True),
  constants.QFT_TIMESTAMP: (utils.FormatTime, False),
  constants.QFT_OTHER: (str, False),
  constants.QFT_UNKNOWN: (str, False),
  }


def _GetColumnFormatter(fdef, override, unit):
  """Returns formatting function for a field.

  @type fdef: L{objects.QueryFieldDefinition}
  @type override: dict
  @param override: Dictionary for overriding field formatting functions,
    indexed by field name, contents like L{_DEFAULT_FORMAT_QUERY}
  @type unit: string
  @param unit: Unit used for formatting fields of type L{constants.QFT_UNIT}
  @rtype: tuple; (callable, bool)
  @return: Returns the function to format a value (takes one parameter) and a
    boolean for aligning the value on the right-hand side

  """
  fmt = override.get(fdef.name, None)
  if fmt is not None:
    return fmt

  assert constants.QFT_UNIT not in _DEFAULT_FORMAT_QUERY

  if fdef.kind == constants.QFT_UNIT:
    # Can't keep this information in the static dictionary
    return (lambda value: utils.FormatUnit(value, unit), True)

  fmt = _DEFAULT_FORMAT_QUERY.get(fdef.kind, None)
  if fmt is not None:
    return fmt

  raise NotImplementedError("Can't format column type '%s'" % fdef.kind)


class _QueryColumnFormatter(object):
  """Callable class for formatting fields of a query.

  """
  def __init__(self, fn, status_fn, verbose):
    """Initializes this class.

    @type fn: callable
    @param fn: Formatting function
    @type status_fn: callable
    @param status_fn: Function to report fields' status
    @type verbose: boolean
    @param verbose: whether to use verbose field descriptions or not

    """
    self._fn = fn
    self._status_fn = status_fn
    self._verbose = verbose

  def __call__(self, data):
    """Returns a field's string representation.

    """
    (status, value) = data

    # Report status
    self._status_fn(status)

    if status == constants.RS_NORMAL:
      return self._fn(value)

    assert value is None, \
           "Found value %r for abnormal status %s" % (value, status)

    return FormatResultError(status, self._verbose)


def FormatResultError(status, verbose):
  """Formats result status other than L{constants.RS_NORMAL}.

  @param status: The result status
  @type verbose: boolean
  @param verbose: Whether to return the verbose text
  @return: Text of result status

  """
  assert status != constants.RS_NORMAL, \
         "FormatResultError called with status equal to constants.RS_NORMAL"
  try:
    (verbose_text, normal_text) = constants.RSS_DESCRIPTION[status]
  except KeyError:
    raise NotImplementedError("Unknown status %s" % status)
  else:
    if verbose:
      return verbose_text
    return normal_text


def FormatQueryResult(result, unit=None, format_override=None, separator=None,
                      header=False, verbose=False):
  """Formats data in L{objects.QueryResponse}.

  @type result: L{objects.QueryResponse}
  @param result: result of query operation
  @type unit: string
  @param unit: Unit used for formatting fields of type L{constants.QFT_UNIT},
    see L{utils.text.FormatUnit}
  @type format_override: dict
  @param format_override: Dictionary for overriding field formatting functions,
    indexed by field name, contents like L{_DEFAULT_FORMAT_QUERY}
  @type separator: string or None
  @param separator: String used to separate fields
  @type header: bool
  @param header: Whether to output header row
  @type verbose: boolean
  @param verbose: whether to use verbose field descriptions or not

  """
  if unit is None:
    if separator:
      unit = "m"
    else:
      unit = "h"

  if format_override is None:
    format_override = {}

  stats = dict.fromkeys(constants.RS_ALL, 0)

  def _RecordStatus(status):
    if status in stats:
      stats[status] += 1

  columns = []
  for fdef in result.fields:
    assert fdef.title and fdef.name
    (fn, align_right) = _GetColumnFormatter(fdef, format_override, unit)
    columns.append(TableColumn(fdef.title,
                               _QueryColumnFormatter(fn, _RecordStatus,
                                                     verbose),
                               align_right))

  table = FormatTable(result.data, columns, header, separator)

  # Collect statistics
  assert len(stats) == len(constants.RS_ALL)
  assert compat.all(count >= 0 for count in stats.values())

  # Determine overall status. If there was no data, unknown fields must be
  # detected via the field definitions.
  if (stats[constants.RS_UNKNOWN] or
      (not result.data and _GetUnknownFields(result.fields))):
    status = QR_UNKNOWN
  elif compat.any(count > 0 for key, count in stats.items()
                  if key != constants.RS_NORMAL):
    status = QR_INCOMPLETE
  else:
    status = QR_NORMAL

  return (status, table)


def _GetUnknownFields(fdefs):
  """Returns list of unknown fields included in C{fdefs}.

  @type fdefs: list of L{objects.QueryFieldDefinition}

  """
  return [fdef for fdef in fdefs
          if fdef.kind == constants.QFT_UNKNOWN]


def _WarnUnknownFields(fdefs):
  """Prints a warning to stderr if a query included unknown fields.

  @type fdefs: list of L{objects.QueryFieldDefinition}

  """
  unknown = _GetUnknownFields(fdefs)
  if unknown:
    ToStderr("Warning: Queried for unknown fields %s",
             utils.CommaJoin(fdef.name for fdef in unknown))
    return True

  return False


def GenericList(resource, fields, names, unit, separator, header, cl=None,
                format_override=None, verbose=False, force_filter=False,
                namefield=None, qfilter=None, isnumeric=False):
  """Generic implementation for listing all items of a resource.

  @param resource: One of L{constants.QR_VIA_LUXI}
  @type fields: list of strings
  @param fields: List of fields to query for
  @type names: list of strings
  @param names: Names of items to query for
  @type unit: string or None
  @param unit: Unit used for formatting fields of type L{constants.QFT_UNIT} or
    None for automatic choice (human-readable for non-separator usage,
    otherwise megabytes); this is a one-letter string
  @type separator: string or None
  @param separator: String used to separate fields
  @type header: bool
  @param header: Whether to show header row
  @type force_filter: bool
  @param force_filter: Whether to always treat names as filter
  @type format_override: dict
  @param format_override: Dictionary for overriding field formatting functions,
    indexed by field name, contents like L{_DEFAULT_FORMAT_QUERY}
  @type verbose: boolean
  @param verbose: whether to use verbose field descriptions or not
  @type namefield: string
  @param namefield: Name of field to use for simple filters (see
    L{qlang.MakeFilter} for details)
  @type qfilter: list or None
  @param qfilter: Query filter (in addition to names)
  @param isnumeric: bool
  @param isnumeric: Whether the namefield's type is numeric, and therefore
    any simple filters built by namefield should use integer values to
    reflect that

  """
  if not names:
    names = None

  namefilter = qlang.MakeFilter(names, force_filter, namefield=namefield,
                                isnumeric=isnumeric)

  if qfilter is None:
    qfilter = namefilter
  elif namefilter is not None:
    qfilter = [qlang.OP_AND, namefilter, qfilter]

  if cl is None:
    cl = GetClient()

  response = cl.Query(resource, fields, qfilter)

  found_unknown = _WarnUnknownFields(response.fields)

  (status, data) = FormatQueryResult(response, unit=unit, separator=separator,
                                     header=header,
                                     format_override=format_override,
                                     verbose=verbose)

  for line in data:
    ToStdout(line)

  assert ((found_unknown and status == QR_UNKNOWN) or
          (not found_unknown and status != QR_UNKNOWN))

  if status == QR_UNKNOWN:
    return constants.EXIT_UNKNOWN_FIELD

  # TODO: Should the list command fail if not all data could be collected?
  return constants.EXIT_SUCCESS


def _FieldDescValues(fdef):
  """Helper function for L{GenericListFields} to get query field description.

  @type fdef: L{objects.QueryFieldDefinition}
  @rtype: list

  """
  return [
    fdef.name,
    _QFT_NAMES.get(fdef.kind, fdef.kind),
    fdef.title,
    fdef.doc,
    ]


def GenericListFields(resource, fields, separator, header, cl=None):
  """Generic implementation for listing fields for a resource.

  @param resource: One of L{constants.QR_VIA_LUXI}
  @type fields: list of strings
  @param fields: List of fields to query for
  @type separator: string or None
  @param separator: String used to separate fields
  @type header: bool
  @param header: Whether to show header row

  """
  if cl is None:
    cl = GetClient()

  if not fields:
    fields = None

  response = cl.QueryFields(resource, fields)

  found_unknown = _WarnUnknownFields(response.fields)

  columns = [
    TableColumn("Name", str, False),
    TableColumn("Type", str, False),
    TableColumn("Title", str, False),
    TableColumn("Description", str, False),
    ]

  rows = map(_FieldDescValues, response.fields)

  for line in FormatTable(rows, columns, header, separator):
    ToStdout(line)

  if found_unknown:
    return constants.EXIT_UNKNOWN_FIELD

  return constants.EXIT_SUCCESS


class TableColumn(object):
  """Describes a column for L{FormatTable}.

  """
  def __init__(self, title, fn, align_right):
    """Initializes this class.

    @type title: string
    @param title: Column title
    @type fn: callable
    @param fn: Formatting function
    @type align_right: bool
    @param align_right: Whether to align values on the right-hand side

    """
    self.title = title
    self.format = fn
    self.align_right = align_right


def _GetColFormatString(width, align_right):
  """Returns the format string for a field.

  """
  if align_right:
    sign = ""
  else:
    sign = "-"

  return "%%%s%ss" % (sign, width)


def FormatTable(rows, columns, header, separator):
  """Formats data as a table.

  @type rows: list of lists
  @param rows: Row data, one list per row
  @type columns: list of L{TableColumn}
  @param columns: Column descriptions
  @type header: bool
  @param header: Whether to show header row
  @type separator: string or None
  @param separator: String used to separate columns

  """
  if header:
    data = [[col.title for col in columns]]
    colwidth = [len(col.title) for col in columns]
  else:
    data = []
    colwidth = [0 for _ in columns]

  # Format row data
  for row in rows:
    assert len(row) == len(columns)

    formatted = [col.format(value) for value, col in zip(row, columns)]

    if separator is None:
      # Update column widths
      for idx, (oldwidth, value) in enumerate(zip(colwidth, formatted)):
        # Modifying a list's items while iterating is fine
        colwidth[idx] = max(oldwidth, len(value))

    data.append(formatted)

  if separator is not None:
    # Return early if a separator is used
    return [separator.join(row) for row in data]

  if columns and not columns[-1].align_right:
    # Avoid unnecessary spaces at end of line
    colwidth[-1] = 0

  # Build format string
  fmt = " ".join([_GetColFormatString(width, col.align_right)
                  for col, width in zip(columns, colwidth)])

  return [fmt % tuple(row) for row in data]


def FormatTimestamp(ts):
  """Formats a given timestamp.

  @type ts: timestamp
  @param ts: a timeval-type timestamp, a tuple of seconds and microseconds

  @rtype: string
  @return: a string with the formatted timestamp

  """
  if not isinstance(ts, (tuple, list)) or len(ts) != 2:
    return "?"

  (sec, usecs) = ts
  return utils.FormatTime(sec, usecs=usecs)


def ParseTimespec(value):
  """Parse a time specification.

  The following suffixed will be recognized:

    - s: seconds
    - m: minutes
    - h: hours
    - d: day
    - w: weeks

  Without any suffix, the value will be taken to be in seconds.

  """
  value = str(value)
  if not value:
    raise errors.OpPrereqError("Empty time specification passed",
                               errors.ECODE_INVAL)
  suffix_map = {
    "s": 1,
    "m": 60,
    "h": 3600,
    "d": 86400,
    "w": 604800,
    }
  if value[-1] not in suffix_map:
    try:
      value = int(value)
    except (TypeError, ValueError):
      raise errors.OpPrereqError("Invalid time specification '%s'" % value,
                                 errors.ECODE_INVAL)
  else:
    multiplier = suffix_map[value[-1]]
    value = value[:-1]
    if not value: # no data left after stripping the suffix
      raise errors.OpPrereqError("Invalid time specification (only"
                                 " suffix passed)", errors.ECODE_INVAL)
    try:
      value = int(value) * multiplier
    except (TypeError, ValueError):
      raise errors.OpPrereqError("Invalid time specification '%s'" % value,
                                 errors.ECODE_INVAL)
  return value


def GetOnlineNodes(nodes, cl=None, nowarn=False, secondary_ips=False,
                   filter_master=False, nodegroup=None):
  """Returns the names of online nodes.

  This function will also log a warning on stderr with the names of
  the online nodes.

  @param nodes: if not empty, use only this subset of nodes (minus the
      offline ones)
  @param cl: if not None, luxi client to use
  @type nowarn: boolean
  @param nowarn: by default, this function will output a note with the
      offline nodes that are skipped; if this parameter is True the
      note is not displayed
  @type secondary_ips: boolean
  @param secondary_ips: if True, return the secondary IPs instead of the
      names, useful for doing network traffic over the replication interface
      (if any)
  @type filter_master: boolean
  @param filter_master: if True, do not return the master node in the list
      (useful in coordination with secondary_ips where we cannot check our
      node name against the list)
  @type nodegroup: string
  @param nodegroup: If set, only return nodes in this node group

  """
  if cl is None:
    cl = GetClient()

  qfilter = []

  if nodes:
    qfilter.append(qlang.MakeSimpleFilter("name", nodes))

  if nodegroup is not None:
    qfilter.append([qlang.OP_OR, [qlang.OP_EQUAL, "group", nodegroup],
                                 [qlang.OP_EQUAL, "group.uuid", nodegroup]])

  if filter_master:
    qfilter.append([qlang.OP_NOT, [qlang.OP_TRUE, "master"]])

  if qfilter:
    if len(qfilter) > 1:
      final_filter = [qlang.OP_AND] + qfilter
    else:
      assert len(qfilter) == 1
      final_filter = qfilter[0]
  else:
    final_filter = None

  result = cl.Query(constants.QR_NODE, ["name", "offline", "sip"], final_filter)

  def _IsOffline(row):
    (_, (_, offline), _) = row
    return offline

  def _GetName(row):
    ((_, name), _, _) = row
    return name

  def _GetSip(row):
    (_, _, (_, sip)) = row
    return sip

  (offline, online) = compat.partition(result.data, _IsOffline)

  if offline and not nowarn:
    ToStderr("Note: skipping offline node(s): %s" %
             utils.CommaJoin(map(_GetName, offline)))

  if secondary_ips:
    fn = _GetSip
  else:
    fn = _GetName

  return map(fn, online)


def GetNodesSshPorts(nodes, cl):
  """Retrieves SSH ports of given nodes.

  @param nodes: the names of nodes
  @type nodes: a list of strings
  @param cl: a client to use for the query
  @type cl: L{ganeti.luxi.Client}
  @return: the list of SSH ports corresponding to the nodes
  @rtype: a list of tuples

  """
  return map(lambda t: t[0],
             cl.QueryNodes(names=nodes,
                           fields=["ndp/ssh_port"],
                           use_locking=False))


def GetNodeUUIDs(nodes, cl):
  """Retrieves the UUIDs of given nodes.

  @param nodes: the names of nodes
  @type nodes: a list of string
  @param cl: a client to use for the query
  @type cl: L{ganeti.luxi.Client}
  @return: the list of UUIDs corresponding to the nodes
  @rtype: a list of tuples

  """
  return map(lambda t: t[0],
             cl.QueryNodes(names=nodes,
                           fields=["uuid"],
                           use_locking=False))


def _ToStream(stream, txt, *args):
  """Write a message to a stream, bypassing the logging system

  @type stream: file object
  @param stream: the file to which we should write
  @type txt: str
  @param txt: the message

  """
  try:
    if args:
      args = tuple(args)
      stream.write(txt % args)
    else:
      stream.write(txt)
    stream.write("\n")
    stream.flush()
  except IOError, err:
    if err.errno == errno.EPIPE:
      # our terminal went away, we'll exit
      sys.exit(constants.EXIT_FAILURE)
    else:
      raise


def ToStdout(txt, *args):
  """Write a message to stdout only, bypassing the logging system

  This is just a wrapper over _ToStream.

  @type txt: str
  @param txt: the message

  """
  _ToStream(sys.stdout, txt, *args)


def ToStdoutAndLoginfo(txt, *args):
  """Write a message to stdout and additionally log it at INFO level"""
  ToStdout(txt, *args)
  logging.info(txt, *args)


def ToStderr(txt, *args):
  """Write a message to stderr only, bypassing the logging system

  This is just a wrapper over _ToStream.

  @type txt: str
  @param txt: the message

  """
  _ToStream(sys.stderr, txt, *args)


class JobExecutor(object):
  """Class which manages the submission and execution of multiple jobs.

  Note that instances of this class should not be reused between
  GetResults() calls.

  """
  def __init__(self, cl=None, verbose=True, opts=None, feedback_fn=None):
    self.queue = []
    if cl is None:
      cl = GetClient()
    self.cl = cl
    self.verbose = verbose
    self.jobs = []
    self.opts = opts
    self.feedback_fn = feedback_fn
    self._counter = itertools.count()

  @staticmethod
  def _IfName(name, fmt):
    """Helper function for formatting name.

    """
    if name:
      return fmt % name

    return ""

  def QueueJob(self, name, *ops):
    """Record a job for later submit.

    @type name: string
    @param name: a description of the job, will be used in WaitJobSet

    """
    SetGenericOpcodeOpts(ops, self.opts)
    self.queue.append((self._counter.next(), name, ops))

  def AddJobId(self, name, status, job_id):
    """Adds a job ID to the internal queue.

    """
    self.jobs.append((self._counter.next(), status, job_id, name))

  def SubmitPending(self, each=False):
    """Submit all pending jobs.

    """
    if each:
      results = []
      for (_, _, ops) in self.queue:
        # SubmitJob will remove the success status, but raise an exception if
        # the submission fails, so we'll notice that anyway.
        results.append([True, self.cl.SubmitJob(ops)[0]])
    else:
      results = self.cl.SubmitManyJobs([ops for (_, _, ops) in self.queue])
    for ((status, data), (idx, name, _)) in zip(results, self.queue):
      self.jobs.append((idx, status, data, name))

  def _ChooseJob(self):
    """Choose a non-waiting/queued job to poll next.

    """
    assert self.jobs, "_ChooseJob called with empty job list"

    result = self.cl.QueryJobs([i[2] for i in self.jobs[:_CHOOSE_BATCH]],
                               ["status"])
    assert result

    for job_data, status in zip(self.jobs, result):
      if (isinstance(status, list) and status and
          status[0] in (constants.JOB_STATUS_QUEUED,
                        constants.JOB_STATUS_WAITING,
                        constants.JOB_STATUS_CANCELING)):
        # job is still present and waiting
        continue
      # good candidate found (either running job or lost job)
      self.jobs.remove(job_data)
      return job_data

    # no job found
    return self.jobs.pop(0)

  def GetResults(self):
    """Wait for and return the results of all jobs.

    @rtype: list
    @return: list of tuples (success, job results), in the same order
        as the submitted jobs; if a job has failed, instead of the result
        there will be the error message

    """
    if not self.jobs:
      self.SubmitPending()
    results = []
    if self.verbose:
      ok_jobs = [row[2] for row in self.jobs if row[1]]
      if ok_jobs:
        ToStdout("Submitted jobs %s", utils.CommaJoin(ok_jobs))

    # first, remove any non-submitted jobs
    self.jobs, failures = compat.partition(self.jobs, lambda x: x[1])
    for idx, _, jid, name in failures:
      ToStderr("Failed to submit job%s: %s", self._IfName(name, " for %s"), jid)
      results.append((idx, False, jid))

    while self.jobs:
      (idx, _, jid, name) = self._ChooseJob()
      ToStdout("Waiting for job %s%s ...", jid, self._IfName(name, " for %s"))
      try:
        job_result = PollJob(jid, cl=self.cl, feedback_fn=self.feedback_fn)
        success = True
      except errors.JobLost, err:
        _, job_result = FormatError(err)
        ToStderr("Job %s%s has been archived, cannot check its result",
                 jid, self._IfName(name, " for %s"))
        success = False
      except (errors.GenericError, rpcerr.ProtocolError), err:
        _, job_result = FormatError(err)
        success = False
        # the error message will always be shown, verbose or not
        ToStderr("Job %s%s has failed: %s",
                 jid, self._IfName(name, " for %s"), job_result)

      results.append((idx, success, job_result))

    # sort based on the index, then drop it
    results.sort()
    results = [i[1:] for i in results]

    return results

  def WaitOrShow(self, wait):
    """Wait for job results or only print the job IDs.

    @type wait: boolean
    @param wait: whether to wait or not

    """
    if wait:
      return self.GetResults()
    else:
      if not self.jobs:
        self.SubmitPending()
      for _, status, result, name in self.jobs:
        if status:
          ToStdout("%s: %s", result, name)
        else:
          ToStderr("Failure for %s: %s", name, result)
      return [row[1:3] for row in self.jobs]


def FormatParamsDictInfo(param_dict, actual, roman=False):
  """Formats a parameter dictionary.

  @type param_dict: dict
  @param param_dict: the own parameters
  @type actual: dict
  @param actual: the current parameter set (including defaults)
  @rtype: dict
  @return: dictionary where the value of each parameter is either a fully
      formatted string or a dictionary containing formatted strings

  """
  ret = {}
  for (key, data) in actual.items():
    if isinstance(data, dict) and data:
      ret[key] = FormatParamsDictInfo(param_dict.get(key, {}), data, roman)
    else:
      default_str = "default (%s)" % compat.TryToRoman(data, roman)
      ret[key] = str(compat.TryToRoman(param_dict.get(key, default_str), roman))
  return ret


def _FormatListInfoDefault(data, def_data):
  if data is not None:
    ret = utils.CommaJoin(data)
  else:
    ret = "default (%s)" % utils.CommaJoin(def_data)
  return ret


def FormatPolicyInfo(custom_ipolicy, eff_ipolicy, iscluster, roman=False):
  """Formats an instance policy.

  @type custom_ipolicy: dict
  @param custom_ipolicy: own policy
  @type eff_ipolicy: dict
  @param eff_ipolicy: effective policy (including defaults); ignored for
      cluster
  @type iscluster: bool
  @param iscluster: the policy is at cluster level
  @type roman: bool
  @param roman: whether to print the values in roman numerals
  @rtype: list of pairs
  @return: formatted data, suitable for L{PrintGenericInfo}

  """
  if iscluster:
    eff_ipolicy = custom_ipolicy

  minmax_out = []
  custom_minmax = custom_ipolicy.get(constants.ISPECS_MINMAX)
  if custom_minmax:
    for (k, minmax) in enumerate(custom_minmax):
      minmax_out.append([
        ("%s/%s" % (key, k),
         FormatParamsDictInfo(minmax[key], minmax[key], roman))
        for key in constants.ISPECS_MINMAX_KEYS
        ])
  else:
    for (k, minmax) in enumerate(eff_ipolicy[constants.ISPECS_MINMAX]):
      minmax_out.append([
        ("%s/%s" % (key, k),
         FormatParamsDictInfo({}, minmax[key], roman))
        for key in constants.ISPECS_MINMAX_KEYS
        ])
  ret = [("bounds specs", minmax_out)]

  if iscluster:
    stdspecs = custom_ipolicy[constants.ISPECS_STD]
    ret.append(
      (constants.ISPECS_STD,
       FormatParamsDictInfo(stdspecs, stdspecs, roman))
      )

  ret.append(
    ("allowed disk templates",
     _FormatListInfoDefault(custom_ipolicy.get(constants.IPOLICY_DTS),
                            eff_ipolicy[constants.IPOLICY_DTS]))
    )
  to_roman = compat.TryToRoman
  ret.extend([
    (key, str(to_roman(custom_ipolicy.get(key,
                                          "default (%s)" % eff_ipolicy[key]),
                       roman)))
    for key in constants.IPOLICY_PARAMETERS
    ])
  return ret


def _PrintSpecsParameters(buf, specs):
  values = ("%s=%s" % (par, val) for (par, val) in sorted(specs.items()))
  buf.write(",".join(values))


def PrintIPolicyCommand(buf, ipolicy, isgroup):
  """Print the command option used to generate the given instance policy.

  Currently only the parts dealing with specs are supported.

  @type buf: StringIO
  @param buf: stream to write into
  @type ipolicy: dict
  @param ipolicy: instance policy
  @type isgroup: bool
  @param isgroup: whether the policy is at group level

  """
  if not isgroup:
    stdspecs = ipolicy.get("std")
    if stdspecs:
      buf.write(" %s " % IPOLICY_STD_SPECS_STR)
      _PrintSpecsParameters(buf, stdspecs)
  minmaxes = ipolicy.get("minmax", [])
  first = True
  for minmax in minmaxes:
    minspecs = minmax.get("min")
    maxspecs = minmax.get("max")
    if minspecs and maxspecs:
      if first:
        buf.write(" %s " % IPOLICY_BOUNDS_SPECS_STR)
        first = False
      else:
        buf.write("//")
      buf.write("min:")
      _PrintSpecsParameters(buf, minspecs)
      buf.write("/max:")
      _PrintSpecsParameters(buf, maxspecs)


def ConfirmOperation(names, list_type, text, extra=""):
  """Ask the user to confirm an operation on a list of list_type.

  This function is used to request confirmation for doing an operation
  on a given list of list_type.

  @type names: list
  @param names: the list of names that we display when
      we ask for confirmation
  @type list_type: str
  @param list_type: Human readable name for elements in the list (e.g. nodes)
  @type text: str
  @param text: the operation that the user should confirm
  @rtype: boolean
  @return: True or False depending on user's confirmation.

  """
  count = len(names)
  msg = ("The %s will operate on %d %s.\n%s"
         "Do you want to continue?" % (text, count, list_type, extra))
  affected = (("\nAffected %s:\n" % list_type) +
              "\n".join(["  %s" % name for name in names]))

  choices = [("y", True, "Yes, execute the %s" % text),
             ("n", False, "No, abort the %s" % text)]

  if count > 20:
    choices.insert(1, ("v", "v", "View the list of affected %s" % list_type))
    question = msg
  else:
    question = msg + affected

  choice = AskUser(question, choices)
  if choice == "v":
    choices.pop(1)
    choice = AskUser(msg + affected, choices)
  return choice


def _MaybeParseUnit(elements):
  """Parses and returns an array of potential values with units.

  """
  parsed = {}
  for k, v in elements.items():
    if v == constants.VALUE_DEFAULT:
      parsed[k] = v
    else:
      parsed[k] = utils.ParseUnit(v)
  return parsed


def _InitISpecsFromSplitOpts(ipolicy, ispecs_mem_size, ispecs_cpu_count,
                             ispecs_disk_count, ispecs_disk_size,
                             ispecs_nic_count, group_ipolicy, fill_all):
  try:
    if ispecs_mem_size:
      ispecs_mem_size = _MaybeParseUnit(ispecs_mem_size)
    if ispecs_disk_size:
      ispecs_disk_size = _MaybeParseUnit(ispecs_disk_size)
  except (TypeError, ValueError, errors.UnitParseError), err:
    raise errors.OpPrereqError("Invalid disk (%s) or memory (%s) size"
                               " in policy: %s" %
                               (ispecs_disk_size, ispecs_mem_size, err),
                               errors.ECODE_INVAL)

  # prepare ipolicy dict
  ispecs_transposed = {
    constants.ISPEC_MEM_SIZE: ispecs_mem_size,
    constants.ISPEC_CPU_COUNT: ispecs_cpu_count,
    constants.ISPEC_DISK_COUNT: ispecs_disk_count,
    constants.ISPEC_DISK_SIZE: ispecs_disk_size,
    constants.ISPEC_NIC_COUNT: ispecs_nic_count,
    }

  # first, check that the values given are correct
  if group_ipolicy:
    forced_type = TISPECS_GROUP_TYPES
  else:
    forced_type = TISPECS_CLUSTER_TYPES
  for specs in ispecs_transposed.values():
    assert type(specs) is dict
    utils.ForceDictType(specs, forced_type)

  # then transpose
  ispecs = {
    constants.ISPECS_MIN: {},
    constants.ISPECS_MAX: {},
    constants.ISPECS_STD: {},
    }
  for (name, specs) in ispecs_transposed.iteritems():
    assert name in constants.ISPECS_PARAMETERS
    for key, val in specs.items(): # {min: .. ,max: .., std: ..}
      assert key in ispecs
      ispecs[key][name] = val
  minmax_out = {}
  for key in constants.ISPECS_MINMAX_KEYS:
    if fill_all:
      minmax_out[key] = \
        objects.FillDict(constants.ISPECS_MINMAX_DEFAULTS[key], ispecs[key])
    else:
      minmax_out[key] = ispecs[key]
  ipolicy[constants.ISPECS_MINMAX] = [minmax_out]
  if fill_all:
    ipolicy[constants.ISPECS_STD] = \
        objects.FillDict(constants.IPOLICY_DEFAULTS[constants.ISPECS_STD],
                         ispecs[constants.ISPECS_STD])
  else:
    ipolicy[constants.ISPECS_STD] = ispecs[constants.ISPECS_STD]


def _ParseSpecUnit(spec, keyname):
  ret = spec.copy()
  for k in [constants.ISPEC_DISK_SIZE, constants.ISPEC_MEM_SIZE]:
    if k in ret:
      try:
        ret[k] = utils.ParseUnit(ret[k])
      except (TypeError, ValueError, errors.UnitParseError), err:
        raise errors.OpPrereqError(("Invalid parameter %s (%s) in %s instance"
                                    " specs: %s" % (k, ret[k], keyname, err)),
                                   errors.ECODE_INVAL)
  return ret


def _ParseISpec(spec, keyname, required):
  ret = _ParseSpecUnit(spec, keyname)
  utils.ForceDictType(ret, constants.ISPECS_PARAMETER_TYPES)
  missing = constants.ISPECS_PARAMETERS - frozenset(ret.keys())
  if required and missing:
    raise errors.OpPrereqError("Missing parameters in ipolicy spec %s: %s" %
                               (keyname, utils.CommaJoin(missing)),
                               errors.ECODE_INVAL)
  return ret


def _GetISpecsInAllowedValues(minmax_ispecs, allowed_values):
  ret = None
  if (minmax_ispecs and allowed_values and len(minmax_ispecs) == 1 and
      len(minmax_ispecs[0]) == 1):
    for (key, spec) in minmax_ispecs[0].items():
      # This loop is executed exactly once
      if key in allowed_values and not spec:
        ret = key
  return ret


def _InitISpecsFromFullOpts(ipolicy_out, minmax_ispecs, std_ispecs,
                            group_ipolicy, allowed_values):
  found_allowed = _GetISpecsInAllowedValues(minmax_ispecs, allowed_values)
  if found_allowed is not None:
    ipolicy_out[constants.ISPECS_MINMAX] = found_allowed
  elif minmax_ispecs is not None:
    minmax_out = []
    for mmpair in minmax_ispecs:
      mmpair_out = {}
      for (key, spec) in mmpair.items():
        if key not in constants.ISPECS_MINMAX_KEYS:
          msg = "Invalid key in bounds instance specifications: %s" % key
          raise errors.OpPrereqError(msg, errors.ECODE_INVAL)
        mmpair_out[key] = _ParseISpec(spec, key, True)
      minmax_out.append(mmpair_out)
    ipolicy_out[constants.ISPECS_MINMAX] = minmax_out
  if std_ispecs is not None:
    assert not group_ipolicy # This is not an option for gnt-group
    ipolicy_out[constants.ISPECS_STD] = _ParseISpec(std_ispecs, "std", False)


def CreateIPolicyFromOpts(ispecs_mem_size=None,
                          ispecs_cpu_count=None,
                          ispecs_disk_count=None,
                          ispecs_disk_size=None,
                          ispecs_nic_count=None,
                          minmax_ispecs=None,
                          std_ispecs=None,
                          ipolicy_disk_templates=None,
                          ipolicy_vcpu_ratio=None,
                          ipolicy_spindle_ratio=None,
                          ipolicy_memory_ratio=None,
                          group_ipolicy=False,
                          allowed_values=None,
                          fill_all=False):
  """Creation of instance policy based on command line options.

  @param fill_all: whether for cluster policies we should ensure that
    all values are filled

  """
  assert not (fill_all and allowed_values)

  split_specs = (ispecs_mem_size or ispecs_cpu_count or ispecs_disk_count or
                 ispecs_disk_size or ispecs_nic_count)
  if (split_specs and (minmax_ispecs is not None or std_ispecs is not None)):
    raise errors.OpPrereqError("A --specs-xxx option cannot be specified"
                               " together with any --ipolicy-xxx-specs option",
                               errors.ECODE_INVAL)

  ipolicy_out = objects.MakeEmptyIPolicy()
  if split_specs:
    assert fill_all
    _InitISpecsFromSplitOpts(ipolicy_out, ispecs_mem_size, ispecs_cpu_count,
                             ispecs_disk_count, ispecs_disk_size,
                             ispecs_nic_count, group_ipolicy, fill_all)
  elif (minmax_ispecs is not None or std_ispecs is not None):
    _InitISpecsFromFullOpts(ipolicy_out, minmax_ispecs, std_ispecs,
                            group_ipolicy, allowed_values)

  if ipolicy_disk_templates is not None:
    if allowed_values and ipolicy_disk_templates in allowed_values:
      ipolicy_out[constants.IPOLICY_DTS] = ipolicy_disk_templates
    else:
      ipolicy_out[constants.IPOLICY_DTS] = list(ipolicy_disk_templates)
  if ipolicy_vcpu_ratio is not None:
    ipolicy_out[constants.IPOLICY_VCPU_RATIO] = ipolicy_vcpu_ratio
  if ipolicy_spindle_ratio is not None:
    ipolicy_out[constants.IPOLICY_SPINDLE_RATIO] = ipolicy_spindle_ratio
  if ipolicy_memory_ratio is not None:
    ipolicy_out[constants.IPOLICY_MEMORY_RATIO] = ipolicy_memory_ratio

  assert not (frozenset(ipolicy_out.keys()) - constants.IPOLICY_ALL_KEYS)

  if not group_ipolicy and fill_all:
    ipolicy_out = objects.FillIPolicy(constants.IPOLICY_DEFAULTS, ipolicy_out)

  return ipolicy_out


def _NotAContainer(data):
  """ Checks whether the input is not a container data type.

  @rtype: bool

  """
  return not (isinstance(data, (list, dict, tuple)))


def _GetAlignmentMapping(data):
  """ Returns info about alignment if present in an encoded ordered dictionary.

  @type data: list of tuple
  @param data: The encoded ordered dictionary, as defined in
               L{_SerializeGenericInfo}.
  @rtype: dict of any to int
  @return: The dictionary mapping alignment groups to the maximum length of the
           dictionary key found in the group.

  """
  alignment_map = {}
  for entry in data:
    if len(entry) > 2:
      group_key = entry[2]
      key_length = len(entry[0])
      if group_key in alignment_map:
        alignment_map[group_key] = max(alignment_map[group_key], key_length)
      else:
        alignment_map[group_key] = key_length

  return alignment_map


def _SerializeGenericInfo(buf, data, level, afterkey=False):
  """Formatting core of L{PrintGenericInfo}.

  @param buf: (string) stream to accumulate the result into
  @param data: data to format
  @type level: int
  @param level: depth in the data hierarchy, used for indenting
  @type afterkey: bool
  @param afterkey: True when we are in the middle of a line after a key (used
      to properly add newlines or indentation)

  """
  baseind = "  "
  if isinstance(data, dict):
    if not data:
      buf.write("\n")
    else:
      if afterkey:
        buf.write("\n")
        doindent = True
      else:
        doindent = False
      for key in sorted(data):
        if doindent:
          buf.write(baseind * level)
        else:
          doindent = True
        buf.write(key)
        buf.write(": ")
        _SerializeGenericInfo(buf, data[key], level + 1, afterkey=True)
  elif isinstance(data, list) and len(data) > 0 and isinstance(data[0], tuple):
    # list of tuples (an ordered dictionary)
    # the tuples may have two or three members - key, value, and alignment group
    # if the alignment group is present, align all values sharing the same group
    if afterkey:
      buf.write("\n")
      doindent = True
    else:
      doindent = False

    alignment_mapping = _GetAlignmentMapping(data)
    for entry in data:
      key, val = entry[0:2]
      if doindent:
        buf.write(baseind * level)
      else:
        doindent = True
      buf.write(key)
      buf.write(": ")
      if len(entry) > 2:
        max_key_length = alignment_mapping[entry[2]]
        buf.write(" " * (max_key_length - len(key)))
      _SerializeGenericInfo(buf, val, level + 1, afterkey=True)
  elif isinstance(data, tuple) and all(map(_NotAContainer, data)):
    # tuples with simple content are serialized as inline lists
    buf.write("[%s]\n" % utils.CommaJoin(data))
  elif isinstance(data, list) or isinstance(data, tuple):
    # lists and tuples
    if not data:
      buf.write("\n")
    else:
      if afterkey:
        buf.write("\n")
        doindent = True
      else:
        doindent = False
      for item in data:
        if doindent:
          buf.write(baseind * level)
        else:
          doindent = True
        buf.write("-")
        buf.write(baseind[1:])
        _SerializeGenericInfo(buf, item, level + 1)
  else:
    # This branch should be only taken for strings, but it's practically
    # impossible to guarantee that no other types are produced somewhere
    buf.write(str(data))
    buf.write("\n")


def PrintGenericInfo(data):
  """Print information formatted according to the hierarchy.

  The output is a valid YAML string.

  @param data: the data to print. It's a hierarchical structure whose elements
      can be:
        - dictionaries, where keys are strings and values are of any of the
          types listed here
        - lists of tuples (key, value) or (key, value, alignment_group), where
          key is a string, value is of any of the types listed here, and
          alignment_group can be any hashable value; it's a way to encode
          ordered dictionaries; any entries sharing the same alignment group are
          aligned by appending whitespace before the value as needed
        - lists of any of the types listed here
        - strings

  """
  buf = StringIO()
  _SerializeGenericInfo(buf, data, 0)
  ToStdout(buf.getvalue().rstrip("\n"))
