Make _GenerateDRBD8Branch accept different VG names
[ganeti-local] / lib / client / gnt_node.py
index ee71258..e058ee7 100644 (file)
@@ -1,7 +1,7 @@
 #
 #
 
 #
 #
 
-# Copyright (C) 2006, 2007, 2008, 2009, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011 Google Inc.
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 #
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -34,6 +34,7 @@ from ganeti import utils
 from ganeti import constants
 from ganeti import errors
 from ganeti import netutils
 from ganeti import constants
 from ganeti import errors
 from ganeti import netutils
+from cStringIO import StringIO
 
 
 #: default list of field for L{ListNodes}
 
 
 #: default list of field for L{ListNodes}
@@ -133,6 +134,8 @@ def _RunSetupSSH(options, nodes):
     cmd.append("--verbose")
   if not options.ssh_key_check:
     cmd.append("--no-ssh-key-check")
     cmd.append("--verbose")
   if not options.ssh_key_check:
     cmd.append("--no-ssh-key-check")
+  if options.force_join:
+    cmd.append("--force-join")
 
   cmd.extend(nodes)
 
 
   cmd.extend(nodes)
 
@@ -160,9 +163,9 @@ def AddNode(opts, args):
   readd = opts.readd
 
   try:
   readd = opts.readd
 
   try:
-    output = cl.QueryNodes(names=[node], fields=['name', 'sip'],
+    output = cl.QueryNodes(names=[node], fields=['name', 'sip', 'master'],
                            use_locking=False)
                            use_locking=False)
-    node_exists, sip = output[0]
+    node_exists, sip, is_master = output[0]
   except (errors.OpPrereqError, errors.OpExecError):
     node_exists = ""
     sip = None
   except (errors.OpPrereqError, errors.OpExecError):
     node_exists = ""
     sip = None
@@ -172,6 +175,9 @@ def AddNode(opts, args):
       ToStderr("Node %s not in the cluster"
                " - please retry without '--readd'", node)
       return 1
       ToStderr("Node %s not in the cluster"
                " - please retry without '--readd'", node)
       return 1
