├── .gitignore ├── README.md ├── http └── preseed.cfg ├── scripts ├── base.sh ├── cleanup.sh ├── mirage.sh ├── network.sh ├── toolchain.sh ├── vagrant.sh └── xen.sh ├── template.json └── vagrant └── Vagrantfile.template /.gitignore: -------------------------------------------------------------------------------- 1 | packer_cache 2 | *.box 3 | Vagrantfile 4 | *.swp 5 | .vagrant 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | mirage-xen-virtualbox 2 | ===================== 3 | 4 | A Packer template to build an environment in which to run [MirageOS](http://www.openmirage.org/) unikernels under Xen. It uses Vagrant, Virtualbox and is based on Ubuntu 14.04. It's based on the blog post here: http://www.skjegstad.com/blog/2015/01/19/mirageos-xen-virtualbox/ 5 | 6 | Ubuntu packer template based on: https://github.com/shiguredo/packer-templates/tree/develop/ubuntu-14.04 7 | 8 | How to build 9 | ------------ 10 | You'll need to have [Packer](https://www.packer.io/), [Vagrant](https://www.vagrantup.com/), Virtualbox (and ideally a speedy internet connection...) 11 | 12 | * clone this repo and cd into it 13 | * `packer build template.json` 14 | * .. wait awhile.. 15 | * If successful, this will result in a vagrant .box file being generated: `virtualbox-xen.box` 16 | 17 | How to use 18 | ---------- 19 | 20 | There are a few possibilties of how to use it. The simplest is documented here 21 | 22 | * Import the `.box` file into Vagrant `vagrant box add virtualbox-xen.box --name virtualbox-xen` 23 | * In an empty directory, `vagrant init virtualbox-xen` - this creates a Vagrantfile 24 | * Spin up the box and provision it: `vagrant up` 25 | * this sets up a bridge interface and installs `opam` and `mirage` for the vagrant user 26 | * `vagrant ssh` 27 | * Then clone eg. `mirage-skeleton` and build :) 28 | 29 | I think it should be possible to customise the Vagrantfile generated in step 2 to allow NFS shared folders, or a different private network subnet. But I haven't tested those yet (see TODO) 30 | 31 | BUGS (KNOWN) 32 | ------------ 33 | 34 | FIXED ~~For some reason https://github.com/mattgray/mirage-xen-virtualbox/blob/master/scripts/toolchain.sh does not install m4 correctly, causing `opam install -y mirage` to fail during provisioning. The fix is to `vagrant ssh` and install manually, then repeat the `opam install `~~ 35 | 36 | direct networking does not work out of the box (have to do some manual setup of `tap0`, but maybe this is an issue with `ocaml-tuntap` or `mirage-net-unix` ? 37 | 38 | TODO 39 | ---- 40 | 41 | * ~~Do virtualbox guest additions work with xen at all?~~ 42 | * ~~script to install xen~~ 43 | * ~~NFS for shared folders?~~ 44 | * ~~configure bridge adaptor + DHCP~~ 45 | * ~~Vagrantfile template with host only + NIC promiscuos mode settings~~ 46 | * ~~Install avahi-daemon?~~ 47 | * ~~Install git / build essential~~ 48 | * ~~Install ocaml / opam (into image?)~~ 49 | * ~~Test building a skeleton~~ 50 | * ~~Figure out why `m4` is not installed by packer scripts, thus preventing provisioners from working~~ 51 | * Test bridge config works with overridden `private_network` in Vagrantfile 52 | * ~~Test NFS synced folders~~ 53 | * make tun/tap work 54 | * Make it so that mirage builds can be pushed to the box and compiled and run with no command line interaction to the VM 55 | * Make it so that running unikernels can be registered into avahi DNS automatically by parsing console output for DHCP assigned IPs 56 | * Support VMWare? But i don't have vmware available to test 57 | -------------------------------------------------------------------------------- /http/preseed.cfg: -------------------------------------------------------------------------------- 1 | choose-mirror-bin mirror/http/proxy string 2 | d-i base-installer/kernel/override-image string linux-server 3 | d-i clock-setup/utc boolean true 4 | d-i clock-setup/utc-auto boolean true 5 | d-i finish-install/reboot_in_progress note 6 | d-i grub-installer/only_debian boolean true 7 | d-i grub-installer/with_other_os boolean true 8 | d-i partman-auto-lvm/guided_size string max 9 | d-i partman-auto/choose_recipe select atomic 10 | d-i partman-auto/method string lvm 11 | d-i partman-lvm/confirm boolean true 12 | d-i partman-lvm/confirm boolean true 13 | d-i partman-lvm/confirm_nooverwrite boolean true 14 | d-i partman-lvm/device_remove_lvm boolean true 15 | d-i partman/choose_partition select finish 16 | d-i partman/confirm boolean true 17 | d-i partman/confirm_nooverwrite boolean true 18 | d-i partman/confirm_write_new_label boolean true 19 | 20 | # Default user 21 | d-i passwd/user-fullname string vagrant 22 | d-i passwd/username string vagrant 23 | d-i passwd/user-password password vagrant 24 | d-i passwd/user-password-again password vagrant 25 | d-i passwd/username string vagrant 26 | 27 | # Minimum packages (see postinstall.sh) 28 | d-i pkgsel/include string openssh-server 29 | d-i pkgsel/install-language-support boolean false 30 | d-i pkgsel/update-policy select none 31 | d-i pkgsel/upgrade select none 32 | 33 | d-i time/zone string UTC 34 | d-i user-setup/allow-password-weak boolean true 35 | d-i user-setup/encrypt-home boolean false 36 | tasksel tasksel/first multiselect standard, ubuntu-server 37 | -------------------------------------------------------------------------------- /scripts/base.sh: -------------------------------------------------------------------------------- 1 | export DEBIAN_FRONTEND="noninteractive" 2 | 3 | apt-get update 4 | apt-get -y upgrade 5 | apt-get -y install linux-headers-$(uname -r) 6 | 7 | sed -i -e '/Defaults\s\+env_reset/a Defaults\texempt_group=sudo' /etc/sudoers 8 | sed -i -e 's/%sudo ALL=(ALL:ALL) ALL/%sudo ALL=NOPASSWD:ALL/g' /etc/sudoers 9 | 10 | echo "UseDNS no" >> /etc/ssh/sshd_config 11 | -------------------------------------------------------------------------------- /scripts/cleanup.sh: -------------------------------------------------------------------------------- 1 | export DEBIAN_FRONTEND="noninteractive" 2 | 3 | apt-get -y autoremove 4 | apt-get -y clean 5 | 6 | echo "cleaning up guest additions" 7 | rm -rf VBoxGuestAdditions_*.iso VBoxGuestAdditions_*.iso.? 8 | 9 | echo "cleaning up dhcp leases" 10 | rm /var/lib/dhcp/* 11 | 12 | echo "cleaning up udev rules" 13 | rm /etc/udev/rules.d/70-persistent-net.rules 14 | mkdir /etc/udev/rules.d/70-persistent-net.rules 15 | rm -rf /dev/.udev/ 16 | rm /lib/udev/rules.d/75-persistent-net-generator.rules 17 | -------------------------------------------------------------------------------- /scripts/mirage.sh: -------------------------------------------------------------------------------- 1 | sudo -u vagrant -H -- opam init -y 2 | sudo -u vagrant -H -- opam install -y mirage 3 | sudo -u vagrant -H -- opam install -y mirage-net-unix 4 | sudo -u vagrant -H -- opam install -y mirage-net-xen 5 | -------------------------------------------------------------------------------- /scripts/network.sh: -------------------------------------------------------------------------------- 1 | export DEBIAN_FRONTEND="noninteractive" 2 | 3 | apt-get install -y dnsmasq avahi-daemon 4 | sleep 5 # sleep here otherwise subsequent package installs fail as network not back up 5 | -------------------------------------------------------------------------------- /scripts/toolchain.sh: -------------------------------------------------------------------------------- 1 | export DEBIAN_FRONTEND="noninteractive" 2 | 3 | apt-get install -y m4 4 | apt-get install -y make 5 | apt-get install -y vim 6 | apt-get install -y git 7 | apt-get install -y curl 8 | apt-get install -y libssl-dev 9 | apt-get install -y pkg-config 10 | apt-get install -y software-properties-common 11 | add-apt-repository -y ppa:avsm/ocaml42+opam12 12 | apt-get update 13 | apt-get install -y opam ocaml-native-compilers camlp4-extra 14 | -------------------------------------------------------------------------------- /scripts/vagrant.sh: -------------------------------------------------------------------------------- 1 | export DEBIAN_FRONTEND="noninteractive" 2 | 3 | date > /etc/vagrant_box_build_time 4 | 5 | mkdir /home/vagrant/.ssh 6 | wget 'https://github.com/mitchellh/vagrant/raw/master/keys/vagrant.pub' \ 7 | -O /home/vagrant/.ssh/authorized_keys 8 | chown -R vagrant /home/vagrant/.ssh 9 | chmod -R go-rwsx /home/vagrant/.ssh 10 | apt-get install -y nfs-kernel-server 11 | -------------------------------------------------------------------------------- /scripts/xen.sh: -------------------------------------------------------------------------------- 1 | export DEBIAN_FRONTEND="noninteractive" 2 | 3 | apt-get install -y xen-system-amd64 4 | -------------------------------------------------------------------------------- /template.json: -------------------------------------------------------------------------------- 1 | { 2 | "provisioners": [ 3 | { 4 | "type": "shell", 5 | "execute_command": "echo 'vagrant'|sudo -S sh '{{.Path}}'", 6 | "override": { 7 | "virtualbox-iso": { 8 | "scripts": [ 9 | "scripts/base.sh", 10 | "scripts/vagrant.sh", 11 | "scripts/xen.sh", 12 | "scripts/network.sh", 13 | "scripts/toolchain.sh", 14 | "scripts/mirage.sh", 15 | "scripts/cleanup.sh" 16 | ] 17 | } 18 | } 19 | } 20 | ], 21 | "post-processors": [ 22 | [ 23 | { 24 | "type": "vagrant", 25 | "vagrantfile_template": "vagrant/Vagrantfile.template", 26 | "keep_input_artifact": false 27 | }, 28 | { 29 | "type": "atlas", 30 | "only": ["virtualbox-iso"], 31 | "artifact": "mattg/mirage-xen-virtualbox", 32 | "artifact_type": "vagrant.box", 33 | "metadata": { 34 | "provider": "virtualbox", 35 | "version": "0.0.3" 36 | } 37 | }] 38 | ], 39 | "builders": [ 40 | { 41 | "type": "virtualbox-iso", 42 | "boot_command": [ 43 | "", 44 | "", 45 | "", 46 | "/install/vmlinuz", 47 | " auto", 48 | " console-setup/ask_detect=false", 49 | " console-setup/layoutcode=us", 50 | " console-setup/modelcode=pc105", 51 | " debconf/frontend=noninteractive", 52 | " debian-installer=en_US", 53 | " fb=false", 54 | " initrd=/install/initrd.gz", 55 | " kbd-chooser/method=us", 56 | " keyboard-configuration/layout=USA", 57 | " keyboard-configuration/variant=USA", 58 | " locale=en_US", 59 | " netcfg/get_hostname=mirage-xen-virtualbox", 60 | " netcfg/get_domain=vagrantup.com", 61 | " noapic", 62 | " preseed/url=http://{{ .HTTPIP }}:{{ .HTTPPort }}/preseed.cfg", 63 | " -- ", 64 | "" 65 | ], 66 | "headless": false, 67 | "boot_wait": "10s", 68 | "disk_size": 40960, 69 | "guest_os_type": "Ubuntu_64", 70 | "http_directory": "http", 71 | "iso_checksum": "9e5fecc94b3925bededed0fdca1bd417", 72 | "iso_checksum_type": "md5", 73 | "iso_url": "http://releases.ubuntu.com/14.04.3/ubuntu-14.04.3-server-amd64.iso", 74 | "ssh_username": "vagrant", 75 | "ssh_password": "vagrant", 76 | "ssh_port": 22, 77 | "ssh_wait_timeout": "10000s", 78 | "shutdown_command": "echo 'shutdown -P now' > /tmp/shutdown.sh; echo 'vagrant'|sudo -S sh '/tmp/shutdown.sh'", 79 | "vboxmanage": [ 80 | [ "modifyvm", "{{.Name}}", "--memory", "1024" ], 81 | [ "modifyvm", "{{.Name}}", "--cpus", "1" ] 82 | ] 83 | } 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /vagrant/Vagrantfile.template: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | VAGRANTFILE_API_VERSION = "2" 5 | 6 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 7 | 8 | config.vm.box = "virtualbox-xen" 9 | 10 | config.vm.network "private_network", ip: "192.168.33.10" 11 | config.vm.provider "virtualbox" do |vbox| 12 | vbox.customize ["modifyvm", :id, "--nicpromisc2", "allow-all"] 13 | end 14 | 15 | config.vm.provision "shell", :inline => <<-NETWORK 16 | 17 | #get the IP address as configured by Vagrant 18 | ip_addr=$(ifquery eth1 | grep address | cut -d' ' -f2) 19 | subnet=$(echo $ip_addr | cut -d. -f1-3) 20 | 21 | # network bridge 22 | tee -a /etc/network/interfaces <> /etc/dnsmasq.conf 39 | echo "dhcp-range=$subnet.150,$subnet.200,1h" >> /etc/dnsmasq.conf 40 | /etc/init.d/dnsmasq restart 41 | NETWORK 42 | config.vm.provision "shell", inline: "eval `opam config env`", privileged: false 43 | config.vm.synced_folder ".", "/vagrant", disabled: true 44 | end 45 | --------------------------------------------------------------------------------