wic: Remove mic package managers

wic doesn't use the yum or zypp package managers, remove them.

(From OE-Core rev: ef70b961b6b8f3a004036f84b608665db2085215)

Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
This commit is contained in:
Tom Zanussi
2014-08-03 12:28:32 -05:00
committed by Richard Purdie
parent f1dbd46e7e
commit a9351096db
2 changed files with 0 additions and 1463 deletions

View File

@@ -1,490 +0,0 @@
#!/usr/bin/python -tt
#
# Copyright (c) 2007 Red Hat Inc.
# Copyright (c) 2010, 2011 Intel, 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; version 2 of the License
#
# 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, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os, sys
import re
import tempfile
import glob
from string import Template
import rpmUtils
import yum
from mic import msger
from mic.kickstart import ksparser
from mic.utils import misc, rpmmisc
from mic.utils.grabber import TextProgress
from mic.utils.proxy import get_proxy_for
from mic.utils.errors import CreatorError
from mic.imager.baseimager import BaseImageCreator
YUMCONF_TEMP = """[main]
installroot=$installroot
cachedir=/var/cache/yum
persistdir=/var/lib/yum
plugins=0
reposdir=
failovermethod=priority
http_caching=packages
sslverify=1
"""
class MyYumRepository(yum.yumRepo.YumRepository):
def __del__(self):
pass
def dirSetup(self):
super(MyYumRepository, self).dirSetup()
# relocate package dir
pkgdir = os.path.join(self.basecachedir, 'packages', self.id)
self.setAttribute('_dir_setup_pkgdir', pkgdir)
self._dirSetupMkdir_p(self.pkgdir)
def _getFile(self, url=None,
relative=None,
local=None,
start=None,
end=None,
copy_local=None,
checkfunc=None,
text=None,
reget='simple',
cache=True,
size=None):
m2c_connection = None
if not self.sslverify:
try:
import M2Crypto
m2c_connection = M2Crypto.SSL.Connection.clientPostConnectionCheck
M2Crypto.SSL.Connection.clientPostConnectionCheck = None
except ImportError, err:
raise CreatorError("%s, please try to install python-m2crypto" % str(err))
proxy = None
if url:
proxy = get_proxy_for(url)
else:
proxy = get_proxy_for(self.urls[0])
if proxy:
self.proxy = str(proxy)
size = int(size) if size else None
rvalue = super(MyYumRepository, self)._getFile(url,
relative,
local,
start,
end,
copy_local,
checkfunc,
text,
reget,
cache,
size)
if m2c_connection and \
not M2Crypto.SSL.Connection.clientPostConnectionCheck:
M2Crypto.SSL.Connection.clientPostConnectionCheck = m2c_connection
return rvalue
from mic.pluginbase import BackendPlugin
class Yum(BackendPlugin, yum.YumBase):
name = 'yum'
def __init__(self, target_arch, instroot, cachedir):
yum.YumBase.__init__(self)
self.cachedir = cachedir
self.instroot = instroot
self.target_arch = target_arch
if self.target_arch:
if not rpmUtils.arch.arches.has_key(self.target_arch):
rpmUtils.arch.arches["armv7hl"] = "noarch"
rpmUtils.arch.arches["armv7tnhl"] = "armv7nhl"
rpmUtils.arch.arches["armv7tnhl"] = "armv7thl"
rpmUtils.arch.arches["armv7thl"] = "armv7hl"
rpmUtils.arch.arches["armv7nhl"] = "armv7hl"
self.arch.setup_arch(self.target_arch)
self.__pkgs_license = {}
self.__pkgs_content = {}
self.__pkgs_vcsinfo = {}
self.install_debuginfo = False
def doFileLogSetup(self, uid, logfile):
# don't do the file log for the livecd as it can lead to open fds
# being left and an inability to clean up after ourself
pass
def close(self):
try:
os.unlink(self.confpath)
os.unlink(self.conf.installroot + "/yum.conf")
except:
pass
if self.ts:
self.ts.close()
self._delRepos()
self._delSacks()
yum.YumBase.close(self)
self.closeRpmDB()
if not os.path.exists("/etc/fedora-release") and \
not os.path.exists("/etc/meego-release"):
for i in range(3, os.sysconf("SC_OPEN_MAX")):
try:
os.close(i)
except:
pass
def __del__(self):
pass
def _writeConf(self, confpath, installroot):
conf = Template(YUMCONF_TEMP).safe_substitute(installroot=installroot)
f = file(confpath, "w+")
f.write(conf)
f.close()
os.chmod(confpath, 0644)
def _cleanupRpmdbLocks(self, installroot):
# cleans up temporary files left by bdb so that differing
# versions of rpm don't cause problems
for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
os.unlink(f)
def setup(self):
# create yum.conf
(fn, self.confpath) = tempfile.mkstemp(dir=self.cachedir,
prefix='yum.conf-')
os.close(fn)
self._writeConf(self.confpath, self.instroot)
self._cleanupRpmdbLocks(self.instroot)
# do setup
self.doConfigSetup(fn = self.confpath, root = self.instroot)
self.conf.cache = 0
self.doTsSetup()
self.doRpmDBSetup()
self.doRepoSetup()
self.doSackSetup()
def preInstall(self, pkg):
# FIXME: handle pre-install package
return None
def selectPackage(self, pkg):
"""Select a given package.
Can be specified with name.arch or name*
"""
try:
self.install(pattern = pkg)
return None
except yum.Errors.InstallError:
return "No package(s) available to install"
except yum.Errors.RepoError, e:
raise CreatorError("Unable to download from repo : %s" % (e,))
except yum.Errors.YumBaseError, e:
raise CreatorError("Unable to install: %s" % (e,))
def deselectPackage(self, pkg):
"""Deselect package. Can be specified as name.arch or name*
"""
sp = pkg.rsplit(".", 2)
txmbrs = []
if len(sp) == 2:
txmbrs = self.tsInfo.matchNaevr(name=sp[0], arch=sp[1])
if len(txmbrs) == 0:
exact, match, unmatch = yum.packages.parsePackages(
self.pkgSack.returnPackages(),
[pkg],
casematch=1)
for p in exact + match:
txmbrs.append(p)
if len(txmbrs) > 0:
for x in txmbrs:
self.tsInfo.remove(x.pkgtup)
# we also need to remove from the conditionals
# dict so that things don't get pulled back in as a result
# of them. yes, this is ugly. conditionals should die.
for req, pkgs in self.tsInfo.conditionals.iteritems():
if x in pkgs:
pkgs.remove(x)
self.tsInfo.conditionals[req] = pkgs
else:
msger.warning("No such package %s to remove" %(pkg,))
def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
try:
yum.YumBase.selectGroup(self, grp)
if include == ksparser.GROUP_REQUIRED:
for p in grp.default_packages.keys():
self.deselectPackage(p)
elif include == ksparser.GROUP_ALL:
for p in grp.optional_packages.keys():
self.selectPackage(p)
return None
except (yum.Errors.InstallError, yum.Errors.GroupsError), e:
return e
except yum.Errors.RepoError, e:
raise CreatorError("Unable to download from repo : %s" % (e,))
except yum.Errors.YumBaseError, e:
raise CreatorError("Unable to install: %s" % (e,))
def addRepository(self, name, url = None, mirrorlist = None, proxy = None,
proxy_username = None, proxy_password = None,
inc = None, exc = None, ssl_verify=True, nocache=False,
cost = None, priority=None):
# TODO: Handle priority attribute for repos
def _varSubstitute(option):
# takes a variable and substitutes like yum configs do
option = option.replace("$basearch", rpmUtils.arch.getBaseArch())
option = option.replace("$arch", rpmUtils.arch.getCanonArch())
return option
repo = MyYumRepository(name)
# Set proxy
repo.proxy = proxy
repo.proxy_username = proxy_username
repo.proxy_password = proxy_password
if url:
repo.baseurl.append(_varSubstitute(url))
# check LICENSE files
if not rpmmisc.checkRepositoryEULA(name, repo):
msger.warning('skip repo:%s for failed EULA confirmation' % name)
return None
if mirrorlist:
repo.mirrorlist = _varSubstitute(mirrorlist)
conf = yum.config.RepoConf()
for k, v in conf.iteritems():
if v or not hasattr(repo, k):
repo.setAttribute(k, v)
repo.sslverify = ssl_verify
repo.cache = not nocache
repo.basecachedir = self.cachedir
repo.base_persistdir = self.conf.persistdir
repo.failovermethod = "priority"
repo.metadata_expire = 0
# Enable gpg check for verifying corrupt packages
repo.gpgcheck = 1
repo.enable()
repo.setup(0)
self.repos.add(repo)
if cost:
repo.cost = cost
msger.verbose('repo: %s was added' % name)
return repo
def installLocal(self, pkg, po=None, updateonly=False):
ts = rpmUtils.transaction.initReadOnlyTransaction()
try:
hdr = rpmUtils.miscutils.hdrFromPackage(ts, pkg)
except rpmUtils.RpmUtilsError, e:
raise yum.Errors.MiscError, \
'Could not open local rpm file: %s: %s' % (pkg, e)
self.deselectPackage(hdr['name'])
yum.YumBase.installLocal(self, pkg, po, updateonly)
def installHasFile(self, file):
provides_pkg = self.whatProvides(file, None, None)
dlpkgs = map(
lambda x: x.po,
filter(
lambda txmbr: txmbr.ts_state in ("i", "u"),
self.tsInfo.getMembers()))
for p in dlpkgs:
for q in provides_pkg:
if (p == q):
return True
return False
def runInstall(self, checksize = 0):
os.environ["HOME"] = "/"
os.environ["LD_PRELOAD"] = ""
try:
(res, resmsg) = self.buildTransaction()
except yum.Errors.RepoError, e:
raise CreatorError("Unable to download from repo : %s" %(e,))
if res != 2:
raise CreatorError("Failed to build transaction : %s" \
% str.join("\n", resmsg))
dlpkgs = map(
lambda x: x.po,
filter(
lambda txmbr: txmbr.ts_state in ("i", "u"),
self.tsInfo.getMembers()))
# record all pkg and the content
for pkg in dlpkgs:
pkg_long_name = misc.RPM_FMT % {
'name': pkg.name,
'arch': pkg.arch,
'version': pkg.version,
'release': pkg.release
}
self.__pkgs_content[pkg_long_name] = pkg.files
license = pkg.license
if license in self.__pkgs_license.keys():
self.__pkgs_license[license].append(pkg_long_name)
else:
self.__pkgs_license[license] = [pkg_long_name]
total_count = len(dlpkgs)
cached_count = 0
download_total_size = sum(map(lambda x: int(x.packagesize), dlpkgs))
msger.info("\nChecking packages cached ...")
for po in dlpkgs:
local = po.localPkg()
repo = filter(lambda r: r.id == po.repoid, self.repos.listEnabled())[0]
if not repo.cache and os.path.exists(local):
os.unlink(local)
if not os.path.exists(local):
continue
if not self.verifyPkg(local, po, False):
msger.warning("Package %s is damaged: %s" \
% (os.path.basename(local), local))
else:
download_total_size -= int(po.packagesize)
cached_count +=1
cache_avail_size = misc.get_filesystem_avail(self.cachedir)
if cache_avail_size < download_total_size:
raise CreatorError("No enough space used for downloading.")
# record the total size of installed pkgs
pkgs_total_size = 0L
for x in dlpkgs:
if hasattr(x, 'installedsize'):
pkgs_total_size += int(x.installedsize)
else:
pkgs_total_size += int(x.size)
# check needed size before actually download and install
if checksize and pkgs_total_size > checksize:
raise CreatorError("No enough space used for installing, "
"please resize partition size in ks file")
msger.info("Packages: %d Total, %d Cached, %d Missed" \
% (total_count, cached_count, total_count - cached_count))
try:
repos = self.repos.listEnabled()
for repo in repos:
repo.setCallback(TextProgress(total_count - cached_count))
self.downloadPkgs(dlpkgs)
# FIXME: sigcheck?
self.initActionTs()
self.populateTs(keepold=0)
deps = self.ts.check()
if len(deps) != 0:
# This isn't fatal, Ubuntu has this issue but it is ok.
msger.debug(deps)
msger.warning("Dependency check failed!")
rc = self.ts.order()
if rc != 0:
raise CreatorError("ordering packages for installation failed")
# FIXME: callback should be refactored a little in yum
cb = rpmmisc.RPMInstallCallback(self.ts)
cb.tsInfo = self.tsInfo
cb.filelog = False
msger.warning('\nCaution, do NOT interrupt the installation, '
'else mic cannot finish the cleanup.')
installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
msger.enable_logstderr(installlogfile)
self.runTransaction(cb)
self._cleanupRpmdbLocks(self.conf.installroot)
except rpmUtils.RpmUtilsError, e:
raise CreatorError("mic does NOT support delta rpm: %s" % e)
except yum.Errors.RepoError, e:
raise CreatorError("Unable to download from repo : %s" % e)
except yum.Errors.YumBaseError, e:
raise CreatorError("Unable to install: %s" % e)
finally:
msger.disable_logstderr()
def getVcsInfo(self):
return self.__pkgs_vcsinfo
def getAllContent(self):
return self.__pkgs_content
def getPkgsLicense(self):
return self.__pkgs_license
def getFilelist(self, pkgname):
if not pkgname:
return None
pkg = filter(lambda txmbr: txmbr.po.name == pkgname, self.tsInfo.getMembers())
if not pkg:
return None
return pkg[0].po.filelist
def package_url(self, pkgname):
pkgs = self.pkgSack.searchNevra(name=pkgname)
if pkgs:
proxy = None
proxies = None
url = pkgs[0].remote_url
repoid = pkgs[0].repoid
repos = filter(lambda r: r.id == repoid, self.repos.listEnabled())
if repos:
proxy = repos[0].proxy
if not proxy:
proxy = get_proxy_for(url)
if proxy:
proxies = {str(url.split(':')[0]): str(proxy)}
return (url, proxies)
return (None, None)