+    if is_master:
+      ToStderr("Node %s is the master, cannot readd", node)
+      return 1
   else:
     if node_exists:
       ToStderr("Node %s already in the cluster (as %s)"
   else:
     if node_exists:
       ToStderr("Node %s already in the cluster (as %s)"
@@ -196,7 +202,7 @@ def AddNode(opts, args):
 
   bootstrap.SetupNodeDaemon(cluster_name, node, opts.ssh_key_check)
 
 
   bootstrap.SetupNodeDaemon(cluster_name, node, opts.ssh_key_check)
 
-  op = opcodes.OpAddNode(node_name=args[0], secondary_ip=sip,
+  op = opcodes.OpNodeAdd(node_name=args[0], secondary_ip=sip,
                          readd=opts.readd, group=opts.nodegroup,
                          vm_capable=opts.vm_capable, ndparams=opts.ndparams,
                          master_capable=opts.master_capable)
                          readd=opts.readd, group=opts.nodegroup,
                          vm_capable=opts.vm_capable, ndparams=opts.ndparams,
                          master_capable=opts.master_capable)
@@ -220,7 +226,7 @@ def ListNodes(opts, args):
 
   return GenericList(constants.QR_NODE, selected_fields, args, opts.units,
                      opts.separator, not opts.no_headers,
 
   return GenericList(constants.QR_NODE, selected_fields, args, opts.units,
                      opts.separator, not opts.no_headers,
-                     format_override=fmtoverride)
+                     format_override=fmtoverride, verbose=opts.verbose)
 
 
 def ListNodeFields(opts, args):
 
 
 def ListNodeFields(opts, args):
@@ -253,9 +259,9 @@ def EvacuateNode(opts, args):
   dst_node = opts.dst_node
   iallocator = opts.iallocator
 
   dst_node = opts.dst_node
   iallocator = opts.iallocator
 
-  op = opcodes.OpNodeEvacuationStrategy(nodes=args,
-                                        iallocator=iallocator,
-                                        remote_node=dst_node)
+  op = opcodes.OpNodeEvacStrategy(nodes=args,
+                                  iallocator=iallocator,
+                                  remote_node=dst_node)
 
   result = SubmitOpCode(op, cl=cl, opts=opts)
   if not result:
 
   result = SubmitOpCode(op, cl=cl, opts=opts)
   if not result:
@@ -274,10 +280,10 @@ def EvacuateNode(opts, args):
     iname = row[0]
     node = row[1]
     ToStdout("Will relocate instance %s to node %s", iname, node)
     iname = row[0]
     node = row[1]
     ToStdout("Will relocate instance %s to node %s", iname, node)
-    op = opcodes.OpReplaceDisks(instance_name=iname,
-                                remote_node=node, disks=[],
-                                mode=constants.REPLACE_DISK_CHG,
-                                early_release=opts.early_release)
+    op = opcodes.OpInstanceReplaceDisks(instance_name=iname,
+                                        remote_node=node, disks=[],
+                                        mode=constants.REPLACE_DISK_CHG,
+                                        early_release=opts.early_release)
     jex.QueueJob(iname, op)
   results = jex.GetResults()
   bad_cnt = len([row for row in results if not row[0]])
     jex.QueueJob(iname, op)
   results = jex.GetResults()
   bad_cnt = len([row for row in results if not row[0]])
@@ -325,7 +331,7 @@ def FailoverNode(opts, args):
 
   jex = JobExecutor(cl=cl, opts=opts)
   for iname in pinst:
 
   jex = JobExecutor(cl=cl, opts=opts)
   for iname in pinst:
-    op = opcodes.OpFailoverInstance(instance_name=iname,
+    op = opcodes.OpInstanceFailover(instance_name=iname,
                                     ignore_consistency=opts.ignore_consistency)
     jex.QueueJob(iname, op)
   results = jex.GetResults()
                                     ignore_consistency=opts.ignore_consistency)
     jex.QueueJob(iname, op)
   results = jex.GetResults()
@@ -368,7 +374,7 @@ def MigrateNode(opts, args):
     mode = constants.HT_MIGRATION_NONLIVE
   else:
     mode = opts.migration_mode
     mode = constants.HT_MIGRATION_NONLIVE
   else:
     mode = opts.migration_mode
-  op = opcodes.OpMigrateNode(node_name=args[0], mode=mode)
+  op = opcodes.OpNodeMigrate(node_name=args[0], mode=mode)
   SubmitOpCode(op, cl=cl, opts=opts)
 
 
   SubmitOpCode(op, cl=cl, opts=opts)
 
 
@@ -388,17 +394,21 @@ def ShowNodeConfig(opts, args):
   result = cl.QueryNodes(fields=["name", "pip", "sip",
                                  "pinst_list", "sinst_list",
                                  "master_candidate", "drained", "offline",
   result = cl.QueryNodes(fields=["name", "pip", "sip",
                                  "pinst_list", "sinst_list",
                                  "master_candidate", "drained", "offline",
-                                 "master_capable", "vm_capable"],
+                                 "master_capable", "vm_capable", "powered",
+                                 "ndparams", "custom_ndparams"],
                          names=args, use_locking=False)
 
                          names=args, use_locking=False)
 
-  for (name, primary_ip, secondary_ip, pinst, sinst,
-       is_mc, drained, offline, master_capable, vm_capable) in result:
+  for (name, primary_ip, secondary_ip, pinst, sinst, is_mc, drained, offline,
+       master_capable, vm_capable, powered, ndparams,
+       ndparams_custom) in result:
     ToStdout("Node name: %s", name)
     ToStdout("  primary ip: %s", primary_ip)
     ToStdout("  secondary ip: %s", secondary_ip)
     ToStdout("  master candidate: %s", is_mc)
     ToStdout("  drained: %s", drained)
     ToStdout("  offline: %s", offline)
     ToStdout("Node name: %s", name)
     ToStdout("  primary ip: %s", primary_ip)
     ToStdout("  secondary ip: %s", secondary_ip)
     ToStdout("  master candidate: %s", is_mc)
     ToStdout("  drained: %s", drained)
     ToStdout("  offline: %s", offline)
+    if powered is not None:
+      ToStdout("  powered: %s", powered)
     ToStdout("  master_capable: %s", master_capable)
     ToStdout("  vm_capable: %s", vm_capable)
     if vm_capable:
     ToStdout("  master_capable: %s", master_capable)
     ToStdout("  vm_capable: %s", vm_capable)
     if vm_capable:
@@ -414,6 +424,10 @@ def ShowNodeConfig(opts, args):
           ToStdout("    - %s", iname)
       else:
         ToStdout("  secondary for no instances")
           ToStdout("    - %s", iname)
       else:
         ToStdout("  secondary for no instances")
+    ToStdout("  node parameters:")
+    buf = StringIO()
+    FormatParameterDict(buf, ndparams_custom, ndparams, level=2)
+    ToStdout(buf.getvalue().rstrip("\n"))
 
   return 0
 
 
   return 0
 
@@ -429,7 +443,7 @@ def RemoveNode(opts, args):
   @return: the desired exit code
 
   """
   @return: the desired exit code
 
   """
-  op = opcodes.OpRemoveNode(node_name=args[0])
+  op = opcodes.OpNodeRemove(node_name=args[0])
   SubmitOpCode(op, opts=opts)
   return 0
 
   SubmitOpCode(op, opts=opts)
   return 0
 
@@ -450,7 +464,7 @@ def PowercycleNode(opts, args):
       not AskUser("Are you sure you want to hard powercycle node %s?" % node)):
     return 2
 
       not AskUser("Are you sure you want to hard powercycle node %s?" % node)):
     return 2
 
