From: Michael Tremer Date: Sun, 9 May 2021 11:18:00 +0000 (+0000) Subject: Implement dependency resolving and package installation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c40105967fa3c4179423cd720e17acdfbd58df16;p=people%2Fms%2Fbricklayer.git Implement dependency resolving and package installation Signed-off-by: Michael Tremer --- diff --git a/Makefile.am b/Makefile.am index d1c3155..95662b7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,6 +49,7 @@ dist_pkgpython_PYTHON = \ src/python/errors.py \ src/python/i18n.py \ src/python/logger.py \ + src/python/packages.py \ src/python/step.py \ src/python/tui.py \ src/python/util.py diff --git a/src/bricklayer b/src/bricklayer index 234b549..f64ba4b 100644 --- a/src/bricklayer +++ b/src/bricklayer @@ -21,6 +21,7 @@ import argparse import logging +import os import sys import bricklayer @@ -39,6 +40,8 @@ class Cli(object): parser = argparse.ArgumentParser( description=_("IPFire Installation Tool CLI"), ) + parser.add_argument("--arch", nargs="?", default=self.native_arch, + help=_("Select the target architecture")) parser.add_argument("--debug", action="store_true", help=_("Enable debugging mode")) parser.add_argument("--unattended", action="store_true", @@ -66,6 +69,14 @@ class Cli(object): # Run it return bl() + @property + def native_arch(self): + """ + Return the native system architecture (i.e. uname -m) + """ + sysname, nodename, release, version, arch = os.uname() + + return arch # Main c = Cli() diff --git a/src/python/__init__.py b/src/python/__init__.py index 0e81c14..da174c0 100644 --- a/src/python/__init__.py +++ b/src/python/__init__.py @@ -24,9 +24,12 @@ import sys import tempfile import traceback +import pakfire + from . import disk from . import i18n from . import logger +from . import packages from . import step from . import tui from . import util @@ -40,7 +43,8 @@ class Bricklayer(object): """ Bricklayer's base class """ - def __init__(self, debug=False, unattended=False, disks=[]): + def __init__(self, arch, debug=False, unattended=False, disks=[]): + self.arch = arch self.unattended = unattended # Enable debug logging @@ -51,6 +55,11 @@ class Bricklayer(object): self.settings = { "language" : i18n.default_language, + "packages" : [ + # Install the Base group + "@Base", + ], + # Set the default swap size to 1 GiB "swap-size": 1024 ** 3, } @@ -84,6 +93,7 @@ class Bricklayer(object): disk.CreatePartitionLayout, disk.CreateFilesystems, disk.MountFilesystems, + packages.InstallPackages, # Done! disk.UmountFilesystems, @@ -197,3 +207,10 @@ class Bricklayer(object): log.debug(output) return output + + def setup_pakfire(self): + """ + Calls Pakfire and has it load its configuration + """ + return pakfire.Pakfire(self.root, arch=self.arch, + conf="/etc/pakfire/distros/ipfire3.conf") diff --git a/src/python/packages.py b/src/python/packages.py new file mode 100644 index 0000000..166274b --- /dev/null +++ b/src/python/packages.py @@ -0,0 +1,84 @@ +############################################################################### +# # +# Bricklayer - An Installer for IPFire # +# Copyright (C) 2021 IPFire Development Team # +# # +# 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; either version 2 # +# of the License, or (at your option) any later version. # +# # +# 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 General Public License for more details. # +# # +# You should have received a copy of the GNU General Public License # +# along with this program. If not, see . # +# # +############################################################################### + +import logging +import pakfire.errors + +from . import step +from .i18n import _ + +# Set up logging +log = logging.getLogger("bricklayer.packages") + +class InstallPackages(step.Step): + def run(self, tui): + # Set up Pakfire + with tui.progress( + _("Setting Up Pakfire"), + _("Pakfire is being set up..."), + ): + p = self.bricklayer.setup_pakfire() + + # Get list of all packages to be installed + packages = self.bricklayer.settings.get("packages", []) + + with p as p: + # Resolve package dependencies + with tui.progress( + _("Resolving Dependencies"), + _("Resolving package dependencies..."), + ): + try: + transaction = p.install(packages) + + # Abort on any dependencies problems + except pakfire.errors.DependencyError as e: + problems = e.args[0] + + # Format problem descriptions + text = [] + for problem in problems: + lines = [ + "* %s" % problem + ] + for solution in problem.solutions: + lines.append(" --> %s" % solution) + + text.append("\n".join(lines)) + + tui.error( + _("Dependency Problem"), + _( + "A problem has occured during resolving package dependencies:\n\n%s", + "Problems have occured during resolving package dependencies:\n\n%s", + len(problems), + ) % "\n\n".join(text), + width=78, + ) + + # Log the transaction + log.info("%s" % transaction.dump()) + + # Run the transaction + with tui.progress( + _("Installing Packages"), + _("Installing packages..."), + ): + transaction.run()