vcluster: Don't virtualize /etc/hosts path
authorMichael Hanselmann <hansmi@google.com>
Wed, 10 Oct 2012 09:09:33 +0000 (11:09 +0200)
committerMichael Hanselmann <hansmi@google.com>
Thu, 11 Oct 2012 09:56:51 +0000 (11:56 +0200)
/etc/hosts is a bit special as it's a system-wide file and the virtual
cluster/node root doesn't apply. The modification of /etc/hosts should
be disabled in virtual clusters. If it isn't, however, the vcluster
functions would raise an exception complaining about a path outside of
the virtual node root. This patch adds a whitelist to exclude
/etc/hosts.

Signed-off-by: Michael Hanselmann <hansmi@google.com>
Reviewed-by: Iustin Pop <iustin@google.com>

lib/pathutils.py
lib/vcluster.py
test/ganeti.vcluster_unittest.py

index 0efbc4c..bb1371a 100644 (file)
@@ -45,7 +45,7 @@ KVM_CONSOLE_WRAPPER = _autoconf.PKGLIBDIR + "/tools/kvm-console-wrapper"
 KVM_IFUP = _autoconf.PKGLIBDIR + "/kvm-ifup"
 SETUP_SSH = _autoconf.TOOLSDIR + "/setup-ssh"
 XM_CONSOLE_WRAPPER = _autoconf.PKGLIBDIR + "/tools/xm-console-wrapper"
-ETC_HOSTS = "/etc/hosts"
+ETC_HOSTS = vcluster.ETC_HOSTS
 
 # Top-level paths
 DATA_DIR = LOCALSTATEDIR + "/lib/ganeti"
index bf25281..0443d11 100644 (file)
@@ -32,10 +32,17 @@ import os
 from ganeti import compat
 
 
+ETC_HOSTS = "/etc/hosts"
+
 _VIRT_PATH_PREFIX = "/###-VIRTUAL-PATH-###,"
 _ROOTDIR_ENVNAME = "GANETI_ROOTDIR"
 _HOSTNAME_ENVNAME = "GANETI_HOSTNAME"
 
+#: List of paths which shouldn't be virtualized
+_VPATH_WHITELIST = frozenset([
+  ETC_HOSTS,
+  ])
+
 
 def _GetRootDirectory(envname):
   """Retrieves root directory from an environment variable.
@@ -236,7 +243,7 @@ def MakeVirtualPath(path, _noderoot=_VIRT_NODEROOT):
   """
   assert os.path.isabs(path)
 
-  if _noderoot:
+  if _noderoot and path not in _VPATH_WHITELIST:
     return _VIRT_PATH_PREFIX + _RemoveNodePrefix(path, _noderoot=_noderoot)
   else:
     return path
@@ -252,7 +259,7 @@ def LocalizeVirtualPath(path, _noderoot=_VIRT_NODEROOT):
   """
   assert os.path.isabs(path)
 
-  if _noderoot:
+  if _noderoot and path not in _VPATH_WHITELIST:
     if path.startswith(_VIRT_PATH_PREFIX):
       return AddNodePrefix(path[len(_VIRT_PATH_PREFIX):], _noderoot=_noderoot)
     else:
index 9808fe4..e47b1f8 100755 (executable)
@@ -27,6 +27,7 @@ import unittest
 from ganeti import utils
 from ganeti import compat
 from ganeti import vcluster
+from ganeti import pathutils
 
 import testutils
 
@@ -200,6 +201,13 @@ class TestMakeVirtualPath(unittest.TestCase):
     self.assertEqual(vcluster.MakeVirtualPath("/tmp/file", _noderoot=None),
                      "/tmp/file")
 
+  def testWhitelisted(self):
+    mvp = vcluster.MakeVirtualPath
+    for path in vcluster._VPATH_WHITELIST:
+      self.assertEqual(mvp(path), path)
+      self.assertEqual(mvp(path, _noderoot=None), path)
+      self.assertEqual(mvp(path, _noderoot="/tmp"), path)
+
 
 class TestLocalizeVirtualPath(unittest.TestCase):
   def testWrongPrefix(self):
@@ -225,6 +233,13 @@ class TestLocalizeVirtualPath(unittest.TestCase):
     self.assertEqual(vcluster.LocalizeVirtualPath("/tmp/file", _noderoot=None),
                      "/tmp/file")
 
+  def testWhitelisted(self):
+    lvp = vcluster.LocalizeVirtualPath
+    for path in vcluster._VPATH_WHITELIST:
+      self.assertEqual(lvp(path), path)
+      self.assertEqual(lvp(path, _noderoot=None), path)
+      self.assertEqual(lvp(path, _noderoot="/tmp"), path)
+
 
 class TestVirtualPathPrefix(unittest.TestCase):
   def test(self):