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 port_status = widgets.CheckBox(label="Port Status")
59 rpms = widgets.CheckBox(label="RPM")
60 rpmvalue = widgets.TextField(label="RPM Pattern")
62 class QueryForm(widgets.TableForm):
64 <form xmlns:py="http://purl.org/kid/ns#"
71 <div py:for="field in hidden_fields"
72 py:replace="field.display(value_for(field), **params_for(field))"
74 <table border="0" cellspacing="0" cellpadding="2" py:attrs="table_attrs">
75 <tr py:for="i, field in enumerate(fields)"
76 class="${i%2 and 'odd' or 'even'}"
79 <label class="fieldlabel" for="${field.field_id}" py:content="field.label" />
82 <span py:replace="field.display(value_for(field), **params_for(field))" />
83 <span py:if="error_for(field)" class="fielderror" py:content="error_for(field)" />
84 <span py:if="field.help_text" class="fieldhelp" py:content="field.help_text" />
89 <td py:content="submit.display(submit_text)" />
95 def getNodeQueryForm():
96 return QueryForm(fields=NodeQueryFields(), action="query")
98 # make it easier group objects without invoking the elixir auto-write feature.
102 def query_to_dict(query):
103 """ take a url query string and chop it up """
105 query_fields = query.split('&')
106 for f in query_fields:
107 (k,v) = urllib.splitvalue(f)
112 def format_ports(data, pcumodel=None):
117 supported_ports=reboot.model_to_object(pcumodel).supported_ports
119 # ports of a production node
120 supported_ports=[22,80,806]
122 if data and len(data.keys()) > 0 :
123 for port in supported_ports:
125 state = data[str(port)]
129 if state == "filtered":
132 retval.append( (port, state) )
135 retval = [( "Closed/Filtered", "state" )]
137 if filtered_length == len(supported_ports):
138 retval = [( "All Filtered", "state" )]
142 def format_pcu_shortstatus(pcu):
145 if pcu.reboot_trial_status == str(0):
147 elif pcu.reboot_trial_status == "NetDown" or pcu.reboot_trial_status == "Not_Run":
148 status = pcu.reboot_trial_status
154 def prep_pcu_for_display(pcu):
159 agg.loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
161 agg.loginbase = "unknown"
163 agg.pcuhist = HistoryPCURecord.query.get(pcu.plc_pcuid)
165 agg.ports = format_ports(pcu.port_status, pcu.plc_pcu_stats['model'])
166 agg.status = format_pcu_shortstatus(pcu)
168 #print pcu.entry_complete
169 agg.entry_complete_str = pcu.entry_complete
170 #pcu.entry_complete_str += "".join([ f[0] for f in pcu.entry_complete.split() ])
171 if pcu.dns_status == "NOHOSTNAME":
172 agg.dns_short_status = 'NoHost'
173 elif pcu.dns_status == "DNS-OK":
174 agg.dns_short_status = 'Ok'
175 elif pcu.dns_status == "DNS-NOENTRY":
176 agg.dns_short_status = 'NoEntry'
177 elif pcu.dns_status == "NO-DNS-OR-IP":
178 agg.dns_short_status = 'NoHostOrIP'
179 elif pcu.dns_status == "DNS-MISMATCH":
180 agg.dns_short_status = 'Mismatch'
183 class ActionListWidget(widgets.Widget):
186 class NodeWidget(widgets.Widget):
189 def prep_nodehist(node):
192 agg.loginbase = "unknown"
194 agg.loginbase = PlcSite.query.get(node.plc_siteid).plc_site_stats['login_base']
196 agg.loginbase = "exception"
201 def prep_node_for_display(node, pcuhash=None, preppcu=True, asofdate=None):
205 if node.plc_pcuid and preppcu:
207 pcu = pcuhash[node.plc_pcuid]
209 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=node.plc_pcuid)
212 agg.pcu_status = pcu.reboot_trial_status
213 agg.pcu_short_status = format_pcu_shortstatus(pcu)
214 agg.pcu = prep_pcu_for_display(pcu)
216 agg.pcu_short_status = "none"
217 agg.pcu_status = "nodata"
221 agg.pcu_status = "nopcu"
222 agg.pcu_short_status = "none"
226 if node.kernel_version:
227 agg.kernel = node.kernel_version.split()[2]
232 agg.loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
234 agg.loginbase = "unknown"
237 agg.site = HistorySiteRecord.by_loginbase(agg.loginbase)
240 agg.site = agg.site.get_as_of(asofdate)
243 # TODO: need a cleaner fix for this...
244 agg.site = HistorySiteRecord.by_loginbase("pl")
246 agg.site = HistorySiteRecord.by_loginbase("ple")
248 agg.history = HistoryNodeRecord.by_hostname(node.hostname)
250 agg.history = agg.history.get_as_of(asofdate)
252 agg.ports = format_ports(node.port_status)
255 exists = node.plc_node_stats['last_contact']
257 # TODO: this should not assign to the fb object!
258 node.plc_node_stats = {'last_contact' : None}
263 class Root(controllers.RootController, MonitorXmlrpcServer):
264 @expose(template="monitorweb.templates.welcome")
266 # log.debug("Happy TurboGears Controller Responding For Duty")
267 flash("Welcome To MyOps!")
268 return dict(now=time.ctime())
270 @expose(template="monitorweb.templates.nodelist", allow_json=True)
271 def node3(self, filter=None):
272 nhquery = HistoryNodeRecord.query.all()
276 if nh.status == filter:
283 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
286 return dict(now=time.ctime(), query=rquery)
288 def node_query(self, filter):
289 nhquery = HistoryNodeRecord.query.all()
293 if nh.status == filter:
300 fb = FindbadNodeRecord.get_latest_by(hostname=q.hostname)
301 agg = prep_node_for_display(fb)
305 @expose("cheetah:monitorweb.templates.nodelist_plain", as_format="plain",
306 accept_format="text/plain", content_type="text/plain")
307 @expose(template="monitorweb.templates.nodelist", allow_json=True)
308 def node2(self, filter=None):
309 rquery=self.node_query(filter)
310 widget = NodeWidget(template='monitorweb.templates.node_template')
311 return dict(now=time.ctime(), query=rquery, nodewidget=widget)
313 @expose("cheetah:monitorweb.templates.query_plain", as_format="plain",
314 accept_format="text/plain", content_type="text/plain")
315 @expose(template="monitorweb.templates.query", allow_json=True)
316 def query(self, **data):
324 if 'object' in data and data['object'] == "nodes":
325 fbquery = FindbadNodeRecord.get_all_latest()
326 elif 'object' in data and data['object'] == "nodehistory":
327 hostname = data['nodehistory_hostname']
328 data['date_checked'] = 'date_checked'
329 fbrecord = FindbadNodeRecord.get_by(hostname=hostname)
330 fbquery = fbrecord.versions[-500:]
334 # NOTE: reformat some fields.
335 if type(node) is not type(FindbadNodeRecord):
336 agg = node.__dict__.copy()
339 agg.update(agg['plc_node_stats'])
340 if agg['kernel_version']:
341 agg['kernel_version'] = agg['kernel_version'].split()[2]
342 if 'rpmvalue' in data and 'rpms' in data:
344 rpm_list = agg['rpms'].split()
345 rpm_list = filter(lambda x: data['rpmvalue'] in x, rpm_list)
346 agg['rpms'] = " ".join(rpm_list)
354 del fields['rpmvalue']
355 del fields['nodehistory_hostname']
357 return dict(now=time.ctime(), query=query, fields=fields, data=data, queryform=getNodeQueryForm())
359 @expose(template="monitorweb.templates.nodefast", allow_json=True)
360 def node(self, filter=None):
361 nhquery = HistoryNodeRecord.query.all()
365 if nh.status == filter:
366 agg = prep_nodehist(nh)
369 agg = prep_nodehist(nh)
372 return dict(now=time.ctime(), query=query)
374 @expose(template="monitorweb.templates.nodelist")
375 def nodeslow(self, filter='boot'):
376 print "NODE------------------"
377 print "befor-len: ", len( [ i for i in session] )
378 session.flush(); session.clear()
379 print "after-len: ", len( [ i for i in session] )
380 fbquery = FindbadNodeRecord.get_all_latest()
382 filtercount = {'down' : 0, 'boot': 0, 'debug' : 0, 'diagnose' : 0, 'disabled': 0,
383 'neverboot' : 0, 'pending' : 0, 'all' : 0, None : 0}
385 # NOTE: reformat some fields.
386 agg = prep_node_for_display(node)
391 if agg.history.status in ['down', 'offline']:
392 if node.plc_node_stats and node.plc_node_stats['last_contact'] != None:
393 filtercount['down'] += 1
395 filtercount['neverboot'] += 1
396 elif agg.history.status in ['good', 'online']:
397 filtercount['boot'] += 1
398 elif agg.history.status in ['debug', 'monitordebug']:
399 filtercount['debug'] += 1
401 if filtercount.has_key(agg.history.status):
402 filtercount[agg.history.status] += 1
406 if filter == "neverboot":
407 if not node.plc_node_stats or node.plc_node_stats['last_contact'] == None:
409 elif filter == "all":
411 elif filter == agg.history.status:
413 elif filter == 'boot':
417 widget = NodeWidget(template='monitorweb.templates.node_template')
418 return dict(now=time.ctime(), query=query, fc=filtercount, nodewidget=widget)
420 def nodeaction_handler(self, tg_exceptions=None):
421 """Handle any kind of error."""
422 print "NODEACTION_HANDLER------------------"
424 if 'pcuid' in request.params:
425 pcuid = request.params['pcuid']
427 refurl = request.headers.get("Referer",link("pcu"))
430 # TODO: do this more intelligently...
431 uri_fields = urllib.splitquery(refurl)
432 if uri_fields[1] is not None:
433 val = query_to_dict(uri_fields[1])
436 elif 'hostname' in val:
437 pcuid = FindbadNodeRecord.get_latest_by(hostname=val['hostname']).plc_pcuid
443 cherry_trail = cherrypy._cputil.get_object_trail()
444 for i in cherry_trail:
448 return self.pcuview(None, pcuid, **dict(exceptions=tg_exceptions))
450 def nodeaction(self, **data):
451 print "NODEACTION------------------"
452 for item in data.keys():
453 print "%s %s" % ( item, data[item] )
455 if 'hostname' in data:
456 hostname = data['hostname']
458 flash("No hostname given in submitted data")
461 if 'submit' in data or 'type' in data:
463 action = data['submit']
465 action = data['type']
467 flash("No submit action given in submitted data")
470 if action == "Reboot":
471 print "REBOOT: %s" % hostname
472 ret = reboot.reboot_str(str(hostname))
474 if ret: raise RuntimeError("Error using PCU: " + str(ret))
475 flash("Reboot appeared to work. Allow at most 5 minutes. Then run ExternalScan to check current status.")
477 elif action == "ExternalScan":
478 scanapi.externalprobe(str(hostname))
479 flash("External Scan Successful!")
480 elif action == "InternalScan":
481 scanapi.internalprobe(str(hostname))
482 flash("Internal Scan Successful!")
485 raise RuntimeError("Unknown action given")
488 @expose(template="monitorweb.templates.simpleview")
489 def simpleview(self, **data):
490 return self.pre_view(**data)
492 @expose(template="monitorweb.templates.detailview")
493 def detailview(self, **data):
494 return self.pre_view(**data)
496 def pre_view(self, **data):
497 session.flush(); session.clear()
504 # if objtype is not None, then treat 'hostname' or 'loginbase' as a search pattern
519 fields = obj.split(":")
522 obj = fields[1].replace("*", "%")
525 if len(obj.split(".")) > 1 or objtype == "node":
530 if 'loginbase' in data:
531 loginbase = data['loginbase']
533 if 'hostname' in data:
534 hostname = data['hostname']
537 try: pcuid = int(data['pcuid'])
541 try: since = int(since)
545 print "pcuid: %s" % pcuid
546 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
547 loginbase_list += [ PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base'] ]
551 nodes = [ FindbadNodeRecord.get_latest_by(hostname=hostname) ]
553 nodes = FindbadNodeRecord.query.filter(FindbadNodeRecord.hostname.like(hostname))
556 lb = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
557 if lb not in loginbase_list:
558 loginbase_list += [ lb ]
562 loginbase_list = [ loginbase ]
564 loginbase_list = HistorySiteRecord.query.filter(HistorySiteRecord.loginbase.like(loginbase))
565 loginbase_list = [ l.loginbase for l in loginbase_list ]
569 for loginbase in loginbase_list:
570 actions = ActionRecord.query.filter_by(loginbase=loginbase
571 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
572 ).order_by(ActionRecord.date_created.desc())
573 actions_list += [ a for a in actions ]
574 site = HistorySiteRecord.by_loginbase(loginbase)
576 sitequery.append(site)
577 # NOTE: because a single pcu may be assigned to multiple hosts,
578 # track unique pcus by their plc_pcuid, then turn dict into list
580 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
581 # NOTE: reformat some fields.
582 agg = prep_node_for_display(node)
585 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
587 for pcuid_key in pcus:
588 pcuquery += [pcus[pcuid_key]]
590 actionlist_widget = ActionListWidget(template='monitorweb.templates.actionlist_template')
591 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions_list, actionlist_widget=actionlist_widget, since=since, exceptions=exceptions)
594 # TODO: add form validation
595 @expose(template="monitorweb.templates.pcuview")
596 @exception_handler(nodeaction_handler,"isinstance(tg_exceptions,RuntimeError)")
597 def pcuview(self, loginbase=None, pcuid=None, hostname=None, since=20, **data):
598 session.flush(); session.clear()
605 try: since = int(since)
611 if 'submit' in data.keys() or 'type' in data.keys():
612 if hostname: data['hostname'] = hostname
613 self.nodeaction(**data)
614 if 'exceptions' in data:
615 exceptions = data['exceptions']
619 if len(obj.split(".")) > 1: hostname = obj
623 print "pcuid: %s" % pcuid
624 pcu = FindbadPCURecord.get_latest_by(plc_pcuid=pcuid)
625 loginbase = PlcSite.query.get(pcu.plc_pcu_stats['site_id']).plc_site_stats['login_base']
628 node = FindbadNodeRecord.get_latest_by(hostname=hostname)
629 loginbase = PlcSite.query.get(node.plc_node_stats['site_id']).plc_site_stats['login_base']
632 actions = ActionRecord.query.filter_by(loginbase=loginbase
633 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since)
634 ).order_by(ActionRecord.date_created.desc())
635 actions = [ a for a in actions ]
636 sitequery = [HistorySiteRecord.by_loginbase(loginbase)]
638 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
639 # NOTE: reformat some fields.
640 agg = prep_node_for_display(node)
642 if agg.pcu: #.pcu.plc_pcuid: # not None
643 #pcu = FindbadPCURecord.get_latest_by(plc_pcuid=agg.plc_pcuid)
644 #prep_pcu_for_display(pcu)
645 pcus[agg.pcu.pcu.plc_pcuid] = agg.pcu
647 for pcuid_key in pcus:
648 pcuquery += [pcus[pcuid_key]]
650 return dict(sitequery=sitequery, pcuquery=pcuquery, nodequery=nodequery, actions=actions, since=since, exceptions=exceptions)
652 @expose(template="monitorweb.templates.pcuhistory")
653 def pcuhistory(self, pcu_id=None):
656 fbnode = HistoryPCURecord.get_by(plc_pcuid=pcu_id)
657 l = fbnode.versions[-100:]
660 #prep_node_for_display(node)
663 return dict(query=query, pcu_id=pcu_id)
665 @expose(template="monitorweb.templates.nodescanhistory")
666 def nodescanhistory(self, hostname=None, length=10):
667 try: length = int(length)
670 fbnode = FindbadNodeRecord.get_by(hostname=hostname)
671 # TODO: add links for earlier history if desired.
672 l = fbnode.versions[-length:]
676 agg = prep_node_for_display(node, pcuhash=None, preppcu=False, asofdate=node.timestamp)
679 if 'length' in request.params:
680 del request.params['length']
681 return dict(query=query, hostname=hostname, params=request.params)
683 @expose(template="monitorweb.templates.nodehistory")
684 def nodehistory(self, hostname=None):
687 fbnode = HistoryNodeRecord.get_by(hostname=hostname)
688 l = fbnode.versions[-100:]
691 #prep_node_for_display(node)
694 return dict(query=query, hostname=hostname)
696 @expose(template="monitorweb.templates.sitehistory")
697 def sitehistory(self, loginbase=None):
700 fbsite = HistorySiteRecord.get_by(loginbase=loginbase)
701 # TODO: add links for earlier history if desired.
702 l = fbsite.versions[-100:]
706 return dict(query=query, loginbase=loginbase)
709 @expose(template="monitorweb.templates.pculist")
710 def pcu(self, filter='all'):
711 print "PCUVIEW------------------"
712 print "befor-len: ", len( [ i for i in session] )
713 session.flush(); session.clear()
714 print "after-len: ", len( [ i for i in session] )
715 fbquery = FindbadPCURecord.get_all_latest()
717 filtercount = {'ok' : 0, 'NetDown': 0, 'Not_Run' : 0, 'pending' : 0, 'all' : 0}
721 if node.reboot_trial_status == str(0):
722 filtercount['ok'] += 1
723 elif node.reboot_trial_status == 'NetDown' or node.reboot_trial_status == 'Not_Run':
724 filtercount[node.reboot_trial_status] += 1
726 filtercount['pending'] += 1
728 pcuagg = prep_pcu_for_display(node)
733 elif filter == "ok" and node.reboot_trial_status == str(0):
735 elif filter == node.reboot_trial_status:
737 elif filter == "pending":
738 # TODO: look in message logs...
739 if node.reboot_trial_status != str(0) and \
740 node.reboot_trial_status != 'NetDown' and \
741 node.reboot_trial_status != 'Not_Run':
745 return dict(query=query, fc=filtercount)
747 @expose(template="monitorweb.templates.sitelist")
748 def site(self, filter='all'):
749 print "SITE------------------"
750 print "befor-len: ", len( [ i for i in session] )
751 session.flush(); session.clear()
752 print "after-len: ", len( [ i for i in session] )
753 filtercount = {'good' : 0, 'down': 0, 'online':0, 'offline' : 0, 'new' : 0, 'pending' : 0, 'all' : 0}
754 fbquery = HistorySiteRecord.query.all()
758 filtercount['all'] += 1
759 if site.new and site.slices_used == 0 and not site.enabled:
760 filtercount['new'] += 1
761 elif not site.enabled:
762 filtercount['pending'] += 1
763 elif site.status in ['good', 'online']:
764 filtercount['good'] += 1
765 elif site.status in ['down', 'offline']:
766 filtercount['down'] += 1
771 elif filter == 'new' and site.new and site.slices_used == 0 and not site.enabled:
773 elif filter == "pending" and not site.enabled:
775 elif filter == 'good' and site.status in ['good', 'online']:
777 elif filter == 'down' and site.status in ['down', 'offline']:
780 return dict(query=query, fc=filtercount)
781 @expose(template="monitorweb.templates.sitesummary")
782 def sitesummary(self, loginbase="princeton"):
784 for node in FindbadNodeRecord.query.filter_by(loginbase=loginbase):
785 agg = prep_node_for_display(node)
788 return dict(nodequery=nodequery, loginbase=loginbase)
790 @expose(template="monitorweb.templates.summary")
791 def summary(self, since=7):
793 sumdata['nodes'] = {}
794 sumdata['sites'] = {}
797 def summarize(query, type):
799 if o.status not in sumdata[type]:
800 sumdata[type][o.status] = 0
801 sumdata[type][o.status] += 1
803 fbquery = HistorySiteRecord.query.all()
804 summarize(fbquery, 'sites')
805 fbquery = HistoryPCURecord.query.all()
806 summarize(fbquery, 'pcus')
807 fbquery = HistoryNodeRecord.query.all()
808 summarize(fbquery, 'nodes')
810 if 'monitordebug' in sumdata['nodes']:
811 d = sumdata['nodes']['monitordebug']
812 del sumdata['nodes']['monitordebug']
813 sumdata['nodes']['failboot'] = d
815 return dict(sumdata=sumdata, setorder=['good', 'offline', 'down', 'online'])
817 @expose(template="monitorweb.templates.actionsummary")
818 def actionsummary(self, since=7):
819 from monitor.wrapper.emailTxt import mailtxt
821 types = filter(lambda x: 'notice' in x, dir(mailtxt))
824 print mon_metadata.bind
825 if session.bind is None:
826 #TODO: figure out why this value gets cleared out...
827 session.bind = mon_metadata.bind
828 result = session.execute("select distinct(action_type) from actionrecord;")
830 types = [r[0] for r in result]
832 try: since = int(since)
836 acts = ActionRecord.query.filter(ActionRecord.action_type==t
837 ).filter(ActionRecord.date_created >= datetime.now() - timedelta(since))
838 results[t] = acts.count()
839 return dict(results=results)
841 @expose(template="monitorweb.templates.actionlist")
842 def actionlist(self, since=7, action_type=None, loginbase=None):
844 try: since = int(since)
847 acts_query = ActionRecord.query.filter(
848 ActionRecord.date_created >= datetime.now() - timedelta(since)
851 acts_query = acts_query.filter_by(loginbase=loginbase)
854 acts_query = acts_query.filter(ActionRecord.action_type==action_type)
856 acts = acts_query.order_by(ActionRecord.date_created.desc())
858 query = [ a for a in acts ]
860 return dict(actions=query, action_type=action_type, since=since)
863 def upload(self, log, **keywords):
866 logtype_list = ['bm.log', ]
868 if 'hostname' in keywords:
869 hostname = keywords['hostname']
870 if 'type' in keywords and keywords['type'] in logtype_list:
871 logtype = keywords['type']
873 if not hostname: return ""
874 if not logtype: return "unknown logtype: %s" % logtype
876 short_target_filename = bootman.bootmanager_log_name(hostname)
877 abs_target_filename = os.path.join(config.MONITOR_BOOTMANAGER_LOG, short_target_filename)
878 print "write data: %s" % abs_target_filename
879 util.file.dumpFile(abs_target_filename, log.file.read())
880 bootman.bootmanager_log_action(hostname, short_target_filename, logtype)
883 print "redirecting 3"