X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=mclu_boot.ml;h=451beb8125c7c48463a3433298e14ff0667fb4a0;hb=f2a17d80287a2afc8f2204035536c81950649e2e;hp=43ab049f6c3eaf2c6d427a3cc1ee6a08988b9bd2;hpb=82f07dbeb68320d31497a49f33585ca0a839ea7a;p=mclu.git diff --git a/mclu_boot.ml b/mclu_boot.ml index 43ab049..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. *) @@ -228,30 +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 \ -base_image=%s \ -format=%s \ -name=%s \ -output=%s \ -%s build" - (quote hostname) - (quote template_info.Template.base_image) (* base_image *) - format (* format *) - name (* name *) - (quote remote_image) (* output *) - remote_filename 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"; @@ -259,15 +310,25 @@ output=%s \ ); (* 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 ] ->