Allow an external kernel to be used to boot guests.
[mclu.git] / mclu_boot.ml
index 16b8ac9..5aa8290 100644 (file)
@@ -165,6 +165,9 @@ Try: `mclu on %s'\n" hostname hostname;
   let remote_template_wrapper = sprintf "/tmp/mclu%s.sh" (string_random8 ()) in
   let xml_template_wrapper = sprintf "/tmp/mclu%s.sh" (string_random8 ()) in
   let remote_image = sprintf "/var/tmp/%s.%s" name extension in
+  let remote_external_kernel_dir = sprintf "/var/tmp/%s.boot" name in
+  let remote_external_kernel = sprintf "/var/tmp/%s.boot/kernel" name in
+  let remote_external_initrd = sprintf "/var/tmp/%s.boot/initrd" name in
 
   (* Get ready to generate the guest XML. *)
   let vcpus = !vcpus in
@@ -184,9 +187,23 @@ Try: `mclu on %s'\n" hostname hostname;
   <memory unit='KiB'>%Ld</memory>
   <currentMemory unit='KiB'>%Ld</currentMemory>
   <vcpu>%d</vcpu>
+" name (memory /^ 1024L) (memory /^ 1024L) vcpus in
+
+    let xml = xml ^ "\
   <os>
     <type>hvm</type>
     <boot dev='hd'/>
+" in
+
+    let xml = xml ^
+      if template_info.Template.needs_external_kernel then
+        sprintf "\
+    <kernel>%s</kernel>
+    <initrd>%s</initrd>
+" remote_external_kernel remote_external_initrd
+      else "" in
+
+    let xml = xml ^ "\
   </os>
   <features>
     <acpi/>
@@ -203,7 +220,7 @@ Try: `mclu on %s'\n" hostname hostname;
   <on_reboot>restart</on_reboot>
   <on_crash>restart</on_crash>
   <devices>
-" name (memory /^ 1024L) (memory /^ 1024L) vcpus in
+" in
 
     let xml = xml ^ sprintf "\
   <disk type='file' device='disk'>
@@ -270,6 +287,8 @@ Try: `mclu on %s'\n" hostname hostname;
       let fpf fs = fprintf chan fs in
       fpf "#!/bin/sh\n";
       fpf "export format=%s\n" (quote format);
+      fpf "export initrd=%s\n" (quote remote_external_initrd);
+      fpf "export kernel=%s\n" (quote remote_external_kernel);
       fpf "export mac_addr=%s\n" (quote mac_addr);
       fpf "export memory_kb=%Ld\n" (memory /^ 1024L);
       fpf "export name=%s\n" (quote name);
@@ -326,7 +345,8 @@ Try: `mclu on %s'\n" hostname hostname;
   let () =
     let chan = open_out remote_template_wrapper in
     let fpf fs = fprintf chan fs in
-    fpf "#!/bin/sh\n";
+    fpf "#!/bin/bash\n";
+    fpf "set -e\n";
     (* XXX Don't hard-code network_bridge here. *)
     fpf "export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=br0\n";
     fpf "export base_image=%s\n" (quote template_info.Template.base_image);
@@ -342,6 +362,15 @@ Try: `mclu on %s'\n" hostname hostname;
     | tz -> fpf "export timezone=%s\n" (quote (sprintf "--timezone %s" tz))
     );
     fpf "%s build\n" remote_template;
+    if template_info.Template.needs_external_kernel then (
+      fpf "rm -rf %s\n" (quote remote_external_kernel_dir);
+      fpf "mkdir %s\n" (quote remote_external_kernel_dir);
+      fpf "pushd %s\n" (quote remote_external_kernel_dir);
+      fpf "virt-builder --get-kernel %s\n" (quote remote_image);
+      fpf "ln vmlinuz-* kernel\n";
+      fpf "ln init* initrd\n";
+      fpf "popd\n";
+    );
     close_out chan;
     Unix.chmod remote_template_wrapper 0o755 in