From: Patrick Donnelly Date: Wed, 17 May 2023 18:32:19 +0000 (-0400) Subject: teuthology/task/install: reorganize binary helpers X-Git-Tag: 1.2.0~102^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=59ebe214b9c27740db84df37a802e4e376b7594c;p=teuthology.git teuthology/task/install: reorganize binary helpers We intend to install these so move them into an appropriately named directory. Signed-off-by: Patrick Donnelly --- diff --git a/setup.cfg b/setup.cfg index 9fbd84c2c..4b5b2314c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -123,8 +123,8 @@ teuthology.openstack = teuthology.suite = fragment-merge.lua teuthology.task.install = - adjust-ulimits - daemon-helper + bin/adjust-ulimits + bin/daemon-helper teuthology.task.internal = edit_sudoers.sh diff --git a/teuthology/task/install/adjust-ulimits b/teuthology/task/install/adjust-ulimits deleted file mode 100755 index 6f05392b9..000000000 --- a/teuthology/task/install/adjust-ulimits +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/sh -# If we're running as root, allow large amounts of open files. -USER=$(whoami) - -# If a ulimit call fails, exit immediately. -set -e - -if [ "$USER" = "root" ] -then - # Enable large number of open files - ulimit -n 65536 -fi - -# Enable core dumps for everything -ulimit -c unlimited -exec "$@" diff --git a/teuthology/task/install/bin/adjust-ulimits b/teuthology/task/install/bin/adjust-ulimits new file mode 100755 index 000000000..6f05392b9 --- /dev/null +++ b/teuthology/task/install/bin/adjust-ulimits @@ -0,0 +1,16 @@ +#!/bin/sh +# If we're running as root, allow large amounts of open files. +USER=$(whoami) + +# If a ulimit call fails, exit immediately. +set -e + +if [ "$USER" = "root" ] +then + # Enable large number of open files + ulimit -n 65536 +fi + +# Enable core dumps for everything +ulimit -c unlimited +exec "$@" diff --git a/teuthology/task/install/bin/daemon-helper b/teuthology/task/install/bin/daemon-helper new file mode 100755 index 000000000..3638a6d73 --- /dev/null +++ b/teuthology/task/install/bin/daemon-helper @@ -0,0 +1,114 @@ +#!/usr/bin/python3 + +""" +Helper script for running long-living processes. + +(Name says daemon, but that is intended to mean "long-living", we +assume child process does not double-fork.) + +We start the command passed as arguments, with /dev/null as stdin, and +then wait for EOF on stdin. + +When EOF is seen on stdin, the child process is killed. + +When the child process exits, this helper exits too. + +Usage: + daemon-helper [--kill-group] [nostdin] COMMAND ... +""" + +from __future__ import print_function + +import fcntl +import os +import select +import signal +import struct +import subprocess +import sys +from argparse import ArgumentParser + +parser = ArgumentParser(epilog= + 'The remaining parameters are the command to be run. If these\n' + + 'parameters start wih nostdin, then no stdin input is expected.') +parser.add_argument('signal') +parser.add_argument('--kill-group', action='store_true', + help='kill all processes in the group') +parser.add_argument('--nostdin', action='store_true', + help='no stdin input expected') +parsed, args = parser.parse_known_args() +end_signal = signal.SIGKILL +if parsed.signal == 'term': + end_signal = signal.SIGTERM +group = parsed.kill_group +nostdin = parsed.nostdin +skip_nostdin = 0 +try: + if args[0] == 'nostdin': + nostdin = True + skip_nostdin = 1 +except IndexError: + print('No command specified') + sys.exit(1) + + +proc = None +if nostdin: + if len(args) - skip_nostdin == 0: + print('No command specified') + sys.exit(1) + proc = subprocess.Popen( + args=args[skip_nostdin:], + ) +else: + with open('/dev/null', 'rb') as devnull: + proc = subprocess.Popen( + args=args, + stdin=devnull, + preexec_fn=os.setsid, + ) + +flags = fcntl.fcntl(0, fcntl.F_GETFL) +fcntl.fcntl(0, fcntl.F_SETFL, flags | os.O_NDELAY) + +saw_eof = False +while True: + r,w,x = select.select([0], [], [0], 0.2) + if r: + data = os.read(0, 1) + if not data: + saw_eof = True + if not group: + proc.send_signal(end_signal) + else: + os.killpg(proc.pid, end_signal) + break + else: + sig, = struct.unpack('!b', data) + if not group: + proc.send_signal(sig) + else: + os.killpg(proc.pid, end_signal) + + + if proc.poll() is not None: + # child exited + break + +exitstatus = proc.wait() +if exitstatus > 0: + print('{me}: command failed with exit status {exitstatus:d}'.format( + me=os.path.basename(sys.argv[0]), + exitstatus=exitstatus, + ), file=sys.stderr) + sys.exit(exitstatus) +elif exitstatus < 0: + if saw_eof and exitstatus == -end_signal: + # suppress error from the exit we intentionally caused + pass + else: + print('{me}: command crashed with signal {signal:d}'.format( + me=os.path.basename(sys.argv[0]), + signal=-exitstatus, + ), file=sys.stderr) + sys.exit(1) diff --git a/teuthology/task/install/daemon-helper b/teuthology/task/install/daemon-helper deleted file mode 100755 index 3638a6d73..000000000 --- a/teuthology/task/install/daemon-helper +++ /dev/null @@ -1,114 +0,0 @@ -#!/usr/bin/python3 - -""" -Helper script for running long-living processes. - -(Name says daemon, but that is intended to mean "long-living", we -assume child process does not double-fork.) - -We start the command passed as arguments, with /dev/null as stdin, and -then wait for EOF on stdin. - -When EOF is seen on stdin, the child process is killed. - -When the child process exits, this helper exits too. - -Usage: - daemon-helper [--kill-group] [nostdin] COMMAND ... -""" - -from __future__ import print_function - -import fcntl -import os -import select -import signal -import struct -import subprocess -import sys -from argparse import ArgumentParser - -parser = ArgumentParser(epilog= - 'The remaining parameters are the command to be run. If these\n' + - 'parameters start wih nostdin, then no stdin input is expected.') -parser.add_argument('signal') -parser.add_argument('--kill-group', action='store_true', - help='kill all processes in the group') -parser.add_argument('--nostdin', action='store_true', - help='no stdin input expected') -parsed, args = parser.parse_known_args() -end_signal = signal.SIGKILL -if parsed.signal == 'term': - end_signal = signal.SIGTERM -group = parsed.kill_group -nostdin = parsed.nostdin -skip_nostdin = 0 -try: - if args[0] == 'nostdin': - nostdin = True - skip_nostdin = 1 -except IndexError: - print('No command specified') - sys.exit(1) - - -proc = None -if nostdin: - if len(args) - skip_nostdin == 0: - print('No command specified') - sys.exit(1) - proc = subprocess.Popen( - args=args[skip_nostdin:], - ) -else: - with open('/dev/null', 'rb') as devnull: - proc = subprocess.Popen( - args=args, - stdin=devnull, - preexec_fn=os.setsid, - ) - -flags = fcntl.fcntl(0, fcntl.F_GETFL) -fcntl.fcntl(0, fcntl.F_SETFL, flags | os.O_NDELAY) - -saw_eof = False -while True: - r,w,x = select.select([0], [], [0], 0.2) - if r: - data = os.read(0, 1) - if not data: - saw_eof = True - if not group: - proc.send_signal(end_signal) - else: - os.killpg(proc.pid, end_signal) - break - else: - sig, = struct.unpack('!b', data) - if not group: - proc.send_signal(sig) - else: - os.killpg(proc.pid, end_signal) - - - if proc.poll() is not None: - # child exited - break - -exitstatus = proc.wait() -if exitstatus > 0: - print('{me}: command failed with exit status {exitstatus:d}'.format( - me=os.path.basename(sys.argv[0]), - exitstatus=exitstatus, - ), file=sys.stderr) - sys.exit(exitstatus) -elif exitstatus < 0: - if saw_eof and exitstatus == -end_signal: - # suppress error from the exit we intentionally caused - pass - else: - print('{me}: command crashed with signal {signal:d}'.format( - me=os.path.basename(sys.argv[0]), - signal=-exitstatus, - ), file=sys.stderr) - sys.exit(1) diff --git a/teuthology/task/install/util.py b/teuthology/task/install/util.py index 0fec21a61..6e58c9a57 100644 --- a/teuthology/task/install/util.py +++ b/teuthology/task/install/util.py @@ -85,7 +85,7 @@ def _ship_utilities(ctx): destdir = '/usr/bin' for filename in FILES: log.info('Shipping %r...', filename) - src = os.path.join(os.path.dirname(__file__), filename) + src = os.path.join(os.path.dirname(__file__), 'bin', filename) dst = os.path.join(destdir, filename) filenames.append(dst) with open(src, 'rb') as f: