robur-coop / mirage-noconfig

Try to infer config.ml for a MirageOS unikernel by looking at unikernel.ml
8 stars 0 forks source link

document motivation clearly #7

Open hannesm opened 4 years ago

hannesm commented 4 years ago

this aims to be a prototype for more intuitive user interaction with mirageos unikernels. the idea is to have a single file (unikernel.ml, but it may be any name) with a single functor that contains a start function. this is especially for developers new to mirageos whom we've seen struggling with the rather complex tooling.

this is a prototype for experiments, some of its results may end up in the mirage/functoria toolchain in the future (and then be simplified).

the intended workflow so far:

in another execution, if the unikernel changed (but same config.ml is generated), only the last step (mirage build) should be executed.

hannesm commented 4 years ago

this whole project started after discussion of mirage/mirage#1004 and versioning -- so atm not many unikernels explicitly define which versions of interfaces they expect (i.e. mirage-clock {>=2.0.0 & <3.0.0} - though they could in config.ml by adding package ~min:"2.0.0" ~max:"3.0.0" "mirage-clock"), which leads to breakages over time (the mirage tool itself cannot infer that since it may be run in a different universe than where the unikernel was developed). Now, proposing to add the above to config.ml would lead to mention mirage-clock 4 times, which is a bit excessive (once in foreign, once in register, once as package, once as functor argument), and the idea that most pain when developing MirageOS unikernels is the bookkeeping with config.ml and inconsistencies between generated main.ml and unikernel.ml -- so who needs config.ml anyways (it also turned out to be not really flexible enough, see #9 #6 -- though that may be technical reasons of not using it correctly)? a goal is to remove the pain as demonstrated in https://github.com/cfcs/eye-of-mirage/blob/0fb468d1ae84f43b35b5f457ab5bb691923cccba/config.ml.

hannesm commented 4 years ago

a laundry list of other issues with the current mirage configure / mirage build workflow:

A.1 (hello with s/time/pclock/ and s/default_time/default_posix_clock/)

File "main.ml", line 10, characters 36-42:
10 | module Unikernel1 = Unikernel.Hello(Pclock)
                                         ^^^^^^
Error: Signature mismatch:
       ...
       The value `sleep_ns' is required but not provided
       File "src/mirage_time.ml", line 32, characters 2-32:
         Expected declaration
Command exited with code 2.
run ['ocamlbuild' '-use-ocamlfind' '-classic-display' '-quiet' '-tags'
     'predicate(mirage_unix),warn(A-4-41-42-44),debug,bin_annot,strict_sequence,principal,safe_string,thread,color(always)'
     '-pkgs'
     'duration,functoria-runtime,lwt,mirage-bootvar-unix,mirage-clock-unix,mirage-logs,mirage-runtime,mirage-types,mirage-types-lwt,mirage-unix'
     '-cflags' '-g' '-lflags' '-g' '-tag-line' '<static*.*>: warn(-32-34)'
     '-Xs' '_build-solo5-hvt,_build-ukvm' 'main.native']: exited with 10
*** Error code 1

A.2 (hello with additional pclock)

File "main.ml", line 10, characters 20-44:
10 | module Unikernel1 = Unikernel.Hello(OS.Time)(Pclock)
                         ^^^^^^^^^^^^^^^^^^^^^^^^
Error: This module is not a functor; it has type
       sig val start : 'a -> unit Lwt.t end
Command exited with code 2.
run ['ocamlbuild' '-use-ocamlfind' '-classic-display' '-quiet' '-tags'
     'predicate(mirage_unix),warn(A-4-41-42-44),debug,bin_annot,strict_sequence,principal,safe_string,thread,color(always)'
     '-pkgs'
     'duration,functoria-runtime,lwt,mirage-bootvar-unix,mirage-clock-unix,mirage-logs,mirage-runtime,mirage-types,mirage-types-lwt,mirage-unix'
     '-cflags' '-g' '-lflags' '-g' '-tag-line' '<static*.*>: warn(-32-34)'
     '-Xs' '_build-solo5-hvt,_build-ukvm' 'main.native']: exited with 10
*** Error code 1

Stop.
make: stopped in /usr/home/hannes/devel/mirage/mirage-skeleton/tutorial/hello

A.3 (hello with pclock, but failed to put the additional argument to start):

File "main.ml", line 37, characters 2-18:
37 |   Unikernel1.start _time1 _pclock1
       ^^^^^^^^^^^^^^^^
Error: This function has type 'a -> unit Lwt.t
       It is applied to too many arguments; maybe you forgot a `;'.
Command exited with code 2.
run ['ocamlbuild' '-use-ocamlfind' '-classic-display' '-quiet' '-tags'
     'predicate(mirage_unix),warn(A-4-41-42-44),debug,bin_annot,strict_sequence,principal,safe_string,thread,color(always)'
     '-pkgs'
     'duration,functoria-runtime,lwt,mirage-bootvar-unix,mirage-clock-unix,mirage-logs,mirage-runtime,mirage-types,mirage-types-lwt,mirage-unix'
     '-cflags' '-g' '-lflags' '-g' '-tag-line' '<static*.*>: warn(-32-34)'
     '-Xs' '_build-solo5-hvt,_build-ukvm' 'main.native']: exited with 10
*** Error code 1

Stop.
make: stopped in /usr/home/hannes/devel/mirage/mirage-skeleton/tutorial/hello

A.4 (hello with wrong order in unikernel.ml)

File "main.ml", line 10, characters 36-43:
10 | module Unikernel1 = Unikernel.Hello(OS.Time)(Pclock)
                                         ^^^^^^^
Error: Signature mismatch:
       Modules do not match:
         sig type 'a io = 'a Lwt.t val sleep_ns : int64 -> unit Lwt.t end
       is not included in
         Mirage_clock.PCLOCK
       The value `period_d_ps' is required but not provided
       File "src/mirage_clock.ml", line 41, characters 2-45:
         Expected declaration
       The value `current_tz_offset_s' is required but not provided
       File "src/mirage_clock.ml", line 36, characters 2-43:
         Expected declaration
       The value `now_d_ps' is required but not provided
       File "src/mirage_clock.ml", line 30, characters 2-33:
         Expected declaration
       The value `disconnect' is required but not provided
       File "src/mirage_device.mli", line 45, characters 2-30:
         Expected declaration
       The type `t' is required but not provided
       File "src/mirage_clock.ml", line 28, characters 31-44:
         Expected declaration
Command exited with code 2.
run ['ocamlbuild' '-use-ocamlfind' '-classic-display' '-quiet' '-tags'
     'predicate(mirage_unix),warn(A-4-41-42-44),debug,bin_annot,strict_sequence,principal,safe_string,thread,color(always)'
     '-pkgs'
     'duration,functoria-runtime,lwt,mirage-bootvar-unix,mirage-clock-unix,mirage-logs,mirage-runtime,mirage-types,mirage-types-lwt,mirage-unix'
     '-cflags' '-g' '-lflags' '-g' '-tag-line' '<static*.*>: warn(-32-34)'
     '-Xs' '_build-solo5-hvt,_build-ukvm' 'main.native']: exited with 10
*** Error code 1

Stop.
make: stopped in /usr/home/hannes/devel/mirage/mirage-skeleton/tutorial/hello