Skip to content

Commit 8771de9

Browse files
committed
backends/eopkg: Modernize privileged operations (upgrade, remove, etc)
- Ensure privileged operations use the privileged decorator in order set progress bars correctly and reinit dbs as required. - Add simulate support to these operations - Add only download support to upgrade() - Ensure common errors are handled and reported appropriately - Add autoremove support to remove()
1 parent 68b3f81 commit 8771de9

File tree

1 file changed

+123
-111
lines changed

1 file changed

+123
-111
lines changed

backends/eopkg/eopkgBackend.py

Lines changed: 123 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@
3636

3737
import pisi
3838
import pisi.ui
39-
from packagekit.backend import *
4039
from packagekit.package import PackagekitPackage
41-
from packagekit import enums
40+
from packagekit.backend import *
41+
from packagekit.enums import *
42+
from packagekit.progress import *
4243
import os.path
4344
import piksemel
4445
import re
@@ -658,18 +659,15 @@ def get_update_detail(self, package_ids):
658659
bugURI, cve_url, reboot, update_message,
659660
changelog, state, issued, updated)
660661

662+
@privileged
661663
def download_packages(self, directory, package_ids):
662664
""" Download the given packages to a directory """
663-
self.allow_cancel(False)
664-
self.percentage(None)
665+
self.allow_cancel(True)
666+
self.percentage(0)
665667
self.status(STATUS_DOWNLOAD)
666668

667669
packages = list()
668670

669-
def progress_cb(**kw):
670-
self.percentage(int(kw['percent']))
671-
672-
ui = SimplePisiHandler()
673671
for package_id in package_ids:
674672
package = self.get_package_from_id(package_id)[0]
675673
packages.append(package)
@@ -678,8 +676,6 @@ def progress_cb(**kw):
678676
except:
679677
self.error(ERROR_PACKAGE_NOT_FOUND, "Package was not found")
680678
try:
681-
pisi.api.set_userinterface(ui)
682-
ui.the_callback = progress_cb
683679
if directory is None:
684680
directory = os.path.curdir
685681
pisi.api.fetch(packages, directory)
@@ -689,70 +685,54 @@ def progress_cb(**kw):
689685
uri = package_obj.packageURI.split("/")[-1]
690686
location = os.path.join(directory, uri)
691687
self.files(package_id, location)
692-
pisi.api.set_userinterface(self.saved_ui)
693-
except Exception, e:
694-
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED,
695-
"Could not download package: %s" % e)
696-
self.percentage(None)
688+
except pisi.fetcher.FetchError as e:
689+
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Could not download package: %s" % e, exit=False)
690+
except IOError as e:
691+
self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % e)
692+
except pisi.Error as e:
693+
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Could not download package: %s" % e, exit=False)
694+
except Exception as e:
695+
self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
697696

698-
def install_files(self, only_trusted, files):
697+
@privileged
698+
def install_files(self, transaction_flags, inst_files):
699699
""" Installs given package into system"""
700700

701701
# FIXME: use only_trusted
702702

703-
# FIXME: install progress
704-
self.allow_cancel(False)
705-
self.percentage(None)
706-
707-
def progress_cb(**kw):
708-
self.percentage(int(kw['percent']))
709-
710-
ui = SimplePisiHandler()
711-
712-
self.status(STATUS_INSTALL)
713-
pisi.api.set_userinterface(ui)
714-
ui.the_callback = progress_cb
703+
if TRANSACTION_FLAG_SIMULATE in transaction_flags:
704+
for f in inst_files:
705+
metadata, _ = pisi.api.info_file(f)
706+
pkg_id = self.get_package_id(metadata.package.name, metadata.package.version, metadata.package.architecture, "local")
707+
self.package(pkg_id, INFO_INSTALL, metadata.package.summary)
708+
for dep in metadata.package.runtimeDependencies():
709+
if not dep.satisfied_by_installed():
710+
if not self.packagedb.has_package(dep.package):
711+
self.error(ERROR_DEP_RESOLUTION_FAILED, "Cannot install: %s. Can't resolve dependency %s" % (f, dep.package))
712+
dep_pkg = self.packagedb.get_package(dep.package)
713+
repo = self.packagedb.get_package_repo(dep_pkg.name, None)
714+
dep_id = self.get_package_id(dep_pkg.name, dep_pkg.version, dep_pkg.architecture, repo)
715+
self.package(dep_id, INFO_INSTALL, dep_pkg.summary)
716+
return
715717

