Moved and renamed some of the source files.
Improved the LDD class to search both lib and lib64 directories for libraries. Made some small changes to fileutils and fileactions.
This commit is contained in:
parent
2908d5a3c4
commit
1da93076b4
@ -1,9 +1,81 @@
|
||||
# initrd template file
|
||||
#
|
||||
# supported variables: @initrd@
|
||||
# @instroot@
|
||||
# initrd template
|
||||
|
||||
:makedir
|
||||
@initrd@/modules
|
||||
@initrd@/sbin
|
||||
@initrd@/dev
|
||||
@initrd@/etc
|
||||
@initrd@/etc/udev/rules.d
|
||||
@initrd@/lib/udev/rules.d
|
||||
@initrd@/proc
|
||||
@initrd@/selinux
|
||||
@initrd@/sys
|
||||
@initrd@/etc/terminfo/{a,b,d,l,s,v,x}
|
||||
@initrd@/tmp
|
||||
@initrd@/usr/libexec
|
||||
@initrd@/usr/@libdir@/NetworkManager
|
||||
@initrd@/usr/share/dbus-1/system-services
|
||||
@initrd@/var/cache/hald
|
||||
@initrd@/var/lib/dbus
|
||||
@initrd@/var/lib/dhclient
|
||||
@initrd@/var/lock/rpm
|
||||
@initrd@/var/run
|
||||
@initrd@/var/run/dbus
|
||||
@initrd@/var/run/hald
|
||||
@initrd@/var/run/NetworkManager
|
||||
@initrd@/etc/dbus-1/system.d
|
||||
@initrd@/etc/modprobe.d
|
||||
@initrd@/etc/NetworkManager/dispatcher.d
|
||||
@initrd@/@libdir@/dbus-1
|
||||
@initrd@/etc/sysconfig/network-scripts
|
||||
@initrd@/usr/share/PolicyKit/policy
|
||||
@initrd@/etc/PolicyKit
|
||||
@initrd@/var/lib/misc
|
||||
@initrd@/etc/hal/fdi
|
||||
@initrd@/usr/share/hal/fdi
|
||||
@initrd@/usr/share/hwdata
|
||||
@initrd@/etc/rc.d/init.d
|
||||
@initrd@/usr/sbin
|
||||
@initrd@/var/run/wpa_supplicant
|
||||
|
||||
:edit
|
||||
@initrd@/etc/arch text "@buildarch@"
|
||||
|
||||
|
||||
:copy
|
||||
# comment
|
||||
@instroot@/bin/bash to @initrd@/bin
|
||||
@instroot@/bin/mount to @initrd@/bin
|
||||
@instroot@/etc/passwd to @initrd@/etc
|
||||
@instroot@/etc/group to @initrd@/etc
|
||||
@instroot@/etc/nsswitch.conf to @initrd@/etc
|
||||
|
||||
# mount/umount
|
||||
:copy
|
||||
@instroot@/bin/mount to @initrd@/sbin/mount
|
||||
@instroot@/bin/umount to @initrd@/sbin/umount
|
||||
@instroot@/usr/sbin/mount.nfs to @initrd@/sbin/mount.nfs
|
||||
:link
|
||||
@initrd@/sbin/umount.nfs to @initrd@/sbin/mount.nfs
|
||||
|
||||
# udev
|
||||
:copy
|
||||
@instroot@/sbin/udevd to @initrd@/sbin
|
||||
@instroot@/sbin/udevadm to @initrd@/sbin
|
||||
:link
|
||||
@initrd@/sbin/udevinfo to @initrd@/sbin/udevadm
|
||||
@initrd@/sbin/udevsettle to @initrd@/sbin/udevadm
|
||||
|
||||
# bash
|
||||
:copy
|
||||
@instroot@/bin/bash to @initrd@/sbin/bash
|
||||
:link
|
||||
@initrd@/sbin/sh to @initrd@/sbin/bash
|
||||
:copy
|
||||
@instroot@/sbin/consoletype to @initrd@/sbin/consoletype
|
||||
@instroot@/usr/bin/logger to @initrd@/sbin/logger
|
||||
|
||||
:copy
|
||||
@instroot@/etc/rc.d/init.d/functions to @initrd@/etc/rc.d/init.d
|
||||
@instroot@/etc/sysconfig/network-scripts/network-functions* @initrd@/etc/sysconfig/network-scripts
|
||||
|
||||
:link
|
||||
@initrd@/etc/init.d to /etc/rc.d/init.d
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# __init__.py
|
||||
# pylorax/__init__.py
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
@ -1,5 +1,10 @@
|
||||
# pylorax/actions/__init__.py
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger('pylorax.actions')
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
@ -7,22 +12,28 @@ def getActions():
|
||||
actions = {}
|
||||
root, actions_dir = os.path.split(os.path.dirname(__file__))
|
||||
|
||||
sys.path.insert(0, root)
|
||||
|
||||
modules = set()
|
||||
for filename in os.listdir(os.path.join(root, actions_dir)):
|
||||
if filename.endswith('.py') and filename != '__init__.py':
|
||||
basename, extension = os.path.splitext(filename)
|
||||
modules.add(os.path.join('pylorax', actions_dir, basename).replace('/', '.'))
|
||||
modules.add(os.path.join(actions_dir, basename).replace('/', '.'))
|
||||
|
||||
for module in modules:
|
||||
print('Loading actions from %s' % module)
|
||||
logger.debug('loading actions from module %s' % module)
|
||||
imported = __import__(module, globals(), locals(), [module], -1)
|
||||
|
||||
try:
|
||||
commands = getattr(imported, 'COMMANDS')
|
||||
except AttributeError:
|
||||
logger.debug('no actions found')
|
||||
continue
|
||||
else:
|
||||
for command, classname in commands.items():
|
||||
print('Loaded: %s' % classname)
|
||||
logger.debug('loaded: %s' % classname)
|
||||
actions[command] = getattr(imported, classname)
|
||||
|
||||
sys.path.pop(0)
|
||||
|
||||
return actions
|
||||
|
@ -1,20 +1,79 @@
|
||||
# pylorax/actions/fileactions.py
|
||||
|
||||
from pylorax.base import LoraxAction
|
||||
# pylorax/actions/base.py
|
||||
|
||||
import os
|
||||
import re
|
||||
from pylorax.utils.fileutil import cp, mv, touch, edit, replace
|
||||
|
||||
from pylorax.utils.fileutils import cp, mv, touch, edit, replace
|
||||
|
||||
|
||||
# command:action mapping
|
||||
# maps a template command to an action class
|
||||
# if you want your new action to be supported, you have to include it in this mapping
|
||||
COMMANDS = { 'copy': 'Copy',
|
||||
'move': 'Move',
|
||||
'link': 'Link',
|
||||
'touch': 'Touch',
|
||||
'edit': 'Edit',
|
||||
'replace': 'Replace' }
|
||||
'replace': 'Replace',
|
||||
'makedir': 'MakeDir' }
|
||||
|
||||
|
||||
class LoraxAction(object):
|
||||
"""Actions base class.
|
||||
|
||||
To create your own custom action, subclass this class and override the methods you need.
|
||||
|
||||
A valid action has to have a REGEX class variable, which specifies the format of the action
|
||||
command line, so the needed parameters can be properly extracted from it.
|
||||
All the work should be done in the execute method, which will be called from Lorax.
|
||||
At the end, set the success to False, or True depending on the success or failure of your action.
|
||||
|
||||
If you need to install some package prior to executing the action, return an install pattern
|
||||
with the "install" property. Lorax will get this first, and will try to install the needed
|
||||
package.
|
||||
|
||||
Don't forget to include a command:action map for your new action in the COMMANDS dictionary.
|
||||
Action classes which are not in the COMMANDS dictionary will not be loaded.
|
||||
|
||||
You can take a look at some of the builtin actions to get an idea of how to create your
|
||||
own actions."""
|
||||
|
||||
|
||||
REGEX = r'' # regular expression for extracting the parameters from the command line
|
||||
|
||||
def __init__(self):
|
||||
if self.__class__ is LoraxAction:
|
||||
raise TypeError, 'LoraxAction is an abstract class, cannot be used this way'
|
||||
|
||||
self._attrs = {}
|
||||
self._attrs['success'] = None # success is None, if the action wasn't executed yet
|
||||
|
||||
def __str__(self):
|
||||
return '%s: %s' % (self.__class__.__name__, self._attrs)
|
||||
|
||||
def execute(self, verbose=False):
|
||||
"""This method is the main body of the action. Put all the "work" stuff in here."""
|
||||
raise NotImplementedError, 'execute method not implemented for LoraxAction class'
|
||||
|
||||
@property
|
||||
def success(self):
|
||||
"""Returns if the action's execution was successful or not."""
|
||||
return self._attrs['success']
|
||||
|
||||
@property
|
||||
def install(self):
|
||||
"""Returns a pattern that needs to be installed, prior to calling the execute method."""
|
||||
return None
|
||||
|
||||
def getDeps(self):
|
||||
# FIXME hmmm, how can i do this more generic?
|
||||
return None
|
||||
|
||||
|
||||
# +-----------------+
|
||||
# | builtin actions |
|
||||
# +-----------------+
|
||||
|
||||
class Copy(LoraxAction):
|
||||
|
||||
REGEX = r'^(?P<src>.*?)\sto\s(?P<dst>.*?)(\smode\s(?P<mode>.*?))?$'
|
||||
@ -33,9 +92,6 @@ class Copy(LoraxAction):
|
||||
cp(src=self.src, dst=self.dst, mode=self.mode, verbose=verbose)
|
||||
self._attrs['success'] = True
|
||||
|
||||
def getDeps(self):
|
||||
return self._attrs['src']
|
||||
|
||||
@property
|
||||
def src(self):
|
||||
return self._attrs['src']
|
||||
@ -50,7 +106,11 @@ class Copy(LoraxAction):
|
||||
|
||||
@property
|
||||
def install(self):
|
||||
return self._attrs.get('src')
|
||||
return self._attrs['src']
|
||||
|
||||
@property
|
||||
def getDeps(self):
|
||||
return self._attrs['src']
|
||||
|
||||
|
||||
class Move(Copy):
|
||||
@ -68,10 +128,6 @@ class Link(LoraxAction):
|
||||
self._attrs['name'] = kwargs.get('name')
|
||||
self._attrs['target'] = kwargs.get('target')
|
||||
|
||||
file = getFileName(self._attrs['name'])
|
||||
if file:
|
||||
self._attrs['install'] = file
|
||||
|
||||
def execute(self, verbose=False):
|
||||
os.symlink(self.name, self.target)
|
||||
self._attrs['success'] = True
|
||||
@ -86,7 +142,7 @@ class Link(LoraxAction):
|
||||
|
||||
@property
|
||||
def install(self):
|
||||
return self._attrs['install']
|
||||
return self._attrs['target']
|
||||
|
||||
|
||||
class Touch(LoraxAction):
|
||||
@ -120,10 +176,6 @@ class Edit(Touch):
|
||||
else:
|
||||
self._attrs['append'] = False
|
||||
|
||||
file = getFileName(self._attrs['filename'])
|
||||
if file:
|
||||
self._attrs['install'] = file
|
||||
|
||||
def execute(self, verbose=False):
|
||||
edit(filename=self.filename, text=self.text, append=self.append, verbose=verbose)
|
||||
self._attrs['success'] = True
|
||||
@ -138,7 +190,7 @@ class Edit(Touch):
|
||||
|
||||
@property
|
||||
def install(self):
|
||||
return self._attrs['install']
|
||||
return self._attrs['filename']
|
||||
|
||||
|
||||
class Replace(Touch):
|
||||
@ -150,10 +202,6 @@ class Replace(Touch):
|
||||
self._attrs['find'] = kwargs.get('find')
|
||||
self._attrs['replace'] = kwargs.get('replace')
|
||||
|
||||
file = getFileName(self._attrs['filename'])
|
||||
if file:
|
||||
self._attrs['install'] = file
|
||||
|
||||
def execute(self, verbose=False):
|
||||
replace(filename=self.filename, find=self.find, replace=self.replace, verbose=verbose)
|
||||
self._attrs['success'] = True
|
||||
@ -168,4 +216,27 @@ class Replace(Touch):
|
||||
|
||||
@property
|
||||
def install(self):
|
||||
return self._attrs['install']
|
||||
return self._attrs['filename']
|
||||
|
||||
|
||||
class MakeDir(LoraxAction):
|
||||
|
||||
REGEX = r'^(?P<dir>.*?)(\smode\s(?P<mode>.*?))?$'
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
LoraxAction.__init__(self)
|
||||
self._attrs['dir'] = kwargs.get('dir')
|
||||
self._attrs['mode'] = kwargs.get('mode')
|
||||
|
||||
def execute(self, verbose=False):
|
||||
if not os.path.isdir(self.dir):
|
||||
os.makedirs(path=self.dir, mode=self.mode)
|
||||
self._attrs['success'] = True
|
||||
|
||||
@property
|
||||
def dir(self):
|
||||
return self._attrs['dir']
|
||||
|
||||
@property
|
||||
def mode(self):
|
||||
return self._attrs['mode']
|
@ -3,28 +3,6 @@
|
||||
import commands
|
||||
|
||||
|
||||
class LoraxAction(object):
|
||||
|
||||
REGEX = r'.*'
|
||||
|
||||
def __init__(self):
|
||||
if self.__class__ is LoraxAction:
|
||||
raise TypeError, 'LoraxAction is an abstract class'
|
||||
|
||||
self._attrs = {}
|
||||
self._attrs['success'] = None
|
||||
|
||||
def __str__(self):
|
||||
return '%s: %s' % (self.__class__.__name__, self._attrs)
|
||||
|
||||
def execute(self, verbose=False):
|
||||
raise NotImplementedError, 'execute method not implemented for LoraxAction class'
|
||||
|
||||
@property
|
||||
def success(self):
|
||||
return self._attrs['success']
|
||||
|
||||
|
||||
def seq(arg):
|
||||
if type(arg) not in (type([]), type(())):
|
||||
return [arg]
|
||||
|
@ -87,6 +87,12 @@ class Template(object):
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
# check vars
|
||||
for lineno, line in enumerate(lines, start=1):
|
||||
for var in re.findall(r'@.*?@', line)
|
||||
if var not in vars:
|
||||
raise TemplateError, 'unknown variable "%s" on line %d' % (var, lineno)
|
||||
|
||||
active_action = ''
|
||||
in_action = False
|
||||
for lineno, line in enumerate(lines, start=1):
|
||||
|
@ -30,7 +30,7 @@ class Images(object):
|
||||
pkgs = i.getPkgs()
|
||||
|
||||
# install needed packages
|
||||
self.yum.addPackages(['anaconda', 'anaconda-runtime', 'kernel', 'syslinux', 'memtest'])
|
||||
self.yum.addPackages(['anaconda', 'anaconda-runtime', 'kernel', 'syslinux'])
|
||||
self.yum.addPackages(pkgs)
|
||||
self.yum.install()
|
||||
|
||||
|
@ -26,7 +26,12 @@ class InitRD(object):
|
||||
'initrd'))
|
||||
|
||||
vars = { '@instroot@': self.conf.treedir,
|
||||
'@initrd@': self.conf.initrddir }
|
||||
'@initrd@': self.conf.initrddir,
|
||||
'@libdir@': self.conf.libdir,
|
||||
'@buildarch@': self.conf.buildarch,
|
||||
'@confdir@' : self.conf.confdir,
|
||||
'@datadir@': self.conf.datadir }
|
||||
|
||||
self.template = Template()
|
||||
for file in initrd_templates:
|
||||
if os.path.isfile(file):
|
||||
|
@ -9,16 +9,28 @@ import re
|
||||
|
||||
|
||||
def cp(src, dst, mode=None, verbose=False):
|
||||
errors = []
|
||||
for name in glob.iglob(src):
|
||||
__copy(name, dst, verbose=verbose)
|
||||
if mode:
|
||||
os.chmod(dst, mode)
|
||||
rc = __copy(name, dst, verbose=verbose)
|
||||
if not rc:
|
||||
errors.append('unable to copy "%s" to "%s"' % (name, dst))
|
||||
else:
|
||||
if mode:
|
||||
os.chmod(dst, mode)
|
||||
|
||||
return errors
|
||||
|
||||
def mv(src, dst, mode=None, verbose=False):
|
||||
errors = []
|
||||
for name in glob.iglob(src):
|
||||
__copy(name, dst, verbose=verbose, remove=True)
|
||||
if mode:
|
||||
os.chmod(dst, mode)
|
||||
rc = __copy(name, dst, verbose=verbose, remove=True)
|
||||
if not rc:
|
||||
errors.append('unable to move "%s" to "%s"' % (name, dst))
|
||||
else:
|
||||
if mode:
|
||||
os.chmod(dst, mode)
|
||||
|
||||
return errors
|
||||
|
||||
def rm(target, verbose=False):
|
||||
if os.path.isdir(target):
|
||||
@ -30,10 +42,12 @@ def rm(target, verbose=False):
|
||||
print('removing file "%s"' % target)
|
||||
os.unlink(target)
|
||||
|
||||
return True
|
||||
|
||||
def __copy(src, dst, verbose=False, remove=False):
|
||||
if not os.path.exists(src):
|
||||
sys.stderr.write('cannot stat "%s": No such file or directory\n' % src)
|
||||
return
|
||||
return False
|
||||
|
||||
if os.path.isdir(dst):
|
||||
basename = os.path.basename(src)
|
||||
@ -42,7 +56,7 @@ def __copy(src, dst, verbose=False, remove=False):
|
||||
if os.path.isdir(src):
|
||||
if os.path.isfile(dst):
|
||||
sys.stderr.write('omitting directory "%s"\n' % src)
|
||||
return
|
||||
return False
|
||||
|
||||
if not os.path.isdir(dst):
|
||||
os.makedirs(dst)
|
||||
@ -53,7 +67,7 @@ def __copy(src, dst, verbose=False, remove=False):
|
||||
else:
|
||||
if os.path.isdir(dst):
|
||||
sys.stderr.write('cannot overwrite directory "%s" with non-directory\n' % dst)
|
||||
return
|
||||
return False
|
||||
|
||||
try:
|
||||
if verbose:
|
||||
@ -61,19 +75,26 @@ def __copy(src, dst, verbose=False, remove=False):
|
||||
shutil.copy2(src, dst)
|
||||
except (shutil.Error, IOError) as why:
|
||||
sys.stderr.write('cannot copy "%s" to "%s": %s\n' % (src, dst, why))
|
||||
return False
|
||||
else:
|
||||
if remove:
|
||||
if verbose:
|
||||
print('removing "%s"' % src)
|
||||
os.unlink(src)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def touch(filename, verbose=False):
|
||||
if os.path.exists(filename):
|
||||
if verbose:
|
||||
print('touching file "%s"' % filename)
|
||||
os.utime(filename, None)
|
||||
return True
|
||||
|
||||
try:
|
||||
if verbose:
|
||||
print('creating file "%s"' % filename)
|
||||
f = open(filename, 'w')
|
||||
except IOError:
|
||||
return False
|
||||
@ -87,6 +108,8 @@ def edit(filename, text, append=False, verbose=False):
|
||||
mode = 'a'
|
||||
|
||||
try:
|
||||
if verbose:
|
||||
print('editing file "%s"' % filename)
|
||||
f = open(filename, mode)
|
||||
except IOError:
|
||||
return False
|
||||
@ -96,6 +119,8 @@ def edit(filename, text, append=False, verbose=False):
|
||||
return True
|
||||
|
||||
def replace(filename, find, replace, verbose=False):
|
||||
if verbose:
|
||||
print('replacing "%s" for "%s" in file "%s"' % (find, replace, filename))
|
||||
fin = fileinput.input(filename, inplace=1)
|
||||
for line in fin:
|
||||
line = re.sub(find, replace, line)
|
@ -1,4 +1,4 @@
|
||||
import sys
|
||||
# pylorax/utils/libutil.py
|
||||
|
||||
import os
|
||||
import commands
|
||||
@ -6,7 +6,7 @@ import re
|
||||
|
||||
|
||||
class LDD(object):
|
||||
def __init__(self, libroot='/'):
|
||||
def __init__(self, libroot='/lib'):
|
||||
f = open('/usr/bin/ldd', 'r')
|
||||
for line in f.readlines():
|
||||
line = line.strip()
|
||||
@ -15,7 +15,14 @@ class LDD(object):
|
||||
break
|
||||
f.close()
|
||||
|
||||
self._ldd = '%s --list --library-path %s' % (ld_linux, libroot)
|
||||
if libroot.endswith('/') and libroot != '/':
|
||||
libroot = libroot[:-1]
|
||||
|
||||
libpaths = [libroot]
|
||||
if libroot.endswith('64'):
|
||||
libpaths.append(libroot[:-2])
|
||||
|
||||
self._ldd = 'LD_LIBRARY_PATH="%s" %s --list' % (':'.join(libpaths), ld_linux)
|
||||
self._deps = set()
|
||||
|
||||
def getDeps(self, filename):
|
||||
@ -46,12 +53,3 @@ class LDD(object):
|
||||
@property
|
||||
def deps(self):
|
||||
return self._deps
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
ldd = LDD(libroot=sys.argv[2])
|
||||
ldd.getDeps(sys.argv[1])
|
||||
ldd.getLinks()
|
||||
|
||||
for dep in ldd.deps:
|
||||
print dep
|
||||
|
Loading…
Reference in New Issue
Block a user