1 | #! /bin/sh |
---|
2 | # ---------------------------------------------------------------------- |
---|
3 | # RAPPTURE PROGRAM EXECUTION |
---|
4 | # |
---|
5 | # This script implements the -execute option for Rappture. It |
---|
6 | # provides a way to run a specific Rappture simulation without |
---|
7 | # invoking the Rappture GUI. Instead, it takes a driver file with |
---|
8 | # the required parameters, submits that for execution, and then |
---|
9 | # returns the run.xml file. If the -tool file is specified, then |
---|
10 | # it double-checks the driver against the tool to make sure that |
---|
11 | # the requested tool and version are compatible. |
---|
12 | # |
---|
13 | # This is normally invoked by launcher.tcl, so it expects $driverxml |
---|
14 | # and $toolxml variable to be already set. |
---|
15 | # |
---|
16 | # USAGE: execute.tcl |
---|
17 | # ====================================================================== |
---|
18 | # AUTHORS: Michael McLennan, Purdue University |
---|
19 | # Copyright (c) 2004-2012 HUBzero Foundation, LLC |
---|
20 | # |
---|
21 | # See the file "license.terms" for information on usage and |
---|
22 | # redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
---|
23 | # ====================================================================== |
---|
24 | #\ |
---|
25 | exec tclsh "$0" $* |
---|
26 | # ---------------------------------------------------------------------- |
---|
27 | # tclsh executes everything from here on... |
---|
28 | |
---|
29 | # bring in the Rappture object system |
---|
30 | package require Rappture |
---|
31 | Rappture::objects::init |
---|
32 | Rappture::resources::load |
---|
33 | |
---|
34 | # load the XML info in the driver file |
---|
35 | if {[catch {Rappture::library $driverxml} result]} { |
---|
36 | puts stderr "ERROR while loading driver file \"$driverxml\"" |
---|
37 | puts stderr $result |
---|
38 | exit 1 |
---|
39 | } |
---|
40 | set driverobj $result |
---|
41 | |
---|
42 | # If tool.xml is not specified, try to find it the way Rappture would. |
---|
43 | if {$toolxml eq ""} { |
---|
44 | if {[file isfile tool.xml]} { |
---|
45 | set toolxml [file normalize tool.xml] |
---|
46 | } elseif {[file isfile [file join rappture tool.xml]]} { |
---|
47 | set toolxml [file normalize [file join rappture tool.xml]] |
---|
48 | } |
---|
49 | } |
---|
50 | |
---|
51 | # If there's still no tool.xml, then see if we can find tooldir in driver |
---|
52 | if {$toolxml eq ""} { |
---|
53 | set tooldir [$driverobj get tool.version.application.directory(tool)] |
---|
54 | if {$tooldir eq ""} { |
---|
55 | puts stderr "ERROR: missing -tool option, and driver file doesn't contain sufficient detail to locate the desired tool." |
---|
56 | exit 1 |
---|
57 | } |
---|
58 | |
---|
59 | set toolxml [file join $tooldir tool.xml] |
---|
60 | if {![file exists $toolxml]} { |
---|
61 | puts stderr "ERROR: missing tool.xml file \"$toolxml\"" |
---|
62 | exit 1 |
---|
63 | } |
---|
64 | } |
---|
65 | |
---|
66 | set installdir [file dirname [file normalize $toolxml]] |
---|
67 | set toolobj [Rappture::library $toolxml] |
---|
68 | set TaskObj [Rappture::Task ::#auto $toolobj $installdir] |
---|
69 | set LogFid "" |
---|
70 | |
---|
71 | # Define some things that we need for logging status... |
---|
72 | # ---------------------------------------------------------------------- |
---|
73 | proc log_output {message} { |
---|
74 | global LogFid |
---|
75 | |
---|
76 | if {$LogFid ne ""} { |
---|
77 | # |
---|
78 | # Scan through and pick out any =RAPPTURE-PROGRESS=> messages. |
---|
79 | # |
---|
80 | set percent "" |
---|
81 | while {[regexp -indices \ |
---|
82 | {=RAPPTURE-PROGRESS=> *([-+]?[0-9]+) +([^\n]*)(\n|$)} $message \ |
---|
83 | match percent mesg]} { |
---|
84 | |
---|
85 | foreach {i0 i1} $percent break |
---|
86 | set percent [string range $message $i0 $i1] |
---|
87 | |
---|
88 | foreach {i0 i1} $mesg break |
---|
89 | set mesg [string range $message $i0 $i1] |
---|
90 | |
---|
91 | foreach {i0 i1} $match break |
---|
92 | set message [string replace $message $i0 $i1] |
---|
93 | } |
---|
94 | if {$percent ne ""} { |
---|
95 | # report the last percent progress found |
---|
96 | log_append progress "$percent% - $mesg" |
---|
97 | } |
---|
98 | } |
---|
99 | } |
---|
100 | |
---|
101 | # Actually write to the log file |
---|
102 | proc log_append {level message} { |
---|
103 | global LogFid |
---|
104 | |
---|
105 | if {$LogFid ne ""} { |
---|
106 | set date [clock format [clock seconds] -format {%Y-%m-%dT%H:%M:%S%z}] |
---|
107 | set host [info hostname] |
---|
108 | puts $LogFid "$date $host rappture [pid] \[$level\] $message" |
---|
109 | flush $LogFid |
---|
110 | } |
---|
111 | } |
---|
112 | |
---|
113 | # Actually write to the log file |
---|
114 | proc log_stats {args} { |
---|
115 | set line "" |
---|
116 | foreach {key val} $args { |
---|
117 | append line "$key=$val " |
---|
118 | } |
---|
119 | log_append usage $line |
---|
120 | } |
---|
121 | |
---|
122 | # Parse command line options to see |
---|
123 | # ---------------------------------------------------------------------- |
---|
124 | Rappture::getopts argv params { |
---|
125 | value -status "" |
---|
126 | value -output "" |
---|
127 | value -cleanup no |
---|
128 | } |
---|
129 | |
---|
130 | if {$params(-status) ne ""} { |
---|
131 | set LogFid [open $params(-status) w] |
---|
132 | $TaskObj configure -logger {log_append status} -jobstats log_stats |
---|
133 | } |
---|
134 | |
---|
135 | if {$params(-output) eq ""} { |
---|
136 | # no output? then run quietly and don't try to save results |
---|
137 | $TaskObj configure -jobstats "" -resultdir "" |
---|
138 | } |
---|
139 | |
---|
140 | # Transfer input values from driver to TaskObj, and then run. |
---|
141 | # ---------------------------------------------------------------------- |
---|
142 | |
---|
143 | # copy inputs from the test into the run file |
---|
144 | $TaskObj reset |
---|
145 | foreach path [Rappture::entities -as path $driverobj input] { |
---|
146 | if {[$driverobj element -as type $path.current] ne ""} { |
---|
147 | lappend args $path [$driverobj get $path.current] |
---|
148 | } |
---|
149 | } |
---|
150 | |
---|
151 | if {$params(-status) ne ""} { |
---|
152 | # recording status? then look through output for progress messages |
---|
153 | lappend args -output log_output |
---|
154 | } |
---|
155 | |
---|
156 | # run the desired case... |
---|
157 | foreach {status result} [eval $TaskObj run $args] break |
---|
158 | |
---|
159 | if {$status == 0 && [Rappture::library isvalid $result]} { |
---|
160 | set runxml $result |
---|
161 | $runxml put output.status ok |
---|
162 | } else { |
---|
163 | # build a run file for the result output |
---|
164 | set info "<?xml version=\"1.0\"?>\n[$driverobj xml]" |
---|
165 | set runxml [Rappture::LibraryObj ::#auto $info] |
---|
166 | $runxml put output.log $result |
---|
167 | $runxml put output.status failed |
---|
168 | } |
---|
169 | |
---|
170 | # Handle output |
---|
171 | # ---------------------------------------------------------------------- |
---|
172 | switch -- $params(-output) { |
---|
173 | "" { |
---|
174 | # no output file -- write to stdout |
---|
175 | puts "<?xml version=\"1.0\"?>\n[$runxml xml]" |
---|
176 | } |
---|
177 | "@default" { |
---|
178 | # do the usual Rappture thing -- move to results dir |
---|
179 | # but ignore any errors if it fails |
---|
180 | catch {$TaskObj save $runxml} |
---|
181 | } |
---|
182 | default { |
---|
183 | # save to the specified file |
---|
184 | $TaskObj save $runxml $params(-output) |
---|
185 | } |
---|
186 | } |
---|
187 | |
---|
188 | if {$params(-cleanup)} { |
---|
189 | file delete -force -- $driverxml |
---|
190 | } |
---|
191 | |
---|
192 | log_append status "exit $status" |
---|
193 | exit $status |
---|