Scheduled Job Anti-Patterns - We Don't Need Version Control

Tags: programming devops

Scheduled jobs tend to suck a bit. They’re usually written after they’re needed and dropped into place with little testing and no plans for fixing them when things go pear-shaped.

This is the third in the series. Here’s the full list that we’ll cover:

It’s just a script, we don’t need version control

If you ever say these words to me as I’m cleaning up a mess caused by you making a “non-impacting change” to a scheduled job that isn’t under version control, then you’re going to see a look come across my face. Behind that look, my brain is calmly keeping my hands from reaching for the nearest blunt object while mentally filing you away as “someone who’s lucky to have a job in IT” and trying to figure out how to best extract ourselves from the mess we’re in. My brain’s multitasking just isn’t good enough to do those things and maintain a poker face. Sorry.

This is what happens when you say that version control isn’t necessary.

-rwxr-xr-x   1 jobsuser jobsuser    6805 Mar  7  2012 sales_prod_export.pl
-rwxr-xr-x   1 jobsuser jobsuser    7.6K Jul 10  2010 sales_prod_export_maint2_2.pl
-rwxr-xr-x   1 jobsuser jobsuser    7.7K Jun 16  2010 sales_prod_export_maint2.pl
-rwxr-xr-x   1 jobsuser jobsuser    7.7K Jun  1  2010 sales_prod_export_maint.pl
-rwxr-xr-x   1 jobsuser jobsuser    2270 Mar 10  2010 sales_prod_export_work.pl
-rwxr-xr-x   1 jobsuser jobsuser   15043 Mar 24  2012 sales_prod_force_send.pl
-rwxr-xr-x   1 jobsuser jobsuser   12564 Aug 26 04:24 sales_prod_verify.pl
-rwxr-xr-x   1 root     root       15659 Jul 19 19:52 sales_prod_verify.pl.bkp
-rwxr-xr-x   1 jobsuser jobsuser   12568 Sep 12 20:32 sales_prod_verify_maint.pl
-rwxr-xr-x   1 jobsuser jobsuser     16K Sep  3  2010 sales_prod_verify_maint2.pl
-rwxr-xr-x   1 jobsuser jobsuser     14K Jun 30 22:02 sales_prod_verify_maint_new_20120629.pl
-rwxr-xr-x   1 jobsuser jobsuser     16K Jun 30 21:55 sales_prod_verify_maint_new.pl
-rwxr-xr-x   1 root     root         16K Mar  1  2012 sales_prod_verify_maint_tim_just_this_once_20110809.pl
-rwxr-xr-x   1 jobsuser jobsuser     16K Aug 10  2011 sales_prod_verify_maint_tim_since_that_is_the_fashionable_thing_to_do.pl
-rwxr-xr-x   1 root     root         16K Jan 29  2011 sales_prod_verify_maint_variable.pl
-rwxr-xr-x   1 jobsuser jobsuser     13K Jun 29  2011 sales_prod_verify_maint_vsmith.pl
-rwxr-xr-x   1 jobsuser jobsuser   16207 Aug 13 15:34 sales_prod_verify-yesterday.pl

There are 17 copies of this one script. That’s dumb. This is a fictionalized real world example, so I’m going to stand up straight and take credit for these two here:

  • sales_prod_verify_maint_tim_just_this_once_20110809.pl
  • sales_prod_verify_maint_tim_since_that_is_the_fashionable_thing_to_do.pl

The sarcasm was lost on this system’s maintainer. Either that, or his brain’s multitasking managed to keep a straight face while he pondered the quickest way to punch me in the nuts and get away with it.

Version Control is too Easy

Version control is too easy not to use for the scripts and configurations that keep your shop humming. You may not trust that statement if your last encounter with version control involved CVS or, to a lesser extent, Subversion, but I swear to you that it is true.

Distributed version control systems let you set up repositories on a local system without ever interacting with a central server. You don’t need to request a new repository from the version control gatekeepers, you just need to init a new repository in place. For bonus points you’re going to back this repository up to a remote location, but that’s outside of our scope here today.

Right now you just need to pick one of the two following tools:

They both work just about everywhere that matters today, and they behave nearly identically for the stuff we’ll be doing. If you have developers on staff or as friends, ask them what they use. Otherwise, flip a coin.

Once you have the binaries installed, you’re only a few commands away from version controlled bliss. We’ll walk through creating a repository, seeing the status of the repository, committing unsaved changes, and reviewing the change log below.

With mercurial:

$ hg init 
$ hg status
? really_important_script.sh
$ hg add
adding really_important_script.sh
$ hg commit -m "Committing really_important_script.sh so we don't lose changes like last time." 
$ hg log 
changeset:   0:0d058a3f5c18
tag:         tip
user:        Tim Freund <tim@freunds.net>
date:        Sat Oct 13 16:09:06 2012 -0500
summary:     Committing really_important_script.sh so we don't lose changes like last time.

And with git:

$ git init
Initialized empty Git repository in /Users/tim/src/dvcsdemo/git/.git/
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   really_important_script.sh
nothing added to commit but untracked files present (use "git add" to track)
$ git add really_important_script.sh 
$ git commit -m "Committing really_important_script.sh so we don't lose changes like last time."
[master (root-commit) 9d9f3d1] Committing really_important_script.sh so we don't lose changes like last time.
 0 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 really_important_script.sh
$ git log
commit 9d9f3d12eaa3d56a9bf0e12364c411baafed2753
Author: Tim Freund <tim@freunds.net>
Date:   Sat Oct 13 16:10:02 2012 -0500

    Committing really_important_script.sh so we don't lose changes like last time.

And that’s really all there is to it. Every time you make a change to your scripts, simply commit the changes before you move on to your next task. You’ll eventually want to learn how to revert to previous versions and share your repositories with others, but just doing what we’ve worked through today will set you up for success when making changes to scripts.