[Zope3-checkins] SVN: zdaemon/trunk/ - If the run directory does not exist it will be created. This allow to use

Christian Zagrodnick cz at gocept.com
Wed Jan 28 10:36:32 EST 2009


Log message for revision 95330:
  - If the run directory does not exist it will be created. This allow to use
    `/var/run/mydaemon` as run directory when /var/run is a tmpfs (LP #318118).
  
  
  

Changed:
  U   zdaemon/trunk/CHANGES.txt
  U   zdaemon/trunk/src/zdaemon/tests/testzdoptions.py
  U   zdaemon/trunk/src/zdaemon/tests/testzdrun.py
  U   zdaemon/trunk/src/zdaemon/zdctl.py
  U   zdaemon/trunk/src/zdaemon/zdoptions.py

-=-
Modified: zdaemon/trunk/CHANGES.txt
===================================================================
--- zdaemon/trunk/CHANGES.txt	2009-01-28 15:33:11 UTC (rev 95329)
+++ zdaemon/trunk/CHANGES.txt	2009-01-28 15:36:32 UTC (rev 95330)
@@ -6,6 +6,9 @@
 
 - Added support to bootstrap on Jython.
 
+- If the run directory does not exist it will be created. This allow to use
+  `/var/run/mydaemon` as run directory when /var/run is a tmpfs (LP #318118).
+
 Bugs Fixed
 ----------
 

Modified: zdaemon/trunk/src/zdaemon/tests/testzdoptions.py
===================================================================
--- zdaemon/trunk/src/zdaemon/tests/testzdoptions.py	2009-01-28 15:33:11 UTC (rev 95329)
+++ zdaemon/trunk/src/zdaemon/tests/testzdoptions.py	2009-01-28 15:36:32 UTC (rev 95330)
@@ -17,12 +17,14 @@
 import os
 import sys
 import tempfile
+import shutil
 import unittest
 from StringIO import StringIO
 
 import ZConfig
 import zdaemon
-from zdaemon.zdoptions import ZDOptions
+from zdaemon.zdoptions import (
+    ZDOptions, RunnerOptions, existing_parent_directory)
 
 class ZDOptionsTestBase(unittest.TestCase):
 
@@ -320,11 +322,53 @@
                              ["-Xunknown=foo"])
 
 
+
+class TestRunnerDirectory(ZDOptionsTestBase):
+
+    OptionsClass = RunnerOptions
+
+    def setUp(self):
+        super(TestRunnerDirectory, self).setUp()
+        # Create temporary directory to work in
+        self.root = tempfile.mkdtemp()
+
+    def tearDown(self):
+        shutil.rmtree(self.root)
+        super(TestRunnerDirectory, self).tearDown()
+
+    def test_not_existing_directory(self):
+        options = self.OptionsClass()
+        path = os.path.join(self.root, 'does-not-exist', 'really-not')
+        self.check_exit_code(options, ["-z", path])
+
+    def test_existing_director(self):
+        options = self.OptionsClass()
+        options.realize(["-z", self.root])
+
+    def test_parent_is_created(self):
+        options = self.OptionsClass()
+        path = os.path.join(self.root, 'will-be-created')
+        options.realize(["-z", path])
+        self.assertEquals(path, options.directory)
+        # Directory will be created when zdaemon runs, not when the
+        # configuration is read
+        self.assertFalse(os.path.exists(path))
+
+    def test_existing_parent_directory(self):
+        self.assertTrue(existing_parent_directory(self.root))
+        self.assertTrue(existing_parent_directory(
+            os.path.join(self.root, 'not-there')))
+        self.assertRaises(
+            ValueError, existing_parent_directory,
+            os.path.join(self.root, 'not-there', 'this-also-not'))
+
+
 def test_suite():
     suite = unittest.TestSuite()
     for cls in [TestBasicFunctionality,
                 TestZDOptionsEnvironment,
-                TestCommandLineOverrides]:
+                TestCommandLineOverrides,
+                TestRunnerDirectory]:
         suite.addTest(unittest.makeSuite(cls))
     return suite
 

Modified: zdaemon/trunk/src/zdaemon/tests/testzdrun.py
===================================================================
--- zdaemon/trunk/src/zdaemon/tests/testzdrun.py	2009-01-28 15:33:11 UTC (rev 95329)
+++ zdaemon/trunk/src/zdaemon/tests/testzdrun.py	2009-01-28 15:36:32 UTC (rev 95330)
@@ -308,6 +308,46 @@
             if os.path.exists(path):
                 os.remove(path)
 
