initial commit after bringing over cleaned up code and testing some examples
This commit is contained in:
parent
c4858e6e0d
commit
00f4ebf5a9
93 changed files with 15189 additions and 13083 deletions
|
@ -1,31 +1,37 @@
|
|||
#
|
||||
# CORE
|
||||
# Copyright (c)2010-2012 the Boeing Company.
|
||||
# See the LICENSE file included in this distribution.
|
||||
#
|
||||
# authors: Tom Goff <thomas.goff@boeing.com>
|
||||
# Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
|
||||
#
|
||||
'''
|
||||
utils.py: miscellaneous utility functions, wrappers around some subprocess
|
||||
procedures.
|
||||
'''
|
||||
"""
|
||||
Miscellaneous utility functions, wrappers around some subprocess procedures.
|
||||
"""
|
||||
|
||||
import ast
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
import subprocess, os, ast
|
||||
import fcntl
|
||||
|
||||
from core.misc import log
|
||||
|
||||
logger = log.get_logger(__name__)
|
||||
|
||||
|
||||
def closeonexec(fd):
|
||||
fdflags = fcntl.fcntl(fd, fcntl.F_GETFD)
|
||||
fcntl.fcntl(fd, fcntl.F_SETFD, fdflags | fcntl.FD_CLOEXEC)
|
||||
|
||||
def checkexec(execlist):
|
||||
for bin in execlist:
|
||||
if which(bin) is None:
|
||||
raise EnvironmentError, "executable not found: %s" % bin
|
||||
|
||||
def check_executables(executables):
|
||||
for executable in executables:
|
||||
if not (os.path.isfile(executable) and os.access(executable, os.X_OK)):
|
||||
raise EnvironmentError("executable not found: %s" % executable)
|
||||
|
||||
|
||||
def which(program):
|
||||
''' From: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
|
||||
'''
|
||||
"""
|
||||
From: http://stackoverflow.com/questions/377017/test-if-executable-exists-in-python
|
||||
|
||||
:param str program: program to check for
|
||||
:return: path if it exists, none otherwise
|
||||
"""
|
||||
|
||||
def is_exe(fpath):
|
||||
return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
|
||||
|
||||
|
@ -42,82 +48,91 @@ def which(program):
|
|||
|
||||
return None
|
||||
|
||||
|
||||
def ensurepath(pathlist):
|
||||
searchpath = os.environ["PATH"].split(":")
|
||||
for p in set(pathlist):
|
||||
if p not in searchpath:
|
||||
os.environ["PATH"] += ":" + p
|
||||
|
||||
|
||||
def maketuple(obj):
|
||||
if hasattr(obj, "__iter__"):
|
||||
return tuple(obj)
|
||||
else:
|
||||
return (obj,)
|
||||
|
||||
return obj,
|
||||
|
||||
|
||||
def maketuplefromstr(s, type):
|
||||
s.replace('\\', '\\\\')
|
||||
return ast.literal_eval(s)
|
||||
#return tuple(type(i) for i in s[1:-1].split(','))
|
||||
#r = ()
|
||||
#for i in s.strip("()").split(','):
|
||||
# return tuple(type(i) for i in s[1:-1].split(','))
|
||||
# r = ()
|
||||
# for i in s.strip("()").split(','):
|
||||
# r += (i.strip("' "), )
|
||||
# chop empty last element from "('a',)" strings
|
||||
#if r[-1] == '':
|
||||
# if r[-1] == '':
|
||||
# r = r[:-1]
|
||||
#return r
|
||||
# return r
|
||||
|
||||
def call(*args, **kwds):
|
||||
return subprocess.call(*args, **kwds)
|
||||
|
||||
def mutecall(*args, **kwds):
|
||||
kwds["stdout"] = open(os.devnull, "w")
|
||||
kwds["stderr"] = subprocess.STDOUT
|
||||
return call(*args, **kwds)
|
||||
return subprocess.call(*args, **kwds)
|
||||
|
||||
def check_call(*args, **kwds):
|
||||
return subprocess.check_call(*args, **kwds)
|
||||
|
||||
def mutecheck_call(*args, **kwds):
|
||||
kwds["stdout"] = open(os.devnull, "w")
|
||||
kwds["stderr"] = subprocess.STDOUT
|
||||
return subprocess.check_call(*args, **kwds)
|
||||
|
||||
|
||||
def spawn(*args, **kwds):
|
||||
return subprocess.Popen(*args, **kwds).pid
|
||||
|
||||
|
||||
def mutespawn(*args, **kwds):
|
||||
kwds["stdout"] = open(os.devnull, "w")
|
||||
kwds["stderr"] = subprocess.STDOUT
|
||||
return subprocess.Popen(*args, **kwds).pid
|
||||
|
||||
|
||||
def detachinit():
|
||||
if os.fork():
|
||||
os._exit(0) # parent exits
|
||||
# parent exits
|
||||
os._exit(0)
|
||||
os.setsid()
|
||||
|
||||
|
||||
def detach(*args, **kwds):
|
||||
kwds["preexec_fn"] = detachinit
|
||||
return subprocess.Popen(*args, **kwds).pid
|
||||
|
||||
|
||||
def mutedetach(*args, **kwds):
|
||||
kwds["preexec_fn"] = detachinit
|
||||
kwds["stdout"] = open(os.devnull, "w")
|
||||
kwds["stderr"] = subprocess.STDOUT
|
||||
return subprocess.Popen(*args, **kwds).pid
|
||||
|
||||
def cmdresult(args):
|
||||
''' Execute a command on the host and return a tuple containing the
|
||||
exit status and result string. stderr output
|
||||
is folded into the stdout result string.
|
||||
'''
|
||||
cmdid = subprocess.Popen(args, stdin = open(os.devnull, 'r'),
|
||||
stdout = subprocess.PIPE,
|
||||
stderr = subprocess.STDOUT)
|
||||
result, err = cmdid.communicate() # err will always be None
|
||||
status = cmdid.wait()
|
||||
return (status, result)
|
||||
|
||||
def hexdump(s, bytes_per_word = 2, words_per_line = 8):
|
||||
def cmdresult(args):
|
||||
"""
|
||||
Execute a command on the host and return a tuple containing the
|
||||
exit status and result string. stderr output
|
||||
is folded into the stdout result string.
|
||||
"""
|
||||
cmdid = subprocess.Popen(args, stdin=open(os.devnull, 'r'),
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT)
|
||||
# err will always be None
|
||||
result, err = cmdid.communicate()
|
||||
status = cmdid.wait()
|
||||
return status, result
|
||||
|
||||
|
||||
def hexdump(s, bytes_per_word=2, words_per_line=8):
|
||||
dump = ""
|
||||
count = 0
|
||||
bytes = bytes_per_word * words_per_line
|
||||
|
@ -132,19 +147,24 @@ def hexdump(s, bytes_per_word = 2, words_per_line = 8):
|
|||
count += len(line)
|
||||
return dump[:-1]
|
||||
|
||||
|
||||
def filemunge(pathname, header, text):
|
||||
''' Insert text at the end of a file, surrounded by header comments.
|
||||
'''
|
||||
filedemunge(pathname, header) # prevent duplicates
|
||||
"""
|
||||
Insert text at the end of a file, surrounded by header comments.
|
||||
"""
|
||||
# prevent duplicates
|
||||
filedemunge(pathname, header)
|
||||
f = open(pathname, 'a')
|
||||
f.write("# BEGIN %s\n" % header)
|
||||
f.write(text)
|
||||
f.write("# END %s\n" % header)
|
||||
f.close()
|
||||
|
||||
|
||||
def filedemunge(pathname, header):
|
||||
''' Remove text that was inserted in a file surrounded by header comments.
|
||||
'''
|
||||
"""
|
||||
Remove text that was inserted in a file surrounded by header comments.
|
||||
"""
|
||||
f = open(pathname, 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
@ -161,10 +181,12 @@ def filedemunge(pathname, header):
|
|||
lines = lines[:start] + lines[end:]
|
||||
f.write("".join(lines))
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
def expandcorepath(pathname, session=None, node=None):
|
||||
''' Expand a file path given session information.
|
||||
'''
|
||||
"""
|
||||
Expand a file path given session information.
|
||||
"""
|
||||
if session is not None:
|
||||
pathname = pathname.replace('~', "/home/%s" % session.user)
|
||||
pathname = pathname.replace('%SESSION%', str(session.sessionid))
|
||||
|
@ -174,20 +196,24 @@ def expandcorepath(pathname, session=None, node=None):
|
|||
pathname = pathname.replace('%NODE%', str(node.objid))
|
||||
pathname = pathname.replace('%NODENAME%', node.name)
|
||||
return pathname
|
||||
|
||||
|
||||
|
||||
def sysctldevname(devname):
|
||||
''' Translate a device name to the name used with sysctl.
|
||||
'''
|
||||
"""
|
||||
Translate a device name to the name used with sysctl.
|
||||
"""
|
||||
if devname is None:
|
||||
return None
|
||||
return devname.replace(".", "/")
|
||||
|
||||
def daemonize(rootdir = "/", umask = 0, close_fds = False, dontclose = (),
|
||||
stdin = os.devnull, stdout = os.devnull, stderr = os.devnull,
|
||||
stdoutmode = 0644, stderrmode = 0644, pidfilename = None,
|
||||
defaultmaxfd = 1024):
|
||||
''' Run the background process as a daemon.
|
||||
'''
|
||||
|
||||
def daemonize(rootdir="/", umask=0, close_fds=False, dontclose=(),
|
||||
stdin=os.devnull, stdout=os.devnull, stderr=os.devnull,
|
||||
stdoutmode=0644, stderrmode=0644, pidfilename=None,
|
||||
defaultmaxfd=1024):
|
||||
"""
|
||||
Run the background process as a daemon.
|
||||
"""
|
||||
if not hasattr(dontclose, "__contains__"):
|
||||
if not isinstance(dontclose, int):
|
||||
raise TypeError, "dontclose must be an integer"
|
||||
|
@ -206,7 +232,7 @@ def daemonize(rootdir = "/", umask = 0, close_fds = False, dontclose = (),
|
|||
fd = os.open(stdout, os.O_WRONLY | os.O_CREAT | os.O_APPEND,
|
||||
stdoutmode)
|
||||
os.dup2(fd, 1)
|
||||
if (stdout == stderr):
|
||||
if stdout == stderr:
|
||||
os.dup2(1, 2)
|
||||
os.close(fd)
|
||||
# redirect stderr
|
||||
|
@ -216,7 +242,8 @@ def daemonize(rootdir = "/", umask = 0, close_fds = False, dontclose = (),
|
|||
os.dup2(fd, 2)
|
||||
os.close(fd)
|
||||
if os.fork():
|
||||
os._exit(0) # parent exits
|
||||
# parent exits
|
||||
os._exit(0)
|
||||
os.setsid()
|
||||
pid = os.fork()
|
||||
if pid:
|
||||
|
@ -225,9 +252,10 @@ def daemonize(rootdir = "/", umask = 0, close_fds = False, dontclose = (),
|
|||
f = open(pidfilename, "w")
|
||||
f.write("%s\n" % pid)
|
||||
f.close()
|
||||
except:
|
||||
pass
|
||||
os._exit(0) # parent exits
|
||||
except IOError:
|
||||
logger.exception("error writing to file: %s", pidfilename)
|
||||
# parent exits
|
||||
os._exit(0)
|
||||
if rootdir:
|
||||
os.chdir(rootdir)
|
||||
os.umask(umask)
|
||||
|
@ -244,12 +272,14 @@ def daemonize(rootdir = "/", umask = 0, close_fds = False, dontclose = (),
|
|||
try:
|
||||
os.close(fd)
|
||||
except:
|
||||
pass
|
||||
logger.exception("error closing file descriptor")
|
||||
|
||||
|
||||
def readfileintodict(filename, d):
|
||||
''' Read key=value pairs from a file, into a dict.
|
||||
Skip comments; strip newline characters and spacing.
|
||||
'''
|
||||
"""
|
||||
Read key=value pairs from a file, into a dict.
|
||||
Skip comments; strip newline characters and spacing.
|
||||
"""
|
||||
with open(filename, 'r') as f:
|
||||
lines = f.readlines()
|
||||
for l in lines:
|
||||
|
@ -259,15 +289,16 @@ def readfileintodict(filename, d):
|
|||
key, value = l.split('=', 1)
|
||||
d[key] = value.strip()
|
||||
except ValueError:
|
||||
pass
|
||||
logger.exception("error reading file to dict: %s", filename)
|
||||
|
||||
|
||||
def checkforkernelmodule(name):
|
||||
''' Return a string if a Linux kernel module is loaded, None otherwise.
|
||||
"""
|
||||
Return a string if a Linux kernel module is loaded, None otherwise.
|
||||
The string is the line from /proc/modules containing the module name,
|
||||
memory size (bytes), number of loaded instances, dependencies, state,
|
||||
and kernel memory offset.
|
||||
'''
|
||||
"""
|
||||
with open('/proc/modules', 'r') as f:
|
||||
for line in f:
|
||||
if line.startswith(name + ' '):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue