Skip to content

Commit 681f3fd

Browse files
author
Dean Troyer
committed
Add run_process() to start services without screen
* USE_SCREEN defaults to True, set it to False to exec the services directly via bash. SCREEN_DEV is still supported until the CI scripts get updated. * The extra logging file descriptors are properly closed in the child process and stdout/stderr are redirected to the log files. * The screen_rc() call is still present; this means that stack-screenrc will have a complete record of what was started and rejoin-stack.sh may be able to re-create the setup under screen. * The python interpreter was unwilling to write to the log files without unbufering stdout by using PYTHONUNBUFFERED. This feels hackish and should be investigated further. Change-Id: I012ed049f2c8b185a2e6929d73edc29e167bc21f
1 parent 43eb8f8 commit 681f3fd

3 files changed

Lines changed: 69 additions & 19 deletions

File tree

functions

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -735,26 +735,69 @@ function restart_service() {
735735
}
736736

737737

738+
# _run_process() is designed to be backgrounded by run_process() to simulate a
739+
# fork. It includes the dirty work of closing extra filehandles and preparing log
740+
# files to produce the same logs as screen_it(). The log filename is derived
741+
# from the service name and global-and-now-misnamed SCREEN_LOGDIR
742+
# _run_process service "command-line"
743+
function _run_process() {
744+
local service=$1
745+
local command="$2"
746+
747+
# Undo logging redirections and close the extra descriptors
748+
exec 1>&3
749+
exec 2>&3
750+
exec 3>&-
751+
exec 6>&-
752+
753+
if [[ -n ${SCREEN_LOGDIR} ]]; then
754+
exec 1>&${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log 2>&1
755+
ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
756+
757+
# TODO(dtroyer): Hack to get stdout from the Python interpreter for the logs.
758+
export PYTHONUNBUFFERED=1
759+
fi
760+
761+
exec /bin/bash -c "$command"
762+
die "$service exec failure: $command"
763+
}
764+
765+
766+
# run_process() launches a child process that closes all file descriptors and
767+
# then exec's the passed in command. This is meant to duplicate the semantics
768+
# of screen_it() without screen. PIDs are written to
769+
# $SERVICE_DIR/$SCREEN_NAME/$service.pid
770+
# run_process service "command-line"
771+
function run_process() {
772+
local service=$1
773+
local command="$2"
774+
775+
# Spawn the child process
776+
_run_process "$service" "$command" &
777+
echo $!
778+
}
779+
780+
738781
# Helper to launch a service in a named screen
739782
# screen_it service "command-line"
740783
function screen_it {
741784
SCREEN_NAME=${SCREEN_NAME:-stack}
742785
SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
743-
SCREEN_DEV=`trueorfalse True $SCREEN_DEV`
786+
USE_SCREEN=$(trueorfalse True $USE_SCREEN)
744787

745788
if is_service_enabled $1; then
746789
# Append the service to the screen rc file
747790
screen_rc "$1" "$2"
748791

749-
screen -S $SCREEN_NAME -X screen -t $1
792+
if [[ "$USE_SCREEN" = "True" ]]; then
793+
screen -S $SCREEN_NAME -X screen -t $1
750794

751-
if [[ -n ${SCREEN_LOGDIR} ]]; then
752-
screen -S $SCREEN_NAME -p $1 -X logfile ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log
753-
screen -S $SCREEN_NAME -p $1 -X log on
754-
ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
755-
fi
795+
if [[ -n ${SCREEN_LOGDIR} ]]; then
796+
screen -S $SCREEN_NAME -p $1 -X logfile ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log
797+
screen -S $SCREEN_NAME -p $1 -X log on
798+
ln -sf ${SCREEN_LOGDIR}/screen-${1}.${CURRENT_LOG_TIME}.log ${SCREEN_LOGDIR}/screen-${1}.log
799+
fi
756800

757-
if [[ "$SCREEN_DEV" = "True" ]]; then
758801
# sleep to allow bash to be ready to be send the command - we are
759802
# creating a new window in screen and then sends characters, so if
760803
# bash isn't running by the time we send the command, nothing happens
@@ -763,7 +806,8 @@ function screen_it {
763806
NL=`echo -ne '\015'`
764807
screen -S $SCREEN_NAME -p $1 -X stuff "$2 || touch \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\"$NL"
765808
else
766-
screen -S $SCREEN_NAME -p $1 -X exec /bin/bash -c "$2 || touch \"$SERVICE_DIR/$SCREEN_NAME/$1.failure\""
809+
# Spawn directly without screen
810+
run_process "$1" "$2" >$SERVICE_DIR/$SCREEN_NAME/$service.pid
767811
fi
768812
fi
769813
}

stack.sh

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -824,8 +824,17 @@ fi
824824
# Configure screen
825825
# ----------------
826826

827-
if [ -z "$SCREEN_HARDSTATUS" ]; then
828-
SCREEN_HARDSTATUS='%{= .} %-Lw%{= .}%> %n%f %t*%{= .}%+Lw%< %-=%{g}(%{d}%H/%l%{g})'
827+
USE_SCREEN=$(trueorfalse True $USE_SCREEN)
828+
if [[ "$USE_SCREEN" == "True" ]]; then
829+
# Create a new named screen to run processes in
830+
screen -d -m -S $SCREEN_NAME -t shell -s /bin/bash
831+
sleep 1
832+
833+
# Set a reasonable status bar
834+
if [ -z "$SCREEN_HARDSTATUS" ]; then
835+
SCREEN_HARDSTATUS='%{= .} %-Lw%{= .}%> %n%f %t*%{= .}%+Lw%< %-=%{g}(%{d}%H/%l%{g})'
836+
fi
837+
screen -r $SCREEN_NAME -X hardstatus alwayslastline "$SCREEN_HARDSTATUS"
829838
fi
830839

831840
# Clear screen rc file
@@ -834,12 +843,6 @@ if [[ -e $SCREENRC ]]; then
834843
echo -n > $SCREENRC
835844
fi
836845

837-
# Create a new named screen to run processes in
838-
screen -d -m -S $SCREEN_NAME -t shell -s /bin/bash
839-
sleep 1
840-
841-
# Set a reasonable status bar
842-
screen -r $SCREEN_NAME -X hardstatus alwayslastline "$SCREEN_HARDSTATUS"
843846

844847
# Initialize the directory for service status check
845848
init_service_check

stackrc

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ NOVA_ENABLED_APIS=ec2,osapi_compute,metadata
3030
# stuffing text into the screen windows so that a developer can use
3131
# ctrl-c, up-arrow, enter to restart the service. Starting services
3232
# this way is slightly unreliable, and a bit slower, so this can
33-
# be disabled for automated testing by setting this value to false.
34-
SCREEN_DEV=True
33+
# be disabled for automated testing by setting this value to False.
34+
USE_SCREEN=True
3535

3636
# Repositories
3737
# ------------
@@ -198,3 +198,6 @@ VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-5130M}
198198

199199
PRIVATE_NETWORK_NAME=${PRIVATE_NETWORK_NAME:-"private"}
200200
PUBLIC_NETWORK_NAME=${PUBLIC_NETWORK_NAME:-"nova"}
201+
202+
# Compatibility until it's eradicated from CI
203+
USE_SCREEN=${SCREEN_DEV:-$USE_SCREEN}

0 commit comments

Comments
 (0)