3

I do a lot of experimentation on my rPi and I frequently want to wipe the OS and start clean. However, there are a number of things that I want installed/ configured no matter what I'm doing on the pi. For example I always want vim on there and I would like it to have a static IP and the credentials neccesary for wifi (the list goes on, but you get the point).

Is there anyway that I can image the SD card (or something like that) so that when I wipe it to start clean I can just mount that image to the micro SD? It would save me a bunch of time getting up and running with new projects.

angussidney
  • 703
  • 9
  • 20
E.T.
  • 33
  • 3

2 Answers2

4

TL;DR -> Skip to "In a nutshell..." at the bottom.

Raw device and filesystem images (.iso or .img or .raw -- they all colloquially refer to the same general concept) are usually created with dd, and you will find many, many examples of this online. For example:

dd if=/dev/sda2 of=fs.img

Will create an image of the filesystem on /dev/sda2; on the pi this is usually the root filesystem (unless you are using NOOBs or some other multi-partition system). This can then be copied back out:

dd if=fs.img of=/dev/sda2

This concept is very copiously described over and over again online, particularly with reference to the pi, so I will not delve into the tweaks which might speed the process (namely, setting the block size via bs=) except to say that they do not matter with regard to the state of the image itself, so you can try whatever you like.

Note that usually these discussions refer to copying the whole card (/dev/sda) and not just the second partition (/dev/sda2).

I've used the latter arbitrarily to to introduce the distinction between "device" and "partition" (or filesystem; technically a partition is something that contains a filesystem, but for our purposes they are synonymous). With regard to the above example:

  • Copying the image back to the partition will completely destroy whatever is on it, and you cannot do this on a running system where that is the root fs.
  • Obviously fs.img can't be on the filesystem in /dev/sda2, because it will
    1. Run out of space.
    2. Change the content of what you are copying while you are copying it.

dd is very straightforward, and many people stop there because it is easy to understand and use.

Another option is copy/sync the filesystem contents (i.e., the files and directory hierarchies it contains), in which case if the system is running there are certain things you absolutely do not want to copy. The reasoning behind that is described here, with reference to maintaining a backup with rsync, which is initially more complex than using dd but also quicker and more flexible (for starters, you can update the backup from the running system without worrying about inconsistencies, and you don't have to copy all X GBs every time).

Creating a base image that you can redeploy later is pretty similar to maintaining a backup, except you don't need to maintain it as much, and you probably want to store it in an image format you can quickly copy to a card with dd. There's a explanation of how pi oriented device images are structured here and here; the second one elaborates upon the first one and refers back to the answer about rsync. If you read these you should be able to understand how to mount partitions from inside device images. When you do that, you can change the content of a filesystem, unmount it, and the content of the device image it is inside of will have changed.

So, you can do that with a virgin SD card image and rsync your changes into it. This can be updated it at any point quickly, without having to shut the pi down or take the card out. You do need some attached or remote storage for the backup/base image, obviously.


In a nutshell, drawing from stuff in the above links, working from a running pi, and assuming we have the original whatever.img from which you made your SD card on external / remote storage (since it won't fit on the card itself):

  • Mount the partitions using something like this (see that answer again, particularly if you get an "overlapping loop" error):

    mount -v -o offset=4194304 -t vfat whatever.img /mnt/img/one
    mount -v -o offset=62914560 -t ext4 whatever.img /mnt/img/two
    
  • Update the first parition, which is normally boot:

    rsync -aHv --delete /boot /mnt/img/one
    
  • Next the root fs:

    rsync -axHv --delete / /mnt/img/two
    

    Note the x and make sure to actually read this to understand the significance.

Unmount both partitions and presto, whatever.img is now updated to contain what you've added to the pi.

goldilocks
  • 56,430
  • 17
  • 109
  • 217
3

You have a couple of options here:

You could install the prerequisites and then image/backup the card; when you need to start fresh again you would flash your custom image not the base image.This answer will show how to backup your current card.

Second you could install puppet/chef/ansible and create manifests or cookbooks (as they are called) to provision your system with your prerequisites (I am using puppet for this purpose). It does not even need a puppet master as you can run puppet apply on the Pi, as long as puppet and its dependencies are installed which you can do with: sudo apt-get install puppet. You can even create a basic shell script to install puppet and its dependencies with a single command.

The first method is perhaps easier, but is more time consuming. The second requires more of a learning curve but is more customizable (you could change what network settings, packages, services and hostnames etc. were installed each time, and is more scalable. You can learn more about puppet here. They have great documentation, including a tutorial that makes use of a virtual machine. Chef and ansible, which I am less familiar with, have similar resources and tutorials a quick google search should turn up plenty of resources for both.

Steve Robillard
  • 34,158
  • 17
  • 102
  • 108