42 from Tkconstants
import *
43 from tkFileDialog
import *
47 sys.path.insert(0,
"/usr/local/lib/python2.7/site-packages")
48 sys.path.insert(0,
"/prj/lib/python2.7/site-packages")
57 "/prj/share/Laelaps/images",
58 "/prj/share/Laelaps/images/icons",
59 "/prj/share/appkit/images",
60 "/prj/share/appkit/images/icons",
61 "/usr/local/share/Laelaps/images",
62 "/usr/local/share/Laelaps/images/icons" 63 "/usr/local/share/appkit/images",
64 "/usr/local/share/appkit/images/icons" 78 'unknown': fgColors[
'normal'],
79 'running': fgColors[
'ok'],
80 'stopped': fgColors[
'error']
84 reDone = re.compile(
r"done", re.IGNORECASE)
85 reFail = re.compile(
r"fail", re.IGNORECASE)
86 reDoneDone = re.compile(
r"done.*done", re.DOTALL | re.IGNORECASE)
87 reFailDone = re.compile(
r"fail.*done", re.DOTALL | re.IGNORECASE)
88 reRunning = re.compile(
r"\s*is\s*running", re.IGNORECASE)
89 reNotRunning = re.compile(
r"\s*is\s*not\s*running", re.IGNORECASE)
90 reActive = re.compile(
r"\s*active:\s*active.*", re.IGNORECASE)
91 reInactive = re.compile(
r"\s*active:\s*inactive.*", re.IGNORECASE)
98 def os_distribution():
100 return platform.linux_distribution()
102 return (
'n/a',
'n/a',
'n/a')
114 def os_ver_ge(v1, v2):
115 if type(v1)
is 'str':
120 if type(v2)
is 'str':
148 image_paths=imagePath)
150 Frame.__init__(self, master=master, cnf=cnf, **kw)
151 self.master.title(
"Laelaps Init.d Console")
154 self.m_imageLoader.loadImage(
"icons/LaelapsInitIcon.png")
155 if self.
m_icons[
'app_icon']
is not None:
156 self.master.tk.call(
'wm',
'iconphoto', self.master._w,
162 self.grid(row=0, column=0, padx=5, pady=5)
182 'laelaps_bsproxy',
'laelaps_roscore',
'laelaps_control',
183 'laelaps_xbox',
'laelaps_teleop']
185 'laelaps_bsproxy':
'BotSense Proxy Server',
186 'laelaps_roscore':
'ROS Master, Parameter Server, rosout logging node',
187 'laelaps_control':
'Laelaps Control ROS node',
188 'laelaps_xbox':
'HID Xbox360 daemon / ROS node',
189 'laelaps_teleop':
'Laelaps Teleoperation ROS node'}
190 self.
m_lock = threading.Lock()
192 if kw.has_key(
'debug'):
210 self.update_idletasks()
219 self.
m_icons[
'rn_logo'] = self.m_imageLoader.loadImage(
"RNLogo48.png");
221 w[
'image'] = self.
m_icons[
'rn_logo']
226 w.grid(row=0, column=0, sticky=W)
230 w[
'font'] = (
'Helvetica', 16)
231 w[
'text'] =
'Laelaps Init.d Console' 233 w.grid(row=0, column=1, sticky=E+W)
237 self.
m_icons[
'laelaps_logo'] = \
238 self.m_imageLoader.loadImage(
"icon_laelaps_logo.png");
239 if self.
m_icons[
'laelaps_logo']:
240 w[
'image'] = self.
m_icons[
'laelaps_logo']
243 w[
'text'] =
'laelaps' 246 w.grid(row=0, column=2, sticky=E)
253 wframe[
'borderwidth'] = 2
254 wframe[
'relief'] =
'ridge' 255 wframe.grid(row=1, column=0, padx=1, pady=3, sticky=N+W+E)
262 w[
'state'] =
'disabled' 263 w.grid(row=row, column=0, sticky=N+E+W)
270 w[
'state'] =
'disabled' 271 w.grid(row=row, column=0, sticky=N+E+W)
276 w = self.
createButton(wframe,
"Restart",
"icon_resume.png",
278 w[
'state'] =
'disabled' 279 w.grid(row=row, column=0, sticky=N+E+W)
288 wframe[
'borderwidth'] = 2
289 wframe[
'relief'] =
'ridge' 290 wframe.grid(row=1, column=1, padx=1, pady=3, sticky=N+W+E)
295 for text
in [
'Sel',
'Status',
'Service',
'Description']:
297 w = Label(wframe, text=text, foreground=fgColors[
'focus'])
298 w[
'font'] = (
'Helvetica', 10,
"bold")
299 w.grid(row=row, column=col, padx=3, pady=3, stick=W)
315 service[
'sel'] = IntVar(0)
317 w = Checkbutton(wframe, bg=bg, variable=service[
'sel'],
319 w.grid(row=row, column=col, padx=1, pady=3, sticky=W)
323 service[
'status'] = StringVar()
324 service[
'status'].set(
"unknown")
326 w = Label(wframe, bg=bg, textvariable=service[
'status'])
327 w[
'fg'] = statusText[service[
'status'].get()]
329 w.grid(row=row, column=col, padx=1, pady=3, stick=W)
330 service[
'wstatus'] = w
334 w = Label(wframe, bg=bg, anchor=W, justify=LEFT, text=key)
335 w.grid(row=row, column=col, padx=1, pady=3, stick=W+E)
339 w = Label(wframe, bg=bg, anchor=W, justify=LEFT, text=self.
m_svcDesc[key])
340 w.grid(row=row, column=col, padx=1, pady=3, stick=W+E)
358 wframe[
'borderwidth'] = 2
359 wframe[
'relief'] =
'ridge' 360 wframe.grid(row=1, column=2, padx=1, pady=3, sticky=N+W+E)
365 w = self.
createButton(wframe,
"Refresh",
"icon_refresh.png",
367 w.grid(row=row, column=0, sticky=N+E+W)
371 w = self.
createButton(wframe,
"Save",
"icon_floppy.png",
373 w[
'state'] =
'disabled' 374 w.grid(row=row, column=0, sticky=N+E+W)
381 w.grid(row=row, column=0, sticky=N+E+W)
388 wframe[
'borderwidth'] = 2
389 wframe[
'relief'] =
'ridge' 390 wframe.grid(row=2, column=0, columnspan=3, padx=1, pady=3, sticky=N+E+W+S)
392 w = Scrollbar(wframe)
393 w.grid(row=0, column=1, sticky=N+S)
403 self.m_wStatusBar.grid(row=0, column=0, padx=3, pady=3, sticky=N+E+W+S)
406 self.
m_wStatusBar[
'yscrollcommand'] = self.m_wScrollBar.set
421 key = str.lower(text.replace(
"\n",
"_"))
422 self.
m_icons[key] = self.m_imageLoader.loadImage(imagefile)
436 w[
'command'] = command
452 bttns = [
'start',
'stop',
'restart']
462 self.
m_wBttn[key][
'state'] = state
468 self.
showSbInfo(
"Starting selected services...\n")
471 text =
" Starting {0} service".format(key)
473 self.update_idletasks()
483 self.
showSbInfo(
"Stopping selected services...\n")
486 text =
" Stopping {0} service".format(key)
488 self.update_idletasks()
498 self.
showSbInfo(
"Restarting selected services...\n")
501 text =
" Restarting {0} service".format(key)
503 self.update_idletasks()
513 self.
showSbInfo(
"Refreshing status of all services...\n")
515 text =
" Checking {0} status".format(key)
517 self.update_idletasks()
541 idx0 = self.m_wStatusBar.index(INSERT)
542 self.m_wStatusBar.insert(END, text)
543 idx1 = self.m_wStatusBar.index(INSERT)
544 self.m_wStatusBar.tag_add(
"norm", idx0, idx1)
545 self.m_wStatusBar.tag_config(
"norm", foreground=fgColors[
'normal'])
546 self.m_wStatusBar.see(END)
556 idx0 = self.m_wStatusBar.index(INSERT)
557 self.m_wStatusBar.insert(END, text)
558 idx1 = self.m_wStatusBar.index(INSERT)
559 self.m_wStatusBar.tag_add(
"err", idx0, idx1)
560 self.m_wStatusBar.tag_config(
"err", foreground=fgColors[
'error'])
561 self.m_wStatusBar.see(END)
571 idx0 = self.m_wStatusBar.index(INSERT)
572 self.m_wStatusBar.insert(END, text)
573 idx1 = self.m_wStatusBar.index(INSERT)
574 self.m_wStatusBar.tag_add(
"ok", idx0, idx1)
575 self.m_wStatusBar.tag_config(
"ok", foreground=fgColors[
'ok'])
576 self.m_wStatusBar.see(END)
602 if status ==
'running':
605 elif status ==
'stopped':
619 self.
m_service[service][
'status'].set(status)
620 self.
m_service[service][
'wstatus'][
'fg'] = statusText[status]
622 def autoRefresh(self):
643 hasLock = self.m_lock.acquire()
645 rsp = subprocess.check_output([
"service", service,
"start"],
646 stderr=subprocess.STDOUT)
647 except subprocess.CalledProcessError, inst:
648 self.m_lock.release()
650 self.m_lock.release()
651 if os_ver_ge(self.
m_osdist[1], 15.04):
654 if reFail.search(rsp):
668 hasLock = self.m_lock.acquire()
670 rsp = subprocess.check_output([
"service", service,
"stop"],
671 stderr=subprocess.STDOUT)
672 except subprocess.CalledProcessError, inst:
673 self.m_lock.release()
675 self.m_lock.release()
676 if os_ver_ge(self.
m_osdist[1], 15.04):
679 if reFail.search(rsp):
693 hasLock = self.m_lock.acquire()
695 rsp = subprocess.check_output([
"service", service,
"restart"],
696 stderr=subprocess.STDOUT)
697 except subprocess.CalledProcessError, inst:
698 self.m_lock.release()
700 self.m_lock.release()
701 if os_ver_ge(self.
m_osdist[1], 15.04):
704 if reDoneDone.search(rsp):
706 elif reFailDone.search(rsp):
725 hasLock = self.m_lock.acquire()
727 rsp = subprocess.check_output([
"service", service,
"status"],
728 stderr=subprocess.STDOUT)
729 except subprocess.CalledProcessError, inst:
731 self.m_lock.release()
733 if os_ver_ge(self.
m_osdist[1], 15.04):
734 rsp = rsp.split(
"\n")
736 if reActive.search(line):
737 return (
'running', line)
738 elif reInactive.search(line):
739 return (
'stopped', line)
740 return (
'unknown',
"")
742 if reRunning.search(rsp):
743 return (
'running', rsp)
744 elif reNotRunning.search(rsp):
745 return (
'stopped', rsp)
747 return (
'unknown', rsp)
794 print "%s: %s" % (self.
_Argv0, emsg)
796 print "%s: error" % (self.
_Argv0)
797 print "Try '%s --help' for more information." % (self.
_Argv0)
806 Options and arguments: 808 -h, --help : Display this help and exit. 824 self.
_Argv0 = kwargs.get(
'argv0', __file__)
827 kwargs[
'debug'] =
False 831 opts, args = getopt.getopt(argv[1:],
"?h",
833 except getopt.error, msg:
835 for opt, optarg
in opts:
836 if opt
in (
'-h',
'--help',
'-?'):
856 def run(self, argv=None, **kwargs):
871 root.protocol(
'WM_DELETE_WINDOW', root.destroy)
874 self.m_win.mainloop()
882 if __name__ ==
'__main__':
884 sys.exit( app.run() );
def showSbError(self, text)
Show error text on status bar.
Unit test command-line exception class.
def showSbResult(self, text, success)
Show operation result on status bar.
def printUsage(self)
Print Command-Line Usage Message.
def cbStopServices(self)
Stop selected services callback.
def createRightButtons(self)
Create gui right hand side buttons.
def execStatus(self, service)
Execute 'service <service> status' subprocess.
def execStop(self, service)
Execute 'service <service> stop' subprocess.
def createHeading(self)
Create top gui heading.
def initData(self, kw)
Initialize class state data.
def execStart(self, service)
Execute 'service <service> start' subprocess.
Class to handle image loading.
def printUsageErr(self, emsg)
Print usage error.
def refresh(self)
Refresh status of all services.
def cbSave(self)
Save new settings callback.
def setStatus(self, service, status)
Set service status field.
def createCenterPanel(self)
Create gui center panel.
def cbStartServices(self)
Start selected services callback.
msg
error message attribute
def createStatusBar(self)
Create gui multi-line status bar at bottom of gui window.
def createLeftButtons(self)
Create gui left hand side buttons.
def execRestart(self, service)
Execute 'service <service> restart' subprocess.
def cbRestartServices(self)
Restart selected services callback.
def cbSelect(self)
Checkbox change state callback.
def getOptions(self, argv=None, kwargs)
Get command-line options.
def showSbOk(self, text)
Show ok text on status bar.
def run(self, argv=None, kwargs)
Run application.
def clearSelect(self)
Clear all select checkboxes.
def __init__(self)
Constructor.
def createWidgets(self)
Create gui widgets with supporting data and show.
def showSbStatus(self, text, status)
Show service status result on status bar.
def createButton(self, parent, text, imagefile, command, fg='black')
Create button.
Window class supporting application.
def destroy(self)
Destroy window callback.
def __init__(self, msg)
Constructor.
def cbRefreshStatus(self)
Refresh services status callback.
def showSbInfo(self, text)
Show information text on status bar.
def __init__(self, master=None, cnf={}, kw)
Constructor.