Cleanup pylorax pylint warnings

This commit is contained in:
Brian C. Lane 2014-05-08 17:21:34 -07:00
parent c12c5f1e47
commit 6d47689a33
9 changed files with 129 additions and 108 deletions

View File

@ -33,21 +33,19 @@ import locale
from subprocess import CalledProcessError from subprocess import CalledProcessError
import selinux import selinux
from base import BaseLoraxClass, DataHolder from pylorax.base import BaseLoraxClass, DataHolder
import output import pylorax.output as output
import yum import yum
import ltmpl
import imgutils from pylorax.sysutils import joinpaths, remove, linktree
from sysutils import *
from rpmUtils.arch import getBaseArch from rpmUtils.arch import getBaseArch
from treebuilder import RuntimeBuilder, TreeBuilder from pylorax.treebuilder import RuntimeBuilder, TreeBuilder
from buildstamp import BuildStamp from pylorax.buildstamp import BuildStamp
from treeinfo import TreeInfo from pylorax.treeinfo import TreeInfo
from discinfo import DiscInfo from pylorax.discinfo import DiscInfo
from executils import runcmd, runcmd_output from pylorax.executils import runcmd, runcmd_output
# List of drivers to remove on ppc64 arch to keep initrd < 32MiB # List of drivers to remove on ppc64 arch to keep initrd < 32MiB
REMOVE_PPC64_DRIVERS = "floppy scsi_debug nouveau radeon cirrus mgag200" REMOVE_PPC64_DRIVERS = "floppy scsi_debug nouveau radeon cirrus mgag200"
@ -60,6 +58,7 @@ class ArchData(DataHolder):
arm="arm", armhfp="arm") arm="arm", armhfp="arm")
def __init__(self, buildarch): def __init__(self, buildarch):
super(ArchData, self).__init__()
self.buildarch = buildarch self.buildarch = buildarch
self.basearch = getBaseArch(buildarch) self.basearch = getBaseArch(buildarch)
self.libdir = "lib64" if self.basearch in self.lib64_arches else "lib" self.libdir = "lib64" if self.basearch in self.lib64_arches else "lib"
@ -70,6 +69,13 @@ class Lorax(BaseLoraxClass):
def __init__(self): def __init__(self):
BaseLoraxClass.__init__(self) BaseLoraxClass.__init__(self)
self._configured = False self._configured = False
self.product = None
self.workdir = None
self.arch = None
self.conf = None
self.inroot = None
self.debug = False
self.outputdir = None
# set locale to C # set locale to C
locale.setlocale(locale.LC_ALL, 'C') locale.setlocale(locale.LC_ALL, 'C')
@ -129,7 +135,7 @@ class Lorax(BaseLoraxClass):
# remove some environmental variables that can cause problems with package scripts # remove some environmental variables that can cause problems with package scripts
env_remove = ('DISPLAY', 'DBUS_SESSION_BUS_ADDRESS') env_remove = ('DISPLAY', 'DBUS_SESSION_BUS_ADDRESS')
[os.environ.pop(k) for k in env_remove if k in os.environ] map(os.environ.pop, (k for k in env_remove if k in os.environ))
self._configured = True self._configured = True
@ -229,7 +235,7 @@ class Lorax(BaseLoraxClass):
product = DataHolder(name=product, version=version, release=release, product = DataHolder(name=product, version=version, release=release,
variant=variant, bugurl=bugurl, isfinal=isfinal) variant=variant, bugurl=bugurl, isfinal=isfinal)
self.product = product self.product = product
logger.debug("product data: %s" % product) logger.debug("product data: %s", product)
# NOTE: if you change isolabel, you need to change pungi to match, or # NOTE: if you change isolabel, you need to change pungi to match, or
# the pungi images won't boot. # the pungi images won't boot.

View File

@ -22,7 +22,7 @@
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
import sys import sys
import output import pylorax.output as output
class BaseLoraxClass(object): class BaseLoraxClass(object):

View File

