[Yum] distribution variable works...
Robert G. Brown
rgb at phy.duke.edu
Tue Sep 28 16:21:56 UTC 2004
On Tue, 28 Sep 2004, Robert G. Brown wrote:
The following (2.0.7 derived) config.py actually works and does the
substitutions and everything. It isn't efficient - both variables could
be set with one set of rpm.TransactionSet() calls, but I don't know how
to return two variables from one subroutine fragment in python.
Probably very simply.
I also patched in the required distribution_reg stuff that makes it
actually work, and tested it. It actually works.
If you decide to implement this, you'll probably need/want to recombine
the two hdr[] assignments into the one transaction set call, and decide
whether or not you want to chop off the -release from the hdr['name']
return. I would -- it is prettier -- but honestly if distribution were
set to redhat-release, centos-release etc. it would work just as well
for automating $distribution/$releasever/$basearch paths.
Either way you'll likely want to insert a sanity check here. I'd
recommend using the 'unknown' fallback/default instead of the 'Null'
default for $distribution (as I attempted below) but whatever.
Just having distribution variable will create a strong incentive to
structure repositories this way.
rgb
--
Robert G. Brown http://www.phy.duke.edu/~rgb/
Duke University Dept. of Physics, Box 90305
Durham, N.C. 27708-0305
Phone: 1-919-660-2567 Fax: 919-660-2525 email:rgb at phy.duke.edu
#!/usr/bin/python -t
# 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 Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
# Copyright 2002 Duke University
import ConfigParser
import sys
import os
import os.path
import urlparse
import string
import urllib
import rpm
import re
import failover
import archwork
import rpmUtils
import progress_meter
from i18n import _
class yumconf:
def __init__(self, configfile = '/etc/yum.conf'):
self.cfg = ConfigParser.ConfigParser()
(s,b,p,q,f,o) = urlparse.urlparse(configfile)
if s in ('http', 'ftp','file'):
configfh = urllib.urlopen(configfile)
try:
self.cfg.readfp(configfh)
except ConfigParser.MissingSectionHeaderError, e:
print _('Error accessing URL: %s') % configfile
sys.exit(1)
else:
if os.access(configfile, os.R_OK):
self.cfg.read(configfile)
else:
print _('Error accessing File: %s') % configfile
sys.exit(1)
self.servers = []
self.servername = {}
self.serverurl = {}
self.serverpkgdir = {}
self.serverhdrdir = {}
self.servercache = {}
self.servergpgcheck= {}
self.serverexclude= {}
self.failoverclass = {}
self.groupsenable = {}
self.excludes = []
#defaults
self.cachedir = '/var/cache/yum'
self.debuglevel = 2
self.logfile = '/var/log/yum.log'
self.pkgpolicy = 'newest'
self.assumeyes = 0
self.errorlevel = 2
self.cache = 0
self.uid = 0
self.yumversion = 'unversioned'
self.commands = None
self.exactarch = 0
self.overwrite_groups = 0
self.groups_enabled = 0
self.diskspacecheck = 1
self.tolerant = 0
self.yumvar = self._getEnvVar()
self.distroverpkg = 'redhat-release'
self.yumvar['basearch'] = archwork.getArch()
self.yumvar['arch'] = os.uname()[4]
# this is ugly and dirty like Zebra - but I'd like for a lot of users
# of fedora to hush about the header download until I get the
# new metadata work done.
self.hdlist = '/usr/share/comps/%s/hdlist' % self.yumvar['basearch']
self.hdlist2 = '/usr/share/comps/%s/hdlist2' % self.yumvar['basearch']
self.usecomps = 1
self.cachedb = '/usr/lib/rpmdb/%s-redhat-linux/redhat/' % self.yumvar['basearch']
self.usecachedb = 1
self.downloadonly = 0
self.bandwidth = None
self.throttle = None
self.retries = 6
self.keepalive = 1
self.modifybootloader = 1
self.progress_obj = progress_meter.text_progress_meter(fo=sys.stdout)
self.installroot = '/'
self.installonlypkgs = ['kernel', 'kernel-bigmem', 'kernel-enterprise',
'kernel-smp', 'kernel-debug', 'kernel-unsupported',
'kernel-source', 'kernel-modules-unsupported']
self.kernelpkgnames = ['kernel','kernel-smp','kernel-enterprise',
'kernel-bigmem','kernel-BOOT']
if self._getoption('main','cachedir') != None:
self.cachedir = self._getoption('main','cachedir')
if self._getoption('main','debuglevel') != None:
self.debuglevel = self._getoption('main','debuglevel')
if self._getoption('main','logfile') != None:
self.logfile = self._getoption('main','logfile')
if self._getoption('main','pkgpolicy') != None:
self.pkgpolicy = self._getoption('main','pkgpolicy')
if self._getoption('main','assumeyes') != None:
self.assumeyes = self.cfg.getboolean('main', 'assumeyes')
if self._getoption('main','errorlevel') != None:
self.errorlevel = self._getoption('main', 'errorlevel')
if self._getoption('main','exactarch') != None:
self.exactarch = self.cfg.getboolean('main', 'exactarch')
if self._getoption('main','overwrite_groups') != None:
self.overwrite_groups = self.cfg.getboolean('main', 'overwrite_groups')
if self._getoption('main','diskspacecheck') != None:
self.diskspacecheck = self.cfg.getboolean('main', 'diskspacecheck')
if self._getoption('main','tolerant') != None:
self.tolerant = self.cfg.getboolean('main', 'tolerant')
if self._getoption('main', 'distroverpkg') != None:
self.distroverpkg = self._getoption('main','distroverpkg')
if self._getoption('main', 'bandwidth') != None:
self.bandwidth = self._getoption('main','bandwidth')
if self._getoption('main', 'throttle') != None:
self.throttle = self._getoption('main','throttle')
if self._getoption('main', 'keepalive') != None:
self.keepalive = self.cfg.getboolean('main','keepalive')
if self._getoption('main', 'retries') != None:
self.retries = self.cfg.getint('main','retries')
if self._getoption('main', 'installroot') != None:
self.installroot = self._getoption('main','installroot')
if self._getoption('main', 'hdlist') != None:
self.hdlist = self._getoption('main', 'hdlist')
if self._getoption('main', 'hdlist2') != None:
self.hdlist2 = self._getoption('main', 'hdlist2')
if self._getoption('main','usecomps') != None:
self.usecomps = self.cfg.getboolean('main', 'usecomps')
if self._getoption('main','download-only') != None:
self.downloadonly = self.cfg.getboolean('main', 'download-only')
if self._getoption('main','bootloader') != None:
self.modifybootloader = self.cfg.getboolean('main', 'bootloader')
if self._getoption('main', 'cachedb') != None:
self.cachedb = self._getoption('main', 'cachedb')
if self._getoption('main', 'usecachedb') != None:
self.usecachedb = self.cfg.getboolean('main', 'usecachedb')
# figure out what the releasever really is from the distroverpkg
self.yumvar['distribution'] = self._getsysdist()
self.yumvar['releasever'] = self._getsysver()
if self._getoption('main','commands') != None:
self.commands = self._getoption('main', 'commands')
self.commands = self._doreplace(self.commands)
self.commands = self.parseList(self.commands)
if self._getoption('main','installonlypkgs') != None:
self.installonlypkgs = self._getoption('main', 'installonlypkgs')
self.installonlypkgs = self._doreplace(self.installonlypkgs)
self.installonlypkgs = self.parseList(self.installonlypkgs)
if self._getoption('main','kernelpkgnames') != None:
self.kernelpkgnames = self._getoption('main', 'kernelpkgnames')
self.kernelpkgnames = self._doreplace(self.kernelpkgnames)
self.kernelpkgnames = self.parseList(self.kernelpkgnames)
# get the global exclude lists.
if self._getoption('main','exclude') != None:
self.excludes = self._getoption('main','exclude')
self.excludes = self._doreplace(self.excludes)
self.excludes = self.parseList(self.excludes)
if len(self.cfg.sections()) > 1:
for section in self.cfg.sections(): # loop through the list of sections
if section != 'main': # must be a serverid
if self._getoption(section, 'baseurl') != None:
name = self._getoption(section, 'name')
urls = self._getoption(section, 'baseurl')
urls = self._doreplace(urls)
urls = self.parseList(urls)
else:
name = None
urls = []
if name != None and len(urls) > 0 and urls[0] != None:
self.servers.append(section)
name = self._doreplace(name)
self.servername[section] = name
self.serverurl[section] = urls
failmeth = self._getoption(section,'failovermethod')
if failmeth == 'roundrobin':
failclass = failover.roundRobin(self, section)
elif failmeth == 'priority':
failclass = failover.priority(self, section)
else:
failclass = failover.roundRobin(self, section)
self.failoverclass[section] = failclass
if self._getoption(section,'gpgcheck') != None:
self.servergpgcheck[section]=self.cfg.getboolean(section,'gpgcheck')
else:
self.servergpgcheck[section]=0
if self._getoption(section, 'exclude') != None:
srvexcludelist = self._getoption(section, 'exclude')
srvexcludelist = self._doreplace(srvexcludelist)
srvexcludelist = self.parseList(srvexcludelist)
else:
srvexcludelist = []
self.serverexclude[section] = srvexcludelist
for url in self.serverurl[section]:
(s,b,p,q,f,o) = urlparse.urlparse(url)
# currently only allowing http and ftp servers
if s not in ['http', 'ftp', 'file', 'https']:
print _('using ftp, http[s], or file for servers, Aborting - %s') % (url)
sys.exit(1)
enablegroups=1
if self._getoption(section, 'enablegroups') != None:
enablegroups=self.cfg.getboolean(section, 'enablegroups')
self.groupsenable[section] = enablegroups
cache = os.path.join(self.cachedir,section)
pkgdir = os.path.join(cache, 'packages')
hdrdir = os.path.join(cache, 'headers')
self.servercache[section] = cache
self.serverpkgdir[section] = pkgdir
self.serverhdrdir[section] = hdrdir
else:
print _('Error: Cannot find baseurl or name for server \'%s\'. Skipping') %(section)
else:
print _('Insufficient server config - no servers found. Aborting.')
sys.exit(1)
def _getoption(self, section, option):
try:
return self.cfg.get(section, option)
except ConfigParser.NoSectionError, e:
print _('Failed to find section: %s') % section
except ConfigParser.NoOptionError, e:
return None
def parseList(self, value):
listvalue = []
# we need to allow for the '\n[whitespace]' continuation - easier
# to sub the \n with a space and then read the lines
slashnrepl = re.compile('\n')
commarepl = re.compile(',')
(value, count) = slashnrepl.subn(' ', value)
(value, count) = commarepl.subn(' ', value)
listvalue = value.split()
return listvalue
def remoteGroups(self, serverid):
return os.path.join(self.baseURL(serverid), 'yumgroups.xml')
def localGroups(self, serverid):
return os.path.join(self.servercache[serverid], 'yumgroups.xml')
def baseURL(self, serverid):
return self.get_failClass(serverid).get_serverurl()
def server_failed(self, serverid):
self.failoverclass[serverid].server_failed()
def get_failClass(self, serverid):
return self.failoverclass[serverid]
def remoteHeader(self, serverid):
return os.path.join(self.baseURL(serverid), 'headers/header.info')
def localHeader(self, serverid):
return os.path.join(self.servercache[serverid], 'header.info')
def _getsysdist(self):
ts = rpm.TransactionSet()
ts.setVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
idx = ts.dbMatch('provides', self.distroverpkg)
# we're going to take the first one - if there is more than one of these
# then the user needs a beating
if idx.count() == 0:
distribution = 'unknown'
else:
hdr = idx.next()
distribution = hdr['name']
del hdr
del idx
del ts
return distribution
def _getsysver(self):
ts = rpm.TransactionSet()
ts.setVSFlags(~(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS))
idx = ts.dbMatch('provides', self.distroverpkg)
# we're going to take the first one - if there is more than one of these
# then the user needs a beating
if idx.count() == 0:
releasever = 'Null'
else:
hdr = idx.next()
releasever = hdr['version']
del hdr
del idx
del ts
return releasever
def _getEnvVar(self):
yumvar = {}
yumvar[0] = os.environ.get('YUM0','$YUM0')
yumvar[1] = os.environ.get('YUM1','$YUM1')
yumvar[2] = os.environ.get('YUM2','$YUM2')
yumvar[3] = os.environ.get('YUM3','$YUM3')
yumvar[4] = os.environ.get('YUM4','$YUM4')
yumvar[5] = os.environ.get('YUM5','$YUM5')
yumvar[6] = os.environ.get('YUM6','$YUM6')
yumvar[7] = os.environ.get('YUM7','$YUM7')
yumvar[8] = os.environ.get('YUM8','$YUM8')
yumvar[9] = os.environ.get('YUM9','$YUM9')
return yumvar
def _doreplace(self, string):
""" do the replacement of yumvar, release, arch and basearch on any
string passed to it"""
if string is None:
return string
basearch_reg = re.compile('\$basearch')
arch_reg = re.compile('\$arch')
releasever_reg = re.compile('\$releasever')
distribution_reg = re.compile('\$distribution')
yum0_reg = re.compile('\$YUM0')
yum1_reg = re.compile('\$YUM1')
yum2_reg = re.compile('\$YUM2')
yum3_reg = re.compile('\$YUM3')
yum4_reg = re.compile('\$YUM4')
yum5_reg = re.compile('\$YUM5')
yum6_reg = re.compile('\$YUM6')
yum7_reg = re.compile('\$YUM7')
yum8_reg = re.compile('\$YUM8')
yum9_reg = re.compile('\$YUM9')
(string, count) = basearch_reg.subn(self.yumvar['basearch'], string)
(string, count) = arch_reg.subn(self.yumvar['arch'], string)
(string, count) = releasever_reg.subn(self.yumvar['releasever'], string)
(string, count) = distribution_reg.subn(self.yumvar['distribution'], string)
(string, count) = yum0_reg.subn(self.yumvar[0], string)
(string, count) = yum1_reg.subn(self.yumvar[1], string)
(string, count) = yum2_reg.subn(self.yumvar[2], string)
(string, count) = yum3_reg.subn(self.yumvar[3], string)
(string, count) = yum4_reg.subn(self.yumvar[4], string)
(string, count) = yum5_reg.subn(self.yumvar[5], string)
(string, count) = yum6_reg.subn(self.yumvar[6], string)
(string, count) = yum7_reg.subn(self.yumvar[7], string)
(string, count) = yum8_reg.subn(self.yumvar[8], string)
(string, count) = yum9_reg.subn(self.yumvar[9], string)
return string
More information about the Yum
mailing list