Switch internal code to use new api
[livecd/EL-5.git] / imgcreate / yuminst.py
blobdd5b189762fe8721f6fc75ce50cbef067b2540d7
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 os
20 import sys
21 import logging
23 import yum
24 import rpmUtils
25 import pykickstart.parser
27 from imgcreate.errors import *
29 class TextProgress(object):
30 def start(self, filename, url, *args, **kwargs):
31 sys.stdout.write("Retrieving %s " % (url,))
32 self.url = url
33 def update(self, *args):
34 pass
35 def end(self, *args):
36 sys.stdout.write("...OK\n")
38 class LiveCDYum(yum.YumBase):
39 def __init__(self):
40 yum.YumBase.__init__(self)
42 def doFileLogSetup(self, uid, logfile):
43 # don't do the file log for the livecd as it can lead to open fds
44 # being left and an inability to clean up after ourself
45 pass
47 def close(self):
48 try:
49 os.unlink(self.conf.installroot + "/yum.conf")
50 except:
51 pass
52 yum.YumBase.close(self)
54 def __del__(self):
55 pass
57 def _writeConf(self, confpath, installroot):
58 conf = "[main]\n"
59 conf += "installroot=%s\n" % installroot
60 conf += "cachedir=/var/cache/yum\n"
61 conf += "plugins=0\n"
62 conf += "reposdir=\n"
63 conf += "failovermethod=priority\n"
65 f = file(confpath, "w+")
66 f.write(conf)
67 f.close()
69 os.chmod(confpath, 0644)
71 def setup(self, confpath, installroot):
72 self._writeConf(confpath, installroot)
73 self.doConfigSetup(fn = confpath, root = installroot)
74 self.conf.cache = 0
75 self.doTsSetup()
76 self.doRpmDBSetup()
77 self.doRepoSetup()
78 self.doSackSetup()
80 def selectPackage(self, pkg):
81 """Select a given package. Can be specified with name.arch or name*"""
82 return self.install(pattern = pkg)
84 def deselectPackage(self, pkg):
85 """Deselect package. Can be specified as name.arch or name*"""
86 sp = pkg.rsplit(".", 2)
87 txmbrs = []
88 if len(sp) == 2:
89 txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
91 if len(txmbrs) == 0:
92 exact, match, unmatch = yum.packages.parsePackages(self.pkgSack.returnPackages(), [pkg], casematch=1)
93 for p in exact + match:
94 txmbrs.append(p)
96 if len(txmbrs) > 0:
97 for x in txmbrs:
98 self.tsInfo.remove(x.pkgtup)
99 # we also need to remove from the conditionals
100 # dict so that things don't get pulled back in as a result
101 # of them. yes, this is ugly. conditionals should die.
102 for req, pkgs in self.tsInfo.conditionals.iteritems():
103 if x in pkgs:
104 pkgs.remove(x)
105 self.tsInfo.conditionals[req] = pkgs
106 else:
107 logging.warn("No such package %s to remove" %(pkg,))
109 def selectGroup(self, grp, include = pykickstart.parser.GROUP_DEFAULT):
110 yum.YumBase.selectGroup(self, grp)
111 if include == pykickstart.parser.GROUP_REQUIRED:
112 map(lambda p: self.deselectPackage(p), grp.default_packages.keys())
113 elif include == pykickstart.parser.GROUP_ALL:
114 map(lambda p: self.selectPackage(p), grp.optional_packages.keys())
116 def addRepository(self, name, url = None, mirrorlist = None):
117 def _varSubstitute(option):
118 # takes a variable and substitutes like yum configs do
119 option = option.replace("$basearch", rpmUtils.arch.getBaseArch())
120 option = option.replace("$arch", rpmUtils.arch.getCanonArch())
121 return option
123 repo = yum.yumRepo.YumRepository(name)
124 if url:
125 repo.baseurl.append(_varSubstitute(url))
126 if mirrorlist:
127 repo.mirrorlist = _varSubstitute(mirrorlist)
128 conf = yum.config.RepoConf()
129 for k, v in conf.iteritems():
130 if v or not hasattr(repo, k):
131 repo.setAttribute(k, v)
132 repo.basecachedir = self.conf.cachedir
133 repo.failovermethod = "priority"
134 repo.metadata_expire = 0
135 # disable gpg check???
136 repo.gpgcheck = 0
137 repo.enable()
138 repo.setup(0)
139 repo.setCallback(TextProgress())
140 self.repos.add(repo)
141 return repo
143 def installHasFile(self, file):
144 provides_pkg = self.whatProvides(file, None, None)
145 dlpkgs = map(lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers()))
146 for p in dlpkgs:
147 for q in provides_pkg:
148 if (p == q):
149 return True
150 return False
153 def runInstall(self):
154 os.environ["HOME"] = "/"
155 try:
156 (res, resmsg) = self.buildTransaction()
157 except yum.Errors.RepoError, e:
158 raise CreatorError("Unable to download from repo : %s" %(e,))
159 if res != 2:
160 raise CreatorError("Failed to build transaction : %s" % str.join("\n", resmsg))
162 dlpkgs = map(lambda x: x.po, filter(lambda txmbr: txmbr.ts_state in ("i", "u"), self.tsInfo.getMembers()))
163 self.downloadPkgs(dlpkgs)
164 # FIXME: sigcheck?
166 self.initActionTs()
167 self.populateTs(keepold=0)
168 deps = self.ts.check()
169 if len(deps) != 0:
170 raise CreatorError("Dependency check failed!")
171 rc = self.ts.order()
172 if rc != 0:
173 raise CreatorError("ordering packages for installation failed!")
175 # FIXME: callback should be refactored a little in yum
176 sys.path.append('/usr/share/yum-cli')
177 import callback
178 cb = callback.RPMInstallCallback()
179 cb.tsInfo = self.tsInfo
180 cb.filelog = False
181 ret = self.runTransaction(cb)
182 print ""
183 return ret