this repo has no description

env and cwd

Changed files
+42 -9
src
vendor
void
+28 -4
src/lib/shelter/shelter_main.ml
···
build : Store.Build.t;
args : string list;
time : int64;
diff : Diff.t;
}
[@@deriving repr]
···
(list s);
store
-
let run (_config : config) _fs clock _proc
(((H.Store ((module S), store) : entry H.t) as s), ctx) = function
| Set_mode mode ->
with_latest ~default:(fun _ -> Ok (s, ctx)) s @@ fun (_, entry) ->
···
args = command;
time = 0L;
diff = [];
})
s
@@ fun (_, e) -> e
···
let void =
Void.empty
|> Void.rootfs ~mode:entry.mode rootfs
-
|> Void.exec [ "/bin/ash"; "-c"; String.concat " " command ]
in
Switch.run @@ fun sw ->
let start = Mtime_clock.now () in
···
Void.exit_status proc |> Eio.Promise.await |> Void.to_eio_status
in
let stop = Mtime_clock.now () in
let span = Mtime.span start stop in
let time = Mtime.Span.to_uint64_ns span in
(* Add command to history regardless of exit status *)
···
in
if res = `Exited 0 then
if entry.mode = RW then
-
Ok { hash_entry with build = Build new_cid; time }
-
else Ok hash_entry
else Error (Eio.Process.Child_error res)
in
match new_entry with
···
build : Store.Build.t;
args : string list;
time : int64;
+
env : string list;
+
cwd : string;
diff : Diff.t;
}
[@@deriving repr]
···
(list s);
store
+
let run (_config : config) fs clock _proc
(((H.Store ((module S), store) : entry H.t) as s), ctx) = function
| Set_mode mode ->
with_latest ~default:(fun _ -> Ok (s, ctx)) s @@ fun (_, entry) ->
···
args = command;
time = 0L;
diff = [];
+
(* TODO: extract with fetch *)
+
env = [];
+
cwd = "/";
})
s
@@ fun (_, e) -> e
···
let void =
Void.empty
|> Void.rootfs ~mode:entry.mode rootfs
+
|> Void.cwd entry.cwd
+
|> Void.exec ~env:entry.env
+
[
+
"/bin/ash";
+
"-c";
+
String.concat " " command ^ " && env > /shelter-env";
+
]
in
Switch.run @@ fun sw ->
let start = Mtime_clock.now () in
···
Void.exit_status proc |> Eio.Promise.await |> Void.to_eio_status
in
let stop = Mtime_clock.now () in
+
(* Extract env *)
+
let env_path = Eio.Path.(fs / rootfs / "shelter-env") in
+
let env = Eio.Path.(load env_path) |> String.split_on_char '\n' in
+
Eio.Path.unlink env_path;
+
let cwd =
+
List.find_map
+
(fun v ->
+
match Astring.String.cut ~sep:"=" v with
+
| Some ("PWD", dir) -> Some dir
+
| _ -> None)
+
env
+
|> Option.value ~default:hash_entry.cwd
+
in
let span = Mtime.span start stop in
let time = Mtime.Span.to_uint64_ns span in
(* Add command to history regardless of exit status *)
···
in
if res = `Exited 0 then
if entry.mode = RW then
+
Ok { hash_entry with build = Build new_cid; time; env; cwd }
+
else Ok { hash_entry with cwd; env }
else Error (Eio.Process.Child_error res)
in
match new_entry with
+2
src/lib/shelter/shelter_main.mli
···
build : Store.Build.t;
args : string list;
time : int64;
diff : Diff.t;
}
[@@deriving repr]
···
build : Store.Build.t;
args : string list;
time : int64;
+
env : string list;
+
cwd : string;
diff : Diff.t;
}
[@@deriving repr]
+7 -4
vendor/void/src/void.ml
···
type void = {
args : string list;
rootfs : (string * mode) option;
mounts : mount list;
}
···
type path = string
-
let empty = { args = []; rootfs = None; mounts = [] }
let actions v : Fork_action.t list =
let root, tmpfs, root_mode =
···
in
let args = match v.args with [] -> failwith "No exec" | args -> args in
let e =
-
Process.Fork_action.execve (List.hd args) ~env:[||]
~argv:(Array.of_list args)
in
(* Process mount point points *)
···
let mounts = pivot_root root root_flags tmpfs mounts in
let uid, gid = Unix.(getuid (), getgid ()) in
let user_namespace = map_uid_gid ~uid ~gid in
-
[ user_namespace; mounts; e ]
let rootfs ~mode path v = { v with rootfs = Some (path, mode) }
-
let exec args v = { v with args }
let mount ~mode ~src ~tgt v =
let mode = if mode = R then Mount.Flags.ms_rdonly else Mount.Flags.empty in
···
type void = {
args : string list;
+
env : string list;
+
cwd : string;
rootfs : (string * mode) option;
mounts : mount list;
}
···
type path = string
+
let empty = { args = []; env = []; rootfs = None; mounts = []; cwd = "/" }
let actions v : Fork_action.t list =
let root, tmpfs, root_mode =
···
in
let args = match v.args with [] -> failwith "No exec" | args -> args in
let e =
+
Process.Fork_action.execve (List.hd args) ~env:(Array.of_list v.env)
~argv:(Array.of_list args)
in
(* Process mount point points *)
···
let mounts = pivot_root root root_flags tmpfs mounts in
let uid, gid = Unix.(getuid (), getgid ()) in
let user_namespace = map_uid_gid ~uid ~gid in
+
[ user_namespace; mounts; Process.Fork_action.chdir v.cwd; e ]
let rootfs ~mode path v = { v with rootfs = Some (path, mode) }
+
let cwd cwd v = { v with cwd }
+
let exec ?(env=[]) args v = { v with args; env }
let mount ~mode ~src ~tgt v =
let mode = if mode = R then Mount.Flags.ms_rdonly else Mount.Flags.empty in
+5 -1
vendor/void/src/void.mli
···
val mount : mode:mode -> src:path -> tgt:path -> void -> void
-
val exec : string list -> void -> void
(** Make a void configuration ready to be spawned *)
val spawn : sw:Eio.Switch.t -> void -> t
···
val mount : mode:mode -> src:path -> tgt:path -> void -> void
+
+
val cwd : string -> void -> void
+
(** Set the current working directory *)
+
+
val exec : ?env:string list -> string list -> void -> void
(** Make a void configuration ready to be spawned *)
val spawn : sw:Eio.Switch.t -> void -> t