about summary refs log tree commit diff
path: root/nixos/lib
diff options
context:
space:
mode:
authorgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>2022-10-21 00:05:50 +0000
committerGitHub <noreply@github.com>2022-10-21 00:05:50 +0000
commitc43416535429396cc99bccf16e7fbe4c0adea4cf (patch)
tree7ff62b70be50a592d302fe76f007f94c5043751a /nixos/lib
parente674dd40b315eec88ac24691145387c202983eb6 (diff)
parentdd2351ee2f2671d2f2216dd843e4997060eb9576 (diff)
Merge master into staging-next
Diffstat (limited to 'nixos/lib')
-rw-r--r--nixos/lib/utils.nix18
1 files changed, 13 insertions, 5 deletions
diff --git a/nixos/lib/utils.nix b/nixos/lib/utils.nix
index f646f70323e35..9eefa80d1c8b7 100644
--- a/nixos/lib/utils.nix
+++ b/nixos/lib/utils.nix
@@ -39,11 +39,19 @@ rec {
     || hasPrefix a'.mountPoint b'.mountPoint
     || any (hasPrefix a'.mountPoint) b'.depends;
 
-  # Escape a path according to the systemd rules, e.g. /dev/xyzzy
-  # becomes dev-xyzzy.  FIXME: slow.
-  escapeSystemdPath = s:
-   replaceChars ["/" "-" " "] ["-" "\\x2d" "\\x20"]
-   (removePrefix "/" s);
+  # Escape a path according to the systemd rules. FIXME: slow
+  # The rules are described in systemd.unit(5) as follows:
+  # The escaping algorithm operates as follows: given a string, any "/" character is replaced by "-", and all other characters which are not ASCII alphanumerics, ":", "_" or "." are replaced by C-style "\x2d" escapes. In addition, "." is replaced with such a C-style escape when it would appear as the first character in the escaped string.
+  # When the input qualifies as absolute file system path, this algorithm is extended slightly: the path to the root directory "/" is encoded as single dash "-". In addition, any leading, trailing or duplicate "/" characters are removed from the string before transformation. Example: /foo//bar/baz/ becomes "foo-bar-baz".
+  escapeSystemdPath = s: let
+    replacePrefix = p: r: s: (if (hasPrefix p s) then r + (removePrefix p s) else s);
+    trim = s: removeSuffix "/" (removePrefix "/" s);
+    normalizedPath = strings.normalizePath s;
+  in
+    replaceChars ["/"] ["-"]
+    (replacePrefix "." (strings.escapeC ["."] ".")
+    (strings.escapeC (stringToCharacters " !\"#$%&'()*+,;<=>=@[\\]^`{|}~-")
+    (if normalizedPath == "/" then normalizedPath else trim normalizedPath)));
 
   # Quotes an argument for use in Exec* service lines.
   # systemd accepts "-quoted strings with escape sequences, toJSON produces