@@ -19,11 +19,13 @@ class MissingAuthorization(Exception):
1919 pass
2020
2121
22- def get_api ():
23- if not connexion .request .headers .get ('Authorization' ):
24- raise MissingAuthorization ()
25- authtoken = connexion .request .headers ['Authorization' ]
26- if authtoken .startswith ("Bearer " ) or authtoken .startswith ("OAuth2 " ):
22+ def get_api (authtoken = None ):
23+ if authtoken is None :
24+ if not connexion .request .headers .get ('Authorization' ):
25+ raise MissingAuthorization ()
26+ authtoken = connexion .request .headers ['Authorization' ]
27+ if not authtoken .startswith ("Bearer " ) or authtoken .startswith ("OAuth2 " ):
28+ raise ValueError ("Authorization token must start with 'Bearer '" )
2729 authtoken = authtoken [7 :]
2830 return arvados .api_from_config (version = "v1" , apiconfig = {
2931 "ARVADOS_API_HOST" : os .environ ["ARVADOS_API_HOST" ],
@@ -55,6 +57,10 @@ def catch_exceptions_wrapper(self, *args, **kwargs):
5557 return {"msg" : str (e ), "status_code" : 500 }, 500
5658 except MissingAuthorization :
5759 return {"msg" : "'Authorization' header is missing or empty, expecting Arvados API token" , "status_code" : 401 }, 401
60+ except ValueError as e :
61+ return {"msg" : str (e ), "status_code" : 400 }, 400
62+ except Exception as e :
63+ return {"msg" : str (e ), "status_code" : 500 }, 500
5864
5965 return catch_exceptions_wrapper
6066
@@ -66,7 +72,7 @@ def GetServiceInfo(self):
6672 "workflow_type_versions" : {
6773 "CWL" : {"workflow_type_version" : ["v1.0" ]}
6874 },
69- "supported_wes_versions" : ["0.2.1 " ],
75+ "supported_wes_versions" : ["0.3.0 " ],
7076 "supported_filesystem_protocols" : ["http" , "https" , "keep" ],
7177 "workflow_engine_versions" : {
7278 "arvados-cwl-runner" : stderr
@@ -108,6 +114,11 @@ def ListRuns(self, page_size=None, page_token=None, state_search=None):
108114 "next_page_token" : workflow_list [- 1 ]["run_id" ] if workflow_list else ""
109115 }
110116
117+ def log_for_run (self , run_id , message , authtoken = None ):
118+ get_api (authtoken ).logs ().create (body = {"log" : {"object_uuid" : run_id ,
119+ "event_type" : "stderr" ,
120+ "properties" : {"text" : message + "\n " }}}).execute ()
121+
111122 def invoke_cwl_runner (self , cr_uuid , workflow_url , workflow_params ,
112123 env , project_uuid ,
113124 tempdir ):
@@ -118,9 +129,18 @@ def invoke_cwl_runner(self, cr_uuid, workflow_url, workflow_params,
118129 })
119130
120131 try :
121- with tempfile .NamedTemporaryFile () as inputtemp :
132+ with tempfile .NamedTemporaryFile (dir = tempdir , suffix = ".json" ) as inputtemp :
122133 json .dump (workflow_params , inputtemp )
123134 inputtemp .flush ()
135+
136+ msg = ""
137+ for dirpath , dirs , files in os .walk (tempdir ):
138+ for f in files :
139+ msg += " " + dirpath + "/" + f + "\n "
140+
141+ self .log_for_run (cr_uuid , "Contents of %s:\n %s" % (tempdir , msg ),
142+ env ['ARVADOS_API_TOKEN' ])
143+
124144 # TODO: run submission process in a container to prevent
125145 # a-c-r submission processes from seeing each other.
126146
@@ -133,6 +153,8 @@ def invoke_cwl_runner(self, cr_uuid, workflow_url, workflow_params,
133153 cmd .append (workflow_url )
134154 cmd .append (inputtemp .name )
135155
156+ self .log_for_run (cr_uuid , "Executing %s" % cmd , env ['ARVADOS_API_TOKEN' ])
157+
136158 proc = subprocess .Popen (cmd , env = env ,
137159 cwd = tempdir ,
138160 stdout = subprocess .PIPE ,
@@ -141,9 +163,8 @@ def invoke_cwl_runner(self, cr_uuid, workflow_url, workflow_params,
141163 if proc .returncode != 0 :
142164 api .container_requests ().update (uuid = cr_uuid , body = {"priority" : 0 }).execute ()
143165
144- api .logs ().create (body = {"log" : {"object_uuid" : cr_uuid ,
145- "event_type" : "stderr" ,
146- "properties" : {"text" : stderrdata }}}).execute ()
166+ self .log_for_run (cr_uuid , stderrdata , env ['ARVADOS_API_TOKEN' ])
167+
147168 if tempdir :
148169 shutil .rmtree (tempdir )
149170
@@ -153,8 +174,6 @@ def invoke_cwl_runner(self, cr_uuid, workflow_url, workflow_params,
153174
154175 @catch_exceptions
155176 def RunWorkflow (self , ** args ):
156- tempdir , body = self .collect_attachments ()
157-
158177 if not connexion .request .headers .get ('Authorization' ):
159178 raise MissingAuthorization ()
160179
@@ -178,17 +197,25 @@ def RunWorkflow(self, **args):
178197 "output_path" : "n/a" ,
179198 "priority" : 500 }}).execute ()
180199
181- workflow_url = body .get ("workflow_url" )
200+ try :
201+ tempdir , body = self .collect_attachments (cr ["uuid" ])
202+
203+ workflow_url = body .get ("workflow_url" )
182204
183- project_uuid = body .get ("workflow_engine_parameters" , {}).get ("project_uuid" )
205+ project_uuid = body .get ("workflow_engine_parameters" , {}).get ("project_uuid" )
184206
185- threading .Thread (target = self .invoke_cwl_runner , args = (cr ["uuid" ],
186- workflow_url ,
187- body ["workflow_params" ],
188- env ,
189- project_uuid ,
190- tempdir )).start ()
207+ threading .Thread (target = self .invoke_cwl_runner , args = (cr ["uuid" ],
208+ workflow_url ,
209+ body ["workflow_params" ],
210+ env ,
211+ project_uuid ,
212+ tempdir )).start ()
191213
214+ except Exception as e :
215+ self .log_for_run (cr ["uuid" ], str (e ))
216+ cr = api .container_requests ().update (uuid = cr ["uuid" ],
217+ body = {"container_request" :
218+ {"priority" : 0 }}).execute ()
192219 return {"run_id" : cr ["uuid" ]}
193220
194221 @catch_exceptions
@@ -203,7 +230,11 @@ def GetRunLog(self, run_id):
203230 containers_map = {c ["uuid" ]: c for c in tasks }
204231 containers_map [container ["uuid" ]] = container
205232 else :
206- container = {"state" : "Queued" , "exit_code" : None , "log" : None }
233+ container = {
234+ "state" : "Queued" if request ["priority" ] > 0 else "Cancelled" ,
235+ "exit_code" : None ,
236+ "log" : None
237+ }
207238 tasks = []
208239 containers_map = {}
209240 task_reqs = []
@@ -256,7 +287,7 @@ def log_object(cr):
256287 "workflow_params" : request ["mounts" ].get ("/var/lib/cwl/cwl.input.json" , {}).get ("content" , {})
257288 },
258289 "state" : statemap [container ["state" ]],
259- "workflow_log " : log_object (request ),
290+ "run_log " : log_object (request ),
260291 "task_logs" : [log_object (t ) for t in task_reqs ],
261292 "outputs" : outputobj
262293 }
0 commit comments