Skip to content

Commit

Permalink
Fail if there are jobs registered without any arguments.
Browse files Browse the repository at this point in the history
This ensures that toplevel expressions in the unikernels are properly evaluated.

Fixes mirage#873 mirage#1426
  • Loading branch information
hannesm committed Jun 19, 2023
1 parent 3c42117 commit eb550ed
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 6 deletions.
11 changes: 11 additions & 0 deletions lib/functoria/impl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,17 @@ and 'a device = ('a, abstract) Device.t

let abstract t = Abstract t

let app_has_no_arguments = function
| App { args ; _ } ->
(match args with
| Cons _ -> false
| _ -> true)
| Dev { args ; _ } ->
(match args with
| Cons _ -> false
| _ -> true)
| If _ -> false

(* Devices *)

let mk_dev ~args ~deps dev = Dev { dev; args; deps }
Expand Down
4 changes: 4 additions & 0 deletions lib/functoria/impl.mli
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ type 'a device = ('a, abstract) Device.t
val abstract : 'a t -> abstract
(** [abstract i] is [i] with its type erased. *)

val app_has_no_arguments : 'a t -> bool
(** [app_has_no_arguments i] is [true] if the argument list is empty and it is
an application, [false] otherwise. *)

val pp : 'a t Fmt.t
(** [pp] is the pretty-printer for module implementations. *)

Expand Down
6 changes: 6 additions & 0 deletions lib/mirage/mirage.ml
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,12 @@ let ( ++ ) acc x =

let register ?(argv = default_argv) ?tracing ?(reporter = default_reporter ())
?keys:extra_keys ?packages ?src name jobs =
if List.exists Functoria.Impl.app_has_no_arguments jobs then
invalid_arg "Your configuration includes a job without arguments. \
Please add a dependency in your config.ml: use \
`let main = Mirage.main \"Unikernel.hello\" (noop @-> job) \
register \"hello\" [ main $ noop ]` \
instead of `.. job .. [ main ]`.";
let first = [ keys argv; backtrace; randomize_hashtables; gc_control ] in
let reporter = if reporter == no_reporter then None else Some reporter in
let init = Some first ++ reporter ++ tracing in
Expand Down
4 changes: 2 additions & 2 deletions test/mirage/help/config.ml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
open Mirage

let main = main "App" job
let main = main "App" (job @-> job)

let key =
let doc = Key.Arg.info ~doc:"How to say hello." [ "hello" ] in
Key.(create "hello" Arg.(opt string "Hello World!" doc))

let () = register ~keys:[ Key.v key ] "noop" [ main ]
let () = register ~keys:[ Key.v key ] "noop" [ main $ noop ]
9 changes: 9 additions & 0 deletions test/mirage/job-no-device/config.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
open Mirage

let main = main "App" job

let key =
let doc = Key.Arg.info ~doc:"How to say hello." [ "hello" ] in
Key.(create "hello" Arg.(opt string "Hello World!" doc))

let () = register ~keys:[ Key.v key ] ~src:`None "noop" [ main ]
6 changes: 6 additions & 0 deletions test/mirage/job-no-device/configure.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
$ export MIRAGE_DEFAULT_TARGET=unix

Configure
$ ./config.exe configure
Fatal error: exception Invalid_argument("Your configuration includes a job without arguments. Please add a dependency in your config.ml: use `let main = Mirage.main \"Unikernel.hello\" (noop @-> job) register \"hello\" [ main $ noop ]` instead of `.. job .. [ main ]`.")
[2]
7 changes: 7 additions & 0 deletions test/mirage/job-no-device/dune
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(executable
(name config)
(libraries mirage))

(cram
(package mirage)
(deps config.exe))
4 changes: 2 additions & 2 deletions test/mirage/query/config.ml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
open Mirage

let main = main "App" job
let main = main "App" (job @-> job)

let key =
let doc = Key.Arg.info ~doc:"How to say hello." [ "hello" ] in
Key.(create "hello" Arg.(opt string "Hello World!" doc))

let () = register ~keys:[ Key.v key ] ~src:`None "noop" [ main ]
let () = register ~keys:[ Key.v key ] ~src:`None "noop" [ main $ noop ]
4 changes: 2 additions & 2 deletions test/mirage/query/config_dash_in_name.ml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
open Mirage

let main = main "App" job
let main = main "App" (job @-> job)

let key =
let doc = Key.Arg.info ~doc:"How to say hello." [ "hello" ] in
Key.(create "hello" Arg.(opt string "Hello World!" doc))

let () = register ~keys:[ Key.v key ] ~src:`None "noop-functor.v0" [ main ]
let () = register ~keys:[ Key.v key ] ~src:`None "noop-functor.v0" [ main $ noop ]

0 comments on commit eb550ed

Please sign in to comment.