Skip to content

Commit d615309

Browse files
jonn-smithlbergelson
authored andcommitted
Added in -w flag for submit command. (#50)
* Added in -w flag for submit command. -w flag will wait for status to change from `Submitted` to anything else before the script exits. The flag causes some interactive messages on the terminal.
1 parent bd2ac67 commit d615309

File tree

2 files changed

+215
-12
lines changed

2 files changed

+215
-12
lines changed

README.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ requires `column`, `curl`, `mail`, and [jq](https://stedolan.github.io/jq/)
3333

3434

3535
#### Start/Stop workflows
36-
* `submit` *`workflow.wdl`* *`inputs.json`* `[options json]` `[included wdls]`
36+
* `submit` `[-w]` *`<wdl>`* *`<inputs_json>`* `[options_json]` `[included_wdl_zip_file]`
3737
* Submit a new workflow
38+
* *`-w`* Wait for workflow to transition from 'Submitted' to some other status
39+
before ${SCRIPTNAME} exits
40+
* *`included_wdl_zip_file`* Zip file containing any WDL files included in the input WDL
3841
* `abort` *`[workflow-id] [[workflow-id]...]`*
3942
* Abort a running workflow
4043
#### Query workflow status:

cromshell

+211-11
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ SCRIPTDIR="$( cd "$( dirname "${UNALIASED_SCRIPT_NAME}" )" && pwd )"
88
SCRIPTNAME=$( echo $0 | sed 's#.*/##g' )
99
MINARGS=1
1010
MAXARGS=99
11-
PREREQUISITES="curl jq mail column"
11+
PREREQUISITES="curl jq mail column tput rev"
1212

1313
# Determine if this shell is interactive:
1414
ISINTERACTIVESHELL=true
@@ -52,6 +52,7 @@ FOLDER_URL=$( echo ${CROMWELL_URL} | sed -e 's#ht.*://##g' )
5252
CROMWELL_METADATA_PARAMETERS="excludeKey=submittedFiles&expandSubWorkflows=true"
5353

5454
CURL_CONNECT_TIMEOUT=5
55+
CURL_MAX_TIMEOUT=10
5556

5657
PING_CMD='ping -c1 -W1 -w10'
5758
if [[ $( uname ) == "Darwin" ]] ; then
@@ -100,7 +101,7 @@ function turtleDead()
100101
function simpleUsage()
101102
{
102103
if [[ $# -ne 0 ]] ; then
103-
usage | grep ${1} | sed -e 's#\(.*]\).*#\1#g' -e "s#^[ \\t]*#Usage: ${SCRIPTNAME} #g"
104+
usage | grep " ${1} " | sed -e 's#\(.*]\).*#\1#g' -e "s#^[ \\t]*#Usage: ${SCRIPTNAME} #g"
104105
else
105106
echo -e "Usage: ${SCRIPTNAME} SUB-COMMAND [options]"
106107
echo -e "Run and inspect workflows on a Cromwell server."
@@ -125,7 +126,9 @@ function usage()
125126
echo -e "Supported Subcommands:"
126127
echo -e ""
127128
echo -e " Start/Stop workflows:"
128-
echo -e " submit <wdl> <inputs_json> [options_json] [included_wdl_zip_file] Submit a new workflow"
129+
echo -e " submit [-w] <wdl> <inputs_json> [options_json] [included_wdl_zip_file] Submit a new workflow"
130+
echo -e " -w Wait for workflow to transition from 'Submitted' to some other status"
131+
echo -e " before ${SCRIPTNAME} exits"
129132
echo -e " included_wdl_zip_file Zip file containing any WDL files included in the input WDL"
130133
echo -e ""
131134
echo -e " abort [workflow-id] [[workflow-id]...] Abort a running workflow."
@@ -402,12 +405,178 @@ function populateWorkflowIdAndServerUrl()
402405
fi
403406
}
404407

408+
function _turtleSpinner()
409+
{
410+
# Require a flag file to be given to this function.
411+
# This keeps it safe.
412+
if [[ $# -ne 1 ]] ; then
413+
return 1
414+
fi
415+
416+
local flagFile=$1
417+
418+
# Let's be fancy and make turtles that are walking while we wait:
419+
local tmpTurtFile=$( makeTemp )
420+
local turtFile=$( makeTemp )
421+
local turtRFile=$( makeTemp )
422+
turtle &> ${tmpTurtFile}
423+
sed 's#^ ##g' ${tmpTurtFile} > ${turtFile}
424+
rev ${turtFile} | sed -e 's$/$#$g' -e 's#\\#/#g' -e 's$#$\\$g' -e 's#(#)#g' -e 's#)#(#g' > ${turtRFile}
425+
426+
# Set up some loop variables:
427+
local i=3
428+
local incrementString="+1"
429+
local curTurtFile=${turtFile}
430+
431+
# Let's loop while the ${flagFile} exists.
432+
# Note that this will be spun off into its own thread:
433+
while [ -f ${flagFile} ] ; do
434+
# Create padding for turtle:
435+
padding=$( printf "%${i}s" "" )
436+
437+
# Display our turtle, moved a little to the right:
438+
cat ${curTurtFile} | sed -e "s#^#${padding}#g"
439+
sleep 0.1
440+
441+
# Move the cursor back up to the top line of the turtle
442+
# so we create the illusion of movement:
443+
tput cuu 6
444+
445+
# Now we update our loop variables in a clever way
446+
# so that the turtle will go back and forth.
447+
let i=i${incrementString}
448+
if [ $i -eq 15 ] ; then
449+
incrementString="-1"
450+
curTurtFile=${turtRFile}
451+
elif [ $i -eq 0 ] ; then
452+
incrementString="+1"
453+
curTurtFile=${turtFile}
454+
fi
455+
456+
done & # The & here spins this off as a background thread/process
457+
}
458+
459+
function waitOnSubmittedStatus()
460+
{
461+
local id=$1
462+
local cromwellServerUrl=$2
463+
464+
echo "Waiting on status to progress from 'Submitted' ..."
465+
echo
466+
467+
# Use tput to save the cursor position:
468+
tput sc
469+
470+
# The turtle starts 9 rows above where the cursor is at this point,
471+
# so if we need to move it, we have to move the cursor there before
472+
# we output anything:
473+
tput cuu 9
474+
475+
# Reserve the name for a file whose non-existence will cause
476+
# the following loop to exit.
477+
# This is good because all temp files made with `makeTemp`
478+
# are automatically removed at exit, so this sub-process
479+
# will always die gracefully.
480+
local flagFile=$(makeTemp)
481+
echo 'TEST' > ${flagFile}
482+
483+
# Kick off a turtle spinner...
484+
_turtleSpinner ${flagFile}
485+
486+
# Now we check the status periodically and if we get a new one
487+
# Other than `Submitted` we can tell the other process to finish.
488+
local gotNewStatus=false
489+
local isDone=false
490+
local nChecks=0
491+
local statusFile=$( makeTemp )
492+
local r
493+
while ! $isDone ; do
494+
# Wait for a little bit so we don't kill the server:
495+
sleep 2
496+
497+
# Check the status of our last submission:
498+
status ${id} ${cromwellServerUrl} &> ${statusFile}
499+
r=$?
500+
grep -q '^[ \t]*"status": "Submitted",' ${statusFile}
501+
502+
# We could no longer field the status as `Submitted`, so we're done.
503+
if [ $? -eq 1 ] && [ $r -ne 2 ] ; then
504+
gotNewStatus=true
505+
fi
506+
507+
# Check if our status changed yet:
508+
if $gotNewStatus ; then
509+
isDone=true
510+
511+
# Delete the flag file to end the display process:
512+
rm -f ${flagFile}
513+
514+
# Wait for the _turtleSpinner to exit:
515+
wait
516+
517+
# Clear out the lines from our fancy animation:
518+
tput el;echo;tput el;echo;tput el;echo;tput el;echo;tput el;echo;tput el;echo;tput el;echo;tput el;echo
519+
tput cuu 8
520+
521+
# Display the status file:
522+
cat ${statusFile} | sed 's#^Using ##g'
523+
524+
# If we have waited too long, then we quit:
525+
elif [[ $nChecks -ge 10 ]] ; then
526+
isDone=true
527+
528+
# Delete the flag file to end the display process:
529+
rm -f ${flagFile}
530+
531+
# Wait for the _turtleSpinner to exit:
532+
wait
533+
534+
echo "{\"id\":\"${id}\",\"status\":\"Submitted\"}"
535+
error "WARNING: Could not validate submission status with server. Try again later."
536+
break
537+
fi
538+
539+
let nChecks=$nChecks+1
540+
done
541+
542+
# Restore cursor position:
543+
tput rc
544+
545+
# Add a line for padding:
546+
echo
547+
548+
# Send a proper return code:
549+
if $gotNewStatus ; then
550+
return 0
551+
else
552+
return 1
553+
fi
554+
}
555+
405556
# Submit a workflow and arguments to the Cromwell Server
406557
function submit()
407558
{
559+
local doWait=false
560+
561+
# Handle Arguments:
562+
local OPTIND
563+
while getopts "w" opt ; do
564+
case ${opt} in
565+
w)
566+
doWait=true
567+
;;
568+
*)
569+
invalidSubCommand submit flag ${OPTARG}
570+
;;
571+
esac
572+
done
573+
shift $((OPTIND-1))
574+
575+
# ----------------------------------------
576+
408577
assertCanCommunicateWithServer $CROMWELL_URL
409578

410-
local response=$(curl --connect-timeout $CURL_CONNECT_TIMEOUT -s -F workflowSource=@${1} ${2:+ -F workflowInputs=@${2}} ${3:+ -F workflowOptions=@${3}} ${4:+ -F workflowDependencies=@${4}} ${CROMWELL_URL}/api/workflows/v1)
579+
local response=$(curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT -s -F workflowSource=@${1} ${2:+ -F workflowInputs=@${2}} ${3:+ -F workflowOptions=@${3}} ${4:+ -F workflowDependencies=@${4}} ${CROMWELL_URL}/api/workflows/v1)
411580
local r=$?
412581

413582
# Check to make sure that we actually submitted the job correctly
@@ -449,6 +618,11 @@ function submit()
449618

450619
echo -e "$(date +%Y%m%d_%H%M%S)\t${CROMWELL_URL}\t${id}\t$(basename ${1})\tSubmitted" >> ${CROMWELL_SUBMISSIONS_FILE}
451620

621+
# Now that we've submitted our task, we should see if we have to wait:
622+
if $doWait ; then
623+
waitOnSubmittedStatus ${id} ${CROMWELL_URL}
624+
fi
625+
452626
return 0
453627
}
454628

@@ -459,7 +633,7 @@ function status()
459633

460634
assertCanCommunicateWithServer $2
461635
local f=$( makeTemp )
462-
curl --connect-timeout $CURL_CONNECT_TIMEOUT -s ${2}/api/workflows/v1/${1}/status > $f
636+
curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT -s ${2}/api/workflows/v1/${1}/status > $f
463637
[[ $? -ne 0 ]] && error "Could not connect to Cromwell server." && return 2
464638

465639
grep -qE '"Failed"|"Aborted"|"fail"' $f
@@ -487,7 +661,7 @@ function logs()
487661
{
488662
assertCanCommunicateWithServer $2
489663
turtle
490-
curl --connect-timeout $CURL_CONNECT_TIMEOUT -s ${2}/api/workflows/v1/${1}/logs | jq .
664+
curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT -s ${2}/api/workflows/v1/${1}/logs | jq .
491665
checkPipeStatus "Could not connect to Cromwell server." "Could not parse JSON output from cromwell server."
492666
return $?
493667
}
@@ -497,7 +671,7 @@ function metadata()
497671
{
498672
assertCanCommunicateWithServer $2
499673
turtle
500-
curl --connect-timeout $CURL_CONNECT_TIMEOUT --compressed -s ${2}/api/workflows/v1/${1}/metadata?${CROMWELL_METADATA_PARAMETERS} | jq .
674+
curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT --compressed -s ${2}/api/workflows/v1/${1}/metadata?${CROMWELL_METADATA_PARAMETERS} | jq .
501675
checkPipeStatus "Could not connect to Cromwell server." "Could not parse JSON output from cromwell server."
502676
return $?
503677
}
@@ -507,7 +681,7 @@ function slim-metadata()
507681
{
508682
assertCanCommunicateWithServer $2
509683
turtle
510-
curl --connect-timeout $CURL_CONNECT_TIMEOUT --compressed -s "${2}/api/workflows/v1/$1/metadata?includeKey=executionStatus&includeKey=backendStatus&expandSubWorkflows=true" | jq .
684+
curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT --compressed -s "${2}/api/workflows/v1/$1/metadata?includeKey=executionStatus&includeKey=backendStatus&expandSubWorkflows=true" | jq .
511685
checkPipeStatus "Could not connect to Cromwell server." "Could not parse JSON output from cromwell server."
512686
return $?
513687
}
@@ -518,7 +692,7 @@ function execution-status-count()
518692
assertCanCommunicateWithServer $2
519693
turtle
520694
f=$( makeTemp )
521-
curl --connect-timeout $CURL_CONNECT_TIMEOUT --compressed -s ${2}/api/workflows/v1/$1/metadata?${CROMWELL_METADATA_PARAMETERS} > $f
695+
curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT --compressed -s ${2}/api/workflows/v1/$1/metadata?${CROMWELL_METADATA_PARAMETERS} > $f
522696
[[ $? -ne 0 ]] && error "Could not connect to Cromwell server." && return 9
523697

524698
# Make sure the query succeeded:
@@ -548,7 +722,7 @@ function abort()
548722
{
549723
assertCanCommunicateWithServer $2
550724
turtle
551-
response=$(curl --connect-timeout $CURL_CONNECT_TIMEOUT -X POST --header "Content-Type: application/json" --header "Accept: application/json" "${2}/api/workflows/v1/${1}/abort")
725+
response=$(curl --connect-timeout $CURL_CONNECT_TIMEOUT --max-time $CURL_MAX_TIMEOUT -X POST --header "Content-Type: application/json" --header "Accept: application/json" "${2}/api/workflows/v1/${1}/abort")
552726
local r=$?
553727
echo $response
554728
return $r
@@ -582,9 +756,28 @@ function list()
582756

583757
# If we need to update the data, do so here:
584758
if $doUpdate ; then
585-
error "Updating cached status list"
759+
error "Updating cached status list..."
586760
local tmpFile srv id runSt
587761

762+
# Use tput to save the cursor position:
763+
tput sc
764+
765+
# The turtle starts 7 rows above where the cursor is at this point,
766+
# so if we need to move it, we have to move the cursor there before
767+
# we output anything:
768+
tput cuu 7
769+
770+
# Reserve the name for a file whose non-existence will cause
771+
# the following loop to exit.
772+
# This is good because all temp files made with `makeTemp`
773+
# are automatically removed at exit, so this sub-process
774+
# will always die gracefully.
775+
local flagFile=$(makeTemp)
776+
echo 'TEST' > ${flagFile}
777+
778+
# Kick off a turtle spinner...
779+
_turtleSpinner ${flagFile}
780+
588781
# Make a copy of our file because we'll be modifying it:
589782
tmpFile=$( makeTemp )
590783
cp ${CROMWELL_SUBMISSIONS_FILE} ${tmpFile}
@@ -602,6 +795,13 @@ function list()
602795
fi
603796
fi
604797
done < ${tmpFile}
798+
799+
# Remove the flag file to kill the spinner and wait for it to finish:
800+
rm ${flagFile}
801+
wait
802+
803+
# Restore cursor position:
804+
tput rc
605805
fi
606806

607807
# If we have to colorize the output, we do so:

0 commit comments

Comments
 (0)