Monday, 30 March 2015

Converting an EC2 AMI to a VirtualBox .vdi

http://church.cs.virginia.edu/genprog/index.php/Converting_an_EC2_AMI_to_a_VirtualBox_.vdi

This README explains how to take a disk image of a Fedora machine from Amazon's EC2 environment and convert it into a .vdi that VirtualBox will boot and let you play with.

Make a new raw drive file

This one is ~10 gigs:
> dd if=/dev/zero of=newimage.raw bs=1M count=10240

Partition it

First, add it to a loopback device:
> losetup -fv newimage.raw
Loop device is /dev/loop0 
Next, partition it (this makes one partition for the whole disk). Make sure it's bootable. The defaults are otherwise fine.
> cfdisk /dev/loop0
Note: You need to actually select Write and hit enter for this to work or you'll Quit without actually partitioning it, which I do every. Time.

Create a filesystem

You can't use mkfs because it screws up its automatic determination of filesystem sizes on loopback devices. Instead, find the partition beginning, end, number of blocks, number of cylinders, and blocksize:
> fdisk -l -u /dev/loop0
Disk /dev/loop0: 10.7 GB, 10737418240 bytes
255 heads, 63 sectors/track, 1305 cylinders, total 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x00000000

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *          63    20964824    10482381   83  Linux

Calculate the beginning of the partition x blocksize. In this case (in most, actually), it's 512 * 63 (sector size * start sector): 32256. Setup a new loopback device for this partition by specifying an offset:
> losetup -fv -o 32256 newimage.raw
Loop device is /dev/loop1
You're going to create a filesystem now with a some block size (probably 4096, which is standard and what I use) and a number of blocks that you compute with: ((end - start) * units) / blocksize, or ((20964824 - 63) * 512) / 4096, in our case.
To create the filesystem on our new partition:
> mkfs.ext3 -b 4096 /dev/loop1 2620595

Copy and prepare the new filesystem

First, set up the .raw image also as a loopback device:
> losetup -fv genprog-raw-image.raw
Loop device is /dev/loop2
Mount it:
> mkdir /mnt/tmp_1
> mount -t ext3 /dev/loop2 /mnt/tmp_1
Do the same for your new image:
> mkdir -p /mnt/loop/1
> mount -t ext3 /dev/loop1 /mnt/loop/1
> cp -a /mnt/tmp_1/* /mnt/loop/1/
The instructions from the website I grabbed this all from suggests you need to copy over boot modules to get the initrd and kernel info, but for some reason I don't think I had to do this.

Various modifications before adding a bootloader

Edit menu.lst and make sure that the root= is set to /dev/sda1: (the root= substring is pretty randomly located)
> vi /mnt/loop/1/boot/grub/menu.lst
Edit fstab for the same purpose (replace /dev/xfvg with /dev/sda1):
> vi /mnt/loop1/etc/fstab
Amazon sets a random root password, which won't do. Instead:
> chroot /mnt/loop/1
> mv /etc/rc.local /etc/rc.local-old
> passwd root
> exit

Set up Grub on the new drive

Unmount and delete the loopback device with the partition (the one with the offset) so Grub will work without complaining:
> umount /mnt/loop/1
> losetup -d /mnt/loop1
Refer back to the info from fdisk, above (> fdisk -l -u /dev/loop0) and get the number of cylinders, heads, and sectors/track. Then do:
> grub --device-map=/dev/null
You'll enter an interactive Grub thing.
grub> device (hd0) newimage.raw
grub> geometry (hd0) 1305 255 63
grub> root (hd0,0)
grub> setup (hd0)
You'll get a lot of output, then:
Done.
grub> quit
Unmount the mounted drives and delete all your loopback devices. Notes: umount unmounts. Why there's no n is beyond me. Also, losetup -a lists all active loopback devices.
> losetup -d /dev/loop0
> losetup -d /dev/loop1
> losetup -d /dev/loop2

Make VirtualBox play nice

It's still a .raw, yes? Convert:
> VBoxManage convertdd newimage.raw newimage.vdi
(I think convertfromraw works too b/c convertdd is for backwards-compatability.)
Use the newimage.vdi in making a new VirtualBox machine. Do the default stuff, but open up settings, select System -> Processor and set the checkbox next to Enable PAE/NX.
Edit /etc/ssh/sshd_config and change the part that says "PasswordAuthentication" or whatever from no to yes.
Shutdown the vm. Back at the command line, to enable sshing in:
> VBoxManage modifyvm "VM name" --natpf1 "guestssh,tcp,,2222,,22"
This will forward requests to the host machine's port 2222 to the guest machine's port 22 (where ssh listening happens by default). To ssh in, do:
> ssh -p 2222 root@localhost

No comments:

Post a Comment