]> git.ipfire.org Git - people/ms/bricklayer.git/commitdiff
Implement dependency resolving and package installation
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 9 May 2021 11:18:00 +0000 (11:18 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 9 May 2021 11:18:00 +0000 (11:18 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Makefile.am
src/bricklayer
src/python/__init__.py
src/python/packages.py [new file with mode: 0644]

index d1c3155b226916e9ce66bc93de21eb45b8e0c3fc..95662b7a19b6a839cb29180537eef358376b3134 100644 (file)
@@ -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
index 234b549d26753e9691ae8cb8fe658b4fa4cac6e2..f64ba4b73d09c6be4a57705a38c92e3fd9baf9af 100644 (file)
@@ -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()
index 0e81c14aa7cd5d353979600a55cd3097684d00fa..da174c06213cb0551854b2632248ab9add332a88 100644 (file)
@@ -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 (file)
index 0000000..166274b
--- /dev/null
@@ -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 <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+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()