Skip to content

How to add support for a new distro type

RedBearAK edited this page Apr 1, 2024 · 3 revisions

Intro

The Toshy installer script is written in Python and contains some significant modularity that makes it a bit easier to add new distro types and/or package managers. The installation of Python packages in a Python virtual environment requires a minimal complement of native packages to be installed to allow the build process of certain Python packages to succeed.

This Wiki article will explain (mainly to myself the next time I have to do this 🧠) the basic structure of how the Toshy installer script manages to install on different distro types where different package managers are in use, and often very different package names are needed.

Perhaps someone with a lot of knowledge could eventually turn this into a proper cross-distro packaging strategy, but that's beyond me right now. The current script has difficulties with containers (e.g., distrobox, toolbox, podman) and unusual environments like NixOS.

Components involved

  1. Map of distro type to list of distro IDs

    • Examples of distro groups: 'fedora-based', 'arch-based'
    • Examples of IDs: 'fedora', 'debian', 'manjaro'
  2. Map of distro type to list of package names

  3. Class with methods to handle difficult distros

  4. Class with methods to use a given package manager

  5. Variable with list of distro IDs that use package manager

  6. Sub-function to contain install logic for distro type

  7. Dispatcher that (only) runs the correct installer sub-function

How to add something new

So to add support for a completely new distro type that uses a different package manager, you'd need to:

  1. Add a newtype-based key into the distro_groups_map dictionary structure, and the value attached to that key would need to be a list of at least one distro ID (not the long name, just the shortened "ID" you find in /etc/os-release).

  2. Add the same newtype-based key into the pkg_groups_map dictionary structure, with a value that is a list of package names, modeled off the existing lists of package names that work for other distros, but tailored to the new distro type. (This will almost always require some trial-and-error testing after the rest of the steps are completed.)

  3. If the distro requires some unusual adjustments before doing the step of installing the native package list, a new method may need to be added to the DistroQuirksHandler class, to be called via the quirks_handler instance of that class. But this is not typically necessary, unless you're insane enough to try to get Toshy to install on something like CentOS 7. And who would do something like that? 👋😄

  4. As part of handling quirks, there are dictionary structures (extra_pkgs_map and remove_pkgs_map) that allow adding or removing packages from the full package list for some oddball distros that don't quite work with the standard package list needed for other distros of the same type. Usage examples are provided as comments within each structure.

  5. Stage a new empty list variable for the new package manager type, then within the try/except block below it, add the new list of distro IDs that was created earlier to the new empty list variable.

  6. Create a sub-function dedicated to installing on this distro type (package manager type). Often, all it has to do is call the native_pkg_installer object to access the native_pkg_installer.install_pkg_list() method. The command list to give the method MUST include the option for the package manager that causes it to run "non-interactively" (without needing user input). The non-interactive option for package managers will typically cause it to automatically answer "no" when there is some kind of package conflict that the package manager can't automatically fix, so that's generally not something to worry about. On some distros it is useful to pre-filter the package list (cnfg.pkgs_for_distro) before the install attempt, so the package manager doesn't try to "reinstall" some packages or show a lot of complaints in the terminal. There are examples in existing installer sub-functions for how to do this. Depends on the package manager options.

  7. Add the new sub-function into the "dispatcher" (pkg_mgr_dispatch_map) dictionary structure, so that when the distro ID is found within one of the package manager distro ID lists, the correct sub-function gets called to do the installing of the packages. (Caveat: Make sure same the distro ID is not found in multiple distro groups, which could lead to the wrong package manager getting called.)

  8. Test the installer script on a fresh install of the new distro type, in a virtual machine where you have a "clean" snapshot that you can revert to, until you are certain the new additions to the installer script results in not install errors and a fully working setup of Toshy.

  9. Submit a pull request (on the dev_beta branch if possible) if you think you've got it working for a new distro type.

Comments

Because of this logical modularity, I was able to add support for distros like Void Linux and openSUSE Aeon/Kalpa after just a few hours in each case.

The main difficulty on something fundamentally different from all existing supported distro types is just figuring out the different package names. This usually involves a lot of googling error messages and getting one of the AI LLMs to produce some wild guesses on replacement package names that might fix those errors on the specific distro type.