From d8470559a5267aed229588f5400b3bf699414a1b Mon Sep 17 00:00:00 2001
From: Michael Hanselmann <hansmi@google.com>
Date: Wed, 6 Aug 2008 14:56:10 +0000
Subject: [PATCH] Implement {Add,Readd,Remove}Node in GanetiContext

By doing this we've a central place which coordinates what needs to be
done when adding or removing nodes. Another patch will add calls into
the job queue.

Two log messages move to config.py.

When removing a node, node_leave_cluster is now called after it has
been removed from the configuration and job manager. That way we're
sure not to access the node again after files have been removed.

Reviewed-by: iustinp
---
 daemons/ganeti-masterd | 25 +++++++++++++++++++++++++
 lib/cmdlib.py          | 19 ++++++-------------
 lib/config.py          |  5 +++++
 3 files changed, 36 insertions(+), 13 deletions(-)

diff --git a/daemons/ganeti-masterd b/daemons/ganeti-masterd
index 28e6c5988..5de935b89 100755
--- a/daemons/ganeti-masterd
+++ b/daemons/ganeti-masterd
@@ -284,6 +284,31 @@ class GanetiContext(object):
     assert self.__class__._instance is None, "Attempt to modify Ganeti Context"
     object.__setattr__(self, name, value)
 
+  def AddNode(self, node):
+    """Adds a node to the configuration and lock manager.
+
+    """
+    # Add it to the configuration
+    self.cfg.AddNode(node)
+
+    # Add the new node to the Ganeti Lock Manager
+    self.glm.add(locking.LEVEL_NODE, node.name)
+
+  def ReaddNode(self, node):
+    """Updates a node that's already in the configuration
+
+    """
+
+  def RemoveNode(self, name):
+    """Removes a node from the configuration and lock manager.
+
+    """
+    # Remove node from configuration
+    self.cfg.RemoveNode(name)
+
+    # Remove the node from the Ganeti Lock Manager
+    self.glm.remove(locking.LEVEL_NODE, name)
+
 
 def ParseOptions():
   """Parse the command line options.
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 7ad77f6cf..744fe16a8 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -1356,15 +1356,9 @@ class LURemoveNode(LogicalUnit):
     logger.Info("stopping the node daemon and removing configs from node %s" %
                 node.name)
 
-    rpc.call_node_leave_cluster(node.name)
-
-    logger.Info("Removing node %s from config" % node.name)
-
-    self.cfg.RemoveNode(node.name)
-    # Remove the node from the Ganeti Lock Manager
-    self.context.glm.remove(locking.LEVEL_NODE, node.name)
+    self.context.RemoveNode(node.name)
 
-    utils.RemoveHostFromEtcHosts(node.name)
+    rpc.call_node_leave_cluster(node.name)
 
 
 class LUQueryNodes(NoHooksLU):
@@ -1738,11 +1732,10 @@ class LUAddNode(LogicalUnit):
       if not result[node]:
         logger.Error("could not copy file %s to node %s" % (fname, node))
 
-    if not self.op.readd:
-      logger.Info("adding node %s to cluster.conf" % node)
-      self.cfg.AddNode(new_node)
-      # Add the new node to the Ganeti Lock Manager
-      self.context.glm.add(locking.LEVEL_NODE, node)
+    if self.op.readd:
+      self.context.ReaddNode(new_node)
+    else:
+      self.context.AddNode(new_node)
 
 
 class LUQueryClusterInfo(NoHooksLU):
diff --git a/lib/config.py b/lib/config.py
index d3c40cdfe..adf57f3c3 100644
--- a/lib/config.py
+++ b/lib/config.py
@@ -34,6 +34,7 @@ much memory.
 import os
 import tempfile
 import random
+import logging
 
 from ganeti import errors
 from ganeti import locking
@@ -461,6 +462,8 @@ class ConfigWriter:
       node: an object.Node instance
 
     """
+    logging.info("Adding node %s to configuration" % node.name)
+
     self._OpenConfig()
     self._config_data.nodes[node.name] = node
     self._WriteConfig()
@@ -470,6 +473,8 @@ class ConfigWriter:
     """Remove a node from the configuration.
 
     """
+    logging.info("Removing node %s from configuration" % node_name)
+
     self._OpenConfig()
     if node_name not in self._config_data.nodes:
       raise errors.ConfigurationError("Unknown node '%s'" % node_name)
-- 
GitLab