commit ea532a8ac67e29cb996eb0d6faaacb9d006355d7
Author: Yi Yang <[email protected]>
Date: Thu Nov 11 10:43:30 2010 +0800
Split yum as a separate module
diff --git a/mic/__init__.py b/mic/__init__.py
index 108fc06..5b13302 100644
--- a/mic/__init__.py
+++ b/mic/__init__.py
@@ -16,9 +16,9 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+from mic.imgcreate.pkgmanagers import *
from mic.imgcreate.live import *
from mic.imgcreate.creator import *
-from mic.imgcreate.yuminst import *
from mic.imgcreate.kickstart import *
from mic.imgcreate.fs import *
from mic.imgcreate.misc import *
@@ -73,4 +73,5 @@ __all__ = (
'read_kickstart',
'construct_name',
'setup_logging',
+ 'pkgManager',
)
diff --git a/mic/appcreate/__init__.py b/mic/appcreate/__init__.py
index 79b6bf4..ddab5b4 100644
--- a/mic/appcreate/__init__.py
+++ b/mic/appcreate/__init__.py
@@ -21,7 +21,6 @@ supported_formats = ['raw', 'vmdk', 'vdi', 'mrstnand', 'nand']
from mic.imgcreate.live import *
from mic.imgcreate.creator import *
-from mic.imgcreate.yuminst import *
from mic.imgcreate.kickstart import *
from mic.imgcreate.fs import *
from mic.imgcreate.debug import *
diff --git a/mic/appcreate/nand.py b/mic/appcreate/nand.py
index 9499854..4fad2b7 100644
--- a/mic/appcreate/nand.py
+++ b/mic/appcreate/nand.py
@@ -30,91 +30,7 @@ from mic.imgcreate.errors import *
from mic.imgcreate.fs import *
from mic.imgcreate.creator import *
from mic.appcreate.appliance import *
-from mic.imgcreate.yuminst import *
-
-class SimplerYum(LiveCDYum):
- """ Simple YumBase class, only download specified rpm and unpack it,
- without dependency checking and running scripts.
- """
-
- def __init__(self):
- LiveCDYum.__init__(self)
-
- def populateTs(self):
- """take transactionData class and populate transaction set"""
-
- if self.dsCallback:
- self.dsCallback.transactionPopulation()
- ts_elem = {}
-
- if self.ts.ts is None:
- self.initActionTs()
-
- for txmbr in self.tsInfo.getMembers():
- if txmbr.isDep:
- # !!! skip all dependency pkgs
- continue
-
- if txmbr.ts_state in ['u', 'i']:
- if ts_elem.has_key((txmbr.pkgtup, 'i')):
- continue
- rpmfile = txmbr.po.localPkg()
- if os.path.exists(rpmfile):
- hdr = txmbr.po.returnHeaderFromPackage()
- else:
- self.downloadHeader(txmbr.po)
- hdr = txmbr.po.returnLocalHeader()
-
- if txmbr.ts_state == 'u':
- if self.allowedMultipleInstalls(txmbr.po):
- txmbr.ts_state = 'i'
- txmbr.output_state = TS_INSTALL
-
- self.ts.addInstall(hdr, (hdr, rpmfile), txmbr.ts_state)
- if self.dsCallback:
- self.dsCallback.pkgAdded(txmbr.pkgtup, txmbr.ts_state)
-
- def runInstall(self, pkgdir = None):
- os.environ["HOME"] = "/"
- 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") and \
- not txmbr.isDep, \
- self.tsInfo.getMembers()))
-
- self.downloadPkgs(dlpkgs)
-
- # set rpm.RPM_FLAG_NOSCRIPTS flags
- self.conf.tsflags.append('noscripts')
-
- self.initActionTs()
- self.populateTs()
-
- deps = self.ts.check()
- # skip dependency check failure
- if deps: pass
-
- rc = self.ts.order()
- if rc != 0:
- raise CreatorError("ordering packages for installation failed!")
-
- sys.path.append('/usr/share/yum-cli')
- import callback
- cb = callback.RPMInstallCallback()
- cb.tsInfo = self.tsInfo
- cb.filelog = False
- ret = self.runTransaction(cb)
- ret = 0
- print ""
- self._cleanupRpmdbLocks(self.conf.installroot)
-
- return ret
+from mic.imgcreate.pkgmanagers import *
class NandImageCreator(ApplianceImageCreator):
def __init__(self, ks, name, initrd_url = None, initrd_path = None,
@@ -365,11 +281,12 @@ class NandImageCreator(ApplianceImageCreator):
yum_conf = self._mktemp(prefix = "yum.conf-")
- ayum = SimplerYum()
+ self._required_pkgs = self._get_required_packages()
+ ayum = self.get_pkg_manager()
ayum.setup(yum_conf, self._instroot)
for repo in kickstart.get_repos(self.ks, repo_urls):
- (name, baseurl, mirrorlist, inc, exc, proxy, proxy_username,
proxy_password) = repo
+ (name, baseurl, mirrorlist, inc, exc, proxy, proxy_username,
proxy_password, debuginfo, source, gpgkey, disable) = repo
yr = ayum.addRepository(name, baseurl, mirrorlist, proxy,
proxy_username, proxy_password)
if inc:
@@ -401,9 +318,8 @@ class NandImageCreator(ApplianceImageCreator):
continue
kernel_found = True
- try:
- ayum.selectPackage(pkg)
- except yum.Errors.InstallError, e:
+ e = ayum.selectPackage(pkg)
+ if e:
raise CreatorError("Failed to find package '%s' :
%s" %
(pkg, e))
if not kernel_found:
@@ -413,10 +329,8 @@ class NandImageCreator(ApplianceImageCreator):
ayum.deselectPackage(pkg)
ayum.runInstall()
- 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,))
+ except CreatorError, e:
+ raise CreatorError("%s" % (e,))
finally:
ayum.closeRpmDB()
ayum.close()
diff --git a/mic/imgconvert/convertor.py b/mic/imgconvert/convertor.py
index 994c585..d483e2a 100644
--- a/mic/imgconvert/convertor.py
+++ b/mic/imgconvert/convertor.py
@@ -29,6 +29,7 @@ import rpm
import mic.appcreate as appcreate
import mic.imgcreate as imgcreate
+import mic.imgcreate.pkgmanagers as pkgmanagers
class ImageConvertor:
def __init__(self):
@@ -90,9 +91,8 @@ class ImageConvertor:
kernel_pkgs.append('kernel')
for pkg in kernel_pkgs:
- try:
- ayum.selectPackage(pkg)
- except imgcreate.yum.Errors.InstallError, e:
+ e = ayum.selectPackage(pkg)
+ if e:
if imgcreate.kickstart.ignore_missing(self.ks):
skipped_pkgs.append(pkg)
else:
@@ -131,7 +131,7 @@ class ImageConvertor:
args = [ imgcreate.fs.find_binary_path("rpm"), "--root=" + instroot,
"-e", kernel ]
subprocess.call(args)
- ayum = imgcreate.LiveCDYum()
+ ayum = self.get_pkg_manager()
ayum.setup(self._yum_conf, self._instroot)
for repo in imgcreate.kickstart.get_repos(self.ks, repo_urls):
@@ -150,10 +150,8 @@ class ImageConvertor:
try:
self._select_kernel_pkg(ayum)
ayum.runInstall()
- except imgcreate.yum.Errors.RepoError, e:
- raise imgcreate.CreatorError("Unable to download from repo :
%s" % (e,))
- except imgcreate.yum.Errors.YumBaseError, e:
- raise imgcreate.CreatorError("Unable to install: %s" % (e,))
+ except imgcreate.CreatorError, e:
+ raise imgcreate.CreatorError("%s" % (e,))
finally:
ayum.closeRpmDB()
ayum.close()
diff --git a/mic/imgcreate/__init__.py b/mic/imgcreate/__init__.py
index d991721..52d53db 100644
--- a/mic/imgcreate/__init__.py
+++ b/mic/imgcreate/__init__.py
@@ -23,12 +23,12 @@ from mic.imgcreate.live import *
from mic.imgcreate.creator import *
from mic.imgcreate.ubi import *
from mic.imgcreate.jffs2 import *
-from mic.imgcreate.yuminst import *
from mic.imgcreate.kickstart import *
from mic.imgcreate.fs import *
from mic.imgcreate.misc import *
from mic.imgcreate.bootstrap import *
from mic.imgcreate.debug import *
+from mic.imgcreate.pkgmanagers import *
"""A set of classes for building Fedora system images.
diff --git a/mic/imgcreate/creator.py b/mic/imgcreate/creator.py
index a7eed56..c12f86f 100644
--- a/mic/imgcreate/creator.py
+++ b/mic/imgcreate/creator.py
@@ -28,7 +28,6 @@ import re
import tarfile
import glob
-import yum
import rpm
import rpmUtils.miscutils
import rpmUtils.arch
@@ -36,9 +35,8 @@ import rpmUtils.arch
from mic.imgcreate.errors import *
from mic.imgcreate.fs import *
from mic.imgcreate.misc import *
-from mic.imgcreate.yuminst import *
from mic.imgcreate import kickstart
-from mic.imgcreate.srcdownload import SrcDownload
+from mic.imgcreate import pkgmanagers
FSLABEL_MAXLEN = 32
"""The maximum string length supported for LoopImageCreator.fslabel."""
@@ -68,6 +66,11 @@ class ImageCreator(object):
filesystem labels
"""
+
+ """ Initialize package managers """
+ self.pkgmgr = pkgmanagers.pkgManager()
+ self.pkgmgr.load_pkg_managers()
+
self.ks = ks
"""A pykickstart.KickstartParser instance."""
@@ -714,9 +717,8 @@ class ImageCreator(object):
def __select_packages(self, ayum):
skipped_pkgs = []
for pkg in self._required_pkgs:
- try:
- ayum.selectPackage(pkg)
- except yum.Errors.InstallError, e:
+ e = ayum.selectPackage(pkg)
+ if e:
if kickstart.ignore_missing(self.ks):
skipped_pkgs.append(pkg)
elif self.__is_excluded_pkg(pkg):
@@ -731,9 +733,8 @@ class ImageCreator(object):
def __select_groups(self, ayum):
skipped_groups = []
for group in self._required_groups:
- try:
- ayum.selectGroup(group.name, group.include)
- except (yum.Errors.InstallError, yum.Errors.GroupsError), e:
+ e = ayum.selectGroup(group.name, group.include)
+ if e:
if kickstart.ignore_missing(self.ks):
skipped_groups.append(group)
else:
@@ -787,7 +788,7 @@ class ImageCreator(object):
if self._recording_pkgs in ('name', 'contents'):
keep_record = self._recording_pkgs
- ayum = LiveCDYum(keep_record, target_arch = self.target_arch)
+ ayum = self.get_pkg_manager(keep_record, target_arch =
self.target_arch)
ayum.setup(yum_conf, self._instroot)
for repo in kickstart.get_repos(self.ks, repo_urls):
@@ -819,10 +820,8 @@ class ImageCreator(object):
if self.target_arch:
ayum._add_prob_flags(rpm.RPMPROB_FILTER_IGNOREARCH)
ayum.runInstall(checksize)
- 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,))
+ except CreatorError, e:
+ raise CreatorError("%s" % (e,))
finally:
if keep_record:
self._pkgs_content = ayum.getAllContent()
@@ -1074,6 +1073,15 @@ class ImageCreator(object):
self.__img_compression_method = compression_method
+ def set_pkg_manager(self, name):
+ self.pkgmgr.set_default_pkg_manager(name)
+
+ def get_pkg_manager(self, recording_pkgs=None, target_arch = None):
+ pkgmgr_instance = self.pkgmgr.get_default_pkg_manager()
+ if not pkgmgr_instance:
+ raise CreatorError("No pakcgae manager available")
+ return pkgmgr_instance(recording_pkgs, target_arch)
+
class LoopImageCreator(ImageCreator):
"""Installs a system into a loopback-mountable filesystem image.
diff --git a/mic/imgcreate/pkgmanagers/__init__.py
b/mic/imgcreate/pkgmanagers/__init__.py
new file mode 100644
index 0000000..4114403
--- /dev/null
+++ b/mic/imgcreate/pkgmanagers/__init__.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python
+
+import os
+from mic.imgcreate.errors import *
+
+class pkgManager:
+ def __init__(self):
+ self.managers = {}
+ self.default_pkg_manager = None
+
+ def register_pkg_manager(self, name, manager):
+ print "Registering package manager: %s" % name
+ if not self.managers.has_key(name):
+ self.managers[name] = manager
+
+ def unregister_pkg_manager(self, name):
+ if self.managers.has_key(name):
+ del self.managers[name]
+
+ def set_default_pkg_manager(self, name):
+ if self.managers.has_key(name):
+ self.default_pkg_manager = self.managers[name]
+
+ def get_default_pkg_manager(self):
+ if self.default_pkg_manager:
+ return self.default_pkg_manager
+ else:
+ if self.managers.has_key("yum"):
+ return self.managers["yum"]
+ elif self.managers.has_key("zypper"):
+ return self.managers["zypper"]
+ else:
+ keys = self.managers.keys()
+ if keys:
+ return self.managers[keys[0]]
+ else:
+ return None
+
+ def load_pkg_managers(self):
+ mydir = os.path.dirname(os.path.realpath(__file__))
+ for file in os.listdir(mydir):
+ if os.path.isfile(mydir + "/" + file) and file.endswith(".py") and
file != "__init__.py":
+ pkgmgrmod = file[:file.rfind(".py")]
+ try:
+ exec("import mic.imgcreate.pkgmanagers.%s as %s " %
(pkgmgrmod, pkgmgrmod))
+ exec("pkgmgr = %s._pkgmgr" % pkgmgrmod)
+ self.register_pkg_manager(pkgmgr[0], pkgmgr[1])
+ except:
+ raise
+ if not self.managers.keys():
+ raise CreatorError("No packag manager available")
diff --git a/mic/imgcreate/pkgmanagers/yumpkgmgr.py
b/mic/imgcreate/pkgmanagers/yumpkgmgr.py
new file mode 100644
index 0000000..b19be72
--- /dev/null
+++ b/mic/imgcreate/pkgmanagers/yumpkgmgr.py
@@ -0,0 +1,426 @@
+#
+# yum.py : yum utilities
+#
+# Copyright 2007, Red Hat 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 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.
+
+import glob
+import os
+import sys
+import logging
+
+import yum
+import rpmUtils
+import pykickstart.parser
+
+import urlparse
+import urllib2 as u2
+import tempfile
+import shutil
+import subprocess
+
+from mic.imgcreate.errors import *
+from mic.imgcreate.fs import *
+
+class Yum(yum.YumBase):
+ def __init__(self, recording_pkgs=None, target_arch = None):
+ yum.YumBase.__init__(self)
+ if target_arch:
+ if rpmUtils.arch.arches.has_key(target_arch):
+ self.arch.setup_arch(target_arch)
+ else:
+ raise CreatorError("Invalid target arch: %s" % target_arch)
+
+ self.__recording_pkgs = recording_pkgs
+ self.__pkgs_content = {}
+
+ 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.conf.installroot + "/yum.conf")
+ except:
+ pass
+ self.closeRpmDB()
+ yum.YumBase.close(self)
+ 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
+ self._delSacks()
+ del self.repos
+ self.repos = None
+
+ def __del__(self):
+ pass
+
+ def _writeConf(self, confpath, installroot):
+ conf = "[main]\n"
+ conf += "installroot=%s\n" % installroot
+ conf += "cachedir=/var/cache/yum\n"
+ conf += "plugins=0\n"
+ conf += "reposdir=\n"
+ conf += "failovermethod=priority\n"
+ conf += "http_caching=packages\n"
+
+ 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, confpath, installroot):
+ self._writeConf(confpath, installroot)
+ self._cleanupRpmdbLocks(installroot)
+ self.doConfigSetup(fn = confpath, root = installroot)
+ self.conf.cache = 0
+ self.doTsSetup()
+ self.doRpmDBSetup()
+ self.doRepoSetup()
+ self.doSackSetup()
+
+ 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, 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 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:
+ logging.warn("No such package %s to remove" %(pkg,))
+
+ def selectGroup(self, grp, include = pykickstart.parser.GROUP_DEFAULT):
+ try:
+ yum.YumBase.selectGroup(self, grp)
+ if include == pykickstart.parser.GROUP_REQUIRED:
+ map(lambda p: self.deselectPackage(p),
grp.default_packages.keys())
+ elif include == pykickstart.parser.GROUP_ALL:
+ map(lambda p: self.selectPackage(p),
grp.optional_packages.keys())
+ 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 __checkAndDownloadURL(self, u2opener, url, savepath):
+ try:
+ if u2opener:
+ f = u2opener.open(url)
+ else:
+ f = u2.urlopen(url)
+ except u2.HTTPError, httperror:
+ if httperror.code in (404, 503):
+ return None
+ else:
+ raise CreatorError(httperror)
+ except OSError, oserr:
+ if oserr.errno == 2:
+ return None
+ else:
+ raise CreatorError(oserr)
+ except IOError, oserr:
+ if hasattr(oserr, "reason") and oserr.reason.errno == 2:
+ return None
+ else:
+ raise CreatorError(oserr)
+ except u2.URLError, err:
+ raise CreatorError(err)
+
+ # save to file
+ licf = open(savepath, "w")
+ licf.write(f.read())
+ licf.close()
+ f.close()
+
+ return savepath
+
+ def __pagerFile(self, savepath):
+ if os.path.splitext(savepath)[1].upper() in ('.HTM', '.HTML'):
+ pagers = ('w3m', 'links', 'lynx', 'less', 'more')
+ else:
+ pagers = ('less', 'more')
+
+ file_showed = None
+ for pager in pagers:
+ try:
+ subprocess.call([pager, savepath])
+ except OSError:
+ continue
+ else:
+ file_showed = True
+ break
+ if not file_showed:
+ f = open(savepath)
+ print f.read()
+ f.close()
+ raw_input('press <ENTER> to continue...')
+
+ def checkRepositoryEULA(self, name, repo):
+ """ This function is to check the LICENSE file if provided. """
+
+ # when proxy needed, make urllib2 follow it
+ proxy = repo.proxy
+ proxy_username = repo.proxy_username
+ proxy_password = repo.proxy_password
+
+ handlers = []
+ auth_handler =
u2.HTTPBasicAuthHandler(u2.HTTPPasswordMgrWithDefaultRealm())
+ u2opener = None
+ if proxy:
+ if proxy_username:
+ proxy_netloc = urlparse.urlsplit(proxy).netloc
+ if proxy_password:
+ proxy_url = 'http://%s:%...@%s' % (proxy_username,
proxy_password, proxy_netloc)
+ else:
+ proxy_url = 'http://%...@%s' % (proxy_username,
proxy_netloc)
+ else:
+ proxy_url = proxy
+
+ proxy_support = u2.ProxyHandler({'http': proxy_url,
+ 'ftp': proxy_url})
+ handlers.append(proxy_support)
+
+ # download all remote files to one temp dir
+ baseurl = None
+ repo_lic_dir = tempfile.mkdtemp(prefix = 'repolic')
+
+ for url in repo.baseurl:
+ if not url.endswith('/'):
+ url += '/'
+ tmphandlers = handlers
+ (scheme, host, path, parm, query, frag) = urlparse.urlparse(url)
+ if scheme not in ("http", "https", "ftp", "ftps", "file"):
+ raise CreateError("Error: invalid url %s" % url)
+ if '@' in host:
+ try:
+ user_pass, host = host.split('@', 1)
+ if ':' in user_pass:
+ user, password = user_pass.split(':', 1)
+ except ValueError, e:
+ raise CreateError('Bad URL: %s' % url)
+ print "adding HTTP auth: %s, %s" %(user, password)
+ auth_handler.add_password(None, host, user, password)
+ tmphandlers.append(auth_handler)
+ url = scheme + "://" + host + path + parm + query + frag
+ if len(tmphandlers) != 0:
+ u2opener = u2.build_opener(*tmphandlers)
+ # try to download
+ repo_eula_url = urlparse.urljoin(url, "LICENSE.txt")
+ repo_eula_path = self.__checkAndDownloadURL(
+ u2opener,
+ repo_eula_url,
+ os.path.join(repo_lic_dir, repo.id +
'_LICENSE.txt'))
+ if repo_eula_path:
+ # found
+ baseurl = url
+ break
+
+ if not baseurl:
+ return True
+
+ # show the license file
+ print 'For the software packages in this yum repo:'
+ print ' %s: %s' % (name, baseurl)
+ print 'There is an "End User License Agreement" file that need to be
checked.'
+ print 'Please read the terms and conditions outlined in it and answer
the followed qustions.'
+ raw_input('press <ENTER> to continue...')
+
+ self.__pagerFile(repo_eula_path)
+
+ # Asking for the "Accept/Decline"
+ accept = True
+ while accept:
+ input_accept = raw_input('Would you agree to the terms and
conditions outlined in the above End User License Agreement? (Yes/No): ')
+ if input_accept.upper() in ('YES', 'Y'):
+ break
+ elif input_accept.upper() in ('NO', 'N'):
+ accept = None
+ print 'Will not install pkgs from this repo.'
+
+ if not accept:
+ #cleanup
+ shutil.rmtree(repo_lic_dir)
+ return None
+
+ # try to find support_info.html for extra infomation
+ repo_info_url = urlparse.urljoin(baseurl, "support_info.html")
+ repo_info_path = self.__checkAndDownloadURL(
+ u2opener,
+ repo_info_url,
+ os.path.join(repo_lic_dir, repo.id +
'_support_info.html'))
+ if repo_info_path:
+ print 'There is one more file in the repo for additional support
information, please read it'
+ raw_input('press <ENTER> to continue...')
+ self.__pagerFile(repo_info_path)
+
+ #cleanup
+ shutil.rmtree(repo_lic_dir)
+ return True
+
+ def addRepository(self, name, url = None, mirrorlist = None, proxy = None,
proxy_username = None, proxy_password = None):
+ 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 = yum.yumRepo.YumRepository(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 self.checkRepositoryEULA(name, repo):
+ 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.basecachedir = self.conf.cachedir
+ repo.failovermethod = "priority"
+ repo.metadata_expire = 0
+ # Enable gpg check for verifying corrupt packages
+ repo.gpgcheck = 1
+ repo.enable()
+ repo.setup(0)
+ repo.setCallback(TextProgress())
+ self.repos.add(repo)
+ return repo
+
+ 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"] = "/"
+ 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 the total size of installed pkgs
+ pkgs_total_size = sum(map(lambda x: int(x.size), dlpkgs))
+
+ # check needed size before actually download and install
+ if checksize and pkgs_total_size > checksize:
+ raise CreatorError("Size of specified root partition in kickstart
file is too small to install all selected packages.")
+
+ if self.__recording_pkgs:
+ # record all pkg and the content
+ for pkg in dlpkgs:
+ pkg_long_name = pkg.compactPrint()
+ self.__pkgs_content[pkg_long_name] = pkg.files
+
+ total_count = len(dlpkgs)
+ cached_count = 0
+ for po in dlpkgs:
+ if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
+ cached_count +=1
+ else:
+ local = po.localPkg()
+ if os.path.exists(local):
+ cached_count += 1
+ print "%d packages to be installed, %d packages gotten from cache, %d
packages to be downloaded" % (total_count, cached_count, total_count -
cached_count)
+ try:
+ 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. """
+ print deps
+ logging.warn("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
+ sys.path.append('/usr/share/yum-cli')
+ import callback
+ cb = callback.RPMInstallCallback()
+ cb.tsInfo = self.tsInfo
+ cb.filelog = False
+ ret = self.runTransaction(cb)
+ print ""
+ self._cleanupRpmdbLocks(self.conf.installroot)
+ return ret
+ 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 getAllContent(self):
+ return self.__pkgs_content
+
+_pkgmgr = ["yum", Yum]
diff --git a/mic/imgcreate/pkgmanagers/zypperpkgmgr.py
b/mic/imgcreate/pkgmanagers/zypperpkgmgr.py
new file mode 100644
index 0000000..567ff8a
--- /dev/null
+++ b/mic/imgcreate/pkgmanagers/zypperpkgmgr.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+
+class Zypper:
+ def __init__(self, recording_pkgs=None, target_arch = None):
+ pass
+
+_pkgmgr = ["zypper", Zypper]
diff --git a/mic/imgcreate/yuminst.py b/mic/imgcreate/yuminst.py
deleted file mode 100644
index 8c41b52..0000000
--- a/mic/imgcreate/yuminst.py
+++ /dev/null
@@ -1,401 +0,0 @@
-#
-# yum.py : yum utilities
-#
-# Copyright 2007, Red Hat 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 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.
-
-import glob
-import os
-import sys
-import logging
-
-import yum
-import rpmUtils
-import pykickstart.parser
-
-import urlparse
-import urllib2 as u2
-import tempfile
-import shutil
-import subprocess
-
-from mic.imgcreate.errors import *
-from mic.imgcreate.fs import *
-
-class LiveCDYum(yum.YumBase):
- def __init__(self, recording_pkgs=None, target_arch = None):
- yum.YumBase.__init__(self)
- if target_arch:
- if rpmUtils.arch.arches.has_key(target_arch):
- self.arch.setup_arch(target_arch)
- else:
- raise CreatorError("Invalid target arch: %s" % target_arch)
-
- self.__recording_pkgs = recording_pkgs
- self.__pkgs_content = {}
-
- 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.conf.installroot + "/yum.conf")
- except:
- pass
- self.closeRpmDB()
- yum.YumBase.close(self)
- 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 = "[main]\n"
- conf += "installroot=%s\n" % installroot
- conf += "cachedir=/var/cache/yum\n"
- conf += "plugins=0\n"
- conf += "reposdir=\n"
- conf += "failovermethod=priority\n"
- conf += "http_caching=packages\n"
-
- 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, confpath, installroot):
- self._writeConf(confpath, installroot)
- self._cleanupRpmdbLocks(installroot)
- self.doConfigSetup(fn = confpath, root = installroot)
- self.conf.cache = 0
- self.doTsSetup()
- self.doRpmDBSetup()
- self.doRepoSetup()
- self.doSackSetup()
-
- def selectPackage(self, pkg):
- """Select a given package. Can be specified with name.arch or name*"""
- return self.install(pattern = pkg)
-
- 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:
- logging.warn("No such package %s to remove" %(pkg,))
-
- def selectGroup(self, grp, include = pykickstart.parser.GROUP_DEFAULT):
- yum.YumBase.selectGroup(self, grp)
- if include == pykickstart.parser.GROUP_REQUIRED:
- map(lambda p: self.deselectPackage(p), grp.default_packages.keys())
- elif include == pykickstart.parser.GROUP_ALL:
- map(lambda p: self.selectPackage(p), grp.optional_packages.keys())
-
- def __checkAndDownloadURL(self, u2opener, url, savepath):
- try:
- if u2opener:
- f = u2opener.open(url)
- else:
- f = u2.urlopen(url)
- except u2.HTTPError, httperror:
- if httperror.code in (404, 503):
- return None
- else:
- raise CreatorError(httperror)
- except OSError, oserr:
- if oserr.errno == 2:
- return None
- else:
- raise CreatorError(oserr)
- except IOError, oserr:
- if hasattr(oserr, "reason") and oserr.reason.errno == 2:
- return None
- else:
- raise CreatorError(oserr)
- except u2.URLError, err:
- raise CreatorError(err)
-
- # save to file
- licf = open(savepath, "w")
- licf.write(f.read())
- licf.close()
- f.close()
-
- return savepath
-
- def __pagerFile(self, savepath):
- if os.path.splitext(savepath)[1].upper() in ('.HTM', '.HTML'):
- pagers = ('w3m', 'links', 'lynx', 'less', 'more')
- else:
- pagers = ('less', 'more')
-
- file_showed = None
- for pager in pagers:
- try:
- subprocess.call([pager, savepath])
- except OSError:
- continue
- else:
- file_showed = True
- break
- if not file_showed:
- f = open(savepath)
- print f.read()
- f.close()
- raw_input('press <ENTER> to continue...')
-
- def checkRepositoryEULA(self, name, repo):
- """ This function is to check the LICENSE file if provided. """
-
- # when proxy needed, make urllib2 follow it
- proxy = repo.proxy
- proxy_username = repo.proxy_username
- proxy_password = repo.proxy_password
-
- handlers = []
- auth_handler =
u2.HTTPBasicAuthHandler(u2.HTTPPasswordMgrWithDefaultRealm())
- u2opener = None
- if proxy:
- if proxy_username:
- proxy_netloc = urlparse.urlsplit(proxy).netloc
- if proxy_password:
- proxy_url = 'http://%s:%...@%s' % (proxy_username,
proxy_password, proxy_netloc)
- else:
- proxy_url = 'http://%...@%s' % (proxy_username,
proxy_netloc)
- else:
- proxy_url = proxy
-
- proxy_support = u2.ProxyHandler({'http': proxy_url,
- 'ftp': proxy_url})
- handlers.append(proxy_support)
-
- # download all remote files to one temp dir
- baseurl = None
- repo_lic_dir = tempfile.mkdtemp(prefix = 'repolic')
-
- for url in repo.baseurl:
- if not url.endswith('/'):
- url += '/'
- tmphandlers = handlers
- (scheme, host, path, parm, query, frag) = urlparse.urlparse(url)
- if scheme not in ("http", "https", "ftp", "ftps", "file"):
- raise CreateError("Error: invalid url %s" % url)
- if '@' in host:
- try:
- user_pass, host = host.split('@', 1)
- if ':' in user_pass:
- user, password = user_pass.split(':', 1)
- except ValueError, e:
- raise CreateError('Bad URL: %s' % url)
- print "adding HTTP auth: %s, %s" %(user, password)
- auth_handler.add_password(None, host, user, password)
- tmphandlers.append(auth_handler)
- url = scheme + "://" + host + path + parm + query + frag
- if len(tmphandlers) != 0:
- u2opener = u2.build_opener(*tmphandlers)
- # try to download
- repo_eula_url = urlparse.urljoin(url, "LICENSE.txt")
- repo_eula_path = self.__checkAndDownloadURL(
- u2opener,
- repo_eula_url,
- os.path.join(repo_lic_dir, repo.id +
'_LICENSE.txt'))
- if repo_eula_path:
- # found
- baseurl = url
- break
-
- if not baseurl:
- return True
-
- # show the license file
- print 'For the software packages in this yum repo:'
- print ' %s: %s' % (name, baseurl)
- print 'There is an "End User License Agreement" file that need to be
checked.'
- print 'Please read the terms and conditions outlined in it and answer
the followed qustions.'
- raw_input('press <ENTER> to continue...')
-
- self.__pagerFile(repo_eula_path)
-
- # Asking for the "Accept/Decline"
- accept = True
- while accept:
- input_accept = raw_input('Would you agree to the terms and
conditions outlined in the above End User License Agreement? (Yes/No): ')
- if input_accept.upper() in ('YES', 'Y'):
- break
- elif input_accept.upper() in ('NO', 'N'):
- accept = None
- print 'Will not install pkgs from this repo.'
-
- if not accept:
- #cleanup
- shutil.rmtree(repo_lic_dir)
- return None
-
- # try to find support_info.html for extra infomation
- repo_info_url = urlparse.urljoin(baseurl, "support_info.html")
- repo_info_path = self.__checkAndDownloadURL(
- u2opener,
- repo_info_url,
- os.path.join(repo_lic_dir, repo.id +
'_support_info.html'))
- if repo_info_path:
- print 'There is one more file in the repo for additional support
information, please read it'
- raw_input('press <ENTER> to continue...')
- self.__pagerFile(repo_info_path)
-
- #cleanup
- shutil.rmtree(repo_lic_dir)
- return True
-
- def addRepository(self, name, url = None, mirrorlist = None, proxy = None,
proxy_username = None, proxy_password = None):
- 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 = yum.yumRepo.YumRepository(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 self.checkRepositoryEULA(name, repo):
- 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.basecachedir = self.conf.cachedir
- repo.failovermethod = "priority"
- repo.metadata_expire = 0
- # Enable gpg check for verifying corrupt packages
- repo.gpgcheck = 1
- repo.enable()
- repo.setup(0)
- repo.setCallback(TextProgress())
- self.repos.add(repo)
- return repo
-
- 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"] = "/"
- 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 the total size of installed pkgs
- pkgs_total_size = sum(map(lambda x: int(x.size), dlpkgs))
-
- # check needed size before actually download and install
- if checksize and pkgs_total_size > checksize:
- raise CreatorError("Size of specified root partition in kickstart
file is too small to install all selected packages.")
-
- if self.__recording_pkgs:
- # record all pkg and the content
- for pkg in dlpkgs:
- pkg_long_name = pkg.compactPrint()
- self.__pkgs_content[pkg_long_name] = pkg.files
-
- total_count = len(dlpkgs)
- cached_count = 0
- for po in dlpkgs:
- if hasattr(po, 'pkgtype') and po.pkgtype == 'local':
- cached_count +=1
- else:
- local = po.localPkg()
- if os.path.exists(local):
- cached_count += 1
- print "%d packages to be installed, %d packages gotten from cache, %d
packages to be downloaded" % (total_count, cached_count, 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. """
- print deps
- logging.warn("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
- sys.path.append('/usr/share/yum-cli')
- import callback
- cb = callback.RPMInstallCallback()
- cb.tsInfo = self.tsInfo
- cb.filelog = False
- ret = self.runTransaction(cb)
- print ""
- self._cleanupRpmdbLocks(self.conf.installroot)
- return ret
-
- def getAllContent(self):
- return self.__pkgs_content
-
diff --git a/setup.py b/setup.py
index 8fc64b3..e80bc0d 100644
--- a/setup.py
+++ b/setup.py
@@ -24,7 +24,7 @@ except:
except:
pass
-PACKAGES = ['mic', 'mic.imgcreate', 'mic.appcreate', 'mic.imgconvert',
'mic.ec2convert', 'mic.imgcreate.kscommands', 'mic.chroot']
+PACKAGES = ['mic', 'mic.imgcreate', 'mic.appcreate', 'mic.imgconvert',
'mic.ec2convert', 'mic.imgcreate.kscommands', 'mic.chroot',
'mic.imgcreate.pkgmanagers']
if sys.version_info[:2] > (2, 5):
if len(sys.argv) > 1 and 'install' in sys.argv:
_______________________________________________
MeeGo-dev mailing list
[email protected]
http://lists.meego.com/listinfo/meego-dev