Introducing modules, in order to expand the types of builders we support
R7J4254ZZREVMWXXDUM772GPLZSCZSIJKOLEAI33WUF2CPS3X6WQC
BQ4E3XLAVS2AQAUYRGN6SZ4J35KQ2KIH7BBT2JNZXSPKKCGX7DYAC
Q6PRCWS6ENGORBXL4N7AYECRKTELQSGUPOCPIPYVABXYKFUAUFAQC
GM4Q532K5D2F7K5POJUDG7Q6FIDRGKOVGWSJOA4CODLKLQN3W24QC
VAKO4QFFT35EXJIEQ7PHSUYVBSSUW5P2HSQDIJSTZCTOWQZKPHXQC
KOWYPLMX4TCQANL33QW5VQTKWBQVCMOVLBQUQCTOK6YVQUHZJR5QC
UWQB743KR36X6A6JVNK3VH6KMEFUHOUT6ZS2Y2SWIJR55JSF5WQAC
ODUDDQRY373JMDR6W2BHUWSKEU6TEICQMNZIAIFKJPNUA5UN3C4QC
HX4TXY2DTPEEQPU6CMHSD3X4VX7A4OKV7N3HT3QZKSNHNAZOK7GQC
7Q4257EPUSDGELWJYF23GKUXGJGOB2QJGPKN3JS3C272IEX6EQ2QC
exception Error of H2.Client_connection.error
type store_path = { path : string }
let ubuntu_release connection ~release ~arch ~repository =
let req =
Elpegrpc.Elpe.UbuntuReleaseRequest.make ~release ~arch ~repository ()
in
let open Ocaml_protoc_plugin in
let open Elpegrpc.Elpe in
let encode, decode = Service.make_client_functions Elpe.ubuntuRelease in
let enc = encode req |> Writer.contents in
Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuRelease"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.unary enc ~f:(fun decoder ->
let+ decoder = decoder in
match decoder with
| Some decoder -> (
Reader.create decoder |> decode |> function
| Ok v -> v
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e)))
| None -> Elpe.Derivation.Response.make ()))
()
let ubuntu_package connection ~index ~name =
let req = Elpegrpc.Elpe.UbuntuPackageRequest.make ~index ~name () in
let open Ocaml_protoc_plugin in
let open Elpegrpc.Elpe in
let encode, decode = Service.make_client_functions Elpe.ubuntuPackage in
let enc = encode req |> Writer.contents in
Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuPackage"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.unary enc ~f:(fun decoder ->
let+ decoder = decoder in
match decoder with
| Some decoder -> (
Reader.create decoder |> decode |> function
| Ok v -> v
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e)))
| None -> Elpe.Derivation.Response.make ()))
()
module Rust = struct
include Rust
end
let derivation connection ~name ~builder ~paths ~target ~output_hash =
let req =
match output_hash with
| None ->
Elpegrpc.Elpe.DerivationRequest.make ~name ~builder ~paths ~target ()
| Some output_hash ->
Elpegrpc.Elpe.DerivationRequest.make ~name ~builder ~paths ~target
~output_hash ()
in
let open Ocaml_protoc_plugin in
let open Elpegrpc.Elpe in
let encode, decode = Service.make_client_functions Elpe.derivation in
let enc = encode req |> Writer.contents in
let result = ref None in
let* _ = Client.call ~service:"elpe.Elpe" ~rpc:"Derivation"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.server_streaming enc ~f:(fun responses ->
Lwt_stream.iter_s
(fun str ->
Reader.create str |> decode |> function
| Ok (`Ok path) -> (result := Some(`Ok path); Lwt.return ())
| Ok (`Error path) -> (result := Some(`Error path); Lwt.return ())
| Ok (`Stdout buf) -> (
let buf = Bytes.unsafe_to_string buf in
Printf.printf "%s" buf; Lwt.return ())
| Ok (`Stderr buf) -> (
let buf = Bytes.unsafe_to_string buf in
Printf.eprintf "%s" buf; Lwt.return ())
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e))
| _ -> Lwt.return ())
responses
))
()
in
match !result with
Some v -> Lwt.return v
| None -> assert false
exception Error of H2.Client_connection.error
method virtual name : string
(* Returns the script to setup the build process, also used in shells. *)
method setup : string Lwt.t = Lwt.return ""
(* List of paths resulting from building the package. *)
method build : build_result Lwt.t = failwith "Not implemented"
end
let backend_conn = ref None
let ubuntu ?(release = "plucky") name =
object
in
let* index =
Lwt_list.map_p
(fun repository ->
let* res = ubuntu_release c ~release ~arch:Amd64 ~repository in
let res, _ = Result.get_ok res in
match res with
| `Ok r -> Lwt.return r.destdir
| `Error e -> failwith e
| _ -> assert false)
[ "main"; "universe" ]
| `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
| `Error e -> failwith e
| _ -> assert false
end
class virtual std_derivation =
object (self)
inherit derivation
method environment : (string * string) List.t Lwt.t = Lwt.return []
method build_inputs : derivation list Lwt.t = Lwt.return []
method target : string = "x86_64-linux-gnu"
val extra_paths : string list ref = ref []
method output_hash : string option Lwt.t = Lwt.return None
method derivation (drv : derivation) =
let* path = drv#build in
extra_paths := path.destdir @ !extra_paths;
Lwt.return path
method local_src p =
let path_drv =
object
inherit derivation
method name = Filename.basename p
method! build =
let c =
match !backend_conn with
| None -> failwith "no conn"
| Some c -> c
in
let* res = add_path c p in
let res, _ = Result.get_ok res in
match res with
| `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
| `Error e -> failwith e
| _ -> assert false
end
in
let* built = path_drv#build in
extra_paths := built.destdir @ !extra_paths;
Lwt.return (List.hd built.destdir)
method src : string Lwt.t = failwith ("No src defined for " ^ self#name)
method! setup =
let* bash = self#derivation (ubuntu "bash-static") in
let bash = List.hd bash.destdir in
let* build_inputs = self#build_inputs in
let* () =
Lwt_list.iter_p
(fun d ->
let* p = d#build in
extra_paths := p.destdir @ !extra_paths;
Lwt.return ())
build_inputs
in
let* post_setup = self#post_setup in
Lwt.return
("#!" ^ bash
^ "/usr/bin/bash-static\n\
export PATH=/usr/bin\n\
export LIBRARY_PATH=/lib/" ^ self#target ^ ":/lib64/" ^ self#target
^ ":/usr/lib:/usr/lib64:/usr/lib/x86_64-linux-gnu\n"^post_setup^"\n")
method post_setup = Lwt.return ""
method pre_unpack = Lwt.return ""
method post_unpack = Lwt.return ""
method unpack_phase =
let* src = self#src in
let* all = Lwt.all [ self#pre_unpack; self#post_unpack ] in
match all with
| pre :: post :: _ -> Lwt.return (pre ^ "\ncp -R " ^ src ^ "/* .\n" ^ post)
| _ -> assert false
method pre_configure = Lwt.return ""
method post_configure = Lwt.return ""
method configure_phase =
let* all = Lwt.all [ self#pre_configure; self#post_configure ] in
match all with
| pre :: post :: _ ->
Lwt.return
(pre ^ "\nif [[ -e configure ]]; then ./configure; fi\n" ^ post)
| _ -> assert false
method pre_build = Lwt.return ""
method post_build = Lwt.return ""
method build_phase =
let* all = Lwt.all [ self#pre_build; self#post_build ] in
match all with
| pre :: post :: _ ->
Lwt.return (pre ^ "\nif [[ -e Makefile ]]; then make; fi\n" ^ post)
| _ -> assert false
method pre_install = Lwt.return ""
method post_install = Lwt.return ""
method install_phase =
let* all = Lwt.all [ self#pre_install; self#post_install ] in
match all with
| pre :: post :: _ ->
Lwt.return
(pre ^ "\nif [[ -e Makefile ]]; then make install; fi\n" ^ post)
| _ -> assert false
method! build =
let* phases =
Lwt.all
[
self#setup;
self#unpack_phase;
self#configure_phase;
self#build_phase;
self#install_phase;
]
in
let builder = String.concat "\n" phases in
let c =
match !backend_conn with None -> failwith "no conn" | Some c -> c
in
let* output_hash = self#output_hash in
let* r =
derivation c ~name:self#name ~builder ~paths:!extra_paths
~target:self#target ~output_hash
in
match r with
open Lwt.Syntax
type store_path = { path : string }
type build_result = { destdir : string list; paths : string list }
let backend_conn = ref None
class virtual derivation =
object
method virtual name : string
val stdout_ : Buffer.t option ref = ref None
val stderr_ : Buffer.t option ref = ref None
method stdout = stdout_
method stderr = stderr_
method set_stdout =
let buf = Buffer.create 1024 in
stdout_ := Some buf;
buf
method set_stderr =
let buf = Buffer.create 1024 in
stderr_ := Some buf;
buf
(* Returns the script to setup the build process, also used in shells. *)
method setup : string Lwt.t = Lwt.return ""
(* List of paths resulting from building the package. *)
method build : build_result Lwt.t = failwith "Not implemented"
end
open Grpc_lwt
let ubuntu_release connection ~release ~arch ~repository =
let req =
Elpegrpc.Elpe.UbuntuReleaseRequest.make ~release ~arch ~repository ()
in
let open Ocaml_protoc_plugin in
let encode, decode =
Service.make_client_functions Elpegrpc.Elpe.Elpe.ubuntuRelease
in
let enc = encode req |> Writer.contents in
Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuRelease"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.unary enc ~f:(fun decoder ->
let+ decoder = decoder in
match decoder with
| Some decoder -> (
Reader.create decoder |> decode |> function
| Ok v -> v
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e)))
| None -> Elpegrpc.Elpe.Elpe.Derivation.Response.make ()))
()
let ubuntu_package connection ~index ~name =
let req = Elpegrpc.Elpe.UbuntuPackageRequest.make ~index ~name () in
let open Ocaml_protoc_plugin in
let encode, decode =
Service.make_client_functions Elpegrpc.Elpe.Elpe.ubuntuPackage
in
let enc = encode req |> Writer.contents in
Client.call ~service:"elpe.Elpe" ~rpc:"UbuntuPackage"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.unary enc ~f:(fun decoder ->
let+ decoder = decoder in
match decoder with
| Some decoder -> (
Reader.create decoder |> decode |> function
| Ok v -> v
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e)))
| None -> Elpegrpc.Elpe.Elpe.Derivation.Response.make ()))
()
let ubuntu ?(release = "plucky") name =
object
inherit derivation
method name = name
method! build =
let c =
match !backend_conn with None -> failwith "no conn" | Some c -> c
in
let* index =
Lwt_list.map_p
(fun repository ->
let* res = ubuntu_release c ~release ~arch:Amd64 ~repository in
let res, _ = Result.get_ok res in
match res with
| `Ok r -> Lwt.return r.destdir
| `Error e -> failwith e
| _ -> assert false)
[ "main"; "universe" ]
in
let index = List.concat index in
let* res = ubuntu_package c ~index ~name in
let res, _ = Result.get_ok res in
match res with
| `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
| `Error e -> failwith e
| _ -> assert false
end
let derivation ?(stdout = None) ?(stderr = None) connection ~name ~builder
~paths ~target ~output_hash =
let req =
match output_hash with
| None ->
Elpegrpc.Elpe.DerivationRequest.make ~name ~builder ~paths ~target ()
| Some output_hash ->
Elpegrpc.Elpe.DerivationRequest.make ~name ~builder ~paths ~target
~output_hash ()
in
let open Ocaml_protoc_plugin in
let encode, decode =
Service.make_client_functions Elpegrpc.Elpe.Elpe.derivation
in
let enc = encode req |> Writer.contents in
let result = ref None in
let* _ =
Client.call ~service:"elpe.Elpe" ~rpc:"Derivation"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.server_streaming enc ~f:(fun responses ->
Lwt_stream.iter_s
(fun str ->
Reader.create str |> decode |> function
| Ok (`Ok path) ->
result := Some (`Ok path);
Lwt.return ()
| Ok (`Error path) ->
result := Some (`Error path);
Lwt.return ()
| Ok (`Stdout buf) ->
let _ =
match stdout with
| Some b -> Buffer.add_bytes b buf
| None ->
let buf = Bytes.to_string buf in
Printf.printf "%s" buf
in
Lwt.return ()
| Ok (`Stderr buf) ->
let _ =
match stderr with
| Some b -> Buffer.add_bytes b buf
| None ->
let buf = Bytes.to_string buf in
Printf.printf "%s" buf
in
Lwt.return ()
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e))
| _ -> Lwt.return ())
responses))
()
in
match !result with Some v -> Lwt.return v | None -> assert false
class virtual std_derivation =
object (self)
inherit derivation
method environment : (string * string) List.t Lwt.t = Lwt.return []
method build_inputs : derivation list Lwt.t = Lwt.return []
method target : string = "x86_64-linux-gnu"
val extra_paths : string list ref = ref []
val extra_paths_h : (string, unit) Hashtbl.t = Hashtbl.create 16
method output_hash : string option Lwt.t = Lwt.return None
method derivation (drv : derivation) =
let* path = drv#build in
List.fold_right
(fun r () ->
if Hashtbl.find_opt extra_paths_h r = None then
let _ = Hashtbl.add extra_paths_h r () in
extra_paths := r :: !extra_paths
else ())
path.destdir ();
Lwt.return path
method src : derivation Lwt.t = failwith ("No src defined for " ^ self#name)
method! setup =
let* bash = self#derivation (ubuntu "bash-static") in
let bash = List.hd bash.destdir in
let* build_inputs = self#build_inputs in
let* paths =
Lwt_list.map_p
(fun d ->
let* p = d#build in
extra_paths := p.destdir @ !extra_paths;
Lwt.return p.destdir)
build_inputs
in
let path =
List.fold_left
(List.fold_left (fun acc path ->
(if acc = "" then acc ^ path else acc ^ ":" ^ path) ^ "/usr/bin"))
"" paths
in
let* post_setup = self#post_setup in
Lwt.return
("#!" ^ bash ^ "/usr/bin/bash-static\nexport PATH=" ^ path
^ "\nexport LIBRARY_PATH=/lib/" ^ self#target ^ ":/lib64/" ^ self#target
^ ":/usr/lib:/usr/lib64:/usr/lib/x86_64-linux-gnu\n" ^ post_setup ^ "\n"
)
method post_setup = Lwt.return ""
method pre_unpack = Lwt.return ""
method post_unpack = Lwt.return ""
method unpack_phase =
let* src = self#src in
let* src_built = src#build in
extra_paths := src_built.destdir @ !extra_paths;
let* all = Lwt.all [ self#pre_unpack; self#post_unpack ] in
match all with
| pre :: post :: _ ->
Lwt.return
(pre ^ "\ncp -R " ^ List.hd src_built.destdir ^ "/. .\n" ^ post)
| _ -> assert false
method pre_configure = Lwt.return ""
method post_configure = Lwt.return ""
method configure_phase =
let* all = Lwt.all [ self#pre_configure; self#post_configure ] in
match all with
| pre :: post :: _ ->
Lwt.return
(pre ^ "\nif [[ -e configure ]]; then ./configure; fi\n" ^ post)
| _ -> assert false
method pre_build = Lwt.return ""
method post_build = Lwt.return ""
method build_phase =
let* all = Lwt.all [ self#pre_build; self#post_build ] in
match all with
| pre :: post :: _ ->
Lwt.return (pre ^ "\nif [[ -e Makefile ]]; then make; fi\n" ^ post)
| _ -> assert false
method pre_install = Lwt.return ""
method post_install = Lwt.return ""
method install_phase =
let* all = Lwt.all [ self#pre_install; self#post_install ] in
match all with
| pre :: post :: _ ->
Lwt.return
(pre ^ "\nif [[ -e Makefile ]]; then make install; fi\n" ^ post)
| _ -> assert false
method! build =
let* phases =
Lwt.all
[
self#setup;
self#unpack_phase;
self#configure_phase;
self#build_phase;
self#install_phase;
]
in
let builder = String.concat "\n" phases in
let c =
match !backend_conn with None -> failwith "no conn" | Some c -> c
in
let* output_hash = self#output_hash in
let* r =
derivation c ~name:self#name ~builder ~paths:!extra_paths
~stdout:!(self#stdout) ~stderr:!(self#stderr) ~target:self#target
~output_hash
in
match r with
| `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
| `Error e -> failwith e
| _ -> assert false
end
let http ~url ~hash_algorithm ~hash =
object
inherit derivation
method name = "http"
method! build =
let connection =
match !backend_conn with None -> failwith "no conn" | Some c -> c
in
let req =
Elpegrpc.Elpe.AddUrlRequest.make ~url ~hash_algorithm ~hash ()
in
let* res =
let open Ocaml_protoc_plugin in
let encode, decode =
Service.make_client_functions Elpegrpc.Elpe.Elpe.addUrl
in
let enc = encode req |> Writer.contents in
Client.call ~service:"elpe.Elpe" ~rpc:"AddUrl"
~do_request:
(H2_lwt_unix.Client.request connection ~error_handler:(fun _ ->
failwith "Error"))
~handler:
(Client.Rpc.unary enc ~f:(fun decoder ->
let+ decoder = decoder in
match decoder with
| Some decoder -> (
Reader.create decoder |> decode |> function
| Ok v -> v
| Error e ->
failwith
(Printf.sprintf "Could not decode request: %s"
(Result.show_error e)))
| None -> Elpegrpc.Elpe.Elpe.Derivation.Response.make ()))
()
in
let res, _ = Result.get_ok res in
match res with
| `Ok r -> Lwt.return { destdir = r.destdir; paths = r.paths }
| `Error e -> failwith e
| _ -> assert false
end