Add Solo5 device manifest to job_build

A user browsing a build can view what network and block devices the
unikernel expects before downloading the unikernel.
This commit is contained in:
Reynir Björnsson 2021-12-14 12:02:35 +01:00
parent 485515e47a
commit 923bc3d9d4
6 changed files with 63 additions and 8 deletions

View file

@ -50,6 +50,8 @@ depends: [
"modulectomy" "modulectomy"
"opam-graph" "opam-graph"
"tar" "tar"
"owee"
"solo5-elftool"
] ]
synopsis: "Web interface for builder" synopsis: "Web interface for builder"

View file

@ -275,11 +275,16 @@ let add_routes datadir configdir =
in in
let job_build req = let job_build req =
let datadir = Dream.global datadir_global req in
let job_name = Dream.param "job" req let job_name = Dream.param "job" req
and build = Dream.param "build" req in and build = Dream.param "build" req in
get_uuid build >>= fun uuid -> get_uuid build >>= fun uuid ->
Dream.sql req (fun conn -> Dream.sql req (fun conn ->
Model.build uuid conn >>= fun (build_id, build) -> Model.build uuid conn >>= fun (build_id, build) ->
(match build.Builder_db.Build.main_binary with
| Some main_binary ->
Model.build_artifact_by_id main_binary conn |> Lwt_result.map Option.some
| None -> Lwt_result.return None) >>= fun main_binary ->
Model.build_artifacts build_id conn >>= fun artifacts -> Model.build_artifacts build_id conn >>= fun artifacts ->
Model.builds_with_same_input_and_same_main_binary build_id conn >>= fun same_input_same_output -> Model.builds_with_same_input_and_same_main_binary build_id conn >>= fun same_input_same_output ->
Model.builds_with_different_input_and_same_main_binary build_id conn >>= fun different_input_same_output -> Model.builds_with_different_input_and_same_main_binary build_id conn >>= fun different_input_same_output ->
@ -287,15 +292,21 @@ let add_routes datadir configdir =
Model.latest_successful_build build.job_id (Some build.Builder_db.Build.platform) conn >>= fun latest -> Model.latest_successful_build build.job_id (Some build.Builder_db.Build.platform) conn >>= fun latest ->
Model.next_successful_build_different_output build_id conn >>= fun next -> Model.next_successful_build_different_output build_id conn >>= fun next ->
Model.previous_successful_build_different_output build_id conn >|= fun previous -> Model.previous_successful_build_different_output build_id conn >|= fun previous ->
(build, artifacts, same_input_same_output, different_input_same_output, same_input_different_output, latest, next, previous) (build, main_binary, artifacts, same_input_same_output, different_input_same_output, same_input_different_output, latest, next, previous)
) )
|> if_error "Error getting job build" |> if_error "Error getting job build"
~log:(fun e -> Log.warn (fun m -> m "Error getting job build: %a" pp_error e)) ~log:(fun e -> Log.warn (fun m -> m "Error getting job build: %a" pp_error e))
>>= fun (build, artifacts, same_input_same_output, different_input_same_output, same_input_different_output, latest, next, previous) -> >>= fun (build, main_binary, artifacts, same_input_same_output, different_input_same_output, same_input_different_output, latest, next, previous) ->
(match main_binary with
| Some main_binary -> Model.solo5_manifest datadir main_binary
| None -> Lwt_result.return None)
|> if_error "Error getting solo5 manifest" >>= fun solo5_manifest ->
Views.Job_build.make Views.Job_build.make
~name:job_name ~name:job_name
~build ~build
~artifacts ~artifacts
~main_binary
~solo5_manifest
~same_input_same_output ~same_input_same_output
~different_input_same_output ~different_input_same_output
~same_input_different_output ~same_input_different_output

View file

@ -6,6 +6,8 @@
opamdiff ptime.clock.os omd tar opamdiff ptime.clock.os omd tar
modulectomy modulectomy
opam-graph opam-graph
owee
solo5-elftool
) )
(flags (:standard)) (flags (:standard))
) )

View file

