3 # Copyright (c) 2010, 2011 Intel, Inc.
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by the Free
7 # Software Foundation; version 2 of the License
9 # This program is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11 # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 # You should have received a copy of the GNU General Public License along
15 # with this program; if not, write to the Free Software Foundation, Inc., 59
16 # Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 import zypp #pylint: disable=import-error
25 if not hasattr(zypp, 'PoolQuery') or \
26 not hasattr(zypp.RepoManager, 'loadSolvFile'):
27 raise ImportError("python-zypp in host system cannot support PoolQuery or "
28 "loadSolvFile interface, please update it to enhanced "
29 "version which can be found in download.tizen.org/tools")
32 from mic.kickstart import ksparser
33 from mic.utils import misc, rpmmisc, runner, fs_related
34 from mic.utils.grabber import myurlgrab, TextProgress
35 from mic.utils.proxy import get_proxy_for
36 from mic.utils.errors import CreatorError, RepoError, RpmError
37 from mic.conf import configmgr
43 self.mirrorlist = None
45 self.proxy_username = None
46 self.proxy_password = None
50 self.autorefresh = True
51 self.keeppackages = True
54 from mic.pluginbase import BackendPlugin
55 class Zypp(BackendPlugin):
58 def __init__(self, target_arch, instroot, cachedir, strict_mode = False):
59 self.cachedir = cachedir
60 self.instroot = instroot
61 self.target_arch = target_arch
62 self.strict_mode = strict_mode
64 self.__pkgs_license = {}
65 self.__pkgs_content = {}
66 self.__pkgs_vcsinfo = {}
70 self.repo_manager = None
71 self.repo_manager_options = None
79 self.probFilterFlags = [ rpm.RPMPROB_FILTER_OLDPACKAGE,
80 rpm.RPMPROB_FILTER_REPLACEPKG ]
82 self.has_prov_query = True
83 self.install_debuginfo = False
84 # this can't be changed, it is used by zypp
85 self.tmp_file_path = '/var/tmp'
87 def doFileLogSetup(self, uid, logfile):
88 # don't do the file log for the livecd as it can lead to open fds
89 # being left and an inability to clean up after ourself
101 self.ts_pre.closeDB()
109 def _cleanupRpmdbLocks(self, installroot):
110 # cleans up temporary files left by bdb so that differing
111 # versions of rpm don't cause problems
113 for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
116 def _cleanupZyppJunk(self, installroot):
118 shutil.rmtree(os.path.join(installroot, '.zypp'))
123 self._cleanupRpmdbLocks(self.instroot)
124 # '/var/tmp' is used by zypp to build cache, so make sure
126 if not os.path.exists(self.tmp_file_path ):
127 os.makedirs(self.tmp_file_path)
129 def whatObsolete(self, pkg):
130 query = zypp.PoolQuery()
131 query.addKind(zypp.ResKind.package)
132 query.addDependency(zypp.SolvAttr.obsoletes, pkg.name(), pkg.edition())
133 query.setMatchExact()
134 for pi in query.queryResults(self.Z.pool()):
138 def _zyppQueryPackage(self, pkg):
139 query = zypp.PoolQuery()
140 query.addKind(zypp.ResKind.package)
141 query.addAttribute(zypp.SolvAttr.name, pkg)
142 query.setMatchExact()
143 for pi in query.queryResults(self.Z.pool()):
147 def _splitPkgString(self, pkg):
148 sp = pkg.rsplit(".", 1)
153 sysarch = zypp.Arch(self.target_arch)
154 if not zypp.Arch(arch).compatible_with (sysarch):
159 def selectPackage(self, pkg):
160 """Select a given package or package pattern, can be specified
161 with name.arch or name* or *name
165 self.__initialize_zypp()
167 def markPoolItem(obs, pi):
169 pi.status().setToBeInstalled (zypp.ResStatus.USER)
171 obs.status().setToBeInstalled (zypp.ResStatus.USER)
174 # compare criterion: arch compatibility first, then repo
175 # priority, and version last
178 if str(a1) != str(a2):
179 if a1.compatible_with(a2):
183 # Priority of a repository is an integer value between 0 (the
184 # highest priority) and 99 (the lowest priority)
185 pr1 = int(p1.repoInfo().priority())
186 pr2 = int(p2.repoInfo().priority())
194 (e1, v1, r1) = list(map(str, [ed1.epoch(), ed1.version(), ed1.release()]))
195 (e2, v2, r2) = list(map(str, [ed2.epoch(), ed2.version(), ed2.release()]))
196 return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
199 startx = pkg.startswith("*")
200 endx = pkg.endswith("*")
201 ispattern = startx or endx
202 name, arch = self._splitPkgString(pkg)
205 q.addKind(zypp.ResKind.package)
208 if startx and not endx:
209 pattern = '%s$' % (pkg[1:])
210 if endx and not startx:
211 pattern = '^%s' % (pkg[0:-1])
213 pattern = '%s' % (pkg[1:-1])
215 q.addAttribute(zypp.SolvAttr.name, pattern)
219 q.addAttribute(zypp.SolvAttr.name, name)
223 q.addAttribute(zypp.SolvAttr.name, pkg)
226 q.queryResults(self.Z.pool()),
227 cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
229 item = zypp.asKindPackage(pitem)
230 if item.name() in list(self.excpkgs.keys()) and \
231 self.excpkgs[item.name()] == item.repoInfo().name():
233 if item.name() in list(self.incpkgs.keys()) and \
234 self.incpkgs[item.name()] != item.repoInfo().name():
238 obspkg = self.whatObsolete(item)
240 if arch == str(item.arch()):
241 pitem.status().setToBeInstalled (zypp.ResStatus.USER)
243 markPoolItem(obspkg, pitem)
247 # Can't match using package name, then search from packge
248 # provides infomation
249 if found == False and not ispattern:
250 q.addAttribute(zypp.SolvAttr.provides, pkg)
251 q.addAttribute(zypp.SolvAttr.name,'')
254 q.queryResults(self.Z.pool()),
255 cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
257 item = zypp.asKindPackage(pitem)
258 if item.name() in list(self.excpkgs.keys()) and \
259 self.excpkgs[item.name()] == item.repoInfo().name():
261 if item.name() in list(self.incpkgs.keys()) and \
262 self.incpkgs[item.name()] != item.repoInfo().name():
266 obspkg = self.whatObsolete(item)
267 markPoolItem(obspkg, pitem)
273 raise CreatorError("Unable to find package: %s" % (pkg,))
275 def inDeselectPackages(self, pitem):
276 """check if specified pacakges are in the list of inDeselectPackages
278 item = zypp.asKindPackage(pitem)
280 for pkg in self.to_deselect:
281 startx = pkg.startswith("*")
282 endx = pkg.endswith("*")
283 ispattern = startx or endx
284 pkgname, pkgarch = self._splitPkgString(pkg)
287 if name == pkgname and str(item.arch()) == pkgarch:
293 if startx and name.endswith(pkg[1:]):
295 if endx and name.startswith(pkg[:-1]):
300 def deselectPackage(self, pkg):
301 """collect packages should not be installed"""
302 self.to_deselect.append(pkg)
304 def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
305 def compareGroup(pitem):
306 item = zypp.asKindPattern(pitem)
307 return item.repoInfo().priority()
309 self.__initialize_zypp()
312 q.addKind(zypp.ResKind.pattern)
313 for pitem in sorted(q.queryResults(self.Z.pool()), key=compareGroup):
314 item = zypp.asKindPattern(pitem)
315 summary = "%s" % item.summary()
316 name = "%s" % item.name()
317 if name == grp or summary == grp:
319 pitem.status().setToBeInstalled (zypp.ResStatus.USER)
323 if include == ksparser.GROUP_REQUIRED:
325 lambda p: self.deselectPackage(p),
326 list(grp.default_packages.keys())))
330 raise CreatorError("Unable to find pattern: %s" % (grp,))
332 def addRepository(self, name,
336 proxy_username = None,
337 proxy_password = None,
344 # TODO: Handle cost attribute for repos
346 if not self.repo_manager:
347 self.__initialize_repo_manager()
349 if not proxy and url:
350 proxy = get_proxy_for(url)
352 repo = RepositoryStub()
356 repo.proxy_username = proxy_username
357 repo.proxy_password = proxy_password
358 repo.ssl_verify = ssl_verify
359 repo.nocache = nocache
360 repo.baseurl.append(url)
363 self.incpkgs[pkg] = name
366 self.excpkgs[pkg] = name
369 repo.mirrorlist = mirrorlist
371 # Enable gpg check for verifying corrupt packages
373 if priority is not None:
374 # priority 0 has issue in RepoInfo.setPriority
375 repo.priority = priority + 1
378 repo_info = zypp.RepoInfo()
379 repo_info.setAlias(repo.name)
380 repo_info.setName(repo.name)
381 repo_info.setEnabled(repo.enabled)
382 repo_info.setAutorefresh(repo.autorefresh)
383 repo_info.setKeepPackages(repo.keeppackages)
384 baseurl = zypp.Url(repo.baseurl[0].full)
386 baseurl.setQueryParam("ssl_verify", "no")
388 host = urllib.parse.urlparse(proxy)[1]
389 # scheme, host, path, parm, query, frag = urlparse.urlparse(proxy)
391 proxyinfo = host.rsplit(":", 1)
395 if len(proxyinfo) > 1:
398 if proxy.startswith("socks") and len(proxy.rsplit(':', 1)) == 2:
399 host = proxy.rsplit(':', 1)[0]
400 port = proxy.rsplit(':', 1)[1]
402 # parse user/pass from proxy host
403 proxyinfo = host.rsplit("@", 1)
404 if len(proxyinfo) == 2:
406 # Known Issue: If password contains ":", which should be
407 # quoted, for example, use '123%3Aabc' instead of 123:abc
408 userpassinfo = proxyinfo[0].rsplit(":", 1)
409 if len(userpassinfo) == 2:
410 proxy_username = userpassinfo[0]
411 proxy_password = userpassinfo[1]
412 elif len(userpassinfo) == 1:
413 proxy_username = userpassinfo[0]
415 baseurl.setQueryParam ("proxy", host)
416 baseurl.setQueryParam ("proxyport", port)
418 baseurl.setQueryParam ("proxyuser", proxy_username)
420 baseurl.setQueryParam ("proxypass", proxy_password)
422 baseurl.setQueryParam ("proxy", "_none_")
424 self.repos.append(repo)
426 repo_info.addBaseUrl(baseurl)
428 if repo.priority is not None:
429 repo_info.setPriority(repo.priority)
431 # this hack is used to change zypp credential file location
432 # the default one is $HOME/.zypp, which cause conflicts when
433 # installing some basic packages, and the location doesn't
434 # have any interface actually, so use a tricky way anyway
436 if 'HOME' in os.environ:
437 homedir = os.environ['HOME']
438 os.environ['HOME'] = '/'
440 os.environ['HOME'] = '/'
442 self.repo_manager.addRepository(repo_info)
444 # save back the $HOME env
446 os.environ['HOME'] = homedir
448 del os.environ['HOME']
450 self.__build_repo_cache(name)
452 except RuntimeError as e:
453 raise CreatorError(str(e))
455 msger.verbose('repo: %s was added' % name)
458 def installHasFile(self, file):
461 def preInstall(self, pkg):
462 self.pre_pkgs.append(pkg)
464 def checkPackage(self, pkg):
465 self.check_pkgs.append(pkg)
467 def _get_local_packages(self):
468 """Return a list of rpm path to be local installed.
469 This is the hook where subclasses may specify a set of rpms which
470 it requires to be installed locally.
471 This returns an empty list by default.
472 Note, subclasses should usually chain up to the base class
473 implementation of this hook.
475 cropts = configmgr.create
476 if cropts['local_pkgs_path']:
477 if os.path.isdir(cropts['local_pkgs_path']):
479 os.path.join(cropts['local_pkgs_path'], '*.rpm'))
480 elif os.path.splitext(cropts['local_pkgs_path'])[-1] == '.rpm':
481 return [cropts['local_pkgs_path']]
483 def __localinst_packages(self):
484 for rpm_path in self._get_local_packages():
485 self.installLocal(rpm_path)
486 def runInstall(self, checksize = 0):
487 os.environ["HOME"] = "/"
488 os.environ["LD_PRELOAD"] = ""
489 self.buildTransaction()
490 self.__localinst_packages()
492 todo = zypp.GetResolvablesToInsDel(self.Z.pool())
493 installed_pkgs = todo._toInstall
496 for pitem in installed_pkgs:
497 if not zypp.isKindPattern(pitem) and \
498 not self.inDeselectPackages(pitem):
499 item = zypp.asKindPackage(pitem)
502 if item.name() in self.check_pkgs:
503 self.check_pkgs.remove(item.name())
505 if not self.install_debuginfo or str(item.arch()) == "noarch":
508 dipkg = self._zyppQueryPackage("%s-debuginfo" % item.name())
510 ditem = zypp.asKindPackage(dipkg)
513 msger.warning("No debuginfo rpm found for: %s" \
517 raise CreatorError('Packages absent in image: %s' % ','.join(self.check_pkgs))
519 # record all pkg and the content
520 localpkgs = list(self.localpkgs.keys())
523 if pkg.name() in localpkgs:
524 hdr = rpmmisc.readRpmHeader(self.ts, self.localpkgs[pkg.name()])
525 pkg_long_name = misc.RPM_FMT % {
528 'version': hdr['version'],
529 'release': hdr['release']
531 license = hdr['license']
534 pkg_long_name = misc.RPM_FMT % {
537 'version': pkg.edition().version(),
538 'release': pkg.edition().release()
541 license = pkg.license()
543 if license in list(self.__pkgs_license.keys()):
544 self.__pkgs_license[license].append(pkg_long_name)
546 self.__pkgs_license[license] = [pkg_long_name]
548 total_count = len(dlpkgs)
550 download_total_size = sum([int(x.downloadSize()) for x in dlpkgs])
551 localpkgs = list(self.localpkgs.keys())
553 msger.info("Checking packages cached ...")
555 # Check if it is cached locally
556 if po.name() in localpkgs:
559 local = self.getLocalPkgPath(po)
560 name = str(po.repoInfo().name())
562 repo = filter(lambda r: r.name == name, self.repos)[0]
565 nocache = repo.nocache if repo else False
567 if os.path.exists(local):
568 if nocache or self.checkPkg(local) !=0:
571 download_total_size -= int(po.downloadSize())
573 cache_avail_size = misc.get_filesystem_avail(self.cachedir)
574 if cache_avail_size < download_total_size:
575 raise CreatorError("No enough space used for downloading.")
577 # record the total size of installed pkgs
578 install_total_size = sum([int(x.installSize()) for x in dlpkgs])
579 # check needed size before actually download and install
581 # FIXME: for multiple partitions for loop type, check fails
582 # skip the check temporarily
583 #if checksize and install_total_size > checksize:
584 # raise CreatorError("No enough space used for installing, "
585 # "please resize partition size in ks file")
587 download_count = total_count - cached_count
588 msger.info("Packages: %d Total, %d Cached, %d Missed" \
589 % (total_count, cached_count, download_count))
592 if download_count > 0:
593 msger.info("Downloading packages ...")
594 self.downloadPkgs(dlpkgs, download_count)
595 except CreatorError as e:
596 raise CreatorError("Package download failed: %s" %(e,))
599 self.installPkgs(dlpkgs)
600 except (RepoError, RpmError):
602 except Exception as e:
603 raise CreatorError("Package installation failed: %s" % (e,))
605 def getVcsInfo(self):
606 if self.__pkgs_vcsinfo:
610 self.__initialize_transaction()
612 mi = self.ts.dbMatch()
614 lname = misc.RPM_FMT % {
617 'version': hdr['version'],
618 'release': hdr['release']
621 self.__pkgs_vcsinfo[lname] = hdr['VCS']
623 # if rpm not support VCS, set to None
624 self.__pkgs_vcsinfo[lname] = None
626 return self.__pkgs_vcsinfo
628 def getAllContent(self):
629 if self.__pkgs_content:
630 return self.__pkgs_content
633 self.__initialize_transaction()
635 mi = self.ts.dbMatch()
637 lname = misc.RPM_FMT % {
640 'version': hdr['version'],
641 'release': hdr['release']
643 self.__pkgs_content[lname] = hdr['FILENAMES']
645 return self.__pkgs_content
647 def getPkgsLicense(self):
648 return self.__pkgs_license
650 def getFilelist(self, pkgname):
655 self.__initialize_transaction()
657 mi = self.ts.dbMatch('name', pkgname)
659 return header['FILENAMES']
661 def __initialize_repo_manager(self):
662 if self.repo_manager:
665 # Clean up repo metadata
666 shutil.rmtree(self.cachedir + "/etc", ignore_errors = True)
667 shutil.rmtree(self.cachedir + "/solv", ignore_errors = True)
668 shutil.rmtree(self.cachedir + "/raw", ignore_errors = True)
670 zypp.KeyRing.setDefaultAccept( zypp.KeyRing.ACCEPT_UNSIGNED_FILE
671 | zypp.KeyRing.ACCEPT_VERIFICATION_FAILED
672 | zypp.KeyRing.ACCEPT_UNKNOWNKEY
673 | zypp.KeyRing.TRUST_KEY_TEMPORARILY
676 self.repo_manager_options = \
677 zypp.RepoManagerOptions(zypp.Pathname(self.instroot))
679 self.repo_manager_options.knownReposPath = \
680 zypp.Pathname(self.cachedir + "/etc/zypp/repos.d")
682 self.repo_manager_options.repoCachePath = \
683 zypp.Pathname(self.cachedir)
685 self.repo_manager_options.repoRawCachePath = \
686 zypp.Pathname(self.cachedir + "/raw")
688 self.repo_manager_options.repoSolvCachePath = \
689 zypp.Pathname(self.cachedir + "/solv")
691 self.repo_manager_options.repoPackagesCachePath = \
692 zypp.Pathname(self.cachedir + "/packages")
694 self.repo_manager = zypp.RepoManager(self.repo_manager_options)
696 def __build_repo_cache(self, name):
697 repo = self.repo_manager.getRepositoryInfo(name)
698 if self.repo_manager.isCached(repo) or not repo.enabled():
701 msger.info('Refreshing repository: %s ...' % name)
702 self.repo_manager.buildCache(repo, zypp.RepoManager.BuildIfNeeded)
704 def __initialize_zypp(self):
708 zconfig = zypp.ZConfig_instance()
710 # Set system architecture
712 zconfig.setSystemArchitecture(zypp.Arch(self.target_arch))
714 msger.info("zypp architecture is <%s>" % zconfig.systemArchitecture())
716 # repoPackagesCachePath is corrected by this
717 self.repo_manager = zypp.RepoManager(self.repo_manager_options)
718 repos = self.repo_manager.knownRepositories()
720 if not repo.enabled():
722 self.repo_manager.loadFromCache(repo)
724 self.Z = zypp.ZYppFactory_instance().getZYpp()
725 self.Z.initializeTarget(zypp.Pathname(self.instroot))
726 self.Z.target().load()
728 def buildTransaction(self):
729 if not self.Z.resolver().resolvePool():
730 probs = self.Z.resolver().problems()
732 for problem in probs:
733 msger.warning("repo problem: %s, %s" \
734 % (problem.description().decode("utf-8"),
735 problem.details().decode("utf-8")))
737 raise RepoError("found %d resolver problem, abort!" \
740 def getLocalPkgPath(self, po):
741 repoinfo = po.repoInfo()
742 cacheroot = repoinfo.packagesPath()
743 location = po.location()
744 rpmpath = str(location.filename())
745 pkgpath = "%s/%s" % (cacheroot, os.path.basename(rpmpath))
748 def installLocal(self, pkg, po=None, updateonly=False):
750 self.__initialize_transaction()
752 solvfile = "%s/.solv" % (self.cachedir)
754 rc, out = runner.runtool([fs_related.find_binary_path("rpms2solv"),
757 f = open(solvfile, "w+")
761 warnmsg = self.repo_manager.loadSolvFile(solvfile,
762 os.path.basename(pkg))
764 msger.warning(warnmsg)
768 msger.warning('Can not get %s solv data.' % pkg)
770 hdr = rpmmisc.readRpmHeader(self.ts, pkg)
771 arch = zypp.Arch(hdr['arch'])
772 sysarch = zypp.Arch(self.target_arch)
774 if arch.compatible_with (sysarch):
775 pkgname = hdr['name']
776 self.localpkgs[pkgname] = pkg
777 self.selectPackage(pkgname)
778 msger.info("Marking %s to be installed" % (pkg))
781 msger.warning("Cannot add package %s to transaction. "
782 "Not a compatible architecture: %s" \
783 % (pkg, hdr['arch']))
785 def downloadPkgs(self, package_objects, count):
786 localpkgs = list(self.localpkgs.keys())
787 progress_obj = TextProgress(count)
789 for po in package_objects:
790 if po.name() in localpkgs:
793 filename = self.getLocalPkgPath(po)
794 if os.path.exists(filename):
795 if self.checkPkg(filename) == 0:
798 dirn = os.path.dirname(filename)
799 if not os.path.exists(dirn):
802 url = self.get_url(po)
803 proxies = self.get_proxies(po)
806 filename = myurlgrab(url.full, filename, proxies, progress_obj)
811 def preinstallPkgs(self):
813 self.__initialize_transaction()
816 cb = rpmmisc.RPMInstallCallback(self.ts_pre)
817 cb.headmsg = "Preinstall"
818 installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
820 # start to catch stderr output from librpm
821 msger.enable_logstderr(installlogfile)
823 errors = self.ts_pre.run(cb.callback, '')
825 msger.disable_logstderr()
826 self.ts_pre.closeDB()
829 if errors is not None:
831 msger.warning('scriptlet or other non-fatal errors occurred '
832 'during transaction.')
837 raise RepoError('Could not run transaction.')
838 def show_unresolved_dependencies_msg(self, unresolved_dependencies):
839 for pkg, need, needflags, sense, key in unresolved_dependencies:
841 package = '-'.join(pkg)
843 if needflags == rpm.RPMSENSE_LESS:
844 deppkg = ' < '.join(need)
845 elif needflags == rpm.RPMSENSE_EQUAL:
846 deppkg = ' = '.join(need)
847 elif needflags == rpm.RPMSENSE_GREATER:
848 deppkg = ' > '.join(need)
850 deppkg = '-'.join(need)
852 if sense == rpm.RPMDEP_SENSE_REQUIRES:
853 msger.warning("[%s] Requires [%s], which is not provided" \
856 elif sense == rpm.RPMDEP_SENSE_CONFLICTS:
857 msger.warning("[%s] Conflicts with [%s]" % (package, deppkg))
859 def installPkgs(self, package_objects):
861 self.__initialize_transaction()
864 self._cleanupRpmdbLocks(self.instroot)
865 self._cleanupZyppJunk(self.instroot)
868 for flag in self.probFilterFlags:
870 self.ts.setProbFilter(probfilter)
871 self.ts_pre.setProbFilter(probfilter)
873 localpkgs = list(self.localpkgs.keys())
875 for po in package_objects:
877 if pkgname in localpkgs:
878 rpmpath = self.localpkgs[pkgname]
880 rpmpath = self.getLocalPkgPath(po)
882 if not os.path.exists(rpmpath):
883 # Maybe it is a local repo
884 rpmuri = self.get_url(po)
885 if rpmuri.startswith("file:/"):
888 if not os.path.exists(rpmpath):
889 raise RpmError("Error: %s doesn't exist" % rpmpath)
891 h = rpmmisc.readRpmHeader(self.ts, rpmpath)
893 if pkgname in self.pre_pkgs:
894 msger.verbose("pre-install package added: %s" % pkgname)
895 self.ts_pre.addInstall(h, rpmpath, 'u')
897 self.ts.addInstall(h, rpmpath, 'u')
899 unresolved_dependencies = self.ts.check()
900 if not unresolved_dependencies:
902 self.preinstallPkgs()
905 cb = rpmmisc.RPMInstallCallback(self.ts)
906 installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
908 # start to catch stderr output from librpm
909 msger.enable_logstderr(installlogfile)
911 errors = self.ts.run(cb.callback, '')
913 msger.disable_logstderr()
917 if errors is not None:
919 msger.warning('scriptlet or other non-fatal errors occurred '
920 'during transaction.')
922 raise CreatorError("mic failes to install some packages")
926 raise RepoError('Could not run transaction.')
929 self.show_unresolved_dependencies_msg(unresolved_dependencies)
930 raise RepoError("Unresolved dependencies, transaction failed.")
932 def __initialize_transaction(self):
934 self.ts = rpm.TransactionSet(self.instroot)
935 # Set to not verify DSA signatures.
936 self.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
939 self.ts_pre = rpm.TransactionSet(self.instroot)
940 # Just unpack the files, don't run scripts
941 self.ts_pre.setFlags(rpm.RPMTRANS_FLAG_ALLFILES | rpm.RPMTRANS_FLAG_NOSCRIPTS)
942 # Set to not verify DSA signatures.
943 self.ts_pre.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
945 def checkPkg(self, pkg):
947 if not os.path.exists(pkg):
949 ret = rpmmisc.checkRpmIntegrity('rpm', pkg)
951 msger.warning("package %s is damaged: %s" \
952 % (os.path.basename(pkg), pkg))
956 def _add_prob_flags(self, *flags):
958 if flag not in self.probFilterFlags:
959 self.probFilterFlags.append(flag)
961 def get_proxies(self, pobj):
967 repoinfo = pobj.repoInfo()
968 reponame = "%s" % repoinfo.name()
969 repos = [r for r in self.repos if r.name == reponame]
970 repourl = str(repoinfo.baseUrls()[0])
973 proxy = repos[0].proxy
975 proxy = get_proxy_for(repourl)
977 proxies = {str(repourl.split(':')[0]): str(proxy)}
981 def get_url(self, pobj):
985 name = str(pobj.repoInfo().name())
987 repo = filter(lambda r: r.name == name, self.repos)[0]
991 location = pobj.location()
992 location = str(location.filename())
993 if location.startswith("./"):
994 location = location[2:]
996 return repo.baseurl[0].join(location)
998 def package_url(self, pkgname):
1003 (e1, v1, r1) = list(map(str, [ed1.epoch(), ed1.version(), ed1.release()]))
1004 (e2, v2, r2) = list(map(str, [ed2.epoch(), ed2.version(), ed2.release()]))
1005 return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
1008 self.__initialize_zypp()
1010 q = zypp.PoolQuery()
1011 q.addKind(zypp.ResKind.package)
1013 q.addAttribute(zypp.SolvAttr.name, pkgname)
1014 items = sorted(q.queryResults(self.Z.pool()),
1015 cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
1019 item = zypp.asKindPackage(items[0])
1020 url = self.get_url(item)
1021 proxies = self.get_proxies(item)
1022 return (url, proxies)