-  op = opcodes.OpPowercycleNode(node_name=node, force=opts.force)
+  op = opcodes.OpNodePowercycle(node_name=node, force=opts.force)
   result = SubmitOpCode(op, opts=opts)
   if result:
     ToStderr(result)
   result = SubmitOpCode(op, opts=opts)
   if result:
     ToStderr(result)
@@ -479,10 +493,11 @@ def PowerNode(opts, args):
 
   opcodelist = []
   if oob_command == constants.OOB_POWER_OFF:
 
   opcodelist = []
   if oob_command == constants.OOB_POWER_OFF:
-    opcodelist.append(opcodes.OpSetNodeParams(node_name=node, offline=True,
+    opcodelist.append(opcodes.OpNodeSetParams(node_name=node, offline=True,
                                               auto_promote=opts.auto_promote))
 
                                               auto_promote=opts.auto_promote))
 
-  opcodelist.append(opcodes.OpOobCommand(node_name=node, command=oob_command))
+  opcodelist.append(opcodes.OpOobCommand(node_names=[node],
+                                         command=oob_command))
 
   cli.SetGenericOpcodeOpts(opcodelist, opts)
 
 
   cli.SetGenericOpcodeOpts(opcodelist, opts)
 
@@ -493,13 +508,22 @@ def PowerNode(opts, args):
   result = cli.PollJob(job_id)[-1]
 
   if result:
   result = cli.PollJob(job_id)[-1]
 
   if result:
-    if oob_command == constants.OOB_POWER_STATUS:
-      text = "The machine is %spowered"
-      if result[constants.OOB_POWER_STATUS_POWERED]:
-        result = text % ""
+    (_, data_tuple) = result[0]
+    if data_tuple[0] != constants.RS_NORMAL:
+      if data_tuple[0] == constants.RS_UNAVAIL:
+        result = "OOB is not supported"
       else:
       else:
-        result = text % "not "
-    ToStderr(result)
+        result = "RPC failed, look out for warning in the output"
+      ToStderr(result)
+      return constants.EXIT_FAILURE
+    else:
+      if oob_command == constants.OOB_POWER_STATUS:
+        text = "The machine is %spowered"
+        if data_tuple[1][constants.OOB_POWER_STATUS_POWERED]:
+          result = text % ""
+        else:
+          result = text % "not "
+        ToStdout(result)
 
   return constants.EXIT_SUCCESS
 
 
   return constants.EXIT_SUCCESS
 
@@ -518,7 +542,7 @@ def ListVolumes(opts, args):
   """
   selected_fields = ParseFields(opts.output, _LIST_VOL_DEF_FIELDS)
 
   """
   selected_fields = ParseFields(opts.output, _LIST_VOL_DEF_FIELDS)
 
-  op = opcodes.OpQueryNodeVolumes(nodes=args, output_fields=selected_fields)
+  op = opcodes.OpNodeQueryvols(nodes=args, output_fields=selected_fields)
   output = SubmitOpCode(op, opts=opts)
 
   if not opts.no_headers:
   output = SubmitOpCode(op, opts=opts)
 
   if not opts.no_headers:
@@ -562,7 +586,7 @@ def ListStorage(opts, args):
 
   selected_fields = ParseFields(opts.output, _LIST_STOR_DEF_FIELDS)
 
 
   selected_fields = ParseFields(opts.output, _LIST_STOR_DEF_FIELDS)
 
-  op = opcodes.OpQueryNodeStorage(nodes=args,
+  op = opcodes.OpNodeQueryStorage(nodes=args,
                                   storage_type=storage_type,
                                   output_fields=selected_fields)
   output = SubmitOpCode(op, opts=opts)
                                   storage_type=storage_type,
                                   output_fields=selected_fields)
   output = SubmitOpCode(op, opts=opts)
@@ -624,7 +648,7 @@ def ModifyStorage(opts, args):
     changes[constants.SF_ALLOCATABLE] = opts.allocatable
 
   if changes:
     changes[constants.SF_ALLOCATABLE] = opts.allocatable
 
   if changes:
-    op = opcodes.OpModifyNodeStorage(node_name=node_name,
+    op = opcodes.OpNodeModifyStorage(node_name=node_name,
                                      storage_type=storage_type,
                                      name=volume_name,
                                      changes=changes)
                                      storage_type=storage_type,
                                      name=volume_name,
                                      changes=changes)