718+
self.allow_cancel(False)
716719
try:
717-
self.status(STATUS_INSTALL)
718-
pisi.api.install(files)
719-
except pisi.Error, e:
720-
# FIXME: Error: internal-error : Package re-install declined
721-
# Force needed?
722-
self.error(ERROR_PACKAGE_ALREADY_INSTALLED, e)
723-
pisi.api.set_userinterface(self.saved_ui)
724-
725-
def _report_all_for_package(self, package, remove=False):
726-
""" Report all deps for the given package """
727-
if not remove:
728-
deps = self.packagedb.get_package(package).runtimeDependencies()
729-
# TODO: Add support to report conflicting packages requiring removal
730-
#conflicts = self.packagedb.get_package (package).conflicts
731-
for dep in deps:
732-
if not self.installdb.has_package(dep.name()):
733-
dep_pkg = self.packagedb.get_package(dep.name())
734-
repo = self.packagedb.get_package_repo(dep_pkg.name, None)
735-
version = self.__get_package_version(dep_pkg)
736-
pkg_id = self.get_package_id(dep_pkg.name, version,
737-
dep_pkg.architecture, repo[1])
738-
self.package(pkg_id, INFO_INSTALLING, dep_pkg.summary)
739-
else:
740-
rev_deps = self.installdb.get_rev_deps(package)
741-
for rev_dep, depinfo in rev_deps:
742-
if self.installdb.has_package(rev_dep):
743-
dep_pkg = self.packagedb.get_package(rev_dep)
744-
repo = self.packagedb.get_package_repo(dep_pkg.name, None)
745-
version = self.__get_package_version(dep_pkg)
746-
pkg_id = self.get_package_id(dep_pkg.name, version,
747-
dep_pkg.architecture, repo[1])
748-
self.package(pkg_id, INFO_REMOVING, dep_pkg.summary)
720+
# Actually install
721+
pisi.api.install(inst_files)
722+
except pisi.fetcher.FetchError as e:
723+
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Could not download package: %s" % e, exit=False)
724+
except IOError as e:
725+
self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % e)
726+
except pisi.Error as e:
727+
self.error(ERROR_LOCAL_INSTALL_FAILED, "Could not install: %s" % e, exit=False)
728+
except Exception as e:
729+
self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
749730

731+
@privileged
750732
def install_packages(self, transaction_flags, package_ids):
751733
""" Installs given package into system"""
752-
# FIXME: fetch/install progress
753734
self.allow_cancel(False)
754-
self.percentage(None)
755-
735+
self.percentage(0)
756736
packages = list()
757737

758738
# FIXME: use only_trusted
@@ -763,25 +743,34 @@ def install_packages(self, transaction_flags, package_ids):
763743
"Package is already installed")
764744
packages.append(package)
765745

766-
def progress_cb(**kw):
767-
self.percentage(int(kw['percent']))
768-
769-
ui = SimplePisiHandler()
770-
771-
self.status(STATUS_INSTALL)
772-
pisi.api.set_userinterface(ui)
773-
ui.the_callback = progress_cb
774-
775746
if TRANSACTION_FLAG_SIMULATE in transaction_flags:
776-
# Simulated, not real.
777-
for package in packages:
778-
self._report_all_for_package(package)
747+
pkgSet = set(packages)
748+
order = pisi.api.get_install_order(pkgSet)
749+
# Merge any forced system.base upgrades to the order as well
750+
base_order = pisi.api.get_base_upgrade_order(pkgSet)
751+
order = base_order + order
752+
for dep in order:
753+
dep_pkg = self.packagedb.get_package(dep)
754+
repo = self.packagedb.get_package_repo(dep_pkg.name, None)
755+
version = self.__get_package_version(dep_pkg)
756+
pkg_id = self.get_package_id(dep_pkg.name, version,
757+
dep_pkg.architecture, repo[1])
758+
self.package(pkg_id, INFO_INSTALL, dep_pkg.summary)
779759
return
760+
761+
if TRANSACTION_FLAG_ONLY_DOWNLOAD in transaction_flags:
762+
pisi.context.set_option("fetch_only", True)
763+
780764
try:
781765
pisi.api.install(packages)
782-
except pisi.Error, e:
783-
self.error(ERROR_UNKNOWN, e)
784-
pisi.api.set_userinterface(self.saved_ui)
766+
except pisi.fetcher.FetchError as e:
767+
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Could not download package: %s" % e, exit=False)
768+
except IOError as e:
769+
self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % e)
770+
except pisi.Error as e:
771+
self.error(ERROR_PACKAGE_FAILED_TO_INSTALL, "Could not install: %s" % e, exit=False)
772+
except Exception as e:
773+
self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
785774

786775
@privileged
787776
def refresh_cache(self, force):
@@ -799,12 +788,12 @@ def refresh_cache(self, force):
799788
percentage += slice
800789
self.percentage(percentage)
801790

791+
@privileged
802792
def remove_packages(self, transaction_flags, package_ids,
803-
allowdeps, autoremove):
793+
allowdep, autoremove):
804794
""" Removes given package from system"""
805795
self.allow_cancel(False)
806-
self.percentage(None)
807-
# TODO: use autoremove
796+
self.percentage(0)
808797
packages = list()
809798

810799
for package_id in package_ids:
@@ -814,24 +803,33 @@ def remove_packages(self, transaction_flags, package_ids,
814803
"Package is not installed")
815804
packages.append(package)
816805

