Made some code and file cleanup.
This commit is contained in:
parent
1da93076b4
commit
032438ddbc
@ -1,81 +1,76 @@
|
||||
# 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
|
||||
# create required directories
|
||||
makedir @initrd@/modules
|
||||
makedir @initrd@/sbin
|
||||
makedir @initrd@/dev
|
||||
makedir @initrd@/etc
|
||||
makedir @initrd@/etc/udev/rules.d
|
||||
makedir @initrd@/lib/udev/rules.d
|
||||
makedir @initrd@/proc
|
||||
makedir @initrd@/selinux
|
||||
makedir @initrd@/sys
|
||||
makedir @initrd@/etc/terminfo/a
|
||||
makedir @initrd@/etc/terminfo/b
|
||||
makedir @initrd@/etc/terminfo/d
|
||||
makedir @initrd@/etc/terminfo/l
|
||||
makedir @initrd@/etc/terminfo/s
|
||||
makedir @initrd@/etc/terminfo/v
|
||||
makedir @initrd@/etc/terminfo/x
|
||||
makedir @initrd@/tmp
|
||||
makedir @initrd@/usr/libexec
|
||||
makedir @initrd@/usr/@libdir@/NetworkManager
|
||||
makedir @initrd@/usr/share/dbus-1/system-services
|
||||
makedir @initrd@/var/cache/hald
|
||||
makedir @initrd@/var/lib/dbus
|
||||
makedir @initrd@/var/lib/dhclient
|
||||
makedir @initrd@/var/lock/rpm
|
||||
makedir @initrd@/var/run
|
||||
makedir @initrd@/var/run/dbus
|
||||
makedir @initrd@/var/run/hald
|
||||
makedir @initrd@/var/run/NetworkManager
|
||||
makedir @initrd@/etc/dbus-1/system.d
|
||||
makedir @initrd@/etc/modprobe.d
|
||||
makedir @initrd@/etc/NetworkManager/dispatcher.d
|
||||
makedir @initrd@/@libdir@/dbus-1
|
||||
makedir @initrd@/etc/sysconfig/network-scripts
|
||||
makedir @initrd@/usr/share/PolicyKit/policy
|
||||
makedir @initrd@/etc/PolicyKit
|
||||
makedir @initrd@/var/lib/misc
|
||||
makedir @initrd@/etc/hal/fdi
|
||||
makedir @initrd@/usr/share/hal/fdi
|
||||
makedir @initrd@/usr/share/hwdata
|
||||
makedir @initrd@/etc/rc.d/init.d
|
||||
makedir @initrd@/usr/sbin
|
||||
makedir @initrd@/var/run/wpa_supplicant
|
||||
|
||||
:edit
|
||||
@initrd@/etc/arch text "@buildarch@"
|
||||
# set the buildarch
|
||||
edit @initrd@/etc/arch text "@buildarch@"
|
||||
|
||||
# copy etc
|
||||
copy @instroot@/etc/passwd to @initrd@/etc
|
||||
copy @instroot@/etc/group to @initrd@/etc
|
||||
copy @instroot@/etc/nsswitch.conf to @initrd@/etc
|
||||
|
||||
:copy
|
||||
@instroot@/etc/passwd to @initrd@/etc
|
||||
@instroot@/etc/group to @initrd@/etc
|
||||
@instroot@/etc/nsswitch.conf to @initrd@/etc
|
||||
# copy mount/umount
|
||||
copy @instroot@/bin/mount to @initrd@/sbin/mount
|
||||
copy @instroot@/bin/umount to @initrd@/sbin/umount
|
||||
copy @instroot@/sbin/mount.nfs to @initrd@/sbin/mount.nfs
|
||||
link @initrd@/sbin/umount.nfs to mount.nfs
|
||||
|
||||
# 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
|
||||
# copy udev
|
||||
copy @instroot@/sbin/udevd to @initrd@/sbin
|
||||
copy @instroot@/sbin/udevadm to @initrd@/sbin
|
||||
link @initrd@/sbin/udevinfo to udevadm
|
||||
link @initrd@/sbin/udevsettle to udevadm
|
||||
|
||||
# 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
|
||||
# copy bash
|
||||
copy @instroot@/bin/bash to @initrd@/sbin/bash
|
||||
link @initrd@/sbin/sh to bash
|
||||
copy @instroot@/sbin/consoletype to @initrd@/sbin/consoletype
|
||||
copy @instroot@/usr/bin/logger to @initrd@/sbin/logger
|
||||
|
||||
# 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
|
||||
copy @instroot@/etc/rc.d/init.d/functions to @initrd@/etc/rc.d/init.d
|
||||
copy @instroot@/etc/sysconfig/network-scripts/network-functions* to @initrd@/etc/sysconfig/network-scripts
|
||||
|
||||
link @initrd@/etc/init.d to /etc/rc.d/init.d
|
||||
|
10
share/images/README
Normal file
10
share/images/README
Normal file
@ -0,0 +1,10 @@
|
||||
This directory contains image files that can be used to create media
|
||||
capable of starting the @PRODUCT@ installation process.
|
||||
|
||||
The boot.iso file is an ISO 9660 image of a bootable CD-ROM. It is useful
|
||||
in cases where the CD-ROM installation method is not desired, but the
|
||||
CD-ROM's boot speed would be an advantage.
|
||||
|
||||
To use this image file, burn the file onto CD-R (or CD-RW) media as you
|
||||
normally would.
|
||||
|
7
share/images/pxeboot/README
Normal file
7
share/images/pxeboot/README
Normal file
@ -0,0 +1,7 @@
|
||||
The files in this directory are useful for booting a machine via PXE.
|
||||
|
||||
The following files are available:
|
||||
vmlinuz - the kernel used for the installer
|
||||
initrd.img - an initrd with support for all install methods and
|
||||
drivers supported for installation of @PRODUCT@
|
||||
|
@ -7,14 +7,14 @@ import tempfile
|
||||
import time
|
||||
import ConfigParser
|
||||
import re
|
||||
from errors import LoraxError
|
||||
|
||||
from config import Container
|
||||
import utils.rpmutil as rpmutil
|
||||
from utils.rpmutils import Yum
|
||||
from utils.fileutils import rm
|
||||
|
||||
import images
|
||||
|
||||
from exceptions import LoraxError
|
||||
|
||||
|
||||
class Config(Container):
|
||||
def __init__(self):
|
||||
@ -52,50 +52,52 @@ class Lorax(object):
|
||||
|
||||
# check if we have all required options
|
||||
if not self.conf.repos:
|
||||
raise LoraxError, 'missing repos'
|
||||
raise LoraxError, "missing required parameter 'repos'"
|
||||
if not self.conf.outdir:
|
||||
raise LoraxError, 'missing outdir'
|
||||
raise LoraxError, "missing required parameter 'outdir'"
|
||||
if not self.conf.product:
|
||||
raise LoraxError, 'missing product'
|
||||
raise LoraxError, "missing required parameter 'product'"
|
||||
if not self.conf.version:
|
||||
raise LoraxError, 'missing version'
|
||||
raise LoraxError, "missing required parameter 'version'"
|
||||
if not self.conf.release:
|
||||
raise LoraxError, 'missing release'
|
||||
raise LoraxError, "missing required parameter 'release'"
|
||||
|
||||
self.yum = None
|
||||
|
||||
def run(self):
|
||||
print('Collecting repos...')
|
||||
bold = ('\033[1m', '\033[0m')
|
||||
|
||||
print('%sCollecting repos%s' % bold)
|
||||
self.collectRepos()
|
||||
|
||||
# check if we have at least one valid repository
|
||||
if not self.conf.repo:
|
||||
sys.stderr.write('ERROR: no valid repository\n')
|
||||
sys.stderr.write('ERROR: No valid repository\n')
|
||||
sys.exit(1)
|
||||
|
||||
print('Initializing directories...')
|
||||
print('%sInitializing directories%s' % bold)
|
||||
self.initDirs()
|
||||
|
||||
print('Initializing yum...')
|
||||
print('%sInitializing yum%s' % bold)
|
||||
self.initYum()
|
||||
|
||||
print('Setting build architecture...')
|
||||
print('%sSetting build architecture%s' % bold)
|
||||
self.setBuildArch()
|
||||
|
||||
print('Writing .treeinfo...')
|
||||
print('%sWriting .treeinfo%s' % bold)
|
||||
self.writeTreeInfo()
|
||||
|
||||
print('Writing .discinfo...')
|
||||
print('%sWriting .discinfo%s' % bold)
|
||||
self.writeDiscInfo()
|
||||
|
||||
print('Preparing the install tree...')
|
||||
print('%sPreparing the install tree%s' % bold)
|
||||
self.prepareInstRoot()
|
||||
|
||||
print('Creating the images...')
|
||||
print('%sCreating the images%s' % bold)
|
||||
self.makeImages()
|
||||
|
||||
if self.conf.cleanup:
|
||||
print('Cleaning up...')
|
||||
print('%sCleaning up%s' % bold)
|
||||
self.cleanUp()
|
||||
|
||||
def collectRepos(self):
|
||||
@ -128,7 +130,7 @@ class Lorax(object):
|
||||
os.makedirs(treedir)
|
||||
cachedir = os.path.join(self.conf.tempdir, 'yumcache')
|
||||
os.makedirs(cachedir)
|
||||
initrddir = os.path.join(self.conf.tempdir, 'initrd')
|
||||
initrddir = os.path.join(self.conf.tempdir, 'initrddir')
|
||||
os.makedirs(initrddir)
|
||||
|
||||
print('Working directories:')
|
||||
@ -145,8 +147,8 @@ class Lorax(object):
|
||||
|
||||
try:
|
||||
f = open(yumconf, 'w')
|
||||
except IOError:
|
||||
sys.stderr.write('ERROR: Unable to write yum.conf file\n')
|
||||
except IOError as why:
|
||||
sys.stderr.write('ERROR: Unable to write yum.conf file: %s\n' % why)
|
||||
sys.exit(1)
|
||||
else:
|
||||
f.write('[main]\n')
|
||||
@ -179,10 +181,11 @@ class Lorax(object):
|
||||
self.conf.addAttr('yumconf')
|
||||
self.conf.set(yumconf=yumconf)
|
||||
|
||||
self.yum = rpmutil.Yum(yumconf=self.conf.yumconf, installroot=self.conf.treedir)
|
||||
# create the Yum object
|
||||
self.yum = Yum(yumconf=self.conf.yumconf, installroot=self.conf.treedir)
|
||||
|
||||
# remove not needed options
|
||||
self.conf.delAttr(['repo', 'extrarepos', 'mirrorlist'])
|
||||
# remove not needed attributes
|
||||
self.conf.delAttr(['repo', 'extrarepos', 'mirrorlist', 'cachedir'])
|
||||
|
||||
def setBuildArch(self):
|
||||
unamearch = os.uname()[4]
|
||||
@ -190,10 +193,11 @@ class Lorax(object):
|
||||
self.conf.addAttr('buildarch')
|
||||
self.conf.set(buildarch=unamearch)
|
||||
|
||||
anaconda = self.yum.find('anaconda')
|
||||
installed, available = self.yum.find('anaconda')
|
||||
try:
|
||||
self.conf.set(buildarch=anaconda[0].arch)
|
||||
self.conf.set(buildarch=available[0].arch)
|
||||
except:
|
||||
# FIXME specify what exceptions can we get here
|
||||
pass
|
||||
|
||||
# set the libdir
|
||||
@ -206,7 +210,7 @@ class Lorax(object):
|
||||
def writeTreeInfo(self, discnum=1, totaldiscs=1, packagedir=''):
|
||||
outfile = os.path.join(self.conf.outdir, '.treeinfo')
|
||||
|
||||
# don't print anything instead of None if variant is not specified
|
||||
# don't print anything instead of None, if variant is not specified
|
||||
variant = ''
|
||||
if self.conf.variant:
|
||||
variant = self.conf.variant
|
||||
@ -232,7 +236,8 @@ class Lorax(object):
|
||||
c.set(section, 'kernel', 'images/pxeboot/vmlinuz')
|
||||
c.set(section, 'initrd', 'images/pxeboot/initrd.img')
|
||||
|
||||
# XXX actually create the boot iso somewhere, and set up this attribute
|
||||
# XXX actually create the boot iso somewhere before calling writeTreeInfo(),
|
||||
# and set up this attribute properly
|
||||
self.conf.addAttr('bootiso')
|
||||
|
||||
if self.conf.bootiso:
|
||||
@ -263,7 +268,7 @@ class Lorax(object):
|
||||
return True
|
||||
|
||||
def prepareInstRoot(self):
|
||||
# XXX why do we need this?
|
||||
# XXX do we need this?
|
||||
os.symlink(os.path.join(os.path.sep, 'tmp'),
|
||||
os.path.join(self.conf.treedir, 'var', 'lib', 'xkb'))
|
||||
|
||||
@ -271,19 +276,11 @@ class Lorax(object):
|
||||
i = images.Images(self.conf, self.yum)
|
||||
i.run()
|
||||
|
||||
# XXX figure out where to put this
|
||||
#def copyUpdates(self):
|
||||
# if self.conf.updates and os.path.isdir(self.conf.updates):
|
||||
# cp(os.path.join(self.conf.updates, '*'), self.conf.treedir)
|
||||
# self.conf.delAttr('updates')
|
||||
|
||||
def cleanUp(self, trash=[]):
|
||||
for item in trash:
|
||||
if os.path.isdir(item):
|
||||
shutil.rmtree(item, ignore_errors=True)
|
||||
else:
|
||||
os.unlink(item)
|
||||
if os.path.exists(item):
|
||||
rm(item)
|
||||
|
||||
# remove the whole lorax tempdir
|
||||
if os.path.isdir(self.conf.tempdir):
|
||||
shutil.rmtree(self.conf.tempdir, ignore_errors=True)
|
||||
rm(self.conf.tempdir)
|
||||
|
@ -1,14 +1,10 @@
|
||||
# pylorax/actions/__init__.py
|
||||
|
||||
import logging
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
logger = logging.getLogger('pylorax.actions')
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def getActions():
|
||||
def getActions(verbose=False):
|
||||
actions = {}
|
||||
root, actions_dir = os.path.split(os.path.dirname(__file__))
|
||||
|
||||
@ -21,17 +17,20 @@ def getActions():
|
||||
modules.add(os.path.join(actions_dir, basename).replace('/', '.'))
|
||||
|
||||
for module in modules:
|
||||
logger.debug('loading actions from module %s' % module)
|
||||
if verbose:
|
||||
print("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')
|
||||
if verbose:
|
||||
print("No actions found")
|
||||
continue
|
||||
else:
|
||||
for command, classname in commands.items():
|
||||
logger.debug('loaded: %s' % classname)
|
||||
if verbose:
|
||||
print("Loaded: %s" % classname)
|
||||
actions[command] = getattr(imported, classname)
|
||||
|
||||
sys.path.pop(0)
|
||||
|
@ -65,14 +65,13 @@ class LoraxAction(object):
|
||||
"""Returns a pattern that needs to be installed, prior to calling the execute method."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def getDeps(self):
|
||||
# FIXME hmmm, how can i do this more generic?
|
||||
return None
|
||||
|
||||
|
||||
# +-----------------+
|
||||
# | builtin actions |
|
||||
# +-----------------+
|
||||
##### builtin actions
|
||||
|
||||
class Copy(LoraxAction):
|
||||
|
||||
@ -85,10 +84,6 @@ class Copy(LoraxAction):
|
||||
self._attrs['mode'] = kwargs.get('mode')
|
||||
|
||||
def execute(self, verbose=False):
|
||||
dst_dir = os.path.dirname(self.dst)
|
||||
if not os.path.isdir(dst_dir):
|
||||
os.makedirs(dst_dir)
|
||||
|
||||
cp(src=self.src, dst=self.dst, mode=self.mode, verbose=verbose)
|
||||
self._attrs['success'] = True
|
||||
|
||||
@ -129,7 +124,7 @@ class Link(LoraxAction):
|
||||
self._attrs['target'] = kwargs.get('target')
|
||||
|
||||
def execute(self, verbose=False):
|
||||
os.symlink(self.name, self.target)
|
||||
os.symlink(self.target, self.name)
|
||||
self._attrs['success'] = True
|
||||
|
||||
@property
|
||||
@ -230,7 +225,10 @@ class MakeDir(LoraxAction):
|
||||
|
||||
def execute(self, verbose=False):
|
||||
if not os.path.isdir(self.dir):
|
||||
os.makedirs(path=self.dir, mode=self.mode)
|
||||
if self.mode:
|
||||
os.makedirs(self.dir, mode=int(self.mode))
|
||||
else:
|
||||
os.makedirs(self.dir)
|
||||
self._attrs['success'] = True
|
||||
|
||||
@property
|
||||
|
@ -1,21 +0,0 @@
|
||||
# pylorax/base.py
|
||||
|
||||
import commands
|
||||
|
||||
|
||||
def seq(arg):
|
||||
if type(arg) not in (type([]), type(())):
|
||||
return [arg]
|
||||
else:
|
||||
return arg
|
||||
|
||||
|
||||
def getConsoleSize():
|
||||
err, output = commands.getstatusoutput('stty size')
|
||||
if not err:
|
||||
height, width = output.split()
|
||||
else:
|
||||
# set defaults
|
||||
height, width = 24, 80
|
||||
|
||||
return int(height), int(width)
|
@ -2,10 +2,9 @@
|
||||
|
||||
import sys
|
||||
import re
|
||||
from errors import TemplateError
|
||||
|
||||
from base import seq
|
||||
|
||||
from exceptions import TemplateError
|
||||
from utils.rpmutils import seq
|
||||
|
||||
|
||||
class Container(object):
|
||||
@ -24,16 +23,17 @@ class Container(object):
|
||||
|
||||
def __getitem__(self, attr):
|
||||
self.__checkInternal(attr)
|
||||
|
||||
if attr not in self.__dict__:
|
||||
raise AttributeError, "'Container' object has no attribute '%s'" % attr
|
||||
|
||||
return self.__dict__[attr]
|
||||
|
||||
def __setattr__(self, attr, value):
|
||||
raise AttributeError, 'you cannot do that, use addAttr() and set() instead'
|
||||
raise AttributeError, "you can't do that, use addAttr() and/or set()"
|
||||
|
||||
def __delattr__(self, attr):
|
||||
raise AttributeError, 'you cannot do that, use delAttr() instead'
|
||||
raise AttributeError, "you can't do that, use delAttr()"
|
||||
|
||||
def addAttr(self, attrs):
|
||||
for attr in filter(lambda attr: attr not in self.__dict__, seq(attrs)):
|
||||
@ -70,62 +70,54 @@ class Container(object):
|
||||
|
||||
def __checkInternal(self, attr):
|
||||
if attr.startswith('__'):
|
||||
raise AttributeError, 'do not mess with internal stuff'
|
||||
raise AttributeError, "do not mess with internal objects"
|
||||
|
||||
|
||||
class Template(object):
|
||||
def __init__(self):
|
||||
self._actions = []
|
||||
|
||||
def parse(self, filename, supported_actions, vars):
|
||||
def parse(self, filename, supported_actions, variables):
|
||||
try:
|
||||
f = open(filename, 'r')
|
||||
except IOError:
|
||||
sys.stdout.write('ERROR: Unable to open the template file\n')
|
||||
except IOError as why:
|
||||
sys.stderr.write("ERROR: Unable to open template file '%s': %s\n" % (filename, why))
|
||||
return False
|
||||
else:
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
|
||||
# check vars
|
||||
# check template variables
|
||||
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)
|
||||
for var in filter(lambda var: var not in variables, re.findall(r'@(.*?)@', line)):
|
||||
raise TemplateError, "unknown variable '%s' on line %d" % (var, lineno)
|
||||
|
||||
active_action = ''
|
||||
in_action = False
|
||||
# parse the template
|
||||
for lineno, line in enumerate(lines, start=1):
|
||||
line = line.strip()
|
||||
|
||||
if not line or line.startswith('#'):
|
||||
line, sep, comment = line.partition('#')
|
||||
if not line:
|
||||
continue
|
||||
|
||||
for var, value in vars.items():
|
||||
line = re.sub(r'(.*)%s(.*)' % var, '\g<1>%s\g<2>' % value, line)
|
||||
# expand variables
|
||||
for var, value in variables.items():
|
||||
line = re.sub(r'@%s@' % var, value, line)
|
||||
|
||||
if in_action and not line.startswith(':'):
|
||||
# create the action object
|
||||
regex = supported_actions[active_action].REGEX
|
||||
m = re.match(regex, line)
|
||||
if m:
|
||||
new_action = supported_actions[active_action](**m.groupdict())
|
||||
self._actions.append(new_action)
|
||||
else:
|
||||
# didn't match the regex
|
||||
raise TemplateError, 'invalid action format "%s" on line %d' % (line, lineno)
|
||||
# get the command
|
||||
command, line = line.split(None, 1)
|
||||
if command not in supported_actions:
|
||||
raise TemplateError, "unknown command '%s' on line %d" % (command, lineno)
|
||||
|
||||
if in_action and line.startswith(':'):
|
||||
in_action = False
|
||||
|
||||
if not in_action and line.startswith(':'):
|
||||
active_action = line[1:]
|
||||
|
||||
if active_action not in supported_actions:
|
||||
raise TemplateError, 'unknown action "%s" on line %d' % (active_action, lineno)
|
||||
else:
|
||||
in_action = True
|
||||
continue
|
||||
# create the action object
|
||||
regex = supported_actions[command].REGEX
|
||||
m = re.match(regex, line)
|
||||
if m:
|
||||
new_action = supported_actions[command](**m.groupdict())
|
||||
self._actions.append(new_action)
|
||||
else:
|
||||
# didn't match the regex
|
||||
raise TemplateError, "invalid command format '%s' on line %d" % (line, lineno)
|
||||
|
||||
return True
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
# pylorax/exceptions.py
|
||||
# pylorax/errors.py
|
||||
|
||||
class LoraxError(Exception):
|
||||
pass
|
@ -2,10 +2,86 @@
|
||||
|
||||
import sys
|
||||
import os
|
||||
import commands
|
||||
import re
|
||||
|
||||
from utils.fileutil import cp, mv, rm, touch, replace
|
||||
import actions
|
||||
import actions.base
|
||||
from config import Template
|
||||
|
||||
import initrd
|
||||
from utils.fileutils import cp, mv, rm, touch, edit, replace
|
||||
from utils.ldd import LDD
|
||||
|
||||
|
||||
class InitRD(object):
|
||||
def __init__(self, config, yum):
|
||||
self.conf = config
|
||||
self.yum = yum
|
||||
|
||||
# get supported actions
|
||||
supported_actions = actions.getActions()
|
||||
|
||||
initrd_templates = []
|
||||
initrd_templates.append(os.path.join(self.conf.confdir, 'templates', 'initrd'))
|
||||
initrd_templates.append(os.path.join(self.conf.confdir, 'templates', self.conf.buildarch,
|
||||
'initrd'))
|
||||
|
||||
vars = { 'instroot': self.conf.treedir,
|
||||
'initrd': self.conf.initrddir,
|
||||
'libdir': self.conf.libdir,
|
||||
'buildarch': self.conf.buildarch,
|
||||
'confdir' : self.conf.confdir,
|
||||
'datadir': self.conf.datadir }
|
||||
|
||||
self.template = Template()
|
||||
for filename in initrd_templates:
|
||||
if os.path.isfile(filename):
|
||||
self.template.parse(filename, supported_actions, vars)
|
||||
|
||||
self._actions = []
|
||||
|
||||
def getPackages(self):
|
||||
packages = []
|
||||
for action in filter(lambda action: action.install, self.template.actions):
|
||||
m = re.match(r'%s(.*)' % self.conf.treedir, action.install)
|
||||
if m:
|
||||
packages.append(m.group(1))
|
||||
|
||||
return packages
|
||||
|
||||
def getDeps(self):
|
||||
ldd = LDD(libroot=os.path.join(self.conf.treedir, self.conf.libdir))
|
||||
for action in filter(lambda action: hasattr(action, 'getDeps'), self.template.actions):
|
||||
ldd.getDeps(action.getDeps)
|
||||
|
||||
# resolve symlinks
|
||||
ldd.getLinks()
|
||||
|
||||
# add dependencies to actions
|
||||
for dep in ldd.deps:
|
||||
kwargs = {}
|
||||
kwargs['src'] = dep
|
||||
kwargs['dst'] = re.sub(r'%s(?P<file>.*)' % self.conf.treedir,
|
||||
'%s\g<file>' % self.conf.initrddir,
|
||||
dep)
|
||||
|
||||
new_action = actions.base.Copy(**kwargs)
|
||||
self._actions.append(new_action)
|
||||
|
||||
def processActions(self):
|
||||
# create the initrd temporary directory if it does not exist
|
||||
if not os.path.isdir(self.conf.initrddir):
|
||||
os.makedirs(self.conf.initrddir)
|
||||
|
||||
for action in self.template.actions + self._actions:
|
||||
action.execute()
|
||||
|
||||
def create(self, dst):
|
||||
err, output = commands.getstatusoutput('find %s | cpio --quiet -c -o | gzip -9 > %s' %
|
||||
(self.conf.initrddir, dst))
|
||||
|
||||
def cleanUp(self):
|
||||
rm(self.conf.initrddir)
|
||||
|
||||
|
||||
class Images(object):
|
||||
@ -13,6 +89,8 @@ class Images(object):
|
||||
self.conf = config
|
||||
self.yum = yum
|
||||
|
||||
self.initrd = InitRD(self.conf, self.yum)
|
||||
|
||||
# XXX don't see this used anywhere... maybe in some other script, have to check...
|
||||
#syslinux = os.path.join(self.conf.treedir, 'usr', 'lib', 'syslinux', 'syslinux-nomtools')
|
||||
#if not os.path.isfile(syslinux):
|
||||
@ -23,45 +101,95 @@ class Images(object):
|
||||
# sys.exit(1)
|
||||
|
||||
def run(self):
|
||||
self.prepareBootTree()
|
||||
bold = ('\033[1m', '\033[0m')
|
||||
|
||||
def prepareBootTree(self):
|
||||
i = initrd.InitRD(self.conf, self.yum)
|
||||
pkgs = i.getPkgs()
|
||||
print('%sInstalling needed packages%s' % bold)
|
||||
self.installPackages()
|
||||
|
||||
# install needed packages
|
||||
print('%sCopying updates%s' % bold)
|
||||
self.copyUpdates()
|
||||
|
||||
print('%sInitializing output directory%s' % bold)
|
||||
self.initOutputDirs()
|
||||
|
||||
print('%sPopulating the isolinux directory%s' % bold)
|
||||
self.populateIsolinuxDir()
|
||||
|
||||
# XXX a lot of other stuff needs to be done here
|
||||
pass
|
||||
|
||||
print('%sDONE%s' % bold)
|
||||
|
||||
def installPackages(self):
|
||||
# required packages
|
||||
self.yum.addPackages(['anaconda', 'anaconda-runtime', 'kernel', 'syslinux'])
|
||||
self.yum.addPackages(pkgs)
|
||||
|
||||
# optional packages from confdir
|
||||
packages_files = []
|
||||
packages_files.append(os.path.join(self.conf.confdir, 'packages', 'packages'))
|
||||
packages_files.append(os.path.join(self.conf.confdir, 'packages', self.conf.buildarch,
|
||||
'packages'))
|
||||
|
||||
packages = set()
|
||||
for pfile in packages_files:
|
||||
if os.path.isfile(pfile):
|
||||
f = open(pfile, 'r')
|
||||
for line in f.readlines():
|
||||
line = line.strip()
|
||||
|
||||
if not line or line.startswith('#'):
|
||||
continue
|
||||
|
||||
if line.startswith('-'):
|
||||
packages.discard(line[1:])
|
||||
else:
|
||||
packages.add(line)
|
||||
|
||||
f.close()
|
||||
|
||||
self.yum.addPackages(list(packages))
|
||||
|
||||
# packages required for initrd image
|
||||
packages = self.initrd.getPackages()
|
||||
self.yum.addPackages(packages)
|
||||
|
||||
# install all packages
|
||||
self.yum.install()
|
||||
|
||||
def copyUpdates(self):
|
||||
if self.conf.updates and os.path.isdir(self.conf.updates):
|
||||
cp(os.path.join(self.conf.updates, '*'), self.conf.treedir)
|
||||
self.conf.delAttr('updates')
|
||||
|
||||
def initOutputDirs(self):
|
||||
# create the destination directories
|
||||
self.imgdir = os.path.join(self.conf.outdir, 'images')
|
||||
if os.path.exists(self.imgdir):
|
||||
rm(self.imgdir)
|
||||
self.pxedir = os.path.join(self.imgdir, 'pxeboot')
|
||||
os.makedirs(self.imgdir)
|
||||
|
||||
self.pxedir = os.path.join(self.imgdir, 'pxeboot')
|
||||
os.makedirs(self.pxedir)
|
||||
|
||||
# write the images/README
|
||||
f = open(os.path.join(self.imgdir, 'README'), 'w')
|
||||
f.write('This directory contains image files that can be used to create media\n'
|
||||
'capable of starting the %s installation process.\n\n' % self.conf.product)
|
||||
f.write('The boot.iso file is an ISO 9660 image of a bootable CD-ROM. It is useful\n'
|
||||
'in cases where the CD-ROM installation method is not desired, but the\n'
|
||||
'CD-ROM\'s boot speed would be an advantage.\n\n')
|
||||
f.write('To use this image file, burn the file onto CD-R (or CD-RW) media as you\n'
|
||||
'normally would.\n')
|
||||
f.close()
|
||||
src = os.path.join(self.conf.datadir, 'images', 'README')
|
||||
dst = os.path.join(self.imgdir, 'README')
|
||||
cp(src, dst)
|
||||
replace(dst, r'@PRODUCT@', self.conf.product)
|
||||
|
||||
# write the images/pxeboot/README
|
||||
f = open(os.path.join(self.pxedir, 'README'), 'w')
|
||||
f.write('The files in this directory are useful for booting a machine via PXE.\n\n')
|
||||
f.write('The following files are available:\n')
|
||||
f.write('vmlinuz - the kernel used for the installer\n')
|
||||
f.write('initrd.img - an initrd with support for all install methods and\n')
|
||||
f.write(' drivers supported for installation of %s\n' % self.conf.product)
|
||||
f.close()
|
||||
src = os.path.join(self.conf.datadir, 'images', 'pxeboot', 'README')
|
||||
dst = os.path.join(self.pxedir, 'README')
|
||||
cp(src, dst)
|
||||
replace(dst, r'@PRODUCT@', self.conf.product)
|
||||
|
||||
# create the isolinux directory
|
||||
self.isodir = os.path.join(self.conf.outdir, 'isolinux')
|
||||
if os.path.exists(self.isodir):
|
||||
rm(self.isodir)
|
||||
os.makedirs(self.isodir)
|
||||
|
||||
def populateIsolinuxDir(self):
|
||||
# set up some dir variables for further use
|
||||
anacondadir = os.path.join(self.conf.treedir, 'usr', 'lib', 'anaconda-runtime')
|
||||
bootdiskdir = os.path.join(anacondadir, 'boot')
|
||||
@ -69,13 +197,7 @@ class Images(object):
|
||||
|
||||
isolinuxbin = os.path.join(syslinuxdir, 'isolinux.bin')
|
||||
if os.path.isfile(isolinuxbin):
|
||||
print('Creating the isolinux directory...')
|
||||
self.isodir = os.path.join(self.conf.outdir, 'isolinux')
|
||||
if os.path.exists(self.isodir):
|
||||
rm(self.isodir)
|
||||
os.makedirs(self.isodir)
|
||||
|
||||
# copy the isolinux.bin to isolinux dir
|
||||
# copy the isolinux.bin
|
||||
cp(isolinuxbin, self.isodir)
|
||||
|
||||
# copy the syslinux.cfg to isolinux/isolinux.cfg
|
||||
@ -86,20 +208,22 @@ class Images(object):
|
||||
replace(isolinuxcfg, r'@PRODUCT@', self.conf.product)
|
||||
replace(isolinuxcfg, r'@VERSION@', self.conf.version)
|
||||
|
||||
# copy the grub.conf to isolinux dir
|
||||
# copy the grub.conf
|
||||
cp(os.path.join(bootdiskdir, 'grub.conf'), self.isodir)
|
||||
|
||||
# create the initrd in isolinux dir
|
||||
i.getDeps()
|
||||
i.processActions()
|
||||
i.create(os.path.join(self.isodir, 'initrd.img'))
|
||||
i.cleanUp()
|
||||
# XXX do we want this here?
|
||||
# create the initrd.img
|
||||
print('Creating the initrd.img')
|
||||
self.initrd.getDeps()
|
||||
self.initrd.processActions()
|
||||
self.initrd.create(os.path.join(self.isodir, 'initrd.img'))
|
||||
#self.initrd.cleanUp()
|
||||
|
||||
# copy the vmlinuz to isolinux dir
|
||||
# copy the vmlinuz
|
||||
vmlinuz = os.path.join(self.conf.treedir, 'boot', 'vmlinuz-*')
|
||||
cp(vmlinuz, os.path.join(self.isodir, 'vmlinuz'))
|
||||
|
||||
# copy the splash files to isolinux dir
|
||||
# copy the splash files
|
||||
vesasplash = os.path.join(anacondadir, 'syslinux-vesa-splash.jpg')
|
||||
if os.path.isfile(vesasplash):
|
||||
cp(vesasplash, os.path.join(self.isodir, 'splash.jpg'))
|
||||
@ -111,29 +235,27 @@ class Images(object):
|
||||
splashtools = os.path.join(anacondadir, 'splashtools.sh')
|
||||
splashlss = os.path.join(bootdiskdir, 'splash.lss')
|
||||
if os.path.isfile(splashtools):
|
||||
os.system('%s %s %s' % (splashtools,
|
||||
os.path.join(bootdiskdir, 'syslinux-splash.jpg'),
|
||||
splashlss))
|
||||
cmd = '%s %s %s' % (splashtools,
|
||||
os.path.join(bootdiskdir, 'syslinux-splash.jpg'),
|
||||
splashlss)
|
||||
os.system(cmd)
|
||||
if os.path.isfile(splashlss):
|
||||
cp(splashlss, self.isodir)
|
||||
|
||||
# copy the .msg files to isolinux dir
|
||||
# copy the .msg files
|
||||
for file in os.listdir(bootdiskdir):
|
||||
if file.endswith('.msg'):
|
||||
cp(os.path.join(bootdiskdir, file), self.isodir)
|
||||
replace(os.path.join(self.isodir, file), r'@VERSION@', self.conf.version)
|
||||
|
||||
# if present, copy the memtest to isolinux dir
|
||||
# XXX search for it in bootdiskdir or treedir/install/boot ?
|
||||
#cp(os.path.join(bootdiskdir, 'memtest*'), os.path.join(self.isodir, 'memtest'))
|
||||
# if present, copy the memtest
|
||||
cp(os.path.join(self.conf.treedir, 'boot', 'memtest*'),
|
||||
os.path.join(self.isodir, 'memtest'))
|
||||
os.path.join(self.isodir, 'memtest'))
|
||||
if os.path.isfile(os.path.join(self.isodir, 'memtest')):
|
||||
f = open(isolinuxcfg, 'a')
|
||||
f.write('label memtest86\n')
|
||||
f.write(' menu label ^Memory test\n')
|
||||
f.write(' kernel memtest\n')
|
||||
f.write(' append -\n')
|
||||
f.close()
|
||||
text = "label memtest86\n"
|
||||
text = text + " menu label ^Memory test\n"
|
||||
text = text + " kernel memtest\n"
|
||||
text = text + " append -\n"
|
||||
edit(isolinuxcfg, text, append=True)
|
||||
else:
|
||||
print('No isolinux binary found, skipping isolinux creation')
|
||||
sys.stderr.write('No isolinux binary found, skipping isolinux creation\n')
|
||||
|
@ -1,84 +0,0 @@
|
||||
# pylorax/initrd.py
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
import actions
|
||||
from config import Template
|
||||
from utils.libutil import LDD
|
||||
from utils.fileutil import rm
|
||||
|
||||
|
||||
class InitRD(object):
|
||||
def __init__(self, config, yum):
|
||||
self.conf = config
|
||||
self.yum = yum
|
||||
|
||||
if not os.path.isdir(self.conf.initrddir):
|
||||
os.makedirs(self.conf.initrddir)
|
||||
|
||||
# get supported actions
|
||||
supported_actions = actions.getActions()
|
||||
|
||||
initrd_templates = []
|
||||
initrd_templates.append(os.path.join(self.conf.confdir, 'templates', 'initrd'))
|
||||
initrd_templates.append(os.path.join(self.conf.confdir, 'templates', self.conf.buildarch,
|
||||
'initrd'))
|
||||
|
||||
vars = { '@instroot@': self.conf.treedir,
|
||||
'@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):
|
||||
self.template.parse(file, supported_actions, vars)
|
||||
|
||||
self.actions = []
|
||||
|
||||
def getPkgs(self):
|
||||
# get needed packages
|
||||
pkgs = []
|
||||
for action in filter(lambda action: hasattr(action, 'install'), self.template.actions):
|
||||
m = re.match(r'%s(.*)' % self.conf.treedir, action.install)
|
||||
if m:
|
||||
pkgs.append(m.group(1))
|
||||
|
||||
return pkgs
|
||||
|
||||
def getDeps(self):
|
||||
# get needed dependencies
|
||||
ldd = LDD(libroot=os.path.join(self.conf.treedir, self.conf.libdir))
|
||||
for action in filter(lambda action: hasattr(action, 'getDeps'), self.template.actions):
|
||||
file = action.getDeps()
|
||||
ldd.getDeps(file)
|
||||
|
||||
# resolve symlinks
|
||||
ldd.getLinks()
|
||||
|
||||
# add dependencies to actions
|
||||
for dep in ldd.deps:
|
||||
kwargs = {}
|
||||
kwargs['src'] = dep
|
||||
kwargs['dst'] = re.sub(r'%s(?P<file>.*)' % self.conf.treedir,
|
||||
'%s\g<file>' % self.conf.initrddir,
|
||||
dep)
|
||||
|
||||
new_action = actions.fileactions.Copy(**kwargs)
|
||||
self.actions.append(new_action)
|
||||
|
||||
def processActions(self):
|
||||
for action in self.template.actions:
|
||||
action.execute()
|
||||
|
||||
for action in self.actions:
|
||||
action.execute()
|
||||
|
||||
def create(self, dst):
|
||||
os.system('find %s | cpio --quiet -c -o | gzip -9 > %s' % (self.conf.initrddir, dst))
|
||||
|
||||
def cleanUp(self):
|
||||
rm(self.conf.initrddir)
|
@ -1,4 +1,4 @@
|
||||
# pylorax/utils/rpmutil.py
|
||||
# pylorax/utils/rpmutils.py
|
||||
|
||||
import sys
|
||||
import os
|
||||
@ -6,6 +6,7 @@ import stat
|
||||
import yum
|
||||
import urlgrabber
|
||||
import shutil
|
||||
import commands
|
||||
|
||||
import yum.callbacks
|
||||
import yum.rpmtrans
|
||||
@ -13,7 +14,23 @@ import yum.rpmtrans
|
||||
from rpmUtils.miscutils import rpm2cpio
|
||||
from cpioarchive import CpioArchive
|
||||
|
||||
from pylorax.base import seq, getConsoleSize
|
||||
|
||||
def seq(arg):
|
||||
if type(arg) not in (type([]), type(())):
|
||||
return [arg]
|
||||
else:
|
||||
return arg
|
||||
|
||||
|
||||
def getConsoleSize():
|
||||
err, output = commands.getstatusoutput('stty size')
|
||||
if not err:
|
||||
height, width = output.split()
|
||||
else:
|
||||
# set defaults
|
||||
height, width = 24, 80
|
||||
|
||||
return int(height), int(width)
|
||||
|
||||
|
||||
class Callback(yum.rpmtrans.SimpleCliCallBack):
|
||||
@ -74,7 +91,7 @@ class Yum(object):
|
||||
|
||||
def download(self, packages):
|
||||
for package in seq(packages):
|
||||
print('Downloading package %s...' % package)
|
||||
print('Downloading package %s' % package)
|
||||
fn = urlgrabber.urlgrab(package.remote_url)
|
||||
shutil.copy(fn, self.installroot)
|
||||
|
||||
@ -82,7 +99,7 @@ class Yum(object):
|
||||
|
||||
def addPackages(self, patterns):
|
||||
for pattern in seq(patterns):
|
||||
print('Adding package matching %s...' % pattern)
|
||||
print('Adding package matching %s' % pattern)
|
||||
try:
|
||||
self.yb.install(name=pattern)
|
||||
except yum.Errors.InstallError:
|
||||
@ -103,7 +120,7 @@ class Yum(object):
|
||||
self.yb.close()
|
||||
|
||||
|
||||
def extract_rpm(rpmfile, destdir):
|
||||
def extractRPM(rpmfile, destdir):
|
||||
if not os.path.isdir(destdir):
|
||||
os.makedirs(destdir)
|
||||
|
||||
@ -125,7 +142,7 @@ def extract_rpm(rpmfile, destdir):
|
||||
if not os.path.isdir(path):
|
||||
os.makedirs(path)
|
||||
else:
|
||||
print('Extracting %s...' % entry.name)
|
||||
print('Extracting %s' % entry.name)
|
||||
dir = os.path.dirname(path)
|
||||
if not os.path.isdir(dir):
|
||||
os.makedirs(dir)
|
||||
|
Loading…
Reference in New Issue
Block a user