add convienience functions for running commands

Adds runcmd() and runcmd_output() which set raise_err=True
This commit is contained in:
Brian C. Lane 2012-08-22 15:24:49 -07:00
parent 12ad7d0d99
commit 43bd549480
6 changed files with 35 additions and 23 deletions

View File

@ -47,7 +47,7 @@ from treebuilder import RuntimeBuilder, TreeBuilder
from buildstamp import BuildStamp from buildstamp import BuildStamp
from treeinfo import TreeInfo from treeinfo import TreeInfo
from discinfo import DiscInfo from discinfo import DiscInfo
from executils import execWithRedirect from executils import runcmd
class ArchData(DataHolder): class ArchData(DataHolder):
lib64_arches = ("x86_64", "ppc64", "sparc64", "s390x", "ia64") lib64_arches = ("x86_64", "ppc64", "sparc64", "s390x", "ia64")
@ -141,7 +141,7 @@ class Lorax(BaseLoraxClass):
if domacboot: if domacboot:
try: try:
execWithRedirect("rpm", ["-q", "hfsplus-tools"], raise_err=True) runcmd(["rpm", "-q", "hfsplus-tools"])
except CalledProcessError: except CalledProcessError:
logger.critical("you need to install hfsplus-tools to create mac images") logger.critical("you need to install hfsplus-tools to create mac images")
sys.exit(1) sys.exit(1)

View File

@ -407,4 +407,15 @@ def execConsole():
except OSError as e: except OSError as e:
raise RuntimeError, "Error running /bin/sh: " + e.strerror raise RuntimeError, "Error running /bin/sh: " + e.strerror
def runcmd(cmd, **kwargs):
""" run execWithRedirect with raise_err=True
"""
kwargs["raise_err"] = True
return execWithRedirect(cmd[0], cmd[1:], **kwargs)
def runcmd_output(cmd, **kwargs):
""" run execWithCapture with raise_err=True
"""
kwargs["raise_err"] = True
return execWithCapture(cmd[0], cmd[1:], **kwargs)

View File

@ -29,6 +29,7 @@ from time import sleep
from pylorax.sysutils import cpfile from pylorax.sysutils import cpfile
from pylorax.executils import execWithRedirect, execWithCapture from pylorax.executils import execWithRedirect, execWithCapture
from pylorax.executils import runcmd, runcmd_output
######## Functions for making container images (cpio, squashfs) ########## ######## Functions for making container images (cpio, squashfs) ##########
@ -69,7 +70,7 @@ def mksparse(outfile, size):
def loop_attach(outfile): def loop_attach(outfile):
'''Attach a loop device to the given file. Return the loop device name. '''Attach a loop device to the given file. Return the loop device name.
Raises CalledProcessError if losetup fails.''' Raises CalledProcessError if losetup fails.'''
dev = execWithCapture("losetup", ["--find", "--show", outfile], raise_err=True) dev = runcmd_output(["losetup", "--find", "--show", outfile])
return dev.strip() return dev.strip()
def loop_detach(loopdev): def loop_detach(loopdev):
@ -79,7 +80,7 @@ def loop_detach(loopdev):
def get_loop_name(path): def get_loop_name(path):
'''Return the loop device associated with the path. '''Return the loop device associated with the path.
Raises RuntimeError if more than one loop is associated''' Raises RuntimeError if more than one loop is associated'''
buf = execWithCapture("losetup", ["-j", path], raise_err=True) buf = runcmd_output(["losetup", "-j", path])
if len(buf.splitlines()) > 1: if len(buf.splitlines()) > 1:
# there should never be more than one loop device listed # there should never be more than one loop device listed
raise RuntimeError("multiple loops associated with %s" % path) raise RuntimeError("multiple loops associated with %s" % path)
@ -92,8 +93,8 @@ def dm_attach(dev, size, name=None):
raises CalledProcessError if dmsetup fails.''' raises CalledProcessError if dmsetup fails.'''
if name is None: if name is None:
name = tempfile.mktemp(prefix="lorax.imgutils.", dir="") name = tempfile.mktemp(prefix="lorax.imgutils.", dir="")
execWithRedirect("dmsetup", ["create", name, "--table", runcmd(["dmsetup", "create", name, "--table",
"0 %i linear %s 0" % (size/512, dev)], raise_err=True) "0 %i linear %s 0" % (size/512, dev)])
return name return name
def dm_detach(dev): def dm_detach(dev):
@ -114,7 +115,7 @@ def mount(dev, opts="", mnt=None):
if opts: if opts:
mount += ["-o", opts] mount += ["-o", opts]
mount += [dev, mnt] mount += [dev, mnt]
execWithRedirect(mount[0], mount[1:], raise_err=True) runcmd(mount)
return mnt return mnt
def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0): def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0):
@ -127,7 +128,7 @@ def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0):
count = 0 count = 0
while maxretry > 0: while maxretry > 0:
try: try:
rv = execWithRedirect(umount[0], umount[1:], raise_err=True) rv = runcmd(umount)
except CalledProcessError: except CalledProcessError:
count += 1 count += 1
if count == maxretry: if count == maxretry:
@ -153,7 +154,7 @@ def copytree(src, dest, preserve=True):
logger.debug("copytree %s %s", src, dest) logger.debug("copytree %s %s", src, dest)
cp = ["cp", "-a"] if preserve else ["cp", "-R", "-L"] cp = ["cp", "-a"] if preserve else ["cp", "-R", "-L"]
cp += [".", os.path.abspath(dest)] cp += [".", os.path.abspath(dest)]
execWithRedirect(cp[0], cp[1:], cwd=src, raise_err=True) runcmd(cp, cwd=src)
def do_grafts(grafts, dest, preserve=True): def do_grafts(grafts, dest, preserve=True):
'''Copy each of the items listed in grafts into dest. '''Copy each of the items listed in grafts into dest.
@ -252,7 +253,7 @@ class PartitionMount(object):
# kpartx -p p -v -a /tmp/diskV2DiCW.im # kpartx -p p -v -a /tmp/diskV2DiCW.im
# add map loop2p1 (253:2): 0 3481600 linear /dev/loop2 2048 # add map loop2p1 (253:2): 0 3481600 linear /dev/loop2 2048
# add map loop2p2 (253:3): 0 614400 linear /dev/loop2 3483648 # add map loop2p2 (253:3): 0 614400 linear /dev/loop2 3483648
kpartx_output = execWithCapture("kpartx", ["-v", "-p", "p", "-a", self.disk_img], raise_err=True) kpartx_output = runcmd_output(["kpartx", "-v", "-p", "p", "-a", self.disk_img])
logger.debug(kpartx_output) logger.debug(kpartx_output)
# list of (deviceName, sizeInBytes) # list of (deviceName, sizeInBytes)
@ -306,7 +307,7 @@ def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=[], mountargs="", gr
size = estimate_size(rootdir, graft, fstype) size = estimate_size(rootdir, graft, fstype)
with LoopDev(outfile, size) as loopdev: with LoopDev(outfile, size) as loopdev:
try: try:
execWithRedirect("mkfs.%s" % fstype, mkfsargs + [loopdev], raise_err=True) runcmd(["mkfs.%s" % fstype] + mkfsargs + [loopdev])
except CalledProcessError as e: except CalledProcessError as e:
logger.error("mkfs exited with a non-zero return code: %d" % e.returncode) logger.error("mkfs exited with a non-zero return code: %d" % e.returncode)
logger.error(e.output) logger.error(e.output)

