Skip to content

Commit f948548

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Run processes without screen"
2 parents 319054f + 3159a82 commit f948548

4 files changed

Lines changed: 279 additions & 51 deletions

File tree

functions-common

Lines changed: 147 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1135,8 +1135,8 @@ function zypper_install {
11351135
# fork. It includes the dirty work of closing extra filehandles and preparing log
11361136
# files to produce the same logs as screen_it(). The log filename is derived
11371137
# from the service name and global-and-now-misnamed ``SCREEN_LOGDIR``
1138-
# Uses globals ``CURRENT_LOG_TIME``, ``SCREEN_LOGDIR``
1139-
# _run_process service "command-line"
1138+
# Uses globals ``CURRENT_LOG_TIME``, ``SCREEN_LOGDIR``, ``SCREEN_NAME``, ``SERVICE_DIR``
1139+
# _old_run_process service "command-line"
11401140
function _run_process {
11411141
local service=$1
11421142
local command="$2"
@@ -1155,8 +1155,12 @@ function _run_process {
11551155
export PYTHONUNBUFFERED=1
11561156
fi
11571157

1158-
exec /bin/bash -c "$command"
1159-
die "$service exec failure: $command"
1158+
# Run under ``setsid`` to force the process to become a session and group leader.
1159+
# The pid saved can be used with pkill -g to get the entire process group.
1160+
setsid $command & echo $! >$SERVICE_DIR/$SCREEN_NAME/$1.pid
1161+
1162+
# Just silently exit this process
1163+
exit 0
11601164
}
11611165

11621166
# Helper to remove the ``*.failure`` files under ``$SERVICE_DIR/$SCREEN_NAME``.
@@ -1184,61 +1188,63 @@ function is_running {
11841188
return $exitcode
11851189
}
11861190

1187-
# run_process() launches a child process that closes all file descriptors and
1188-
# then exec's the passed in command. This is meant to duplicate the semantics
1189-
# of screen_it() without screen. PIDs are written to
1190-
# ``$SERVICE_DIR/$SCREEN_NAME/$service.pid``
1191+
# Run a single service under screen or directly
1192+
# If the command includes shell metachatacters (;<>*) it must be run using a shell
11911193
# run_process service "command-line"
11921194
function run_process {
11931195
local service=$1
11941196
local command="$2"
11951197

1196-
# Spawn the child process
1197-
_run_process "$service" "$command" &
1198-
echo $!
1198+
if is_service_enabled $service; then
1199+
if [[ "$USE_SCREEN" = "True" ]]; then
1200+
screen_service "$service" "$command"
1201+
else
1202+
# Spawn directly without screen
1203+
_run_process "$service" "$command" &
1204+
fi
1205+
fi
11991206
}
12001207

12011208
# Helper to launch a service in a named screen
12021209
# Uses globals ``CURRENT_LOG_TIME``, ``SCREEN_NAME``, ``SCREEN_LOGDIR``,
12031210
# ``SERVICE_DIR``, ``USE_SCREEN``
1204-
# screen_it service "command-line"
1205-
function screen_it {
1211+
# screen_service service "command-line"
1212+
# Run a command in a shell in a screen window
1213+
function screen_service {
1214+
local service=$1
1215+
local command="$2"
1216+
12061217
SCREEN_NAME=${SCREEN_NAME:-stack}
12071218
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
12081219
USE_SCREEN=$(trueorfalse True $USE_SCREEN)
12091220

1210-
if is_service_enabled $1; then
1221+
if is_service_enabled $service; then
12111222
# Append the service to the screen rc file
1212-
screen_rc "$1" "$2"
1223+
screen_rc "$service" "$command"
12131224

1214-
if [[ "$USE_SCREEN" = "True" ]]; then
1215-
screen -S $SCREEN_NAME -X screen -t $1
1216-
1217-
if [[ -n ${SCREEN_LOGDIR} ]]; then
1218-
screen -S $SCREEN_NAME -p $1 -X logfile ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log
1219-
screen -S $SCREEN_NAME -p $1 -X log on
1220-
ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
1221-
fi
1225+
screen -S $SCREEN_NAME -X screen -t $service
12221226

1223-
# sleep to allow bash to be ready to be send the command - we are
1224-
# creating a new window in screen and then sends characters, so if
1225-
# bash isn't running by the time we send the command, nothing happens
1226-
sleep 3
1227-
1228-
NL=`echo -ne '\015'`
1229-
# This fun command does the following:
1230-
# - the passed server command is backgrounded
1231-
# - the pid of the background process is saved in the usual place
1232-
# - the server process is brought back to the foreground
1233-
# - if the server process exits prematurely the fg command errors
1234-
# and a message is written to stdout and the service failure file
1235-
# The pid saved can be used in screen_stop() as a process group
1236-
# id to kill off all child processes
1237-
screen -S $SCREEN_NAME -p $1 -X stuff "$2 & echo \$! >$SERVICE_DIR/$SCREEN_NAME/$1.pid; fg || echo \"$1 failed to start\" | tee \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\"$NL"
1238-
else
1239-
# Spawn directly without screen
1240-
run_process "$1" "$2" >$SERVICE_DIR/$SCREEN_NAME/$1.pid
1227+
if [[ -n ${SCREEN_LOGDIR} ]]; then
1228+
screen -S $SCREEN_NAME -p $service -X logfile ${SCREEN_LOGDIR}/screen-${service}.${CURRENT_LOG_TIME}.log
1229+
screen -S $SCREEN_NAME -p $service -X log on
1230+
ln -sf ${SCREEN_LOGDIR}/screen-${service}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${service}.log
12411231
fi
1232+
1233+
# sleep to allow bash to be ready to be send the command - we are
1234+
# creating a new window in screen and then sends characters, so if
1235+
# bash isn't running by the time we send the command, nothing happens
1236+
sleep 3
1237+
1238+
NL=`echo -ne '\015'`
1239+
# This fun command does the following:
1240+
# - the passed server command is backgrounded
1241+
# - the pid of the background process is saved in the usual place
1242+
# - the server process is brought back to the foreground
1243+
# - if the server process exits prematurely the fg command errors
1244+
# and a message is written to stdout and the service failure file
1245+
# The pid saved can be used in screen_stop() as a process group
1246+
# id to kill off all child processes
1247+
screen -S $SCREEN_NAME -p $service -X stuff "$command & echo \$! >$SERVICE_DIR/$SCREEN_NAME/${service}.pid; fg || echo \"$service failed to start\" | tee \"$SERVICE_DIR/$SCREEN_NAME/${service}.failure\"$NL"
12421248
fi
12431249
}
12441250

@@ -1276,20 +1282,40 @@ function screen_rc {
12761282
# that did not leave a PID behind
12771283
# Uses globals ``SCREEN_NAME``, ``SERVICE_DIR``, ``USE_SCREEN``
12781284
# screen_stop service
1279-
function screen_stop {
1285+
function screen_stop_service {
1286+
local service=$1
1287+
12801288
SCREEN_NAME=${SCREEN_NAME:-stack}
12811289
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
12821290
USE_SCREEN=$(trueorfalse True $USE_SCREEN)
12831291

1284-
if is_service_enabled $1; then
1292+
if is_service_enabled $service; then
1293+
# Clean up the screen window
1294+
screen -S $SCREEN_NAME -p $service -X kill
1295+
fi
1296+
}
1297+
1298+
# Stop a service process
1299+
# If a PID is available use it, kill the whole process group via TERM
1300+
# If screen is being used kill the screen window; this will catch processes
1301+
# that did not leave a PID behind
1302+
# Uses globals ``SERVICE_DIR``, ``USE_SCREEN``
1303+
# stop_process service
1304+
function stop_process {
1305+
local service=$1
1306+
1307+
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
1308+
USE_SCREEN=$(trueorfalse True $USE_SCREEN)
1309+
1310+
if is_service_enabled $service; then
12851311
# Kill via pid if we have one available
1286-
if [[ -r $SERVICE_DIR/$SCREEN_NAME/$1.pid ]]; then
1287-
pkill -TERM -P -$(cat $SERVICE_DIR/$SCREEN_NAME/$1.pid)
1288-
rm $SERVICE_DIR/$SCREEN_NAME/$1.pid
1312+
if [[ -r $SERVICE_DIR/$SCREEN_NAME/$service.pid ]]; then
1313+
pkill -g $(cat $SERVICE_DIR/$SCREEN_NAME/$service.pid)
1314+
rm $SERVICE_DIR/$SCREEN_NAME/$service.pid
12891315
fi
12901316
if [[ "$USE_SCREEN" = "True" ]]; then
12911317
# Clean up the screen window
1292-
screen -S $SCREEN_NAME -p $1 -X kill
1318+
screen_stop_service $service
12931319
fi
12941320
fi
12951321
}
@@ -1325,6 +1351,80 @@ function service_check {
13251351
}
13261352

13271353

1354+
# Deprecated Functions
1355+
# --------------------
1356+
1357+
# _old_run_process() is designed to be backgrounded by old_run_process() to simulate a
1358+
# fork. It includes the dirty work of closing extra filehandles and preparing log
1359+
# files to produce the same logs as screen_it(). The log filename is derived
1360+
# from the service name and global-and-now-misnamed ``SCREEN_LOGDIR``
1361+
# Uses globals ``CURRENT_LOG_TIME``, ``SCREEN_LOGDIR``, ``SCREEN_NAME``, ``SERVICE_DIR``
1362+
# _old_run_process service "command-line"
1363+
function _old_run_process {
1364+
local service=$1
1365+
local command="$2"
1366+
1367+
# Undo logging redirections and close the extra descriptors
1368+
exec 1>&3
1369+
exec 2>&3
1370+
exec 3>&-
1371+
exec 6>&-
1372+
1373+
if [[ -n ${SCREEN_LOGDIR} ]]; then
1374+
exec 1>&${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log 2>&1
1375+
ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
1376+
1377+
# TODO(dtroyer): Hack to get stdout from the Python interpreter for the logs.
1378+
export PYTHONUNBUFFERED=1
1379+
fi
1380+
1381+
exec /bin/bash -c "$command"
1382+
die "$service exec failure: $command"
1383+
}
1384+
1385+
# old_run_process() launches a child process that closes all file descriptors and
1386+
# then exec's the passed in command. This is meant to duplicate the semantics
1387+
# of screen_it() without screen. PIDs are written to
1388+
# ``$SERVICE_DIR/$SCREEN_NAME/$service.pid`` by the spawned child process.
1389+
# old_run_process service "command-line"
1390+
function old_run_process {
1391+
local service=$1
1392+
local command="$2"
1393+
1394+
# Spawn the child process
1395+
_old_run_process "$service" "$command" &
1396+
echo $!
1397+
}
1398+
1399+
# Compatibility for existing start_XXXX() functions
1400+
# Uses global ``USE_SCREEN``
1401+
# screen_it service "command-line"
1402+
function screen_it {
1403+
if is_service_enabled $1; then
1404+
# Append the service to the screen rc file
1405+
screen_rc "$1" "$2"
1406+
1407+
if [[ "$USE_SCREEN" = "True" ]]; then
1408+
screen_service "$1" "$2"
1409+
else
1410+
# Spawn directly without screen
1411+
old_run_process "$1" "$2" >$SERVICE_DIR/$SCREEN_NAME/$1.pid
1412+
fi
1413+
fi
1414+
}
1415+
1416+
# Compatibility for existing stop_XXXX() functions
1417+
# Stop a service in screen
1418+
# If a PID is available use it, kill the whole process group via TERM
1419+
# If screen is being used kill the screen window; this will catch processes
1420+
# that did not leave a PID behind
1421+
# screen_stop service
1422+
function screen_stop {
1423+
# Clean up the screen window
1424+
stop_process $1
1425+
}
1426+
1427+
13281428
# Python Functions
13291429
# ================
13301430

lib/cinder

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,15 +431,15 @@ function start_cinder {
431431
sudo tgtadm --mode system --op update --name debug --value on
432432
fi
433433

434-
screen_it c-api "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-api --config-file $CINDER_CONF"
434+
run_process c-api "$CINDER_BIN_DIR/cinder-api --config-file $CINDER_CONF"
435435
echo "Waiting for Cinder API to start..."
436436
if ! wait_for_service $SERVICE_TIMEOUT $CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT; then
437437
die $LINENO "c-api did not start"
438438
fi
439439

440-
screen_it c-sch "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-scheduler --config-file $CINDER_CONF"
441-
screen_it c-bak "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-backup --config-file $CINDER_CONF"
442-
screen_it c-vol "cd $CINDER_DIR && $CINDER_BIN_DIR/cinder-volume --config-file $CINDER_CONF"
440+
run_process c-sch "$CINDER_BIN_DIR/cinder-scheduler --config-file $CINDER_CONF"
441+
run_process c-bak "$CINDER_BIN_DIR/cinder-backup --config-file $CINDER_CONF"
442+
run_process c-vol "$CINDER_BIN_DIR/cinder-volume --config-file $CINDER_CONF"
443443

444444
# NOTE(jdg): For cinder, startup order matters. To ensure that repor_capabilities is received
445445
# by the scheduler start the cinder-volume service last (or restart it) after the scheduler

tests/fake-service.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#!/bin/bash
2+
# fake-service.sh - a fake service for start/stop testing
3+
# $1 - sleep time
4+
5+
SLEEP_TIME=${1:-3}
6+
7+
LOG=/tmp/fake-service.log
8+
TIMESTAMP_FORMAT=${TIMESTAMP_FORMAT:-"%F-%H%M%S"}
9+
10+
# duplicate output
11+
exec 1> >(tee -a ${LOG})
12+
13+
echo ""
14+
echo "Starting fake-service for ${SLEEP_TIME}"
15+
while true; do
16+
echo "$(date +${TIMESTAMP_FORMAT}) [$$]"
17+
sleep ${SLEEP_TIME}
18+
done
19+

0 commit comments

Comments
 (0)