about summary refs log tree commit diff
path: root/nixos/lib
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/lib
parent1203e7fc416979acf6eec2d43ad51c2c25fdb573 (diff)
parent40a35299fa30421de85a56f084f6c59d05ea883e (diff)
Merge pull request #154113 from pennae/systemd-escaping
nixos: add functions and documentation for escaping systemd Exec* directives
Diffstat (limited to 'nixos/lib')
-rw-r--r--nixos/lib/utils.nix20
1 files changed, 20 insertions, 0 deletions
diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix
index 733f9ca522bec..ae68c3920c5bb 100644
--- a/nixos/lib/utils.nix
+++ b/nixos/lib/utils.nix
@@ -45,6 +45,26 @@ rec {
    replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
    (removePrefix "/" s);
 
+  # Quotes an argument for use in Exec* service lines.
+  # systemd accepts "-quoted strings with escape sequences, toJSON produces
+  # a subset of these.
+  # Additionally we escape % to disallow expansion of % specifiers. Any lone ;
+  # in the input will be turned it ";" and thus lose its special meaning.
+  # Every $ is escaped to $$, this makes it unnecessary to disable environment
+  # substitution for the directive.
+  escapeSystemdExecArg = arg:
+    let
+      s = if builtins.isPath arg then "${arg}"
+        else if builtins.isString arg then arg
+        else if builtins.isInt arg || builtins.isFloat arg then toString arg
+        else throw "escapeSystemdExecArg only allows strings, paths and numbers";
+    in
+      replaceChars [ "%" "$" ] [ "%%" "$$" ] (builtins.toJSON s);
+
+  # Quotes a list of arguments into a single string for use in a Exec*
+  # line.
+  escapeSystemdExecArgs = concatMapStringsSep " " escapeSystemdExecArg;
+
   # Returns a system path for a given shell package
   toShellPath = shell:
     if types.shellPackage.check shell then