Running CLI tools like ansible often requires a specific environment with dependencies on the core operating system libraries. That makes it hard to run different versions in parallel – or test the newest updates. And it might clutter the OS. Toolbox offers simple container management to avoid these shortcomings.
The recent development of Linux distributions has seen a shift away from all-purpose distributions towards stable core distributions with limited packages and additional sand-boxed tooling running on top to enable management of applications. One of the most advanced distributions here is for sure Fedora Silverblue, but even the enterprise distribution Red Hat Enterprise Linux 8 brings a lot of changes which aim into the right direction. Technologies in this context are for example rpm-ostree for the management of immutable OS images and Flatpak for the management of GUI applications. Additionally, RHEL 8 comes along with so called app-streams – and of course there is always the option of using containers with for example podman.
In this blog post I want to focus on the last one: using containers to manage your CLI tools, thus keeping them independent of your operating system packaging and libraries. With Fedora and RHEL, there is tooling provided which makes this even easier: Toolbox.
The basic idea for using containers, and especially Toolbox, is similar to the one about Flatpak: it solves many problems of the Linux packaging problem. This means essentially:
- Independence from OS libraries and their versions
- Sand-boxing, meaning better protection of the OS
- Multi-version support
- Less OS clutter through isolated installation of dependencies
- Easy to recreate environments (think of “works on my machine”)
- Immutable environments possible
Think of it that way: with complex applications, behavior sometimes depends on certain versions of some libraries. When those are managed by the OS packaging system, it is hard to keep them up2date or just in the same version across multiple machines, not to speak about multiple distributions. Also, I don’t want my OS to be cluttered with weird dependencies which I might not even trust just to justify a weird application’s requirements. And I might want to install different versions of a tool to test them, – with different libraries as well, which is often impossible with OS package management.
In comes Toolbox:
Toolbox is a tool that offers a familiar package based environment for developing and debugging software that runs fully unprivileged using Podman.
The toolbox container is a fully mutable container; when you see yum install ansible for example, that’s something you can do inside your toolbox container, without affecting the base operating system.Toolbox on Github
While Toolbox is particularly interesting for immutable systems like Fedora Silverblue, it even makes sense to run it on other distributions. I started using it on my regular Fedora for example just to have certain tools available in certain versions for tests.
And why use Toolbox, and not just the usual container tools? Toolbox takes care of volume mounting and all the other necessary bits of container management, and enables you to just use a very basic set of commands to create – and reuse – your tool containers. It is simpler and easier than always typing in fully fledged podman or docker commands all the time.
You can read more about Toolbox in the Fedora Silverblue Toolbox docs or the Red Hat Enterprise Linux 8 Toolbox docs.
It is very easy to get started with Toolbox. First, it needs to be installed on the system. For example, on Fedora 31, this can be done via:
$ sudo dnf install toolbox
After that, you are good to go. Since the idea is to have re-usable containers, let’s create the first. In my example I want to have a container with the newest Ansible version to run some automation. So we just create a new container called ansible:
$ toolbox create --container ansible Image required to create toolbox container. Download registry.fedoraproject.org/f31/fedora-toolbox:31 (500MB)? [y/N]: y Created container: ansible
As you see, a base image for my distribution was downloaded, and the container created. Next, let’s access it and look around:
$ toolbox enter --container ansible Welcome to the Toolbox; a container where you can install and run all your tools. - Use DNF in the usual manner to install command line tools. - To create a new tools container, run 'toolbox create'. For more information, see the documentation. ⬢[liquidat@toolbox ~]$
We are greeted with a short message and then dropped to a shell. Note the bubble at the start of the command prompt – a nice touch to differentiate if you are inside a toolbox or not. Next, let’s look at our environment:
⬢[liquidat@toolbox ~]$ pwd /home/liquidat ⬢[liquidat@toolbox ~]$ ls bin development documents downloads ... ⬢[liquidat@toolbox ~]$ ls / README.md bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var ⬢[liquidat@toolbox ~]$ cat /README.md # Toolbox — Unprivileged development environment [Toolbox](https://github.com/debarshiray/toolbox) is a tool that offers a [...]
As you see, the toolbox has actual access to the file system. That way we can use the tools just like normal shell tools, interact with things we have in our environment. However, at the same time we have limited access to the root system since we see the container root system (as identified by the readme), not the host root system.
Getting my first tool ready
As mentioned I’d like to have a container with the newest Ansible. Let’s install it:
⬢[liquidat@toolbox ~]$ pip install --user ansible Collecting ansible Using cached https://files.pythonhosted.org/packages/ae/b7/c717363f767f7af33d90af9458d5f1e0960db9c2393a6c221c2ce97ad1aa/ansible-2.9.6.tar.gz Collecting jinja2 (from ansible) [...] Running setup.py install for ansible … done Successfully installed MarkupSafe-1.1.1 PyYAML-5.3 ansible-2.9.6 cffi-1.14.0 cryptography-2.8 jinja2-2.11.1 pycparser-2.20 ⬢[liquidat@toolbox ~]$ ansible --version ansible 2.9.6 config file = /home/liquidat/.ansible.cfg configured module search path = ['/home/liquidat/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/liquidat/.local/lib/python3.7/site-packages/ansible executable location = /home/liquidat/.local/bin/ansible python version = 3.7.6 (default, Jan 30 2020, 09:44:41) [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)]
As you see, Ansible was properly installed. And with this we are already done – we have our first tool ready, name “ansible”.
Using our tool
Now let’s assume I use the container for some things, exit it – and want to reuse it later on. This is no problem at all, since that is exactly what Toolbox was built for. And we have a name, which makes it fairly easy to remember how to access it. But even if we do not remember the name, we can easily list all available tools:
$ toolbox list IMAGE ID IMAGE NAME CREATED 64e68e194389 registry.fedoraproject.org/f31/fedora-toolbox:31 2 weeks ago CONTAINER ID CONTAINER NAME CREATED STATUS IMAGE NAME 8ec117845e06 ansible 47 minutes ago Up 47 minutes ago registry.fedoraproject.org/f31/fedora-toolbox:31 $ toolbox enter -c ansible ⬢[liquidat@toolbox ~]$ ansible --version ansible 2.9.6 config file = /home/liquidat/.ansible.cfg configured module search path = ['/home/liquidat/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules'] ansible python module location = /home/liquidat/.local/lib/python3.7/site-packages/ansible executable location = /home/liquidat/.local/bin/ansible python version = 3.7.6 (default, Jan 30 2020, 09:44:41) [GCC 9.2.1 20190827 (Red Hat 9.2.1-1)]
As you see the container is in the same state as we left it: Ansible is still installed in the proper way, and ready to be used. And we can do this now with all kinds of other tools: be it another version of Ansible, or even some daemon we want to experiment with. It can all be easily installed and run and re-used, without worrying of cluttering the OS, or having the wrong library versions installed, or not being able to update some library because of a system dependency.
Toolbox is an interesting approach to simplify container management to fool around with CLI based tools. If you have an immutable environment like Fedora Silverblue, it might become a crucial piece in your daily operations since it is a pain to install additional packages on top of Silverblue’s ostree infrastructure. But even for “normal” distributions it is worth a try!