Add support for timeout and totaltimeout to livecd-iso-to-disk (#531566)
[livecd.git] / imgcreate / yuminst.py
blob9e549827c7ff027d618dca46d2fc2a2c990cdf21
2 # yum.py : yum utilities
4 # Copyright 2007, Red Hat Inc.
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; version 2 of the License.
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Library General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 import glob
20 import os
21 import sys
22 import logging
24 import yum
25 import rpmUtils
26 import pykickstart.parser
28 from imgcreate.errors import *
30 class TextProgress(object):
31 def start(self, filename, url, *args, **kwargs):
32 sys.stdout.write("Retrieving %s " % (url,))
33 self.url = url
34 def update(self, *args):
35 pass
36 def end(self, *args):
37 sys.stdout.write("...OK\n")
39 class LiveCDYum(yum.YumBase):
40 def __init__(self):
41 yum.YumBase.__init__(self)
43 def doFileLogSetup(self, uid, logfile):
44 # don't do the file log for the livecd as it can lead to open fds
45 # being left and an inability to clean up after ourself
46 pass
48 def close(self):
49 try:
50 os.unlink(self.conf.installroot + "/yum.conf")
51 except:
52 pass
53 yum.YumBase.close(self)
55 def __del__(self):
56 pass
58 def _writeConf(self, confpath, installroot):
59 conf = "[main]\n"
60 conf += "installroot=%s\n" % installroot
61 conf += "cachedir=/var/cache/yum\n"
62 conf += "plugins=0\n"
63 conf += "reposdir=\n"
64 conf += "failovermethod=priority\n"
65 conf += "keepcache=1\n"
67 f = file(confpath, "w+")
68 f.write(conf)
69 f.close()
71 os.chmod(confpath, 0644)
73 def _cleanupRpmdbLocks(self, installroot):
74 # cleans up temporary files left by bdb so that differing
75 # versions of rpm don't cause problems
76 for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
77 os.unlink(f)
79 def setup(self, confpath, installroot):
80 self._writeConf(confpath, installroot)
81 self._cleanupRpmdbLocks(installroot)
82 self.doConfigSetup(fn = confpath, root = installroot)
83 self.conf.cache = 0
84 self.doTsSetup()
85 self.doRpmDBSetup()
86 self.doRepoSetup()
87 self.doSackSetup()
89 def selectPackage(self, pkg):
90 """Select a given package. Can be specified with name.arch or name*"""
91 return self.install(pattern = pkg)
93 def deselectPackage(self, pkg):
94 """Deselect package. Can be specified as name.arch or name*"""
95 sp = pkg.rsplit(".", 2)
96 txmbrs = []
97 if len(sp) == 2:
98 txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
100 if len(txmbrs) == 0:
101 exact, match, unmatch = yum.packages.parsePackages(self.pkgSack.returnPackages(), [pkg], casematch=1)
102 for p in exact + match:
103 txmbrs.append(p)
105 if len(txmbrs) > 0:
106 for x in txmbrs:
107 self.tsInfo.remove(x.pkgtup)
108 # we also need to remove from the conditionals
109 # dict so that things don't get pulled back in as a result
110 # of them. yes, this is ugly. conditionals should die.
111 for req, pkgs in self.tsInfo.conditionals.iteritems():
112 if x in pkgs:
113 pkgs.remove(x)
114 self.tsInfo.conditionals[req] = pkgs
115 else:
116 logging.warn("No such package %s to remove" %(pkg,))
118 def selectGroup(self, grp, include = pykickstart.parser.GROUP_DEFAULT):
119 # default to getting mandatory and default packages from a group
120 # unless we have specific options from kickstart
121 package_types = ['mandatory', 'default']
122 if include == pykickstart.parser.GROUP_REQUIRED:
123 package_types.remove('default')
124 elif include == pykickstart.parser.GROUP_ALL:
125 package_types.append('optional')
126 yum.YumBase.selectGroup(self, grp, group_package_types=package_types)
128 def addRepository(self, name, url = None, mirrorlist = None):
129 def _varSubstitute(option):
130 # takes a variable and substitutes like yum configs do
131 option = option.replace("$basearch", rpmUtils.arch.getBaseArch())
132 option = option.replace("$arch", rpmUtils.arch.getCanonArch())
133 option = option.replace("$releasever", yum.config._getsysver("/", "redhat-release"))
134 return option
136 repo = yum.yumRepo.YumRepository(name)
137 if url:
138 repo.baseurl.append(_varSubstitute(url))
139 if mirrorlist:
140 repo.mirrorlist = _varSubstitute(mirrorlist)
141 conf = yum.config.RepoConf()
142 for k, v in conf.iteritems():
143 if v or not hasattr(repo, k):
144 repo.setAttribute(k, v)
145 repo.basecachedir = self.conf.cachedir
146 repo.failovermethod = "priority"
147 repo.metadata_expire = 0
148 repo.mirrorlist_expire = 0
149 repo.timestamp_check = 0
150 # disable gpg check???
151 repo.gpgcheck = 0
152 repo.enable()
153 repo.setup(0)
154 repo.setCallback(TextProgress())
155 self.repos.add(repo)
156 return repo
158 def installHasFile(self, file):
159 provides_pkg = self.whatProvides(file, None, None)
160 dlpkgs = map(lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers()))
161 for p in dlpkgs:
162 for q in provides_pkg:
163 if (p == q):
164 return True
165 return False
168 def runInstall(self):
169 os.environ["HOME"] = "/"
170 try:
171 (res, resmsg) = self.buildTransaction()
172 except yum.Errors.RepoError, e:
173 raise CreatorError("Unable to download from repo : %s" %(e,))
174 if res != 2:
175 raise CreatorError("Failed to build transaction : %s" % str.join("\n", resmsg))
177 dlpkgs = map(lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers()))
178 self.downloadPkgs(dlpkgs)
179 # FIXME: sigcheck?
181 self.initActionTs()
182 self.populateTs(keepold=0)
183 deps = self.ts.check()
184 if len(deps) != 0:
185 raise CreatorError("Dependency check failed!")
186 rc = self.ts.order()
187 if rc != 0:
188 raise CreatorError("ordering packages for installation failed!")
190 # FIXME: callback should be refactored a little in yum
191 sys.path.append('/usr/share/yum-cli')
192 import yum.misc
193 yum.misc.setup_locale()
194 import callback
195 cb = callback.RPMInstallCallback()
196 cb.tsInfo = self.tsInfo
197 cb.filelog = False
198 ret = self.runTransaction(cb)
199 print ""
200 self._cleanupRpmdbLocks(self.conf.installroot)
201 return ret