Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F2824968
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
14 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/shell/modules/userprefs.py b/shell/modules/userprefs.py
index a686909a9c..f95787e4b2 100644
--- a/shell/modules/userprefs.py
+++ b/shell/modules/userprefs.py
@@ -1,175 +1,178 @@
# Copyright (C) 2008 Dejan Muhamedagic <dmuhamedagic@suse.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
from os import getenv
from singletonmixin import Singleton
from term import TerminalController
from utils import *
class Options(Singleton):
interactive = False
batch = False
regression_tests = False
options = Options.getInstance()
termctrl = TerminalController.getInstance()
def is_program(prog):
return subprocess.call("which %s >/dev/null 2>&1"%prog, shell=True) == 0
def find_program(envvar,*args):
if envvar and getenv(envvar):
return getenv(envvar)
for prog in args:
if is_program(prog):
return prog
+def is_boolean_true(opt):
+ return opt.lower() in ("yes","true","on")
+
class UserPrefs(Singleton):
'''
Keep user preferences here.
'''
dflt_colorscheme = "yellow,normal,cyan,red,green,magenta".split(',')
skill_levels = {"operator":0, "administrator":1, "expert":2}
output_types = ("plain", "color", "uppercase")
check_frequencies = ("always", "on-verify", "never")
check_modes = ("strict", "relaxed")
def __init__(self):
self.skill_level = 2 #TODO: set back to 0?
self.editor = find_program("EDITOR","vim","vi","emacs","nano")
self.pager = find_program("PAGER","less","more","pg")
self.dotty = find_program("","dotty")
if not self.editor:
self.missing("editor")
if not self.pager:
self.missing("pager")
self.crm_user = ""
self.xmlindent = " " # two spaces
# keywords,ids,attribute names,values
self.colorscheme = self.dflt_colorscheme
# plain or color
self.output = ['color',]
# the semantic checks preferences
self.check_frequency = "always"
self.check_mode = "strict"
self.debug = False
self.force = False
self.sort_elems = "yes"
def missing(self,n):
print >> sys.stderr, "could not find any %s on the system"%n
def check_skill_level(self,n):
return self.skill_level >= n
def set_skill_level(self,skill_level):
if skill_level in self.skill_levels:
self.skill_level = self.skill_levels[skill_level]
else:
common_err("no %s skill level"%skill_level)
return False
def get_skill_level(self):
for s in self.skill_levels:
if self.skill_level == self.skill_levels[s]:
return s
def set_editor(self,prog):
if is_program(prog):
self.editor = prog
else:
common_err("program %s does not exist"% prog)
return False
def set_pager(self,prog):
if is_program(prog):
self.pager = prog
else:
common_err("program %s does not exist"% prog)
return False
def set_crm_user(self,user = ''):
self.crm_user = user
def set_output(self,otypes):
l = otypes.split(',')
for otype in l:
if not otype in self.output_types:
common_err("no %s output type" % otype)
return False
self.output = l
def set_colors(self,scheme):
colors = scheme.split(',')
if len(colors) != 6:
common_err("bad color scheme: %s"%scheme)
colors = UserPrefs.dflt_colorscheme
rc = True
for c in colors:
if not termctrl.is_color(c):
common_err("%s is not a recognized color" % c)
rc = False
if rc:
self.colorscheme = colors
else:
self.output.remove("color")
return rc
def is_check_always(self):
'''
Even though the frequency may be set to always, it doesn't
make sense to do that with non-interactive sessions.
'''
return options.interactive and self.check_frequency == "always"
def get_check_rc(self):
'''
If the check mode is set to strict, then on errors we
return 2 which is the code for error. Otherwise, we
pretend that errors are warnings.
'''
return self.check_mode == "strict" and 2 or 1
def set_check_freq(self,frequency):
if frequency not in self.check_frequencies:
common_err("no %s check frequency"%frequency)
return False
self.check_frequency = frequency
def set_check_mode(self,mode):
if mode not in self.check_modes:
common_err("no %s check mode"%mode)
return False
self.check_mode = mode
def set_debug(self):
self.debug = True
def get_debug(self):
return self.debug
def set_force(self):
self.force = True
def get_force(self):
return self.force
def set_sort_elems(self,opt):
self.sort_elems = is_boolean_true(opt) and "yes" or "no"
def get_sort_elems(self):
return self.sort_elems == "yes"
def write_rc(self,f):
print >>f, '%s "%s"' % ("editor",self.editor)
print >>f, '%s "%s"' % ("pager",self.pager)
print >>f, '%s "%s"' % ("user",self.crm_user)
print >>f, '%s "%s"' % ("skill-level",self.get_skill_level())
print >>f, '%s "%s"' % ("output", ','.join(self.output))
print >>f, '%s "%s"' % ("colorscheme", ','.join(self.colorscheme))
print >>f, '%s "%s"' % ("sort-elements", self.sort_elems)
print >>f, '%s "%s"' % ("check-frequency",self.check_frequency)
print >>f, '%s "%s"' % ("check-mode",self.check_mode)
def save_options(self,rc_file):
try: f = open(rc_file,"w")
except IOError,msg:
common_err("open: %s"%msg)
return
print >>f, 'options'
self.write_rc(f)
print >>f, 'end'
f.close()
# vim:ts=4:sw=4:et:
diff --git a/shell/modules/utils.py b/shell/modules/utils.py
index 4d69eb187a..a67cf649d8 100644
--- a/shell/modules/utils.py
+++ b/shell/modules/utils.py
@@ -1,273 +1,271 @@
# Copyright (C) 2008 Dejan Muhamedagic <dmuhamedagic@suse.de>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This software is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
import os
from tempfile import mkstemp
import subprocess
import re
import glob
from userprefs import Options, UserPrefs
from msg import *
def is_program(prog):
return subprocess.call("which %s >/dev/null 2>&1"%prog, shell=True) == 0
def ask(msg):
print_msg = True
while True:
try:
ans = raw_input(msg + ' ')
except EOFError:
ans = 'n'
if not ans or ans[0].lower() not in ('n','y'):
if print_msg:
print "Please answer with y[es] or n[o]"
print_msg = False
else:
return ans[0].lower() == 'y'
def verify_boolean(opt):
return opt.lower() in ("yes","true","on") or \
opt.lower() in ("no","false","off")
-def is_boolean_true(opt):
- return opt.lower() in ("yes","true","on")
def keyword_cmp(string1, string2):
return string1.lower() == string2.lower()
from UserDict import DictMixin
class odict(DictMixin):
def __init__(self, data=None, **kwdata):
self._keys = []
self._data = {}
def __setitem__(self, key, value):
if key not in self._data:
self._keys.append(key)
self._data[key] = value
def __getitem__(self, key):
if key not in self._data:
return self._data[key.lower()]
return self._data[key]
def __delitem__(self, key):
del self._data[key]
self._keys.remove(key)
def keys(self):
return list(self._keys)
def copy(self):
copyDict = odict()
copyDict._data = self._data.copy()
copyDict._keys = self._keys[:]
return copyDict
class olist(list):
def __init__(self, keys):
#print "Init %s" % (repr(keys))
super(olist, self).__init__()
for key in keys:
self.append(key)
self.append(key.upper())
def setup_aliases(obj):
for cmd in obj.cmd_aliases.keys():
for alias in obj.cmd_aliases[cmd]:
if obj.help_table:
obj.help_table[alias] = obj.help_table[cmd]
obj.cmd_table[alias] = obj.cmd_table[cmd]
def os_types_list(path):
l = []
for f in glob.glob(path):
if os.access(f,os.X_OK) and os.path.isfile(f):
a = f.split("/")
l.append(a[-1])
return l
def add_sudo(cmd):
if user_prefs.crm_user:
return "sudo -E -u %s %s"%(user_prefs.crm_user,cmd)
return cmd
def pipe_string(cmd,s):
rc = -1 # command failed
cmd = add_sudo(cmd)
p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE)
try:
p.communicate(s)
p.wait()
rc = p.returncode
except IOError, msg:
common_err(msg)
return rc
def str2tmp(s):
'''
Write the given string to a temporary file. Return the name
of the file.
'''
fd,tmp = mkstemp()
try: f = os.fdopen(fd,"w")
except IOError, msg:
common_err(msg)
return
f.write(s)
f.close()
return tmp
def is_filename_sane(name):
if re.search("['`/#*?$\[\]]",name):
common_err("%s: bad name"%name)
return False
return True
def is_name_sane(name):
if re.search("[']",name):
common_err("%s: bad name"%name)
return False
return True
def is_value_sane(name):
if re.search("[']",name):
common_err("%s: bad name"%name)
return False
return True
def ext_cmd(cmd):
if options.regression_tests:
print ".EXT", cmd
return subprocess.call(add_sudo(cmd), shell=True)
def get_stdout(cmd, stderr_on = True):
'''
Run a cmd, return stdin output.
stderr_on controls whether to show output which comes on stderr.
'''
if stderr_on:
stderr = None
else:
stderr = subprocess.PIPE
proc = subprocess.Popen(cmd, shell = True, \
stdout = subprocess.PIPE, stderr = stderr)
outp = proc.communicate()[0]
proc.wait()
outp = outp.strip()
return outp
def stdout2list(cmd, stderr_on = True):
'''
Run a cmd, fetch output, return it as a list of lines.
stderr_on controls whether to show output which comes on stderr.
'''
s = get_stdout(add_sudo(cmd), stderr_on)
return s.split('\n')
def is_id_valid(id):
"""
Verify that the id follows the definition:
http://www.w3.org/TR/1999/REC-xml-names-19990114/#ns-qualnames
"""
if not id:
return False
id_re = "^[A-Za-z_][\w._-]*$"
return re.match(id_re,id)
def check_filename(fname):
"""
Verify that the string is a filename.
"""
fname_re = "^[^/]+$"
return re.match(fname_re,id)
def is_process(s):
proc = subprocess.Popen("ps -e -o pid,command | grep -qs '%s'" % s, \
shell=True, stdout=subprocess.PIPE)
proc.wait()
return proc.returncode == 0
def cluster_stack():
if is_process("heartbeat:.[m]aster"):
return "heartbeat"
elif is_process("[a]isexec"):
return "openais"
return ""
def edit_file(fname):
'Edit a file.'
if not fname:
return
if not user_prefs.editor:
return
return ext_cmd("%s %s" % (user_prefs.editor,fname))
def page_string(s):
'Write string through a pager.'
if not s:
return
w,h = get_winsize()
if s.count('\n') <= h:
print s
elif not user_prefs.pager or not options.interactive:
print s
else:
opts = ""
if user_prefs.pager == "less":
opts = "-R"
pipe_string("%s %s" % (user_prefs.pager,opts), s)
def get_winsize():
try:
import curses
curses.setupterm()
w = curses.tigetnum('cols')
h = curses.tigetnum('lines')
except:
try:
w = os.environ['COLS']
h = os.environ['LINES']
except:
w = 80; h = 25
return w,h
def multicolumn(l):
'''
A ls-like representation of a list of strings.
A naive approach.
'''
min_gap = 2
w,h = get_winsize()
max_len = 8
for s in l:
if len(s) > max_len:
max_len = len(s)
cols = w/(max_len + min_gap) # approx.
col_len = w/cols
for i in range(len(l)/cols + 1):
s = ''
for j in range(i*cols,(i+1)*cols):
if not j < len(l):
break
if not s:
s = "%-*s" % (col_len,l[j])
elif (j+1)%cols == 0:
s = "%s%s" % (s,l[j])
else:
s = "%s%-*s" % (s,col_len,l[j])
if s:
print s
def find_value(pl,name):
for n,v in pl:
if n == name:
return v
return None
user_prefs = UserPrefs.getInstance()
options = Options.getInstance()
# vim:ts=4:sw=4:et:
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Jan 25, 11:07 AM (1 d, 7 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1322268
Default Alt Text
(14 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment