# Path: processes.py
# def killProcesses(pid, pgrp):
#     """ kill a job upon request """
# 
#     pUtil.tolog("killProcesses() called")
# 
#     # if there is a known subprocess pgrp, then it should be enough to kill the group in one go
#     status = False
# 
#     _sleep = True
#     if pgrp != 0:
#         # kill the process gracefully
#         pUtil.tolog("Killing group process %d" % (pgrp))
#         try:
#             os.killpg(pgrp, signal.SIGTERM)
#         except Exception,e:
#             pUtil.tolog("WARNING: Exception thrown when killing the child group process with SIGTERM: %s" % (e))
#             _sleep = False
#         else:
#             pUtil.tolog("(SIGTERM sent)")
# 
#         if _sleep:
#             _t = 30
#             pUtil.tolog("Sleeping %d s to allow processes to exit" % (_t))
#             time.sleep(_t)
# 
#         try:
#             os.killpg(pgrp, signal.SIGKILL)
#         except Exception,e:
#             pUtil.tolog("WARNING: Exception thrown when killing the child group process with SIGKILL: %s" % (e))
#         else:
#             pUtil.tolog("(SIGKILL sent)")
#             status = True
# 
#     if not status:
#         # firstly find all the children process IDs to be killed
#         children = []
#         findProcessesInGroup(children, pid)
# 
#         # reverse the process order so that the athena process is killed first (otherwise the stdout will be truncated)
#         children.reverse()
#         pUtil.tolog("Process IDs to be killed: %s (in reverse order)" % str(children))
# 
#         # find which commands are still running
#         try:
#             cmds = getProcessCommands(os.geteuid(), children)
#         except Exception, e:
#             pUtil.tolog("getProcessCommands() threw an exception: %s" % str(e))
#         else:
#             if len(cmds) <= 1:
#                 pUtil.tolog("Found no corresponding commands to process id(s)")
#             else:
#                 pUtil.tolog("Found commands still running:")
#                 for cmd in cmds:
#                     pUtil.tolog(cmd)
# 
#                 # loop over all child processes
#                 for i in children:
#                     # dump the stack trace before killing it
#                     dumpStackTrace(i)
# 
#                     # kill the process gracefully
#                     try:
#                         os.kill(i, signal.SIGTERM)
#                     except Exception,e:
#                         pUtil.tolog("WARNING: Exception thrown when killing the child process %d under SIGTERM, wait for kill -9 later: %s" % (i, str(e)))
#                         pass
#                     else:
#                         pUtil.tolog("Killed pid: %d (SIGTERM)" % (i))
# 
#                     _t = 10
#                     pUtil.tolog("Sleeping %d s to allow process to exit" % (_t))
#                     time.sleep(_t)
# 
#                     # now do a hardkill just in case some processes haven't gone away
#                     try:
#                         os.kill(i, signal.SIGKILL)
#                     except Exception,e:
#                         pUtil.tolog("WARNING: Exception thrown when killing the child process %d under SIGKILL, ignore this if it is already killed by previous SIGTERM: %s" % (i, str(e)))
#                         pass
#                     else:
#                         pUtil.tolog("Killed pid: %d (SIGKILL)" % (i))
# 
#     pUtil.tolog("Killing any remaining orphan processes")
#     killOrphans()


import sys, os, signal, time, shutil, cgi
import commands, re
import urllib
import json
import traceback
import environment
    import datetime
    import logging
        import inspect
            import JobInfoXML
        import traceback
    import socket
    import collections
