From 6b0d2d7827dedf553ac7d25cb75ebcacc7379532 Mon Sep 17 00:00:00 2001 From: Tomas Sedovic Date: Thu, 26 Apr 2012 17:27:25 +0200 Subject: [PATCH] Implement runas for cfn-hup As a side effect, this fixes #109. By running everything through `su -c`, all the piping and redirection issues are outsourced there. --- heat/cfntools/cfn_helper.py | 2 +- heat/tests/test_cfn.py | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/heat/cfntools/cfn_helper.py b/heat/cfntools/cfn_helper.py index 3b6e491a45..637cdab3e7 100644 --- a/heat/cfntools/cfn_helper.py +++ b/heat/cfntools/cfn_helper.py @@ -159,7 +159,7 @@ class CommandRunner(object): self """ logging.debug("Running command: %s" % self._command) - cmd = self._command.split() + cmd = ['su', user, '-c', self._command] subproc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output = subproc.communicate() diff --git a/heat/tests/test_cfn.py b/heat/tests/test_cfn.py index 8f6d523722..9e0ee49ac1 100644 --- a/heat/tests/test_cfn.py +++ b/heat/tests/test_cfn.py @@ -6,9 +6,11 @@ import io import sys +import mox import nose from nose.plugins.attrib import attr from nose import with_setup +import unittest import shutil from heat.cfntools.cfn_helper import * @@ -113,6 +115,12 @@ def tearDown_metadata_files(): shutil.rmtree('/tmp/_files_test_', ignore_errors=True) +class PopenMock: + def communicate(self): + self.returncode = 0 + return ['', None] + + @with_setup(None, tearDown_metadata_files) @attr(tag=['unit', 'cfn-metadata']) @attr(speed='fast') @@ -161,6 +169,40 @@ def test_metadata_files(): assert(os.stat('/tmp/_files_test_/epel.repo').st_mode & mask == 0644) assert(os.stat('/tmp/_files_test_/_with/some/dirs/to/make/small.conf').st_mode & mask == 0777) +class CommandRunnerTest(unittest.TestCase): + def setUp(self): + self.m = mox.Mox() + + def tearDown(self): + self.m.UnsetStubs() + + @attr(tag=['unit', 'cfn-helper']) + @attr(speed='fast') + def test_runas(self): + import subprocess + self.m.StubOutWithMock(subprocess, 'Popen') + subprocess.Popen(['su', 'user', '-c', 'some command'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).AndReturn(PopenMock()) + + self.m.ReplayAll() + CommandRunner('some command').run('user') + self.m.VerifyAll() + + @attr(tag=['unit', 'cfn-helper']) + @attr(speed='fast') + def test_default_runas(self): + import subprocess + self.m.StubOutWithMock(subprocess, 'Popen') + subprocess.Popen(['su', 'root', '-c', 'some command'], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE).AndReturn(PopenMock()) + + self.m.ReplayAll() + CommandRunner('some command').run() + self.m.VerifyAll() + + if __name__ == '__main__': sys.argv.append(__file__) nose.main()