@@ -221,66 +221,7 @@ module Make (Raw_store : S.STORE) (Sandbox : S.SANDBOX) = struct
221221 | `Shell shell ->
222222 k ~base ~context: {context with shell}
223223
224- let export_env base : Config.env Lwt.t =
225- Os. pread [" docker" ; " image" ; " inspect" ;
226- " --format" ; {| {{range .Config. Env }}{{print . " \x00 " }}{{end}}| };
227- " --" ; base] > |= fun env ->
228- String. split_on_char '\x00' env
229- |> List. filter_map (function
230- | "\n " -> None
231- | kv ->
232- match Astring.String. cut ~sep: " =" kv with
233- | None -> Fmt. failwith " Invalid environment in Docker image %S (should be 'K=V')" kv
234- | Some _ as pair -> pair
235- )
236-
237- let copy_to_log ~src ~dst =
238- let buf = Bytes. create 4096 in
239- let rec aux () =
240- Lwt_unix. read src buf 0 (Bytes. length buf) >> = function
241- | 0 -> Lwt. return_unit
242- | n -> Build_log. write dst (Bytes. sub_string buf 0 n) >> = aux
243- in
244- aux ()
245-
246- let with_container ~log base fn =
247- Os. with_pipe_from_child (fun ~r ~w ->
248- (* We might need to do a pull here, so log the output to show progress. *)
249- let copy = copy_to_log ~src: r ~dst: log in
250- Os. pread ~stderr: (`FD_move_safely w) [" docker" ; " create" ; " --" ; base] >> = fun cid ->
251- copy > |= fun () ->
252- String. trim cid
253- ) >> = fun cid ->
254- Lwt. finalize
255- (fun () -> fn cid)
256- (fun () -> Os. exec ~stdout: `Dev_null [" docker" ; " rm" ; " --" ; cid])
257-
258- let get_base t ~log base =
259- log `Heading (Fmt. strf " (from %a)" Sexplib.Sexp. pp_hum (Atom base));
260- let id = Sha256. to_hex (Sha256. string base) in
261- Store. build t.store ~id ~log (fun ~cancelled :_ ~log tmp ->
262- Log. info (fun f -> f " Base image not present; importing %S..." base);
263- let rootfs = tmp / " rootfs" in
264- Os. sudo [" mkdir" ; " --mode=755" ; " --" ; rootfs] >> = fun () ->
265- (* Lwt_process.exec ("", [| "docker"; "pull"; "--"; base |]) >>= fun _ -> *)
266- with_container ~log base (fun cid ->
267- Os. with_pipe_between_children @@ fun ~r ~w ->
268- let exporter = Os. exec ~stdout: (`FD_move_safely w) [" docker" ; " export" ; " --" ; cid] in
269- let tar = Os. sudo ~stdin: (`FD_move_safely r) [" tar" ; " -C" ; rootfs; " -xf" ; " -" ] in
270- exporter >> = fun () ->
271- tar
272- ) >> = fun () ->
273- export_env base >> = fun env ->
274- Os. write_file ~path: (tmp / " env" )
275- (Sexplib.Sexp. to_string_hum Saved_context. (sexp_of_t {env})) >> = fun () ->
276- Lwt_result. return ()
277- )
278- >>!= fun id ->
279- let path = Option. get (Store. result t.store id) in
280- let { Saved_context. env } = Saved_context. t_of_sexp (Sexplib.Sexp. load_sexp (path / " env" )) in
281- Lwt_result. return (id, env)
282-
283- let rec build ~scope t context { Obuilder_spec. child_builds; from = base ; ops } =
224+ let rec build ~scope t context { Obuilder_spec. child_builds; from; ops } =
284225 let rec aux context = function
285226 | [] -> Lwt_result. return context
286227 | (name , child_spec ) :: child_builds ->
@@ -291,7 +232,18 @@ module Make (Raw_store : S.STORE) (Sandbox : S.SANDBOX) = struct
291232 aux context child_builds
292233 in
293234 aux context child_builds >>!= fun context ->
294- get_base t ~log: context.Context. log base >>!= fun (id , env ) ->
235+ let log = context.Context. log in
236+ let id = Sha256. to_hex (Sha256. string from) in
237+ let f = Sandbox. from ~from ~log t.sandbox in
238+ (Store. build t.store ~id ~log f >>!= fun id ->
239+ (match Store. result t.store id with
240+ | Some path ->
241+ if Sys. file_exists @@ path / " env" then begin
242+ let { Saved_context. env } = Saved_context. t_of_sexp (Sexplib.Sexp. load_sexp (path / " env" )) in
243+ Lwt_result. return (id, env)
244+ end else Lwt_result. return (id, [] )
245+ | None -> Lwt_result. return (id, [] )))
246+ >>!= fun (id , env ) ->
295247 let context = { context with env = context.env @ env } in
296248 run_steps t ~context ~base: id ops
297249
@@ -325,7 +277,12 @@ module Make (Raw_store : S.STORE) (Sandbox : S.SANDBOX) = struct
325277 (* Get the base image first, before starting the timer. *)
326278 let switch = Lwt_switch. create () in
327279 let context = Context. v ~switch ~log ~src_dir: " /tmp" () in
328- get_base t ~log healthcheck_base >> = function
280+ let id = Sha256. to_hex (Sha256. string healthcheck_base) in
281+ let f = Sandbox. from ~from: healthcheck_base ~log t.sandbox in
282+ (Store. build t.store ~id ~log f >>!= fun id ->
283+ let path = Option. get (Store. result t.store id) in
284+ let { Saved_context. env } = Saved_context. t_of_sexp (Sexplib.Sexp. load_sexp (path / " env" )) in
285+ Lwt_result. return (id, env)) >> = function
329286 | Error (`Msg _ ) as x -> Lwt. return x
330287 | Error `Cancelled -> failwith " Cancelled getting base image (shouldn't happen!)"
331288 | Ok (id , env ) ->
0 commit comments