@ -112,7 +112,7 @@ def execWithRedirect(command, argv, stdin = None, stdout = None,
elif stderr is None or not isinstance(stderr, file): elif stderr is None or not isinstance(stderr, file):
stderr = sys.stderr.fileno() stderr = sys.stderr.fileno()
program_log.info("Running... %s" % (" ".join([command] + argv),)) program_log.info("Running... %s", " ".join([command] + argv))
#prepare os pipes for feeding tee proceses #prepare os pipes for feeding tee proceses
pstdout, pstdin = os.pipe() pstdout, pstdin = os.pipe()
@ -124,9 +124,9 @@ def execWithRedirect(command, argv, stdin = None, stdout = None,
if root: if root:
preexec_fn = chroot preexec_fn = chroot
cwd = root cwd = root
program_log.info("chrooting into %s" % (cwd,)) program_log.info("chrooting into %s", cwd)
elif cwd: elif cwd:
program_log.info("chdiring into %s" % (cwd,)) program_log.info("chdiring into %s", cwd)
try: try:
#prepare tee proceses #prepare tee proceses
@ -173,7 +173,7 @@ def execWithRedirect(command, argv, stdin = None, stdout = None,
stdinclose() stdinclose()
stdoutclose() stdoutclose()
stderrclose() stderrclose()
raise RuntimeError, errstr raise RuntimeError(errstr)
if ret and raise_err: if ret and raise_err:
raise subprocess.CalledProcessError(ret, [command]+argv) raise subprocess.CalledProcessError(ret, [command]+argv)
@ -223,7 +223,7 @@ def execWithCapture(command, argv, stdin = None, stderr = None, root=None,
elif stderr is None or not isinstance(stderr, file): elif stderr is None or not isinstance(stderr, file):
stderr = sys.stderr.fileno() stderr = sys.stderr.fileno()
program_log.info("Running... %s" % (" ".join([command] + argv),)) program_log.info("Running... %s", " ".join([command] + argv))
env = os.environ.copy() env = os.environ.copy()
env.update({"LC_ALL": "C"}) env.update({"LC_ALL": "C"})
@ -231,9 +231,9 @@ def execWithCapture(command, argv, stdin = None, stderr = None, root=None,
if root: if root:
preexec_fn = chroot preexec_fn = chroot
cwd = root cwd = root
program_log.info("chrooting into %s" % (cwd,)) program_log.info("chrooting into %s", cwd)
elif cwd: elif cwd:
program_log.info("chdiring into %s" % (cwd,)) program_log.info("chdiring into %s", cwd)
try: try:
proc = subprocess.Popen([command] + argv, stdin=stdin, proc = subprocess.Popen([command] + argv, stdin=stdin,
@ -254,9 +254,9 @@ def execWithCapture(command, argv, stdin = None, stderr = None, root=None,
if proc.returncode is not None: if proc.returncode is not None:
break break
except OSError as e: except OSError as e:
log.error ("Error running " + command + ": " + e.strerror) log.error("Error running %s: %s", command, e.strerror)
closefds() closefds()
raise RuntimeError, "Error running " + command + ": " + e.strerror raise RuntimeError("Error running %s: %s" % (command, e.strerror))
closefds() closefds()
if proc.returncode and raise_err: if proc.returncode and raise_err:
@ -267,9 +267,6 @@ def execWithCapture(command, argv, stdin = None, stderr = None, root=None,
def execWithCallback(command, argv, stdin = None, stdout = None, def execWithCallback(command, argv, stdin = None, stdout = None,
stderr = None, echo = True, callback = None, stderr = None, echo = True, callback = None,
callback_data = None, root = '/'): callback_data = None, root = '/'):
def chroot():
os.chroot(root)
def closefds (): def closefds ():
stdinclose() stdinclose()
stdoutclose() stdoutclose()
@ -305,7 +302,7 @@ def execWithCallback(command, argv, stdin = None, stdout = None,
elif stderr is None or not isinstance(stderr, file): elif stderr is None or not isinstance(stderr, file):
stderr = sys.stderr.fileno() stderr = sys.stderr.fileno()
program_log.info("Running... %s" % (" ".join([command] + argv),)) program_log.info("Running... %s", " ".join([command] + argv))
p = os.pipe() p = os.pipe()
p_stderr = os.pipe() p_stderr = os.pipe()
@ -333,7 +330,7 @@ def execWithCallback(command, argv, stdin = None, stdout = None,
except OSError as e: except OSError as e:
if e.errno != 4: if e.errno != 4:
map(program_log.info, log_output.splitlines()) map(program_log.info, log_output.splitlines())
raise IOError, e.args raise IOError(e.args)
if echo: if echo:
os.write(stdout, s) os.write(stdout, s)
@ -349,7 +346,7 @@ def execWithCallback(command, argv, stdin = None, stdout = None,
if pid != 0: if pid != 0:
break break
except OSError as e: except OSError as e:
log.critical("exception from waitpid: %s %s" %(e.errno, e.strerror)) log.critical("exception from waitpid: %s %s", e.errno, e.strerror)
if len(s) < 1: if len(s) < 1:
break break
@ -363,7 +360,7 @@ def execWithCallback(command, argv, stdin = None, stdout = None,
except OSError as e: except OSError as e:
if e.errno != 4: if e.errno != 4:
map(program_log.error, log_errors.splitlines()) map(program_log.error, log_errors.splitlines())
raise IOError, e.args raise IOError(e.args)
break break
log_errors += err log_errors += err
if len(err) < 1: if len(err) < 1:
@ -379,7 +376,7 @@ def execWithCallback(command, argv, stdin = None, stdout = None,
if not pid: if not pid:
(pid, status) = os.waitpid(childpid, 0) (pid, status) = os.waitpid(childpid, 0)
except OSError as e: except OSError as e:
log.critical("exception from waitpid: %s %s" %(e.errno, e.strerror)) log.critical("exception from waitpid: %s %s", e.errno, e.strerror)
closefds() closefds()
@ -405,7 +402,7 @@ def execConsole():
proc = subprocess.Popen(["/bin/sh"]) proc = subprocess.Popen(["/bin/sh"])
proc.wait() proc.wait()
except OSError as e: except OSError as e:
raise RuntimeError, "Error running /bin/sh: " + e.strerror raise RuntimeError("Error running /bin/sh: %s" % e.strerror)
def runcmd(cmd, **kwargs): def runcmd(cmd, **kwargs):
""" run execWithRedirect with raise_err=True """ run execWithRedirect with raise_err=True

View File

@ -34,13 +34,14 @@ from pylorax.executils import runcmd, runcmd_output
######## Functions for making container images (cpio, tar, squashfs) ########## ######## Functions for making container images (cpio, tar, squashfs) ##########
def compress(command, rootdir, outfile, compression="xz", compressargs=["-9"]): def compress(command, rootdir, outfile, compression="xz", compressargs=None):
'''Make a compressed archive of the given rootdir. '''Make a compressed archive of the given rootdir.
command is a list of the archiver commands to run command is a list of the archiver commands to run
compression should be "xz", "gzip", "lzma", "bzip2", or None. compression should be "xz", "gzip", "lzma", "bzip2", or None.
compressargs will be used on the compression commandline.''' compressargs will be used on the compression commandline.'''
if compression not in (None, "xz", "gzip", "lzma", "bzip2"): if compression not in (None, "xz", "gzip", "lzma", "bzip2"):
raise ValueError, "Unknown compression type %s" % compression raise ValueError("Unknown compression type %s" % compression)
compressargs = compressargs or ["-9"]
if compression == "xz": if compression == "xz":
compressargs.insert(0, "--check=crc32") compressargs.insert(0, "--check=crc32")
if compression is None: if compression is None:
@ -70,19 +71,22 @@ def compress(command, rootdir, outfile, compression="xz", compressargs=["-9"]):
except OSError as e: except OSError as e:
logger.error(e) logger.error(e)
# Kill off any hanging processes # Kill off any hanging processes
[p.kill() for p in (find, archive, comp) if p] map(lambda p: p.kill(), (p for p in (find, archive, comp) if p))
return 1 return 1
def mkcpio(rootdir, outfile, compression="xz", compressargs=["-9"]): def mkcpio(rootdir, outfile, compression="xz", compressargs=None):
compressargs = compressargs or ["-9"]
return compress(["cpio", "--null", "--quiet", "-H", "newc", "-o"], return compress(["cpio", "--null", "--quiet", "-H", "newc", "-o"],
rootdir, outfile, compression, compressargs) rootdir, outfile, compression, compressargs)
def mktar(rootdir, outfile, compression="xz", compressargs=["-9"]): def mktar(rootdir, outfile, compression="xz", compressargs=None):
compressargs = compressargs or ["-9"]
return compress(["tar", "--selinux", "--acls", "--xattrs", "-cf-", "--null", "-T-"], return compress(["tar", "--selinux", "--acls", "--xattrs", "-cf-", "--null", "-T-"],
rootdir, outfile, compression, compressargs) rootdir, outfile, compression, compressargs)
def mksquashfs(rootdir, outfile, compression="default", compressargs=[]): def mksquashfs(rootdir, outfile, compression="default", compressargs=None):
'''Make a squashfs image containing the given rootdir.''' '''Make a squashfs image containing the given rootdir.'''
compressargs = compressargs or []
if compression != "default": if compression != "default":
compressargs = ["-comp", compression] + compressargs compressargs = ["-comp", compression] + compressargs
return execWithRedirect("mksquashfs", [rootdir, outfile] + compressargs) return execWithRedirect("mksquashfs", [rootdir, outfile] + compressargs)
@ -150,24 +154,24 @@ def mount(dev, opts="", mnt=None):
if mnt is None: if mnt is None:
mnt = tempfile.mkdtemp(prefix="lorax.imgutils.") mnt = tempfile.mkdtemp(prefix="lorax.imgutils.")
logger.debug("make tmp mountdir %s", mnt) logger.debug("make tmp mountdir %s", mnt)
mount = ["mount"] cmd = ["mount"]
if opts: if opts:
mount += ["-o", opts] cmd += ["-o", opts]
mount += [dev, mnt] cmd += [dev, mnt]
runcmd(mount) runcmd(cmd)
return mnt return mnt
def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0): def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0):
'''Unmount the given mountpoint. If lazy is True, do a lazy umount (-l). '''Unmount the given mountpoint. If lazy is True, do a lazy umount (-l).
If the mount was a temporary dir created by mount, it will be deleted. If the mount was a temporary dir created by mount, it will be deleted.
raises CalledProcessError if umount fails.''' raises CalledProcessError if umount fails.'''
umount = ["umount"] cmd = ["umount"]
if lazy: umount += ["-l"] if lazy: cmd += ["-l"]
umount += [mnt] cmd += [mnt]
count = 0 count = 0
while maxretry > 0: while maxretry > 0:
try: try:
rv = runcmd(umount) rv = runcmd(cmd)
except CalledProcessError: except CalledProcessError:
count += 1 count += 1
if count == maxretry: if count == maxretry:
@ -220,7 +224,8 @@ def round_to_blocks(size, blocksize):
return size return size
# TODO: move filesystem data outside this function # TODO: move filesystem data outside this function
def estimate_size(rootdir, graft={}, fstype=None, blocksize=4096, overhead=128): def estimate_size(rootdir, graft=None, fstype=None, blocksize=4096, overhead=128):
graft = graft or {}
getsize = lambda f: os.lstat(f).st_size getsize = lambda f: os.lstat(f).st_size
if fstype == "btrfs": if fstype == "btrfs":
overhead = 64*1024 # don't worry, it's all sparse overhead = 64*1024 # don't worry, it's all sparse
@ -245,22 +250,24 @@ def estimate_size(rootdir, graft={}, fstype=None, blocksize=4096, overhead=128):
class LoopDev(object): class LoopDev(object):
def __init__(self, filename, size=None): def __init__(self, filename, size=None):
self.loopdev = None
self.filename = filename self.filename = filename
if size: if size:
mksparse(self.filename, size) mksparse(self.filename, size)
def __enter__(self): def __enter__(self):
self.loopdev = loop_attach(self.filename) self.loopdev = loop_attach(self.filename)
return self.loopdev return self.loopdev
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, tracebk):
loop_detach(self.loopdev) loop_detach(self.loopdev)
class DMDev(object): class DMDev(object):
def __init__(self, dev, size, name=None): def __init__(self, dev, size, name=None):
self.mapperdev = None
(self.dev, self.size, self.name) = (dev, size, name) (self.dev, self.size, self.name) = (dev, size, name)
def __enter__(self): def __enter__(self):
self.mapperdev = dm_attach(self.dev, self.size, self.name) self.mapperdev = dm_attach(self.dev, self.size, self.name)
return self.mapperdev return self.mapperdev
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, tracebk):
dm_detach(self.mapperdev) dm_detach(self.mapperdev)
class Mount(object): class Mount(object):
@ -269,7 +276,7 @@ class Mount(object):
def __enter__(self): def __enter__(self):
self.mnt = mount(self.dev, self.opts, self.mnt) self.mnt = mount(self.dev, self.opts, self.mnt)
return self.mnt return self.mnt
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, tracebk):
umount(self.mnt) umount(self.mnt)
class PartitionMount(object): class PartitionMount(object):
@ -280,6 +287,8 @@ class PartitionMount(object):
mount_ok is a function that is passed the mount point and mount_ok is a function that is passed the mount point and
returns True if it should be mounted. returns True if it should be mounted.
""" """
self.mount_dev = None
self.mount_size = None
self.mount_dir = None self.mount_dir = None
self.disk_img = disk_img self.disk_img = disk_img
self.mount_ok = mount_ok self.mount_ok = mount_ok
@ -325,7 +334,7 @@ class PartitionMount(object):
os.rmdir(mount_dir) os.rmdir(mount_dir)
return self return self
def __exit__(self, exc_type, exc_value, traceback): def __exit__(self, exc_type, exc_value, tracebk):
if self.mount_dir: if self.mount_dir:
umount( self.mount_dir ) umount( self.mount_dir )
os.rmdir(self.mount_dir) os.rmdir(self.mount_dir)
@ -335,12 +344,14 @@ class PartitionMount(object):
######## Functions for making filesystem images ########################## ######## Functions for making filesystem images ##########################
def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=[], mountargs="", graft={}): def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=None, mountargs="", graft=None):
'''Generic filesystem image creation function. '''Generic filesystem image creation function.
fstype should be a filesystem type - "mkfs.${fstype}" must exist. fstype should be a filesystem type - "mkfs.${fstype}" must exist.
graft should be a dict: {"some/path/in/image": "local/file/or/dir"}; graft should be a dict: {"some/path/in/image": "local/file/or/dir"};
if the path ends with a '/' it's assumed to be a directory. if the path ends with a '/' it's assumed to be a directory.
Will raise CalledProcessError if something goes wrong.''' Will raise CalledProcessError if something goes wrong.'''
mkfsargs = mkfsargs or []
graft = graft or {}
preserve = (fstype not in ("msdos", "vfat")) preserve = (fstype not in ("msdos", "vfat"))
if not size: if not size:
size = estimate_size(rootdir, graft, fstype) size = estimate_size(rootdir, graft, fstype)
@ -348,7 +359,7 @@ def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=[], mountargs="", gr
try: try:
runcmd(["mkfs.%s" % fstype] + mkfsargs + [loopdev]) 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)
sys.exit(e.returncode) sys.exit(e.returncode)
@ -361,18 +372,22 @@ def mkfsimage(fstype, rootdir, outfile, size=None, mkfsargs=[], mountargs="", gr
runcmd(["sync"]) runcmd(["sync"])
# convenience functions with useful defaults # convenience functions with useful defaults
def mkdosimg(rootdir, outfile, size=None, label="", mountargs="shortname=winnt,umask=0077", graft={}): def mkdosimg(rootdir, outfile, size=None, label="", mountargs="shortname=winnt,umask=0077", graft=None):
graft = graft or {}
mkfsimage("msdos", rootdir, outfile, size, mountargs=mountargs, mkfsimage("msdos", rootdir, outfile, size, mountargs=mountargs,
mkfsargs=["-n", label], graft=graft) mkfsargs=["-n", label], graft=graft)
def mkext4img(rootdir, outfile, size=None, label="", mountargs="", graft={}): def mkext4img(rootdir, outfile, size=None, label="", mountargs="", graft=None):
graft = graft or {}
mkfsimage("ext4", rootdir, outfile, size, mountargs=mountargs, mkfsimage("ext4", rootdir, outfile, size, mountargs=mountargs,
mkfsargs=["-L", label, "-b", "1024", "-m", "0"], graft=graft) mkfsargs=["-L", label, "-b", "1024", "-m", "0"], graft=graft)
def mkbtrfsimg(rootdir, outfile, size=None, label="", mountargs="", graft={}): def mkbtrfsimg(rootdir, outfile, size=None, label="", mountargs="", graft=None):
graft = graft or {}
mkfsimage("btrfs", rootdir, outfile, size, mountargs=mountargs, mkfsimage("btrfs", rootdir, outfile, size, mountargs=mountargs,
mkfsargs=["-L", label], graft=graft) mkfsargs=["-L", label], graft=graft)
def mkhfsimg(rootdir, outfile, size=None, label="", mountargs="", graft={}): def mkhfsimg(rootdir, outfile, size=None, label="", mountargs="", graft=None):
graft = graft or {}
mkfsimage("hfsplus", rootdir, outfile, size, mountargs=mountargs, mkfsimage("hfsplus", rootdir, outfile, size, mountargs=mountargs,
mkfsargs=["-v", label], graft=graft) mkfsargs=["-v", label], graft=graft)

View File

@ -27,9 +27,9 @@ import os, re, glob, shlex, fnmatch
from os.path import basename, isdir from os.path import basename, isdir
from subprocess import CalledProcessError from subprocess import CalledProcessError
from sysutils import joinpaths, cpfile, mvfile, replace, remove from pylorax.sysutils import joinpaths, cpfile, mvfile, replace, remove
from yumhelper import * # Lorax*Callback classes from pylorax.yumhelper import LoraxDownloadCallback, LoraxTransactionCallback, LoraxRpmCallback
from base import DataHolder from pylorax.base import DataHolder
from pylorax.executils import runcmd, runcmd_output from pylorax.executils import runcmd, runcmd_output
from mako.lookup import TemplateLookup from mako.lookup import TemplateLookup
@ -38,7 +38,8 @@ import sys, traceback
import struct import struct
class LoraxTemplate(object): class LoraxTemplate(object):
def __init__(self, directories=["/usr/share/lorax"]): def __init__(self, directories=None):
directories = directories or ["/usr/share/lorax"]
# we have to add ["/"] to the template lookup directories or the # we have to add ["/"] to the template lookup directories or the
# file includes won't work properly for absolute paths # file includes won't work properly for absolute paths
self.directories = ["/"] + directories self.directories = ["/"] + directories
@ -67,7 +68,6 @@ class LoraxTemplate(object):
# split with shlex and perform brace expansion # split with shlex and perform brace expansion
lines = map(split_and_expand, lines) lines = map(split_and_expand, lines)
self.lines = lines
return lines return lines
def split_and_expand(line): def split_and_expand(line):
@ -92,7 +92,7 @@ def rglob(pathname, root="/", fatal=False):
seen.add(f) seen.add(f)
yield f[rootlen:] # remove the root to produce relative path yield f[rootlen:] # remove the root to produce relative path
if fatal and not seen: if fatal and not seen:
raise IOError, "nothing matching %s in %s" % (pathname, root) raise IOError("nothing matching %s in %s" % (pathname, root))
def rexists(pathname, root=""): def rexists(pathname, root=""):
# Generator is always True, even with no values; # Generator is always True, even with no values;
@ -145,16 +145,17 @@ class LoraxTemplateRunner(object):
* Commands should raise exceptions for errors - don't use sys.exit() * Commands should raise exceptions for errors - don't use sys.exit()
''' '''
def __init__(self, inroot, outroot, yum=None, fatalerrors=True, def __init__(self, inroot, outroot, yum=None, fatalerrors=True,
templatedir=None, defaults={}): templatedir=None, defaults=None):
self.inroot = inroot self.inroot = inroot
self.outroot = outroot self.outroot = outroot
self.yum = yum self.yum = yum
self.fatalerrors = fatalerrors self.fatalerrors = fatalerrors
self.templatedir = templatedir or "/usr/share/lorax" self.templatedir = templatedir or "/usr/share/lorax"
self.templatefile = None
# some builtin methods # some builtin methods
self.builtins = DataHolder(exists=lambda p: rexists(p, root=inroot), self.builtins = DataHolder(exists=lambda p: rexists(p, root=inroot),
glob=lambda g: list(rglob(g, root=inroot))) glob=lambda g: list(rglob(g, root=inroot)))
self.defaults = defaults self.defaults = defaults or {}
self.results = DataHolder(treeinfo=dict()) # just treeinfo for now self.results = DataHolder(treeinfo=dict()) # just treeinfo for now
# TODO: set up custom logger with a filter to add line info # TODO: set up custom logger with a filter to add line info
@ -195,9 +196,9 @@ class LoraxTemplateRunner(object):
# grab the method named in cmd and pass it the given arguments # grab the method named in cmd and pass it the given arguments
f = getattr(self, cmd, None) f = getattr(self, cmd, None)
if cmd[0] == '_' or cmd == 'run' or not callable(f): if cmd[0] == '_' or cmd == 'run' or not callable(f):
raise ValueError, "unknown command %s" % cmd raise ValueError("unknown command %s" % cmd)
f(*args) f(*args)
except Exception: except Exception: # pylint: disable=broad-except
if skiperror: if skiperror:
logger.debug("ignoring error") logger.debug("ignoring error")
continue continue
@ -258,7 +259,7 @@ class LoraxTemplateRunner(object):
match = True match = True
replace(f, pat, repl) replace(f, pat, repl)
if not match: if not match:
raise IOError, "no files matched %s" % " ".join(fileglobs) raise IOError("no files matched %s" % " ".join(fileglobs))
def append(self, filename, data): def append(self, filename, data):
''' '''
@ -453,7 +454,7 @@ class LoraxTemplateRunner(object):
for p in pkgs: for p in pkgs:
try: try:
self.yum.install(pattern=p) self.yum.install(pattern=p)
except Exception as e: except Exception as e: # pylint: disable=broad-except
# FIXME: save exception and re-raise after the loop finishes # FIXME: save exception and re-raise after the loop finishes
logger.error("installpkg %s failed: %s",p,str(e)) logger.error("installpkg %s failed: %s",p,str(e))
if required: if required:
@ -524,15 +525,15 @@ class LoraxTemplateRunner(object):
logger.debug("removefrom %s %s: no files matched!", pkg, g) logger.debug("removefrom %s %s: no files matched!", pkg, g)
# are we removing the matches, or keeping only the matches? # are we removing the matches, or keeping only the matches?
if keepmatches: if keepmatches:
remove = filelist.difference(matches) remove_files = filelist.difference(matches)
else: else:
remove = matches remove_files = matches
# remove the files # remove the files
if remove: if remove_files:
logger.debug("%s: removed %i/%i files, %ikb/%ikb", cmd, logger.debug("%s: removed %i/%i files, %ikb/%ikb", cmd,
len(remove), len(filelist), len(remove_files), len(filelist),
self._getsize(*remove)/1024, self._getsize(*filelist)/1024) self._getsize(*remove_files)/1024, self._getsize(*filelist)/1024)
self.remove(*remove) self.remove(*remove_files)
else: else:
logger.debug("%s: no files to remove!", cmd) logger.debug("%s: no files to remove!", cmd)

View File

@ -22,7 +22,7 @@
import sys import sys
import re import re
import decorators import pylorax.decorators as decorators
# output levels # output levels
@ -88,44 +88,44 @@ class LinuxTerminalOutput(object):
if self._indent_level > 0: if self._indent_level > 0:
self._indent_level -= 1 self._indent_level -= 1
def write(self, s, file=sys.stdout): def write(self, s, fout=sys.stdout):
if self._colors: if self._colors:
s = self.__format(s) s = self.__format(s)
else: else:
s = self.__raw(s) s = self.__raw(s)
file.write(s) fout.write(s)
file.flush() fout.flush()
def writeline(self, s, file=sys.stdout): def writeline(self, s, fout=sys.stdout):
s = "{0}{1}\n".format(" " * self._indent_level, s) s = "{0}{1}\n".format(" " * self._indent_level, s)
self.write(s, file=file) self.write(s, fout=fout)
def critical(self, s, file=sys.stdout): def critical(self, s, fout=sys.stdout):
s = "** critical: {0}".format(s) s = "** critical: {0}".format(s)
if (self._output_level <= CRITICAL and if (self._output_level <= CRITICAL and
self.__raw(s) not in self._ignored_messages): self.__raw(s) not in self._ignored_messages):
self.writeline(s, file=file) self.writeline(s, fout=fout)
def error(self, s, file=sys.stdout): def error(self, s, fout=sys.stdout):
s = "** error: {0}".format(s) s = "** error: {0}".format(s)
if (self._output_level <= ERROR and if (self._output_level <= ERROR and
self.__raw(s) not in self._ignored_messages): self.__raw(s) not in self._ignored_messages):
self.writeline(s, file=file) self.writeline(s, fout=fout)
def warning(self, s, file=sys.stdout): def warning(self, s, fout=sys.stdout):
s = "** warning: {0}".format(s) s = "** warning: {0}".format(s)
if (self._output_level <= WARNING and if (self._output_level <= WARNING and
self.__raw(s) not in self._ignored_messages): self.__raw(s) not in self._ignored_messages):
self.writeline(s, file=file) self.writeline(s, fout=fout)
def info(self, s, file=sys.stdout): def info(self, s, fout=sys.stdout):
if self._output_level <= INFO: if self._output_level <= INFO:
self.writeline(s, file=file) self.writeline(s, fout=fout)
def debug(self, s, file=sys.stdout): def debug(self, s, fout=sys.stdout):
if self._output_level <= DEBUG: if self._output_level <= DEBUG:
self.writeline(s, file=file) self.writeline(s, fout=fout)
def __format(self, s): def __format(self, s):
for tag, ccode in TAGS: for tag, ccode in TAGS:

View File

@ -30,7 +30,6 @@ import pwd
import grp import grp
import glob import glob
import shutil import shutil
import subprocess
from pylorax.executils import runcmd from pylorax.executils import runcmd
@ -48,12 +47,12 @@ def touch(fname):
pass pass
def replace(fname, find, replace): def replace(fname, find, sub):
fin = fileinput.input(fname, inplace=1) fin = fileinput.input(fname, inplace=1)
pattern = re.compile(find) pattern = re.compile(find)
for line in fin: for line in fin:
line = pattern.sub(replace, line) line = pattern.sub(sub, line)
sys.stdout.write(line) sys.stdout.write(line)
fin.close() fin.close()

View File

@ -21,13 +21,13 @@ import logging
logger = logging.getLogger("pylorax.treebuilder") logger = logging.getLogger("pylorax.treebuilder")
import os, re import os, re
from os.path import basename, isdir from os.path import basename
from sysutils import joinpaths, remove
from shutil import copytree, copy2 from shutil import copytree, copy2
from base import DataHolder
from ltmpl import LoraxTemplateRunner from pylorax.sysutils import joinpaths, remove
import imgutils from pylorax.base import DataHolder
from pylorax.ltmpl import LoraxTemplateRunner
import pylorax.imgutils as imgutils
from pylorax.executils import runcmd, runcmd_output from pylorax.executils import runcmd, runcmd_output
templatemap = { templatemap = {
@ -53,10 +53,10 @@ def generate_module_info(moddir, outfile=None):
'eth':read_module_set("modules.networking")} 'eth':read_module_set("modules.networking")}
modinfo = list() modinfo = list()
for root, dirs, files in os.walk(moddir): for root, _dirs, files in os.walk(moddir):
for modtype, modset in modsets.items(): for modtype, modset in modsets.items():
for mod in modset.intersection(files): # modules in this dir for mod in modset.intersection(files): # modules in this dir
(name, ext) = os.path.splitext(mod) # foo.ko -> (foo, .ko) (name, _ext) = os.path.splitext(mod) # foo.ko -> (foo, .ko)
desc = module_desc(joinpaths(root,mod)) or "%s driver" % name desc = module_desc(joinpaths(root,mod)) or "%s driver" % name
modinfo.append(dict(name=name, type=modtype, desc=desc)) modinfo.append(dict(name=name, type=modtype, desc=desc))
@ -146,8 +146,9 @@ class RuntimeBuilder(object):
runcmd(["depmod", "-a", "-F", ksyms, "-b", root, kver]) 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="/var/tmp/squashfs.img", compression="xz", compressargs=[], size=2): def create_runtime(self, outfile="/var/tmp/squashfs.img", compression="xz", compressargs=None, size=2):
# make live rootfs image - must be named "LiveOS/rootfs.img" for dracut # make live rootfs image - must be named "LiveOS/rootfs.img" for dracut
compressargs = compressargs or []
workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir") workdir = joinpaths(os.path.dirname(outfile), "runtime-workdir")
if size: if size:
fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin' fssize = size * (1024*1024*1024) # 2GB sparse file compresses down to nothin'
@ -181,18 +182,20 @@ class TreeBuilder(object):
self._runner = LoraxTemplateRunner(inroot, outroot, templatedir=templatedir) self._runner = LoraxTemplateRunner(inroot, outroot, templatedir=templatedir)
self._runner.defaults = self.vars self._runner.defaults = self.vars
self.templatedir = templatedir self.templatedir = templatedir
self.treeinfo_data = None
@property @property
def kernels(self): def kernels(self):
return findkernels(root=self.vars.inroot) return findkernels(root=self.vars.inroot)
def rebuild_initrds(self, add_args=[], backup="", prefix=""): def rebuild_initrds(self, add_args=None, backup="", prefix=""):
'''Rebuild all the initrds in the tree. If backup is specified, each '''Rebuild all the initrds in the tree. If backup is specified, each
initrd will be renamed with backup as a suffix before rebuilding. initrd will be renamed with backup as a suffix before rebuilding.
If backup is empty, the existing initrd files will be overwritten. If backup is empty, the existing initrd files will be overwritten.
If suffix is specified, the existing initrd is untouched and a new If suffix is specified, the existing initrd is untouched and a new
image is built with the filename "${prefix}-${kernel.version}.img" image is built with the filename "${prefix}-${kernel.version}.img"
''' '''
add_args = add_args or []
dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + add_args dracut = ["dracut", "--nomdadmconf", "--nolvmconf"] + add_args
if not backup: if not backup:
dracut.append("--force") dracut.append("--force")
@ -231,7 +234,7 @@ class TreeBuilder(object):
self.implantisomd5() self.implantisomd5()
def implantisomd5(self): def implantisomd5(self):
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'])
runcmd(["implantisomd5", iso]) runcmd(["implantisomd5", iso])
@ -261,7 +264,7 @@ class TreeBuilder(object):
for hook_script, dracut_path in hooks: for hook_script, dracut_path in hooks:
src = joinpaths(self.dracut_hooks_path, hook_script) src = joinpaths(self.dracut_hooks_path, hook_script)
if not os.path.exists(src): if not os.path.exists(src):
logger.error("Missing lorax dracut hook script %s" % (src)) logger.error("Missing lorax dracut hook script %s", (src))
continue continue
dst = joinpaths(self.vars.inroot, "/tmp/", hook_script) dst = joinpaths(self.vars.inroot, "/tmp/", hook_script)
copy2(src, dst) copy2(src, dst)
@ -289,13 +292,13 @@ def findkernels(root="/", kdir="boot"):
for kernel in kernels: for kernel in kernels:
for f in bootfiles: for f in bootfiles:
if f.endswith('-'+kernel.version+'.img'): if f.endswith('-'+kernel.version+'.img'):
imgtype, rest = f.split('-',1) imgtype, _rest = f.split('-',1)
# special backwards-compat case # special backwards-compat case
if imgtype == 'initramfs': if imgtype == 'initramfs':
imgtype = 'initrd' imgtype = 'initrd'
kernel[imgtype] = DataHolder(path=joinpaths(kdir, f)) kernel[imgtype] = DataHolder(path=joinpaths(kdir, f))
logger.debug("kernels=%s" % kernels) logger.debug("kernels=%s", kernels)
return kernels return kernels
# udev whitelist: 'a-zA-Z0-9#+.:=@_-' (see is_whitelisted in libudev-util.c) # udev whitelist: 'a-zA-Z0-9#+.:=@_-' (see is_whitelisted in libudev-util.c)

View File

@ -23,7 +23,7 @@ import logging
logger = logging.getLogger("pylorax.yumhelper") logger = logging.getLogger("pylorax.yumhelper")
import sys import sys
import yum, yum.callbacks, yum.rpmtrans import yum, yum.callbacks, yum.rpmtrans
import output import pylorax.output as output
__all__ = ['LoraxDownloadCallback', 'LoraxTransactionCallback', __all__ = ['LoraxDownloadCallback', 'LoraxTransactionCallback',
'LoraxRpmCallback'] 'LoraxRpmCallback']