From 10b86782721c3a5ca5850344404ed973f317a064 Mon Sep 17 00:00:00 2001 From: Michael Hanselmann <hansmi@google.com> Date: Tue, 6 Nov 2012 18:27:39 +0100 Subject: [PATCH] Add utility to check if file is executable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This replaces direct calls to βos.accessβ and βos.path.existsβ/βos.path.isfileβ. Signed-off-by: Michael Hanselmann <hansmi@google.com> Reviewed-by: Guido Trotter <ultrotter@google.com> Reviewed-by: Iustin Pop <iustin@google.com> --- lib/backend.py | 2 +- lib/utils/process.py | 4 +-- lib/utils/wrapper.py | 11 +++++++ test/ganeti.utils.wrapper_unittest.py | 46 +++++++++++++++++++++++++++ 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/lib/backend.py b/lib/backend.py index 0a3f2dc89..4aa851fff 100644 --- a/lib/backend.py +++ b/lib/backend.py @@ -711,7 +711,7 @@ def VerifyNode(what, cluster_name): if constants.NV_USERSCRIPTS in what: result[constants.NV_USERSCRIPTS] = \ [script for script in what[constants.NV_USERSCRIPTS] - if not (os.path.exists(script) and os.access(script, os.X_OK))] + if not utils.IsExecutable(script)] if constants.NV_OOB_PATHS in what: result[constants.NV_OOB_PATHS] = tmp = [] diff --git a/lib/utils/process.py b/lib/utils/process.py index e56932f9c..243151f32 100644 --- a/lib/utils/process.py +++ b/lib/utils/process.py @@ -718,8 +718,8 @@ def RunParts(dir_name, env=None, reset_env=False): for relname in sorted(dir_contents): fname = utils_io.PathJoin(dir_name, relname) - if not (os.path.isfile(fname) and os.access(fname, os.X_OK) and - constants.EXT_PLUGIN_MASK.match(relname) is not None): + if not (constants.EXT_PLUGIN_MASK.match(relname) is not None and + utils_wrapper.IsExecutable(fname)): rr.append((relname, constants.RUNPARTS_SKIP, None)) else: try: diff --git a/lib/utils/wrapper.py b/lib/utils/wrapper.py index 982971e71..3b6f6f3dd 100644 --- a/lib/utils/wrapper.py +++ b/lib/utils/wrapper.py @@ -172,6 +172,17 @@ def GetClosedTempfile(*args, **kwargs): return path +def IsExecutable(filename): + """Checks whether a file exists and is executable. + + @type filename: string + @param filename: Filename + @rtype: bool + + """ + return os.path.isfile(filename) and os.access(filename, os.X_OK) + + def ResetTempfileModule(_time=time.time): """Resets the random name generator of the tempfile module. diff --git a/test/ganeti.utils.wrapper_unittest.py b/test/ganeti.utils.wrapper_unittest.py index 16633f7a2..cfdae9a15 100755 --- a/test/ganeti.utils.wrapper_unittest.py +++ b/test/ganeti.utils.wrapper_unittest.py @@ -27,6 +27,7 @@ import os import socket import tempfile import unittest +import shutil from ganeti import constants from ganeti import utils @@ -122,5 +123,50 @@ class TestIgnoreSignals(unittest.TestCase): self.assertEquals(utils.IgnoreSignals(self._Return, 33), 33) +class TestIsExecutable(unittest.TestCase): + def setUp(self): + self.tmpdir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.tmpdir) + + def testNonExisting(self): + fname = utils.PathJoin(self.tmpdir, "file") + assert not os.path.exists(fname) + self.assertFalse(utils.IsExecutable(fname)) + + def testNoFile(self): + path = utils.PathJoin(self.tmpdir, "something") + os.mkdir(path) + assert os.path.isdir(path) + self.assertFalse(utils.IsExecutable(path)) + + def testExecutable(self): + fname = utils.PathJoin(self.tmpdir, "file") + utils.WriteFile(fname, data="#!/bin/bash", mode=0700) + assert os.path.exists(fname) + self.assertTrue(utils.IsExecutable(fname)) + + self.assertTrue(self._TestSymlink(fname)) + + def testFileNotExecutable(self): + fname = utils.PathJoin(self.tmpdir, "file") + utils.WriteFile(fname, data="#!/bin/bash", mode=0600) + assert os.path.exists(fname) + self.assertFalse(utils.IsExecutable(fname)) + + self.assertFalse(self._TestSymlink(fname)) + + def _TestSymlink(self, fname): + assert os.path.exists(fname) + + linkname = utils.PathJoin(self.tmpdir, "cmd") + os.symlink(fname, linkname) + + assert os.path.islink(linkname) + + return utils.IsExecutable(linkname) + + if __name__ == "__main__": testutils.GanetiTestProgram() -- GitLab