X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;ds=sidebyside;f=mclu_boot.ml;h=451beb8125c7c48463a3433298e14ff0667fb4a0;hb=f2a17d80287a2afc8f2204035536c81950649e2e;hp=6927363ba8245a904ad3a221493eaaa7ce45c996;hpb=b29a837444aa5827b683bee5a7457fbb32305ae5;p=mclu.git
diff --git a/mclu_boot.ml b/mclu_boot.ml
index 6927363..451beb8 100644
--- a/mclu_boot.ml
+++ b/mclu_boot.ml
@@ -33,13 +33,28 @@ let set_memory s =
eprintf "mclu: don't understand --memory parameter '%s'
Try something like --memory 1G\n" s;
exit 1
+let size = ref 0L (* 0 = default *)
+let set_size s =
+ try size := bytes_of_human_size s
+ with Not_found ->
+ eprintf "mclu: don't understand --size parameter '%s'
+Try something like --size 20G\n" s;
+ exit 1
+let timezone = ref "" (* "" = no timezone set *)
let vcpus = ref 0 (* 0 = choose for me *)
+let open_console = ref false
+let open_viewer = ref false
+
let get_arg_speclist () = Arg.align [
+ "--console", Arg.Set open_console, " Open the serial console";
"--cpus", Arg.Set_int vcpus, "n Number of virtual CPUs";
"--memory", Arg.String set_memory, "nnG Amount of RAM to give guest";
"--ram", Arg.String set_memory, "nnG Amount of RAM to give guest";
+ "--size", Arg.String set_size, "nnG Size of disk to give guest";
+ "--timezone", Arg.Set_string timezone, "TZ Set timezone of guest";
"--vcpus", Arg.Set_int vcpus, "n Number of virtual CPUs";
+ "--viewer", Arg.Set open_viewer, " Open the graphical console";
]
let boot ~verbose template name =
@@ -56,6 +71,18 @@ Try `mclu list --templates' to list all known templates.\n" template;
(* Probe the template for various features. *)
let template_info = Template.probe ~verbose template_filename in
+ (* Check --size is not too small. *)
+ let size =
+ match !size, template_info.Template.minimum_size with
+ | 0L, None -> 0L (* virt-builder default *)
+ | 0L, Some min_size -> (* go with template minimum size *)
+ min_size
+ | size, Some min_size when size < min_size ->
+ eprintf "mclu: --size parameter is smaller than the minimum specified by the template (%s).\n"
+ (human_size min_size);
+ exit 1
+ | size, _ -> size in (* go with user-specified size *)
+
(* Decide how much RAM we will give the guest. This affects our
* choice of node, so do it early.
*)
@@ -134,7 +161,8 @@ Try: `mclu on %s'\n" hostname hostname;
(* Where we upload the template and image on remote. *)
let format, extension = "qcow2", "qcow2" in
- let remote_filename = sprintf "/tmp/mclu%s.sh" (string_random8 ()) in
+ let remote_template = sprintf "/tmp/mclu%s.sh" (string_random8 ()) in
+ let remote_template_wrapper = sprintf "/tmp/mclu%s.sh" (string_random8 ()) in
let remote_image = sprintf "/var/tmp/%s.%s" name extension in
(* Get ready to generate the guest XML. *)
@@ -212,8 +240,11 @@ Try: `mclu on %s'\n" hostname hostname;
" mac_addr network_model in
let xml = xml ^ "\
+
+
+
-
+
@@ -225,21 +256,53 @@ Try: `mclu on %s'\n" hostname hostname;
" in
- (* Copy the template to remote and build the guest. *)
+ (* Copy the template to remote. *)
let cmd =
sprintf "scp %s root@%s:%s"
- (quote template_filename) (quote hostname) remote_filename in
+ (quote template_filename) (quote hostname) remote_template in
if verbose then printf "%s\n%!" cmd;
if Sys.command cmd <> 0 then (
eprintf "mclu: scp template to remote failed\n";
exit 1
);
- let cmd =
+
+ (* Create a wrapper script that sets the variables and runs the
+ * template. This just avoids complex quoting.
+ *)
+ let () =
+ let chan = open_out remote_template_wrapper in
+ let fpf fs = fprintf chan fs in
+ fpf "#!/bin/sh\n";
(* XXX Don't hard-code network_bridge here. *)
- sprintf "ssh root@%s LIBGUESTFS_BACKEND_SETTINGS=network_bridge=br0 %s build %s %s %s"
- (quote hostname) remote_filename
- (quote template_info.Template.base_image) (quote remote_image)
- format in
+ fpf "export LIBGUESTFS_BACKEND_SETTINGS=network_bridge=br0\n";
+ fpf "export base_image=%s\n" (quote template_info.Template.base_image);
+ fpf "export format=%s\n" (quote format);
+ fpf "export name=%s\n" (quote name);
+ fpf "export output=%s\n" (quote remote_image);
+ (match size with
+ | 0L -> ()
+ | size -> fpf "export size=%s\n" (quote (sprintf "--size %Ldb" size))
+ );
+ (match !timezone with
+ | "" -> ()
+ | tz -> fpf "export timezone=%s\n" (quote (sprintf "--timezone %s" tz))
+ );
+ fpf "%s build\n" remote_template;
+ close_out chan;
+ Unix.chmod remote_template_wrapper 0o755 in
+
+ let cmd =
+ sprintf "scp %s root@%s:%s"
+ (quote remote_template_wrapper) (quote hostname)
+ (quote remote_template_wrapper) in
+ if verbose then printf "%s\n%!" cmd;
+ if Sys.command cmd <> 0 then (
+ eprintf "mclu: scp template wrapper to remote failed\n";
+ exit 1
+ );
+
+ let cmd =
+ sprintf "ssh root@%s %s" (quote hostname) (quote remote_template_wrapper) in
if verbose then printf "%s\n%!" cmd;
if Sys.command cmd <> 0 then (
eprintf "mclu: remote build failed\n";
@@ -247,15 +310,25 @@ Try: `mclu on %s'\n" hostname hostname;
);
(* Start the guest. *)
- try
- let conn =
- let name = node.MS.node_status.MS.node.Mclu_conf.libvirt_uri in
- C.connect ~name () in
- let dom = D.create_xml conn xml [] in
- printf "mclu: %s:%s started\n" hostname (D.get_name dom)
- with Libvirt.Virterror msg ->
- eprintf "mclu: %s: %s\n" hostname (Libvirt.Virterror.to_string msg);
- exit 1
+ let dom =
+ try
+ let conn =
+ let name = node.MS.node_status.MS.node.Mclu_conf.libvirt_uri in
+ C.connect ~name () in
+ let dom = D.create_xml conn xml [] in
+ printf "mclu: %s:%s started\n" hostname (D.get_name dom);
+ dom
+ with Libvirt.Virterror msg ->
+ eprintf "mclu: %s: %s\n" hostname (Libvirt.Virterror.to_string msg);
+ exit 1 in
+
+ (* Graphical console? *)
+ if !open_viewer then
+ Mclu_viewer.viewer ~verbose ~host:hostname (D.get_name dom);
+
+ (* Serial console? (Interactive, so run it last) *)
+ if !open_console then
+ Mclu_console.console ~verbose ~host:hostname (D.get_name dom)
let run ~verbose = function
| [ template; name ] ->