from xml.dom import minidom
from xml.dom.minidom import Document
from xml.dom.minidom import parse, parseString
from xml.etree import ElementTree
from processes import killProcesses
    from PilotErrors import PilotErrors
    from Logger import Logger
    from SiteMover import SiteMover
            from xml.sax import make_parser
            from xml.sax.handler import feature_namespaces
            from SiteMover import SiteMover
        from SiteMover import SiteMover
    from SiteMover import SiteMover
        from TimerCommand import TimerCommand
    from SiteInformation import SiteInformation
        from SiteInformation import SiteInformation
    from JobState import JobState
    from DBReleaseHandler import DBReleaseHandler
    from SiteMover import SiteMover
    from glob import glob
    from ExperimentFactory import ExperimentFactory
    from SiteInformationFactory import SiteInformationFactory
    from urllib import urlencode
        from urlparse import parse_qs
        from cgi import parse_qs
    from FileHandling import findLatestTRFLogFile
        from glob import glob
    from JobLog import JobLog
    from JobState import JobState
    from glob import glob
            from FileHandling import getExtension
    from PandaServerClient import PandaServerClient
    from EventServiceFactory import EventServiceFactory
    from re import split
                ec = error.ERR_SIGXCPU
            elif sig == signal.SIGBUS:
                ec = error.ERR_SIGBUS
            elif sig == signal.SIGUSR1:
                ec = error.ERR_SIGUSR1
            else:
                ec = error.ERR_KILLSIGNAL

            env['jobDic'][k][1].result[0] = "failed"
            env['jobDic'][k][1].subStatus = 'pilot_killed'
            env['jobDic'][k][1].currentState = env['jobDic'][k][1].result[0]
            # do not overwrite any previous error
            if env['jobDic'][k][1].result[2] == 0:
                env['jobDic'][k][1].result[2] = ec
            if not env['logTransferred']:
                env['jobDic'][k][1].pilotErrorDiag = "Job killed by signal %s: Signal handler has set job result to FAILED, ec = %d" %\
                                              (str(sig), ec)
                logMsg = "!!FAILED!!1999!! %s\n%s" % (env['jobDic'][k][1].pilotErrorDiag, env['version'])
                tolog(logMsg)

                ret, retNode = updatePandaServer(env['jobDic'][k][1], log = logMsg)
                if ret == 0:
                    tolog("Successfully updated panda server at %s" % timeStamp())
            else:
                # log should have been transferred
                env['jobDic'][k][1].pilotErrorDiag = "Job killed by signal %s: Signal handler has set job result to FAILED, ec = %d" %\
                                              (str(sig), ec)
                logMsg = "!!FAILED!!1999!! %s\n%s" % (env['jobDic'][k][1].pilotErrorDiag, env['version'])
                tolog(logMsg)


# Path: processes.py
# def killProcesses(pid, pgrp):
#     """ kill a job upon request """
# 
#     pUtil.tolog("killProcesses() called")
# 
#     # if there is a known subprocess pgrp, then it should be enough to kill the group in one go
#     status = False
# 
#     _sleep = True
#     if pgrp != 0:
#         # kill the process gracefully
#         pUtil.tolog("Killing group process %d" % (pgrp))
#         try:
#             os.killpg(pgrp, signal.SIGTERM)
#         except Exception,e:
#             pUtil.tolog("WARNING: Exception thrown when killing the child group process with SIGTERM: %s" % (e))
#             _sleep = False
#         else:
#             pUtil.tolog("(SIGTERM sent)")
# 
#         if _sleep:
#             _t = 30
#             pUtil.tolog("Sleeping %d s to allow processes to exit" % (_t))
#             time.sleep(_t)
# 
#         try:
#             os.killpg(pgrp, signal.SIGKILL)
#         except Exception,e:
#             pUtil.tolog("WARNING: Exception thrown when killing the child group process with SIGKILL: %s" % (e))
#         else:
#             pUtil.tolog("(SIGKILL sent)")
#             status = True
# 
#     if not status:
#         # firstly find all the children process IDs to be killed
#         children = []
#         findProcessesInGroup(children, pid)
# 
#         # reverse the process order so that the athena process is killed first (otherwise the stdout will be truncated)
#         children.reverse()
#         pUtil.tolog("Process IDs to be killed: %s (in reverse order)" % str(children))
# 
#         # find which commands are still running
#         try:
#             cmds = getProcessCommands(os.geteuid(), children)
#         except Exception, e:
#             pUtil.tolog("getProcessCommands() threw an exception: %s" % str(e))
#         else:
#             if len(cmds) <= 1:
#                 pUtil.tolog("Found no corresponding commands to process id(s)")
#             else:
#                 pUtil.tolog("Found commands still running:")
#                 for cmd in cmds:
#                     pUtil.tolog(cmd)
# 
#                 # loop over all child processes
#                 for i in children:
#                     # dump the stack trace before killing it
#                     dumpStackTrace(i)
# 
#                     # kill the process gracefully
#                     try:
#                         os.kill(i, signal.SIGTERM)
#                     except Exception,e:
#                         pUtil.tolog("WARNING: Exception thrown when killing the child process %d under SIGTERM, wait for kill -9 later: %s" % (i, str(e)))
#                         pass
#                     else:
#                         pUtil.tolog("Killed pid: %d (SIGTERM)" % (i))
# 
#                     _t = 10
#                     pUtil.tolog("Sleeping %d s to allow process to exit" % (_t))
#                     time.sleep(_t)
# 
#                     # now do a hardkill just in case some processes haven't gone away
#                     try:
#                         os.kill(i, signal.SIGKILL)
#                     except Exception,e:
#                         pUtil.tolog("WARNING: Exception thrown when killing the child process %d under SIGKILL, ignore this if it is already killed by previous SIGTERM: %s" % (i, str(e)))
#                         pass
#                     else:
#                         pUtil.tolog("Killed pid: %d (SIGKILL)" % (i))
# 
#     pUtil.tolog("Killing any remaining orphan processes")
#     killOrphans()


# Path: pUtil.py
import sys, os, signal, time, shutil, cgi
import commands, re
import urllib
import json
import traceback
import environment
    import datetime
    import logging
        import inspect
            import JobInfoXML
        import traceback
    import socket
    import collections
from xml.dom import minidom
from xml.dom.minidom import Document
from xml.dom.minidom import parse, parseString
from xml.etree import ElementTree
from processes import killProcesses
    from PilotErrors import PilotErrors
    from Logger import Logger
    from SiteMover import SiteMover
            from xml.sax import make_parser
            from xml.sax.handler import feature_namespaces
            from SiteMover import SiteMover
        from SiteMover import SiteMover
    from SiteMover import SiteMover
        from TimerCommand import TimerCommand
    from SiteInformation import SiteInformation
        from SiteInformation import SiteInformation
    from JobState import JobState
    from DBReleaseHandler import DBReleaseHandler
    from SiteMover import SiteMover
    from glob import glob
    from ExperimentFactory import ExperimentFactory
    from SiteInformationFactory import SiteInformationFactory
    from urllib import urlencode
        from urlparse import parse_qs
        from cgi import parse_qs
    from FileHandling import findLatestTRFLogFile
        from glob import glob
    from JobLog import JobLog
    from JobState import JobState
    from glob import glob
            from FileHandling import getExtension
    from PandaServerClient import PandaServerClient
    from EventServiceFactory import EventServiceFactory
    from re import split

                ec = error.ERR_SIGXCPU
            elif sig == signal.SIGBUS:
                ec = error.ERR_SIGBUS
            elif sig == signal.SIGUSR1:
                ec = error.ERR_SIGUSR1
            else:
                ec = error.ERR_KILLSIGNAL

            env['jobDic'][k][1].result[0] = "failed"
            env['jobDic'][k][1].subStatus = 'pilot_killed'
            env['jobDic'][k][1].currentState = env['jobDic'][k][1].result[0]
            # do not overwrite any previous error
            if env['jobDic'][k][1].result[2] == 0:
                env['jobDic'][k][1].result[2] = ec
            if not env['logTransferred']:
                env['jobDic'][k][1].pilotErrorDiag = "Job killed by signal %s: Signal handler has set job result to FAILED, ec = %d" %\
                                              (str(sig), ec)
                logMsg = "!!FAILED!!1999!! %s\n%s" % (env['jobDic'][k][1].pilotErrorDiag, env['version'])
                tolog(logMsg)

                ret, retNode = updatePandaServer(env['jobDic'][k][1], log = logMsg)
                if ret == 0:
                    tolog("Successfully updated panda server at %s" % timeStamp())
            else:
                # log should have been transferred
                env['jobDic'][k][1].pilotErrorDiag = "Job killed by signal %s: Signal handler has set job result to FAILED, ec = %d" %\
                                              (str(sig), ec)
                logMsg = "!!FAILED!!1999!! %s\n%s" % (env['jobDic'][k][1].pilotErrorDiag, env['version'])
                tolog(logMsg)


            killProcesses(env['jobDic'][k][0], env['jobDic'][k][1].pgrp)