#
# pylorax
# Install image and tree support data generation tool -- Python module.
#
# Copyright (C) 2008 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
# Author(s): David Cantrell
#
version = (0, 1)
import os
import shutil
import tempfile
import yum
import rpmUtils
import discinfo
import treeinfo
from instroot import InstRoot
class Lorax:
def __init__(self, repos=[], output=None, mirrorlist=[], updates=None):
self.conf = {}
self.conf['confdir'] = '/etc/lorax'
self.conf['tmpdir'] = tempfile.gettempdir()
self.conf['datadir'] = '/usr/share/lorax'
if repos != []:
self.repo, self.extrarepos = self._collectRepos(repos)
else:
self.repo = None
self.extrarepos = []
self.output = output
self.mirrorlist = mirrorlist
self.updates = updates
def run(self):
"""run()
Generate install images.
"""
print("\n+=======================================================+")
print("| Setting up work directories and configuration data... |")
print("+=======================================================+\n")
self.buildinstdir, self.treedir, self.cachedir = self._initializeDirs()
self.yumconf = self._writeYumConf()
print("\n+================================================+")
print("| Creating instroot tree to build images from... |")
print("+================================================+\n")
self.instroot = InstRoot(conf=self.conf, yumconf=self.yumconf, arch=self.getBuildArch(), treedir=self.treedir, updates=self.updates)
def showVersion(self, driver=None):
"""showVersion(driver)
Display program name (driver) and version number. If prog is an empty
string or None, use the value 'pylorax'.
"""
if prog is None or prog == '':
prog = 'pylorax'
print "%s version %d.%d" % (prog, version[0], version[1],)
def cleanup(self, trash=[]):
"""cleanup(trash)
Given a list of things to remove, cleanup() will remove them if it can.
Never fails, just tries to remove things and returns regardless of
failures removing things.
"""
if trash != []:
for item in trash:
if os.path.isdir(item):
shutil.rmtree(item, ignore_errors=True)
else:
os.unlink(item)
if os.path.isdir(self.conf['tmpdir']):
shutil.rmtree(self.conf['tmpdir'], ignore_errors=True)
def getBuildArch(self):
"""getBuildArch()
Query the configured yum repositories to determine our build architecture,
which is the architecture of the anaconda package in the repositories.
This function is based on a subset of what repoquery(1) does.
"""
uname_arch = os.uname()[4]
if self.yumconf == '' or self.yumconf is None or not os.path.isfile(self.yumconf):
print "RETURN HERE"
return uname_arch
repoq = yum.YumBase()
repoq.doConfigSetup()
try:
repoq.doRepoSetup()
except yum.Errors.RepoError, e:
sys.stderr.write("ERROR: could not query yum repository for build arch, defaulting to %s\n" % (uname_arch,))
return uname_arch
repoq.doSackSetup(rpmUtils.arch.getArchList())
repoq.doTsSetup()
ret_arch = None
for pkg in repoq.pkgSack.simplePkgList():
(n, a, e, v, r) = pkg
if n == 'anaconda':
ret_arch = a
break
if ret_arch is None:
ret_arch = uname_arch
print("Building images for %s" % (ret_arch,))
return ret_arch
def _collectRepos(self, repos):
"""_collectRepos(repos)
Get the main repo (the first one) and then build a list of all remaining
repos in the list. Sanitize each repo URL for proper yum syntax.
"""
if repos is None or repos == []:
return '', []
repolist = []
for repospec in repos:
if repospec.startswith('/'):
repo = "file://%s" % (repospec,)
print("Adding local repo:\n %s" % (repo,))
repolist.append(repo)
elif repospec.startswith('http://') or repospec.startswith('ftp://'):
print("Adding remote repo:\n %s" % (repospec,))
repolist.append(repospec)
repo = repolist[0]
extrarepos = []
if len(repolist) > 1:
for extra in repolist[1:]:
print("Adding extra repo:\n %s" % (extra,))
extrarepos.append(extra)
return repo, extrarepos
def _initializeDirs(self):
"""_initializeDirs()
Create directories used for image generation.
"""
if not os.path.isdir(self.output):
os.makedirs(self.output, mode=0755)
self.conf['tmpdir'] = tempfile.mkdtemp('XXXXXX', 'lorax.tmp.', self.conf['tmpdir'])
buildinstdir = tempfile.mkdtemp('XXXXXX', 'buildinstall.tree.', self.conf['tmpdir'])
treedir = tempfile.mkdtemp('XXXXXX', 'treedir.', self.conf['tmpdir'])
cachedir = tempfile.mkdtemp('XXXXXX', 'yumcache.', self.conf['tmpdir'])
print("Working directories:")
print(" tmpdir = %s" % (self.conf['tmpdir'],))
print(" buildinstdir = %s" % (buildinstdir,))
print(" treedir = %s" % (treedir,))
print(" cachedir = %s" % (cachedir,))
return buildinstdir, treedir, cachedir
def _writeYumConf(self):
"""_writeYumConf()
Generate a temporary yum.conf file for image generation. Returns the path
to the temporary yum.conf file on success, None of failure.
"""
tmpdir = self.conf['tmpdir']
(fd, yumconf) = tempfile.mkstemp(prefix='yum.conf', dir=tmpdir)
f = os.fdopen(fd, 'w')
f.write("[main]\n")
f.write("cachedir=%s\n" % (self.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.repo,))
f.write("enabled=1\n\n")
if self.extrarepos != []:
n = 1
for extra in self.extrarepos:
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")
n += 1
if self.mirrorlist != []:
n = 1
for mirror in self.mirrorlist:
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")
n += 1
f.close()
print("Wrote lorax yum configuration to %s" % (yumconf,))
return yumconf