1
2
3
4
5
6
7
8
9
10
11 """
12 Operations for jobs.
13
14 Available at: /zport/dmd/jobs_router
15 """
16 import cgi
17 import logging
18 from collections import defaultdict
19 from Products import Zuul
20 from Products.ZenMessaging.audit import audit
21 from Products.ZenUtils.Ext import DirectRouter, DirectResponse
22 from Products.Jobber.exceptions import NoSuchJobException
23 from zope.event import notify
24 from ZODB.transact import transact
25 from Products.ZenUtils.events import QuickstartWizardFinishedEvent
26
27 log = logging.getLogger('zen.JobsRouter')
28
29
30 JOBKEYS = ['uuid', 'type', 'description', 'scheduled', 'started', 'finished',
31 'status', 'user']
32
33
35 """
36 A JSON/Ext.Direct interface to operations on jobs
37 """
39 self.api = Zuul.getFacade('jobs', context.dmd)
40 self.context = context
41 self.request = request
42 super(DirectRouter, self).__init__(context, request)
43
44 - def getJobs(self, start, limit, page, sort, dir, uid=None):
45
46 user = self.context.dmd.ZenUsers.getUserSettings()
47 createdBy = user.id if user.hasNoGlobalRoles() else None
48
49 results, total = self.api.getJobs(start=start, limit=limit, sort=sort,
50 dir=dir, createdBy=createdBy)
51 jobs = Zuul.marshal(results, keys=JOBKEYS)
52 for job in jobs:
53 job['description'] = cgi.escape(job.get('description') or '')
54 return DirectResponse(jobs=jobs, totalCount=total)
55
57 for id_ in jobids:
58 try:
59 self.api.abortJob(id_)
60 except NoSuchJobException:
61 log.debug("Unable to abort job: %s No such job found.", id_)
62
64
65 if not Zuul.checkPermission('Manage DMD'):
66 return DirectResponse.fail("You don't have permission to execute this command", sticky=False)
67
68 deletedJobs = []
69 for id_ in jobids:
70 try:
71 self.api.deleteJob(id_)
72 except NoSuchJobException:
73 log.debug("Unable to delete job: %s No such job found.", id_)
74 else:
75 deletedJobs.append(id_)
76 if deletedJobs:
77 audit('UI.Jobs.Delete', ids=deletedJobs)
78 return DirectResponse.succeed(deletedJobs=Zuul.marshal(deletedJobs))
79
81 job = self.api.getInfo(jobid)
82 return DirectResponse.succeed(data=Zuul.marshal(job))
83
85 try:
86 logfile, content, maxLimit = self.api.getJobDetail(jobid)
87 except NoSuchJobException:
88
89
90 logfile, content, maxLimit = None, None, None
91 return {'content': content, 'logfile': logfile, 'maxLimit' : maxLimit}
92
94 results = defaultdict(list)
95 totals = {}
96 validstates = {'STARTED':'started', 'SUCCESS':'finished',
97 'PENDING':'scheduled'}
98 for job in self.api.getUserJobs():
99 if job.status in validstates:
100 results[job.status].append(job)
101
102 for status, jobs in results.iteritems():
103 jobs.sort(key=lambda j:getattr(j, validstates[status]),
104 reverse=True)
105 totals[status] = len(jobs)
106 results[status] = jobs[:10]
107 jobs = Zuul.marshal(results, keys=JOBKEYS)
108 for joblist in jobs.itervalues():
109 for job in joblist:
110 job['description'] = cgi.escape(job['description'])
111 return DirectResponse(jobs=jobs, totals=totals)
112
114
115 app = self.context.dmd.primaryAq().getParentNode().getParentNode()
116 transact(notify)(QuickstartWizardFinishedEvent(app))
117 return DirectResponse.succeed()
118