= How I manage installed packages

Linux makes it easy to track software on servers and workstations.
Package management has been a part of Linux very early in the operating system's life, and the tool set has been perfected over decades.
There's no reason that even a total system rebuild should require any more than one quick Ansible playbook or shell script to get back to its previous state.
Even though Linux has robust package management, though, new software for Linux is released all the time, and not all of is integrated with the system's package manager.
However, it doesn't take much beyond a little organization and consistency to ensure that even application outliers are well accounted for.

Here are the 5 tactics I use to track applications installed on my fleet.

== 1. List packages with RPM

Do the easy one first.
RHEL, CentOS, Fedora, and several others catalogue all supported software as RPM packages, and usually the `dnf` command is the best interface to that manifest.
However, getting a dump of all installed packages can be achieved with just the `rpm` command:

[source,bash]
----
$ rpm --query --all
publicsuffix-list-dafsa-20190417-4.noarch
ncurses-base-6.2-3.20200222.noarch
libssh-config-0.9.5-1.noarch
kbd-misc-2.3.0-2.noarch
[...]
----

That's a lot of information, and it's specific to the versions of packages installed on a system you may be anticipating on upgrading.
I find its output even more useful when I look the full package information, coupled with a simple https://www.redhat.com/sysadmin/beginners-guide-gawk[awk] command to extract just the package name:

[source,bash]
----
$ rpm --query --all --info | \
awk --field-separator ': ' '/^Name/ {print $2;}'
publicsuffix-list-dafsa
ncurses-base
libssh-config
kbd-misc
[...]
----

The advantage of getting a package name without the version is that you can pipe the whole list into `dnf` on an upgraded system, and `dnf` doesn't fail due to mismatched version numbers.

== 2. Flatpakrefs

The Flatpak system makes it trivial for even non-administrative users to install applications on workstations in a safe way.
It also makes reporting on what's installed trivial:

[source,bash]
----
$ flatpak list --app --columns=application | head -n-1
im.element.Element
io.github.Cockatrice.cockatrice
net.scribus.Scribus
org.audacityteam.Audacity
org.inkscape.Inkscape
org.kde.kdenlive
org.kde.krita
org.signal.Signal
org.synfig.SynfigStudio
[...]
----

This reports on just applications installed as a Flatpak, not runtimes.
Installing an application as a Flatpak also installs its required runtime, so I don't bother reporting on installed runtimes.

Flatpaks are usually installed to the user environment but with root privileges they can also be installed to the system.
If you're auditing what's been installed, keep that in mind.

Finally, Flatpaks don't all necessarily come from the same repository.
When in doubt, you can see what Flatpak remotes have been added to a system with the `flatpak remotes` command.

== 3. Outliers

Some vendors provide software for Linux as plain old tarballs, or as self-extracting scripts with embedded "install wizards" that unarchive its components to the system location of your choosing.
Whether you use `/usr/local` or `/opt` or some other location, make sure you make the outlier location a strict standard within the organization.

These are the hardest to track, and it takes discipline.
You have to define a process for installing to `/opt` (or whatever location you use), and part of that process must be keeping a log.
In my experience, many of the applications I end up installing to `/opt` also happen to be applications that require a license, so I keep a copy of the tarball or installer in a central directory along with the licensing information.
(But don't let that create a loophole where applications installed to `/opt` without licenses never logged.)

== 4. SDKMAN and Maven and Pip and Node and Cargo

Many popular languages have package managers of their own now.
Luckily, these tend to restrict themselves to a user's environment.
The best way to deal with language-specific package managers is for developers to actually use them.
These tools are designed to be _all the big words_: programmatic, ephemeral, and idempotent.
Reinforce with your developers that their environments are meant to be easy to replicate.
As long as their code is pushed to the organization's version control system, it should be self-migratory.

== 5. The stuff you almost forgot

I'm a testament to just how customized a home directory can become.
There are scripts I've written and thrown into my personal `~/bin` directory that I've sometimes forgotten weren't just default Linux commands.
It can be genuinely difficult to separate actual Linux from _your_ Linux, and that's actually why people use Linux.
You want it to be yours, and an organization often needs Linux to be uniquely crafted for its needs.

The key is to keep track of what's yours.

At some point, that useful script everyone's shared around the office isn't just a useful script, it's a product of the organization.
Encourage its maintainer to give it a version number, commit it to Git, and package it up so it can be included in the upgrade process.

== Be aware

Tracking applications in your organization is often a matter of being aware of what's being used, whether it's an officially supported package or something surprisingly useful that an intern drummed up while accidentally learning Python one day.
And knowing the right tools to get full reports about applications on your systems is vital to and consistent upgrade or recovery.