Commit f0b37366 authored by Tomáš Peterka's avatar Tomáš Peterka

[recipe.wrapper] Add init(-command) and cpu-exclusive into buildout parameters.

-  intial command being run before actual `command` is specified by "init"
-  wrapper can demand exclusive CPU core by "reserve-cpu"
-  "command-line" has alias "command"
-  "wrapper-path" has alias "destination" to be consistent with other recipes
parent 066a340c
......@@ -131,7 +131,7 @@ class GenericBaseRecipe(object):
def createWrapper(self, name, command, parameters, comments=[],
parameters_extra=False, environment=None,
pidfile=None
pidfile=None, init_command=None, reserve_cpu=False
):
"""
Creates a shell script for process replacement.
......@@ -139,6 +139,9 @@ class GenericBaseRecipe(object):
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,
accepting to run only if no other instance is running.
:param init_command: str, arbitrary command being run before the actual `command`
:param reserve_cpu: bool, try to reserve one core for the `command`
"""
lines = [ '#!/bin/sh' ]
......@@ -163,6 +166,18 @@ class GenericBaseRecipe(object):
fi
echo $$ > $pidfile""" % shlex.quote(pidfile)))
if reserve_cpu:
# if the CGROUPS cpuset is available (and prepared by slap format)
# request an exclusive CPU core for this process
lines.append(dedent("""
# put own PID into waiting list for exclusive CPU-core access
echo $$ >> ~/.slapos-cpu-exclusive
"""))
if init_command is not None:
lines.append("")
lines.append(init_command)
lines.append(dedent('''
# If the wrapped command uses a shebang, execute the referenced
# executable passing the script path as first argument.
......
......@@ -31,9 +31,28 @@ import os
from slapos.recipe.librecipe import GenericBaseRecipe
class Recipe(GenericBaseRecipe):
"""Recipe to create a script from given command and options.
:param str init: shell command to execute before actuall command
:param str command: shell command which launches the intended process
:param str cleanup: shell command executed at the end or in case of SIGTERM/INT/KILL
:param bool safe: controls whether the parameters will be escaped (default false implies escaping)
:param lines wait-for-files: list of files to wait for
:param str pidfile: path to pidfile ensure exclusivity for the process
:param bool remove-pidfile: if pidfile is removed upon exit
:param bool parameters-extra: whether wrapper parameters are passed onto command
"""
def install(self):
command_line = shlex.split(self.options['command-line'])
wrapper_path = self.options['wrapper-path']
command_line = shlex.split(self.options.get('command-line') or self.options.get('command'))
assert command_line, "Specify either 'command-line' or 'command'"
# be more consistent with the naming across recipies - use "destination" too
wrapper_path = self.options.get('wrapper-path') or self.options.get('destination')
assert wrapper_path, "Specify either 'wrapper-path' or 'destination'"
# optionals bellow
init = self.options.get('init')
reserve_cpu = self.options.get('reserve-cpu', False)
wait_files = self.options.get('wait-for-files')
environment = self.options.get('environment')
parameters_extra = self.options.get('parameters-extra')
......@@ -47,6 +66,8 @@ class Recipe(GenericBaseRecipe):
parameters=command_line[1:],
parameters_extra=parameters_extra,
pidfile=pidfile,
init_command=init,
reserve_cpu=reserve_cpu
)]
# More complex needs: create a Python script as wrapper
......@@ -76,5 +97,7 @@ class Recipe(GenericBaseRecipe):
parameters=[],
parameters_extra=parameters_extra,
pidfile=pidfile,
init_command=init,
reserve_cpu=reserve_cpu
)]
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