summary refs log tree commit diff
path: root/nixos/doc/manual/from_md/development
diff options
context:
space:
mode:
authorpennae <82953136+pennae@users.noreply.github.com>2022-03-13 19:57:32 +0000
committerGitHub <noreply@github.com>2022-03-13 19:57:32 +0000
commitaa7b1297080cbf6ca0d9c3a51e071358b62a491c (patch)
tree8d76ace316e338f361087795657cbca0604dcb82 /nixos/doc/manual/from_md/development
parent1203e7fc416979acf6eec2d43ad51c2c25fdb573 (diff)
parent40a35299fa30421de85a56f084f6c59d05ea883e (diff)
downloadnixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.tar
nixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.tar.gz
nixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.tar.bz2
nixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.tar.lz
nixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.tar.xz
nixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.tar.zst
nixpkgs-aa7b1297080cbf6ca0d9c3a51e071358b62a491c.zip
Merge pull request #154113 from pennae/systemd-escaping
nixos: add functions and documentation for escaping systemd Exec* directives
Diffstat (limited to 'nixos/doc/manual/from_md/development')
-rw-r--r--nixos/doc/manual/from_md/development/writing-modules.chapter.xml49
1 files changed, 49 insertions, 0 deletions
diff --git a/nixos/doc/manual/from_md/development/writing-modules.chapter.xml b/nixos/doc/manual/from_md/development/writing-modules.chapter.xml
index e33c24f4f12..367731eda09 100644
--- a/nixos/doc/manual/from_md/development/writing-modules.chapter.xml
+++ b/nixos/doc/manual/from_md/development/writing-modules.chapter.xml
@@ -122,6 +122,25 @@
     services) and <literal>systemd.timers</literal> (the list of
     commands to be executed periodically by <literal>systemd</literal>).
   </para>
+  <para>
+    Care must be taken when writing systemd services using
+    <literal>Exec*</literal> directives. By default systemd performs
+    substitution on <literal>%&lt;char&gt;</literal> specifiers in these
+    directives, expands environment variables from
+    <literal>$FOO</literal> and <literal>${FOO}</literal>, splits
+    arguments on whitespace, and splits commands on
+    <literal>;</literal>. All of these must be escaped to avoid
+    unexpected substitution or splitting when interpolating into an
+    <literal>Exec*</literal> directive, e.g. when using an
+    <literal>extraArgs</literal> option to pass additional arguments to
+    the service. The functions
+    <literal>utils.escapeSystemdExecArg</literal> and
+    <literal>utils.escapeSystemdExecArgs</literal> are provided for
+    this, see <link linkend="exec-escaping-example">Example: Escaping in
+    Exec directives</link> for an example. When using these functions
+    system environment substitution should <emphasis>not</emphasis> be
+    disabled explicitly.
+  </para>
   <anchor xml:id="locate-example" />
   <para>
     <emphasis role="strong">Example: NixOS Module for the
@@ -184,6 +203,36 @@ in {
   };
 }
 </programlisting>
+  <anchor xml:id="exec-escaping-example" />
+  <para>
+    <emphasis role="strong">Example: Escaping in Exec
+    directives</emphasis>
+  </para>
+  <programlisting language="bash">
+{ config, lib, pkgs, utils, ... }:
+
+with lib;
+
+let
+  cfg = config.services.echo;
+  echoAll = pkgs.writeScript &quot;echo-all&quot; ''
+    #! ${pkgs.runtimeShell}
+    for s in &quot;$@&quot;; do
+      printf '%s\n' &quot;$s&quot;
+    done
+  '';
+  args = [ &quot;a%Nything&quot; &quot;lang=\${LANG}&quot; &quot;;&quot; &quot;/bin/sh -c date&quot; ];
+in {
+  systemd.services.echo =
+    { description = &quot;Echo to the journal&quot;;
+      wantedBy = [ &quot;multi-user.target&quot; ];
+      serviceConfig.Type = &quot;oneshot&quot;;
+      serviceConfig.ExecStart = ''
+        ${echoAll} ${utils.escapeSystemdExecArgs args}
+      '';
+    };
+}
+</programlisting>
   <xi:include href="option-declarations.section.xml" />
   <xi:include href="option-types.section.xml" />
   <xi:include href="option-def.section.xml" />