dist_pkgpython_PYTHON = \
src/python/__init__.py \
+ src/python/bootloaders.py \
src/python/disk.py \
src/python/errors.py \
src/python/i18n.py \
import pakfire
+from . import bootloaders
from . import disk
from . import i18n
from . import logger
# Read OS information
self.os = self._read_os_release()
+ # Select a bootloaders
+ self.bootloaders = self._select_bootloaders()
+
# Hardware
self.disks = disk.Disks(self)
for path in disks:
disk.CreateFilesystems,
disk.MountFilesystems,
packages.InstallPackages,
+ bootloaders.InstallBootloader,
# Done!
disk.UmountFilesystems,
"""
return pakfire.Pakfire(self.root, arch=self.arch,
conf="/etc/pakfire/distros/ipfire3.conf")
+
+ def _select_bootloaders(self):
+ """
+ Select all bootloaders for this installation process
+ """
+ _bootloaders = (
+ bootloaders.Grub(self),
+ bootloaders.GrubEFI(self),
+ )
+
+ # Return all supported bootloaders
+ return [bl for bl in _bootloaders if bl.supported]
--- /dev/null
+###############################################################################
+# #
+# 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 itertools
+import logging
+
+from . import step
+from .i18n import _, N_
+
+# Setup logging
+log = logging.getLogger("bricklayer.bootloaders")
+
+class Bootloader(object):
+ """
+ A generic class for bootloaders
+ """
+
+ # Set the name of the bootloader
+ name = None
+
+ # Which architectures are supported?
+ arches = []
+
+ # Packages that need to be installed
+ packages = []
+
+ def __init__(self, bricklayer):
+ self.bricklayer = bricklayer
+
+ @property
+ def supported(self):
+ """
+ Returns True if this booloader is supported
+ """
+ # If arches is empty, this bootloader is supported
+ if not self.arches:
+ return True
+
+ return self.bricklayer.arch in self.arches
+
+ def install(self):
+ """
+ Called to install the bootloader
+ """
+ pass
+
+
+class Grub(Bootloader):
+ name = N_("GRUB")
+
+ arches = [
+ "x86_64",
+ ]
+
+ packages = [
+ "grub",
+ ]
+
+ def install(self):
+ # Initialize Pakfire
+ pakfire = self.bricklayer.setup_pakfire()
+
+ # Install GRUB2 on all disks that have been selected
+ for disk in self.bricklayer.disks.selected:
+ self.install_on_disk(disk, pakfire)
+
+ @property
+ def grub_arch(self):
+ return "i386-pc"
+
+ @property
+ def grub_args(self):
+ return [
+ "--target=%s" % self.grub_arch,
+ ]
+
+ def install_on_disk(self, disk, pakfire):
+ log.info("Installing GRUB on %s" % disk.path)
+
+ pakfire.execute(["grub-install"] + self.grub_args + [disk.path])
+
+
+class GrubEFI(Grub):
+ name = N_("GRUB EFI")
+
+ @property
+ def grub_arch(self):
+ if self.bricklayer.arch == "aarch64":
+ return "arm64-efi"
+
+ elif self.bricklayer.arch == "x86_64":
+ return "x86_64-efi"
+
+ @property
+ def grub_args(self):
+ return [
+ "--target=%s" % self.grub_arch,
+ "--efi-directory=/boot/efi",
+ ]
+
+
+class InstallBootloader(step.Step):
+ """
+ Installs the bootloader
+ """
+ def run(self, tui):
+ # Find all packages that need to be installed
+ packages = []
+ for bootloader in self.bricklayer.bootloaders:
+ packages += bootloader.packages
+
+ # Install them
+ #self.install_packages(tui, packages)
+
+ # Install all bootloaders
+ for bootloader in self.bricklayer.bootloaders:
+ with tui.progress(
+ _("Installing Bootloader"),
+ _("Installing bootloader \"%s\"...") % _(bootloader.name),
+ ):
+ bootloader.install()
# #
###############################################################################
-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()
+ self.install_packages(tui, packages)
import logging
import os
import time
+import pakfire.errors
import snack
"""
pass
+ def install_packages(self, tui, packages):
+ # Nothing to do if there are no packages
+ if not packages:
+ return
+
+ # Set up Pakfire
+ with tui.progress(
+ _("Setting Up Pakfire"),
+ _("Pakfire is being set up..."),
+ ):
+ p = self.bricklayer.setup_pakfire()
+
+ 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()
+
class InteractiveStep(Step):
"""