@ -50,6 +50,12 @@ let build_artifacts build (module Db : CONN) =
Db.collect_list Builder_db.Build_artifact.get_all_by_build build >|= Db.collect_list Builder_db.Build_artifact.get_all_by_build build >|=
List.map snd List.map snd
let solo5_manifest datadir file =
try
let buf = Owee_buf.map_binary Fpath.(to_string (datadir // file.Builder_db.localpath)) in
Lwt.return (Solo5_elftool.query_manifest buf |> Result.map Option.some)
with Owee_buf.Invalid_format _ -> Lwt_result.return None
let platforms_of_job id (module Db : CONN) = let platforms_of_job id (module Db : CONN) =
Db.collect_list Builder_db.Build.get_platforms_for_job id Db.collect_list Builder_db.Build.get_platforms_for_job id

View file

@ -21,6 +21,9 @@ val build_artifact_data : Fpath.t -> Builder_db.file ->
val build_artifacts : [`build] Builder_db.id -> Caqti_lwt.connection -> val build_artifacts : [`build] Builder_db.id -> Caqti_lwt.connection ->
(Builder_db.file list, [> Caqti_error.call_or_retrieve ]) result Lwt.t (Builder_db.file list, [> Caqti_error.call_or_retrieve ]) result Lwt.t
val solo5_manifest : Fpath.t -> Builder_db.file ->
(Solo5_elftool.mft option, [> `Msg of string ]) result Lwt.t
val platforms_of_job : [`job] Builder_db.id -> Caqti_lwt.connection -> val platforms_of_job : [`job] Builder_db.id -> Caqti_lwt.connection ->
(string list, [> Caqti_error.call_or_retrieve ]) result Lwt.t (string list, [> Caqti_error.call_or_retrieve ]) result Lwt.t

View file

@ -431,17 +431,42 @@ module Job_build = struct
in in
List.exists check artifacts List.exists check artifacts
let make_artifacts ~artifacts = let make_artifacts ~artifacts ~main_binary ~solo5_manifest =
let solo5_devices solo5_manifest =
let pp_devices =
let pp_device_name ppf = function
| Solo5_elftool.Dev_block_basic name | Solo5_elftool.Dev_net_basic name ->
Fmt.pf ppf "%S" name
in
Fmt.(list ~sep:(any ", ") pp_device_name)
in
match
List.partition (function Solo5_elftool.Dev_block_basic _ -> true | _ -> false)
solo5_manifest.Solo5_elftool.entries
with
| [], [] -> [txtf "with no devices in solo5 manifest"]
| (_::_) as block_devices, [] ->
[txtf "with block devices %a" pp_devices block_devices]
| [], ((_::_) as net_devices) ->
[txtf "with net devices %a" pp_devices net_devices]
| block_devices, net_devices ->
[txtf "with block devices %a, and net devices %a"
pp_devices block_devices pp_devices net_devices]
in
let aux (file:Builder_db.file) = let aux (file:Builder_db.file) =
let (`Hex sha256_hex) = Hex.of_cstruct file.sha256 in let (`Hex sha256_hex) = Hex.of_cstruct file.sha256 in
[ [
H.dt [ H.dt [
H.a ~a:H.[Fmt.kstr a_href "f/%a" Fpath.pp file.filepath] H.a ~a:H.[Fmt.kstr a_href "f/%a" Fpath.pp file.filepath]
[H.code [txtf "%a" Fpath.pp file.filepath]] ]; [H.code [txtf "%a" Fpath.pp file.filepath]] ];
H.dd [ H.dd ([
H.code [H.txt "SHA256:"; H.txt sha256_hex]; H.code [H.txt "SHA256:"; H.txt sha256_hex];
txtf " (%a)" Fmt.byte_size file.size; txtf " (%a)" Fmt.byte_size file.size;
]; ] @
match main_binary, solo5_manifest with
| Some main_binary, Some solo5_manifest when main_binary = file ->
(H.br () :: solo5_devices solo5_manifest)
| _ -> []);
] ]
in in
[ [
@ -539,6 +564,8 @@ module Job_build = struct
~delta ~delta
~(build:Builder_db.Build.t) ~(build:Builder_db.Build.t)
~artifacts ~artifacts
~main_binary
~solo5_manifest
~same_input_same_output ~same_input_same_output
~different_input_same_output ~different_input_same_output
~same_input_different_output ~same_input_different_output
@ -563,7 +590,7 @@ module Job_build = struct
] ]
]; ];
] ]
@ make_artifacts ~artifacts @ make_artifacts ~artifacts ~main_binary ~solo5_manifest
@ make_reproductions @ make_reproductions
~name ~name
~build ~build
@ -623,6 +650,8 @@ module Job_build = struct
~name ~name
~(build:Builder_db.Build.t) ~(build:Builder_db.Build.t)
~artifacts ~artifacts
~main_binary
~solo5_manifest
~same_input_same_output ~same_input_same_output
~different_input_same_output ~different_input_same_output
~same_input_different_output ~same_input_different_output
@ -636,6 +665,8 @@ module Job_build = struct
~delta ~delta
~build ~build
~artifacts ~artifacts
~main_binary
~solo5_manifest
~same_input_same_output ~same_input_same_output
~different_input_same_output ~different_input_same_output
~same_input_different_output ~same_input_different_output