Infestation is a portable environment manager currently implemented as a makefile.
Infestation allows a user to install specific versions of all their favorite apps and their dot (configuration) files wherever they go regardless of host operating system or architecture or root privileges.
Why?
As a consultant, I’m often called in to fix clients’ server problems. When I’m responsible for building a server, I would make an ansible playbook with all the server config and store it in a shared git repo for easy reference if something needs to be fixed, but often I’m fixing servers strung together by other developers, which means spending time discovering how things are already configured.
Unfortunately, many of these servers are configured with the stock shell (sh/bash) stock vim configs, no tmux etc, etc, which means I spend up to the first hour of the project just trying to get to a point where I can feel productive.
Previously, I’ve tried both Ansible and Bash scripts for configuration, but neither was quite right, because other than having to handle specific distributions and different versions (IE if ubuntu apt-get install git if centos && version >= 6 then yum install git-core) I also had to account for weird edge cases like the stock terminal having unexpected opts set that I had to check for and deal with.
I figured there had to be a distribution agnostic way to get in setup my environment in one or two commands and get to work.
My first idea was docker, I figured I could create a docker container that was exactly how I wanted it to be with all my apps and configs, but
- I need root access to install docker (which I don’t always have / want)
- docker only works on Linux (I support and use OSX as well)
- realistically a client might not want docker installed on their server and always running.
But docker gave me a good idea, basically docker is LXC containers, which is basically a chroot jail, is there a way I could build a chroot jail without using a (persistent, privileged) runtime?
Long story not so short, the answer is yes, turns out there is a neat tool called proot
that allows you to create a chroot jail without having root access as well, it doesn’t need to run all the time.
But that’s only half the equation. The second problem was how do I ship apps around in my chroot? I initially thought I could just ship binaries, but of course not all bins are statically linked and that introduces me to dependency hell (something I care deeply about avoiding.)
Then I remember, hey there is this great package called nix that I love, maybe I can ship the package manager and the dependencies I want to be installed as a nix config and ba da bing ba da boom, I’d have a dependency free portable environment.
Installation
Right now it’s a proof of concept to show that it can work, check out https://www.github.com/edude03/infestation if you’re interested in editing the makefile to get it to work.
Right now it depends on you having a directory structure like so
$ tree
dotfiles-master (assuming your git repo is 'dotfiles' and you clone the master branch)
├── nix
│ └── config.nix (this contains the apps you want to be installed)
└── zsh
├── .zsh
│ ├── antibody.zsh
│ ├── plugins.txt
etc etc
Next Steps
As mentioned his is just a POC, the plan going forward is to build a statically linked app with all the functionality needed to set up the environment (git, HTTP(s) client, busy box (maybe) to implement the core utils, etc)
Once that’s done, I’ll implement a templating language allowing users to write scripts for custom dependencies (in my case, antibody)
FAQ
Q: Aren’t you depending on the host system having bash, make and wget to install this?
A: At the moment yes, for the sake of getting the POC done it was built as a Makefile with some fairly common dependencies (though notably OSX doesn’t ship with wget). In the future, the plan is to implement the Makefile as a statically linked rust binary with a git client, an HTTP client, the ability to create the symlinks etc etc
Q: Aren’t you depending on the arch matching your binaries, the system having and having internet connection, a kernel that supports proot etc etc
A: Sure, I doubt I can ever get it completely zero dependency (don’t I have to depend on the client having a server and internet connection har-har ) however the concept is to rely on the lowest common denominator, and over time, build more functionality into the install to rely less and less on the host.