Mission Impossible Code - Compact, Idempotent, DevOps Oriented, Multi-Distro Package Installer Script for Linux and Mac

Search for a command to run...

No comments yet. Be the first to comment.
In the most recent Mission Impossible Live Coding event, Jefferson and I convert the GitHub Action Super-Linter to run in GitLab CI. This is a summary of lessons learned and pointers to the results. So Jefferson and I worked through this approach. Be...
Why Least Privilege Security Engineering Is Frequently Skipped or Done Loosely In a previous life, I was on a team that reviewed the IAM policies specified by developers when they created new Cloud applications or required additional permissions for ...

Obscuring sensitive information like AWS account IDs in screenshots and videos is tedious and error-prone. Even with video editing tools that simplify the process, I still have to repeatedly add and remove blurring boxes as the view changes. You know...

AWS CloudShell joins the ranks of hostless shells for operating in your cloud environment. Cloud shells are a huge help to training and enablement scenarios because they remove the pain of fussy configuration of a user-owned endpoint - which can have...

This article is the third and final of a series. Part 1 justified that human-performed DevOps checklists are essentially source code, and according to GitOps principles, belong in Git just like any other code required for successfully managing a soft...

There are always those who feel checklists are an unnecessary waste of time because they think they can always remember the basics of the steps involved to complete a task. Many are also not aware of the huge, cross-discipline benefits that can come ...

Everyone loves Linux for its ability to stick to fundamentals and common platform expectations. Except those of us who do a lot of deployment automation.
Why? Two main reasons: In a world of stripped back distros (think containers), even fundamental Gnu coreutils and other basics can be missing. Which leads to the second frustration - for some reason distro families thought it would be great to not only innovate package management technology but also change up the command set and also not provide a universal command set (like an api) to hide the differences.
So after bashing my head on this a million times, a bit of bash code eventually emerged (yeah from my head). And as you’ll read, it was not a process of random chance and natural selection - but rather it’s opposite - hyper-engineering.
As per Mission Impossible Code Principles I’ve tried to make it “as simple as possible, but still have a very broad scope of reuse”
FYI - Windows isn’t any better - while Windows PackageManagement (aka OneGet) and Chocolatey both tried to consolidate down to one command set for all package types for the platform, we now have a third one.
I used to take time to expand the section “Architecture Heuristics” and discuss the enablement created by each of the bullets in the section.
I won’t be doing that any longer for these reasons:
This section appears in many Mission Impossible Code samples because it: 1) Demonstrates there is an actual pattern to the thinking underlying this approach, 2) It allows you to learn the patterns but making the thinking plain, 3) It shows the complex engineering of creating simplicity.
The following list demonstrates the Architectural thrust of the solution. This approach is intended to be pure to simplicity of operation and maintenance, rather than purity of a language or framework or development methodology. It is also intended to have the least possible dependencies. It’s an approach I call “Mission Impossible Coding” because it enables the code to get it’s job done no matter what.
New versions of the code are not synced to the below article insert, please use the repository link below to get the latest.
function ifcmdmissing-instpkg () {
#If you don't need brew, this can be much more compact by removing the relevant code
#If command is not on path, installs the package
#detects package managers: apt, yum and brew
if [[ -n "$(command -v brew)" ]] ; then
#Detect package manager, brew first because some macOSes have an apt-get stub
PKGMGR='brew'
elif [[ -n "$(command -v yum)" ]] ; then
PKGMGR='yum'
elif [[ -n "$(command -v apt-get)" ]] ; then
PKGMGR='apt-get'
fi
for cmdpkg in $1 ; do
IFS=':' read -ra CMDPKGPAIR <<<"${cmdpkg}"
CMDNAME=${CMDPKGPAIR[0]}
PKGNAME=${CMDPKGPAIR[1]}
echo "If command ${CMDNAME} is not on path, the package ${PKGNAME} will be installed."
if [[ -n "$(command -v ${CMDNAME})" ]]; then
echo " '${CMDNAME}' command already present"
else
echo " Missing command '${CMDNAME}'"
echo " Installing package '${PKGNAME}' to resolve missing command."
if [[ $PKGMGR != 'brew' ]]; then
if [[ $PKGMGR == 'apt-get' ]]; then $PKGMGR update; fi;
$PKGMGR install -y ${PKGNAME}
else
#automatically abstract the difference between brew taps and casks
if brew info ${PKGNAME} >/dev/null 2>&1; then
brew install ${PKGNAME} --force
elif brew cask info ${PKGNAME} >/dev/null 2>&1; then
brew cask install ${PKGNAME} --force
else
echo " '${PKGNAME}' not found as a formulae or cask"
fi
fi
fi
done
}
ifcmdmissing-instpkg "jq:jq wget:wget curl:curl"
Mission Impossible Code samples are intended to be both 1) usable directly for production use and 2) a top notch pattern to use for your own innovation. More details on this approach are in the post
While epitomized by the Blaise Pascal quote “I have made this longer than usual because I have not had the time to make it shorter.”, I find that the process of creating concise, simple observations and solutions is complicated and sometimes complex.
Creating concise designs and solutions is a deep passion of mine. However, there is a frustration that is quick on the heals of creating something that is concise. In my line of work, at some point, you usually have to justify your final work. That is the point at which the rest of the iceberg of thinking that backs the concise tip comes to the fore. Frequently the reaction is that it can’t possibly be that involved or that you are spinning up reasons on the fly to simply bolster an idea or solution that was arrived at haphazardly.
Why bother addressing this sentiment? Because concise, mission impossible style, solutions can easily be criticized as lacking sophistication in their implementation. But much like a Mark Twain quote - that ruddy external appearance belies a hard wrought balance of many interrelated tradeoffs to get to a simple solution.
Said another way, solutions that are earnestly designed for conciseness can be rewarded by a perception of being the opposite of what they are - simplistic, backed with little or no thought.
This Mission Impossible Coding series exposes the submerged methodological icebergs below the waterline of the visible and concise solutions it attempts to arrive at.