Upgrading Atlassian Applications via Ansible

Over the next few weeks, I’ll be doing write-ups on how I upgrade some of our developer tools. Specifically, I’ll focus on the Atlassian applications I manage, but the process for our other tools (like Artifactory, SonarQube, etc.) is largely the same and most of the Ansible Roles are common across all of the applications.

For now, the playbooks and roles will not be available but I’ll post relevant snippets where I feel it’s needed.

Finally, we use RHEL/CentOS internally (for hosting our internal tools, we have other OSes for doing builds) so our playbooks are oriented towards a single OS.

 

Curb Cuts

I was listening to the 99PI from last week and it reminded me of a childhood friend who had MS. Unfortunately, he passed away a few years ago.

He was a year younger than I was but we both had a mutual love of video games. I remember carrying him up my front porch and setting him into a computer chair so I could roll him to the TV. We played games for hours. When he needed to go home, I’d carry him back to his chair and he’d head out. I have fond memories of playing Halo and Baldor’s Gate.

Unfortunately, we grew apart once I got involved with cars and girls and we stopped spending time together.

Jonathon, I miss you and I hope we meet again some day.

Take care.

 

Building Something from Nothing

It’s pretty cool to build something that people grow to rely on. It’s also a little terrifying for someone like me who has a habit of second guessing decisions and who tends to be risk adverse.

A few years back, the developer who writes our installers made changes to enable them to run in headless mode. To facilitate testing, I wrote a small PowerShell script that ran through the basic installation steps that our engineers and QA followed manually. My goal was to give this script to our QA department so they could download the build from our build system and with a few parameters, run this script against their testing environments to perform an upgrade.

We demoed it to our R&D organization. We showed how it could be tied into the build system so that when the build was completed, it could kick off a “deployment” job that would upgrade environments. It was pretty straightforward: Download the build binaries into a folder called “artifacts” in a sibling directory to the said script and then execute the script with a few parameters.

For over a year, no one really bit. My colleague and I just used it for installer testing, mostly. That’s not completely true. There were a few QA teams that decided to start using it, but if I had to guess, the automated upgrade script was being used for approximately one in twenty test environments.

At some point, the organization began to build out a performance testing team. They had requirements around automating the deployment of environments with more than one server. They were trying to replicate how our application was run in production environments, which meant that there might be dozens of VMs running different portions of our product.

Well, perhaps unfortunately for them, I was the only person really fooling with ways to automate the deployment of the product. I took their requirements and changed my script so that you could give it all the same parameters as before but also give it a “run mode” flag that’d tell it what kind of work it’d be doing. For example, perhaps you wanted to stop or start all of the application services, or just update the database, or maybe just install a subset of the products functionality againt the target VM. I (quite kludgily, if that’s a word) added that functionality to the existing script all while sticking to my original goal: Have a single PowerShell script that a user could run from anywhere with just a few parameters.

No one bit and the requester exited the company shortly thereafter.

Around the time I was asked to extend the functionality of my script, other teams began researching how to build out full automation for our SaaS environments. I sat with them and went over what I had devised. Obviously, what I had would not scale but I at least had sorted out the process to upgrade an environment and scripted it out. They began building a large, scalable automation system. I later found out that for several months my script was tucked inside their automation system doing some of the heavy lifting until they had re-written everything.

One day out of the blue, my manager sent me a link to a repository the performance team owned that had taken the script I had written and began developing additional tooling to coordinate their use case of large scale deployments. At the core, it was calling my script to do all of the installation work. I was both elated and annoyed. It felt like my work, which had largely been ignored or dismissed as being insufficient was being used and built on for bigger and better things. Additionally, the only direct proof that this was my code was a single comment left in the script that had my name and email and some commit messages vaguely referring to my repository.

In short, it felt like a group of engineers grabbed my work, tweaked a couple things, and ran with it without giving credit where credit was due. Still, swallowed my pride quick. The other side of the coin was this: I had built something that was seen as worthy of being reused. I had never done that before. Never mind that I was never hired as a developer. I came onto the build team through a string of transfers / promotions and built the script in my spare time. It wasn’t robust. It wasn’t easily extendable. It was not built with any solid patterns. My goal was to write a single, portable tool that people could use to upgrade their single environments with and it had grown into something much, MUCH larger.

Now days, it’s used to upgrade several dozen testing environments including several large multi VM product environments each day, some several times a day. Though I’ve never measured it, I’m positive It has by now given hundreds and hundreds of hours back to the engineering team and rescued them from a boring, thankless, and sometimes tedious task.

I learned a lot from building my automation tool. There’s a lot I wish I had done differently, but that’s okay. It’s in maintenance mode these days, it mostly does everything that it’s ever been asked to do, and it continues to be relied on two years after I demoed it initially. People keep waxing poetic about a replacement but it hasn’t happened yet.

EDIT: I recently came across another instance of this code being used without attribution (which is fine, but goes against the spirit of code sharing) for some tools being shipped to a customer. 😐

 

Jimmy Martin

You really gotta hunt for the good life.

Jimmy Martin was a popular bluegrass musician from the 1950’s and 1960’s. Despite being a renowned and beloved musician, he was snubbed by the Grand Ole Opry because of his problems with alcohol. The quote above was his voicemail message before he passed away.

 

Determine What Files Changed Between Two Releases

I get asked this a lot. Luckily, Git makes it pretty easy to get this information, but sometimes you need to string together multiple commands to do this gracefully.

Here’s the meat and potatoes:

git diff --name-only REVISION1..REVISION2 desired/sub/directory

