Magnus Skjegstadhttp://www.skjegstad.com/2015-08-17T00:00:00+01:00Just-in-Time Summoning of Unikernels (v0.2)2015-08-17T00:00:00+01:00Magnus Skjegstadtag:www.skjegstad.com,2015-08-17:blog/2015/08/17/jitsu-v02/<p><a href="https://github.com/mirage/jitsu.git">Jitsu</a> - or Just-in-Time Summoning of Unikernels - is a prototype DNS server that can boot virtual machines on demand. When Jitsu receives a DNS query, a virtual machine is booted automatically before the query response is sent back to the client. If the virtual machine is a <a href="http://queue.acm.org/detail.cfm?id=2566628">unikernel</a>, it can boot in milliseconds and be available as soon as the client receives the response. To the client it will look like it was on the whole time. </p>
<p>Jitsu can be used to run microservices that only exist after they have been resolved in DNS - and perhaps in the future can facilitate <a href="http://amirchaudhry.com/heroku-for-unikernels-pt2/">demand-driven clouds</a> or extreme scaling with <a href="http://www.skjegstad.com/blog/2015/03/25/mirageos-vm-per-url-experiment/">a unikernel per URL</a>. Jitsu has also been used to boot unikernels in milliseconds on <a href="https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-madhavapeddy.pdf">ARM devices</a>.</p>
<p>A new version of Jitsu was just released and I'll summarize some of the old and new features here. This is the first version that supports both <a href="https://mirage.io">MirageOS</a> and <a href="https://github.com/rumpkernel/rumprun">Rumprun</a> unikernels and uses the distributed <a href="https://github.com/mirage/irmin">Irmin</a> database to store state. A full list of changes is available <a href="https://github.com/mirage/jitsu/blob/master/CHANGES.md">here</a>.</p>
<p>A Jitsu demo hosting a MirageOS unikernel runs <a href="http://www.jitsu.v0.no">here</a> and nginx on Rumprun <a href="http://www.rump.jitsu.v0.no">here</a>. These demos should be up most of the time, but may occasionally be unstable or unavailable as they are also used to test new features. </p>
<p>For more technical details and up to date example configurations with MirageOS and Rumprun, see the Jitsu <a href="https://github.com/mirage/jitsu/blob/master/README.md">README</a>.</p>
<h3>Overview</h3>
<ul>
<li><a href="#how-it-works">How it works</a></li>
<li><a href="#masking-boot-delays">Masking boot delays</a><ul>
<li><a href="#synjitsu">Synjitsu</a></li>
</ul>
</li>
<li><a href="#irmin-and-jitsu">Irmin and Jitsu</a></li>
<li><a href="#new-backends">New backends</a></li>
<li><a href="#tell-me-more-about-unikernels">Tell me more!</a></li>
</ul>
<h2>How it works</h2>
<p>The following figure shows what happens when Jitsu receives a DNS query for a unikernel that is not currently running.</p>
<p><img alt="Jitsu" src="/images/blog/jitsu/jitsu_mirage.jpg" /></p>
<p>First, the client sends a DNS request to Jitsu. The request is received and checked against a list of domains mapped to unikernels. If there is a match, Jitsu boots the corresponding unikernel VM. When the unikernel has started booting, Jitsu sends a DNS reply to the client containing the future IP address of the unikernel. When the DNS response is received by the client it initiates a TCP connection to the IP address in the DNS response.</p>
<p>Each DNS reply from Jitsu contains a time-to-live (TTL) value that tells the client for how long the reply is valid. This is a feature built into DNS that allows query results to be cached by the client or by other name servers. When the TTL expires, the client will have to send a new DNS query to Jitsu to verify that a cached response still correct. By using low TTL values (typically less than an hour), Jitsu can keep track of how often a unikernel is used and may automatically stop unikernels that have not been requested within a certain time period. By default, unikernels are stopped after 2 x TTL timeout.</p>
<h2>Masking boot delays</h2>
<p>When Jitsu boots a unikernel and returns the DNS response there is a race between the client and the unikernel. The unikernel has to be able to respond to a TCP request within the time it takes to send the DNS reponse back to the client and for the client to attempt to connect. What happens if the unikernel is unable to complete its boot process in time?</p>
<p>The problem is illustrated in this figure:</p>
<p><img alt="Jitsu without Synjitsu" src="/images/blog/jitsu/jitsu_nosynjitsu.jpg" /></p>
<p>After being booted by Jitsu, the unikernel has about 1 round-trip-time (RTT) to finish booting. This is the time it takes for the DNS query to go back to the client and for the TCP handshake to be initiated with a SYN packet. For example, the typical boot time of a MirageOS unikernel on ARM is about 3-400 ms. It is then likely that the unikernel will not be ready in time and that the first SYN packet is lost. TCP is able to recover by retransmitting the SYN packet, but it requires a timeout and a retransmit. With <a href="https://tools.ietf.org/html/rfc6298">recommended timeout values</a> it will take a second or longer for the client to finally connect.</p>
<p>To mask this delay and avoid the SYN retransmission, Jitsu now supports three alternative mechanisms:</p>
<ul>
<li>Delay the DNS response by a fixed timeout (e.g. 150-200 ms) to let the unikernel complete the boot process</li>
<li>Wait for the unikernel to signal Jitsu before sending the DNS response</li>
<li>Cache the incoming SYN packet on behalf of the unikernel with <a href="https://github.com/mirage/synjitsu">Synjitsu</a></li>
</ul>
<p>The simplest solution to set up is the fixed delay. Depending on the application, a delay of a few hundred milliseconds may be acceptable to the client. For a web application for example, this may not be noticeable. This mechanism does not require modifications to the unikernel itself. The downside is that the delay is fixed, so even if the unikernel starts faster than expected there will still be a delay for the client.</p>
<p>A more dynamic approach is to let the unikernel notify Jitsu when it is ready. This is currently done by waiting for a key to appear in <a href="http://wiki.xen.org/wiki/XenStore">Xenstore</a>, Xen's shared information store. To write the key the unikernel only needs a working Xenstore client implementation. Jitsu will watch Xenstore and immediately send the DNS response when the key appears. While more dynamic, this mechanism doesn't allow Jitsu to send the DNS reply while the unikernel is booting - making the delay longer than necessary.</p>
<p>To be able to use both a dynamic delay and send the response back while the unikernel is booting, Jitsu has support for running a separate unikernel service that caches incoming SYNs until the unikernel is ready. We call this Synjitsu.</p>
<h3>Synjitsu</h3>
<p><a href="https://github.com/samoht/synjitsu">Synjitsu</a> is a unikernel service that handles TCP connections on behalf of unikernels that are completing their boot process. Synjitsu is always running and captures TCP SYN packets that appear on the network bridge that don't have a matching unikernel yet. The SYNs are then stored in the Xenstore database. When a new unikernel has booted it will check for cached SYNs that matches its MAC- and IP-address in Xenstore. Every SYN it finds will then be processed as if it was received over the network and trigger a SYN/ACK to complete the TCP <a href="http://en.wikipedia.org/wiki/Transmission_Control_Protocol#Connection_establishment">three way handshake</a>.
When the unikernel has finished booting all incoming SYNs are ignored by Synjitsu and go directly to the unikernel as regular network traffic.</p>
<p><img alt="" src="/images/blog/jitsu/synjitsu_mirage.jpg" /></p>
<p>The process is shown above. A DNS query has already been sent to Jitsu DNS, a unikernel has been booted and a reply sent back to the client. The client now attempts to send a TCP SYN packet to initiate the TCP connection. Unfortunately, the unikernel is not ready yet and would be unable to reply. Synjitsu then silently stores the SYN for the remaining milliseconds while the unikernel completes its boot process. When the unikernel is ready it will retrieve the SYN and send a SYN/ACK back to the client. </p>
<p>For Synjitsu to work properly we also have to handle <a href="http://en.wikipedia.org/wiki/Address_Resolution_Protocol">ARP</a> traffic. ARP is used to find the MAC address that matches an IP address on the local network. Before the incoming TCP SYN can reach its destination, the router (usually the local gateway) has to know the MAC address it should be sent to. As the unikernel is still booting it is unable to announce its address and IP - in fact the IP is not really in use yet. To compensate for this, Jitsu will tell Synjitsu the MAC- and IP-address of every unikernel that is currently booting. Synjitsu then sends <a href="http://en.wikipedia.org/wiki/Address_Resolution_Protocol#ARP_announcements">gratuitous ARP</a> packets to announce to the network that it is handling the specified MAC and IP for now. As soon as the real unikernel finishes booting it sends its own gratuitous ARP packet to notify the network that it is ready. </p>
<p><em>Synjitsu is currently a highly experimental feature and requires a modified MirageOS TCP/IP stack. For more information about running Synjitsu, see <a href="https://www.usenix.org/system/files/conference/nsdi15/nsdi15-paper-madhavapeddy.pdf">our paper</a> or ask on the <a href="http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel">mailing list</a>. The source code is available <a href="https://github.com/mirage/synjitsu">here</a>.</em></p>
<h2>Irmin and Jitsu</h2>
<p><a href="https://github.com/mirage/irmin">Irmin</a> is a distributed database with git-like features, such as a full history of changes and support for branching and merging. Jitsu's internal state is now stored in an Irmin database which can be inspected using the Irmin tool. The database used to store the state of the demonstration is shown below.</p>
<div class="highlight"><pre><span class="nv">$ </span>irmin tree
/jitsu/vm/1ca...b60/config/disk/0.........................<span class="s2">"/dev/loop5@xvda"</span>
/jitsu/vm/1ca...b60/config/disk/1.........................<span class="s2">"/dev/loop6@xvdb"</span>
/jitsu/vm/1ca...b60/config/dns/0.....................<span class="s2">"www.rump.jitsu.v0.no"</span>
/jitsu/vm/1ca...b60/config/ip/0.............................<span class="s2">"89.16.190.215"</span>
/jitsu/vm/1ca...b60/config/kernel/0.............................<span class="s2">"nginx.bin"</span>
/jitsu/vm/1ca...b60/config/memory/0.................................<span class="s2">"64000"</span>
/jitsu/vm/1ca...b60/config/name/0.................................<span class="s2">"rump-xl"</span>
/jitsu/vm/1ca...b60/config/nic/0......................................<span class="s2">"br0"</span>
/jitsu/vm/1ca...b60/config/response_delay/0...........................<span class="s2">"0.9"</span>
/jitsu/vm/1ca...b60/config/rumprun_config/0......................<span class="s2">"json.cfg"</span>
/jitsu/vm/1ca...b60/dns/www.rump.jitsu.v0.no/ttl.......................<span class="s2">"60"</span>
/jitsu/vm/1ca...b60/ip......................................<span class="s2">"89.16.190.215"</span>
/jitsu/vm/1ca...b60/response_delay....................................<span class="s2">"0.1"</span>
/jitsu/vm/1ca...b60/stop_mode.....................................<span class="s2">"destroy"</span>
/jitsu/vm/1ca...b60/use_synjitsu....................................<span class="s2">"false"</span>
/jitsu/vm/de4...ad3/config/dns/0..........................<span class="s2">"www.jitsu.v0.no"</span>
/jitsu/vm/de4...ad3/config/ip/0.............................<span class="s2">"89.16.190.214"</span>
/jitsu/vm/de4...ad3/config/kernel/0...........................<span class="s2">"mir-www.xen"</span>
/jitsu/vm/de4...ad3/config/memory/0.................................<span class="s2">"64000"</span>
/jitsu/vm/de4...ad3/config/name/0..................................<span class="s2">"www-xl"</span>
/jitsu/vm/de4...ad3/config/nic/0......................................<span class="s2">"br0"</span>
/jitsu/vm/de4...ad3/config/response_delay/0...........................<span class="s2">"0.1"</span>
/jitsu/vm/de4...ad3/config/wait_for_key/0.....................<span class="s2">"data/status"</span>
/jitsu/vm/de4...ad3/dns/www.jitsu.v0.no/ttl............................<span class="s2">"60"</span>
/jitsu/vm/de4...ad3/ip......................................<span class="s2">"89.16.190.214"</span>
/jitsu/vm/de4...ad3/response_delay....................................<span class="s2">"0.1"</span>
/jitsu/vm/de4...ad3/stop_mode.....................................<span class="s2">"destroy"</span>
/jitsu/vm/de4...ad3/use_synjitsu....................................<span class="s2">"false"</span>
/jitsu/vm/de4...ad3/wait_for_key..............................<span class="s2">"data/status"</span>
</pre></div>
<p>The Jitsu database is currently read only, but in the future the plan is to allow clients to create their own branch of the database, perform changes and then merge with Jitsu's master branch. This can then be used to control Jitsu while it is running and may, for example, allow unikernels to modify their own boot- and DNS configuration. The Irmin database will also make it easier to split Jitsu into smaller components that cooperate and allow some features to run within separate unikernels (e.g. DNS).</p>
<h2>New backends</h2>
<p>Jitsu v0.2 includes support for several backends that can be used to manage the unikernel VMs. The original libvirt backend is still used by default, but libxl and XAPI are also supported (but not as well tested). If you encounter problems with the new backends, please report them <a href="https://github.com/mirage/jitsu/issues">here</a>.</p>
<h2>Tell me more!</h2>
<p>This post has mainly focused on Jitsu, but if you are interested in unikernels and want more information about writing your own or hosting your web site with one, these links may be useful:</p>
<ul>
<li><a href="http://openmirage.org/wiki/hello-world">Hello Mirage World</a> describes how to create and compile a simple "Hello world" unikernel.</li>
<li>In <a href="http://roscidus.com/blog/blog/2014/07/28/my-first-unikernel/">My first unikernel</a>, Thomas Leonard describes how he set up a MirageOS REST service with a storage backend.</li>
<li>Mindy Preston has documented how she runs her blog as a unikernel with Amazon EC2 in <a href="http://www.somerandomidiot.com/blog/2014/08/19/i-am-unikernel/">I Am Unikernel! (and So Can You!)</a>. </li>
<li><a href="http://amirchaudhry.com/from-jekyll-to-unikernel-in-fifty-lines/">From Jekyll site to Unikernel in fifty lines of code</a></li>
<li><a href="https://github.com/rumpkernel/wiki/wiki/Tutorial%3A-Serve-a-static-website-as-a-Unikernel">Tutorial: Serve a static website as a Unikernel</a> explains how to run an nginx server in a Rumprun unikernel.</li>
</ul>
<p>There are also many MirageOS application examples available <a href="https://github.com/mirage/mirage-skeleton">here</a>. The examples are kept up to date with the latest libraries.</p>
<p>If you experiment with Jitsu, please let us know how it went on the <a href="http://lists.xenproject.org/cgi-bin/mailman/listinfo/mirageos-devel">mailing list</a>!</p>
<p>(Thanks to Daniel Bünzli and Amir Chaudhry for comments on previous versions of this post)</p>A unikernel experiment: A VM for every URL2015-03-25T00:00:00+00:00Magnus Skjegstadtag:www.skjegstad.com,2015-03-25:blog/2015/03/25/mirageos-vm-per-url-experiment/<p>I recently wrote a DNS server that can boot unikernels on demand called <a href="https://github.com/MagnusS/jitsu">Jitsu</a>. The following diagram shows a simplified version of how Jitsu works. The client sends a DNS query to a DNS server (Jitsu). The DNS server starts a unikernel and sends a DNS response back to the client while the unikernel is booting. When the client receives the DNS response it opens a TCP connection to the unikernel, which now has completed booting and is ready to respond to the TCP connection.</p>
<p><img src="/images/blog/jitsu/jitsu.jpg" class="center"></p>
<p>The unikernels are built using <a href="http://www.openmirage.org">MirageOS</a>, a library operating system that allows applications to be compiled directly to small Xen VMs. These unikernels only include the operating system components the application needs - nothing else is added. This results in very small VMs with low resource requirements that boot quickly. </p>
<p>Now, what if I wanted to use Jitsu to boot my unikernel website when someone accesses it? My website is fairly low traffic, so this could potentially save me some resource use and hosting costs. Unfortunately, there are always a few requests per hour to some of the more popular sections, which likely would make my unikernel run most of the time. But what if I could split my unikernel into even smaller unikernels? What if I went to an extreme and had one unikernel per URL? Then I could only boot unikernels for the URLs that are being used and they would only need to know how to serve a single page. This could also have a number of benefits, such as the ability to spin up multiple unikernels for an extremely popular web page and use DNS to direct clients to the unikernel that is closest to them — while keeping the rest of the site inactive (let's ignore web crawlers for now). If I had dynamic sections of my website there could also be security benefits: Every dynamic page would run as a separate VM. An attack on a single page would not have to bring down the rest of the site nor reveal any data stored in other unikernels.</p>
<p>As an experiment, I wanted to see if I could run <em>every</em> URL hosted under my domain as a separate virtual machine. The goal was to map each URL to a domain name, which in turn was directed to a separate VM running a web server that hosts a single page. For example, the URL http://www.skjegstad.com/index.html becomes http://index.html.www.skjegstad.com/. Each domain is then mapped to a single IPv4 address on my local network.</p>
<p>Here is an abstract from the DNS zone file.</p>
<div class="highlight"><pre><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.10</span>
<span class="n">images</span><span class="p">.</span><span class="n">profile</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.11</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">m4v</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.12</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">camera</span><span class="o">-</span><span class="mf">33.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.13</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.14</span>
<span class="p">[...]</span>
</pre></div>
<p>You can see that even individual images have their own DNS entry, and will be served separately.</p>
<p>There is an OCaml web server library, called <a href="https://github.com/mirage/ocaml-cohttp">CoHTTP</a>, which we can use with MirageOS. Using this library, unikernels can be written that host static web pages. The web content itself can either be compiled into the unikernel (as a data structure) or be stored directly on a block storage device. For this experiment, I use the built-in data structure to store a single file per unikernel. </p>
<p>For the unikernel code, I take the static_webserver example from <a href="https://github.com/mirage/mirage-skeleton">mirage-skeleton</a>. The code automatically creates a web server that hosts the files located in the <code>./htdocs</code> subdirectory when the unikernel is built.</p>
<p>The demo code (available <a href="https://github.com/MagnusS/vm-per-url-experiment">here</a>) accepts a directory with static web pages as input. I will use my own website in the examples below, but any site with static web pages should work.</p>
<p>First, mirror (or copy) a static website:</p>
<div class="highlight"><pre><span class="err">$</span> <span class="n">wget</span> <span class="o">-</span><span class="n">m</span> <span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span>
</pre></div>
<p>Then run the <a href="https://github.com/MagnusS/vm-per-url-experiment/blob/master/create.py">create.py</a> script to generate a unikernel with a web server for each file, which will serve that single file from memory. Note that the folder name and domain name must match - otherwise the script will become confused and not rewrite the URLs properly. My site has 49 pages and I've copied the entire output below. This step should only take a few seconds on a reasonably modern machine.</p>
<div class="highlight"><pre><span class="cp"># Run create.py on the contents of the www.skjegstad.com folder. Folder name and domain name must match.</span>
<span class="err">$</span> <span class="n">python</span> <span class="n">create</span><span class="p">.</span><span class="n">py</span> <span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span>
<span class="n">Indexing</span> <span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">...</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">85956378</span><span class="n">dc89cf3a2729</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">profile</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">profile</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">f7fb9c68d5c3701996b3</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">m4v</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">m4v</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">c286eccb0f59b299cca1</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">camera</span><span class="o">-</span><span class="mf">33.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">camera_33</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">5</span><span class="n">bef80428ab04abb98c3</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">png</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">41</span><span class="n">d9ee421440ceec86a4</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone1</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">ardrone1</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">a9fdfed9d054ee4d48de</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">camera</span><span class="o">-</span><span class="mf">28.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">camera_28</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">5</span><span class="n">ca0d87ae96d8648c36d</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">screenshot1</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">screenshot1</span><span class="p">.</span><span class="n">png</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">5</span><span class="n">b1ce89d1c806c4234f2</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">mirage</span><span class="o">-</span><span class="n">dev</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ubuntu</span><span class="o">-</span><span class="n">in</span><span class="o">-</span><span class="n">vm</span><span class="o">-</span><span class="n">overview</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">ubuntu_in_vm_overview</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">0</span><span class="n">d368ef42317b28f6243</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">mirage</span><span class="o">-</span><span class="n">dev</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">xen</span><span class="o">-</span><span class="n">in</span><span class="o">-</span><span class="n">vm</span><span class="o">-</span><span class="n">overview</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">xen_in_vm_overview</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">2</span><span class="n">a4e519b0d91b8967b62</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">MobileNode</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">MobileNode</span><span class="p">.</span><span class="n">png</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">390</span><span class="n">a92f0488aa32f17e3</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image6</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">image6</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">f9a90e263ac465d53558</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image1</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">image1</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">fc21dfa295c33c6e3bd3</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image5</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">image5</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">afc6634e807f1bddad22</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image4</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">image4</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">1f</span><span class="mi">7</span><span class="n">b97ef7d3a4a1ba0f4</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image3</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">image3</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">4</span><span class="n">dedbc5bfcd11fe49a83</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image2</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">image2</span><span class="p">.</span><span class="n">jpg</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">8f15f</span><span class="n">a23ae6563d2d890</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">software</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">855</span><span class="n">d32b8905249554f69</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">macvim</span><span class="o">-</span><span class="n">and</span><span class="o">-</span><span class="n">funnel</span><span class="o">-</span><span class="n">pl</span><span class="mf">.05.01.2012</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">cb72fc8606b734fd7322</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="o">-</span><span class="n">flight</span><span class="o">-</span><span class="mf">1.12.01.2012</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">570</span><span class="n">b6f207695db4d2898</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">mirageos</span><span class="o">-</span><span class="n">xen</span><span class="o">-</span><span class="n">virtualbox</span><span class="mf">.19.01.2015</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">9</span><span class="n">ada75a179f0d6c6cdff</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">experimenting</span><span class="o">-</span><span class="n">with</span><span class="o">-</span><span class="n">distributed</span><span class="o">-</span><span class="n">chat</span><span class="mf">.02.12.2011</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">0</span><span class="n">d0613c7f413609ab402</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">a</span><span class="o">-</span><span class="n">stand</span><span class="o">-</span><span class="n">alone</span><span class="o">-</span><span class="n">java</span><span class="o">-</span><span class="n">bloom</span><span class="o">-</span><span class="n">filter</span><span class="mf">.20.10.2011</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">c11e5af4b1a8ee667bf5</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">virtualbox</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">198f10ff</span><span class="n">b77757798200</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">bloom</span><span class="o">-</span><span class="n">filters</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">da3c099920c48f77b625</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">mist</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">ec590d332b74f3521787</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">unikernel</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">befa876942eb63d806d0</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">experiments</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">2</span><span class="n">d14e6010e04324f1fa9</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">vim</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">d09920f7a15c2f930686</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">xen</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">9</span><span class="n">bd2e2788f6309bc762c</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">mirageos</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">8</span><span class="n">b08718e16dddf30473f</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">ardrone</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">dfc57a0ce3fc7382a001</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">java</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">a13890b437ef10df36e4</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">papers</span><span class="p">.</span><span class="n">skjegstad</span><span class="o">-</span><span class="n">mistsd</span><span class="o">-</span><span class="n">milcom2010</span><span class="p">.</span><span class="n">pdf</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">skjegstad_mistsd_milcom2010</span><span class="p">.</span><span class="n">pdf</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">2</span><span class="n">b39a34888b769596fe0</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">papers</span><span class="p">.</span><span class="n">milcom09skjegstad</span><span class="p">.</span><span class="n">pdf</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">milcom09skjegstad</span><span class="p">.</span><span class="n">pdf</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">09854f</span><span class="mi">35</span><span class="n">b4a6c9bafe01</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">papers</span><span class="p">.</span><span class="n">milcom11</span><span class="o">-</span><span class="n">distributed</span><span class="o">-</span><span class="n">chat</span><span class="p">.</span><span class="n">pdf</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">milcom11_distributed_chat</span><span class="p">.</span><span class="n">pdf</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">759</span><span class="n">daabffb7ac70f3c82</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">publications</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">2434</span><span class="n">cc8c7a5f966b2bc9</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">about</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">index</span><span class="p">.</span><span class="n">html</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">6ff</span><span class="mi">5</span><span class="n">ef4c2d9236d7a398</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">modernizr</span><span class="o">-</span><span class="mf">2.0</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">modernizr</span><span class="o">-</span><span class="mf">2.0</span><span class="p">.</span><span class="n">js</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">1</span><span class="n">b8ff82e33ce3d777d9e</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">octopress</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">octopress</span><span class="p">.</span><span class="n">js</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">2e5</span><span class="n">e43546763b649cd3b</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">ender</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">ender</span><span class="p">.</span><span class="n">js</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">edf18f0bba513af40346</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">github</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">github</span><span class="p">.</span><span class="n">js</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">a577cb04bac38034dc95</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">noise</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">noise</span><span class="p">.</span><span class="n">png</span><span class="o">?</span><span class="mi">1395516324</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">e9d12885cf941b2f149c</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">search</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">search</span><span class="p">.</span><span class="n">png</span><span class="o">?</span><span class="mi">1395516324</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="n">c23144b5f096a13a71bb</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">code</span><span class="o">-</span><span class="n">bg</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">code_bg</span><span class="p">.</span><span class="n">png</span><span class="o">?</span><span class="mi">1395516324</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">19e1</span><span class="n">de022f4a565bc1e2</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">line</span><span class="o">-</span><span class="n">tile</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">line</span><span class="o">-</span><span class="n">tile</span><span class="p">.</span><span class="n">png</span><span class="o">?</span><span class="mi">1395516324</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mf">29ff</span><span class="mo">05</span><span class="n">b603a5d0cdebdc</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">email</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">email</span><span class="p">.</span><span class="n">png</span><span class="o">?</span><span class="mi">1395516324</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">4</span><span class="n">d4e8d94047cf9c45080</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">rss</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">rss</span><span class="p">.</span><span class="n">png</span><span class="o">?</span><span class="mi">1395516324</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">433115</span><span class="n">bed52cbea861a0</span>
<span class="n">Preparing</span> <span class="n">unikernel</span> <span class="k">for</span> <span class="n">css</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">main</span><span class="p">.</span><span class="n">css</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="o">/</span><span class="n">main</span><span class="p">.</span><span class="n">css</span> <span class="n">in</span> <span class="n">staging</span><span class="o">/</span><span class="mi">1</span><span class="n">bacfdf7b71099057d8c</span>
<span class="n">Zone</span> <span class="n">file</span> <span class="n">generated</span> <span class="n">in</span> <span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">.</span><span class="n">zone</span><span class="p">.</span>
<span class="n">Makefile</span> <span class="n">generated</span><span class="p">.</span> <span class="n">Type</span> <span class="err">'</span><span class="n">make</span><span class="err">'</span> <span class="n">to</span> <span class="n">build</span><span class="p">,</span> <span class="err">'</span><span class="n">make</span> <span class="n">run</span><span class="err">'</span> <span class="n">to</span> <span class="n">run</span> <span class="n">and</span> <span class="err">'</span><span class="n">make</span> <span class="n">destroy</span><span class="err">'</span> <span class="n">to</span> <span class="n">stop</span> <span class="n">VMs</span><span class="p">.</span> <span class="n">Start</span> <span class="n">local</span> <span class="n">DNS</span> <span class="n">server</span> <span class="n">with</span> <span class="err">'</span><span class="n">make</span> <span class="n">dns</span><span class="err">'</span>
</pre></div>
<p>When the script completes, a unikernel has been created in <code>./staging</code> for each file in the www.skjegstad.com directory. To compile the unikernels using the mirage-tool, run <code>make</code>. Note that this requires a working MirageOS development environment and I have written a guide for setting this up <a href="http://www.skjegstad.com/blog/2015/01/19/mirageos-xen-virtualbox/">here</a>. This step will take some time, depending on how many pages you have. In my case, it was around 4 minutes in Virtualbox on my laptop.</p>
<p>When all the unikernels have been successfully built, <code>make run</code> will start each of them using Xen's <code>xl</code> tool. Use <code>sudo xl list</code> to see the running unikernels. This is the <code>xl</code> output for 49 MirageOS virtual machines hosting www.skjegstad.com on my local network:</p>
<div class="highlight"><pre><span class="err">$</span> <span class="n">sudo</span> <span class="n">xl</span> <span class="n">list</span>
<span class="n">Name</span> <span class="n">ID</span> <span class="n">Mem</span> <span class="n">VCPUsStateTime</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="n">Domain</span><span class="o">-</span><span class="mi">0</span> <span class="mi">0</span> <span class="mi">292</span> <span class="mi">1</span> <span class="n">r</span><span class="o">-----</span> <span class="mf">2156.1</span>
<span class="mi">85956378</span><span class="n">dc89cf3a2729</span> <span class="mi">39</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">f7fb9c68d5c3701996b3</span> <span class="mi">40</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">c286eccb0f59b299cca1</span> <span class="mi">41</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">5</span><span class="n">bef80428ab04abb98c3</span> <span class="mi">42</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">41</span><span class="n">d9ee421440ceec86a4</span> <span class="mi">43</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">a9fdfed9d054ee4d48de</span> <span class="mi">44</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">5</span><span class="n">ca0d87ae96d8648c36d</span> <span class="mi">45</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">5</span><span class="n">b1ce89d1c806c4234f2</span> <span class="mi">46</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">0</span><span class="n">d368ef42317b28f6243</span> <span class="mi">47</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">2</span><span class="n">a4e519b0d91b8967b62</span> <span class="mi">48</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">390</span><span class="n">a92f0488aa32f17e3</span> <span class="mi">49</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">f9a90e263ac465d53558</span> <span class="mi">50</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">fc21dfa295c33c6e3bd3</span> <span class="mi">51</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">afc6634e807f1bddad22</span> <span class="mi">52</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mf">1f</span><span class="mi">7</span><span class="n">b97ef7d3a4a1ba0f4</span> <span class="mi">53</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">4</span><span class="n">dedbc5bfcd11fe49a83</span> <span class="mi">54</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mf">8f15f</span><span class="n">a23ae6563d2d890</span> <span class="mi">55</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">855</span><span class="n">d32b8905249554f69</span> <span class="mi">56</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">cb72fc8606b734fd7322</span> <span class="mi">57</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">570</span><span class="n">b6f207695db4d2898</span> <span class="mi">58</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">9</span><span class="n">ada75a179f0d6c6cdff</span> <span class="mi">59</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">0</span><span class="n">d0613c7f413609ab402</span> <span class="mi">60</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">c11e5af4b1a8ee667bf5</span> <span class="mi">61</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mf">198f10ff</span><span class="n">b77757798200</span> <span class="mi">62</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">da3c099920c48f77b625</span> <span class="mi">63</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">ec590d332b74f3521787</span> <span class="mi">64</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">befa876942eb63d806d0</span> <span class="mi">65</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">2</span><span class="n">d14e6010e04324f1fa9</span> <span class="mi">66</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">d09920f7a15c2f930686</span> <span class="mi">67</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">9</span><span class="n">bd2e2788f6309bc762c</span> <span class="mi">68</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">8</span><span class="n">b08718e16dddf30473f</span> <span class="mi">69</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">dfc57a0ce3fc7382a001</span> <span class="mi">70</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="n">a13890b437ef10df36e4</span> <span class="mi">71</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mi">2</span><span class="n">b39a34888b769596fe0</span> <span class="mi">72</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.1</span>
<span class="mf">09854f</span><span class="mi">35</span><span class="n">b4a6c9bafe01</span> <span class="mi">73</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mi">759</span><span class="n">daabffb7ac70f3c82</span> <span class="mi">74</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mi">2434</span><span class="n">cc8c7a5f966b2bc9</span> <span class="mi">75</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mf">6ff</span><span class="mi">5</span><span class="n">ef4c2d9236d7a398</span> <span class="mi">76</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mi">1</span><span class="n">b8ff82e33ce3d777d9e</span> <span class="mi">77</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mf">2e5</span><span class="n">e43546763b649cd3b</span> <span class="mi">78</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="n">edf18f0bba513af40346</span> <span class="mi">79</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="n">a577cb04bac38034dc95</span> <span class="mi">80</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="n">e9d12885cf941b2f149c</span> <span class="mi">81</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="n">c23144b5f096a13a71bb</span> <span class="mi">82</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mf">19e1</span><span class="n">de022f4a565bc1e2</span> <span class="mi">83</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mf">29ff</span><span class="mo">05</span><span class="n">b603a5d0cdebdc</span> <span class="mi">84</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mi">4</span><span class="n">d4e8d94047cf9c45080</span> <span class="mi">85</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mi">433115</span><span class="n">bed52cbea861a0</span> <span class="mi">86</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
<span class="mi">1</span><span class="n">bacfdf7b71099057d8c</span> <span class="mi">87</span> <span class="mi">32</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.0</span>
</pre></div>
<p>The create.py-script also generated a DNS zone file that maps the domain names to IP addresses. This is the generated zone file for www.skjegstad.com:</p>
<div class="highlight"><pre><span class="err">$</span> <span class="n">cat</span> <span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">.</span><span class="n">zone</span>
<span class="err">@</span> <span class="n">IN</span> <span class="n">SOA</span> <span class="n">ns</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">.</span> <span class="n">postmaster</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">.</span> <span class="p">(</span><span class="mi">1</span> <span class="mi">600</span> <span class="mi">600</span> <span class="mi">600</span> <span class="mi">60</span><span class="p">)</span>
<span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">.</span> <span class="n">IN</span> <span class="n">CNAME</span> <span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span><span class="p">.</span>
<span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.10</span>
<span class="n">images</span><span class="p">.</span><span class="n">profile</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.11</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">m4v</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.12</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">camera</span><span class="o">-</span><span class="mf">33.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.13</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.14</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ardrone1</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.15</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">camera</span><span class="o">-</span><span class="mf">28.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.16</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">experiment</span><span class="o">-</span><span class="mf">1.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">screenshot1</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.17</span>
<span class="n">mirage</span><span class="o">-</span><span class="n">dev</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">ubuntu</span><span class="o">-</span><span class="n">in</span><span class="o">-</span><span class="n">vm</span><span class="o">-</span><span class="n">overview</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.18</span>
<span class="n">mirage</span><span class="o">-</span><span class="n">dev</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">xen</span><span class="o">-</span><span class="n">in</span><span class="o">-</span><span class="n">vm</span><span class="o">-</span><span class="n">overview</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.19</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">MobileNode</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.20</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image6</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.21</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image1</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.22</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image5</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.23</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image4</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.24</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image3</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.25</span>
<span class="n">uavexperiment</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">images</span><span class="p">.</span><span class="n">image2</span><span class="p">.</span><span class="n">jpg</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.26</span>
<span class="n">software</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.27</span>
<span class="n">macvim</span><span class="o">-</span><span class="n">and</span><span class="o">-</span><span class="n">funnel</span><span class="o">-</span><span class="n">pl</span><span class="mf">.05.01.2012</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.28</span>
<span class="n">ardrone</span><span class="o">-</span><span class="n">test</span><span class="o">-</span><span class="n">flight</span><span class="o">-</span><span class="mf">1.12.01.2012</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.29</span>
<span class="n">mirageos</span><span class="o">-</span><span class="n">xen</span><span class="o">-</span><span class="n">virtualbox</span><span class="mf">.19.01.2015</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.30</span>
<span class="n">experimenting</span><span class="o">-</span><span class="n">with</span><span class="o">-</span><span class="n">distributed</span><span class="o">-</span><span class="n">chat</span><span class="mf">.02.12.2011</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.31</span>
<span class="n">a</span><span class="o">-</span><span class="n">stand</span><span class="o">-</span><span class="n">alone</span><span class="o">-</span><span class="n">java</span><span class="o">-</span><span class="n">bloom</span><span class="o">-</span><span class="n">filter</span><span class="mf">.20.10.2011</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.32</span>
<span class="n">virtualbox</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.33</span>
<span class="n">bloom</span><span class="o">-</span><span class="n">filters</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.34</span>
<span class="n">mist</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.35</span>
<span class="n">unikernel</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.36</span>
<span class="n">experiments</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.37</span>
<span class="n">vim</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.38</span>
<span class="n">xen</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.39</span>
<span class="n">mirageos</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.40</span>
<span class="n">ardrone</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.41</span>
<span class="n">java</span><span class="p">.</span><span class="n">categories</span><span class="p">.</span><span class="n">blog</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.42</span>
<span class="n">papers</span><span class="p">.</span><span class="n">skjegstad</span><span class="o">-</span><span class="n">mistsd</span><span class="o">-</span><span class="n">milcom2010</span><span class="p">.</span><span class="n">pdf</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.43</span>
<span class="n">papers</span><span class="p">.</span><span class="n">milcom09skjegstad</span><span class="p">.</span><span class="n">pdf</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.44</span>
<span class="n">papers</span><span class="p">.</span><span class="n">milcom11</span><span class="o">-</span><span class="n">distributed</span><span class="o">-</span><span class="n">chat</span><span class="p">.</span><span class="n">pdf</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.45</span>
<span class="n">publications</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.46</span>
<span class="n">about</span><span class="p">.</span><span class="n">index</span><span class="p">.</span><span class="n">html</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.47</span>
<span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">modernizr</span><span class="o">-</span><span class="mf">2.0</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.48</span>
<span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">octopress</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.49</span>
<span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">ender</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.50</span>
<span class="n">js</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">github</span><span class="p">.</span><span class="n">js</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.51</span>
<span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">noise</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.52</span>
<span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">search</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.53</span>
<span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">code</span><span class="o">-</span><span class="n">bg</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.54</span>
<span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">line</span><span class="o">-</span><span class="n">tile</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.55</span>
<span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">email</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.56</span>
<span class="n">images</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">rss</span><span class="p">.</span><span class="n">png</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.57</span>
<span class="n">css</span><span class="p">.</span><span class="n">theme</span><span class="p">.</span><span class="n">main</span><span class="p">.</span><span class="n">css</span><span class="p">.</span><span class="n">www</span><span class="p">.</span><span class="n">skjegstad</span><span class="p">.</span><span class="n">com</span> <span class="n">IN</span> <span class="n">A</span> <span class="mf">192.168.56.58</span>
</pre></div>
<p>The zone file can be loaded in your favorite DNS server (e.g. bind or unbound). It is also relatively easy to build a quick DNS server in OCaml based on ocaml-dns:</p>
<div class="highlight"><pre><span class="n">open</span> <span class="n">Dns</span>
<span class="n">open</span> <span class="n">Lwt</span>
<span class="n">let</span> <span class="p">()</span> <span class="o">=</span>
<span class="n">Lwt_main</span><span class="p">.</span><span class="n">run</span> <span class="p">(</span>
<span class="n">let</span> <span class="n">address</span> <span class="o">=</span> <span class="s">"0.0.0.0"</span> <span class="n">in</span>
<span class="n">let</span> <span class="n">port</span> <span class="o">=</span> <span class="mi">53</span> <span class="n">in</span>
<span class="n">Dns_server_unix</span><span class="p">.</span><span class="n">serve_with_zonefile</span> <span class="o">~</span><span class="n">address</span> <span class="o">~</span><span class="n">port</span> <span class="s">"www.skjegstad.com.zone"</span>
<span class="p">)</span>
</pre></div>
<p>I have written an extended version with support for forwarding unknown DNS requests to another DNS server. It is available for download <a href="https://github.com/MagnusS/vm-per-url-experiment/blob/master/serve_dns.ml">here</a> and is included in the demo code. In fact, you could also run the DNS server as a unikernel, but I will leave that as an exercise for the reader (<a href="http://hh360.user.srcf.net/blog/2015/02/part-1-running-your-own-dns-resolver-with-mirageos/">this blog post</a> by Heidi Howard is a good starting point with lots of <a href="https://github.com/heidi-ann/ocaml-dns-examples">examples</a>).</p>
<p>Point your DNS server to the IP of the DNS server that hosts the zone file to start browsing the static website. Each static page should map to a separate domain name which is run by a single MirageOS unikernel!</p>
<h3>Conclusion / discussion</h3>
<p>Currently this is just a quick experiment and is not very practical. I would still need a unikernel or Linux VM to run the DNS server and I have not been able to find a hosting provider that has a minimum configuration which would be appropriate for large or small unikernels (e.g. 8MB vs 64MB RAM). Each VM/URL would also require a unique public IP address unless they are placed behind another service (NAT) that can route the HTTP requests to an internal network. </p>
<p>If you followed along, then you would also notice that the compiled unikernels in <code>./staging</code> take up around 175MB (49 unikernels). When running, they collectively consume around 1.6GB of memory. However, it was a lot easier to try this experiment using unikernels than it would have been with a traditional OS stack.</p>
<p>A more practical architecture would perhaps be to run a website and DNS server from a single host initially. As each web page is mapped to a URL, the DNS server could then be configured to automatically boot new unikernels only if a subdomain experienced high load. It could, for example, deploy unikernels automatically to Amazon EC2 that serve a single file and start returning its IP address in DNS queries in periods with high load. Once the website has been 'disaggregated' this way, it would even be possible to start VMs in availability zones that are geographically close to the where the spike in traffic is originating! This could all be configured to happen automatically, with DNS entries being updated as new pages are added and with unikernels being deployed to places where they are in demand.</p>
<p>(Thanks to Amir Chaudry for commenting on a draft of this post)</p>Local MirageOS development with Xen and Virtualbox2015-01-19T00:00:00+00:00Magnus Skjegstadtag:www.skjegstad.com,2015-01-19:blog/2015/01/19/mirageos-xen-virtualbox/<p><a href="http://www.openmirage.org">MirageOS</a> is a library operating system. An application written for MirageOS is compiled to an operating system kernel that only contains the specific functionality required by the application - a <a href="http://queue.acm.org/detail.cfm?id=2566628">unikernel</a>. The MirageOS unikernels can be compiled for different targets, including standalone VMs that run under Xen. The Xen unikernels can be deployed directly to common cloud services such as <a href="http://openmirage.org/wiki/xen-boot">Amazon EC2</a> and <a href="http://christopherbothwell.com/ocaml/mirage/linode/2014/12/08/hello-linode.html">Linode</a>.</p>
<p>I have done a lot of MirageOS development for Xen lately and it can be inconvenient to have to rely on an external server or service to be able to run and debug the unikernel. As an alternative I have set up a VM in Virtualbox with a Xen server. The MirageOS unikernels then run as VMs in Xen, which itself runs in a VM in Virtualbox. With the "Host-only networking" feature in Virtualbox the unikernels are accessible from the host operating system, which can be very useful for testing client/server applications. A unikernel that hosts a web page can for example be tested in a web browser in the host OS. I am hoping that this setup may be useful to others so I am documenting it in this blog post.</p>
<p>My current VM is based on <a href="http://releases.ubuntu.com/14.04/">Ubuntu Server 14.04 LTS</a> with Xen hypervisor 4.4 installed. The steps described in this post should be transferrable to other distributions if they support newer versions of the Xen hypervisor (4.4+). I have also included a list of alternative development environments for Mirage <a href="#alternatives">near the end</a>.</p>
<h3>Install the Ubuntu VM</h3>
<p>First, create a new Virtualbox VM with at least 1 GB RAM and 20 GB disk and start the Ubuntu Server installation. How to install Ubuntu in Virtualbox is covered in detail <a href="https://help.ubuntu.com/community/Ubuntu_as_Guest_OS">elsewhere</a>, so I will only briefly describe the most relevant steps. </p>
<p>To keep the VM lightweight, install as few features as possible. We will use SSH to login to the server so select "OpenSSH Server". You may want to install a desktop environment later, but keep in mind that the graphics support will be limited under two layers of virtualization (Virtualbox + Xen). </p>
<p>Give the Linux VM a hostname that is unique on your network as we will use this to access it with SSH later. I use "virtualxen". </p>
<p>Add a user you want to use for development, for example "mirage". </p>
<p>You may also want to reserve some of the disk space for Mirage if you plan to run applications that use block storage. During guided partitioning in the Ubuntu installer, if you choose to use the entire disk, the next question will allow you to specify a percentage of the disk that you want to use. If you plan to use Xen VMs that need direct disk access you should leave some of it for this purpose, for example 50%.</p>
<p>After completing the installation, run apt-get update/upgrade and install the Virtualbox guest utilities, then reboot:</p>
<div class="highlight"><pre>sudo apt-get update
sudo apt-get upgrade
sudo apt-get install virtualbox-guest-utils
sudo reboot
</pre></div>
<h3>Install the Xen Hypervisor</h3>
<p>After installing the Ubuntu Server VM, your configuration will be as in the following figure. Ubuntu runs in Virtualbox which runs under the main operating system (OS X in my case). </p>
<p><img src="/images/blog/mirage_dev/ubuntu_in_vm_overview.jpg" class="center"></p>
<p>We are now going to install the Xen hypervisor, which will become a thin layer between Virtualbox and the Ubuntu Server installation. The Xen hypervisor will be able to run VMs within the Virtualbox VM and we can use the Ubuntu installation to control Xen. This is the new configuration with Xen:</p>
<p><img src="/images/blog/mirage_dev/xen_in_vm_overview.jpg" class="center"></p>
<p><a href="http://wiki.xen.org/wiki/Dom0">Dom0</a> is the original Ubuntu Server installation and the <a href="http://wiki.xen.org/wiki/DomU">DomU</a>'s will be our future Mirage applications.</p>
<p>To install Xen, log in to Ubuntu and install the Xen hypervisor with the following command. We will also need bridge-utils (for configuring networking), build-essential (development tools) and git (version control):</p>
<div class="highlight"><pre><span class="c"># install hypervisor and other tools</span>
sudo apt-get install xen-hypervisor-4.4-amd64 bridge-utils build-essential git
</pre></div>
<p>After the installation is complete, reboot the Virtualbox VM to start into Xen and the Ubuntu Server installation (which now has become dom0). </p>
<p>Xen can be controlled from dom0 with the <code>xl</code> command. To verify that Ubuntu is running under Xen, log in and run <code>sudo xl list</code> to show a list of running domains. The output should look similar to this:</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo xl list
Name ID Mem VCPUs State Time<span class="o">(</span>s<span class="o">)</span>
Domain-0 0 1896 1 r----- 31.7
</pre></div>
<p>The only Xen domain running at this point should be Dom0.</p>
<p>We are now ready to set up networking. </p>
<h3>Networking</h3>
<p>Internet access should work out of the box for dom0, but to enable network access from the domU's we have set up a bridge device that they can connect to. We will call this device br0. Since this is a development environment we also want the unikernels to be accessible from the host operating system (so we can test them), but not from the local network. Virtualbox has a feature that allows this called a host-only network. </p>
<p>To set up the host-only network in Virtualbox we have to shutdown the VM (<code>sudo shutdown -h now</code>). Then go to Preferences in Virtualbox and select the "Network" tab and "Host-only Networks". Create a new network. Make sure that the built-in DHCP server is disabled - I have not managed to get the built-in DHCP server to work with Mirage, so we will install a DHCP server in dom0 instead. If you already have an existing host-only network and you disabled the DHCP server in this step, remember to restart Virtualbox to make sure that the DHCP server is not running. </p>
<p>After setting up the host-only network, exit preferences and open the settings for the VM. Under the "Network" tab, go to "Adapter 2", enable it and choose to attach to "Host-only Adapter". Select the name of the network that you just created in Preferences. Under advanced, select "Allow All" for "Promiscuous mode". Exit and save.</p>
<p>You can now start the VM with the new network configuration. After booting, edit /etc/network/interfaces to setup up the host-only adapter (eth1) and add it to the bridge (br0). The configuration below is based on the default IP range (192.168.56.x) for host-only networking in Virtualbox - if you have made changes to the default network configuration you may have to update the configuration here as well. </p>
<div class="highlight"><pre><span class="c"># /etc/network/interfaces</span>
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
auto eth1
iface eth1 inet manual
pre-up ifconfig <span class="nv">$IFACE</span> up
post-down ifconfig <span class="nv">$IFACE</span> down
auto br0
iface br0 inet static
bridge_ports eth1
address 192.168.56.5
broadcast 192.168.56.255
netmask 255.255.255.0
<span class="c"># disable ageing (turn bridge into switch)</span>
up /sbin/brctl setageing br0 0
<span class="c"># disable stp</span>
up /sbin/brctl stp br0 off
</pre></div>
<p>Next, we install dnsmasq to setup a DHCP server in dom0. This DHCP server will be responsible for assigning IP addresses to the unikernels that attach to br0.</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo apt-get install dnsmasq
</pre></div>
<p>To enable the DHCP server on br0, edit /etc/dnsmasq.conf and add the following lines:</p>
<div class="highlight"><pre><span class="n">interface</span><span class="o">=</span><span class="n">br0</span>
<span class="n">dhcp</span><span class="o">-</span><span class="n">range</span><span class="o">=</span><span class="mf">192.168.56.150</span><span class="p">,</span><span class="mf">192.168.56.200</span><span class="p">,</span><span class="mi">1</span><span class="n">h</span>
</pre></div>
<p>This configures the DHCP server to run on br0 and to dynamically assign IP addresses in the range 192.168.56.150 to 192.168.56.200 with a lease time of 1 hour. </p>
<p>To be able to access dom0 via SSH from the host operating system (outside Virtualbox) we install avahi-daemon. Avahi-daemon enables mDNS, which will allow you to connect to "virtualxen.local" from the host operating system:</p>
<div class="highlight"><pre><span class="nv">$ </span>sudo apt-get install avahi-daemon
</pre></div>
<p>Reboot dom0 to activate the changes (<code>sudo reboot</code>).</p>
<p>You should now be able to connect to dom0 with SSH from the host OS:</p>
<div class="highlight"><pre><span class="nv">$ </span>ssh mirage@virtualxen.local
</pre></div>
<p>Dom0 can also be accessed from the host by using the IP address for br0 that we set above: 192.168.56.5.</p>
<h3>Installing MirageOS in dom0</h3>
<p>Before we can compile MirageOS unikernels we have to install OCaml.</p>
<div class="highlight"><pre><span class="c"># install ocaml and friends</span>
sudo apt-get install ocaml-compiler-libs ocaml-interp ocaml-base-nox ocaml-base ocaml ocaml-nox ocaml-native-compilers camlp4 camlp4-extra m4
</pre></div>
<p>We also need the OCaml package manager, <a href="https://opam.ocaml.org">opam</a>. A new version of opam was recently release and the version that comes with many Linux distros is outdated. To get the latest version (currently 1.2.x) I use <a href="http://0install.net">0install</a> to install opam directly from the installation script provided on the ocaml.org web page. If you don't want to use 0install, a list of other options is available <a href="http://opam.ocaml.org/doc/Install.html">here</a> (including PPA's). </p>
<div class="highlight"><pre><span class="c"># install 0install</span>
sudo apt-get install zeroinstall-injector
<span class="c"># install opam</span>
0install add opam http://tools.ocaml.org/opam.xml
</pre></div>
<p>0install installs applications in ~/bin. To add this directory to your path logout and back in. </p>
<p>After installing opam, run <code>opam init</code> and follow the instructions to complete the installation. Note that the opam commands should not be run with sudo, as it installs everything in ~/.opam in your home directory.</p>
<p>If you want to run the development version of Mirage, you can add mirage-dev as an opam repository. Keep in mind that this repository contains the latest changes to Mirage, which may not always work. <em>The safest option is to skip this step</em>.</p>
<div class="highlight"><pre><span class="c"># optional - add mirage-dev to opam </span>
opam remote add mirage-dev git://github.com/mirage/mirage-dev
</pre></div>
<p>We can now install Mirage:</p>
<div class="highlight"><pre><span class="c"># install libs required to build many mirage apps</span>
sudo apt-get install libssl-dev pkg-config
<span class="c"># install mirage</span>
opam install mirage -v
</pre></div>
<p>After Mirage has been installed you should be able to run the Mirage configuration tool <code>mirage</code>.</p>
<div class="highlight"><pre><span class="nv">$ </span>mirage --version
2.0.0
</pre></div>
<p>If you use emacs or vim I also recommend installing <a href="https://github.com/the-lambda-church/merlin/wiki">Merlin</a>, which provides tab completion, type lookup and many other useful IDE features for OCaml. </p>
<h3>Creating a Mirage VM</h3>
<p>To verify that everything works, we will now download the <a href="https://github.com/mirage/mirage-skeleton">Mirage examples</a> and compile the static website example. This example will start a web server hosting a "Hello world" page that we should be able to access from the host OS. The IP-address will be assigned with DHCP. </p>
<p>First, clone the Mirage examples:</p>
<div class="highlight"><pre><span class="c"># clone mirage-skeleton</span>
git clone http://github.com/mirage/mirage-skeleton.git
</pre></div>
<p>Then go to the <code>mirage-skeleton/static-webpage</code> folder and run <code>env DHCP=true mirage configure --xen</code>. This command will download and install all the required dependencies and then create a Makefile. When the command completes, run <code>make</code> to compile.</p>
<p>If make completes successfully, there will be a file called <code>www.xl</code> that contains the Xen DomU configuration file for the unikernel. By default the line that contains the network interface configuration is commented out. Remove the # in front of the line that begins with 'vif = ...' to enable network support. The <code>www.xl</code> file should look similar to this:</p>
<div class="highlight"><pre><span class="n">name</span> <span class="o">=</span> <span class="err">'</span><span class="n">www</span><span class="err">'</span>
<span class="n">kernel</span> <span class="o">=</span> <span class="err">'</span><span class="o">/</span><span class="n">home</span><span class="o">/</span><span class="n">mirage</span><span class="o">/</span><span class="n">mirage</span><span class="o">-</span><span class="n">skeleton</span><span class="o">/</span><span class="n">static_website</span><span class="o">/</span><span class="n">mir</span><span class="o">-</span><span class="n">www</span><span class="p">.</span><span class="n">xen</span><span class="err">'</span>
<span class="n">builder</span> <span class="o">=</span> <span class="err">'</span><span class="n">linux</span><span class="err">'</span>
<span class="n">memory</span> <span class="o">=</span> <span class="mi">256</span>
<span class="n">on_crash</span> <span class="o">=</span> <span class="err">'</span><span class="n">preserve</span><span class="err">'</span>
<span class="cp"># You must define the network and block interfaces manually.</span>
<span class="cp"># The disk configuration is defined here:</span>
<span class="cp"># http:</span><span class="c1">//xenbits.xen.org/docs/4.3-testing/misc/xl-disk-configuration.txt</span>
<span class="cp"># An example would look like:</span>
<span class="cp"># disk = [ '/dev/loop0,,xvda' ]</span>
<span class="cp"># The network configuration is defined here:</span>
<span class="cp"># http:</span><span class="c1">//xenbits.xen.org/docs/4.3-testing/misc/xl-network-configuration.html</span>
<span class="cp"># An example would look like:</span>
<span class="n">vif</span> <span class="o">=</span> <span class="p">[</span> <span class="err">'</span><span class="n">mac</span><span class="o">=</span><span class="n">c0</span><span class="o">:</span><span class="n">ff</span><span class="o">:</span><span class="n">ee</span><span class="o">:</span><span class="n">c0</span><span class="o">:</span><span class="n">ff</span><span class="o">:</span><span class="n">ee</span><span class="p">,</span><span class="n">bridge</span><span class="o">=</span><span class="n">br0</span><span class="err">'</span> <span class="p">]</span>
</pre></div>
<p>The memory is set to 256 MB by default, but most of the example unikernels require much less than this. The static webserver example runs fine with 16 MB.</p>
<p>You should now be able to start the unikernel using the command <code>sudo xl create www.xl -c</code>: </p>
<div class="highlight"><pre><span class="nx">$</span> <span class="nx">sudo</span> <span class="nx">xl</span> <span class="nx">create</span> <span class="nx">www</span><span class="p">.</span><span class="nx">xl</span> <span class="o">-</span><span class="nx">c</span>
<span class="nx">Parsing</span> <span class="nx">config</span> <span class="nx">from</span> <span class="nx">www</span><span class="p">.</span><span class="nx">xl</span>
<span class="nx">Xen</span> <span class="nx">Minimal</span> <span class="nx">OS</span><span class="o">!</span>
<span class="nx">start_info</span><span class="o">:</span> <span class="mi">0000000000332000</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">nr_pages</span><span class="o">:</span> <span class="mh">0x10000</span>
<span class="nx">shared_inf</span><span class="o">:</span> <span class="mh">0x5457d000</span><span class="p">(</span><span class="nx">MA</span><span class="p">)</span>
<span class="nx">pt_base</span><span class="o">:</span> <span class="mi">0000000000335000</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">nr_pt_frames</span><span class="o">:</span> <span class="mh">0x5</span>
<span class="nx">mfn_list</span><span class="o">:</span> <span class="mi">00000000002</span><span class="nx">b2000</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">mod_start</span><span class="o">:</span> <span class="mh">0x0</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">mod_len</span><span class="o">:</span> <span class="mi">0</span>
<span class="nx">flags</span><span class="o">:</span> <span class="mh">0x0</span>
<span class="nx">cmd_line</span><span class="o">:</span>
<span class="nx">stack</span><span class="o">:</span> <span class="mi">0000000000291</span><span class="nx">b40</span><span class="o">-</span><span class="mi">00000000002</span><span class="nx">b1b40</span>
<span class="nx">Mirage</span><span class="o">:</span> <span class="nx">start_kernel</span>
<span class="nx">MM</span><span class="o">:</span> <span class="nx">Init</span>
<span class="nx">_text</span><span class="o">:</span> <span class="mi">0000000000000000</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">_etext</span><span class="o">:</span> <span class="mi">000000000015</span><span class="nx">cc0f</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">_erodata</span><span class="o">:</span> <span class="mi">0000000000197000</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">_edata</span><span class="o">:</span> <span class="mi">0000000000258220</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">stack</span> <span class="nx">start</span><span class="o">:</span> <span class="mi">0000000000291</span><span class="nx">b40</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">_end</span><span class="o">:</span> <span class="mi">00000000002</span><span class="nx">b1b40</span><span class="p">(</span><span class="nx">VA</span><span class="p">)</span>
<span class="nx">start_pfn</span><span class="o">:</span> <span class="mi">33</span><span class="nx">d</span>
<span class="nx">max_pfn</span><span class="o">:</span> <span class="mi">10000</span>
<span class="nx">Mapping</span> <span class="nx">memory</span> <span class="nx">range</span> <span class="mh">0x400000</span> <span class="o">-</span> <span class="mh">0x10000000</span>
<span class="nx">setting</span> <span class="mi">0000000000000000</span><span class="o">-</span><span class="mi">0000000000197000</span> <span class="nx">readonly</span>
<span class="nx">skipped</span> <span class="mi">1000</span>
<span class="nx">MM</span><span class="o">:</span> <span class="nx">Initialise</span> <span class="nx">page</span> <span class="nx">allocator</span> <span class="k">for</span> <span class="mi">3</span><span class="nx">bb000</span><span class="p">(</span><span class="mi">3</span><span class="nx">bb000</span><span class="p">)</span><span class="o">-</span><span class="mi">10000000</span><span class="p">(</span><span class="mi">10000000</span><span class="p">)</span>
<span class="nx">MM</span><span class="o">:</span> <span class="nx">done</span>
<span class="nx">Demand</span> <span class="nx">map</span> <span class="nx">pfns</span> <span class="nx">at</span> <span class="mi">10001000</span><span class="o">-</span><span class="mi">0000002010001000</span><span class="p">.</span>
<span class="nx">Initialising</span> <span class="nx">timer</span> <span class="kr">interface</span>
<span class="nx">Initialising</span> <span class="nx">console</span> <span class="p">...</span> <span class="nx">done</span><span class="p">.</span>
<span class="nx">gnttab_table</span> <span class="nx">mapped</span> <span class="nx">at</span> <span class="mi">0000000010001000</span><span class="p">.</span>
<span class="nx">xencaml</span><span class="o">:</span> <span class="nx">app_main_thread</span>
<span class="nx">getenv</span><span class="p">(</span><span class="nx">OCAMLRUNPARAM</span><span class="p">)</span> <span class="o">-></span> <span class="kc">null</span>
<span class="nx">getenv</span><span class="p">(</span><span class="nx">CAMLRUNPARAM</span><span class="p">)</span> <span class="o">-></span> <span class="kc">null</span>
<span class="nx">Unsupported</span> <span class="kd">function</span> <span class="nx">lseek</span> <span class="nx">called</span> <span class="k">in</span> <span class="nx">Mini</span><span class="o">-</span><span class="nx">OS</span> <span class="nx">kernel</span>
<span class="nx">Unsupported</span> <span class="kd">function</span> <span class="nx">lseek</span> <span class="nx">called</span> <span class="k">in</span> <span class="nx">Mini</span><span class="o">-</span><span class="nx">OS</span> <span class="nx">kernel</span>
<span class="nx">Unsupported</span> <span class="kd">function</span> <span class="nx">lseek</span> <span class="nx">called</span> <span class="k">in</span> <span class="nx">Mini</span><span class="o">-</span><span class="nx">OS</span> <span class="nx">kernel</span>
<span class="nx">getenv</span><span class="p">(</span><span class="nx">OCAMLRUNPARAM</span><span class="p">)</span> <span class="o">-></span> <span class="kc">null</span>
<span class="nx">getenv</span><span class="p">(</span><span class="nx">CAMLRUNPARAM</span><span class="p">)</span> <span class="o">-></span> <span class="kc">null</span>
<span class="nx">getenv</span><span class="p">(</span><span class="nx">TMPDIR</span><span class="p">)</span> <span class="o">-></span> <span class="kc">null</span>
<span class="nx">getenv</span><span class="p">(</span><span class="nx">TEMP</span><span class="p">)</span> <span class="o">-></span> <span class="kc">null</span>
<span class="nx">Netif</span><span class="o">:</span> <span class="nx">add</span> <span class="nx">resume</span> <span class="nx">hook</span>
<span class="nx">Netif</span><span class="p">.</span><span class="nx">connect</span> <span class="mi">0</span>
<span class="nx">Netfront</span><span class="p">.</span><span class="nx">create</span><span class="o">:</span> <span class="nx">id</span><span class="o">=</span><span class="mi">0</span> <span class="nx">domid</span><span class="o">=</span><span class="mi">0</span>
<span class="nx">MAC</span><span class="o">:</span> <span class="nx">c0</span><span class="o">:</span><span class="nx">ff</span><span class="o">:</span><span class="nx">ee</span><span class="o">:</span><span class="nx">c0</span><span class="o">:</span><span class="nx">ff</span><span class="o">:</span><span class="nx">ee</span>
<span class="nx">Manager</span><span class="o">:</span> <span class="nx">connect</span>
<span class="nx">Attempt</span> <span class="nx">to</span> <span class="nx">open</span><span class="p">(</span><span class="err">/dev/urandom)!</span>
<span class="nx">Manager</span><span class="o">:</span> <span class="nx">configuring</span>
<span class="nx">DHCP</span><span class="o">:</span> <span class="nx">start</span> <span class="nx">discovery</span>
<span class="nx">Sending</span> <span class="nx">DHCP</span> <span class="nx">broadcast</span> <span class="p">(</span><span class="nx">length</span> <span class="mi">552</span><span class="p">)</span>
<span class="nx">DHCP</span> <span class="nx">response</span><span class="o">:</span>
<span class="nx">input</span> <span class="nx">ciaddr</span> <span class="mf">0.0</span><span class="p">.</span><span class="mf">0.0</span> <span class="nx">yiaddr</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.178</span>
<span class="nx">siaddr</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.5</span> <span class="nx">giaddr</span> <span class="mf">0.0</span><span class="p">.</span><span class="mf">0.0</span>
<span class="nx">chaddr</span> <span class="nx">c0ffeec0ffee00000000000000000000</span> <span class="nx">sname</span> <span class="nx">file</span>
<span class="nx">DHCP</span><span class="o">:</span> <span class="nx">offer</span> <span class="nx">received</span><span class="o">:</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.178</span>
<span class="nx">DHCP</span> <span class="nx">options</span><span class="o">:</span> <span class="nx">Offer</span> <span class="o">:</span> <span class="nx">DNS</span> <span class="nx">servers</span><span class="p">(</span><span class="mf">192.168</span><span class="p">.</span><span class="mf">56.5</span><span class="p">),</span> <span class="nx">Routers</span><span class="p">(</span><span class="mf">192.168</span><span class="p">.</span><span class="mf">56.5</span><span class="p">),</span> <span class="nx">Broadcast</span><span class="p">(</span><span class="mf">192.168</span><span class="p">.</span><span class="mf">56.255</span><span class="p">),</span> <span class="nx">Subnet</span> <span class="nx">mask</span><span class="p">(</span><span class="mf">255.255</span><span class="p">.</span><span class="mf">255.0</span><span class="p">),</span> <span class="nx">Unknown</span><span class="p">(</span><span class="mi">59</span><span class="cp">[</span><span class="mi">4</span><span class="cp">]</span><span class="p">),</span> <span class="nx">Unknown</span><span class="p">(</span><span class="mi">58</span><span class="cp">[</span><span class="mi">4</span><span class="cp">]</span><span class="p">),</span> <span class="nx">Lease</span> <span class="nx">time</span><span class="p">(</span><span class="mi">43200</span><span class="p">),</span> <span class="nx">Server</span> <span class="nx">identifer</span><span class="p">(</span><span class="mf">192.168</span><span class="p">.</span><span class="mf">56.5</span><span class="p">)</span>
<span class="nx">Sending</span> <span class="nx">DHCP</span> <span class="nx">broadcast</span> <span class="p">(</span><span class="nx">length</span> <span class="mi">552</span><span class="p">)</span>
<span class="nx">DHCP</span> <span class="nx">response</span><span class="o">:</span>
<span class="nx">input</span> <span class="nx">ciaddr</span> <span class="mf">0.0</span><span class="p">.</span><span class="mf">0.0</span> <span class="nx">yiaddr</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.178</span>
<span class="nx">siaddr</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.5</span> <span class="nx">giaddr</span> <span class="mf">0.0</span><span class="p">.</span><span class="mf">0.0</span>
<span class="nx">chaddr</span> <span class="nx">c0ffeec0ffee00000000000000000000</span> <span class="nx">sname</span> <span class="nx">file</span>
<span class="nx">DHCP</span><span class="o">:</span> <span class="nx">offer</span> <span class="nx">received</span>
<span class="nx">IPv4</span><span class="o">:</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.178</span>
<span class="nx">Netmask</span><span class="o">:</span> <span class="mf">255.255</span><span class="p">.</span><span class="mf">255.0</span>
<span class="nx">Gateways</span><span class="o">:</span> <span class="cp">[</span><span class="mf">192.168.56.5</span><span class="cp">]</span>
<span class="nx">sg</span><span class="o">:</span><span class="kc">true</span> <span class="nx">gso_tcpv4</span><span class="o">:</span><span class="kc">true</span> <span class="nx">rx_copy</span><span class="o">:</span><span class="kc">true</span> <span class="nx">rx_flip</span><span class="o">:</span><span class="kc">false</span> <span class="nx">smart_poll</span><span class="o">:</span><span class="kc">false</span>
<span class="nx">ARP</span><span class="o">:</span> <span class="nx">sending</span> <span class="nx">gratuitous</span> <span class="nx">from</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.178</span>
<span class="nx">DHCP</span> <span class="nx">offer</span> <span class="nx">received</span> <span class="nx">and</span> <span class="nx">bound</span> <span class="nx">to</span> <span class="mf">192.168</span><span class="p">.</span><span class="mf">56.178</span> <span class="nx">nm</span> <span class="mf">255.255</span><span class="p">.</span><span class="mf">255.0</span> <span class="nx">gw</span> <span class="cp">[</span><span class="mf">192.168.56.5</span><span class="cp">]</span>
<span class="nx">Manager</span><span class="o">:</span> <span class="nx">configuration</span> <span class="nx">done</span>
</pre></div>
<p>The console output shows the IP address that was assigned to the unikernel ("DHCP offer received and bound..."). In the example above the IP is 192.168.56.178. From the host operating system you should now be able to open this IP in a web browser to see the "Hello Mirage World!" message.</p>
<p>If you login to dom0 in a new terminal <code>xl list</code> will show the running domains, which now includes "www":</p>
<div class="highlight"><pre><span class="err">$</span> <span class="n">sudo</span> <span class="n">xl</span> <span class="n">list</span>
<span class="n">Name</span> <span class="n">ID</span> <span class="n">Mem</span> <span class="n">VCPUsStateTime</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="n">Domain</span><span class="o">-</span><span class="mi">0</span> <span class="mi">0</span> <span class="mi">1355</span> <span class="mi">1</span> <span class="n">r</span><span class="o">-----</span> <span class="mf">6691.4</span>
<span class="n">www</span> <span class="mi">33</span> <span class="mi">256</span> <span class="mi">1</span> <span class="o">-</span><span class="n">b</span><span class="o">----</span> <span class="mf">0.2</span>
</pre></div>
<p>To stop the unikernel, run <code>sudo xl destroy www</code>.</p>
<h3><a name="alternatives">Some alternatives</a></h3>
<p>The environment described in this post is my current development environment and is based on a Xen server running in a Virtualbox VM with the latest versions of opam and Mirage. I use a host-only second network adapter to allow access to the Mirage applications from the host running Virtualbox. </p>
<p>Mirage applications can also be compiled in <a href="http://openmirage.org/wiki/hello-world">Unix mode</a>, which produces an executable that can be executed directly in a Unix-like operating system. Currently OS X seems to be particularly well supported. This mode may often be the easiest way to debug and develop a Mirage application, but not all of Mirage's features are available in this mode and some applications may require low level access to the system - for example to block storage or network interfaces - which may not be available in this mode. </p>
<p>Another approach is to use a <a href="http://cubieboard.org">Cubieboard2</a> with a prebuilt <a href="http://github.com/mirage/xen-arm-builder">Mirage/Xen image</a> to set up a low cost, portable Xen server for development. If you want to have long running Mirage services in your local network or host your own web page this may be a good alternative. Note that compilation times can be slow on this platform compared to an x86 based VM.</p>
<p>An automated VM setup is being developed based on Debian, Vagrant and Packer <a href="http://github.com/mirage/mirage-vagrant-vms">here</a>. This can be useful if you don't want to manually perform the setup steps outlined in this post. Currently this setup uses an older version of Debian which comes with Xen 4.1, but it should be possible to upgrade to Debian Jessie or later.</p>