Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reproducible builds #102

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

Reproducible builds #102

wants to merge 12 commits into from

Conversation

PizieDust
Copy link
Collaborator

@PizieDust PizieDust commented Jan 9, 2025

Related to #54

This PR checks if there is an update to a unikernel from builds.robur.coop and if there's an update it displays the differences between the current unikernel and the update.
At the moment, this PR only displays the diff and doesn't update the unikernel binary (yet).

@PizieDust PizieDust added the enhancement New feature or request label Jan 9, 2025
@PizieDust PizieDust requested a review from hannesm January 9, 2025 15:15
@PizieDust PizieDust self-assigned this Jan 9, 2025
@hannesm
Copy link
Contributor

hannesm commented Jan 10, 2025

The PR title is confusing.

@@ -301,6 +301,21 @@ struct
reply);
[]

let single_unikernel albatross ~user_name ~unikernel_name =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we name this differently? I'm a bit confused by "single_unikernel" and "unikernel_info_one".

| Error msg ->
Logs.err (fun m -> m "error while communicating with albatross: %s" msg);
[]
| Ok (_hdr, `Success (`Unikernel_info unikernels)) -> unikernels
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about directly here constraining to a single unikernel... and return (Name.t * Unikernel.info) option instead of having to deal with that at the call sites?

| Error (`Msg err) ->
Middleware.redirect_to_error
~data:(`String ("Builder_web request: " ^ err))
~title:"Update Error" ~api_meth:false `Internal_server_error reqd ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we be more specific than "Update error"?

| Error (`Msg err) ->
Middleware.redirect_to_error
~data:(`String ("Builder_web request: " ^ err))
~title:"Update Error" ~api_meth:false `Internal_server_error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above. It would help to provide some context.

| Error (`Msg err) ->
Middleware.redirect_to_error
~data:(`String ("Builder_web request: " ^ err))
~title:"Update Error" ~api_meth:false `Internal_server_error
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above

>>= fun unikernels ->
if List.length unikernels > 0 then
let name, unikernel = List.hd unikernels in
let job_response_body = ref "" in
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is it possible to have a different API than passing an (empty) reference cell to the send_request?

~title:"Update Error" ~api_meth:false
`Internal_server_error reqd ()
| Ok latest_job_data -> (
match
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the match if done on boolean values always looks strange to me.

Why not use if?

String.equal latest_job_data.uuid current_job_data.uuid
with
| true ->
Logs.warn (fun m ->
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure about the log level, warn feels a bit strange.

a_href
("/unikernel/update/"
^ Option.value ~default:""
(Vmm_core.Name.name u_name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand this Option here -- how can a unikernel_single be done where there's u_name being None?

@@ -93,6 +97,350 @@ module Status = struct
|> Yojson.Basic.to_string
end

module Builder_web = struct
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should that better be in a separate file -- builder_web.ml?

}

type duniverse = { name : string; value_ : string }
type duniverse_detailed_diff = { name : string }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that's pretty verbose -- can we remove this type (and use string instead)?

left : duniverse list;
right : duniverse list;
detailed_diff : duniverse_detailed_diff list;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand why these type definitions differ from builder-web -- are the types in builder-web not ergonomic enough? should we separate the opamdiff subpackage into a custom opam package and depend on that in mollymawk (to share the type definitions and avoid code duplication)?

Comment on lines +424 to +441
let send_request url response_body =
let body_f _ acc chunk =
response_body := !response_body ^ chunk;
Lwt.return acc
in
Http_lwt_client.request ~follow_redirect:true
~headers:[ ("Accept", "application/json") ]
url body_f ()
>>= function
| Error (`Msg err) -> Lwt.return (Error (`Msg err))
| Ok (resp, ()) -> (
match resp.Http_lwt_client.status with
| `OK -> Lwt.return (Ok response_body)
| _ ->
Lwt.return
(Error
(`Msg (Format.asprintf "%a" Http_lwt_client.pp_response resp)))
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let send_request url response_body =
let body_f _ acc chunk =
response_body := !response_body ^ chunk;
Lwt.return acc
in
Http_lwt_client.request ~follow_redirect:true
~headers:[ ("Accept", "application/json") ]
url body_f ()
>>= function
| Error (`Msg err) -> Lwt.return (Error (`Msg err))
| Ok (resp, ()) -> (
match resp.Http_lwt_client.status with
| `OK -> Lwt.return (Ok response_body)
| _ ->
Lwt.return
(Error
(`Msg (Format.asprintf "%a" Http_lwt_client.pp_response resp)))
)
let send_request url =
let body = "" in
let body_f _ acc chunk =
Lwt.return (acc ^ chunk)
in
Http_lwt_client.request ~follow_redirect:true
~headers:[ ("Accept", "application/json") ]
url body_f body
>>= function
| Error (`Msg err) -> Lwt.return (Error (`Msg err))
| Ok (resp, body) -> (
match resp.Http_lwt_client.status with
| `OK -> Lwt.return (Ok body)
| _ ->
Lwt.return
(Error
(`Msg (Format.asprintf "%a" Http_lwt_client.pp_response resp)))
)

this way we avoid the reference cell, and deliver the body as output

Comment on lines +515 to +517
let bytes_to_megabytes bytes =
let megabytes = float_of_int bytes /. (1024.0 *. 1024.0) in
Printf.sprintf "%.2f" megabytes
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we write the "MB" as well to the string?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Development

Successfully merging this pull request may close these issues.

2 participants