VirtualBox#
First Steps#
salt-call state.sls virtualbox
File > Preferences > Default Machine Folder:
~/VMs
Block Device to VM#
Use Case: Install any OS on a USB drive:
sudo fdisk -l
to find the drive, e.g./dev/sdd
Create a VM with this drive
mount an iso into the VM’s CD drive
install on the drive using the VM
profit
bash vbox_blockdevice_vm.sh /dev/sdd ~/isos/xubuntu-14.04.4-desktop-amd64.iso
Static IP on Linux Host#
Goal: make virtual machine (guest) available on your LAN
I own this place#
Change VM and router (dhcp server, dns server) settings, aka. “I own this place”.
the good: any PC on your LAN can access the VM under its name
the bad: you need full control over dhcp and dns in your network
change network settings of VM
Bridged
choose host interface that’s connected to the LAN
(if you did this before, click “settings symbol” and set old MAC address (see ifconfig of guest))
set “static” IP address
go to your DHCP server
set reserved IP for guest’s MAC address
(set name for guest’s “static” IP address)
boot VM, start ethernet with dhcp
e.g. via
/etc/network/interfaces
ifdown eth0
ifup eth0
I don’t need no host names#
Change VM only.
the good: easy setup
the bad: machines other that the host can access the guest only via its IP address
do I own this place, step 1
set static IP-address on guest in same subnet as host
adapt
/etc/hosts
on host
IP Address in /etc/issue#
cat<<'EOF' > /etc/issue.template
Ubuntu 12.04.1 LTS \n \l
username: root
password: toor
ip address: IP_ADDRESS
EOF
cp /etc/rc.local /var/backup/
# note the interface eth0 in the following block
cat<<'EOF' > /etc/rc.local
ip_address=`ifconfig eth0 | awk '/inet addr/ {print $2}' | cut -f2 -d:`
sed -e "s/IP_ADDRESS/$ip_address/" /etc/issue.template > /etc/issue
exit 0
EOF
Headless Guest#
starting point:
ubuntu_server_12.04.1_x64.ova
target:
salt-master
VM
Import an OVA and make a snapshot:
# list import options
vboxmanage import --dry-run ubuntu_server_12.04.1_x64.ova
# import
vboxmanage import ubuntu_server_12.04.1_x64.ova --vsys 0 --unit 4 --ignore --unit 5 --ignore --unit 7 --ignore --cpus 4 --memory 2048
vboxmanage showvminfo ubuntu_server_12.04.1_x64
# snapshot
vboxmanage snapshot ubuntu_server_12.04.1_x64 take "initial" --description "vanilla directly after ova import"
Clone a machine:
# linked clone
vboxmanage clonevm "ubuntu_server_12.04.1_x64" --snapshot "initial" --mode "machine" --options "link" --name "salt-master" --register
Start / Stop:
vboxmanage startvm salt-master --type headless
vboxmanage controlvm salt-master poweroff
Enable NAT, forward SSH and make a shortcut:
vboxmanage modifyvm salt-master --nic1 nat
add_public_forward() {
box=$1
host_port=$2
guest_port=$3
name="public-${local_port}-${guest_port}"
vboxmanage modifyvm $box --natpf1 "$name,tcp,,$host_port,,$guest_port"
}
remove_public_forward() {
box=$1
host_port=$2
guest_port=$3
name="public-${local_port}-${guest_port}"
vboxmanage modifyvm $box --natpf1 delete $name
}
add_local_forward() {
box=$1
host_port=$2
guest_port=$3
name="local-${local_port}-${guest_port}"
vboxmanage modifyvm $box --natpf1 "$name,tcp,127.0.0.1,$host_port,,$guest_port"
}
remove_local_forward() {
box=$1
host_port=$2
guest_port=$3
name="local-${local_port}-${guest_port}"
vboxmanage modifyvm $box --natpf1 delete $name
}
list_forwards() {
box=$1
vboxmanage showvminfo $box | grep Rule
}
add_local_forward salt-master 2222 22
# undo: remove_local_forward salt-master 2222 22
# ssh config
cat <<EOF >> ~/.ssh/config
Host salt-master
Hostname 127.0.0.1
Port $local_port
User root
EOF
Enable remote desktop (optional):
vboxmanage modifyvm salt-master --vrde on
vboxmanage modifyvm salt-master --vrdeauthtype external
username=felix
password=changeme
vboxmanage setextradata salt-master "VBoxAuthSimple/users/$username" $(vboxmanage internalcommands passwordhash "$password" | awk '{ print $3; }')
# undo on the fly: vboxmanage controlvm salt-master vrde off
# undo when down: vboxmanage modifyvm salt-master --vrde off
Check ports openend by us:
netstat -anp | grep 222
netstat -anp | grep 3389
For inter-machine networking, add internal network named close-circle
on NIC 2 and enable dhcp server:
# for each VM
box=salt-master
vboxmanage modifyvm $box --nic2 intnet
vboxmanage modifyvm $box --intnet2 close-circle
vboxmanage dhcpserver add --netname close-circle --ip 10.1.1.254 --netmask 255.255.255.0 --lowerip 10.1.1.1 --upperip 10.1.1.99 --enable
vboxmanage list dhcpservers
Resize Disk#
Resize the VDI image:
vboxmanage modifyhd <hd-name-vdi> --resize 40000
Add Live CD image, e.g. crunchbang:
thunar-volman-settings # disable automatic mounting, which would interfere with the resize
gparted
- If it is a VMDK image:
- If you have Snapshots:
Navigate to snapshot:
Nice post about cloning snapshots: https://forums.virtualbox.org/viewtopic.php?f=1&t=791#p106206
Compact Disk#
live CD boot, then:
apt-get install zerofree || apt-get update && apt-get install zerofree
zerofree /dev/sda1
shutdown, then:
vboxmanage modifyhd foo.vdi --compact
vboxmanage Cheat Sheet#
vboxmanage list vms
Change default storage location:
vboxmanage setproperty machinefolder ~/VMs
New Box from VDI:
box=
vboxmanage list ostypes
os_type=
# create
vboxmanage createvm --name $box --ostype $os_type --register
# DELETE == undo create
vboxmanage unregistervm $box --delete
# add storage controller
vboxmanage storagectl $box --name "SATA Controller" --add sata --controller IntelAHCI
# attach image
image=
vboxmanage storageattach $box --storagectl "SATA Controller" --port 0 --device 0 --type hdd --medium $image
# set mem to 8GB
vboxmanage modifyvm $box --memory 8192
Snapshot:
vboxmanage snapshot $box take "foo" --description "bar"
Links:
USB-Stick to Virtual Machine#
Let /dev/sdc
be a USB Drive that should run in a VM. Run the following
once:
# make an iso
dd if=/dev/sdc of=~/my_image.iso
# mount the iso as block device
sudo losetup /dev/loop0 ~/my_image.iso
# make a vmdk for it
box=loop0vm
vboxmanage internalcommands createrawvmdk -filename ~/VMs/$box.vmdk -rawdisk /dev/loop0
# create VM
vboxmanage createvm --name $box --register
vboxmanage storagectl $box --name sata --add sata --controller IntelAhci --portcount 1
vboxmanage storageattach $box --storagectl sata --port 0 --device 0 --type hdd --medium ~/VMs/$box.vmdk
vboxmanage startvm $box --type gui
vboxmanage setextradata $box VBoxInternal/CPUM/CMPXCHG16B 1
You can now start the machine. After rebooting the host, you need to re-mount the file as block device before starting the VM:
sudo losetup /dev/loop0 ~/my_image.iso
Windows 8 Guest Screen Resolution#
This works without installing Guest Additions:
vboxmanage setextradata $box CustomVideoMode1 1920x1080x32
Thanks go to http://superuser.com/questions/497173/windows-8-screen-resolution-in-virtualbox
Xen Partition Image to Virtualbox#
Jiffybox uses Xen. Backups contain raw partition images.
Those are not disk images, so there is no partition table, no bootloader and no mbr.
To boot those, you can either
create a separate boot image or
create an image containing everything.
The benefit of a) is speed. Only the boot image needs to be created, so this is the way to go to quickly run a backup image.
On the other hand b) is more convenient, because you get a single VDI that Just Works. The problem is that you need to copy the whole partition to a new image.
Use Loopbacks and raw images#
Unpack the tarfile. This might take a while:
tarfile=
tar xf $tarfile
Prep stuff:
mkdir {boot,root}
Prepare the boot image:
dd if=/dev/zero of=boot.img count=1 bs=10MiB
echo 'n
p
1
2048
a
1
w
' | fdisk boot.img
file boot.img
Install grub. Using kpartx is important here, so Grub thinks it installs to a real device. I tried “losetup -P” to no avail.
sudo kpartx -av boot.img
# sets up /dev/loop0 and /dev/mapper/loop0p1
sudo mkfs.ext2 -L boot /dev/mapper/loop0p1
sudo mount /dev/mapper/loop0p1 boot
sudo grub-install --target=i386-pc --recheck --boot-directory=boot/boot /dev/loop0
Mount the raw partition:
raw=$(ls -S *.raw | head -n1) # the big one
ls -l $raw
sudo losetup /dev/loop1 $raw
sudo mount /dev/loop1 root/
Configure the boot image. First, convert legacy Grub’s menu.lst
to Grub 2
grub.cfg
. Then tell grub to look at the second drive, i.e. hd0
and sdb
respectively:
sudo grub-menulst2cfg root/boot/grub/menu.lst boot/boot/grub/grub.cfg
sudo sed -i -e 's;(hd0);(hd1);' boot/boot/grub/grub.cfg
sudo sed -i -e 's;root=/dev/xvda;root=/dev/sdb;' boot/boot/grub/grub.cfg
Create a VM using both images:
box=foo
vboxmanage createvm --name $box --register
vboxmanage storagectl $box --name sata --add sata --controller IntelAhci --portcount 2
vboxmanage internalcommands createrawvmdk -filename raw-boot.vmdk -rawdisk /dev/loop0
vboxmanage internalcommands createrawvmdk -filename raw-root.vmdk -rawdisk /dev/loop1
vboxmanage storageattach $box --storagectl sata --type hdd --device 0 --port 0 --medium raw-boot.vmdk
vboxmanage storageattach $box --storagectl sata --type hdd --device 0 --port 1 --medium raw-root.vmdk
Tweak VM (NAT, RAM, CPU):
vboxmanage modifyvm $box --nic1 nat
vboxmanage modifyvm $box --natpf1 "guestssh,tcp,,2222,,22"
vboxmanage modifyvm $box --memory 2048
vboxmanage modifyvm $box --cpus 3
We could package the boot image as a VDI:
vboxmanage convertfromraw boot.img boot.vdi --format VDI
vboxmanage storageattach $box --storagectl sata --port 0 --device 0 --type hdd --medium boot.vdi
# let the media registry forget about the raw boot image
vboxmanage closemedium raw-boot.vmdk
Test it. If it does not work, iterate:
vboxmanage storageattach $box --storagectl sata --port 0 --device 0 --type hdd --medium none
vboxmanage closemedium boot.vdi --delete
vboxmanage convertfromraw boot.img boot.vdi --format VDI
vboxmanage storageattach $box --storagectl sata --port 0 --device 0 --type hdd --medium boot.vdi
Complete VDI#
Thanks to https://blog.filippo.io/converting-a-partition-image-to-a-bootable-disk-image/
Note that this involves a lot of copying:
from raw to partition in new image
from new image to vdi
Tools i did not have before following Filippo’s post:
sudo apt-get install pv
And here’s the paste:
dd if=/dev/zero of=new.img count=1 bs=1MiB
raw=$(ls -S *.raw | head -n1) # the big one
pv $raw >> new.img
echo 'n
p
1
2048
a
w
' | fdisk new.img
sudo kpartx -av new.img
mkdir new
sudo mount /dev/mapper/loop0p1 new
sudo grub-install --target=i386-pc --recheck --boot-directory=new/boot /dev/loop0
sudo grub-menulst2cfg new/boot/grub/menu.lst new/boot/grub/grub.cfg
sudo sed -i -e 's;(hd0);(hd0,1);' new/boot/grub/grub.cfg
sudo sed -i -e 's;root=/dev/xvda;root=/dev/sda1;' new/boot/grub/grub.cfg
sudo kpartx -dv new.img
Try it raw:
box=bar
vboxmanage createvm --name $box --register
vboxmanage storagectl $box --name sata --add sata --controller IntelAhci --portcount 1
vboxmanage internalcommands createrawvmdk -filename raw-new.vmdk -rawdisk /dev/loop0
vboxmanage storageattach $box --storagectl sata --type hdd --device 0 --port 0 --medium raw-new.vmdk
vboxmanage modifyvm $box --nic1 nat
vboxmanage modifyvm $box --natpf1 "guestssh,tcp,,2223,,22"
vboxmanage modifyvm $box --memory 2048
vboxmanage modifyvm $box -ioapic on
vboxmanage modifyvm $box --cpus 3
vboxmanage startvm $box --type headless
OK, convert to VDI:
vboxmanage controlvm $box acpipowerbutton
vboxmanage convertfromraw boot.img boot.vdi --format VDI
Troubleshooting#
Could not find an open hard disk with UUID#
https://www.virtualbox.org/ticket/8595
Transcript:
Close out of VirtualBox
Open the .vbox file for the VM in a text editor. Look for a section towards the end of the file labeled <Image uuid=”[the UUID from the error message]”> and delete the whole <AttachedDevice> section around it.
Reopen VirtualBox
Open the Settings for the VM and reattach the hard disk file.