(* * Copyright (c) 2015 Gabriel Radanne * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *) module Action = Functoria.Action module Key = Functoria.Key (** {2 Documentation helper} *) let mirage_section = "MIRAGE PARAMETERS" let unikernel_section = "UNIKERNEL PARAMETERS" let pp_group = Fmt.(option ~none:(any "the unikernel") @@ fmt "the %s group") (** {2 Special keys} *) (** {3 Mode} *) type mode_unix = [ `Unix | `MacOSX ] type mode_xen = [ `Xen | `Qubes ] type mode_solo5 = [ `Hvt | `Spt | `Virtio | `Muen | `Genode ] type mode_unikraft = [ `Firecracker | `QEMU ] type mode = [ mode_unix | mode_xen | mode_solo5 | mode_unikraft ] let (target_conv : mode Cmdliner.Arg.conv), target_doc_alts = let enum = [ ("unix", `Unix); ("macosx", `MacOSX); ("xen", `Xen); ("virtio", `Virtio); ("hvt", `Hvt); ("muen", `Muen); ("qubes", `Qubes); ("genode", `Genode); ("spt", `Spt); ("unikraft-firecracker", `Firecracker); ("unikraft-qemu", `QEMU); ] in let conv = Cmdliner.Arg.enum enum in (conv, Cmdliner.Arg.doc_alts_enum enum) let pp_target fmt m = Cmdliner.Arg.conv_printer target_conv fmt m let default_target = match Sys.getenv "MIRAGE_DEFAULT_TARGET" with | "unix" -> `Unix | s -> Fmt.failwith "invalid default target: %S" s | exception Not_found -> ( match Action.run @@ Action.run_cmd_out Bos.Cmd.(v "uname" % "-s") with | Ok "Darwin" -> `MacOSX | _ -> `Unix) let target = let doc = Fmt.str "Target platform to compile the unikernel for. Valid values are: %s" target_doc_alts in let doc = Cmdliner.Arg.info ~docs:mirage_section ~docv:"TARGET" ~doc [ "t"; "target" ] ~env:(Cmdliner.Cmd.Env.info "MODE") in let key = Key.Arg.opt target_conv default_target doc in Key.create "target" key let is_unix = Key.match_ Key.(value target) @@ function | #mode_unix -> true | #mode_xen | #mode_solo5 | #mode_unikraft -> false let is_solo5 = Key.match_ Key.(value target) @@ function | #mode_solo5 -> true | #mode_xen | #mode_unix | #mode_unikraft -> false let is_xen = Key.match_ Key.(value target) @@ function | #mode_xen -> true | #mode_solo5 | #mode_unix | #mode_unikraft -> false let is_unikraft = Key.match_ Key.(value target) @@ function | #mode_unikraft -> true | #mode_solo5 | #mode_unix | #mode_xen -> false (** {2 General mirage keys} *) let configure_key ?(group = "") ~doc ~default conv name = let prefix = if group = "" then group else group ^ "-" in let doc = Cmdliner.Arg.info ~docs:unikernel_section ~docv:(String.uppercase_ascii name) ~doc [ prefix ^ name ] in let key = Key.Arg.opt conv default doc in Key.create (prefix ^ name) key (** {3 File system keys} *) let kv_ro ?group () = let enum = [ ("crunch", `Crunch); ("direct", `Direct) ] in let conv = Cmdliner.Arg.enum enum in let doc = Fmt.str "Use %s pass-through implementation for %a." (Cmdliner.Arg.doc_alts_enum enum) pp_group group in configure_key ~doc ?group ~default:`Crunch conv "kv_ro" (** {3 Block device keys} *) let block ?group () = let enum = [ ("xenstore", `XenstoreId); ("file", `BlockFile); ("ramdisk", `Ramdisk) ] in let conv = Cmdliner.Arg.enum enum in let doc = Fmt.str "Use %s pass-through implementation for %a." (Cmdliner.Arg.doc_alts_enum enum) pp_group group in configure_key ~doc ?group ~default:`Ramdisk conv "block" (** {3 Stack keys} *) let dhcp ?group () = let doc = Fmt.str "Enable dhcp for %a." pp_group group in configure_key ~doc ?group ~default:false Cmdliner.Arg.bool "dhcp" let net ?group () : [ `Host | `OCaml ] option Key.key = let enum = [ ("host", `Host); ("socket", `Host); ("direct", `OCaml); ("ocaml", `OCaml); ] in let conv = Cmdliner.Arg.enum enum in let doc = Fmt.str "Use %s group for %a." (Cmdliner.Arg.doc_alts_enum enum) pp_group group in configure_key ~doc ?group ~default:None (Cmdliner.Arg.some conv) "net" include Key