diff --git a/cdist/exec/remote.py b/cdist/exec/remote.py index af9e70cb..ac416651 100644 --- a/cdist/exec/remote.py +++ b/cdist/exec/remote.py @@ -216,18 +216,46 @@ class Remote: _wrap_addr(self.target_host[0]), destination)]) self._run_command(command) + def check_if_executable(self, path): + """Check if the given remote resource is "executable", + (i.e. has its execute bit set). + Return True/False + + """ + self.log.trace("Remote check if executable : %s", path) + + # XXX: Too bad we can't just check the returned status. + # Hence the dance with "echo TRUE/FALSE" + chk = " ".join([ + 'if [ -f "{path}" ] && [ -x "{path}" ] ', + '; then echo TRUE ; else echo FALSE ; fi']).format(path=path) + + out = self.run(['/bin/sh', '-c', "'" + chk + "'"], + env=None, return_output=True) or "" + return out.strip() == 'TRUE' + def run_script(self, script, env=None, return_output=False, stdout=None, stderr=None): """Run the given script with the given environment on the remote side. Return the output as a string. """ + command = [script] - command = [ - self.configuration.get('remote_shell', "/bin/sh"), - "-e" - ] - command.append(script) + if self.check_if_executable(script): + # Allow transparent shebang support for "executable" scripts + self.log.debug( + '%-70s : Remote script is executable, ' + + 'running it directly', script) + else: + # FIXME: Who knows what "-e" means for an arbitrary remote_shell ? + # Keeping the old behavior (of always adding "-e") for the moment. + shell = [self.configuration.get('remote_shell', "/bin/sh"), "-e"] + + command = shell + command + self.log.debug( + '%-70s : Remote script is NOT executable, ' + + 'running it with %s', script, " ".join(shell)) return self.run(command, env=env, return_output=return_output, stdout=stdout, stderr=stderr)