From 6c36534206bb1f850b1a957cbb3206e5af9373a1 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Tue, 29 Aug 2017 04:18:47 -0400 Subject: [PATCH] Package module: fix packages-could-be-objects code - Check for 'list' when it's actually a 'dict' is strange. Reverse logic to consider 'str' a package name and everything else is special. - Refactor to handle the difference between package names and packages-with-script-data in one place. - Add code and config documentation. - Switch sample configurations to dummy-backend. --- src/modules/packages/main.py | 96 ++++++++++++++++++------------ src/modules/packages/packages.conf | 10 +++- src/modules/packages/test.yaml | 3 +- 3 files changed, 66 insertions(+), 43 deletions(-) diff --git a/src/modules/packages/main.py b/src/modules/packages/main.py index 97d97738e..dcd999727 100644 --- a/src/modules/packages/main.py +++ b/src/modules/packages/main.py @@ -42,13 +42,26 @@ class PackageManager(metaclass=abc.ABCMeta): @abc.abstractmethod def install(self, pkgs, from_local=False): + """ + Install a list of packages (named) into the system. + Although this handles lists, in practice it is called + with one package at a time. + + @param pkgs: list[str] + list of package names + @param from_local: bool + if True, then these are local packages (on disk) and the + pkgs names are paths. + """ pass @abc.abstractmethod def remove(self, pkgs): - """ Removes packages. + """ + Removes packages. - :param pkgs: + @param pkgs: list[str] + list of package names """ pass @@ -60,6 +73,23 @@ class PackageManager(metaclass=abc.ABCMeta): if script != "": check_target_env_call(script.split(" ")) + def install_package(self, packagedata, from_local=False): + """ + Install a package from a single entry in the install list. + This can be either a single package name, or an object + with pre- and post-scripts. + + @param packagedata: str|dict + @param from_local: bool + see install.from_local + """ + if isinstance(packagedata, str): + self.install([packagedata], from_local=from_local) + else: + self.run(packagedata["pre-script"]) + self.install([packagedata["package"]], from_local=from_local) + self.run(packagedata["post-script"]) + class PMPackageKit(PackageManager): backend = "packagekit" @@ -81,13 +111,13 @@ class PMZypp(PackageManager): def install(self, pkgs, from_local=False): check_target_env_call(["zypper", "--non-interactive", - "--quiet-install", "install", - "--auto-agree-with-licenses", - "install"] + pkgs) + "--quiet-install", "install", + "--auto-agree-with-licenses", + "install"] + pkgs) def remove(self, pkgs): check_target_env_call(["zypper", "--non-interactive", - "remove"] + pkgs) + "remove"] + pkgs) def update_db(self): check_target_env_call(["zypper", "--non-interactive", "update"]) @@ -101,7 +131,7 @@ class PMYum(PackageManager): def remove(self, pkgs): check_target_env_call(["yum", "--disablerepo=*", "-C", "-y", - "remove"] + pkgs) + "remove"] + pkgs) def update_db(self): # Doesn't need updates @@ -118,7 +148,7 @@ class PMDnf(PackageManager): # ignore the error code for now because dnf thinks removing a # nonexistent package is an error target_env_call(["dnf", "--disablerepo=*", "-C", "-y", - "remove"] + pkgs) + "remove"] + pkgs) def update_db(self): # Doesn't need to update explicitly @@ -126,13 +156,13 @@ class PMDnf(PackageManager): class PMUrpmi(PackageManager): - backend = "urpmi"; + backend = "urpmi" def install(self, pkgs, from_local=False): check_target_env_call(["urpmi", "--download-all", "--no-suggests", - "--no-verify-rpm", "--fastunsafe", - "--ignoresize", "--nolock", - "--auto"] + pkgs) + "--no-verify-rpm", "--fastunsafe", + "--ignoresize", "--nolock", + "--auto"] + pkgs) def remove(self, pkgs): check_target_env_call(["urpme", "--auto"] + pkgs) @@ -149,9 +179,9 @@ class PMApt(PackageManager): def remove(self, pkgs): check_target_env_call(["apt-get", "--purge", "-q", "-y", - "remove"] + pkgs) + "remove"] + pkgs) check_target_env_call(["apt-get", "--purge", "-q", "-y", - "autoremove"]) + "autoremove"]) def update_db(self): check_target_env_call(["apt-get", "update"]) @@ -167,7 +197,7 @@ class PMPacman(PackageManager): pacman_flags = "-Sy" check_target_env_call(["pacman", pacman_flags, - "--noconfirm"] + pkgs) + "--noconfirm"] + pkgs) def remove(self, pkgs): check_target_env_call(["pacman", "-Rs", "--noconfirm"] + pkgs) @@ -215,11 +245,14 @@ class PMDummy(PackageManager): def update_db(self): libcalamares.utils.debug("Updating DB") + def run(self, script): + libcalamares.utils.debug("Running script '" + str(script) + "'") + backend_managers = [ (c.backend, c) for c in globals().values() - if type(c) is abc.ABCMeta and issubclass(c, PackageManager) and c.backend ] + if type(c) is abc.ABCMeta and issubclass(c, PackageManager) and c.backend] def subst_locale(list): @@ -247,33 +280,18 @@ def run_operations(pkgman, entry): for key in entry.keys(): entry[key] = subst_locale(entry[key]) if key == "install": - if isinstance(entry[key], list): - for package in entry[key]: - pkgman.run(package["pre-script"]) - pkgman.install([package["package"]]) - pkgman.run(package["post-script"]) - else: - pkgman.install(entry[key]) + for package in entry[key]: + pkgman.install_package(package) elif key == "try_install": # we make a separate package manager call for each package so a # single failing package won't stop all of them for package in entry[key]: - if isinstance(package, str): - try: - pkgman.install([package]) - except subprocess.CalledProcessError: - warn_text = "WARNING: could not install package " - warn_text += package - libcalamares.utils.debug(warn_text) - else: - try: - pkgman.run(package["pre-script"]) - pkgman.install([package["package"]]) - pkgman.run(package["post-script"]) - except subprocess.CalledProcessError: - warn_text = "WARNING: could not install packages " - warn_text += package["package"] - libcalamares.utils.debug(warn_text) + try: + pkgman.install_package(package) + except subprocess.CalledProcessError: + warn_text = "WARNING: could not install package " + warn_text += str(package) + libcalamares.utils.debug(warn_text) elif key == "remove": pkgman.remove(entry[key]) elif key == "try_remove": diff --git a/src/modules/packages/packages.conf b/src/modules/packages/packages.conf index 4039278b3..da47cec25 100644 --- a/src/modules/packages/packages.conf +++ b/src/modules/packages/packages.conf @@ -8,11 +8,15 @@ # - urpmi - Mandriva package manager # - apt - APT frontend for DEB and RPM # - pacman - Pacman -# - portage - Gentoo package manager -# - entropy - Sabayon package manager +# - portage - Gentoo package manager +# - entropy - Sabayon package manager +# - dummy - Dummy manager, only logs # -backend: packagekit +backend: dummy +# If set to true, a package-manager specific update procedure +# is run first (only if there is internet) to update the list +# of packages and dependencies. update_db: true # diff --git a/src/modules/packages/test.yaml b/src/modules/packages/test.yaml index 345172622..49c1a5197 100644 --- a/src/modules/packages/test.yaml +++ b/src/modules/packages/test.yaml @@ -1,5 +1,6 @@ +backend: dummy rootMountPoint: /tmp/mount -packageOperations: +operations: - install: - pre-script: touch /tmp/foo package: vi