@@ -671,7 +695,7 @@ def SetNodeParams(opts, args):
     ToStderr("Please give at least one of the parameters.")
     return 1
 
     ToStderr("Please give at least one of the parameters.")
     return 1
 
-  op = opcodes.OpSetNodeParams(node_name=args[0],
+  op = opcodes.OpNodeSetParams(node_name=args[0],
                                master_candidate=opts.master_candidate,
                                offline=opts.offline,
                                drained=opts.drained,
                                master_candidate=opts.master_candidate,
                                offline=opts.offline,
                                drained=opts.drained,
@@ -680,7 +704,8 @@ def SetNodeParams(opts, args):
                                secondary_ip=opts.secondary_ip,
                                force=opts.force,
                                ndparams=opts.ndparams,
                                secondary_ip=opts.secondary_ip,
                                force=opts.force,
                                ndparams=opts.ndparams,
-                               auto_promote=opts.auto_promote)
+                               auto_promote=opts.auto_promote,
+                               powered=opts.node_powered)
 
   # even if here we process the result, we allow submit only
   result = SubmitOrSend(op, opts)
 
   # even if here we process the result, we allow submit only
   result = SubmitOrSend(op, opts)
@@ -695,10 +720,11 @@ def SetNodeParams(opts, args):
 commands = {
   'add': (
     AddNode, [ArgHost(min=1, max=1)],
 commands = {
   'add': (
     AddNode, [ArgHost(min=1, max=1)],
-    [SECONDARY_IP_OPT, READD_OPT, NOSSH_KEYCHECK_OPT, NONODE_SETUP_OPT,
-     VERBOSE_OPT, NODEGROUP_OPT, PRIORITY_OPT, CAPAB_MASTER_OPT,
-     CAPAB_VM_OPT, NODE_PARAMS_OPT],
-    "[-s ip] [--readd] [--no-ssh-key-check] [--no-node-setup]  [--verbose] "
+    [SECONDARY_IP_OPT, READD_OPT, NOSSH_KEYCHECK_OPT, NODE_FORCE_JOIN_OPT,
+     NONODE_SETUP_OPT, VERBOSE_OPT, NODEGROUP_OPT, PRIORITY_OPT,
+     CAPAB_MASTER_OPT, CAPAB_VM_OPT, NODE_PARAMS_OPT],
+    "[-s ip] [--readd] [--no-ssh-key-check] [--force-join]"
+    " [--no-node-setup] [--verbose]"
     " <node_name>",
     "Add a node to the cluster"),
   'evacuate': (
     " <node_name>",
     "Add a node to the cluster"),
   'evacuate': (
@@ -724,7 +750,7 @@ commands = {
     "[<node_name>...]", "Show information about the node(s)"),
   'list': (
     ListNodes, ARGS_MANY_NODES,
     "[<node_name>...]", "Show information about the node(s)"),
   'list': (
     ListNodes, ARGS_MANY_NODES,
-    [NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT],
+    [NOHDR_OPT, SEP_OPT, USEUNITS_OPT, FIELDS_OPT, VERBOSE_OPT],
     "[nodes...]",
     "Lists the nodes in the cluster. The available fields can be shown using"
     " the \"list-fields\" command (see the man page for details)."
     "[nodes...]",
     "Lists the nodes in the cluster. The available fields can be shown using"
     " the \"list-fields\" command (see the man page for details)."
@@ -739,7 +765,8 @@ commands = {
     SetNodeParams, ARGS_ONE_NODE,
     [FORCE_OPT, SUBMIT_OPT, MC_OPT, DRAINED_OPT, OFFLINE_OPT,
      CAPAB_MASTER_OPT, CAPAB_VM_OPT, SECONDARY_IP_OPT,
     SetNodeParams, ARGS_ONE_NODE,
     [FORCE_OPT, SUBMIT_OPT, MC_OPT, DRAINED_OPT, OFFLINE_OPT,
      CAPAB_MASTER_OPT, CAPAB_VM_OPT, SECONDARY_IP_OPT,
-     AUTO_PROMOTE_OPT, DRY_RUN_OPT, PRIORITY_OPT, NODE_PARAMS_OPT],
+     AUTO_PROMOTE_OPT, DRY_RUN_OPT, PRIORITY_OPT, NODE_PARAMS_OPT,
+     NODE_POWERED_OPT],
     "<node_name>", "Alters the parameters of a node"),
   'powercycle': (
     PowercycleNode, ARGS_ONE_NODE,
     "<node_name>", "Alters the parameters of a node"),
   'powercycle': (
     PowercycleNode, ARGS_ONE_NODE,