+++ title = "Slotting: what it is, why it matters" paginate_by = 5 +++ - [Overview](#overview) - [Technical choices](#technical-choices) - [Custom tools](#custom-tools) - [Slotting](#slotting) - [Roadmap](#roadmap) - [BaguetteOS File-System Hierarchy](#baguetteos-fsh) # Slotting: providing software the right way The usual way to provide software is to package it into a distribution, then provide it as *the* OS version of the software. In the long run, software and libraries change, which is no big deal since maintainers verify the consistency of the different versions provided by the OS. Maintainers' job is to verify that all programs have the right library versions under their OS. ### Current set of problems - What happens when two programs need a different version of a library?
The installation of both may not be possible without workarounds. See python from version 2 to 3 as an example. To make it work, OSs have given new names for their binaries (`python-2.7` and `python-3.5` for example). Libraries are *by default* packaged into a directory specific for a python version, such as `/usr/lib/python3.5/`. This is mostly done for languages, but what about other packaged applications and libraries? - What happens when two libraries are compatible but you want both on your system (see libressl and openssl)?
One of them could be provided in another path, such as `/usr/lib/libressl`. - What happens when you want to provide a **very** long-term support for your users? *see companies running decade-old OSs and databases* BaguetteOS has a simple and safe way to let users and maintainers provide packages: `slotting`. ### What is slotting? Slotting is a way to use prefixes (paths, directories) to separate execution environments: a program **A**, requiring libraries **B and C** can be installed this way: ```sh /usr/awesome-slot/bin/A /usr/awesome-slot/lib/B /usr/awesome-slot/lib/C ``` In this example, the `slot` is named **awesome-slot**, providing an execution environment for A no matter the OS version of *B* and *C*. **Without slotting** *basically, your life sucks*
Let's take an example with software provided by a non-official repository on a Linux distribution. You add a non-official repository for my-overly-awesome-game to your Debian system. This newly installed program will be in `/usr/bin`, as every other program. 1. What if the game requires libraries?
These libraries are installed in `/usr/lib`. 2. What if the game requires libraries that are not in the official repository?
Either the repository for my-overly-awesome-game provides them directly, or you can find another repository providing them. In both cases these libraries will end-up in `/usr/lib`. **With slotting** *your're awesome*
With slotting, the program will be in `/usr/`my-overly-awesome-game`/bin`. 1. What if the game requires libraries?
If these libraries are available in the `BaguetteOS` repository, they will be installed in your base system. 2. What if the game requires libraries that aren't available in the official `BaguetteOS` repository?
Either the game slot provides them, or they are in another slot. In both cases the base system won't change. Besides essential programs such as `coreutils` which are in `/bin` and `/sbin`, all official OS packages are installed in the slot named `baguette` (`/usr/baguette/`). Any non-official package is in another slot. Wanna support Python 2.7 **for life**? Just maintain a `python-2.7` slot and tell the world! If BaguetteOS does not provide the libraries required for the continuous support of your application, just add them in your slot. **Slotting is nothing new, however it is usually not used directly in OSs, whereas it may be the best way to handle the problem.** ### Why not use *X*? Others are doing slotting too: snap, flatpak, cpanm, pip, go, stack, cabal... *the list seems endless*
They all use slotting... *but*. Since they are *yet another package manager for your system*, you need to install all your software dependencies from their own dependency tree. You have now a shit-ton of ways to get software updates, and for *almost* all of them, it's just giving up the idea of having people testing the software before providing it. **Having an alternate package manager for your system is a fancy way of saying:**
*"I trust all the developers more than my OS maintainers. And fuck testing, who needs that anyway."* - **snap**
Snap maintains a `/snap` directory on your system, everything is in there. They even go to a slotting **per recipe version**, which is *kinda* per application version. See the readme in `/snap/README`, does it ring a bell? ``` /snap/bin - Symlinks to snap applications. /snap// - Mountpoint for snap content. /snap//current - Symlink to current revision, if enabled. ``` - **flatpak**: same as `snap` - cpanm, pip, stack, cabal, go... and other **developer tools**
These are tools for developers to overcome the relatively slow process of providing a library in an OS. But this process is **slow for a reason**, taking shortcuts is not safe. wanna the updates at all cost *But, BaguetteOS... I still need my last version of Blah!* We gotcha buddy.
You wanna go fast? Try sonic the fast slot: `/usr/sonic`. With this slot, the BaguetteOS maintainers provide the last versions of a variety of applications and libraries. You will have bleeding-edge technologies and bugs. You're welcome! ### How slotting works in BaguetteOS **Applications and libraries provided by BaguetteOS.**
For all official OS versions of the applications and libraries, `BaguetteOS` will provide them in `/usr/baguette`, the `baguette` slot. In case several versions of a library are provided, they will be slotted. For example, `LLVM` is provided in several versions (8, 9 and 10), only the most recent is in `baguette`. ```zsh $ ls /usr /usr/baguette /usr/llvm-8 /usr/llvm-9 ``` **Applications and libraries provided by third parties.**
`BaguetteOS` allows third parties to provide their applications and libraries easily by creating repositories, but they have to be slotted. For example, to provide a specific `nodejs` version, the following convention must be used: ```zsh /usr/$application-$version/ ``` ### How to use slots and install new repositories **Use a slot.**
`BaguetteOS` comes with a `/etc/profile` script, adding the functions `prefix_add` and `prefix_del` to your shell. For example, if you want to use an application in the slot `my-awesome-app`, type: ```sh $ prefix_add my-awesome-app ``` This will change your `$PATH`, allowing you to run applications in `/usr/my-awesome-app`: ```sh $ echo $PATH /bin:/usr/baguette/bin:/usr/local/bin:/usr/my-awesome-app/bin ``` **Install a new repository.**
A new repository can be used after adding its address in `/etc/package.conf`: ``` # File `/etc/package.conf` # Default repositories https://repos.baguette.netlib.re/$arch/ # Add your repositories here https://repos.my-awesome-app.com/$arch/ ``` You can then update your list of packages and install your application: ```zsh # package update # package install my-awesome-app ``` That's all folks! [service]: https://git.baguette.netlib.re/Baguette/service [package]: https://git.baguette.netlib.re/Baguette/package [packaging]: https://git.baguette.netlib.re/Baguette/packaging [build.zsh]: https://git.baguette.netlib.re/Baguette/build.zsh [libipc]: https://git.baguette.netlib.re/Baguette/libipc [todod]: https://git.baguette.netlib.re/Baguette/todod [webhooksd]: https://git.baguette.netlib.re/Baguette/ [tap-aggregator]: https://git.baguette.netlib.re/Baguette/tap-aggregator [baguette-gitea]: https://git.baguette.netlib.re/ [baguette-rc]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/rc [baguette-profile]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/rc/profile [recipes]: https://git.baguette.netlib.re/Baguette/recipes/ [recipe-hello]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/hello/recipe.spec [recipe-dhcpcd]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/dhcpcd/recipe.spec [recipe-alsautils]: https://git.baguette.netlib.re/Baguette/recipes/src/branch/master/alsa-utils/recipe.spec [autotools]: https://www.gnu.org/software/automake/manual/html_node/Autotools-Introduction.html [toybox]: http://www.landley.net/toybox/ [cruxinit]: https://crux.nu/gitweb/?p=ports/core.git;a=blob;f=rc/rc;h=26b8ca08d67208ceda4d4004c8333d362bcdc689;hb=HEAD [ksh]: https://github.com/att/ast [zsh]: https://www.zsh.org/ [libarchive]: https://libarchive.org/ [bsdcpio]: https://libarchive.org/ [bsdtar]: https://libarchive.org/ [m4]: https://www.gnu.org/software/m4/m4.html [gmake]: https://www.gnu.org/software/make/ [proot]: https://man.openbsd.org/proot [crinja]: https://github.com/straight-shoota/crinja [zig]: https://ziglang.org/ [openbsd]: https://openbsd.org/ [pfsense]: https://www.pfsense.org/ [alpine]: https://alpinelinux.org/ [crux]: https://crux.nu/ [inferno]: http://www.vitanuova.com/inferno/index.html [plan9]: https://9p.io/plan9/index.html [morpheus]: https://morpheus.2f30.org/ [suckless]: https://suckless.org/ [cat-v]: http://cat-v.org/ [working-service-asciinema]: https://asciinema.org/a/0p2vGNA1TUmvq0s61Lu0r4TN6 [ruby-memory-bp]: https://web.archive.org/web/20160329122617/http://blog.rubybestpractices.com/posts/ewong/005-Avoiding-system-calls.html [scdoc]: https://git.sr.ht/~sircmpwn/scdoc [pledge]: https://man.openbsd.org/pledge.2 [unveil]: https://man.openbsd.org/unveil.2 [retguard]: https://undeadly.org/cgi?action=article&sid=20170819230157 [cveqemu]: https://www.cvedetails.com/vulnerability-list.php?vendor_id=7506&product_id=0&version_id=0&page=1&hasexp=0&opdos=0&opec=0&opov=0&opcsrf=0&opgpriv=0&opsqli=0&opxss=0&opdirt=0&opmemc=0&ophttprs=0&opbyp=0&opfileinc=0&opginf=0&cvssscoremin=0&cvssscoremax=0&year=0&cweid=0&order=1&trc=276&sha=6055b0330a499f6aed7620adb79dc0cc143e50bc