1 import turbogears as tg
2 from turbogears import controllers, expose, flash, exception_handler, redirect
3 from turbogears import widgets
4 from cherrypy import request, response
6 # from monitorweb import model
8 # log = logging.getLogger("monitorweb.controllers")
11 from monitor.database.info.model import *
12 #from monitor.database.zabbixapi.model import *
13 from monitor_xmlrpc import MonitorXmlrpcServer
15 from monitor import util
16 from monitor import reboot
17 from monitor import bootman
18 from monitor import scanapi
19 from monitor import config
22 from monitor.wrapper.plccache import plcdb_hn2lb as site_hn2lb
24 from monitorweb.templates.links import *
26 class ObjectQueryFields(widgets.WidgetsList):
27 """The WidgetsList defines the fields of the form."""
32 class NodeQueryFields(widgets.WidgetsList):
33 """The WidgetsList defines the fields of the form."""
35 object = widgets.RadioButtonList(label="Query Type", options=[('nodes', 'All Nodes'),
36 ('nodehistory', 'Single Node History'),
37 #('sites', 'All Sites'),
38 #('sitehistory', 'Single Site History'),
40 nodehistory_hostname = widgets.TextField(label="Hostname Node History", attrs={'size':30})
42 hostname = widgets.CheckBox(label="Hostname")
43 firewall = widgets.CheckBox(label="Firewall?")
44 fs_status = widgets.CheckBox(label="Filesystem Status")
45 ssh_status = widgets.CheckBox(label="SSH Status")
46 ssh_error = widgets.CheckBox(label="SSH Errors")
47 dns_status = widgets.CheckBox(label="DNS Status")
48 iptables_status = widgets.CheckBox(label="IP Tables Status")
49 nm_status = widgets.CheckBox(label="NM Status")
50 princeton_comon_dir = widgets.CheckBox(label="CoMon Dir")
51 princeton_comon_running = widgets.CheckBox(label="CoMon Running")
52 princeton_comon_procs = widgets.CheckBox(label="CoMon Processes")
53 external_dns_status = widgets.CheckBox(label="Hostname Resolves?")
54 kernel_version = widgets.CheckBox(label="Kernel")
55 bootcd_version = widgets.CheckBox(label="BootCD")
56 observed_status = widgets.CheckBox(label="Observed Status")
57 uptime = widgets.CheckBox(label="Uptime")
58 traceroute = widgets.CheckBox(label="Traceroute")
59 port_status = widgets.CheckBox(label="Port Status")
60 rpms = widgets.CheckBox(label="RPM")
61 rpmvalue = widgets.TextField(label="RPM Pattern")
63 class QueryForm(widgets.TableForm):
65 <form xmlns:py="http://purl.org/kid/ns#"
73 <div py:for="field in hidden_fields"
74 py:replace="field.display(value_for(field), **params_for(field))"
76 <table border="0" cellspacing="0" cellpadding="2" py:attrs="table_attrs">
77 <tr py:for="i, field in enumerate(fields)"
78 class="${i%2 and 'odd' or 'even'}"
81 <label class="fieldlabel" for="${field.field_id}" py:content="field.label" />
84 <span py:replace="field.display(value_for(field), **params_for(field))" />
85 <span py:if="error_for(field)" class="fielderror" py:content="error_for(field)" />
86 <span py:if="field.help_text" class="fieldhelp" py:content="field.help_text" />
91 <td py:content="submit.display(submit_text)" />
97 def getNodeQueryForm():
98 return QueryForm(fields=NodeQueryFields(), action="query")
100 # make it easier group objects without invoking the elixir auto-write feature.
101 class aggregate: pass
104 def query_to_dict(query):
105 """ take a url query string and chop it up """
107 query_fields = query.split('&')
108 for f in query_fields:
109 (k,v) = urllib.splitvalue(f)
114 def format_ports(data, pcumodel=None):
119 supported_ports=reboot.model_to_object(pcumodel).supported_ports
121 # ports of a production node
122 supported_ports=[22,80,806]
124 if data and len(data.keys()) > 0 :
125 for port in supported_ports:
127 state = data[str(port)]
131 if state == "filtered":
134 retval.append( (port, state) )
137 retval = [( "Closed/Filtered", "state" )]
139 if filtered_length == len(supported_ports):
140 retval = [( "All Filtered", "state" )]
144 def format_pcu_shortstatus(pcu):
147 if pcu.reboot_trial_status == str(0):
149 elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
150 status = pcu.reboot_trial_status
156 def prep_pcu_for_display(pcu):
161 agg.loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
163 agg.loginbase = "unknown"
165 agg.pcuhist = HistoryPCURecord.query.get(pcu.plc_pcuid)
167 agg.ports = format_ports(pcu.port_status, pcu.plc_pcu_stats['model'])
168 agg.status = format_pcu_shortstatus(pcu)
170 #print pcu.entry_complete
171 agg.entry_complete_str = pcu.entry_complete
172 #pcu.entry_complete_str += "".join([ f[0] for f in pcu.entry_complete.split() ])
173 if pcu.dns_status == "NOHOSTNAME":
174 agg.dns_short_status = 'NoHost'
175 elif pcu.dns_status == "DNS-OK":
176 agg.dns_short_status = 'Ok'
177 elif pcu.dns_status == "DNS-NOENTRY":
178 agg.dns_short_status = 'NoEntry'
179 elif pcu.dns_status == "NO-DNS-OR-IP":
180 agg.dns_short_status = 'NoHostOrIP'
181 elif pcu.dns_status == "DNS-MISMATCH":
182 agg.dns_short_status = 'Mismatch'
185 class ActionListWidget(widgets.Widget):
188 class NodeWidget(widgets.Widget):
191 def prep_nodehist(node):
194 agg.loginbase = "unknown"
196 agg.loginbase = PlcSite.query.get(node.plc_siteid).plc_site_stats['login_base']
198 agg.loginbase = "exception"
203 def prep_node_for_display(node, pcuhash=None, preppcu=True, asofdate=None):
207 if node.plc_pcuid and preppcu:
209 pcu = pcuhash[node.plc_pcuid]
211 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid)
214 agg.pcu_status = pcu.reboot_trial_status
215 agg.pcu_short_status = format_pcu_shortstatus(pcu)
216 agg.pcu = prep_pcu_for_display(pcu)
218 agg.pcu_short_status = "none"
219 agg.pcu_status = "nodata"
223 agg.pcu_status = "nopcu"
224 agg.pcu_short_status = "none"
228 if node.kernel_version:
229 agg.kernel = node.kernel_version.split()[2]
234 agg.loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
236 agg.loginbase = "unknown"
239 agg.site = HistorySiteRecord.by_loginbase(agg.loginbase)
242 agg.site = agg.site.get_as_of(asofdate)
245 # TODO: need a cleaner fix for this...
246 agg.site = HistorySiteRecord.by_loginbase("pl")
248 agg.site = HistorySiteRecord.by_loginbase("ple")
250 agg.history = HistoryNodeRecord.by_hostname(node.hostname)
252 agg.history = agg.history.get_as_of(asofdate)
254 agg.ports = format_ports(node.port_status)
257 exists = node.plc_node_stats['last_contact']
259 # TODO: this should not assign to the fb object!
260 node.plc_node_stats = {'last_contact' : None}
265 class Root(controllers.RootController, MonitorXmlrpcServer):
266 @expose(template="monitorweb.templates.welcome")
268 # log.debug("Happy TurboGears Controller Responding For Duty")
269 flash("Welcome To MyOps!")
270 return dict(now=time.ctime())
272 @expose(template="monitorweb.templates.nodelist", allow_json=True)
273 def node3(self, filter=None):
274 nhquery = HistoryNodeRecord.query.all()
278 if nh.status == filter:
285 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
288 return dict(now=time.ctime(), query=rquery)
290 def node_query(self, filter):
291 nhquery = HistoryNodeRecord.query.all()
295 if nh.status == filter:
302 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
303 agg = prep_node_for_display(fb)
307 @expose("cheetah:monitorweb.templates.nodelist_plain", as_format="plain",
308 accept_format="text/plain", content_type="text/plain")
309 @expose(template="monitorweb.templates.nodelist", allow_json=True)
310 def node2(self, filter=None):
311 rquery=self.node_query(filter)
312 widget = NodeWidget(template='monitorweb.templates.node_template')
313 return dict(now=time.ctime(), query=rquery, nodewidget=widget)
315 @expose("cheetah:monitorweb.templates.query_plain", as_format="plain",
316 accept_format="text/plain", content_type="text/plain")
317 @expose(template="monitorweb.templates.query", allow_json=True)
318 def query(self, **data):
326 if 'object' in data and data['object'] == "nodes":
327 fbquery = FindbadNodeRecord.get_all_latest()
328 elif 'object' in data and data['object'] == "nodehistory":
329 hostname = data['nodehistory_hostname']
330 data['date_checked'] = 'date_checked'
331 fbrecord = FindbadNodeRecord.get_by(hostname=hostname)
332 fbquery = fbrecord.versions[-500:]
336 # NOTE: reformat some fields.
337 if type(node) is not type(FindbadNodeRecord):
338 agg = node.__dict__.copy()
341 agg.update(agg['plc_node_stats'])
342 if agg['kernel_version']:
343 agg['kernel_version'] = agg['kernel_version'].split()[2]
344 if 'traceroute' in data and agg['traceroute']:
345 agg['traceroute'] = "<pre>" + agg['traceroute'] + "</pre>"
346 if 'rpmvalue' in data and 'rpms' in data:
348 rpm_list = agg['rpms'].split()
349 rpm_list = filter(lambda x: data['rpmvalue'] in x, rpm_list)
350 agg['rpms'] = " ".join(rpm_list)
358 del fields['rpmvalue']
359 del fields['nodehistory_hostname']
361 return dict(now=time.ctime(), query=query, fields=fields, data=data, queryform=getNodeQueryForm())
363 @expose(template="monitorweb.templates.nodefast", allow_json=True)
364 def node(self, filter=None):
365 nhquery = HistoryNodeRecord.query.all()
369 if nh.status == filter:
370 agg = prep_nodehist(nh)
373 agg = prep_nodehist(nh)
376 return dict(now=time.ctime(), query=query)
378 @expose(template="monitorweb.templates.nodelist")
379 def nodeslow(self, filter='boot'):
380 print "NODE------------------"
381 print "befor-len: ", len( [ i for i in session] )
382 session.flush(); session.clear()
383 print "after-len: ", len( [ i for i in session] )
384 fbquery = FindbadNodeRecord.get_all_latest()
386 filtercount = {'down' : 0, 'boot': 0, 'debug' : 0, 'diagnose' : 0, 'disabled': 0,
387 'neverboot' : 0, 'pending' : 0, 'all' : 0, None : 0}
389 # NOTE: reformat some fields.
390 agg = prep_node_for_display(node)
395 if agg.history.status in ['down', 'offline']:
396 if node.plc_node_stats and node.plc_node_stats['last_contact'] != None:
397 filtercount['down'] += 1
399 filtercount['neverboot'] += 1
400 elif agg.history.status in ['good', 'online']:
401 filtercount['boot'] += 1
402 elif agg.history.status in ['debug', 'monitordebug']:
403 filtercount['debug'] += 1
405 if filtercount.has_key(agg.history.status):
406 filtercount[agg.history.status] += 1
410 if filter == "neverboot":
411 if not node.plc_node_stats or node.plc_node_stats['last_contact'] == None:
413 elif filter == "all":
415 elif filter == agg.history.status:
417 elif filter == 'boot':
421 widget = NodeWidget(template='monitorweb.templates.node_template')
422 return dict(now=time.ctime(), query=query, fc=filtercount, nodewidget=widget)
424 def nodeaction_handler(self, tg_exceptions=None):
425 """Handle any kind of error."""
426 print "NODEACTION_HANDLER------------------"
428 if 'pcuid' in request.params:
429 pcuid = request.params['pcuid']
431 refurl = request.headers.get("Referer",link("pcu"))
434 # TODO: do this more intelligently...
435 uri_fields = urllib.splitquery(refurl)
436 if uri_fields[1] is not None:
437 val = query_to_dict(uri_fields[1])
440 elif 'hostname' in val:
441 pcuid = FindbadNodeRecord.get_latest_by(hostname=val['hostname']).plc_pcuid
447 cherry_trail = cherrypy._cputil.get_object_trail()
448 for i in cherry_trail:
452 return self.pcuview(None, pcuid, **dict(exceptions=tg_exceptions))
454 def nodeaction(self, **data):
455 print "NODEACTION------------------"
456 for item in data.keys():
457 print "%s %s" % ( item, data[item] )
459 if 'hostname' in data:
460 hostname = data['hostname']
462 flash("No hostname given in submitted data")
465 if 'submit' in data or 'type' in data:
467 action = data['submit']
469 action = data['type']
471 flash("No submit action given in submitted data")
474 if action == "Reboot":
475 print "REBOOT: %s" % hostname
476 ret = reboot.reboot_str(str(hostname))
478 if ret: raise RuntimeError("Error using PCU: " + str(ret))
479 flash("Reboot appeared to work. Allow at most 5 minutes. Then run ExternalScan to check current status.")
481 elif action == "ExternalScan":
482 scanapi.externalprobe(str(hostname))
483 flash("External Scan Successful!")
484 elif action == "InternalScan":
485 scanapi.internalprobe(str(hostname))
486 flash("Internal Scan Successful!")
489 raise RuntimeError("Unknown action given")
492 @expose(template="monitorweb.templates.simpleview")
493 def simpleview(self, **data):
494 return self.pre_view(**data)
496 @expose(template="monitorweb.templates.simpleview")
497 def pcuview(self, **data):
498 return self.pre_view(**data)
500 @expose(template="monitorweb.templates.detailview")
501 def detailview(self, **data):
502 return self.pre_view(**data)
505 def pre_view(self, **data):
506 session.flush(); session.clear()
513 # if objtype is not None, then treat 'hostname' or 'loginbase' as a search pattern
528 fields = obj.split(":")
531 obj = fields[1].replace("*", "%")
534 if len(obj.split(".")) > 1 or objtype == "node":
539 if 'loginbase' in data:
540 loginbase = data['loginbase']
542 if 'hostname' in data:
543 hostname = data['hostname']
546 try: pcuid = int(data['pcuid'])
550 try: since = int(since)
554 print "pcuid: %s" % pcuid
555 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
556 loginbase_list += [ PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base'] ]
560 nodes = [ FindbadNodeRecord.get_latest_by(hostname=hostname) ]
562 nodes = FindbadNodeRecord.query.filter(FindbadNodeRecord.hostname.like(hostname))
565 lb = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
566 if lb not in loginbase_list:
567 loginbase_list += [ lb ]
571 loginbase_list = [ loginbase ]
573 loginbase_list = HistorySiteRecord.query.filter(HistorySiteRecord.loginbase.like(loginbase))
574 loginbase_list = [ l.loginbase for l in loginbase_list ]
578 for loginbase in loginbase_list:
579 actions = ActionRecord.query.filter_by(loginbase=loginbase
580 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
581 ).order_by(ActionRecord.date_created.desc())
582 actions_list += [ a for a in actions ]
583 site = HistorySiteRecord.by_loginbase(loginbase)
585 sitequery.append(site)
586 # NOTE: because a single pcu may be assigned to multiple hosts,
587 # track unique pcus by their plc_pcuid, then turn dict into list
589 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
590 # NOTE: reformat some fields.
591 agg = prep_node_for_display(node)
594 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
596 for pcuid_key in pcus:
597 pcuquery += [pcus[pcuid_key]]
599 actionlist_widget = ActionListWidget(template='monitorweb.templates.actionlist_template')
600 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions_list, actionlist_widget=actionlist_widget, since=since, exceptions=exceptions)
603 # TODO: add form validation
604 @expose(template="monitorweb.templates.pcuview")
605 @exception_handler(nodeaction_handler,"isinstance(tg_exceptions,RuntimeError)")
606 def pcuviewold(self, loginbase=None, pcuid=None, hostname=None, since=20, **data):
607 session.flush(); session.clear()
614 try: since = int(since)
620 if 'submit' in data.keys() or 'type' in data.keys():
621 if hostname: data['hostname'] = hostname
622 self.nodeaction(**data)
623 if 'exceptions' in data:
624 exceptions = data['exceptions']
628 if len(obj.split(".")) > 1: hostname = obj
632 print "pcuid: %s" % pcuid
633 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
634 loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
637 node = FindbadNodeRecord.get_latest_by(hostname=hostname)
638 loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
641 actions = ActionRecord.query.filter_by(loginbase=loginbase
642 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
643 ).order_by(ActionRecord.date_created.desc())
644 actions = [ a for a in actions ]
645 sitequery = [HistorySiteRecord.by_loginbase(loginbase)]
647 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
648 # NOTE: reformat some fields.
649 agg = prep_node_for_display(node)
651 if agg.pcu: #.pcu.plc_pcuid: # not None
652 #pcu = FindbadPCURecord.get_latest_by(plc_pcuid=agg.plc_pcuid)
653 #prep_pcu_for_display(pcu)
654 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
656 for pcuid_key in pcus:
657 pcuquery += [pcus[pcuid_key]]
659 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions, since=since, exceptions=exceptions)
661 @expose(template="monitorweb.templates.pcuhistory")
662 def pcuhistory(self, pcu_id=None):
665 fbnode = HistoryPCURecord.get_by(plc_pcuid=pcu_id)
666 l = fbnode.versions[-100:]
669 #prep_node_for_display(node)
672 return dict(query=query, pcu_id=pcu_id)
674 @expose(template="monitorweb.templates.nodescanhistory")
675 def nodescanhistory(self, hostname=None, length=10):
676 try: length = int(length)
679 fbnode = FindbadNodeRecord.get_by(hostname=hostname)
680 # TODO: add links for earlier history if desired.
681 l = fbnode.versions[-length:]
685 agg = prep_node_for_display(node, pcuhash=None, preppcu=False, asofdate=node.timestamp)
688 if 'length' in request.params:
689 del request.params['length']
690 return dict(query=query, hostname=hostname, params=request.params)
692 @expose(template="monitorweb.templates.nodehistory")
693 def nodehistory(self, hostname=None):
696 fbnode = HistoryNodeRecord.get_by(hostname=hostname)
697 l = fbnode.versions[-100:]
700 #prep_node_for_display(node)
703 return dict(query=query, hostname=hostname)
705 @expose(template="monitorweb.templates.sitehistory")
706 def sitehistory(self, loginbase=None):
709 fbsite = HistorySiteRecord.get_by(loginbase=loginbase)
710 # TODO: add links for earlier history if desired.
711 l = fbsite.versions[-100:]
715 return dict(query=query, loginbase=loginbase)
718 @expose(template="monitorweb.templates.pculist")
719 def pcu(self, filter='all'):
720 print "PCUVIEW------------------"
721 print "befor-len: ", len( [ i for i in session] )
722 session.flush(); session.clear()
723 print "after-len: ", len( [ i for i in session] )
724 fbquery = FindbadPCURecord.get_all_latest()
726 filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
730 if node.reboot_trial_status == str(0):
731 filtercount['ok'] += 1
732 elif node.reboot_trial_status == 'NetDown' or node.reboot_trial_status == 'Not_Run':
733 filtercount[node.reboot_trial_status] += 1
735 filtercount['pending'] += 1
737 pcuagg = prep_pcu_for_display(node)
742 elif filter == "ok" and node.reboot_trial_status == str(0):
744 elif filter == node.reboot_trial_status:
746 elif filter == "pending":
747 # TODO: look in message logs...
748 if node.reboot_trial_status != str(0) and \
749 node.reboot_trial_status != 'NetDown' and \
750 node.reboot_trial_status != 'Not_Run':
754 return dict(query=query, fc=filtercount)
756 @expose(template="monitorweb.templates.sitelist")
757 def site(self, filter='all'):
758 print "SITE------------------"
759 print "befor-len: ", len( [ i for i in session] )
760 session.flush(); session.clear()
761 print "after-len: ", len( [ i for i in session] )
762 filtercount = {'good' : 0, 'down': 0, 'online':0, 'offline' : 0, 'new' : 0, 'pending' : 0, 'all' : 0}
763 fbquery = HistorySiteRecord.query.all()
767 filtercount['all'] += 1
768 if site.new and site.slices_used == 0 and not site.enabled:
769 filtercount['new'] += 1
770 elif not site.enabled:
771 filtercount['pending'] += 1
772 elif site.status in ['good', 'online']:
773 filtercount['good'] += 1
774 elif site.status in ['down', 'offline']:
775 filtercount['down'] += 1
780 elif filter == 'new' and site.new and site.slices_used == 0 and not site.enabled:
782 elif filter == "pending" and not site.enabled:
784 elif filter == 'good' and site.status in ['good', 'online']:
786 elif filter == 'down' and site.status in ['down', 'offline']:
789 return dict(query=query, fc=filtercount)
790 @expose(template="monitorweb.templates.sitesummary")
791 def sitesummary(self, loginbase="princeton"):
793 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
794 agg = prep_node_for_display(node)
797 return dict(nodequery=nodequery, loginbase=loginbase)
799 @expose(template="monitorweb.templates.summary")
800 def summary(self, since=7):
802 sumdata['nodes'] = {}
803 sumdata['sites'] = {}
806 def summarize(query, type):
808 if o.status not in sumdata[type]:
809 sumdata[type][o.status] = 0
810 sumdata[type][o.status] += 1
812 fbquery = HistorySiteRecord.query.all()
813 summarize(fbquery, 'sites')
814 fbquery = HistoryPCURecord.query.all()
815 summarize(fbquery, 'pcus')
816 fbquery = HistoryNodeRecord.query.all()
817 summarize(fbquery, 'nodes')
819 if 'monitordebug' in sumdata['nodes']:
820 d = sumdata['nodes']['monitordebug']
821 del sumdata['nodes']['monitordebug']
822 sumdata['nodes']['failboot'] = d
824 return dict(sumdata=sumdata, setorder=['good', 'offline', 'down', 'online'])
826 @expose(template="monitorweb.templates.actionsummary")
827 def actionsummary(self, since=7):
828 from monitor.wrapper.emailTxt import mailtxt
830 types = filter(lambda x: 'notice' in x, dir(mailtxt))
833 print mon_metadata.bind
834 if session.bind is None:
835 #TODO: figure out why this value gets cleared out...
836 session.bind = mon_metadata.bind
837 result = session.execute("select distinct(action_type) from actionrecord;")
839 types = [r[0] for r in result]
841 try: since = int(since)
845 acts = ActionRecord.query.filter(ActionRecord.action_type==t
846 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since))
847 results[t] = acts.count()
848 return dict(results=results)
850 @expose(template="monitorweb.templates.actionlist")
851 def actionlist(self, since=7, action_type=None, loginbase=None):
853 try: since = int(since)
856 acts_query = ActionRecord.query.filter(
857 ActionRecord.date_created >= datetime.now() - timedelta(since)
860 acts_query = acts_query.filter_by(loginbase=loginbase)
863 acts_query = acts_query.filter(ActionRecord.action_type==action_type)
865 acts = acts_query.order_by(ActionRecord.date_created.desc())
867 query = [ a for a in acts ]
869 return dict(actions=query, action_type=action_type, since=since)
872 def upload(self, log, **keywords):
875 logtype_list = ['bm.log', ]
877 if 'hostname' in keywords:
878 hostname = keywords['hostname']
879 if 'type' in keywords and keywords['type'] in logtype_list:
880 logtype = keywords['type']
882 if not hostname: return ""
883 if not logtype: return "unknown logtype: %s" % logtype
885 short_target_filename = bootman.bootmanager_log_name(hostname)
886 abs_target_filename = os.path.join(config.MONITOR_BOOTMANAGER_LOG, short_target_filename)
887 print "write data: %s" % abs_target_filename
888 util.file.dumpFile(abs_target_filename, log.file.read())
889 bootman.bootmanager_log_action(hostname, short_target_filename, logtype)
892 print "redirecting 3"