View File

@@ -1,973 +0,0 @@
#!/usr/bin/python -tt
#
# Copyright (c) 2010, 2011 Intel, 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; version 2 of the License
#
# 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, write to the Free Software Foundation, Inc., 59
# Temple Place - Suite 330, Boston, MA 02111-1307, USA.
import os
import shutil
import urlparse
import rpm
import zypp
if not hasattr(zypp, 'PoolQuery') or \
not hasattr(zypp.RepoManager, 'loadSolvFile'):
raise ImportError("python-zypp in host system cannot support PoolQuery or "
"loadSolvFile interface, please update it to enhanced "
"version which can be found in download.tizen.org/tools")
from mic import msger
from mic.kickstart import ksparser
from mic.utils import misc, rpmmisc, runner, fs_related
from mic.utils.grabber import myurlgrab, TextProgress
from mic.utils.proxy import get_proxy_for
from mic.utils.errors import CreatorError, RepoError, RpmError
from mic.imager.baseimager import BaseImageCreator
class RepositoryStub:
def __init__(self):
self.name = None
self.baseurl = []
self.mirrorlist = None
self.proxy = None
self.proxy_username = None
self.proxy_password = None
self.nocache = False
self.enabled = True
self.autorefresh = True
self.keeppackages = True
self.priority = None
from mic.pluginbase import BackendPlugin
class Zypp(BackendPlugin):
name = 'zypp'
def __init__(self, target_arch, instroot, cachedir):
self.cachedir = cachedir
self.instroot = instroot
self.target_arch = target_arch
self.__pkgs_license = {}
self.__pkgs_content = {}
self.__pkgs_vcsinfo = {}
self.repos = []
self.to_deselect = []
self.localpkgs = {}
self.repo_manager = None
self.repo_manager_options = None
self.Z = None
self.ts = None
self.ts_pre = None
self.incpkgs = {}
self.excpkgs = {}
self.pre_pkgs = []
self.probFilterFlags = [ rpm.RPMPROB_FILTER_OLDPACKAGE,
rpm.RPMPROB_FILTER_REPLACEPKG ]
self.has_prov_query = True
self.install_debuginfo = False
def doFileLogSetup(self, uid, logfile):
# don't do the file log for the livecd as it can lead to open fds
# being left and an inability to clean up after ourself
pass
def closeRpmDB(self):
pass
def close(self):
if self.ts:
self.ts.closeDB()
self.ts = None
if self.ts_pre:
self.ts_pre.closeDB()
self.ts = None
self.closeRpmDB()
if not os.path.exists("/etc/fedora-release") and \
not os.path.exists("/etc/meego-release"):
for i in range(3, os.sysconf("SC_OPEN_MAX")):
try:
os.close(i)
except:
pass
def __del__(self):
self.close()
def _cleanupRpmdbLocks(self, installroot):
# cleans up temporary files left by bdb so that differing
# versions of rpm don't cause problems
import glob
for f in glob.glob(installroot + "/var/lib/rpm/__db*"):
os.unlink(f)
def _cleanupZyppJunk(self, installroot):
try:
shutil.rmtree(os.path.join(installroot, '.zypp'))
except:
pass
def setup(self):
self._cleanupRpmdbLocks(self.instroot)
def whatObsolete(self, pkg):
query = zypp.PoolQuery()
query.addKind(zypp.ResKind.package)
query.addAttribute(zypp.SolvAttr.obsoletes, pkg)
query.setMatchExact()
for pi in query.queryResults(self.Z.pool()):
return pi
return None
def _zyppQueryPackage(self, pkg):
query = zypp.PoolQuery()
query.addKind(zypp.ResKind.package)
query.addAttribute(zypp.SolvAttr.name,pkg)
query.setMatchExact()
for pi in query.queryResults(self.Z.pool()):
return pi
return None
def _splitPkgString(self, pkg):
sp = pkg.rsplit(".",1)
name = sp[0]
arch = None
if len(sp) == 2:
arch = sp[1]
sysarch = zypp.Arch(self.target_arch)
if not zypp.Arch(arch).compatible_with (sysarch):
arch = None
name = ".".join(sp)
return name, arch
def selectPackage(self, pkg):
"""Select a given package or package pattern, can be specified
with name.arch or name* or *name
"""
if not self.Z:
self.__initialize_zypp()
def markPoolItem(obs, pi):
if obs == None:
pi.status().setToBeInstalled (zypp.ResStatus.USER)
else:
obs.status().setToBeInstalled (zypp.ResStatus.USER)
def cmpEVR(p1, p2):
# compare criterion: arch compatibility first, then repo
# priority, and version last
a1 = p1.arch()
a2 = p2.arch()
if str(a1) != str(a2):
if a1.compatible_with(a2):
return -1
else:
return 1
# Priority of a repository is an integer value between 0 (the
# highest priority) and 99 (the lowest priority)
pr1 = int(p1.repoInfo().priority())
pr2 = int(p2.repoInfo().priority())
if pr1 > pr2:
return -1
elif pr1 < pr2:
return 1
ed1 = p1.edition()
ed2 = p2.edition()
(e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()])
(e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()])
return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
found = False
startx = pkg.startswith("*")
endx = pkg.endswith("*")
ispattern = startx or endx
name, arch = self._splitPkgString(pkg)
q = zypp.PoolQuery()
q.addKind(zypp.ResKind.package)
if ispattern:
if startx and not endx:
pattern = '%s$' % (pkg[1:])
if endx and not startx:
pattern = '^%s' % (pkg[0:-1])
if endx and startx:
pattern = '%s' % (pkg[1:-1])
q.setMatchRegex()
q.addAttribute(zypp.SolvAttr.name,pattern)
elif arch:
q.setMatchExact()
q.addAttribute(zypp.SolvAttr.name,name)
else:
q.setMatchExact()
q.addAttribute(zypp.SolvAttr.name,pkg)
for pitem in sorted(
q.queryResults(self.Z.pool()),
cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
reverse=True):
item = zypp.asKindPackage(pitem)
if item.name() in self.excpkgs.keys() and \
self.excpkgs[item.name()] == item.repoInfo().name():
continue
if item.name() in self.incpkgs.keys() and \
self.incpkgs[item.name()] != item.repoInfo().name():
continue
found = True
obspkg = self.whatObsolete(item.name())
if arch:
if arch == str(item.arch()):
item.status().setToBeInstalled (zypp.ResStatus.USER)
else:
markPoolItem(obspkg, pitem)
if not ispattern:
break
# Can't match using package name, then search from packge
# provides infomation
if found == False and not ispattern:
q.addAttribute(zypp.SolvAttr.provides, pkg)
q.addAttribute(zypp.SolvAttr.name,'')
for pitem in sorted(
q.queryResults(self.Z.pool()),
cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
reverse=True):
item = zypp.asKindPackage(pitem)
if item.name() in self.excpkgs.keys() and \
self.excpkgs[item.name()] == item.repoInfo().name():
continue
if item.name() in self.incpkgs.keys() and \
self.incpkgs[item.name()] != item.repoInfo().name():
continue
found = True
obspkg = self.whatObsolete(item.name())
markPoolItem(obspkg, pitem)
break
if found:
return None
else:
raise CreatorError("Unable to find package: %s" % (pkg,))
def inDeselectPackages(self, pitem):
"""check if specified pacakges are in the list of inDeselectPackages
"""
item = zypp.asKindPackage(pitem)
name = item.name()
for pkg in self.to_deselect:
startx = pkg.startswith("*")
endx = pkg.endswith("*")
ispattern = startx or endx
pkgname, pkgarch = self._splitPkgString(pkg)
if not ispattern:
if pkgarch:
if name == pkgname and str(item.arch()) == pkgarch:
return True;
else:
if name == pkgname:
return True;
else:
if startx and name.endswith(pkg[1:]):
return True;
if endx and name.startswith(pkg[:-1]):
return True;
return False;
def deselectPackage(self, pkg):
"""collect packages should not be installed"""
self.to_deselect.append(pkg)
def selectGroup(self, grp, include = ksparser.GROUP_DEFAULT):
if not self.Z:
self.__initialize_zypp()
found = False
q=zypp.PoolQuery()
q.addKind(zypp.ResKind.pattern)
for pitem in q.queryResults(self.Z.pool()):
item = zypp.asKindPattern(pitem)
summary = "%s" % item.summary()
name = "%s" % item.name()
if name == grp or summary == grp:
found = True
pitem.status().setToBeInstalled (zypp.ResStatus.USER)
break
if found:
if include == ksparser.GROUP_REQUIRED:
map(
lambda p: self.deselectPackage(p),
grp.default_packages.keys())
return None
else:
raise CreatorError("Unable to find pattern: %s" % (grp,))
def addRepository(self, name,
url = None,
mirrorlist = None,
proxy = None,
proxy_username = None,
proxy_password = None,
inc = None,
exc = None,
ssl_verify = True,
nocache = False,
cost=None,
priority=None):
# TODO: Handle cost attribute for repos
if not self.repo_manager:
self.__initialize_repo_manager()
if not proxy and url:
proxy = get_proxy_for(url)
repo = RepositoryStub()
repo.name = name
repo.id = name
repo.proxy = proxy
repo.proxy_username = proxy_username
repo.proxy_password = proxy_password
repo.ssl_verify = ssl_verify
repo.nocache = nocache
repo.baseurl.append(url)
if inc:
for pkg in inc:
self.incpkgs[pkg] = name
if exc:
for pkg in exc:
self.excpkgs[pkg] = name
# check LICENSE files
if not rpmmisc.checkRepositoryEULA(name, repo):
msger.warning('skip repo:%s for failed EULA confirmation' % name)
return None
if mirrorlist:
repo.mirrorlist = mirrorlist
# Enable gpg check for verifying corrupt packages
repo.gpgcheck = 1
if priority is not None:
# priority 0 has issue in RepoInfo.setPriority
repo.priority = priority + 1
try:
repo_info = zypp.RepoInfo()
repo_info.setAlias(repo.name)
repo_info.setName(repo.name)
repo_info.setEnabled(repo.enabled)
repo_info.setAutorefresh(repo.autorefresh)
repo_info.setKeepPackages(repo.keeppackages)
baseurl = zypp.Url(repo.baseurl[0])
if not ssl_verify:
baseurl.setQueryParam("ssl_verify", "no")
if proxy:
scheme, host, path, parm, query, frag = urlparse.urlparse(proxy)
proxyinfo = host.split(":")
host = proxyinfo[0]
port = "80"
if len(proxyinfo) > 1:
port = proxyinfo[1]
if proxy.startswith("socks") and len(proxy.rsplit(':', 1)) == 2:
host = proxy.rsplit(':', 1)[0]
port = proxy.rsplit(':', 1)[1]
baseurl.setQueryParam ("proxy", host)
baseurl.setQueryParam ("proxyport", port)
repo.baseurl[0] = baseurl.asCompleteString()
self.repos.append(repo)
repo_info.addBaseUrl(baseurl)
if repo.priority is not None:
repo_info.setPriority(repo.priority)
# this hack is used to change zypp credential file location
# the default one is $HOME/.zypp, which cause conflicts when
# installing some basic packages, and the location doesn't
# have any interface actually, so use a tricky way anyway
homedir = None
if 'HOME' in os.environ:
homedir = os.environ['HOME']
os.environ['HOME'] = '/'
else:
os.environ['HOME'] = '/'
self.repo_manager.addRepository(repo_info)
# save back the $HOME env
if homedir:
os.environ['HOME'] = homedir
else:
del os.environ['HOME']
self.__build_repo_cache(name)
except RuntimeError, e:
raise CreatorError(str(e))
msger.verbose('repo: %s was added' % name)
return repo
def installHasFile(self, file):
return False
def preInstall(self, pkg):
self.pre_pkgs.append(pkg)
def runInstall(self, checksize = 0):
os.environ["HOME"] = "/"
os.environ["LD_PRELOAD"] = ""
self.buildTransaction()
todo = zypp.GetResolvablesToInsDel(self.Z.pool())
installed_pkgs = todo._toInstall
dlpkgs = []
for pitem in installed_pkgs:
if not zypp.isKindPattern(pitem) and \
not self.inDeselectPackages(pitem):
item = zypp.asKindPackage(pitem)
dlpkgs.append(item)
if not self.install_debuginfo or str(item.arch()) == "noarch":
continue
dipkg = self._zyppQueryPackage("%s-debuginfo" % item.name())
if dipkg:
ditem = zypp.asKindPackage(dipkg)
dlpkgs.append(ditem)
else:
msger.warning("No debuginfo rpm found for: %s" \
% item.name())
# record all pkg and the content
localpkgs = self.localpkgs.keys()
for pkg in dlpkgs:
license = ''
if pkg.name() in localpkgs:
hdr = rpmmisc.readRpmHeader(self.ts, self.localpkgs[pkg.name()])
pkg_long_name = misc.RPM_FMT % {
'name': hdr['name'],
'arch': hdr['arch'],
'version': hdr['version'],
'release': hdr['release']
}
license = hdr['license']
else:
pkg_long_name = misc.RPM_FMT % {
'name': pkg.name(),
'arch': pkg.arch(),
'version': pkg.edition().version(),
'release': pkg.edition().release()
}
license = pkg.license()
if license in self.__pkgs_license.keys():
self.__pkgs_license[license].append(pkg_long_name)
else:
self.__pkgs_license[license] = [pkg_long_name]
total_count = len(dlpkgs)
cached_count = 0
download_total_size = sum(map(lambda x: int(x.downloadSize()), dlpkgs))
localpkgs = self.localpkgs.keys()
msger.info("Checking packages cached ...")
for po in dlpkgs:
# Check if it is cached locally
if po.name() in localpkgs:
cached_count += 1
else:
local = self.getLocalPkgPath(po)
name = str(po.repoInfo().name())
try:
repo = filter(lambda r: r.name == name, self.repos)[0]
except IndexError:
repo = None
nocache = repo.nocache if repo else False
if os.path.exists(local):
if nocache or self.checkPkg(local) !=0:
os.unlink(local)
else:
download_total_size -= int(po.downloadSize())
cached_count += 1
cache_avail_size = misc.get_filesystem_avail(self.cachedir)
if cache_avail_size < download_total_size:
raise CreatorError("No enough space used for downloading.")
# record the total size of installed pkgs
install_total_size = sum(map(lambda x: int(x.installSize()), dlpkgs))
# check needed size before actually download and install
# FIXME: for multiple partitions for loop type, check fails
# skip the check temporarily
#if checksize and install_total_size > checksize:
# raise CreatorError("No enough space used for installing, "
# "please resize partition size in ks file")
download_count = total_count - cached_count
msger.info("Packages: %d Total, %d Cached, %d Missed" \
% (total_count, cached_count, download_count))
try:
if download_count > 0:
msger.info("Downloading packages ...")
self.downloadPkgs(dlpkgs, download_count)
self.installPkgs(dlpkgs)
except (RepoError, RpmError):
raise
except Exception, e:
raise CreatorError("Package installation failed: %s" % (e,))
def getVcsInfo(self):
if self.__pkgs_vcsinfo:
return
if not self.ts:
self.__initialize_transaction()
mi = self.ts.dbMatch()
for hdr in mi:
lname = misc.RPM_FMT % {
'name': hdr['name'],
'arch': hdr['arch'],
'version': hdr['version'],
'release': hdr['release']
}
self.__pkgs_vcsinfo[lname] = hdr['VCS']
return self.__pkgs_vcsinfo
def getAllContent(self):
if self.__pkgs_content:
return self.__pkgs_content
if not self.ts:
self.__initialize_transaction()
mi = self.ts.dbMatch()
for hdr in mi:
lname = misc.RPM_FMT % {
'name': hdr['name'],
'arch': hdr['arch'],
'version': hdr['version'],
'release': hdr['release']
}
self.__pkgs_content[lname] = hdr['FILENAMES']
return self.__pkgs_content
def getPkgsLicense(self):
return self.__pkgs_license
def getFilelist(self, pkgname):
if not pkgname:
return None
if not self.ts:
self.__initialize_transaction()
mi = self.ts.dbMatch('name', pkgname)
for header in mi:
return header['FILENAMES']
def __initialize_repo_manager(self):
if self.repo_manager:
return
# Clean up repo metadata
shutil.rmtree(self.cachedir + "/etc", ignore_errors = True)
shutil.rmtree(self.cachedir + "/solv", ignore_errors = True)
shutil.rmtree(self.cachedir + "/raw", ignore_errors = True)
zypp.KeyRing.setDefaultAccept( zypp.KeyRing.ACCEPT_UNSIGNED_FILE
| zypp.KeyRing.ACCEPT_VERIFICATION_FAILED
| zypp.KeyRing.ACCEPT_UNKNOWNKEY
| zypp.KeyRing.TRUST_KEY_TEMPORARILY
)
self.repo_manager_options = \
zypp.RepoManagerOptions(zypp.Pathname(self.instroot))
self.repo_manager_options.knownReposPath = \
zypp.Pathname(self.cachedir + "/etc/zypp/repos.d")
self.repo_manager_options.repoCachePath = \
zypp.Pathname(self.cachedir)
self.repo_manager_options.repoRawCachePath = \
zypp.Pathname(self.cachedir + "/raw")
self.repo_manager_options.repoSolvCachePath = \
zypp.Pathname(self.cachedir + "/solv")
self.repo_manager_options.repoPackagesCachePath = \
zypp.Pathname(self.cachedir + "/packages")
self.repo_manager = zypp.RepoManager(self.repo_manager_options)
def __build_repo_cache(self, name):
repo = self.repo_manager.getRepositoryInfo(name)
if self.repo_manager.isCached(repo) or not repo.enabled():
return
msger.info('Refreshing repository: %s ...' % name)
self.repo_manager.buildCache(repo, zypp.RepoManager.BuildIfNeeded)
def __initialize_zypp(self):
if self.Z:
return
zconfig = zypp.ZConfig_instance()
# Set system architecture
if self.target_arch:
zconfig.setSystemArchitecture(zypp.Arch(self.target_arch))
msger.info("zypp architecture is <%s>" % zconfig.systemArchitecture())
# repoPackagesCachePath is corrected by this
self.repo_manager = zypp.RepoManager(self.repo_manager_options)
repos = self.repo_manager.knownRepositories()
for repo in repos:
if not repo.enabled():
continue
self.repo_manager.loadFromCache(repo)
self.Z = zypp.ZYppFactory_instance().getZYpp()
self.Z.initializeTarget(zypp.Pathname(self.instroot))
self.Z.target().load()
def buildTransaction(self):
if not self.Z.resolver().resolvePool():
probs = self.Z.resolver().problems()
for problem in probs:
msger.warning("repo problem: %s, %s" \
% (problem.description().decode("utf-8"),
problem.details().decode("utf-8")))
raise RepoError("found %d resolver problem, abort!" \
% len(probs))
def getLocalPkgPath(self, po):
repoinfo = po.repoInfo()
cacheroot = repoinfo.packagesPath()
location= po.location()
rpmpath = str(location.filename())
pkgpath = "%s/%s" % (cacheroot, os.path.basename(rpmpath))
return pkgpath
def installLocal(self, pkg, po=None, updateonly=False):
if not self.ts:
self.__initialize_transaction()
solvfile = "%s/.solv" % (self.cachedir)
rc, out = runner.runtool([fs_related.find_binary_path("rpms2solv"),
pkg])
if rc == 0:
f = open(solvfile, "w+")
f.write(out)
f.close()
warnmsg = self.repo_manager.loadSolvFile(solvfile,
os.path.basename(pkg))
if warnmsg:
msger.warning(warnmsg)
os.unlink(solvfile)
else:
msger.warning('Can not get %s solv data.' % pkg)
hdr = rpmmisc.readRpmHeader(self.ts, pkg)
arch = zypp.Arch(hdr['arch'])
sysarch = zypp.Arch(self.target_arch)
if arch.compatible_with (sysarch):
pkgname = hdr['name']
self.localpkgs[pkgname] = pkg
self.selectPackage(pkgname)
msger.info("Marking %s to be installed" % (pkg))
else:
msger.warning("Cannot add package %s to transaction. "
"Not a compatible architecture: %s" \
% (pkg, hdr['arch']))
def downloadPkgs(self, package_objects, count):
localpkgs = self.localpkgs.keys()
progress_obj = TextProgress(count)
for po in package_objects:
if po.name() in localpkgs:
continue
filename = self.getLocalPkgPath(po)
if os.path.exists(filename):
if self.checkPkg(filename) == 0:
continue
dirn = os.path.dirname(filename)
if not os.path.exists(dirn):
os.makedirs(dirn)
url = self.get_url(po)
proxies = self.get_proxies(po)
try:
filename = myurlgrab(url, filename, proxies, progress_obj)
except CreatorError:
self.close()
raise
def preinstallPkgs(self):
if not self.ts_pre:
self.__initialize_transaction()
self.ts_pre.order()
cb = rpmmisc.RPMInstallCallback(self.ts_pre)
cb.headmsg = "Preinstall"
installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
# start to catch stderr output from librpm
msger.enable_logstderr(installlogfile)
errors = self.ts_pre.run(cb.callback, '')
# stop catch
msger.disable_logstderr()
self.ts_pre.closeDB()
self.ts_pre = None
if errors is not None:
if len(errors) == 0:
msger.warning('scriptlet or other non-fatal errors occurred '
'during transaction.')
else:
for e in errors:
msger.warning(e[0])
raise RepoError('Could not run transaction.')
def installPkgs(self, package_objects):
if not self.ts:
self.__initialize_transaction()
# clean rpm lock
self._cleanupRpmdbLocks(self.instroot)
self._cleanupZyppJunk(self.instroot)
# Set filters
probfilter = 0
for flag in self.probFilterFlags:
probfilter |= flag
self.ts.setProbFilter(probfilter)
self.ts_pre.setProbFilter(probfilter)
localpkgs = self.localpkgs.keys()
for po in package_objects:
pkgname = po.name()
if pkgname in localpkgs:
rpmpath = self.localpkgs[pkgname]
else:
rpmpath = self.getLocalPkgPath(po)
if not os.path.exists(rpmpath):
# Maybe it is a local repo
rpmuri = self.get_url(po)
if rpmuri.startswith("file:/"):
rpmpath = rpmuri[5:]
if not os.path.exists(rpmpath):
raise RpmError("Error: %s doesn't exist" % rpmpath)
h = rpmmisc.readRpmHeader(self.ts, rpmpath)
if pkgname in self.pre_pkgs:
msger.verbose("pre-install package added: %s" % pkgname)
self.ts_pre.addInstall(h, rpmpath, 'u')
self.ts.addInstall(h, rpmpath, 'u')
unresolved_dependencies = self.ts.check()
if not unresolved_dependencies:
if self.pre_pkgs:
self.preinstallPkgs()
self.ts.order()
cb = rpmmisc.RPMInstallCallback(self.ts)
installlogfile = "%s/__catched_stderr.buf" % (self.instroot)
# start to catch stderr output from librpm
msger.enable_logstderr(installlogfile)
errors = self.ts.run(cb.callback, '')
# stop catch
msger.disable_logstderr()
self.ts.closeDB()
self.ts = None
if errors is not None:
if len(errors) == 0:
msger.warning('scriptlet or other non-fatal errors occurred '
'during transaction.')
else:
for e in errors:
msger.warning(e[0])
raise RepoError('Could not run transaction.')
else:
for pkg, need, needflags, sense, key in unresolved_dependencies:
package = '-'.join(pkg)
if needflags == rpm.RPMSENSE_LESS:
deppkg = ' < '.join(need)
elif needflags == rpm.RPMSENSE_EQUAL:
deppkg = ' = '.join(need)
elif needflags == rpm.RPMSENSE_GREATER:
deppkg = ' > '.join(need)
else:
deppkg = '-'.join(need)
if sense == rpm.RPMDEP_SENSE_REQUIRES:
msger.warning("[%s] Requires [%s], which is not provided" \
% (package, deppkg))
elif sense == rpm.RPMDEP_SENSE_CONFLICTS:
msger.warning("[%s] Conflicts with [%s]" %(package,deppkg))
raise RepoError("Unresolved dependencies, transaction failed.")
def __initialize_transaction(self):
if not self.ts:
self.ts = rpm.TransactionSet(self.instroot)
# Set to not verify DSA signatures.
self.ts.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
if not self.ts_pre:
self.ts_pre = rpm.TransactionSet(self.instroot)
# Just unpack the files, don't run scripts
self.ts_pre.setFlags(rpm.RPMTRANS_FLAG_ALLFILES | rpm.RPMTRANS_FLAG_NOSCRIPTS)
# Set to not verify DSA signatures.
self.ts_pre.setVSFlags(rpm._RPMVSF_NOSIGNATURES|rpm._RPMVSF_NODIGESTS)
def checkPkg(self, pkg):
ret = 1
if not os.path.exists(pkg):
return ret
ret = rpmmisc.checkRpmIntegrity('rpm', pkg)
if ret != 0:
msger.warning("package %s is damaged: %s" \
% (os.path.basename(pkg), pkg))
return ret
def _add_prob_flags(self, *flags):
for flag in flags:
if flag not in self.probFilterFlags:
self.probFilterFlags.append(flag)
def get_proxies(self, pobj):
if not pobj:
return None
proxy = None
proxies = None
repoinfo = pobj.repoInfo()
reponame = "%s" % repoinfo.name()
repos = filter(lambda r: r.name == reponame, self.repos)
repourl = str(repoinfo.baseUrls()[0])
if repos:
proxy = repos[0].proxy
if not proxy:
proxy = get_proxy_for(repourl)
if proxy:
proxies = {str(repourl.split(':')[0]): str(proxy)}
return proxies
def get_url(self, pobj):
if not pobj:
return None
name = str(pobj.repoInfo().name())
try:
repo = filter(lambda r: r.name == name, self.repos)[0]
except IndexError:
return None
baseurl = repo.baseurl[0]
index = baseurl.find("?")
if index > -1:
baseurl = baseurl[:index]
location = pobj.location()
location = str(location.filename())
if location.startswith("./"):
location = location[2:]
return os.path.join(baseurl, location)
def package_url(self, pkgname):
def cmpEVR(p1, p2):
ed1 = p1.edition()
ed2 = p2.edition()
(e1, v1, r1) = map(str, [ed1.epoch(), ed1.version(), ed1.release()])
(e2, v2, r2) = map(str, [ed2.epoch(), ed2.version(), ed2.release()])
return rpm.labelCompare((e1, v1, r1), (e2, v2, r2))
if not self.Z:
self.__initialize_zypp()
q = zypp.PoolQuery()
q.addKind(zypp.ResKind.package)
q.setMatchExact()
q.addAttribute(zypp.SolvAttr.name, pkgname)
items = sorted(q.queryResults(self.Z.pool()),
cmp=lambda x,y: cmpEVR(zypp.asKindPackage(x), zypp.asKindPackage(y)),
reverse=True)
if items:
item = zypp.asKindPackage(items[0])
url = self.get_url(item)
proxies = self.get_proxies(item)
return (url, proxies)
return (None, None)