What if you don’t have the revision/commit but instead a branch name? And what if that branch name has a / in it? Well, you’ll find that this command fails. It throws a generic ambiguous argument error. How would you get around this? Easy! Find the revision/commit of that branch. How? Check out the branch, make sure it’s the latest revision, and determine the revision/commit ID.

How this can be accomplished in Bash:

git checkout BRANCH/NAME && git pull origin BRANCH/NAME
REV_ID=$(git rev-parse HEAD)

But who added the file and what is the associated work item? STOP MOVING THE GOAL POST! Still, that’s fairly easy, too. Just pull the last commit to each file that’s returned in the diff command. Below is a simple Bash script that will generate this information:

BRANCH_A=release/9.2.0.0
BRANCH_B=release/9.3.0.0
REPO_DIR=/path/to/cloned/repo
CHECK_DIR=sub/path/to/desired/dir

cd $REPO_DIR
git fetch

git checkout $BRANCH_A && git pull origin $BRANCH_A
COMMIT_A=$(git rev-parse HEAD)

git checkout $BRANCH_B && git pull origin $BRANCH_B
COMMIT_B=$(git rev-parse HEAD)

FILE_LIST=$(git diff --name-only $COMMIT_A..$COMMIT_B $CHECK_DIR)

echo "FROM - $BRANCH_A"
echo "TO - $BRANCH_B"
for FILENAME in $FILE_LIST;
do
 echo $FILENAME
 git log -n 1 --pretty=short -- $FILENAME
done
 

Seneca VI

I haven’t posted anything in awhile, however I read this today from The Shortness of Life and I felt like it needed to be documented. I’m not sure this one requires much fleshing out or additional work to tease the meaning out. I’ll just present this by it’s self and let the reader be the judge.

I am often filled with wonder when I see some men demanding the time of others and those from whom they ask it most indulgent. Both of them fix their eyes on the object of the request for time, neither of them on the time itself; just as if what is asked were nothing, what is given, nothing. Men trifle with the most precious thing in the world; but they are blind to it because it is an incorporeal thing, because it does not come beneath the sight of the eyes, and for this reason it is counted a very cheap thing—nay, of almost no value at all. Men set very great store by pensions and doles, and for these they hire out their labour or service or effort. But no one sets a value on time; all use it lavishly as if it cost nothing. But see how these same people clasp the knees of physicians if they fall ill and the danger of death draws nearer, see how ready they are, if threatened with capital punishment, to spend all their possessions in order to live! So great is the inconsistency of their feelings. But if each one could have the number of his future years set before him as is possible in the case of the years that have passed, how alarmed those would be who saw only a few remaining, how sparing of them would they be! And yet it is easy to dispense an amount that is assured, no matter how small it may be; but that must be guarded more carefully which will fail you know not when.

Yet there is no reason for you to suppose that these people do not know how precious a thing time is; for to those whom they love most devotedly they have a habit of saying that they are ready to give them a part of their own years. And they do give it, without realizing it; but the result of their giving is that they themselves suffer loss without adding to the years of their dear ones. But the very thing they do not know is whether they are suffering loss; therefore, the removal of something that is lost without being noticed they find is bearable. Yet no one will bring back the years, no one will bestow you once more on yourself. Life will follow the path it started upon, and will neither reverse nor check its course; it will make no noise, it will not remind you of its swiftness. Silent it will glide on; it will not prolong itself at the command of a king, or at the applause of the populace. Just as it was started on its first day, so it will run; nowhere will it turn aside, nowhere will it delay. And what will be the result? You have been engrossed, life hastens by; meanwhile death will be at hand, for which, willy nilly, you must find leisure.

 

Martin Luther King

It’s all right to tell a man to lift himself by his own bootstraps, but it is cruel jest to say to a bootless man that he ought to lift himself by his own bootstraps.

I think all he was trying to say is that when you start with nothing and there are systems specifically crafted to ensure that you continue to have nothing, it’s not reasonable to expect that this will just work it’s way out by dint of hard work or perseverance. We’re still struggling to right this ship fifty years later, but I believe we’re trending in the right direction, even if the last year or so has been a set back for some people.

To that end, I spent my morning cleaning up one of the first integrated cemeteries in Atlanta. Today is not a vacation or a day off of work. It’s a day for reflection and giving something back to your community.

 

Gun Violence

The politics as I see them in a nutshell:

Democrats say that gun violence is a symptom of easy access to powerful firearms, inequality, and mental health issues. Their prescription is increasing the background checks and/or barring access to particularly powerful and/or large numbers of weapons and increasing investment in healthcare by way of ACA.

Republicans say that gun violence is a symptom of mental health issues. Their prescription? I haven’t heard one. Perhaps prayer.

You can stand on either side of the fence, but you have to admit that there is a stark incongruency in the response offered by the two parties. Republicans recognize that there’s a problem but offer no solution. You can disagree with the prescribed fix, but you cannot agree with inaction assuming you believe this is a real problem. Not doing something is admitting that you’d rather, to use a rather apt euphemism, stick to your guns than try to resolve a problem you recognize as legitimate. I will never recognize the bloodletting of innocent bystanders as being a just, necessary price to pay to uphold 2A.

Full disclosure: I vote Democrat. I own guns. I appreciate the point of 2A (as ineffective and insane as a civil uprising would be in todays day and age). I support things like stronger background checks, purchasing limits, mandatory safety training for firearm ownership, removing the “gun show loophole.”

 

Seneca V

Philosophy is good advice; and no one can give advice at the top of his lungs.

 

Seneca IV

A single tree is not remarkable if the whole forest rises to the same height.