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#"
72 <div py:for="field in hidden_fields"
73 py:replace="field.display(value_for(field), **params_for(field))"
75 <table border="0" cellspacing="0" cellpadding="2" py:attrs="table_attrs">
76 <tr py:for="i, field in enumerate(fields)"
77 class="${i%2 and 'odd' or 'even'}"
80 <label class="fieldlabel" for="${field.field_id}" py:content="field.label" />
83 <span py:replace="field.display(value_for(field), **params_for(field))" />
84 <span py:if="error_for(field)" class="fielderror" py:content="error_for(field)" />
85 <span py:if="field.help_text" class="fieldhelp" py:content="field.help_text" />
90 <td py:content="submit.display(submit_text)" />
96 def getNodeQueryForm():
97 return QueryForm(fields=NodeQueryFields(), action="query")
99 # make it easier group objects without invoking the elixir auto-write feature.
100 class aggregate: pass
103 def query_to_dict(query):
104 """ take a url query string and chop it up """
106 query_fields = query.split('&')
107 for f in query_fields:
108 (k,v) = urllib.splitvalue(f)
113 def format_ports(data, pcumodel=None):
118 supported_ports=reboot.model_to_object(pcumodel).supported_ports
120 # ports of a production node
121 supported_ports=[22,80,806]
123 if data and len(data.keys()) > 0 :
124 for port in supported_ports:
126 state = data[str(port)]
130 if state == "filtered":
133 retval.append( (port, state) )
136 retval = [( "Closed/Filtered", "state" )]
138 if filtered_length == len(supported_ports):
139 retval = [( "All Filtered", "state" )]
143 def format_pcu_shortstatus(pcu):
146 if pcu.reboot_trial_status == str(0):
148 elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
149 status = pcu.reboot_trial_status
155 def prep_pcu_for_display(pcu):
160 agg.loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
162 agg.loginbase = "unknown"
164 agg.pcuhist = HistoryPCURecord.query.get(pcu.plc_pcuid)
166 agg.ports = format_ports(pcu.port_status, pcu.plc_pcu_stats['model'])
167 agg.status = format_pcu_shortstatus(pcu)
169 #print pcu.entry_complete
170 agg.entry_complete_str = pcu.entry_complete
171 #pcu.entry_complete_str += "".join([ f[0] for f in pcu.entry_complete.split() ])
172 if pcu.dns_status == "NOHOSTNAME":
173 agg.dns_short_status = 'NoHost'
174 elif pcu.dns_status == "DNS-OK":
175 agg.dns_short_status = 'Ok'
176 elif pcu.dns_status == "DNS-NOENTRY":
177 agg.dns_short_status = 'NoEntry'
178 elif pcu.dns_status == "NO-DNS-OR-IP":
179 agg.dns_short_status = 'NoHostOrIP'
180 elif pcu.dns_status == "DNS-MISMATCH":
181 agg.dns_short_status = 'Mismatch'
184 class ActionListWidget(widgets.Widget):
187 class NodeWidget(widgets.Widget):
190 def prep_nodehist(node):
193 agg.loginbase = "unknown"
195 agg.loginbase = PlcSite.query.get(node.plc_siteid).plc_site_stats['login_base']
197 agg.loginbase = "exception"
202 def prep_node_for_display(node, pcuhash=None, preppcu=True, asofdate=None):
206 if node.plc_pcuid and preppcu:
208 pcu = pcuhash[node.plc_pcuid]
210 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid)
213 agg.pcu_status = pcu.reboot_trial_status
214 agg.pcu_short_status = format_pcu_shortstatus(pcu)
215 agg.pcu = prep_pcu_for_display(pcu)
217 agg.pcu_short_status = "none"
218 agg.pcu_status = "nodata"
222 agg.pcu_status = "nopcu"
223 agg.pcu_short_status = "none"
227 if node.kernel_version:
228 agg.kernel = node.kernel_version.split()[2]
233 agg.loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
235 agg.loginbase = "unknown"
238 agg.site = HistorySiteRecord.by_loginbase(agg.loginbase)
241 agg.site = agg.site.get_as_of(asofdate)
244 # TODO: need a cleaner fix for this...
245 agg.site = HistorySiteRecord.by_loginbase("pl")
247 agg.site = HistorySiteRecord.by_loginbase("ple")
249 agg.history = HistoryNodeRecord.by_hostname(node.hostname)
251 agg.history = agg.history.get_as_of(asofdate)
253 agg.ports = format_ports(node.port_status)
256 exists = node.plc_node_stats['last_contact']
258 # TODO: this should not assign to the fb object!
259 node.plc_node_stats = {'last_contact' : None}
264 class Root(controllers.RootController, MonitorXmlrpcServer):
265 @expose(template="monitorweb.templates.welcome")
267 # log.debug("Happy TurboGears Controller Responding For Duty")
268 flash("Welcome To MyOps!")
269 return dict(now=time.ctime())
271 @expose(template="monitorweb.templates.nodelist", allow_json=True)
272 def node3(self, filter=None):
273 nhquery = HistoryNodeRecord.query.all()
277 if nh.status == filter:
284 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
287 return dict(now=time.ctime(), query=rquery)
289 def node_query(self, filter):
290 nhquery = HistoryNodeRecord.query.all()
294 if nh.status == filter:
301 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
302 agg = prep_node_for_display(fb)
306 @expose("cheetah:monitorweb.templates.nodelist_plain", as_format="plain",
307 accept_format="text/plain", content_type="text/plain")
308 @expose(template="monitorweb.templates.nodelist", allow_json=True)
309 def node2(self, filter=None):
310 rquery=self.node_query(filter)
311 widget = NodeWidget(template='monitorweb.templates.node_template')
312 return dict(now=time.ctime(), query=rquery, nodewidget=widget)
314 @expose("cheetah:monitorweb.templates.query_plain", as_format="plain",
315 accept_format="text/plain", content_type="text/plain")
316 @expose(template="monitorweb.templates.query", allow_json=True)
317 def query(self, **data):
325 if 'object' in data and data['object'] == "nodes":
326 fbquery = FindbadNodeRecord.get_all_latest()
327 elif 'object' in data and data['object'] == "nodehistory":
328 hostname = data['nodehistory_hostname']
329 data['date_checked'] = 'date_checked'
330 fbrecord = FindbadNodeRecord.get_by(hostname=hostname)
331 fbquery = fbrecord.versions[-500:]
335 # NOTE: reformat some fields.
336 if type(node) is not type(FindbadNodeRecord):
337 agg = node.__dict__.copy()
340 agg.update(agg['plc_node_stats'])
341 if agg['kernel_version']:
342 agg['kernel_version'] = agg['kernel_version'].split()[2]
343 if 'traceroute' in data and agg['traceroute']:
344 agg['traceroute'] = "<pre>" + agg['traceroute'] + "</pre>"
345 if 'rpmvalue' in data and 'rpms' in data:
347 rpm_list = agg['rpms'].split()
348 rpm_list = filter(lambda x: data['rpmvalue'] in x, rpm_list)
349 agg['rpms'] = " ".join(rpm_list)
357 del fields['rpmvalue']
358 del fields['nodehistory_hostname']
360 return dict(now=time.ctime(), query=query, fields=fields, data=data, queryform=getNodeQueryForm())
362 @expose(template="monitorweb.templates.nodefast", allow_json=True)
363 def node(self, filter=None):
364 nhquery = HistoryNodeRecord.query.all()
368 if nh.status == filter:
369 agg = prep_nodehist(nh)
372 agg = prep_nodehist(nh)
375 return dict(now=time.ctime(), query=query)
377 @expose(template="monitorweb.templates.nodelist")
378 def nodeslow(self, filter='boot'):
379 print "NODE------------------"
380 print "befor-len: ", len( [ i for i in session] )
381 session.flush(); session.clear()
382 print "after-len: ", len( [ i for i in session] )
383 fbquery = FindbadNodeRecord.get_all_latest()
385 filtercount = {'down' : 0, 'boot': 0, 'debug' : 0, 'diagnose' : 0, 'disabled': 0,
386 'neverboot' : 0, 'pending' : 0, 'all' : 0, None : 0}
388 # NOTE: reformat some fields.
389 agg = prep_node_for_display(node)
394 if agg.history.status in ['down', 'offline']:
395 if node.plc_node_stats and node.plc_node_stats['last_contact'] != None:
396 filtercount['down'] += 1
398 filtercount['neverboot'] += 1
399 elif agg.history.status in ['good', 'online']:
400 filtercount['boot'] += 1
401 elif agg.history.status in ['debug', 'monitordebug']:
402 filtercount['debug'] += 1
404 if filtercount.has_key(agg.history.status):
405 filtercount[agg.history.status] += 1
409 if filter == "neverboot":
410 if not node.plc_node_stats or node.plc_node_stats['last_contact'] == None:
412 elif filter == "all":
414 elif filter == agg.history.status:
416 elif filter == 'boot':
420 widget = NodeWidget(template='monitorweb.templates.node_template')
421 return dict(now=time.ctime(), query=query, fc=filtercount, nodewidget=widget)
423 def nodeaction_handler(self, tg_exceptions=None):
424 """Handle any kind of error."""
425 print "NODEACTION_HANDLER------------------"
427 if 'pcuid' in request.params:
428 pcuid = request.params['pcuid']
430 refurl = request.headers.get("Referer",link("pcu"))
433 # TODO: do this more intelligently...
434 uri_fields = urllib.splitquery(refurl)
435 if uri_fields[1] is not None:
436 val = query_to_dict(uri_fields[1])
439 elif 'hostname' in val:
440 pcuid = FindbadNodeRecord.get_latest_by(hostname=val['hostname']).plc_pcuid
446 cherry_trail = cherrypy._cputil.get_object_trail()
447 for i in cherry_trail:
451 return self.pcuview(None, pcuid, **dict(exceptions=tg_exceptions))
453 def nodeaction(self, **data):
454 print "NODEACTION------------------"
455 for item in data.keys():
456 print "%s %s" % ( item, data[item] )
458 if 'hostname' in data:
459 hostname = data['hostname']
461 flash("No hostname given in submitted data")
464 if 'submit' in data or 'type' in data:
466 action = data['submit']
468 action = data['type']
470 flash("No submit action given in submitted data")
473 if action == "Reboot":
474 print "REBOOT: %s" % hostname
475 ret = reboot.reboot_str(str(hostname))
477 if ret: raise RuntimeError("Error using PCU: " + str(ret))
478 flash("Reboot appeared to work. Allow at most 5 minutes. Then run ExternalScan to check current status.")
480 elif action == "ExternalScan":
481 scanapi.externalprobe(str(hostname))
482 flash("External Scan Successful!")
483 elif action == "InternalScan":
484 scanapi.internalprobe(str(hostname))
485 flash("Internal Scan Successful!")
488 raise RuntimeError("Unknown action given")
491 @expose(template="monitorweb.templates.simpleview")
492 def simpleview(self, **data):
493 return self.pre_view(**data)
495 @expose(template="monitorweb.templates.simpleview")
496 def pcuview(self, **data):
497 return self.pre_view(**data)
499 @expose(template="monitorweb.templates.detailview")
500 def detailview(self, **data):
501 return self.pre_view(**data)
504 def pre_view(self, **data):
505 session.flush(); session.clear()
512 # if objtype is not None, then treat 'hostname' or 'loginbase' as a search pattern
527 fields = obj.split(":")
530 obj = fields[1].replace("*", "%")
533 if len(obj.split(".")) > 1 or objtype == "node":
538 if 'loginbase' in data:
539 loginbase = data['loginbase']
541 if 'hostname' in data:
542 hostname = data['hostname']
545 try: pcuid = int(data['pcuid'])
549 try: since = int(since)
553 print "pcuid: %s" % pcuid
554 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
555 loginbase_list += [ PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base'] ]
559 nodes = [ FindbadNodeRecord.get_latest_by(hostname=hostname) ]
561 nodes = FindbadNodeRecord.query.filter(FindbadNodeRecord.hostname.like(hostname))
564 lb = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
565 if lb not in loginbase_list:
566 loginbase_list += [ lb ]
570 loginbase_list = [ loginbase ]
572 loginbase_list = HistorySiteRecord.query.filter(HistorySiteRecord.loginbase.like(loginbase))
573 loginbase_list = [ l.loginbase for l in loginbase_list ]
577 for loginbase in loginbase_list:
578 actions = ActionRecord.query.filter_by(loginbase=loginbase
579 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
580 ).order_by(ActionRecord.date_created.desc())
581 actions_list += [ a for a in actions ]
582 site = HistorySiteRecord.by_loginbase(loginbase)
584 sitequery.append(site)
585 # NOTE: because a single pcu may be assigned to multiple hosts,
586 # track unique pcus by their plc_pcuid, then turn dict into list
588 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
589 # NOTE: reformat some fields.
590 agg = prep_node_for_display(node)
593 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
595 for pcuid_key in pcus:
596 pcuquery += [pcus[pcuid_key]]
598 actionlist_widget = ActionListWidget(template='monitorweb.templates.actionlist_template')
599 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions_list, actionlist_widget=actionlist_widget, since=since, exceptions=exceptions)
602 # TODO: add form validation
603 @expose(template="monitorweb.templates.pcuview")
604 @exception_handler(nodeaction_handler,"isinstance(tg_exceptions,RuntimeError)")
605 def pcuviewold(self, loginbase=None, pcuid=None, hostname=None, since=20, **data):
606 session.flush(); session.clear()
613 try: since = int(since)
619 if 'submit' in data.keys() or 'type' in data.keys():
620 if hostname: data['hostname'] = hostname
621 self.nodeaction(**data)
622 if 'exceptions' in data:
623 exceptions = data['exceptions']
627 if len(obj.split(".")) > 1: hostname = obj
631 print "pcuid: %s" % pcuid
632 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
633 loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
636 node = FindbadNodeRecord.get_latest_by(hostname=hostname)
637 loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
640 actions = ActionRecord.query.filter_by(loginbase=loginbase
641 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
642 ).order_by(ActionRecord.date_created.desc())
643 actions = [ a for a in actions ]
644 sitequery = [HistorySiteRecord.by_loginbase(loginbase)]
646 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
647 # NOTE: reformat some fields.
648 agg = prep_node_for_display(node)
650 if agg.pcu: #.pcu.plc_pcuid: # not None
651 #pcu = FindbadPCURecord.get_latest_by(plc_pcuid=agg.plc_pcuid)
652 #prep_pcu_for_display(pcu)
653 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
655 for pcuid_key in pcus:
656 pcuquery += [pcus[pcuid_key]]
658 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions, since=since, exceptions=exceptions)
660 @expose(template="monitorweb.templates.pcuhistory")
661 def pcuhistory(self, pcu_id=None):
664 fbnode = HistoryPCURecord.get_by(plc_pcuid=pcu_id)
665 l = fbnode.versions[-100:]
668 #prep_node_for_display(node)
671 return dict(query=query, pcu_id=pcu_id)
673 @expose(template="monitorweb.templates.nodescanhistory")
674 def nodescanhistory(self, hostname=None, length=10):
675 try: length = int(length)
678 fbnode = FindbadNodeRecord.get_by(hostname=hostname)
679 # TODO: add links for earlier history if desired.
680 l = fbnode.versions[-length:]
684 agg = prep_node_for_display(node, pcuhash=None, preppcu=False, asofdate=node.timestamp)
687 if 'length' in request.params:
688 del request.params['length']
689 return dict(query=query, hostname=hostname, params=request.params)
691 @expose(template="monitorweb.templates.nodehistory")
692 def nodehistory(self, hostname=None):
695 fbnode = HistoryNodeRecord.get_by(hostname=hostname)
696 l = fbnode.versions[-100:]
699 #prep_node_for_display(node)
702 return dict(query=query, hostname=hostname)
704 @expose(template="monitorweb.templates.sitehistory")
705 def sitehistory(self, loginbase=None):
708 fbsite = HistorySiteRecord.get_by(loginbase=loginbase)
709 # TODO: add links for earlier history if desired.
710 l = fbsite.versions[-100:]
714 return dict(query=query, loginbase=loginbase)
717 @expose(template="monitorweb.templates.pculist")
718 def pcu(self, filter='all'):
719 print "PCUVIEW------------------"
720 print "befor-len: ", len( [ i for i in session] )
721 session.flush(); session.clear()
722 print "after-len: ", len( [ i for i in session] )
723 fbquery = FindbadPCURecord.get_all_latest()
725 filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
729 if node.reboot_trial_status == str(0):
730 filtercount['ok'] += 1
731 elif node.reboot_trial_status == 'NetDown' or node.reboot_trial_status == 'Not_Run':
732 filtercount[node.reboot_trial_status] += 1
734 filtercount['pending'] += 1
736 pcuagg = prep_pcu_for_display(node)
741 elif filter == "ok" and node.reboot_trial_status == str(0):
743 elif filter == node.reboot_trial_status:
745 elif filter == "pending":
746 # TODO: look in message logs...
747 if node.reboot_trial_status != str(0) and \
748 node.reboot_trial_status != 'NetDown' and \
749 node.reboot_trial_status != 'Not_Run':
753 return dict(query=query, fc=filtercount)
755 @expose(template="monitorweb.templates.sitelist")
756 def site(self, filter='all'):
757 print "SITE------------------"
758 print "befor-len: ", len( [ i for i in session] )
759 session.flush(); session.clear()
760 print "after-len: ", len( [ i for i in session] )
761 filtercount = {'good' : 0, 'down': 0, 'online':0, 'offline' : 0, 'new' : 0, 'pending' : 0, 'all' : 0}
762 fbquery = HistorySiteRecord.query.all()
766 filtercount['all'] += 1
767 if site.new and site.slices_used == 0 and not site.enabled:
768 filtercount['new'] += 1
769 elif not site.enabled:
770 filtercount['pending'] += 1
771 elif site.status in ['good', 'online']:
772 filtercount['good'] += 1
773 elif site.status in ['down', 'offline']:
774 filtercount['down'] += 1
779 elif filter == 'new' and site.new and site.slices_used == 0 and not site.enabled:
781 elif filter == "pending" and not site.enabled:
783 elif filter == 'good' and site.status in ['good', 'online']:
785 elif filter == 'down' and site.status in ['down', 'offline']:
788 return dict(query=query, fc=filtercount)
789 @expose(template="monitorweb.templates.sitesummary")
790 def sitesummary(self, loginbase="princeton"):
792 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
793 agg = prep_node_for_display(node)
796 return dict(nodequery=nodequery, loginbase=loginbase)
798 @expose(template="monitorweb.templates.summary")
799 def summary(self, since=7):
801 sumdata['nodes'] = {}
802 sumdata['sites'] = {}
805 def summarize(query, type):
807 if o.status not in sumdata[type]:
808 sumdata[type][o.status] = 0
809 sumdata[type][o.status] += 1
811 fbquery = HistorySiteRecord.query.all()
812 summarize(fbquery, 'sites')
813 fbquery = HistoryPCURecord.query.all()
814 summarize(fbquery, 'pcus')
815 fbquery = HistoryNodeRecord.query.all()
816 summarize(fbquery, 'nodes')
818 if 'monitordebug' in sumdata['nodes']:
819 d = sumdata['nodes']['monitordebug']
820 del sumdata['nodes']['monitordebug']
821 sumdata['nodes']['failboot'] = d
823 return dict(sumdata=sumdata, setorder=['good', 'offline', 'down', 'online'])
825 @expose(template="monitorweb.templates.actionsummary")
826 def actionsummary(self, since=7):
827 from monitor.wrapper.emailTxt import mailtxt
829 types = filter(lambda x: 'notice' in x, dir(mailtxt))
832 print mon_metadata.bind
833 if session.bind is None:
834 #TODO: figure out why this value gets cleared out...
835 session.bind = mon_metadata.bind
836 result = session.execute("select distinct(action_type) from actionrecord;")
838 types = [r[0] for r in result]
840 try: since = int(since)
844 acts = ActionRecord.query.filter(ActionRecord.action_type==t
845 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since))
846 results[t] = acts.count()
847 return dict(results=results)
849 @expose(template="monitorweb.templates.actionlist")
850 def actionlist(self, since=7, action_type=None, loginbase=None):
852 try: since = int(since)
855 acts_query = ActionRecord.query.filter(
856 ActionRecord.date_created >= datetime.now() - timedelta(since)
859 acts_query = acts_query.filter_by(loginbase=loginbase)
862 acts_query = acts_query.filter(ActionRecord.action_type==action_type)
864 acts = acts_query.order_by(ActionRecord.date_created.desc())
866 query = [ a for a in acts ]
868 return dict(actions=query, action_type=action_type, since=since)
871 def upload(self, log, **keywords):
874 logtype_list = ['bm.log', ]
876 if 'hostname' in keywords:
877 hostname = keywords['hostname']
878 if 'type' in keywords and keywords['type'] in logtype_list:
879 logtype = keywords['type']
881 if not hostname: return ""
882 if not logtype: return "unknown logtype: %s" % logtype
884 short_target_filename = bootman.bootmanager_log_name(hostname)
885 abs_target_filename = os.path.join(config.MONITOR_BOOTMANAGER_LOG, short_target_filename)
886 print "write data: %s" % abs_target_filename
887 util.file.dumpFile(abs_target_filename, log.file.read())
888 bootman.bootmanager_log_action(hostname, short_target_filename, logtype)
891 print "redirecting 3"