Add a generic write file function
[ganeti-local] / lib / cmdlib.py
index 2599687..46c5c6e 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#
 #
 
 # Copyright (C) 2006, 2007 Google Inc.
@@ -161,7 +161,7 @@ class NoHooksLU(LogicalUnit):
     This is a no-op, since we don't run hooks.
 
     """
-    return
+    return {}, [], []
 
 
 def _GetWantedNodes(lu, nodes):
@@ -239,6 +239,7 @@ def _BuildInstanceHookEnv(name, primary_node, secondary_nodes, os_type, status,
     secondary_nodes: List of secondary nodes as strings
   """
   env = {
+    "OP_TARGET": name,
     "INSTANCE_NAME": name,
     "INSTANCE_PRIMARY": primary_node,
     "INSTANCE_SECONDARIES": " ".join(secondary_nodes),
@@ -545,10 +546,7 @@ class LUInitCluster(LogicalUnit):
     ourselves in the post-run node list.
 
     """
-    env = {
-      "CLUSTER": self.op.cluster_name,
-      "MASTER": self.hostname.name,
-      }
+    env = {"OP_TARGET": self.op.cluster_name}
     return env, [], [self.hostname.name]
 
   def CheckPrereq(self):
@@ -567,8 +565,8 @@ class LUInitCluster(LogicalUnit):
 
     self.clustername = clustername = utils.HostInfo(self.op.cluster_name)
 
-    result = utils.RunCmd(["fping", "-S127.0.0.1", "-q", hostname.ip])
-    if result.failed:
+    if not utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, hostname.ip,
+                         constants.DEFAULT_NODED_PORT):
       raise errors.OpPrereqError("Inconsistency: this host's name resolves"
                                  " to %s,\nbut this ip address does not"
                                  " belong to this host."
@@ -577,12 +575,13 @@ class LUInitCluster(LogicalUnit):
     secondary_ip = getattr(self.op, "secondary_ip", None)
     if secondary_ip and not utils.IsValidIP(secondary_ip):
       raise errors.OpPrereqError("Invalid secondary ip given")
-    if secondary_ip and secondary_ip != hostname.ip:
-      result = utils.RunCmd(["fping", "-S127.0.0.1", "-q", secondary_ip])
-      if result.failed:
-        raise errors.OpPrereqError("You gave %s as secondary IP,\n"
-                                   "but it does not belong to this host." %
-                                   secondary_ip)
+    if (secondary_ip and
+        secondary_ip != hostname.ip and
+        (not utils.TcpPing(constants.LOCALHOST_IP_ADDRESS, secondary_ip,
+                           constants.DEFAULT_NODED_PORT))):
+      raise errors.OpPrereqError("You gave %s as secondary IP,\n"
+                                 "but it does not belong to this host." %
+                                 secondary_ip)
     self.secondary_ip = secondary_ip
 
     # checks presence of the volume group given
@@ -614,7 +613,7 @@ class LUInitCluster(LogicalUnit):
     hostname = self.hostname
 
     # set up the simple store
-    ss = ssconf.SimpleStore()
+    self.sstore = ss = ssconf.SimpleStore()
     ss.SetKey(ss.SS_HYPERVISOR, self.op.hypervisor_type)
     ss.SetKey(ss.SS_MASTER_NODE, hostname.name)
     ss.SetKey(ss.SS_MASTER_IP, clustername.ip)
@@ -642,7 +641,7 @@ class LUInitCluster(LogicalUnit):
     _InitSSHSetup(hostname.name)
 
     # init of cluster config file
-    cfgw = config.ConfigWriter()
+    self.cfg = cfgw = config.ConfigWriter()
     cfgw.InitConfig(hostname.name, hostname.ip, self.secondary_ip,
                     sshkey, self.op.mac_prefix,
                     self.op.vg_name, self.op.def_bridge)
@@ -939,6 +938,7 @@ class LURenameCluster(LogicalUnit):
 
     """
     env = {
+      "OP_TARGET": self.op.sstore.GetClusterName(),
       "NEW_NAME": self.op.name,
       }
     mn = self.sstore.GetMasterNode()
@@ -1129,6 +1129,7 @@ class LURemoveNode(LogicalUnit):
 
     """
     env = {
+      "OP_TARGET": self.op.node_name,
       "NODE_NAME": self.op.node_name,
       }
     all_nodes = self.cfg.GetNodeList()
@@ -1198,7 +1199,8 @@ class LUQueryNodes(NoHooksLU):
 
     """
     self.dynamic_fields = frozenset(["dtotal", "dfree",
-                                     "mtotal", "mnode", "mfree"])
+                                     "mtotal", "mnode", "mfree",
+                                     "bootid"])
 
     _CheckOutputFields(static=["name", "pinst_cnt", "sinst_cnt",
                                "pinst_list", "sinst_list",
@@ -1229,6 +1231,7 @@ class LUQueryNodes(NoHooksLU):
             "mfree": utils.TryConvert(int, nodeinfo['memory_free']),
             "dtotal": utils.TryConvert(int, nodeinfo['vg_size']),
             "dfree": utils.TryConvert(int, nodeinfo['vg_free']),
+            "bootid": nodeinfo['bootid'],
             }
         else:
           live_data[name] = {}
@@ -1366,6 +1369,7 @@ class LUAddNode(LogicalUnit):
 
     """
     env = {
+      "OP_TARGET": self.op.node_name,
       "NODE_NAME": self.op.node_name,
       "NODE_PIP": self.op.primary_ip,
       "NODE_SIP": self.op.secondary_ip,
@@ -1426,17 +1430,18 @@ class LUAddNode(LogicalUnit):
                                    " new node doesn't have one")
 
     # checks reachablity
-    command = ["fping", "-q", primary_ip]
-    result = utils.RunCmd(command)
-    if result.failed:
+    if not utils.TcpPing(utils.HostInfo().name,
+                         primary_ip,
+                         constants.DEFAULT_NODED_PORT):
       raise errors.OpPrereqError("Node not reachable by ping")
 
     if not newbie_singlehomed:
       # check reachability from my secondary ip to newbie's secondary ip
-      command = ["fping", "-S%s" % myself.secondary_ip, "-q", secondary_ip]
-      result = utils.RunCmd(command)
-      if result.failed:
-        raise errors.OpPrereqError("Node secondary ip not reachable by ping")
+      if not utils.TcpPing(myself.secondary_ip,
+                           secondary_ip,
+                           constants.DEFAULT_NODED_PORT):
+        raise errors.OpPrereqError(
+          "Node secondary ip not reachable by TCP based ping to noded port")
 
     self.new_node = objects.Node(name=node,
                                  primary_ip=primary_ip,
@@ -1527,9 +1532,11 @@ class LUAddNode(LogicalUnit):
                       self.cfg.GetHostKey())
 
     if new_node.secondary_ip != new_node.primary_ip:
-      result = ssh.SSHCall(node, "root",
-                           "fping -S 127.0.0.1 -q %s" % new_node.secondary_ip)
-      if result.failed:
+      if not rpc.call_node_tcp_ping(new_node.name,
+                                    constants.LOCALHOST_IP_ADDRESS,
+                                    new_node.secondary_ip,
+                                    constants.DEFAULT_NODED_PORT,
+                                    10, False):
         raise errors.OpExecError("Node claims it doesn't have the"
                                  " secondary ip you gave (%s).\n"
                                  "Please fix and re-run this command." %
@@ -1585,6 +1592,7 @@ class LUMasterFailover(LogicalUnit):
 
     """
     env = {
+      "OP_TARGET": self.new_master,
       "NEW_MASTER": self.new_master,
       "OLD_MASTER": self.old_master,
       }
@@ -2842,11 +2850,10 @@ class LUCreateInstance(LogicalUnit):
                                  " adding an instance in start mode")
 
     if self.op.ip_check:
