Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Allow more control of slave environment variables

The slave_env parameter now also allows a pass-through behavior
where the slave process inherits all environment variables from the
master. The default whitelist has been changed to include only
"OCAMLRUNPARAM".
  • Loading branch information...
commit 687173cf3b184b5204278aab9d87c0bb0d7fa26e 1 parent 29dd53c
Andre Nathan authored
10 README.md
Source Rendered
@@ -73,7 +73,7 @@ the function `Release.master_slave`.
73 73 -> ?background:bool
74 74 -> ?syslog:bool
75 75 -> ?privileged:bool
76   - -> ?slave_env:string list
  76 + -> ?slave_env:[`Inherit | `Keep of string list]
77 77 -> ?control:(Lwt_io.file_name * Release_ipc.handler)
78 78 -> ?main:((unit -> (int * Lwt_unix.file_descr) list) -> unit Lwt.t)
79 79 -> lock_file:Lwt_io.file_name
@@ -89,9 +89,11 @@ described in more details below.
89 89 The `background` argument indicates whether `Release.daemon` will be called.
90 90 The `syslog` argument indicates if the syslog facilities from the `Lwt_log`
91 91 module will be enabled. If the master process is supposed to run as root, then
92   -the `privileged` argument must be set to `true`. The `slave_env` argument is
93   -a whitelist of environment variables that are passed to the slave process.
94   -By default it includes only `TZ`.
  92 +the `privileged` argument must be set to `true`. The slave process environment
  93 +variables can be controlled by the `slave_env` argument; they can be inherited
  94 +from the master process, or filtered via a whitelist of variable names. By
  95 +default, only the `OCAMLRUNPARAM` environment variable is passed to slave
  96 +processes.
95 97
96 98 The `master_slave` function will create a lock file in the path given in the
97 99 `lock_file` argument. This file will contain the PID of the master process.
15 lib/core/release.ml
@@ -182,10 +182,13 @@ let getenv k =
182 182 with Not_found ->
183 183 None
184 184
185   -let restrict_env allowed =
186   - let setenv env k =
187   - Option.may_default env (fun v -> v::env) (getenv k) in
188   - Array.of_list (List.fold_left setenv ["PATH=/bin:/usr/bin"] allowed)
  185 +let restrict_env = function
  186 + | `Inherit ->
  187 + None
  188 + | `Keep allowed ->
  189 + let setenv env k =
  190 + Option.may_default env (fun v -> v::env) (getenv k) in
  191 + Some (Array.of_list (List.fold_left setenv [] allowed))
189 192
190 193 let rec exec_process cmd ipc_handler slave_env check_death_rate =
191 194 lwt () = check_death_rate () in
@@ -195,7 +198,7 @@ let rec exec_process cmd ipc_handler slave_env check_death_rate =
195 198 exec_process cmd ipc_handler slave_env check_death_rate in
196 199 Lwt_process.with_process_none
197 200 ~stdin:(`FD_move (Lwt_unix.unix_file_descr slave_fd))
198   - ~env:(restrict_env slave_env)
  201 + ?env:(restrict_env slave_env)
199 202 cmd
200 203 (handle_process master_fd reexec) in
201 204 let _slave_t =
@@ -256,7 +259,7 @@ let setup_syslog () =
256 259 fprintf stderr "could not setup syslog: %s" err;
257 260 exit 1
258 261
259   -let default_slave_env = ["TZ"; "OCAMLRUNPARAM"]
  262 +let default_slave_env = `Keep ["TZ"; "OCAMLRUNPARAM"]
260 263
261 264 let master_slaves ?(background = true) ?(syslog = true) ?(privileged = true)
262 265 ?(slave_env = default_slave_env) ?control ?main ~lock_file
12 lib/core/release.mli
@@ -40,7 +40,7 @@ val master_slave :
40 40 -> ?background:bool
41 41 -> ?syslog:bool
42 42 -> ?privileged:bool
43   - -> ?slave_env:string list
  43 + -> ?slave_env:[`Inherit | `Keep of string list]
44 44 -> ?control:(Lwt_io.file_name * Release_ipc.handler)
45 45 -> ?main:((unit -> (int * Lwt_unix.file_descr) list) -> unit Lwt.t)
46 46 -> lock_file:Lwt_io.file_name
@@ -61,9 +61,11 @@ val master_slave :
61 61 [privileged] indicates if the master process is to be run as [root].
62 62 Defaults to [true].
63 63
64   - [slave_env] is a list of allowed environment variable names for the slave
65   - process. The slave will only have access to variables in this list.
66   - Defaults to [["TZ"]].
  64 + [slave_env] controls the environment variables available to the slave
  65 + process. If [slave_env] is [`Inherit], the slave process will inherit
  66 + the master's full environment. Otherwise, if [slave_env] is
  67 + [`Keep env], the slave process will only have access to the variables
  68 + in the [env] list. Defaults to [`Keep ["OCAMLRUNPARAM"]].
67 69
68 70 [control], if present, is a tuple containing a path to a UNIX domain
69 71 socket that will be created for communication with external process and
@@ -86,7 +88,7 @@ val master_slaves :
86 88 ?background:bool
87 89 -> ?syslog:bool
88 90 -> ?privileged:bool
89   - -> ?slave_env:string list
  91 + -> ?slave_env:[`Inherit | `Keep of string list]
90 92 -> ?control:(Lwt_io.file_name * Release_ipc.handler)
91 93 -> ?main:((unit -> (int * Lwt_unix.file_descr) list) -> unit Lwt.t)
92 94 -> lock_file:Lwt_io.file_name
1  lib_test/master.ml
@@ -50,6 +50,7 @@ let () =
50 50 ~syslog:false
51 51 ~lock_file:(sprintf "./_build/release%s.pid" exec)
52 52 ~control:("./_build/master.socket", control_connection_handler)
  53 + ~slave_env:(`Keep ["OCAMLRUNPARAM"; "RELEASE"])
53 54 ~main:store_slave_connections
54 55 ~slaves:[ slave_cmd, ipc_handler, 1
55 56 ; helper_cmd, lwt_ignore, 1 ]
8 lib_test/slave.ml
@@ -41,7 +41,15 @@ let rec produce_ipc fd =
41 41 else
42 42 produce_ipc fd
43 43
  44 +let check_env () =
  45 + try_lwt
  46 + let env = Sys.getenv "RELEASE" in
  47 + Lwt_log.notice_f "environment check: RELEASE=%s" env
  48 + with Not_found ->
  49 + Lwt_log.notice_f "environment RELEASE is empty"
  50 +
44 51 let main fd =
  52 + lwt () = check_env () in
45 53 let read_t = consume_ipc fd in
46 54 let write_t = produce_ipc fd in
47 55 read_t <?> write_t

0 comments on commit 687173c

Please sign in to comment.
Something went wrong with that request. Please try again.