View File

@ -30,7 +30,7 @@ from subprocess import CalledProcessError
from sysutils import joinpaths, cpfile, mvfile, replace, remove from sysutils import joinpaths, cpfile, mvfile, replace, remove
from yumhelper import * # Lorax*Callback classes from yumhelper import * # Lorax*Callback classes
from base import DataHolder from base import DataHolder
from pylorax.executils import execWithRedirect, execWithCapture from pylorax.executils import runcmd, runcmd_output
from mako.lookup import TemplateLookup from mako.lookup import TemplateLookup
from mako.exceptions import text_error_template from mako.exceptions import text_error_template
@ -372,7 +372,7 @@ class LoraxTemplateRunner(object):
cmd = ["gconftool-2", "--direct", cmd = ["gconftool-2", "--direct",
"--config-source=xml:readwrite:%s" % outfile, "--config-source=xml:readwrite:%s" % outfile,
"--set", "--type", keytype, path, value] "--set", "--type", keytype, path, value]
execWithRedirect(cmd[0], cmd[1:], raise_err=True) runcmd(cmd)
def log(self, msg): def log(self, msg):
''' '''
@ -414,7 +414,7 @@ class LoraxTemplateRunner(object):
cmd = cmd[1:] cmd = cmd[1:]
try: try:
output = execWithCapture(cmd[0], cmd[1:], cwd=cwd, raise_err=True) output = runcmd_output(cmd, cwd=cwd)
if output: if output:
logger.debug('command output:\n%s', output) logger.debug('command output:\n%s', output)
logger.debug("command finished successfully") logger.debug("command finished successfully")
@ -552,6 +552,6 @@ class LoraxTemplateRunner(object):
# XXX for some reason 'systemctl enable/disable' always returns 1 # XXX for some reason 'systemctl enable/disable' always returns 1
try: try:
cmd = systemctl + units cmd = systemctl + units
execWithRedirect(cmd[0], cmd[1:], raise_err=True) runcmd(cmd)
except CalledProcessError: except CalledProcessError:
pass pass

View File

