Warning: I've done no testing of this script on anything other than my own machine. Take care when running these scripts, as they can result in wiping the wrong disk if you are not careful. You've been warned.
To speed up imaging of disks instead of using dd and copying the whole thing (including blocks that are just full of zeroes), we can use partclone to be more intelligent about things. This is a two step process, first we must prepare the image to something partclone knows how to use, and then we can restore it to our disks.
apt-get install partclone fdisk mount
Once you've downloaded a contest image, you must first prepare it. This process runs partclone to create optimized images of the partitions, basically only including the blocks that are used.
python3 prepare_image.py midatlantic-2024-02-16_image-amd64.img
This should take maybe 20 minutes or so and create some new files in the directory.
Use the included restore_image.sh
script to re-assemble these parts back onto a flash drive. Edit line 14 to match the image name you ran the prepare script on, then you can invoke it as something like:
./restore_image.sh /dev/sde # Replacing /dev/sde with your usb flash drive
On my system using usb3 ports and usb3 drive(Sandisk Cruzer Ultra Flair 32GB), this restore process takes a little bit under 15 minutes.
WARNING Here be dragons, I make no claims that this might work anywhere else/I don't have any other systems to test on.
Because I'm lazy, figuring out which drive id and invoking commands manually is a pain (and I typically have to image ~100+ usb drives), I have some other scripts that use udev to watch for usb hotplug events, and trigger the scripts above automatically.
The basic process is to figure out what your usb ports map to in udev (see detect_ports.py), and then run a script that watches a specific port and runs a command whenever a device is plugged into it.
These python scripts require pyudev, which seems like it's available as apt-get install python3-pyudev
, but I can't be certain as I use a virtualenv for it.
Invoking this script will watch for all usb hotplug events, and print out some path identifier. So the way to use this is to start the script, then plug a usb drive into each port you want to use, then wait for it to print the identifier out.
For example, the front 4 ports on my desktop output the following:
$ python detect_ports.py
Kingston DataTraveler 3.0 at /dev/sde (port /devices/pci0000:00/0000:00:14.0/usb3/3-1/3-1:1.0/host6/target6:0:0/6:0:0:0/block/sde)
Kingston DataTraveler 3.0 at /dev/sde (port /devices/pci0000:00/0000:00:14.0/usb3/3-2/3-2:1.0/host6/target6:0:0/6:0:0:0/block/sde)
Kingston DataTraveler 3.0 at /dev/sde (port /devices/pci0000:00/0000:00:14.0/usb2/2-6/2-6:1.0/host6/target6:0:0/6:0:0:0/block/sde)
Kingston DataTraveler 3.0 at /dev/sde (port /devices/pci0000:00/0000:00:14.0/usb2/2-5/2-5:1.0/host6/target6:0:0/6:0:0:0/block/sde)
Take the identifiers from detect_ports.py, strip off some suffix on it (I'm not 100% sure what the rule for how much to cut off is, but see the script for examples), and plug it into the portmapping dictionary at the top of clonedisk.py.
Then you can invoke clonedisk.py (as root) with an argument like python clonedisk.py Port_2 $PWD/restore_image.sh
. Plug a drive into that port, and watch as it kicks off the restore_image script. I usually add some more output to the restore_image script to make it clear when the drive is finished.
With a usb hub, I'm usually able to do about 8 drives at a time, and finish imaging all 100+ drives over the course of a day or so.