+
+class TestRunnerDirectory(unittest.TestCase):
+
+    def setUp(self):
+        super(TestRunnerDirectory, self).setUp()
+        self.root = tempfile.mkdtemp()
+        self.save_stdout = sys.stdout
+        self.save_stderr = sys.stderr
+        sys.stdout = StringIO()
+        sys.stderr = StringIO()
+
+    def tearDown(self):
+        shutil.rmtree(self.root)
+        sys.stdout = self.save_stdout
+        sys.stderr = self.save_stderr
+        super(TestRunnerDirectory, self).tearDown()
+
+    def run_ctl(self, path):
+        true_cmd = "/bin/true"
+        if not os.path.exists(true_cmd):
+            true_cmd = "/usr/bin/true"  # Mac OS X
+        options = zdctl.ZDCtlOptions()
+        options.realize(['-z', path, '-p', 'sleep 1', 'fg'])
+        self.expect = 'sleep 1\n'
+        proc = zdctl.ZDCmd(options)
+        proc.onecmd(" ".join(options.args))
+
+    def testCtlRunDirectoryCreation(self):
+        path = os.path.join(self.root, 'rundir')
+        self.run_ctl(path)
+        self.assert_(os.path.exists(path))
+
+    def testCtlRunDirectoryCreationOnlyOne(self):
+        path = os.path.join(self.root, 'rundir', 'not-created')
+        self.run_ctl(path)
+        self.assertFalse(os.path.exists(path))
+        self.assertTrue(sys.stdout.getvalue().startswith(
+            'Error: invalid value for -z'))
+
+
 def send_action(action, sockname):
     """Send an action to the zdrun server and return the response.
 
@@ -338,6 +378,7 @@
     suite = unittest.TestSuite()
     if os.name == "posix":
         suite.addTest(unittest.makeSuite(ZDaemonTests))
+        suite.addTest(unittest.makeSuite(TestRunnerDirectory))
     return suite
 
 if __name__ == '__main__':

Modified: zdaemon/trunk/src/zdaemon/zdctl.py
===================================================================
--- zdaemon/trunk/src/zdaemon/zdctl.py	2009-01-28 15:33:11 UTC (rev 95329)
+++ zdaemon/trunk/src/zdaemon/zdctl.py	2009-01-28 15:36:32 UTC (rev 95330)
@@ -144,8 +144,20 @@
                     for k, v in env.items():
                         os.environ[k] = v
 
+        self.create_rundir()
         self.set_uid()
 
+    def create_rundir(self):
+        if self.options.directory is None:
+            return
+        if os.path.isdir(self.options.directory):
+            return
+        os.mkdir(self.options.directory)
+        uid = os.geteuid()
+        if uid == 0 and uid != self.options.uid:
+            # Change owner of directory to target
+            os.chown(self.options.uid, self.options.gid)
+
     def set_uid(self):
         if self.options.uid is None:
             return

Modified: zdaemon/trunk/src/zdaemon/zdoptions.py
===================================================================
--- zdaemon/trunk/src/zdaemon/zdoptions.py	2009-01-28 15:33:11 UTC (rev 95329)
+++ zdaemon/trunk/src/zdaemon/zdoptions.py	2009-01-28 15:36:32 UTC (rev 95330)
@@ -362,7 +362,7 @@
         self.add("umask", "runner.umask", "m:", "umask=", octal_type,
                  default=022)
         self.add("directory", "runner.directory", "z:", "directory=",
-                 ZConfig.datatypes.existing_directory)
+                 existing_parent_directory)
         self.add("hang_around", "runner.hang_around", default=0)
 
     def realize(self, *args, **kwds):
@@ -401,6 +401,14 @@
     return int(arg, 8)
 
 
+def existing_parent_directory(arg):
+    path = os.path.expanduser(arg)
+    parent, tail = os.path.split(path)
+    if os.path.isdir(parent):
+        return path
+    raise ValueError('%s is not an existing directory' % arg)
+
+
 def _test():
     # Stupid test program
     z = ZDOptions()



More information about the Zope3-Checkins mailing list