@ -32,7 +32,7 @@ import glob
import shutil import shutil
import subprocess import subprocess
from pylorax.executils import execWithRedirect from pylorax.executils import runcmd
def joinpaths(*args, **kwargs): def joinpaths(*args, **kwargs):
path = os.path.sep.join(args) path = os.path.sep.join(args)
@ -106,5 +106,5 @@ def remove(target):
os.unlink(target) os.unlink(target)
def linktree(src, dst): def linktree(src, dst):
execWithRedirect("/bin/cp", ["-al", src, dst], raise_err=True) runcmd(["/bin/cp", "-al", src, dst])

View File

@ -28,7 +28,7 @@ from shutil import copytree, copy2
from base import DataHolder from base import DataHolder
from ltmpl import LoraxTemplateRunner from ltmpl import LoraxTemplateRunner
import imgutils import imgutils
from pylorax.executils import execWithRedirect, execWithCapture from pylorax.executils import runcmd, runcmd_output
templatemap = { templatemap = {
'i386': 'x86.tmpl', 'i386': 'x86.tmpl',
@ -45,7 +45,7 @@ templatemap = {
def generate_module_info(moddir, outfile=None): def generate_module_info(moddir, outfile=None):
def module_desc(mod): def module_desc(mod):
output = execWithCapture("modinfo", ["-F", "description", mod], raise_err=True) output = runcmd_output(["modinfo", "-F", "description", mod])
return output.strip() return output.strip()
def read_module_set(name): def read_module_set(name):
return set(l.strip() for l in open(joinpaths(moddir,name)) if ".ko" in l) return set(l.strip() for l in open(joinpaths(moddir,name)) if ".ko" in l)
@ -149,7 +149,7 @@ class RuntimeBuilder(object):
for kver in os.listdir(moddir): for kver in os.listdir(moddir):
ksyms = joinpaths(root, "boot/System.map-%s" % kver) ksyms = joinpaths(root, "boot/System.map-%s" % kver)
logger.info("doing depmod and module-info for %s", kver) logger.info("doing depmod and module-info for %s", kver)
execWithRedirect("depmod", ["-a", "-F", ksyms, "-b", root, kver], raise_err=True) runcmd(["depmod", "-a", "-F", ksyms, "-b", root, kver])
generate_module_info(moddir+kver, outfile=moddir+"module-info") generate_module_info(moddir+kver, outfile=moddir+"module-info")
def create_runtime(self, outfile="/tmp/squashfs.img", compression="xz", compressargs=[], size=1): def create_runtime(self, outfile="/tmp/squashfs.img", compression="xz", compressargs=[], size=1):
@ -167,7 +167,7 @@ class RuntimeBuilder(object):
with imgutils.LoopDev( joinpaths(workdir, "LiveOS/rootfs.img") ) as loopdev: with imgutils.LoopDev( joinpaths(workdir, "LiveOS/rootfs.img") ) as loopdev:
with imgutils.Mount(loopdev) as mnt: with imgutils.Mount(loopdev) as mnt:
cmd = [ "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/etc/selinux/targeted/contexts/files/file_contexts", "/"] cmd = [ "setfiles", "-e", "/proc", "-e", "/sys", "-e", "/dev", "-e", "/selinux", "/etc/selinux/targeted/contexts/files/file_contexts", "/"]
execWithRedirect(cmd[0], cmd[1:], root=mnt, raise_err=True) runcmd(cmd, root=mnt)
# squash the live rootfs and clean up workdir # squash the live rootfs and clean up workdir
imgutils.mksquashfs(workdir, outfile, compression, compressargs) imgutils.mksquashfs(workdir, outfile, compression, compressargs)
@ -208,7 +208,7 @@ class TreeBuilder(object):
initrd = joinpaths(self.vars.inroot, kernel.initrd.path) initrd = joinpaths(self.vars.inroot, kernel.initrd.path)
os.rename(initrd, initrd + backup) os.rename(initrd, initrd + backup)
cmd = dracut + [kernel.initrd.path, kernel.version] cmd = dracut + [kernel.initrd.path, kernel.version]
execWithRedirect(cmd[0], cmd[1:], root=self.vars.inroot, raise_err=True) runcmd(cmd, root=self.vars.inroot)
os.unlink(joinpaths(self.vars.inroot,"/proc/modules")) os.unlink(joinpaths(self.vars.inroot,"/proc/modules"))
def build(self): def build(self):
@ -221,7 +221,7 @@ class TreeBuilder(object):
for section, data in self.treeinfo_data.items(): for section, data in self.treeinfo_data.items():
if 'boot.iso' in data: if 'boot.iso' in data:
iso = joinpaths(self.vars.outroot, data['boot.iso']) iso = joinpaths(self.vars.outroot, data['boot.iso'])
execWithRedirect("implantisomd5", [iso], raise_err=True) runcmd(["implantisomd5", iso])
@property @property
def dracut_hooks_path(self): def dracut_hooks_path(self):