lorax/src/pylorax/__init__.py

287 lines
8.9 KiB
Python
Raw Normal View History

# pylorax/__init__.py
import sys
import os
import shutil
import tempfile
import time
import ConfigParser
import re
2009-06-09 14:10:01 +00:00
from errors import LoraxError
from config import Container
2009-06-09 14:10:01 +00:00
from utils.rpmutils import Yum
from utils.fileutils import rm
import images
class Config(Container):
def __init__(self):
config = ('confdir', 'datadir', 'tempdir', 'debug', 'cleanup')
# options
required = ('product', 'version', 'release', 'outdir', 'repos')
optional = ('variant', 'bugurl', 'updates', 'mirrorlist')
Container.__init__(self, config + required + optional)
# set defaults
self.set(confdir='/etc/lorax',
datadir='/usr/share/lorax',
tempdir=tempfile.mkdtemp(prefix='lorax.tmp.', dir=tempfile.gettempdir()),
debug=False,
cleanup=False)
self.set(product='',
version='',
release='',
outdir='',
repos=[])
self.set(variant='',
bugurl='',
updates='',
mirrorlist=[])
class Lorax(object):
def __init__(self, config):
assert isinstance(config, Config) == True
self.conf = config
# check if we have all required options
if not self.conf.repos:
2009-06-09 14:10:01 +00:00
raise LoraxError, "missing required parameter 'repos'"
if not self.conf.outdir:
2009-06-09 14:10:01 +00:00
raise LoraxError, "missing required parameter 'outdir'"
if not self.conf.product:
2009-06-09 14:10:01 +00:00
raise LoraxError, "missing required parameter 'product'"
if not self.conf.version:
2009-06-09 14:10:01 +00:00
raise LoraxError, "missing required parameter 'version'"
if not self.conf.release:
2009-06-09 14:10:01 +00:00
raise LoraxError, "missing required parameter 'release'"
self.yum = None
def run(self):
2009-06-09 14:10:01 +00:00
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:
2009-06-09 14:10:01 +00:00
sys.stderr.write('ERROR: No valid repository\n')
sys.exit(1)
2009-06-09 14:10:01 +00:00
print('%sInitializing directories%s' % bold)
self.initDirs()
2009-06-09 14:10:01 +00:00
print('%sInitializing yum%s' % bold)
self.initYum()
2009-06-09 14:10:01 +00:00
print('%sSetting build architecture%s' % bold)
self.setBuildArch()
2009-06-09 14:10:01 +00:00
print('%sWriting .treeinfo%s' % bold)
self.writeTreeInfo()
2009-06-09 14:10:01 +00:00
print('%sWriting .discinfo%s' % bold)
self.writeDiscInfo()
2009-06-09 14:10:01 +00:00
print('%sPreparing the install tree%s' % bold)
self.prepareInstRoot()
2009-06-09 14:10:01 +00:00
print('%sCreating the images%s' % bold)
self.makeImages()
if self.conf.cleanup:
2009-06-09 14:10:01 +00:00
print('%sCleaning up%s' % bold)
self.cleanUp()
def collectRepos(self):
repolist = []
for repospec in self.conf.repos:
if repospec.startswith('/'):
repo = 'file://%s' % repospec
print('Adding local repo: %s' % repo)
repolist.append(repo)
elif repospec.startswith('http://') or repospec.startswith('ftp://'):
print('Adding remote repo: %s' % repospec)
repolist.append(repospec)
if not repolist:
repo, extrarepos = None, []
else:
repo, extrarepos = repolist[0], repolist[1:]
self.conf.addAttr(['repo', 'extrarepos'])
self.conf.set(repo=repo, extrarepos=extrarepos)
# remove repos attribute, to get a traceback, if we use it later
self.conf.delAttr('repos')
def initDirs(self):
if not os.path.isdir(self.conf.outdir):
os.makedirs(self.conf.outdir, mode=0755)
treedir = os.path.join(self.conf.tempdir, 'treedir', 'install')
os.makedirs(treedir)
cachedir = os.path.join(self.conf.tempdir, 'yumcache')
os.makedirs(cachedir)
2009-06-09 14:10:01 +00:00
initrddir = os.path.join(self.conf.tempdir, 'initrddir')
os.makedirs(initrddir)
print('Working directories:')
print(' tempdir = %s' % self.conf.tempdir)
print(' treedir = %s' % treedir)
print(' cachedir = %s' % cachedir)
print(' initrddir = %s' % initrddir)
self.conf.addAttr(['treedir', 'cachedir', 'initrddir'])
self.conf.set(treedir=treedir, cachedir=cachedir, initrddir=initrddir)
2008-10-06 01:08:38 +00:00
def initYum(self):
yumconf = os.path.join(self.conf.tempdir, 'yum.conf')
try:
f = open(yumconf, 'w')
2009-06-09 14:10:01 +00:00
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')
f.write('cachedir=%s\n' % self.conf.cachedir)
f.write('keepcache=0\n')
f.write('gpgcheck=0\n')
f.write('plugins=0\n')
f.write('reposdir=\n')
f.write('tsflags=nodocs\n\n')
f.write('[loraxrepo]\n')
f.write('name=lorax repo\n')
f.write('baseurl=%s\n' % self.conf.repo)
f.write('enabled=1\n\n')
for n, extra in enumerate(self.conf.extrarepos, start=1):
f.write('[lorax-extrarepo-%d]\n' % n)
f.write('name=lorax extra repo %d\n' % n)
f.write('baseurl=%s\n' % extra)
f.write('enabled=1\n')
for n, mirror in enumerate(self.conf.mirrorlist, start=1):
f.write('[lorax-mirrorlistrepo-%d]\n' % n)
f.write('name=lorax mirrorlist repo %d\n' % n)
f.write('mirrorlist=%s\n' % mirror)
f.write('enabled=1\n')
f.close()
self.conf.addAttr('yumconf')
self.conf.set(yumconf=yumconf)
2009-06-09 14:10:01 +00:00
# create the Yum object
self.yum = Yum(yumconf=self.conf.yumconf, installroot=self.conf.treedir)
2009-06-09 14:10:01 +00:00
# remove not needed attributes
self.conf.delAttr(['repo', 'extrarepos', 'mirrorlist', 'cachedir'])
def setBuildArch(self):
unamearch = os.uname()[4]
self.conf.addAttr('buildarch')
self.conf.set(buildarch=unamearch)
2009-06-09 14:10:01 +00:00
installed, available = self.yum.find('anaconda')
try:
2009-06-09 14:10:01 +00:00
self.conf.set(buildarch=available[0].arch)
except:
2009-06-09 14:10:01 +00:00
# FIXME specify what exceptions can we get here
pass
# set the libdir
self.conf.addAttr('libdir')
self.conf.set(libdir='lib')
# on 64-bit systems, make sure we use lib64 as the lib directory
if self.conf.buildarch.endswith('64') or self.conf.buildarch == 's390x':
self.conf.set(libdir='lib64')
def writeTreeInfo(self, discnum=1, totaldiscs=1, packagedir=''):
outfile = os.path.join(self.conf.outdir, '.treeinfo')
2009-06-09 14:10:01 +00:00
# don't print anything instead of None, if variant is not specified
variant = ''
if self.conf.variant:
variant = self.conf.variant
data = { 'timestamp': time.time(),
'family': self.conf.product,
'version': self.conf.version,
'arch': self.conf.buildarch,
'variant': variant,
'discnum': str(discnum),
'totaldiscs': str(totaldiscs),
'packagedir': packagedir }
c = ConfigParser.ConfigParser()
section = 'general'
c.add_section(section)
for key, value in data.items():
c.set(section, key, value)
2008-10-06 01:08:38 +00:00
section = 'images-%s' % self.conf.buildarch
c.add_section(section)
c.set(section, 'kernel', 'images/pxeboot/vmlinuz')
c.set(section, 'initrd', 'images/pxeboot/initrd.img')
2009-06-09 14:10:01 +00:00
# XXX actually create the boot iso somewhere before calling writeTreeInfo(),
# and set up this attribute properly
self.conf.addAttr('bootiso')
if self.conf.bootiso:
c.set(section, 'boot.iso', 'images/%s' % self.conf.bootiso)
try:
f = open(outfile, 'w')
except IOError:
return False
else:
c.write(f)
f.close()
return True
def writeDiscInfo(self, discnum=0):
outfile = os.path.join(self.conf.outdir, '.discinfo')
try:
f = open(outfile, 'w')
except IOError:
return False
else:
f.write('%f\n' % time.time())
f.write('%s\n' % self.conf.release)
f.write('%s\n' % self.conf.buildarch)
f.write('%d\n' % discnum)
f.close()
return True
def prepareInstRoot(self):
2009-06-09 14:10:01 +00:00
# XXX do we need this?
os.symlink(os.path.join(os.path.sep, 'tmp'),
os.path.join(self.conf.treedir, 'var', 'lib', 'xkb'))
def makeImages(self):
i = images.Images(self.conf, self.yum)
i.run()
def cleanUp(self, trash=[]):
for item in trash:
2009-06-09 14:10:01 +00:00
if os.path.exists(item):
rm(item)
# remove the whole lorax tempdir
if os.path.isdir(self.conf.tempdir):
2009-06-09 14:10:01 +00:00
rm(self.conf.tempdir)