From 8f9a87c57f0c6de8a2176f8c988e26d6efb2b50d Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Thu, 28 Apr 2011 10:26:53 +0200
Subject: [PATCH] SetEtcHostsEntry: maintain existing ordering

Currently RemoveEtcHostsEntry keeps the ordering, but SetEtcHostsEntry
not, as it will always write the new entry at the end of file. I
personally dislike this as it "uglifies" my custom host files, so this
patch makes it update the record instead in-place so to say instead of
moving it.

The patch also simplifies the construction of the new line (we were
doing duplicate work for no gain).

Signed-off-by: Iustin Pop <iustin@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>
---
 lib/utils/nodesetup.py                  | 20 ++++++++++++--------
 test/ganeti.utils.nodesetup_unittest.py | 12 +++++++++++-
 2 files changed, 23 insertions(+), 9 deletions(-)

diff --git a/lib/utils/nodesetup.py b/lib/utils/nodesetup.py
index 13b70f3c7..e5d27ca7e 100644
--- a/lib/utils/nodesetup.py
+++ b/lib/utils/nodesetup.py
@@ -45,19 +45,23 @@ def SetEtcHostsEntry(file_name, ip, hostname, aliases):
 
   """
   # Ensure aliases are unique
-  aliases = algo.UniqueSequence([hostname] + aliases)[1:]
+  names = algo.UniqueSequence([hostname] + aliases)
 
   out = StringIO()
+
+  def _write_entry(written):
+    if not written:
+      out.write("%s\t%s\n" % (ip, " ".join(names)))
+    return True
+
+  written = False
   for line in io.ReadFile(file_name).splitlines(True):
     fields = line.split()
     if fields and not fields[0].startswith("#") and ip == fields[0]:
-      continue
-    out.write(line)
-
-  out.write("%s\t%s" % (ip, hostname))
-  if aliases:
-    out.write(" %s" % " ".join(aliases))
-  out.write("\n")
+      written = _write_entry(written)
+    else:
+      out.write(line)
+  _write_entry(written)
 
   io.WriteFile(file_name, data=out.getvalue(), mode=0644)
 
diff --git a/test/ganeti.utils.nodesetup_unittest.py b/test/ganeti.utils.nodesetup_unittest.py
index 3d386a465..c3480c2e0 100755
--- a/test/ganeti.utils.nodesetup_unittest.py
+++ b/test/ganeti.utils.nodesetup_unittest.py
@@ -1,7 +1,7 @@
 #!/usr/bin/python
 #
 
-# Copyright (C) 2006, 2007, 2010 Google Inc.
+# Copyright (C) 2006, 2007, 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
@@ -76,6 +76,16 @@ class TestEtcHosts(testutils.GanetiTestCase):
       "198.51.100.4\tmyhost\n")
     self.assertFileMode(self.tmpname, 0644)
 
+  def testSettingOrdering(self):
+    utils.SetEtcHostsEntry(self.tmpname, "127.0.0.1", "localhost.localdomain",
+                           ["localhost"])
+
+    self.assertFileContent(self.tmpname,
+      "# This is a test file for /etc/hosts\n"
+      "127.0.0.1\tlocalhost.localdomain localhost\n"
+      "192.0.2.1 router gw\n")
+    self.assertFileMode(self.tmpname, 0644)
+
   def testRemovingExistingHost(self):
     utils.RemoveEtcHostsEntry(self.tmpname, "router")
 
-- 
GitLab