Commit a1c8bd23 authored by Jérome Perrin's avatar Jérome Perrin

wrapper script: workaround kernel limitation in shebang line length

http://stackoverflow.com/a/10826085
parent 5cd8ff9f
...@@ -134,13 +134,14 @@ class GenericBaseRecipe(object): ...@@ -134,13 +134,14 @@ class GenericBaseRecipe(object):
pidfile=None pidfile=None
): ):
""" """
Creates a very simple (one command) shell script for process replacement. Creates a shell script for process replacement.
Takes care of quoting. Takes care of quoting.
Takes care of #! line limitation when the wrapped command is a script.
if pidfile parameter is specified, then it will make the wrapper a singleton, if pidfile parameter is specified, then it will make the wrapper a singleton,
accepting to run only if no other instance is running. accepting to run only if no other instance is running.
""" """
lines = [ '#!/bin/sh' ] lines = [ '#!/bin/bash' ]
for comment in comments: for comment in comments:
lines.append('# %s' % comment) lines.append('# %s' % comment)
...@@ -164,7 +165,20 @@ class GenericBaseRecipe(object): ...@@ -164,7 +165,20 @@ class GenericBaseRecipe(object):
fi fi
echo $$ > $pidfile""" % (pidfile, command))) echo $$ > $pidfile""" % (pidfile, command)))
lines.append('exec %s' % shlex.quote(command)) # Inspired by http://stackoverflow.com/a/10826085
lines.append(dedent("""\
COMMAND=%s
# If the wrapped command uses a shebang, execute the referenced
# executable passing the script path as first argument.
# This is to workaround the limitation of 127 characters in #!
if [[ -f $COMMAND && x$(head -c2 "$COMMAND") = x"#!" ]]; then
SHEBANG=$(head -1 "$COMMAND")
INTERPRETER=( ${SHEBANG#\#!} )
COMMAND="${INTERPRETER[@]} $COMMAND"
fi
exec $COMMAND """ % shlex.quote(command)))
for param in parameters: for param in parameters:
if len(lines[-1]) < 40: if len(lines[-1]) < 40:
......
...@@ -54,8 +54,15 @@ class Recipe(GenericBaseRecipe): ...@@ -54,8 +54,15 @@ class Recipe(GenericBaseRecipe):
if environment is not None: if environment is not None:
environment = dict((k.strip(), v.strip()) for k, v in [ environment = dict((k.strip(), v.strip()) for k, v in [
line.split('=') for line in environment.splitlines() if line.strip() ]) line.split('=') for line in environment.splitlines() if line.strip() ])
return [self.createPythonScript(
wrapper_path, # We create a python script and a wrapper around the python
# script because the python script might have a too long #! line
python_script = self.createPythonScript(
wrapper_path+'.py',
'slapos.recipe.librecipe.execute.generic_exec', 'slapos.recipe.librecipe.execute.generic_exec',
(command_line, wait_files, environment,), (command_line, wait_files, environment,), )
)] return [python_script, self.createWrapper(
name=wrapper_path,
command=python_script,
parameters_extra=parameters_extra) ]
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment