Thoughts and opinions of a technology enthusiast.

Challenge: Ship-It August

I’ve set a goal for myself. Deliver something of value every day in August. I realize 31-straight days is probably unrealistic, especially since I’m moving at the end of the month, but nevertheless the die is cast.

Ultimately I want to have at least 31 pieces of content, code, scripts, blog posts, etc. that I can be proud of by the end of the month. I’ll keep the list here so feel free to follow my progress. I’ll also tweet updates with the #shipit hashtag. :)

Progress Update: 5 Items Shipped

  1. 2013-08-01: Blog Post: RAID Your Storage – Ubuntu School
  2. 2013-08-01: Script: DDNS Script on GitHub
  3. 2013-08-01: Blog Post: Point the Way Home – DDNS with Linode
  4. 2013-08-02: Blog Post: Dynamic DNS with Linode API
  5. 2013-08-02: Blog Post: Challenge: Ship-It August

Dynamic DNS with Linode API

Yesterday I posted an article up on Knightwise.com detailing a very small script I put together to enhance my quality of life.

My pointing a DNS entry for one of my domains back to the public IP of my home network I am able to more easily “phone home” when I’m out and about. While not a major issue most of the time, it does provide some added flexibility and security knowing I could create a nice encrypted SSH tunnel from whatever polluted WiFi network I’m on back to my nice clean DSL connection at home.

If you’re interested you can read the article Point The Way Home on the knightwise.com blog.

If all you want is the shell script, you can grab the gist from my GitHub account.

RAID Your Storage – Ubuntu School

I recently upgraded my server machine (see the recent server posts) and one of the things I decided to do was provide a bit of local redundancy, so I put in a RAID array to help protect against local disk failure.

Before I go any further, let me be clear. RAID is not backup. I know this. It’s finicky and still represents a single volume for storing your data. The case can be made that RAID is potentially worse than just storing your data on the bare disks. I decided to try it out anyway as a means of protecting against disk failure — presumably I can lose a single disk from my array and not lose any data. I do still have backups in place to protect against data loss. The array represents the second copy of a three storage medium system for my important data.

The one additional wrinkle I had with my setup is that I wasn’t starting with a brand new system. I was going to be migrating data from a single 2TB disk, into a new RAID-5 array composed of three 2TB disks, one of which currently contained the data to be pushed to the array.

For the purposes of this article, the three disks in my system are:

  • /dev/sdb — The disk with the existing data
  • /dev/sdc — Empty disk #1
  • /dev/sdd — Empty disk #2

First off the two empty disks need to be partitioned so that the system can use them in the array. This is done by using the fdisk command to prepare the disks with a brand new empty primary partition.

Once this is complete, repeat for the second disk, /dev/sdd

Before we get into the data dance, the first step is to get the tools installed to allow your Ubuntu system to deal with a multi-disk volume. The first tool you need is mdadm which is the system used to administer multi-disk volumes.

Now here’s where the magic of RAID starts. Because our array will contain a disk which already has data on it, we won’t be able to wipe that disk to prepare it for use in the array. This is where we can use the properties of RAID itself to do some of the work for us. When a disk in a RAID-5 array fails the remaining disks take over and allow the data to remain accessible until a replacement disk can be inserted into the array (or until enough disks fail that the data is unrecoverable.)

We can use this property to our advantage by creating the 3-disk array in a degraded state. In other words we’ll create a 3-disk array with only two disks. By using the mdadm command below, we can create the array with a missing disk:

Once that’s done we can create a new filesystem on the new RAID volume.

Then we’ll create a folder to use as the mount-point for the array.

And mount the new RAID volume to its new home.

We also need to mount the single disk to its home as well.

Once this is done all of the data from the single disk can be migrated to the RAID array.

This transfer took about 5 hours on my system to migrate 1.4 TB of data from the single disk to the array. Once that was done. I did some spot checks on the data in the array to make sure it was intact. Everything seemed to be ok.

The next step was to unmount the single disk.

Once this is done the disk can be added to the array.

Once the final disk has been added to the array it will remain in a degraded state until all of the storage and parity blocks are in place across all of the disks in the array. Once complete, you’ll be up and running and a bit more protected against disk failure.

Use nano to Edit Mac Crontab

If you want to change the editor for modifying your Mac’s crontab file from the cryptic yet powerful vim, to the vastly simpler nano, follow these steps:

  1. If you don’t already have a .bash_profile file in your home directory, create one
  2. Add the following line to that file: export EDITOR=nano
  3. Save the file, close any open terminals and open a new one.
  4. Type crontab -e in the terminal and you should have your crontab file open in nano.

Make New Directories Inherit The Parent Group – Ubuntu School

This is a quick one, but one I’ve had to look up a number of times. I constantly run into issues on my backup drives and SMB shares of new files not properly inheriting the parent group-owner. This has the effect of me needing to run the chgrp -R command on large swaths of files to align things.

There is, of course, a better way. If you want all new files and directories under a given parent to inherit the parent’s group owner, you just need to set the sticky bit.

sudo chmod -R g+s /path/to/parent

That’s it! Now all new directories and files inside the parent directory will have the same group owner as the parent directory.

Reload Mounted Volumes from fstab

If you make a change to the /etc/fstab file in Ubuntu (or most Linux distributions for that matter) you will need to refresh your system for the changes to take effect. The most common way to do this is to reboot the machine:

sudo shutdown -r now

However, a restart isn’t necessarily required. You can simply remount everything in your file system table with the command:

sudo mount -a

Easy peasy!

The Problem to Be Solved

Before working on any new project it’s important to have a good grasp on just what ends you are trying to achieve. Accomplished podcaster and all-around good egg Allison Sherridan of the Nosillacast has a policy for product reviewers on her show: first, start with the problem to be solved. Since I believe this is a wise and logical course of action, the second post in the home technology series will do just that.

Let me just start with the caveat that I’m going to throw the word need around rather loosely for this post. I realize these are toys, for the most part. I could certainly survive without them, but these are toys and tools that I use in my day-to-day life pretty extensively, and a number of my personal hobbies and interests revolve around my ability to have these toys close at hand. So with that out of the way, here we go…

I’m setting up brand new infrastructure for the home. The client machines, for the most part, will remain unchanged (iPhone, iPad, Macbook Pro etc.) but the underlying infrastructure is going to be unavailable (for reasons which are immaterial to this post).

The needs I’ve identified so far are:

  • a router / wi-fi access point
  • a file server / NAS device
  • a set-top box for the living room
  • a location to run VMs
  • an SSH endpoint

Along with that are a couple of nice-to-haves:

  • a set-top box for the bedroom
  • a DNS server
  • a BitTorrent client daemon
  • a VPN server

Some other considerations I’ve come up with for the new equipment coming into the home:

  • low power usage
  • quiet
  • low-maintenance
  • open
  • free software (the Stallman kind, and the everyone else kind)

Under my previous network setup, I had a giant server box in my basement (ok not giant, but large) which handled the NAS, SSH, BitTorrent, DNS and VM duties. It did a lot, but was a standard Ubuntu installation which required the usual care and feeding. Everything also had to be set up and configured by hand so it took a while to get everything working the way I want, and moving that configuration to a new server in the future would be challenging.

I also don’t currently have a set-top box for streaming media on any of the TVs (unless you count getting a laptop to do the job temporarily). I also don’t have a VPN endpoint. The current VM management strategy is also challenging because it doesn’t have the polish or finish of a purpose-built VM solution.

Given the past challenges I’m thinking that the configuration I was using, though certainly workable at the time I set it up, doesn’t meet the needs I have going forward. I’ll explore some of the options in more detail in my next post.

Taking Stock

Quite some time ago I started a series of posts on setting up your own home server from scratch using a desktop PC running Ubuntu. The series was fairly popular and provided a good detailed look at just what it takes to get a home server going.

Well the server I built is going away and I find myself planning, once again, how best to address the computing needs of my household. It seems obvious to me that I **need** a server. I’ve had one for the past few years and it’s been very beneficial for a number of reasons. But times change, people change and computing needs do, in fact, change.

This series of posts is going to be as much for me as anything else. I figure if I write down my thought processes I might have a better chance of actually arriving at a decision because I’ve had a chance to externalize and review my own opinions about this project.

The first question I started to consider was one of hardware. It seemed a logical step — I have hardware going out, I’m going to need to bring some hardware back in. The real question is: what to buy? The answer, as any technology consultant will tell you, is: “it depends.”

The real first question, as I covered off in my first post about the last home server, is “what do you want the machine to do?” Until you can answer that, everything else is nothing more than a guessing game. So that’s where things sit for the moment. I need to ponder long and hard just what I need out of this replacement machine. There are a number of possible computing functions in my household. It’s undoubtedly time to take stock of the technology that I’ve already acquired and see where it all fits in relation to the needs and wants that I have.

Never Again – Enterprise Client Development

Never Again.


I know they say “never say never” but I can truly say that never again will I recommend trying to produce a piece of software for internal corporate use that is a desktop client. I’m done.

For the past two years I’ve been working on a project to create a new desktop client application to replace an old desktop client application. After two years of effort I have come to the conclusion that there had to have been a better way.

Building the software was a long and complex process, a bit longer and more complex than we anticipated, but overall it was manageable. We created an application that the team is proud of and we can’t wait to get the thing deployed so we can call this project done. Therin lies the rub. Deployment. The key difference between web applications and desktop clients – how do I get the software to my users?

We now have to get a piece of software pushed out to several hundred end users. The task sounds simple until you start to take into account the gotchas that accompany this simple task:

  1. Who needs the software?
  2. What is their machine name?
  3. Do they have all the pre-requisites?
  4. Will the pre-requisites break something they already have?
  5. How will you deploy it?
  6. Did you test all the possible software/hardware configurations?

