Raspberry Pi SD Card Cloning

Instead of setting up a new Raspberry Pi by hand each time I need one, I only do it once. I get all of the basic stuff I prefer installed and configured, including things like GPU memory split, enabling the SSH server, connecting to a wireless network, etc. My setup may be different than yours, but the idea is the same. Once you get things to a point where you are happy with the configuration, and you don't want to go through all of those steps again, it's time to stop and make a clone of your SD card.

Disclaimer

The information presented below is for Linux and OS X only. If you're running Windows, I'm sorry. I don't know much about that. The good news is that Ubuntu is free (and awesome) so you might consider setting up dual boot. Ultimately it's worth it because working with the Pi is so much easier this way.


Cloning with Linux

After shutting down your Raspberry Pi, remove the SD card and plug it into your computer's card reader. First verify and make a note of the /dev/ node where the card is mounted. This is very important to ensure you don't accidentally perform operations on the wrong disk.

df -h

The next command will clone the entire SD card into a single file on your computer. Keep in mind that this file will end up being the same size as the SD card you are cloning. For example, an 8GB card will create an 8GB file. It's also worth noting that because of the file size this step will take a little longer than you might expect to run. Also, it's a good idea to keep all of your Raspberry Pi images in a single directory. After making a new directory, cd into it before running this command. In the snippet below, replace "x" as needed based on the result of the previous command.

sudo dd if=/dev/sdx of=raspberry_pi.img bs=1M

Cloning with OS X

After shutting down your Raspberry Pi, remove the SD card and plug it into your computer's card reader. First verify and make a note of the /dev/ node where the card is mounted. This is very important to ensure you don't accidentally perform operations on the wrong disk.

diskutil list

The next command will clone the entire SD card into a single file on your computer. Keep in mind that this file will end up being the same size as the SD card you are cloning. For example, an 8GB card will create an 8GB file. It's also worth noting that because of the file size this step will take a little longer than you might expect to run. Also, it's a good idea to keep all of your Raspberry Pi images in a single directory. After making a new directory, cd into it before running this command. In the snippet below, replace "x" as needed based on the result of the previous command.

sudo dd if=/dev/rdiskx of=raspberry_pi.img bs=1m
 

Try it out

If you're like me, you probably want to try writing your new disk image onto a blank SD card as soon as it's done. I like to see things work. It helps me sleep at night. Starting in the directory where your SD image file is saved, insert a new SD card and use the following steps.


Writing with Linux

Just like before, first verify and make a note of the /dev/ node where the card is mounted. This is very important to ensure you don't accidentally perform operations on the wrong disk.

df -h

Next, unmount the SD card so that it can be overwritten with the image file. In the snippet below, replace "x" as needed based on the result of the previous command.

umount /dev/sbx

This last command will write the contents of the image file onto your SD card. This may take a little longer than you might expect depending on the size of the image file. Again, replace "x" as needed the same as before.

sudo dd if=raspberry_pi.img of=/dev/sdx

Writing with OS X

Just like before, first verify and make a note of the /dev/ node where the card is mounted. This is very important to ensure you don't accidentally perform operations on the wrong disk.

diskutil list

Next, unmount the SD card so that it can be overwritten with the image file. In the snippet below, replace "x" as needed based on the result of the previous command.

diskutil unmountDisk /dev/diskx

This last command will write the contents of the image file onto your SD card. This may take a little longer than you might expect depending on the size of the image file. Again, replace "x" as needed the same as before.

sudo dd if=raspberry_pi.img of=/dev/rdiskx bs=1m
 
 

Now what?

If you're feeling especially lazy, check out my personal setup script on Github: https://github.com/projectweekend/Pi-Setup. It will have you up and running in no time with a great starting point for your first SD card clone.

It's Time

I'm officially shutting down the Project Weekend site. I had a blast building it and it was even more fun as a creative outlet working together with a very dear friend. It was my first solo web project and I learned so much from it. I wouldn't be where I am today had I not slaved over that thing for countless hours. Having said all of that, it's time to scrap it and apply those resources elsewhere.

Azure Mobile Services and Custom Authentication

Over the last few weeks at the office, I've been working on a JSON API project that is hosted using Microsoft Azure Mobile Services. The decision to use this platform wasn't mine, but at least it hasn't been as bad as I originally though it would be. So far, I've had to make a few small concessions to the way I would normally do things. I expected as much given the way Microsoft has attempted to hide many under-the-hood elements of a Node.js project. With that said, it wasn't until today that this framework made me do something "hackish" in order to accomplish my task.

This MSDN blog post leads a developer to believe that the referenced "extensions.startup" script guarantees "complete control over your application", with the power to implement "custom routes, middleware or even use socket.io to do realtime communication". The part that caught my eye here was middleware. Since none of the built-in authentication providers offered by Azure Mobile Services fit the project's needs, I was going to implement one using express-jwt. It looked great on paper, but turned out to be impossible.

The main problem with any code defined in the "extensions.startup" script is that it doesn't actually get executed until after rest of the project's middleware and URL router (which you have no access to since you never get to implement your own server.js/app.js file). This makes it impossible to register middleware intended to intercept all incoming requests in the normal way:

app.use( myMiddleware );

However, fortunately for you I spent half a day trying all sorts of suggested hacks I stumbled across on the Internet. When none of them worked, I took a step back, consulted the Express API documentation, and found something I could use. After Express registers the router, an object containing all the routing info, with each handler callback can be found at:

app.routes;

Using this I was able to iterate through all routes and push my custom middleware function onto the front of the callback stack for each. It worked great so I made a Gist with an example of the "startup.js" file for the project. You'll notice below that I ended up abandoning express-jwt, even though I found a way to add my middleware. That's because Azure's implementation of the Node/Express project doesn't handle the validation errors thrown by express-jwt properly. Instead on returning the appropriate 400/401 codes it throws a 500.  Oh well, I've never been afraid to roll my own. ;)