]> git.uio.no Git - u/mrichter/AliRoot.git/blame - PWGPP/benchmark/alirelval
better log validation
[u/mrichter/AliRoot.git] / PWGPP / benchmark / alirelval
CommitLineData
50881e44 1#!/bin/bash
2
3#
e9562f6f 4# alirelval -- by Dario Berzano <dario.berzano@cern.ch>
50881e44 5#
6# Controls the release validation submission by managing the validation virtual
7# cluster.
8#
9
10#
11# Variables
12#
13
14# error codes
15errCfg=1
16errMissingCmd=2
17errEc2Auth=3
18errInvalidOpt=4
19errSessionDir=5
20errCreateKey=6
21errRunVm=7
22errLaunchValidation=8
23errSshNotReady=9
24errStatusUnavailable=10
25errPickSession=11
26errCopyKey=12
27errAttachScreen=13
6e33d1ed 28errRecycleSession=14
50881e44 29
30# error codes not treated as errors (100 to 140)
31errStatusRunning=100
32errStatusNotRunning=101
33errStatusDoneOk=102
34errStatusDoneFail=103
35
36# thresholds
e9562f6f 37maxVmLaunchAttempts=100
50881e44 38maxSshConnectAttempts=400
e9562f6f 39maxVmAddressWait=200
50881e44 40
41# working directory prefix
1211d5b0 42sessionPrefix="$HOME/.alice-release-validation"
50881e44 43
718e1365 44# screen name: <screenPrefix>-<sessionTag>
45screenPrefix='AliRelVal'
50881e44 46
47# program name
48Prog=$(basename "$0")
49
50#
51# Functions
52#
53
54# Pretty print
55function pr() {
56 local nl
57 if [ "$1" == '-n' ] ; then
58 nl="-n"
59 shift
60 fi
61 echo $nl -e "\033[1m$@\033[m" >&2
62}
63
64# Nice date in UTC
65function ndate() {
66 date -u +%Y%m%d-%H%M%S-utc
67}
68
69# Temporary file
70function tmpf() {
71 mktemp /tmp/alirelval-XXXX
72}
73
74# Swallow output. Show only if something goes wrong
75function swallow() {
76 local tout ret
77 tout=$(tmpf)
78 "$@" > "$tout" 2>&1
79 ret=$?
80 if [ $ret != 0 ] ; then
81 pr "Command failed (exit status: $ret): $@"
82 cat "$tout" >&2
83 fi
84 rm -f "$tout"
85 return $ret
86}
87
88# Launch a VM. Create the keypair if the given keyfile does not exist. Syntax:
89#
90# RunVM <image_id> <profile> <user_data> <key_name> <key_file>
91#
92# Returns 0 on success, nonzero on failure. IP address is returned on stdout.
93function RunVM() {
94 local imageId profile userData keyName
95 imageId="$1"
96 profile="$2"
97 userData="$3"
98 keyName="$4"
99 keyFile="$5"
8ca5b365 100 local raw iip iid ret attempt createdKeypair error
50881e44 101
102 # keypair part: if file does not exist, create keypair
103 if [ ! -e "$keyFile" ] ; then
104 pr "Creating a new keypair: $keyName (private key: $keyFile)"
105 swallow euca-create-keypair -f "$keyFile" "$keyName"
106 if [ $? != 0 ] ; then
107 pr 'Problems creating the keypair'
108 return $errCreateKey
109 fi
110 createdKeypair=1
111 fi
112
113 attempt=0
114 pr 'Attempting to run virtual machine'
115
116 # resubmit loop
117 while true ; do
118
119 if [ $((++attempt)) -gt $maxVmLaunchAttempts ] ; then
120 pr " * Reached maximum number of attempts, giving up"
121 if [ "$createdKeypair" == 1 ] ; then
122 ( euca-delete-keypair "$keyName" ; rm -f "$keyFile" ) > /dev/null 2>&1
123 fi
124 return $errRunVm
e9562f6f 125 elif [ $attempt != 1 ] ; then
126 pr " * Pausing between retries"
127 sleep 5
50881e44 128 fi
129
130 pr -n " * Launching VM (attempt #$attempt/$maxVmLaunchAttempts)..."
8ca5b365 131 error=0
50881e44 132
133 raw=$( euca-run-instances "$imageId" -t "$profile" -d "$userData" -k "$keyName" 2>&1 )
134 ret=$?
135 iid=$( echo "$raw" | egrep '^INSTANCE' | head -n1 | awk '{ print $2 }' )
136 if [ $ret != 0 ] || [ "$iid" == '' ] ; then
137 # 'hard' error, but can be temporary
138 pr 'error: message follows'
139 echo "$raw" >&2
140 sleep 1
141 continue
142 else
143 pr 'ok'
144 fi
145
146 pr " * VM has instance ID $iid"
147 pr -n " * Waiting for IP address..."
148
149 # wait for address loop
150 iip=''
151 for ((i=0; i<$maxVmAddressWait; i++)) ; do
152 sleep 1
153 raw=$( euca-describe-instances 2>&1 | grep -E '^INSTANCE' | grep "$iid" | head -n1 )
154
155 # error state?
156 echo "$raw" | grep -i error -q
157 if [ $? == 0 ] ; then
8ca5b365 158 pr ; pr " * VM went to error state"
159 error=1
50881e44 160 break
161 fi
162
163 # no error: try to parse address (NOTE: only IPv4 for the moment)
164 iip=$( echo "$raw" | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}' )
165 if [ "$iip" != '' ] ; then
166 pr
167 break
168 fi
169
170 # no address
171 pr -n '.'
172
173 done
174
175 # do we have address?
176 if [ "$iip" != '' ] ; then
177 pr " * VM has address $iip"
178 break
179 fi
180
181 # we don't: terminate (timeout)
8ca5b365 182 [ "$error" != 1 ] && pr 'timeout'
183 pr " * Terminating instance $iid"
50881e44 184 euca-terminate-instances "$iid" > /dev/null 2>&1
185
186 done
187
188 # success
189 [ "$createdKeypair" == 1 ] && euca-delete-keypair "$keyName" > /dev/null 2>&1
190 echo "$iid $iip" # must be parsed
191 return 0
192
193}
194
195# Prepare the validation session directory. Syntax:
196#
5689da0c 197# PrepareSession <aliroot_tag> <new_session_name>
50881e44 198#
199# Returns 0 on success, nonzero on failure. Session tag returned on stdout.
200function PrepareSession() {
201 local aliRootTag sessionTag sessionDir
202 aliRootTag="$1"
5689da0c 203
204 # session tag can be "auto" or any user-specified value
205 if [ "$2" != 'auto' ] ; then
206 sessionTag="$2"
207 else
208 sessionTag="${aliRootTag}_$(ndate)"
209 fi
210 shift 2
50881e44 211 sessionDir="$sessionPrefix/$sessionTag"
212
213 # session directory already exists? abort
214 if [ -d "$sessionDir" ] ; then
215 pr "Session directory already exists, aborting"
216 return $errSessionDir
217 fi
218
219 # create working directory
220 mkdir -p "$sessionDir"
221 if [ $? != 0 ] ; then
222 pr "Fatal: cannot create session directory $sessionDir"
223 return $errSessionDir
224 fi
225
226 # aliroot version written to a file
227 echo "$aliRootTag" > "$sessionDir/aliroot-version.txt"
228
001644af 229 # benchmark script, benchmark config, cloud config and file list
626ad825 230 cp -L benchmark.sh cloud.config benchmark.config files.list "$sessionDir/"
50881e44 231 if [ $? != 0 ] ; then
001644af 232 pr "Cannot copy configuration files to $sessionDir"
233 rm -rf "$sessionDir"
50881e44 234 return $errSessionDir
235 fi
236
237 # append local files to the configuration
238 for f in benchmark.config.d/*.config ; do
239 [ ! -e "$f" ] && continue
240 ( echo ''
241 echo "### from $f ###"
242 cat $f
243 echo ''
244 ) >> "$sessionDir/benchmark.config"
245 done
246
4a94e8bb 247 # command-line options override the configuration
248 if [ $# != 0 ] ; then
249 pr "Note: the following command-line options will override the corresponding ones in the config files:"
250 ( echo ''
251 echo "### from the command line ###"
252 while [ $# -gt 0 ] ; do
253 extraName="${1%%=*}"
254 extraVal="${1#*=}"
255 if [ "$extraName" != "$1" ] ; then
256 pr " * $extraName = $extraVal"
257 echo "$1"
258 fi
259 shift
260 done
261 echo ''
262 ) >> "$sessionDir/benchmark.config"
263 fi
264
50881e44 265 # success: return the session tag and move to the session directory
266 pr "*** Creating new working session: $sessionTag ***"
267 pr "*** Use this name for future session operations ***"
268 echo "$sessionTag"
269 return 0
270}
271
272# Undo the previous action
273function PrepareSession_Undo() {
274 rm -rf "$sessionPrefix/$1"
275}
276
6e33d1ed 277# Recycle the VM from an existing session
278function RecycleSession() {
279 local sessionTag="$1"
280 local fromSessionTag="$2"
281 local fromSessionDir="$sessionPrefix/$fromSessionTag"
282 local f
283
284 for f in 'instance-id.txt' 'instance-address.txt' 'key.pem' ; do
626ad825 285 cp -L "$fromSessionDir/$f" "$f" > /dev/null 2>&1
6e33d1ed 286 if [ $? != 0 ] ; then
287 pr "Cannot copy $f from the source session dir $fromSessionDir"
288 return $errRecycleSession
289 fi
290 done
291
292 return 0
293}
294
50881e44 295# Move into the session tag directory. Usage:
296#
297# MoveToSessionDir <session_tag>
298#
299# Returns 0 on success, nonzero on error.
300function MoveToSessionDir() {
301 originalWorkDir="$PWD"
302 cd "$sessionPrefix/$sessionTag" || return $errSessionDir
303 return 0
304}
305
306# Undo the previous action
307function MoveToSessionDir_Undo() {
308 cd "$originalWorkDir"
309}
310
311# Load the benchmark configuration
312function LoadConfig() {
001644af 313 source cloud.config > /dev/null 2>&1
50881e44 314 if [ $? != 0 ] ; then
315 pr "Cannot load benchmark configuration"
316 return $errCfg
317 fi
318 return 0
319}
320
321# Instantiate the validation VM
322function InstantiateValidationVM() {
323 local sessionTag instanceId instanceIp ret raw
324 sessionTag="$1"
325
326 # check if we already have a vm
327 instanceId="$(cat instance-id.txt 2> /dev/null)"
328 if [ "$instanceId" != '' ] ; then
329 pr "Virtual machine $instanceId is already running"
330 return 0 # consider it a success
331 else
332 rm -f instance-id.txt instance-address.txt
333 fi
334
335 # do we need to create a keypair?
336 if [ "$cloudKeyName" == '' ] ; then
337 pr "Note: temporary SSH keys will be created for this VM"
338 cloudKeyName="$sessionTag"
339 cloudKeyFile="$PWD/key.pem"
340 rm -f "$cloudKeyFile"
341 elif [ -e "$cloudKeyFile" ] ; then
342 # copy key to session dir
343 pr -n "Copying private key $cloudKeyFile to session directory..."
e9562f6f 344 rm -f 'key.pem'
626ad825 345 cp -L "$cloudKeyFile" 'key.pem' 2> /dev/null
50881e44 346 if [ $? != 0 ] ; then
347 pr 'error'
348 return $errCopyKey
349 else
350 pr 'ok'
351 fi
352 cloudKeyFile="$PWD/key.pem"
353 else
354 pr "Cannot find private key to access virtual machines: $cloudKeyFile"
355 return $errCopyKey
356 fi
357
358 # launch virtual machine and get its address
359 raw=$( RunVM "$cloudImageId" "$cloudProfile" "$cloudUserData" "$cloudKeyName" "$cloudKeyFile" )
360 ret=$?
361
362 if [ $ret == 0 ] ; then
363 instanceId=$( echo $raw | cut -d' ' -f1 )
364 instanceIp=$( echo $raw | cut -d' ' -f2 )
365
366 # write both parameters to files
367 echo $instanceId > 'instance-id.txt'
368 echo $instanceIp > 'instance-address.txt'
369 fi
370
371 return $ret
372}
373
374# Undo the previous action
375function InstantiateValidationVM_Undo() {
376 local sessionTag
377 sessionTag="$1"
378 if [ -e 'instance-id.txt' ] ; then
379 swallow euca-terminate-instances $(cat instance-id.txt)
380 if [ $? == 0 ] ; then
381 rm -f instance-id.txt instance-address.txt key.pem
382 fi
383 fi
384}
385
386# Generic SSH function to the VM
387function VMSSH() {
388 local instanceIp sshParams ret
389 instanceIp=$(cat instance-address.txt 2> /dev/null)
390 sshParams="-oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -oPasswordAuthentication=no -i $PWD/key.pem"
391
392 if [ "$1" == '--rsync-cmd' ] ; then
393 shift
394 echo ssh $sshParams "$@"
395 ret=0
396 else
397 ssh $sshParams "$cloudUserName"@"$instanceIp" "$@"
398 ret=$?
399 fi
400 return $ret
401}
402
403# Opens a shell to the remote VM
404function Shell() {
405 local sessionTag
406 sessionTag="$1"
407 VMSSH
408}
409
410# Checks status of the validation
411function Status() {
718e1365 412 local raw ret screen exitcode sessionTag
413 sessionTag="$1"
414 raw=$( VMSSH -t "screen -ls 2> /dev/null | grep -q .${screenPrefix}-${sessionTag} && echo -n 'screen_yes ' || echo -n 'screen_no ' ; cat $sessionTag/validation.done 2> /dev/null || echo 'not_done' ; true" 2> /dev/null )
50881e44 415 raw=$( echo "$raw" | tr -cd '[:alnum:]_ ' ) # garbage removal
416 ret=$?
417
418 if [ "$ret" != 0 ] ; then
419 pr "Cannot get status"
420 return $errStatusUnavailable
421 fi
422
423 screen="${raw%% *}"
424 exitcode="${raw#* }"
425
426 if [ "$screen" == 'screen_yes' ] ; then
427 pr 'Status: validation still running'
428 return $errStatusRunning
429 else
430 if [ "$exitcode" == 'not_done' ] ; then
431 pr 'Status: validation not running'
432 return $errStatusNotRunning
433 elif [ "$exitcode" == 0 ] ; then
434 pr 'Status: validation completed successfully'
435 return $errStatusDoneOk
436 else
437 pr "Status: validation finished with errors (exitcode: $exitcode)"
438 return $errStatusDoneFail
439 fi
440 fi
441
442}
443
444# Wait for host to be ready
445function WaitSsh() {
446 local attempt error
447 attempt=0
448 pr -n 'Waiting for the VM to accept SSH connections...'
449
450 while ! VMSSH -Tq true > /dev/null 2>&1 ; do
451 if [ $((++attempt)) -gt $maxSshConnectAttempts ] ; then
452 pr 'timeout'
453 error=1
454 break
455 fi
456 pr -n '.'
457 sleep 3
458 done
459
460 [ "$error" == 1 ] && return $errSshNotReady
461 pr 'ok'
462 return 0
463}
464
465# Run the validation
466function Validate() {
467 local instanceIp sshParams sessionTag
468 sessionTag="$1"
469 instanceIp=$(cat instance-address.txt 2> /dev/null)
470 sshParams="-oUserKnownHostsFile=/dev/null -oStrictHostKeyChecking=no -oPasswordAuthentication=no -i $PWD/key.pem"
471
472 # create helper script to launch benchmark
473 cat > run-benchmark.sh <<_EoF_
474#!/bin/bash
1b4d3886 475export LANG=C
50881e44 476cd \$(dirname "\$0")
477v=validation.done
478rm -f \$v
1b4d3886 479env ALIROOT_VERSION=$(cat aliroot-version.txt) ./benchmark.sh run $sessionTag files.list benchmark.config 2>&1 | tee run-benchmark.log
50881e44 480#sleep 1000
481ret=\$?
482echo \$ret > \$v
483echo ; echo ; echo
484echo "*** Validation finished with exitcode \$ret ***"
485echo ; echo ; echo
486read -p 'Press ENTER to dismiss: automatic dismiss in 60 seconds...' -t 60
487_EoF_
488 chmod +x run-benchmark.sh
489
490 # transfer files
491 pr 'Transferring files to the VM'
8c3e0568 492 rsync -av -e "$(VMSSH --rsync-cmd)" $PWD/ $cloudUserName@$instanceIp:$sessionTag/ || return $errLaunchValidation
50881e44 493
494 # open a screen that does something; note that the command is not executed if
495 # the screen already exists, which is what we want
496 # note: sleep necessary to avoid "dead" screens
718e1365 497 VMSSH -t "screen -wipe > /dev/null 2>&1 ; if screen -ls | grep -q ${screenPrefix}-${sessionTag} ; then ret=42 ; else screen -dmS ${screenPrefix}-${sessionTag} $sessionTag/run-benchmark.sh ; ret=0 ; sleep 3 ; fi ; exit \$ret"
50881e44 498 ret=$?
499
500 # message
501 if [ $ret == 42 ] ; then
502 pr 'Validation already running inside a screen.'
503 else
504 pr 'Validation launched inside a screen.'
505 fi
506
507 pr
508 pr 'Check the progress status with:'
509 pr " $Prog --session $sessionTag --status"
510 pr 'Attach to the screen for debug:'
511 pr " $Prog --session $sessionTag --attach"
512 pr 'Open a shell to the virtual machine:'
513 pr " $Prog --session $sessionTag --shell"
514 pr
515
516 # ignore ssh errors
517 return 0
518}
519
520# Attach current validation screen, if possible
521function Attach() {
522 local sessionTag
523 sessionTag="$1"
524
718e1365 525 VMSSH -t "( screen -wipe ; screen -rx ${screenPrefix}-${sessionTag} ) > /dev/null 2>&1"
50881e44 526
527 if [ $? != 0 ] ; then
528 pr "Cannot attach screen: check if validation is running with:"
529 pr " $Prog --session $sessionTag --status"
530 pr "or connect manually to the VM for debug:"
531 pr " $Prog --session $sessionTag --attach"
532 return $errAttachScreen
533 fi
534
535 return 0
536}
537
538# Pick session interactively
539function PickSession() {
6e33d1ed 540 local sessionTag sess listSessions mess
541 mess="$1"
50881e44 542 listSessions=()
543 mkdir -p "$sessionPrefix"
544
545 while read sess ; do
546 [ ! -d "$sessionPrefix/$sess" ] && continue
547 listSessions+=( $sess )
548 done < <( cd $sessionPrefix ; ls -1t )
549
550 if [ ${#listSessions[@]} == 0 ] ; then
551 pr "No session available in session directory $sessionPrefix"
552 return $errPickSession
553 fi
554
6e33d1ed 555 # print user message if provided
556 [ "$mess" != '' ] && pr "$mess"
557
50881e44 558 pr 'Available sessions (most recent first):'
559 for ((i=0; i<${#listSessions[@]}; i++)) ; do
560 pr "$( printf " % 2d. ${listSessions[$i]}" $((i+1)) )"
561 done
562 pr -n 'Pick one: '
563 read i
564
565 let i--
566 if [ "$i" -lt 0 ] || [ "${listSessions[$i]}" == '' ] ; then
567 pr 'Invalid session'
568 return $errPickSession
569 fi
570
571 sess="${listSessions[$i]}"
572 pr "You chose session $sess"
573 echo $sess
574 return 0
575}
576
577# Run an action
578function RunAction() {
579 local ret
580 type "$1" > /dev/null 2>&1
581 if [ $? == 0 ] ; then
582 #pr "--> $1 (wd: $PWD)"
583 eval "$@"
584 ret=$?
585 #pr "<-- $1 (ret: $ret, wd: $PWD)"
586 return $ret
587 fi
588 return 0
589}
590
591# Print help screen
592function Help() {
593 pr "$Prog -- by Dario Berzano <dario.berzano@cern.ch>"
594 pr 'Controls the Release Validation workflow on the cloud for AliRoot.'
595 pr
5689da0c 596 pr "Usage 1: $Prog [--prepare|--launch|--recycle] [--from-session] --aliroot <aliroot_tag> [--session <custom_session_tag>] [-- arbitraryOpt1=value [arbitraryOpt2=value2...]]"
50881e44 597 pr
598 pr 'A new session is created to validate the specified AliRoot tag.'
599 pr
600 pr ' --prepare : prepares the session directory containing the files needed'
6e33d1ed 601 pr ' for the validation'
602 pr ' --recycle : prepares a new session by recycling the head node from an'
603 pr ' existing one. Source session is specified via the'
604 pr ' --from-session switch or it can be interactively selected'
50881e44 605 pr ' --launch : launches the full validation process: prepares session,'
6e33d1ed 606 pr ' runs the virtual machine, launches the validation program'
50881e44 607 pr ' --aliroot : the AliRoot tag to validate, in the form "vAN-20140610"'
5689da0c 608 pr ' --session : custom session name to provide to the validation session:'
609 pr ' if omitted, defaults to <aliroot_tag>_<utc_datetime_now>'
4a94e8bb 610 pr
611 pr 'Arbitrary options (in the form variable=value) can be specified after the'
612 pr 'double dash and will override the corresponding options in any of the'
613 pr 'configuration files.'
50881e44 614 pr ; pr
615 pr "Usage 2: $Prog [--runvm|--validate|--shell|--status] --session <session_tag>"
616 pr
617 pr 'Runs the validation step by step after a session is created with'
618 pr '--prepare, and runs other actions on a certain session.'
619 pr
620 pr ' --session : session identifier, e.g. vAN-20140610_20140612-123047-utc:'
621 pr ' if no session is specified an interactive prompt is'
622 pr ' presented'
623 pr ' --runvm : instantiates the head node of the validation cluster on'
624 pr ' the cloud'
625 pr ' --validate : runs the validation script on the head node for the'
626 pr ' current session. Head node must be already up, or it'
627 pr ' should be created with --runvm. If validation is running'
628 pr ' already, connects to the existing validation shell'
629 pr ' --attach : attach a currently running validation screen; remember to'
630 pr ' detach with Ctrl+A+D (and *not* Ctrl-C)'
631 pr ' --shell : does SSH on the head node'
632 pr ' --status : returns the status of the validation'
633 pr ; pr
634 pr 'Example 1: run the validation of AliRoot tag vAN-20140610:'
635 pr
636 pr " $Prog --aliroot vAN-20140610 --launch"
637 pr
638 pr 'Example 2: do the same thing step-by-step:'
639 pr
640 pr " $Prog --aliroot vAN-20140610 --prepare"
641 pr " $Prog --runvm"
642 pr " $Prog --validate"
643 pr
644}
645
646# The main function
647function Main() {
648
649 # local variables
6e33d1ed 650 local Args aliRootTag EnterShell Actions sessionTag fromSessionTag
50881e44 651 Actions=()
652
653 # parse command line options
654 while [ $# -gt 0 ] ; do
655 case "$1" in
656
657 # options
658 --aliroot|-a)
659 aliRootTag="$2"
660 shift 2
661 ;;
662 --session)
663 sessionTag="$2"
664 shift 2
665 ;;
6e33d1ed 666 --from-session)
667 fromSessionTag="$2"
668 shift 2
669 ;;
50881e44 670
671 # actions
672 --launch)
673 # all actions
674 Actions=( PrepareSession MoveToSessionDir LoadConfig InstantiateValidationVM WaitSsh Validate )
675 shift
676 ;;
677 --prepare)
678 Actions=( PrepareSession MoveToSessionDir )
679 shift
680 ;;
6e33d1ed 681 --recycle)
682 Actions=( PrepareSession MoveToSessionDir RecycleSession )
683 shift
684 ;;
50881e44 685 --runvm)
686 Actions=( MoveToSessionDir LoadConfig InstantiateValidationVM )
687 shift
688 ;;
689 --validate)
690 Actions=( MoveToSessionDir LoadConfig WaitSsh Validate )
691 shift
692 ;;
693 --attach)
694 Actions=( MoveToSessionDir LoadConfig WaitSsh Attach )
695 shift
696 ;;
697
698 # extra actions
699 --shell)
700 Actions=( MoveToSessionDir LoadConfig WaitSsh Shell )
701 shift
702 ;;
703 --status)
704 Actions=( MoveToSessionDir LoadConfig WaitSsh Status )
705 shift
706 ;;
707 --help)
708 Help
709 exit 0
710 ;;
711
4a94e8bb 712 # end of options
713 --)
714 shift
715 break
716 ;;
717
50881e44 718 *)
719 pr "Invalid option: $1. Use --help for assistance."
720 return $errInvalidOpt
721 ;;
722 esac
723 done
50881e44 724
725 # check for the presence of the required tools in the $PATH
726 for T in euca-describe-instances euca-describe-regions euca-run-instances euca-create-keypair euca-delete-keypair rsync ; do
727 which "$T" > /dev/null 2>&1
728 if [ $? != 0 ] ; then
729 pr "Cannot find one of the required commands: $T"
730 return $errMissingCmd
731 fi
732 done
733
734 # test EC2 credentials
735 # euca-describe-regions > /dev/null 2>&1
736 # if [ $? != 0 ] ; then
737 # pr 'Cannot authenticate to EC2.'
738 # pr 'Note: you must have at least the following variables properly set in your environment:'
739 # pr " * EC2_URL (current value: ${EC2_URL-<not set>})"
740 # pr " * EC2_ACCESS_KEY (current value: ${EC2_ACCESS_KEY-<not set>})"
741 # pr " * EC2_SECRET_KEY (current value: ${EC2_SECRET_KEY-<not set>})"
742 # return $errEc2Auth
743 # fi
744
745 # what to do?
746 if [ ${#Actions[@]} == 0 ] ; then
747 pr 'Nothing to do. Use --help for assistance.'
748 return $errInvalidOpt
749 fi
750
751 # run actions
752 for ((i=0; i<${#Actions[@]}; i++)) ; do
753
754 A=${Actions[$i]}
755
756 if [ "$A" == 'PrepareSession' ] ; then
757 # special action returning the session tag
758 if [ "$aliRootTag" == '' ] ; then
759 pr 'Specify an AliRoot version with --aliroot <tag>'
760 return $errInvalidOpt
761 fi
5689da0c 762 [ "$sessionTag" == '' ] && sessionTag='auto'
763 sessionTag=$( RunAction "$A" "$aliRootTag" "$sessionTag" "$@" )
50881e44 764 ret=$?
6e33d1ed 765 elif [ "$A" == 'RecycleSession' ] ; then
766 # special action requiring additional parameters
767 if [ "$fromSessionTag" == '' ] ; then
768 fromSessionTag=$( PickSession 'Select a source session to recycle.' )
769 ret=$?
770 [ $ret != 0 ] && break
771 fi
772 RunAction "$A" "$sessionTag" "$fromSessionTag"
773 ret=$?
50881e44 774 else
775 if [ "$sessionTag" == '' ] ; then
776 sessionTag=$( PickSession )
777 ret=$?
6e33d1ed 778 [ $ret != 0 ] && break
50881e44 779 fi
780 RunAction "$A" "$sessionTag"
781 ret=$?
782 fi
783
784 # 100 to 140 --> not errors
785 ( [ $ret != 0 ] && ( [ $ret -ge 100 ] || [ $ret -le 140 ] ) ) && break
786
787 done
788
789 # undo actions
790 let i--
791 if [ $ret != 0 ] && ( [ $ret -ge 100 ] || [ $ret -le 140 ] ) ; then
792 for ((; i>=0; i--)) ; do
793 RunAction "${Actions[$i]}_Undo" "$sessionTag"
794 done
795 fi
796
797 # return last value
798 return $ret
799
800}
801
802#
803# Entry point
804#
805
806Main "$@" || exit $?