I sighted increasing interest to my project Bash Booster last week. There
is a lot of links, tweets, discussions over the Internet. So, I think I have
to write this post to clarify what Bash Booster is and what it isn’t.
First of all, I am definitely not devop. However I played this role at the
begin of last summer. This is how it happened. I finished my project,
and had to wait while Thumbtack’s sales team was signing a contract of
a new one. At that time, another team went into production and they needed
help. Because I had nothing to do, I joined the team as a devop engineer.
I had to write Chef recipes for AWS OpsWorks to deploy and manage
application cluster. It was my first and last time I was using Chef.
Chef is awesome thing, but IMO it is too complicated. I spent a week looking
into it. I think, it is mainly because of Chef documentation. I guess, it
had been written by marketing-oriented assholes. I understand their goals,
you can buy support, and they will make you happy. But if you decide to
make it work by your own... Well, there is nobody to blame. Another reason
is that Chef is written in Ruby (at least some of its components). The fact
itself is not bad. However, in my experience, rubists don’t give a shit about
backward compatibility. If Ruby is not your primary tool, get ready to
shamanic dance. The most stuff does not work on Ruby shipped with your favorite
distributive, because it’s too old. It is also very possible that it
will not work on the most recent version, because this version breaks
backward compatibility.
Despite all of these, I got working cluster after three weeks. And Chef
have done its work perfectly. It is a good tool for devops, sysadmins, and
everyone who works with dozens of servers. However, using it for provisioning
single Vagrant virtual machine is overkill, it is like hunting a fly with
sledgehammer.
When this project was done, my new one had been postponed, and I decided to
go to vacation. But before it happened, I had joined to another team for a
couple of days. They asked me to set up developing environment using Vagrant.
I had written provisioning script using Bash, and went to booze trip into
Kazakhstan.
In the middle of the vacation, I reviewed this script. It had been written in
Chef recipe style. I didn’t think about it when I was writing it. But in fact
Chef’s philosophy influenced me. So I decide to prove a crazy idea—write
a Bash version of Chef subset.
As I wrote above, I am not devop, I am developer. I do not work with dozens
of servers. It would rather an exception, when I had to. However, it is
my normal routine when I have to setup single server for development purposes.
It is also usual to me to share my virtual machines with teammates. So it is
obvious, that I intensively use Vagrant. Because it is the best tool for such
tasks.
Additionally, I do not like overcomplicated tools, which enforce end user
set up various dependencies, write config files, and so on. And learning time
is also critical to me. Ideally, it should be zero hours.
So, Bash is such tool. Everybody knows it, and it is installed everywhere.
BTW, this fact have played Old Harry with Bash recently. I mean ShellShock
vulnerability. But anyway, I decided to make a provisioning tool using Bash.
So this is how Bash Booster was born.
It does not include any remote execution feature, because I do not need it.
It does not try to cover all existent package managers, because I mainly use
Debian-based and RedHat-based distributives. So support of Apt and Yum is
enough for me. I also did not try, to unify these two ones. Because similar
packages have different names in Apt and Yum, anyway you will have to check
what manager do you use. So I applied JavaScript approach: test for feature,
instead of version. That is why there are functions bb-apt? and
bb-yum?.
I also like readability. Because of readability there is a lot of short
functions of 1–2 LOC like this one:
bb-apt-package?() {
local PACKAGE=$1
dpkg -s "$PACKAGE" 2> /dev/null | grep -q '^Status:.\+installed'
}
I can use $1 variable directly, but assignment to $PACKAGE means
that this function accepts single argument—package name. It is for self
documenting. The black magic spell of the second line... Well, I do not want
to see it in my final script. After a month I would have to find out what does
it mean. And I would hardly reproduce it in the next script. So let it
live in the library.
The main feature of Bash Booster is delayed events. It helps to avoid
unnecessary operations. That is why sync module does not use rsync
(I got a lot of criticism about it). It is not about coping files and
directories, it is for triggering events when target and destination files
are different.
In short, I solved my practical tasks developing Bash Booster. It is definitely
not a Chef substitution. You can not manage a server park using it.
It is not useful in writing universal platform-agnostic scripts.
But if you need a little bit more than simple Bash script, especially when you
need event driven Bash script, it will be helpful for you.
Moreover, if you missed something, I will be happy to merge your
pull request.