817-
def progress_cb(**kw):
818-
self.percentage(int(kw['percent']))
819-
820-
ui = SimplePisiHandler()
821-
822-
package = self.get_package_from_id(package_ids[0])[0]
823-
self.status(STATUS_REMOVE)
824-
825806
if TRANSACTION_FLAG_SIMULATE in transaction_flags:
826-
# Simulated, not real.
827-
for package in packages:
828-
self._report_all_for_package(package, remove=True)
807+
pkgSet = set(packages)
808+
order = pisi.api.get_remove_order(pkgSet, autoremove)
809+
for dep in order:
810+
dep_pkg = self.packagedb.get_package(dep)
811+
if dep_pkg.partOf == "system.base":
812+
self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE, "Cannot remove system.base package: %s" % dep_pkg.name)
813+
repo = self.packagedb.get_package_repo(dep_pkg.name, None)
814+
version = self.__get_package_version(dep_pkg)
815+
pkg_id = self.get_package_id(dep_pkg.name, version,
816+
dep_pkg.architecture, repo[1])
817+
self.package(pkg_id, INFO_REMOVE, dep_pkg.summary)
829818
return
819+
830820
try:
831-
pisi.api.remove(packages)
832-
except pisi.Error, e:
833-
self.error(ERROR_CANNOT_REMOVE_SYSTEM_PACKAGE, e)
834-
pisi.api.set_userinterface(self.saved_ui)
821+
if autoremove:
822+
pisi.api.autoremove(packages)
823+
else:
824+
pisi.api.remove(packages)
825+
except pisi.fetcher.FetchError as e:
826+
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Could not download package: %s" % e, exit=False)
827+
except IOError as e:
828+
self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % e)
829+
except pisi.Error as e:
830+
self.error(ERROR_PACKAGE_FAILED_TO_REMOVE, "Could not remove: %s" % e, exit=False)
831+
except Exception as e:
832+
self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
835833

836834
@privileged
837835
def repo_enable(self, repoid, enable):
@@ -943,14 +941,15 @@ def search_name(self, filters, values):
943941
for pkg in pisi.api.search_package([value]):
944942
self.__get_package(pkg, filters)
945943

944+
@privileged
946945
def update_packages(self, transaction_flags, package_ids):
947946
""" Updates given package to its latest version """
948947

949948
# FIXME: use only_trusted
950-
951-
# FIXME: fetch/install progress
952-
self.allow_cancel(False)
949+
# FIXME: install progress
950+
self.allow_cancel(True)
953951
self.percentage(None)
952+
self.status(STATUS_RUNNING)
954953

955954
packages = list()
956955
for package_id in package_ids:
@@ -960,22 +959,35 @@ def update_packages(self, transaction_flags, package_ids):
960959
"Cannot update a package that is not installed")
961960
packages.append(package)
962961

963-
def progress_cb(**kw):
964-
self.percentage(int(kw['percent']))
965-
966-
ui = SimplePisiHandler()
967-
pisi.api.set_userinterface(ui)
968-
ui.the_callback = progress_cb
969-
970962
if TRANSACTION_FLAG_SIMULATE in transaction_flags:
971-
for package in packages:
972-
self._report_all_for_package(package)
963+
pkgSet = set(packages)
964+
order = pisi.api.get_upgrade_order(pkgSet)
965+
# Merge any forced system.base upgrades to the order as well
966+
base_order = pisi.api.get_base_upgrade_order(pkgSet)
967+
order = base_order + order
968+
for dep in order:
969+
dep_pkg = self.packagedb.get_package(dep)
970+
repo = self.packagedb.get_package_repo(dep_pkg.name, None)
971+
version = self.__get_package_version(dep_pkg)
972+
pkg_id = self.get_package_id(dep_pkg.name, version,
973+
dep_pkg.architecture, repo[1])
974+
self.package(pkg_id, INFO_INSTALL, dep_pkg.summary)
973975
return
976+
977+
if TRANSACTION_FLAG_ONLY_DOWNLOAD in transaction_flags:
978+
pisi.context.set_option("fetch_only", True)
979+
974980
try:
981+
# Actually upgrade
975982
pisi.api.upgrade(packages)
976-
except pisi.Error, e:
977-
self.error(ERROR_UNKNOWN, e)
978-
pisi.api.set_userinterface(self.saved_ui)
983+
except pisi.fetcher.FetchError as e:
984+
self.error(ERROR_PACKAGE_DOWNLOAD_FAILED, "Could not download package: %s" % e, exit=False)
985+
except IOError as e:
986+
self.error(ERROR_NO_SPACE_ON_DEVICE, "Disk error: %s" % e)
987+
except pisi.Error as e:
988+
self.error(ERROR_PACKAGE_FAILED_TO_INSTALL, "Could not update: %s" % e, exit=False)
989+
except Exception as e:
990+
self.error(ERROR_INTERNAL_ERROR, _format_str(traceback.format_exc()))
979991

980992

981993
def main():

0 commit comments

Comments
 (0)