from mic.utils.proxy import get_proxy_for
from mic.utils import runner
-
class RPMInstallCallback:
""" Command line callback class for callbacks from the RPM library.
"""
self.total_installing = 0
self.installed_pkg_names = []
self.total_removed = 0
+ self.total_removing = 0
self.mark = "+"
self.marks = 40
self.lastmsg = None
self.ts = ts
self.filelog = False
self.logString = []
- self.headmsg = "Installing"
def _dopkgtup(self, hdr):
tmpepoch = hdr['epoch']
if self.output:
msger.info(msg)
- def _makefmt(self, percent, progress = True):
+ def _makefmt(self, doing, percent, progress = True):
l = len(str(self.total_actions))
size = "%s.%s" % (l, l)
fmt_done = "[%" + size + "s/%" + size + "s]"
- done = fmt_done % (self.total_installing,
- self.total_actions)
+ done = fmt_done % (doing, self.total_actions)
marks = self.marks - (2 * l)
width = "%s.%s" % (marks, marks)
fmt_bar = "%-" + width + "s"
elif what == rpm.RPMCALLBACK_INST_START:
self.total_installing += 1
- elif what == rpm.RPMCALLBACK_UNINST_STOP:
+ elif what == rpm.RPMCALLBACK_INST_STOP:
pass
elif what == rpm.RPMCALLBACK_INST_PROGRESS:
else:
pkgname = os.path.basename(rpmloc)
if self.output:
- fmt = self._makefmt(percent)
- msg = fmt % (self.headmsg, pkgname)
+ fmt = self._makefmt(self.total_installing, percent)
+ msg = fmt % ("Installing", pkgname)
if msg != self.lastmsg:
self.lastmsg = msg
msger.verbose('\n'.join(self.logString))
elif what == rpm.RPMCALLBACK_UNINST_START:
- pass
+ self.total_removing += 1
elif what == rpm.RPMCALLBACK_UNINST_PROGRESS:
- pass
+ if h is not None:
+ percent = (self.total_removed*100)/self.total_actions
+ if total > 0:
+ try:
+ hdr, rpmloc = h
+ except:
+ rpmloc = h
+
+ m = re.match(r"(.*)-(\d+.*)-(\d+\.\d+)\.(.+)\.rpm", os.path.basename(rpmloc))
+ if m:
+ pkgname = m.group(1)
+ else:
+ pkgname = os.path.basename(rpmloc)
+ if self.output:
+ fmt = self._makefmt(self.total_removing, percent)
+ msg = fmt % ("Uninstalling", pkgname)
+ if msg != self.lastmsg:
+ self.lastmsg = msg
+
+ msger.info(msg)
+
+ if self.total_installed == self.total_actions:
+ msger.raw('')
+ msger.verbose('\n'.join(self.logString))
elif what == rpm.RPMCALLBACK_UNINST_STOP:
self.total_removed += 1
elif os.path.splitext(cropts['local_pkgs_path'])[-1] == '.rpm':
return [cropts['local_pkgs_path']]
return []
-
def __localinst_packages(self):
for rpm_path in self._get_local_packages():
self.installLocal(rpm_path)
-
- def _getPackagesToReinstall(self):
- to_install_pkgs = []
- for pkg in self.update_pkgs:
- to_install_pkgs.append(pkg)
- isInstalled = pkg.status().isInstalled()
- msger.info("Update package %s : installed = %s" % (pkg.name(), isInstalled))
-
- for item in self.Z.pool():
- if item.name() == pkg.name and item.kind() == pkg.kind():
- msger.info("package %s in pool : installed = %s" % (item.name(), item.status().isInstalled()))
-
- return to_install_pkgs
-
def runInstall(self, checksize = 0):
if not self.Z:
self.__initialize_zypp()
installed_pkgs = todo._toInstall
dlpkgs = []
+ # re-create image with updating some packages
if len(installed_pkgs) == 0:
- installed_pkgs = self._getPackagesToReinstall()
+ self.deleteUpdatedPkgs()
+ installed_pkgs = self.update_pkgs
for pitem in installed_pkgs:
if not zypp.isKindPattern(pitem) and \
self.show_unresolved_dependencies_msg(unresolved_dependencies)
raise RepoError("Unresolved dependencies, transaction failed.")
+ def deleteUpdatedPkgs(self):
+ if not self.update_pkgs:
+ return
+
+ 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)
+
+ to_delete = []
+ for po in self.update_pkgs:
+ self.ts.addErase(po.name())
+ to_delete.append(po.name())
+ self.ts.order()
+
+ unresolved_dependencies = self.ts.check()
+ while unresolved_dependencies:
+ self.ts.clean()
+ check = False
+ for pkg, need, needflags, sense, key in unresolved_dependencies:
+ (name, version, release) = pkg
+ if sense == rpm.RPMDEP_SENSE_REQUIRES and name not in to_delete:
+ self.ts.addErase(name)
+ to_delete.append(name)
+ check = True
+
+ if check:
+ self.ts.order()
+ unresolved_dependencies = self.ts.check()
+ else:
+ self.show_unresolved_dependencies_msg(unresolved_dependencies)
+ raise RepoError("Unresolved dependencies, transaction failed.")
+
+ cb = rpmmisc.RPMInstallCallback(self.ts)
+ logfile = "%s/__catched_stderr.buf" % (self.instroot)
+
+ # start to catch stderr output from librpm
+ msger.enable_logstderr(logfile)
+
+ 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.')
+ if self.strict_mode:
+ raise CreatorError("mic failes to uninstall some packages")
+ else:
+ for e in errors:
+ msger.warning(e[0])
+ raise RepoError('Could not run transaction.')
+
+ self.update_pkgs.clear()
+ for item in to_delete:
+ pkg = self._zyppQueryPackage(item)
+ if pkg:
+ self.update_pkgs.append(pkg)
+ else:
+ msger.warning("No updated rpm found for: %s" % item)
+
def __initialize_transaction(self):
if not self.ts:
self.ts = rpm.TransactionSet(self.instroot)