1616"""GraphQL resolvers for use in data accessing and mutation of workflows."""
1717
1818import asyncio
19- from contextlib import suppress
2019import errno
21- from getpass import getuser
2220import os
23- from copy import deepcopy
2421import signal
25- from subprocess import Popen , PIPE , DEVNULL
22+ from contextlib import suppress
23+ from copy import deepcopy
24+ from getpass import getuser
25+ from subprocess import (
26+ DEVNULL ,
27+ PIPE ,
28+ Popen ,
29+ )
2630from typing import (
31+ TYPE_CHECKING ,
2732 Any ,
2833 AsyncGenerator ,
2934 Callable ,
3035 Dict ,
3136 Iterable ,
3237 List ,
3338 Optional ,
34- TYPE_CHECKING ,
3539 Tuple ,
3640 Union ,
3741)
3842
39- from graphql .language .base import print_ast
4043import psutil
41-
4244from cylc .flow .data_store_mgr import WORKFLOW
43- from cylc .flow .exceptions import (
44- ServiceFileError ,
45- WorkflowFilesError ,
46- )
45+ from cylc .flow .exceptions import ServiceFileError , WorkflowFilesError
4746from cylc .flow .id import Tokens
4847from cylc .flow .network .resolvers import BaseResolvers
49- from cylc .flow .scripts .clean import CleanOptions
50- from cylc . flow . scripts . clean import run
48+ from cylc .flow .scripts .clean import CleanOptions , run
49+ from graphql . language . base import print_ast
5150
5251if TYPE_CHECKING :
5352 from concurrent .futures import Executor
5453 from logging import Logger
5554 from optparse import Values
56- from graphql import ResolveInfo
55+
5756 from cylc .flow .data_store_mgr import DataStoreMgr
5857 from cylc .flow .option_parsers import Options
58+ from graphql import ResolveInfo
59+
5960 from cylc .uiserver .workflows_mgr import WorkflowsManager
6061
6162
@@ -429,7 +430,7 @@ async def cat_log(cls, id_: Tokens, log, info, file=None):
429430 yield {'connected' : False }
430431
431432 @classmethod
432- async def cat_log_files (cls , id_ : Tokens ) :
433+ async def cat_log_files (cls , id_ : Tokens , log : 'Logger' ) -> List [ str ] :
433434 """Calls cat log to get list of available log files.
434435
435436 Note kept separate from the cat_log method above as this is a one off
@@ -438,26 +439,27 @@ async def cat_log_files(cls, id_: Tokens):
438439 file checking.
439440 """
440441 cmd : List [str ] = ['cylc' , 'cat-log' , '-m' , 'l' , '-o' , id_ .id ]
442+ log .debug (f"$ { ' ' .join (cmd )} " )
441443 proc_job = await asyncio .subprocess .create_subprocess_exec (
442444 * cmd ,
443445 stdout = asyncio .subprocess .PIPE ,
444446 stderr = asyncio .subprocess .PIPE ,
445447 )
446- # wait for proc to finish
447- await proc_job .wait ()
448-
449- # MOTD returned in stderr, no use in returning
450- out_job , _ = await proc_job .communicate ()
451- if out_job :
448+ ret_code = await proc_job .wait ()
449+ out , err = await proc_job .communicate ()
450+ if ret_code :
451+ log .error (
452+ f"Command failed ({ ret_code } ): { ' ' .join (cmd )} \n { err .decode ()} "
453+ )
454+ if out :
452455 return sorted (
453456 # return the log files in reverse sort order
454457 # this means that the most recent log file rotations
455458 # will be at the top of the list
456- out_job .decode ().splitlines (),
459+ out .decode ().splitlines (),
457460 reverse = True ,
458461 )
459- else :
460- return []
462+ return []
461463
462464
463465class Resolvers (BaseResolvers ):
@@ -569,7 +571,7 @@ async def query_service(
569571 self ,
570572 id_ : Tokens ,
571573 ):
572- return await Services .cat_log_files (id_ )
574+ return await Services .cat_log_files (id_ , self . log )
573575
574576
575577def kill_process_tree (
0 commit comments