Mini Shell
#!/opt/imh-python/bin/python3
"""Executes a process, pausing and resuming it while monitoring server load"""
# vim: set ts=4 sw=4 expandtab syntax=python:
import sys
import argparse
import cproc
MISSING_RCODE = 127
BAD_ARGS_RCODE = 2
def parse_args() -> tuple[cproc.ProcLimit, list[str]]:
"""Parse limits used to create cproc.ProcLimit"""
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.MetavarTypeHelpFormatter,
usage='%(prog)s [-l float] [-s int -r int] -- COMMAND',
)
parser.add_argument(
'--load',
'-l',
type=float,
dest='load',
help='Specify a custom maximum server load. '
'If unset, uses number of cpu cores (1 on vps)',
)
grace = parser.add_argument_group(title='Grace periods')
grace.add_argument(
'--sleep',
'-s',
type=int,
dest='sleep',
help='Number of seconds to sleep if the server is overloaded. If not '
'specified, sleep indefinitely until server load improves',
)
grace.add_argument(
'--run',
'-r',
type=int,
dest='run',
help='Number of seconds to execute once -s/--sleep expires. '
'Required if -s/--sleep is specified',
)
parser.add_argument('cmd', nargs='+', type=str, help=argparse.SUPPRESS)
args = parser.parse_args()
if args.sleep is not None and args.run is None:
print('-r/--run is required if -s/--sleep is used', file=sys.stderr)
sys.exit(BAD_ARGS_RCODE)
limit = cproc.ProcLimit(
value=args.load,
grace=None if args.sleep is None else (args.sleep, args.run),
)
return limit, args.cmd
def main():
"""Collect args, execute command, return with the same return code"""
limit, cmd = parse_args()
try:
proc = cproc.Proc(
cmd,
lim=limit,
shell=False,
encoding=None,
stdout=None,
stderr=None,
)
sys.exit(proc.wait())
except FileNotFoundError as exc:
print(exc, file=sys.stderr)
sys.exit(MISSING_RCODE)
if __name__ == '__main__':
main()
Zerion Mini Shell 1.0