-      command = ["fping", "-q", hostname1.ip]
-      result = utils.RunCmd(command)
-      if not result.failed:
-        raise errors.OpPrereqError("IP address %s of instance %s already"
-                                   " in use" % (hostname1.ip, instance_name))
+      if utils.TcpPing(utils.HostInfo().name, hostname1.ip,
+                       constants.DEFAULT_NODED_PORT):
+        raise errors.OpPrereqError("IP %s of instance %s already in use" %
+                                   (hostname1.ip, instance_name))
 
     # bridge verification
     bridge = getattr(self.op, "bridge", None)
@@ -3706,7 +3713,7 @@ class TagsLU(NoHooksLU):
       self.op.name = name
       self.target = self.cfg.GetNodeInfo(name)
     elif self.op.kind == constants.TAG_INSTANCE:
-      name = self.cfg.ExpandInstanceName(name)
+      name = self.cfg.ExpandInstanceName(self.op.name)
       if name is None:
         raise errors.OpPrereqError("Invalid instance name (%s)" %
                                    (self.op.name,))
@@ -3730,11 +3737,11 @@ class LUGetTags(TagsLU):
     return self.target.GetTags()
 
 
-class LUAddTag(TagsLU):
+class LUAddTags(TagsLU):
   """Sets a tag on a given object.
 
   """
