From cd21d2e61b2da9cc5b96f848ac6fd3c4dc377a1b Mon Sep 17 00:00:00 2001 From: RedEtherbloom Date: Thu, 31 Oct 2024 21:55:36 +0100 Subject: [PATCH] git-sync: fix crash when whitespace in path systemd rejects the service unit due to whitespace in the environment variable assignment, pointing to the repo path, being invalid for systemd's unit format. See https://github.com/nix-community/home-manager/issues/6023 for details. The git-sync variable should also be escaped due to similar issues with e.g. local git urls. --- modules/services/git-sync.nix | 4 +- tests/modules/services/git-sync/basic.nix | 2 +- tests/modules/services/git-sync/default.nix | 5 ++- .../modules/services/git-sync/whitespace.nix | 42 +++++++++++++++++++ 4 files changed, 49 insertions(+), 4 deletions(-) create mode 100644 tests/modules/services/git-sync/whitespace.nix diff --git a/modules/services/git-sync.nix b/modules/services/git-sync.nix index 2d90d6331..4bc2381b2 100644 --- a/modules/services/git-sync.nix +++ b/modules/services/git-sync.nix @@ -16,9 +16,9 @@ let "PATH=${ lib.makeBinPath (with pkgs; [ openssh git ] ++ repo.extraPackages) }" - "GIT_SYNC_DIRECTORY=${repo.path}" + "GIT_SYNC_DIRECTORY=${strings.escapeShellArg repo.path}" "GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync" - "GIT_SYNC_REPOSITORY=${repo.uri}" + "GIT_SYNC_REPOSITORY=${strings.escapeShellArg repo.uri}" "GIT_SYNC_INTERVAL=${toString repo.interval}" ]; ExecStart = "${cfg.package}/bin/git-sync-on-inotify"; diff --git a/tests/modules/services/git-sync/basic.nix b/tests/modules/services/git-sync/basic.nix index a82e9a4b1..0412f93b1 100644 --- a/tests/modules/services/git-sync/basic.nix +++ b/tests/modules/services/git-sync/basic.nix @@ -27,7 +27,7 @@ Environment=PATH=@openssh@/bin:/nix/store/00000000000000000000000000000000-git/bin Environment=GIT_SYNC_DIRECTORY=/a/path Environment=GIT_SYNC_COMMAND=@git-sync@/bin/git-sync - Environment=GIT_SYNC_REPOSITORY=git+ssh://user@example.com:/~user/path/to/repo.git + Environment=GIT_SYNC_REPOSITORY='git+ssh://user@example.com:/~user/path/to/repo.git' Environment=GIT_SYNC_INTERVAL=500 ExecStart=@git-sync@/bin/git-sync-on-inotify Restart=on-abort diff --git a/tests/modules/services/git-sync/default.nix b/tests/modules/services/git-sync/default.nix index 0e9db79d0..7a2000a3e 100644 --- a/tests/modules/services/git-sync/default.nix +++ b/tests/modules/services/git-sync/default.nix @@ -1 +1,4 @@ -{ git-sync = ./basic.nix; } +{ + git-sync = ./basic.nix; + git-sync-with-whitespace = ./whitespace.nix; +} diff --git a/tests/modules/services/git-sync/whitespace.nix b/tests/modules/services/git-sync/whitespace.nix new file mode 100644 index 000000000..871843553 --- /dev/null +++ b/tests/modules/services/git-sync/whitespace.nix @@ -0,0 +1,42 @@ +{ config, ... }: + +{ + services.git-sync = { + enable = true; + package = config.lib.test.mkStubPackage { outPath = "@git-sync@"; }; + repositories = { + testWithWhitespace = { + path = "/a path"; + uri = "git+ssh://user@example.com:/~user/path to/repo.git"; + }; + }; + }; + + test.stubs.openssh = { name = "openssh"; }; + + nmt.script = '' + serviceFile=home-files/.config/systemd/user/git-sync-testWithWhitespace.service + + assertFileExists $serviceFile + + serviceFile=$(normalizeStorePaths $serviceFile) + assertFileContent $serviceFile ${ + builtins.toFile "expected" '' + [Install] + WantedBy=default.target + + [Service] + Environment=PATH=@openssh@/bin:/nix/store/00000000000000000000000000000000-git/bin + Environment=GIT_SYNC_DIRECTORY='/a path' + Environment=GIT_SYNC_COMMAND=@git-sync@/bin/git-sync + Environment=GIT_SYNC_REPOSITORY='git+ssh://user@example.com:/~user/path to/repo.git' + Environment=GIT_SYNC_INTERVAL=500 + ExecStart=@git-sync@/bin/git-sync-on-inotify + Restart=on-abort + + [Unit] + Description=Git Sync testWithWhitespace + '' + } + ''; +}