Determining the first two items on the list is a lot harder than it sounds. Does everyone who needs to know actually know that this new software is coming? Do you have a good sense of the users of the current legacy system that your application is replacing? How old is the list of hostnames you’re working from? Is there actually any documentation for the old system? If so, has anyone validated it in the past 5 years?

Software pre-requisites are another nasty piece of business. Making sure that the libraries you have are licensed for deployment is important. If your users departments need to purchase licenses to use your software, did you tell them in advance? Did you now they wouldn’t already have that “standard” application installed? How impressed were they to take on an additonal $20K in software license fees in late September?

Beyond licensing the nastiness continues with deployment of the dependencies. Can they be pushed out the same way as your application? Do they require restarts? Do they need to be deployed before you can deploy your own application?

On top of that you may have certain versions of libraries that you’ve tested with your application and that you’ve used throughout the build and test process. If you’re working with a server-side web application you probably have full control of the environment you’ll deploy to in production. Not so with a client. You may not know you have an incompatibility until you start pushing your application out to actual users. Now what? You’re supposed to go live in less than a week and your product will cripple some critical application on the users’ machines.

Now that you have all that sorted out and you know how you’re going to deploy your application, the question is whether or not you’ve tested all of the permutations of hardware and software that could impact (or be impacted by) your application. Are your users on laptops or desktops? Are they running Windows XP or Windows 7? Are any of those Windows 7 machines running 64-bit versions of the OS? You did make sure your pre-requisites were all Windows 7 compatible, right? Do you need to package up a version of the .NET Framework or the JVM with your application? Do the users have any applications installed which rely on older (or newer) versions of the libraries you’re pushing out?

Oh, and you did realize that nearly half your user base is running in some sort of virtualized desktop environmnt, right? Do you know how to deploy to them? Will your software work properly in a virtualized environment?

Oh, and you did realize that about 20% of your users don’t ever come into the office right? You can deploy over someone’s low-bandwidth VPN connection, right?

These are all examples of questions that require solid answers before you can deploy a client application in an enterprise environment. The smaller the group, the easier it is. But if you have more than 100 end users or if any of them are in critical customer-facing roles you had better be damn sure you can answer all of these questions months before you plan to deploy. Otherwise you’ll be deploying months after you planned.

From now on I’ll be looking for web-based solutions to as many new application builds as possible. Going through the circus of trying to put software on my users’ machines is not an experience I care to repeat. In this increasingly heterogeneous world of multiple platforms, multiple operating systems and bring-your-own-device programs it is more important than ever to be able to consolidate the development effort to the server. It is a far simpler thing to deal with the quirks of a few browser versions than to worry about how many employees won’t be able to do their work the next time you release a software update.

The Winding Road of Procrastination

I sat down tonight to do some more learning about Ruby. I thought that I’d spend an hour or so and build something trivial, but useful. Well 90 minutes later and I have had an enjoyable evening, but I have yet to write a single line of Ruby code.

It started out with a Ruby tutorial which had a header on the first line with the standard directive pointing to the executable for the Ruby interpreter. That led me to realize I wasn’t 100% sure where that executable was on a Mac. I remembered that there was some kind of command to find these exectuables so off I went to Google. My search results led mt to a Perl primer describing the use of the which command.

Having used the which command on my Mac and finding that it gave me exactly what I was looking for, the next logical step would be to continue with the tutorial. Unfortunately, that’s not how my brain works. The next logical step for me was to put together a short blog post on the which command so that I would have a reference for myself at some future date.

Writing the blog post sent me to my terminal to test out the which command on my Ubuntu and CentOS machines to make sure it was a cross-platform as I thought. Research for the blog post also sent me to some documentation for which that I wanted to link in my article.

After posting the article I realized that the Markdown-to-HTML engine on my blog had converted the #!/usr/bin/ruby line in my blog post to a header because of the hash mark. This sent me in search of Markdown documentation which I found on the Markdown syntax page on Daring Fireball. I of course had to take a moment and peruse the DF site while I was there and found a reference to a recent episode of his podcast The Talk Show being sponsored by The Magazine.

Remembering that I had just subscribed to The Magazine earlier in the evening I picked up my iPhone to peruse the article titles and found that one was an update about The Magazine itself. Reading through that short update from Marco and that he had received tons of submissions for new article pitches reminded me that I had an article of my own to pitch. I fired up my email client and sent the pitch email off.

Remembering that I hadn’t yet fixed my typo I jumped back to my blog to correct the error. Glancing at my browser sidebar I looked at all the open tabs, then up at the clock and realized it had been over an hour since I had intended to write some Ruby code. Thinking back over the activities of the past hour I realized that an article about procrastination might have made an even better pitch. So I wrote this up and am going to send that in right now.