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.
This commit is contained in:
Adriaan de Groot 2017-08-29 04:18:47 -04:00
parent d66434985e
commit 6c36534206
3 changed files with 66 additions and 43 deletions

View File

@ -42,13 +42,26 @@ class PackageManager(metaclass=abc.ABCMeta):
@abc.abstractmethod @abc.abstractmethod
def install(self, pkgs, from_local=False): 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 pass
@abc.abstractmethod @abc.abstractmethod
def remove(self, pkgs): def remove(self, pkgs):
""" Removes packages. """
Removes packages.
:param pkgs: @param pkgs: list[str]
list of package names
""" """
pass pass
@ -60,6 +73,23 @@ class PackageManager(metaclass=abc.ABCMeta):
if script != "": if script != "":
check_target_env_call(script.split(" ")) 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): class PMPackageKit(PackageManager):
backend = "packagekit" backend = "packagekit"
@ -81,13 +111,13 @@ class PMZypp(PackageManager):
def install(self, pkgs, from_local=False): def install(self, pkgs, from_local=False):
check_target_env_call(["zypper", "--non-interactive", check_target_env_call(["zypper", "--non-interactive",
"--quiet-install", "install", "--quiet-install", "install",
"--auto-agree-with-licenses", "--auto-agree-with-licenses",
"install"] + pkgs) "install"] + pkgs)
def remove(self, pkgs): def remove(self, pkgs):
check_target_env_call(["zypper", "--non-interactive", check_target_env_call(["zypper", "--non-interactive",
"remove"] + pkgs) "remove"] + pkgs)
def update_db(self): def update_db(self):
check_target_env_call(["zypper", "--non-interactive", "update"]) check_target_env_call(["zypper", "--non-interactive", "update"])
@ -101,7 +131,7 @@ class PMYum(PackageManager):
def remove(self, pkgs): def remove(self, pkgs):
check_target_env_call(["yum", "--disablerepo=*", "-C", "-y", check_target_env_call(["yum", "--disablerepo=*", "-C", "-y",
"remove"] + pkgs) "remove"] + pkgs)
def update_db(self): def update_db(self):
# Doesn't need updates # Doesn't need updates
@ -118,7 +148,7 @@ class PMDnf(PackageManager):
# ignore the error code for now because dnf thinks removing a # ignore the error code for now because dnf thinks removing a
# nonexistent package is an error # nonexistent package is an error
target_env_call(["dnf", "--disablerepo=*", "-C", "-y", target_env_call(["dnf", "--disablerepo=*", "-C", "-y",
"remove"] + pkgs) "remove"] + pkgs)
def update_db(self): def update_db(self):
# Doesn't need to update explicitly # Doesn't need to update explicitly
@ -126,13 +156,13 @@ class PMDnf(PackageManager):
class PMUrpmi(PackageManager): class PMUrpmi(PackageManager):
backend = "urpmi"; backend = "urpmi"
def install(self, pkgs, from_local=False): def install(self, pkgs, from_local=False):
check_target_env_call(["urpmi", "--download-all", "--no-suggests", check_target_env_call(["urpmi", "--download-all", "--no-suggests",
"--no-verify-rpm", "--fastunsafe", "--no-verify-rpm", "--fastunsafe",
"--ignoresize", "--nolock", "--ignoresize", "--nolock",
"--auto"] + pkgs) "--auto"] + pkgs)
def remove(self, pkgs): def remove(self, pkgs):
check_target_env_call(["urpme", "--auto"] + pkgs) check_target_env_call(["urpme", "--auto"] + pkgs)
@ -149,9 +179,9 @@ class PMApt(PackageManager):
def remove(self, pkgs): def remove(self, pkgs):
check_target_env_call(["apt-get", "--purge", "-q", "-y", check_target_env_call(["apt-get", "--purge", "-q", "-y",
"remove"] + pkgs) "remove"] + pkgs)
check_target_env_call(["apt-get", "--purge", "-q", "-y", check_target_env_call(["apt-get", "--purge", "-q", "-y",
"autoremove"]) "autoremove"])
def update_db(self): def update_db(self):
check_target_env_call(["apt-get", "update"]) check_target_env_call(["apt-get", "update"])
@ -167,7 +197,7 @@ class PMPacman(PackageManager):
pacman_flags = "-Sy" pacman_flags = "-Sy"
check_target_env_call(["pacman", pacman_flags, check_target_env_call(["pacman", pacman_flags,
"--noconfirm"] + pkgs) "--noconfirm"] + pkgs)
def remove(self, pkgs): def remove(self, pkgs):
check_target_env_call(["pacman", "-Rs", "--noconfirm"] + pkgs) check_target_env_call(["pacman", "-Rs", "--noconfirm"] + pkgs)
@ -215,11 +245,14 @@ class PMDummy(PackageManager):
def update_db(self): def update_db(self):
libcalamares.utils.debug("Updating DB") libcalamares.utils.debug("Updating DB")
def run(self, script):
libcalamares.utils.debug("Running script '" + str(script) + "'")
backend_managers = [ backend_managers = [
(c.backend, c) (c.backend, c)
for c in globals().values() 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): def subst_locale(list):
@ -247,33 +280,18 @@ def run_operations(pkgman, entry):
for key in entry.keys(): for key in entry.keys():
entry[key] = subst_locale(entry[key]) entry[key] = subst_locale(entry[key])
if key == "install": if key == "install":
if isinstance(entry[key], list): for package in entry[key]:
for package in entry[key]: pkgman.install_package(package)
pkgman.run(package["pre-script"])
pkgman.install([package["package"]])
pkgman.run(package["post-script"])
else:
pkgman.install(entry[key])
elif key == "try_install": elif key == "try_install":
# we make a separate package manager call for each package so a # we make a separate package manager call for each package so a
# single failing package won't stop all of them # single failing package won't stop all of them
for package in entry[key]: for package in entry[key]:
if isinstance(package, str): try:
try: pkgman.install_package(package)
pkgman.install([package]) except subprocess.CalledProcessError:
except subprocess.CalledProcessError: warn_text = "WARNING: could not install package "
warn_text = "WARNING: could not install package " warn_text += str(package)
warn_text += package libcalamares.utils.debug(warn_text)
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)
elif key == "remove": elif key == "remove":
pkgman.remove(entry[key]) pkgman.remove(entry[key])
elif key == "try_remove": elif key == "try_remove":

View File

@ -8,11 +8,15 @@
# - urpmi - Mandriva package manager # - urpmi - Mandriva package manager
# - apt - APT frontend for DEB and RPM # - apt - APT frontend for DEB and RPM
# - pacman - Pacman # - pacman - Pacman
# - portage - Gentoo package manager # - portage - Gentoo package manager
# - entropy - Sabayon 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 update_db: true
# #

View File

@ -1,5 +1,6 @@
backend: dummy
rootMountPoint: /tmp/mount rootMountPoint: /tmp/mount
packageOperations: operations:
- install: - install:
- pre-script: touch /tmp/foo - pre-script: touch /tmp/foo
package: vi package: vi