-  _OP_REQP = ["kind", "name", "tag"]
+  _OP_REQP = ["kind", "name", "tags"]
 
   def CheckPrereq(self):
     """Check prerequisites.
@@ -3743,14 +3750,16 @@ class LUAddTag(TagsLU):
 
     """
     TagsLU.CheckPrereq(self)
-    objects.TaggableObject.ValidateTag(self.op.tag)
+    for tag in self.op.tags:
+      objects.TaggableObject.ValidateTag(tag)
 
   def Exec(self, feedback_fn):
     """Sets the tag.
 
     """
     try:
-      self.target.AddTag(self.op.tag)
+      for tag in self.op.tags:
+        self.target.AddTag(tag)
     except errors.TagError, err:
       raise errors.OpExecError("Error while setting tag: %s" % str(err))
     try:
@@ -3761,11 +3770,11 @@ class LUAddTag(TagsLU):
                                 " aborted. Please retry.")
 
 
-class LUDelTag(TagsLU):
-  """Delete a tag from a given object.
+class LUDelTags(TagsLU):
+  """Delete a list of tags from a given object.
 
   """
-  _OP_REQP = ["kind", "name", "tag"]
+  _OP_REQP = ["kind", "name", "tags"]
 
   def CheckPrereq(self):
     """Check prerequisites.
@@ -3774,15 +3783,23 @@ class LUDelTag(TagsLU):
 
     """
     TagsLU.CheckPrereq(self)
-    objects.TaggableObject.ValidateTag(self.op.tag)
-    if self.op.tag not in self.target.GetTags():
-      raise errors.OpPrereqError("Tag not found")
+    for tag in self.op.tags:
+      objects.TaggableObject.ValidateTag(tag)
+    del_tags = frozenset(self.op.tags)
+    cur_tags = self.target.GetTags()
+    if not del_tags <= cur_tags:
+      diff_tags = del_tags - cur_tags
+      diff_names = ["'%s'" % tag for tag in diff_tags]
+      diff_names.sort()
+      raise errors.OpPrereqError("Tag(s) %s not found" %
+                                 (",".join(diff_names)))
 
   def Exec(self, feedback_fn):
     """Remove the tag from the object.
 
     """
-    self.target.RemoveTag(self.op.tag)
+    for tag in self.op.tags:
+      self.target.RemoveTag(tag)
     try:
       self.cfg.Update(self.target)
     except errors.ConfigurationError: