Skip to content

Commit

Permalink
Add abortedby property to Execution/BaseReport, and log user who kill…
Browse files Browse the repository at this point in the history
…s jobs
  • Loading branch information
gschueler committed Feb 16, 2011
1 parent 528a3ab commit 039baf2
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 58 deletions.
67 changes: 15 additions & 52 deletions rundeckapp/grails-app/controllers/ExecutionController.groovy
Expand Up @@ -106,39 +106,22 @@ class ExecutionController {
}
}
def ScheduledExecution se = e.scheduledExecution

def ident = scheduledExecutionService.getJobIdent(se,e)
def didcancel
def statusStr
if(scheduledExecutionService.existsJob(ident.jobname, ident.groupname)){
didcancel=scheduledExecutionService.interruptJob(ident.jobname, ident.groupname)
}else if(null==e.dateCompleted){
executionService.saveExecutionState(
se?se.id:null,
e.id,
[
status:String.valueOf(false),
dateCompleted:new Date(),
cancelled:true
]
)
didcancel=true
}else{
didcancel=e.cancelled || 'true'!=e.status
statusStr='previously '+('true'==e.status?'success':e.cancelled?'killed':'failed')
}

def abortresult=executionService.abortExecution(se,e,session.user)

def didcancel=abortresult.abortstate in [ABORT_ABORTED,ABORT_PENDING]
withFormat{
json{
render(contentType:"text/json"){
delegate.cancelled(didcancel)
delegate.status(statusStr?statusStr:(didcancel?'killed':'failed'))
delegate.status(abortresult.statusStr?abortresult.statusStr:(didcancel?'killed':'failed'))
}
}
xml {
render(contentType:"text/xml",encoding:"UTF-8"){
result(error:false,success:didcancel){
success{
message("Job status: ${statusStr?statusStr:(didcancel?'killed': 'failed')}")
message("Job status: ${abortresult.statusStr?abortresult.statusStr:(didcancel?'killed': 'failed')}")
}
}
}
Expand Down Expand Up @@ -565,7 +548,7 @@ class ExecutionController {
public static String EXECUTION_SUCCEEDED = "succeeded"
public static String EXECUTION_FAILED = "failed"
public static String EXECUTION_ABORTED = "aborted"
public String getExecutionState(Execution e){
public static String getExecutionState(Execution e){
return null==e.dateCompleted?EXECUTION_RUNNING:"true"==e.status?EXECUTION_SUCCEEDED:e.cancelled?EXECUTION_ABORTED:EXECUTION_FAILED
}
/**
Expand All @@ -587,6 +570,9 @@ class ExecutionController {
if (null != e.dateCompleted) {
delegate.'date-ended'(unixtime: e.dateCompleted.time, g.w3cDateValue(date: e.dateCompleted))
}
if(e.cancelled){
abortedby(e.abortedby?e.abortedby:e.user)
}
if (e.scheduledExecution) {
job(id: e.scheduledExecution.id) {
name(e.scheduledExecution.jobName)
Expand Down Expand Up @@ -636,37 +622,14 @@ class ExecutionController {
}
def ScheduledExecution se = e.scheduledExecution

def ident = scheduledExecutionService.getJobIdent(se,e)
def statusStr
def abortstate
def jobstate
if(scheduledExecutionService.existsJob(ident.jobname, ident.groupname)){
def didcancel=scheduledExecutionService.interruptJob(ident.jobname, ident.groupname)
abortstate=didcancel?ABORT_PENDING:ABORT_FAILED
jobstate=EXECUTION_RUNNING
}else if(null==e.dateCompleted){
executionService.saveExecutionState(
se?se.id:null,
e.id,
[
status:String.valueOf(false),
dateCompleted:new Date(),
cancelled:true
]
)
abortstate=ABORT_ABORTED
jobstate=EXECUTION_ABORTED
}else{
jobstate=getExecutionState(e)
statusStr='previously '+jobstate
abortstate=ABORT_FAILED
}
def abortresult=executionService.abortExecution(se,e,session.user)

return new ApiController().success{ delegate->
delegate.'success'{
message("Execution status: ${statusStr?statusStr:jobstate}")
message("Execution status: ${abortresult.statusStr?abortresult.statusStr:abortresult.jobstate}")
}
delegate.'abort'(status:abortstate){
execution(id:params.id, status: jobstate)
delegate.'abort'(status:abortresult.abortstate){
execution(id:params.id, status: abortresult.jobstate)
}

}
Expand Down
3 changes: 3 additions & 0 deletions rundeckapp/grails-app/controllers/ReportsController.groovy
Expand Up @@ -408,6 +408,9 @@ class ReportsController {
delegate.'node-summary'(succeeded:nodesum[0],failed:nodesum[1],total:nodesum[2])
user(rpt.author)
project(rpt.ctxProject)
if(rpt.status=='cancel' && rpt.abortedByUser){
abortedby(rpt.abortedByUser)
}
delegate.'date-started'(g.w3cDateValue(date:rpt.dateStarted))
delegate.'date-ended'(g.w3cDateValue(date:rpt.dateCompleted))
if(rpt.jcJobId){
Expand Down
2 changes: 2 additions & 0 deletions rundeckapp/grails-app/domain/ExecReport.groovy
Expand Up @@ -6,6 +6,7 @@ class ExecReport extends BaseReport{
String jcJobId
Boolean adhocExecution
String adhocScript
String abortedByUser

static constraints = {
adhocExecution(nullable:true)
Expand All @@ -14,5 +15,6 @@ class ExecReport extends BaseReport{
jcExecId(nullable:true,blank:false)
jcJobId(nullable:true,blank:false)
adhocScript(nullable:true,blank:true)
abortedByUser(nullable:true,blank:true)
}
}
2 changes: 2 additions & 0 deletions rundeckapp/grails-app/domain/Execution.groovy
Expand Up @@ -10,6 +10,7 @@ class Execution extends ExecutionContext {
String status
String outputfilepath
String failedNodeList
String abortedby
boolean cancelled

static constraints = {
Expand Down Expand Up @@ -46,6 +47,7 @@ class Execution extends ExecutionContext {
adhocLocalString(nullable:true, blank:true)
adhocFilepath(nullable:true, blank:true)
failedNodeList(nullable:true, blank:true)
abortedby(nullable:true, blank:true)
}


Expand Down
49 changes: 44 additions & 5 deletions rundeckapp/grails-app/services/ExecutionService.groovy
Expand Up @@ -402,7 +402,7 @@ class ExecutionService implements ApplicationContextAware, Executor{
}


public static synchronized logExecution(uri,project,user,issuccess,framework,execId,Date startDate=null, jobExecId=null, jobName=null, jobSummary=null,iscancelled=false, nodesummary=null){
public static synchronized logExecution(uri,project,user,issuccess,framework,execId,Date startDate=null, jobExecId=null, jobName=null, jobSummary=null,iscancelled=false, nodesummary=null, abortedby=null){

def internalLog = org.apache.log4j.Logger.getLogger("ExecutionService")
if(null==project || null==user ){
Expand Down Expand Up @@ -431,14 +431,17 @@ class ExecutionService implements ApplicationContextAware, Executor{
def logger = org.apache.log4j.Logger.getLogger("com.dtolabs.rundeck.log.internal")
org.apache.log4j.MDC.put(LogConstants.MDC_ITEM_TYPE_KEY,"commandExec")
org.apache.log4j.MDC.put(LogConstants.MDC_PROJECT_KEY,project)
if(uri){
org.apache.log4j.MDC.put(LogConstants.MDC_MAPREF_KEY,uri)

if(iscancelled && abortedby){
org.apache.log4j.MDC.put('rundeckAbortedBy',abortedby)
}else if(iscancelled){
org.apache.log4j.MDC.put('rundeckAbortedBy',user)
}
org.apache.log4j.MDC.put(LogConstants.MDC_AUTHOR_KEY,user)
org.apache.log4j.MDC.put(LogConstants.MDC_ACTION_KEY, jobSummary?jobSummary:"rundeck Job Execution")
org.apache.log4j.MDC.put(LogConstants.MDC_ACTION_TYPE_KEY, issuccess ? LogConstants.ActionType.SUCCEED.toString():iscancelled?LogConstants.ActionType.CANCEL.toString():LogConstants.ActionType.FAIL.toString())
org.apache.log4j.MDC.put(LogConstants.MDC_NODENAME_KEY, null!=nodesummary?nodesummary: framework.getFrameworkNodeName())
logger.info(issuccess?'Job completed successfully':iscancelled?'Job killed':'Job failed')
logger.info(issuccess?'Job completed successfully':iscancelled?('Job killed by: '+(abortedby?:user)):'Job failed')

org.apache.log4j.MDC.remove(LogConstants.MDC_ITEM_TYPE_KEY)
org.apache.log4j.MDC.remove(LogConstants.MDC_PROJECT_KEY)
Expand All @@ -449,6 +452,7 @@ class ExecutionService implements ApplicationContextAware, Executor{
org.apache.log4j.MDC.remove(LogConstants.MDC_ACTION_TYPE_KEY)
org.apache.log4j.MDC.remove(LogConstants.MDC_NODENAME_KEY)
org.apache.log4j.MDC.remove(LogConstants.MDC_ADHOCEXEC_KEY)
org.apache.log4j.MDC.remove('rundeckAbortedBy')
org.apache.log4j.MDC.remove('rundeckJobName')
org.apache.log4j.MDC.remove('rundeckJobId')
org.apache.log4j.MDC.remove('rundeckExecId')
Expand Down Expand Up @@ -675,6 +679,39 @@ class ExecutionService implements ApplicationContextAware, Executor{
return thread.isSuccessful()
}

def abortExecution(ScheduledExecution se, Execution e, String user){
def ident = scheduledExecutionService.getJobIdent(se,e)
def statusStr
def abortstate
def jobstate
if(scheduledExecutionService.existsJob(ident.jobname, ident.groupname)){
if(!e.abortedby){
e.abortedby=user
e.save()
}
def didcancel=scheduledExecutionService.interruptJob(ident.jobname, ident.groupname)
abortstate=didcancel?ExecutionController.ABORT_PENDING:ExecutionController.ABORT_FAILED
jobstate=ExecutionController.EXECUTION_RUNNING
}else if(null==e.dateCompleted){
saveExecutionState(
se?se.id:null,
e.id,
[
status:String.valueOf(false),
dateCompleted:new Date(),
cancelled:true,
abortedby:user
]
)
abortstate=ExecutionController.ABORT_ABORTED
jobstate=ExecutionController.EXECUTION_ABORTED
}else{
jobstate=ExecutionController.getExecutionState(e)
statusStr='previously '+jobstate
abortstate=ExecutionController.ABORT_FAILED
}
return [abortstate:abortstate,jobstate:jobstate,statusStr:statusStr]
}

/**
* Return a map of include filters as used by the NodeSet type
Expand Down Expand Up @@ -1065,7 +1102,9 @@ class ExecutionService implements ApplicationContextAware, Executor{
totalCount=matched.size()
}
def Framework fw = frameworkService.getFramework()
logExecution(null, execution.project, execution.user, "true" == execution.status, fw, exId, execution.dateStarted, jobid, jobname, summarizeJob(scheduledExecution, execution), props.cancelled, node)
logExecution(null, execution.project, execution.user, "true" == execution.status, fw, exId,
execution.dateStarted, jobid, jobname, summarizeJob(scheduledExecution, execution), props.cancelled,
node, execution.abortedby)
notificationService.triggerJobNotification(props.status == 'true' ? 'success' : 'failure', schedId, [execution: execution,nodestatus:[succeeded:sucCount,failed:failedCount,total:totalCount]])
}
}
Expand Down
9 changes: 9 additions & 0 deletions rundeckapp/grails-app/services/ReportService.groovy
Expand Up @@ -3,6 +3,11 @@ import com.dtolabs.rundeck.services.ReportAcceptor
class ReportService implements ReportAcceptor {
def grailsApplication
public void makeReport(Map fields) {
/**
* allowed fields are specified
* in the {@link com.dtolabs.rundeck.services.ReportAppender} class
*/

fields['title'] = fields['evtAction']
if(!fields['node'] && fields['evtRemoteHost']){
fields['node']=fields['evtRemoteHost']
Expand Down Expand Up @@ -46,6 +51,9 @@ class ReportService implements ReportAcceptor {
if(fields['rundeckAdhocScript']){
fields['adhocScript']=fields['rundeckAdhocScript']
}
if(fields['rundeckAbortedBy']){
fields['abortedByUser']=fields['rundeckAbortedBy']
}

if(!fields['ctxController']){
fields['ctxController']=fields['ctxType']
Expand Down Expand Up @@ -263,6 +271,7 @@ class ReportService implements ReportAcceptor {
proj: 'ctxProject',
cmd: 'ctxCommand',
user: 'author',
abortedBy: 'abortedByUser',
node: 'node',
message: 'message',
//job filter repurposed for reportId
Expand Down
2 changes: 1 addition & 1 deletion rundeckapp/grails-app/views/execution/show.gsp
Expand Up @@ -149,7 +149,7 @@
Successful
</g:if>
<g:elseif test="${execution.cancelled}">
Killed
Killed<g:if test="${execution.abortedby}"> by: ${execution.abortedby.encodeAsHTML()}</g:if>
</g:elseif>
<g:else>
Failed
Expand Down
1 change: 1 addition & 0 deletions rundeckapp/src/groovy/ExecQuery.groovy
Expand Up @@ -39,6 +39,7 @@ class ExecQuery extends ReportQuery{
"maprefUriFilter",
"messageFilter",
"reportIdFilter",
"abortedByFilter",
])

}
Expand Down
1 change: 1 addition & 0 deletions rundeckapp/src/groovy/ReportQuery.groovy
Expand Up @@ -50,6 +50,7 @@ class ReportQuery extends BaseQuery{
String statFilter
String reportIdFilter
String tagsFilter
String abortedByFilter

public void configureFilter(){
if(recentFilter){
Expand Down
Expand Up @@ -67,6 +67,7 @@ protected void append(LoggingEvent event) {
map.put("rundeckExecId", event.getMDC("rundeckExecId"));
map.put("rundeckJobId", event.getMDC("rundeckJobId"));
map.put("rundeckJobName", event.getMDC("rundeckJobName"));
map.put("rundeckAbortedBy", event.getMDC("rundeckAbortedBy"));
map.put("epochDateStarted", event.getMDC(Constants.MDC_EPOCHSTART_KEY));
map.put("epochDateEnded", event.getMDC(Constants.MDC_EPOCHEND_KEY));
if (null!=event.getMDC("adhocScript")) {
Expand Down

0 comments on commit 039baf2

Please sign in to comment.