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:
Martin Gracik 2009-06-08 16:54:20 +02:00
parent 2908d5a3c4
commit 1da93076b4
11 changed files with 246 additions and 80 deletions

View File

@ -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

View File

@ -1,4 +1,4 @@
# __init__.py
# pylorax/__init__.py
import sys
import os

View File

@ -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

View File

@ -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']

View File

@ -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]

View File

@ -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):

View File

@ -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()

View File

@ -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):

View 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)

View File

@ -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