diff options
author | Soispha <soispha@vhack.eu> | 2023-07-03 08:49:41 +0200 |
---|---|---|
committer | Soispha <soispha@vhack.eu> | 2023-07-03 14:26:40 +0200 |
commit | 3f2fedfb794a1fccf4581a9cef5eaf4fd1c837a7 (patch) | |
tree | ba11fac01f887359954073c9e53712d7e8a5e4a3 | |
parent | Fix(system/fs-layout): Remove persistent dir as it's now in /srv (diff) | |
download | nixos-server-3f2fedfb794a1fccf4581a9cef5eaf4fd1c837a7.tar.gz nixos-server-3f2fedfb794a1fccf4581a9cef5eaf4fd1c837a7.zip |
Feat(system/services/nix-sync): Remodel git-sync to make it useful
-rw-r--r-- | system/services/git-sync/default.nix | 99 | ||||
-rw-r--r-- | system/services/nix-sync/default.nix | 193 |
2 files changed, 193 insertions, 99 deletions
diff --git a/system/services/git-sync/default.nix b/system/services/git-sync/default.nix deleted file mode 100644 index 4295870..0000000 --- a/system/services/git-sync/default.nix +++ /dev/null @@ -1,99 +0,0 @@ -/* -Taken from: -https://github.com/nix-community/home-manager/blob/9ba7b3990eb1f4782ea3f5fe7ac4f3c88dd7a32c/modules/services/git-sync.nix -*/ -{ - config, - lib, - pkgs, - ... -}: let - cfg = config.services.git-sync; - - mkUnit = name: repo: { - unitConfig.Description = "Git Sync ${name}"; - - wantedBy = ["default.target"]; - - serviceConfig = { - Environment = [ - "PATH=${lib.makeBinPath (with pkgs; [openssh git])}" - "GIT_SYNC_DIRECTORY=${repo.path}" - "GIT_SYNC_COMMAND=${cfg.package}/bin/git-sync" - "GIT_SYNC_REPOSITORY=${repo.uri}" - "GIT_SYNC_INTERVAL=${toString repo.interval}" - ]; - ExecStart = "${cfg.package}/bin/git-sync-on-inotify"; - Restart = "on-abort"; - }; - }; - - services = - lib.mapAttrs' (name: repo: { - name = "git-sync-${name}"; - value = mkUnit name repo; - }) - cfg.repositories; - - repositoryType = lib.types.submodule ({name, ...}: { - options = { - name = lib.mkOption { - internal = true; - default = name; - type = lib.types.str; - description = "The name that should be given to this unit."; - }; - - path = lib.mkOption { - type = lib.types.str; - description = "The path at which to sync the repository"; - }; - - uri = lib.mkOption { - type = lib.types.str; - example = "git+ssh://user@example.com:/~[user]/path/to/repo.git"; - description = '' - The URI of the remote to be synchronized. This is only used in the - event that the directory does not already exist. See - <link xlink:href="https://git-scm.com/docs/git-clone#_git_urls"/> - for the supported URIs. - ''; - }; - - interval = lib.mkOption { - type = lib.types.int; - default = 500; - description = '' - The interval, specified in seconds, at which the synchronization will - be triggered even without filesystem changes. - ''; - }; - }; - }); -in { - options = { - services.git-sync = { - enable = lib.mkEnableOption "git-sync services"; - - package = lib.mkOption { - type = lib.types.package; - default = pkgs.git-sync; - defaultText = lib.literalExpression "pkgs.git-sync"; - description = '' - Package containing the <command>git-sync</command> program. - ''; - }; - - repositories = lib.mkOption { - type = with lib.types; attrsOf repositoryType; - description = '' - The repositories that should be synchronized. - ''; - }; - }; - }; - - config = lib.mkIf cfg.enable { - systemd.services = services; - }; -} diff --git a/system/services/nix-sync/default.nix b/system/services/nix-sync/default.nix new file mode 100644 index 0000000..18511b3 --- /dev/null +++ b/system/services/nix-sync/default.nix @@ -0,0 +1,193 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.services.nix-sync; + + mkUnit = name: repo: let + esa = lib.strings.escapeShellArg; + execStartScript = lib.writeShellScript "git-sync-exec" '' + cd ${esa cfg.cachePath}/${esa repo.path}; + + while true; do + origin="$(git rev-parse @{u})"; + branch="$(git rev-parse @)"; + + if ! [ "$origin" = "$branch" ]; then + git pull; + + out_paths=$(mktemp); + nix build . --print-out-paths --experimental-features 'nix-command flakes' > "$out_paths"; + [ "$(wc -l < "$out_paths")" -gt 1 ] && (echo "To many out-paths"; exit 1) + out_path="$(cat "$out_paths")"; + rm -r ${esa repo.path}; + ln -s "$out_path" ${esa repo.path}; + rm "$out-paths"; + fi + sleep ${esa repo.interval}; + done + ''; + execStartPreScript = '' + if ! stat ${esa cfg.cachePath}/${esa repo.path}/.git; then + mkdir --parents ${esa cfg.cachePath}/${esa repo.path}; + git clone ${esa repo.uri} ${esa cfg.cachePath}/${esa repo.path}; + + out_paths=$(mktemp); + nix build ${esa cfg.cachePath}/${esa repo.path} --print-out-paths --experimental-features 'nix-command flakes' > "$out_paths"; + [ "$(wc -l < "$out_paths")" -gt 1 ] && (echo "To many out-paths"; exit 1) + out_path="$(cat "$out_paths")"; + ln -s "$out_path" ${esa repo.path}; + rm "$out-paths"; + fi + ''; + in { + description = "Nix Sync ${name}"; + wantedBy = ["default.target"]; + after = ["network.target"]; + path = with pkgs; [openssh git nix mktemp coreutils]; + preStart = execStartPreScript; + + serviceConfig = { + ExecStart = execStartScript; + Restart = "on-abort"; + # User and group + User = cfg.user; + Group = cfg.group; + # Runtime directory and mode + RuntimeDirectory = "nginx"; + RuntimeDirectoryMode = "0750"; + # Cache directory and mode + CacheDirectory = "nginx"; + CacheDirectoryMode = "0750"; + # Logs directory and mode + LogsDirectory = "nginx"; + LogsDirectoryMode = "0750"; + # Proc filesystem + ProcSubset = "pid"; + ProtectProc = "invisible"; + # New file permissions + UMask = "0027"; # 0640 / 0750 + # Capabilities + AmbientCapabilities = ["CAP_CHOWN"]; + CapabilityBoundingSet = ["CAP_CHOWN"]; + # Security + NoNewPrivileges = true; + # Sandboxing (sorted by occurrence in https://www.freedesktop.org/software/systemd/man/systemd.exec.html) + ReadWritePaths = ["${repo.path}" "${cfg.cachePath}/${repo.path}"]; + ProtectSystem = "strict"; + ProtectHome = true; + PrivateTmp = true; + PrivateDevices = true; + ProtectHostname = true; + ProtectClock = true; + ProtectKernelTunables = true; + ProtectKernelModules = true; + ProtectKernelLogs = true; + ProtectControlGroups = true; + RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; + RestrictNamespaces = true; + LockPersonality = true; + MemoryDenyWriteExecute = true; + RestrictRealtime = true; + RestrictSUIDSGID = true; + RemoveIPC = true; + PrivateMounts = true; + # System Call Filtering + SystemCallArchitectures = "native"; + SystemCallFilter = ["~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid"]; + }; + }; + + services = + lib.mapAttrs' (name: repo: { + name = "git-sync-${name}"; + value = mkUnit name repo; + }) + cfg.repositories; + + repositoryType = lib.types.submodule ({name, ...}: { + options = { + name = lib.mkOption { + internal = true; + default = name; + type = lib.types.str; + description = "The name that should be given to this unit."; + }; + + path = lib.mkOption { + type = lib.types.str; + description = "The path at which to sync the repository"; + }; + + uri = lib.mkOption { + type = lib.types.str; + example = "git+ssh://user@example.com:/~[user]/path/to/repo.git"; + description = '' + The URI of the remote to be synchronized. This is only used in the + event that the directory does not already exist. See + <link xlink:href="https://git-scm.com/docs/git-clone#_git_urls"/> + for the supported URIs. + ''; + }; + + interval = lib.mkOption { + type = lib.types.int; + default = 500; + description = '' + The interval, specified in seconds, at which the synchronization will + be triggered even without filesystem changes. + ''; + }; + }; + }); +in { + options = { + services.git-sync = { + enable = lib.mkEnableOption "git-sync services"; + + package = lib.mkOption { + type = lib.types.package; + default = pkgs.git-sync; + defaultText = lib.literalExpression "pkgs.git-sync"; + description = '' + Package containing the <command>git-sync</command> program. + ''; + }; + + user = lib.mkOption { + type = lib.types.str; + default = "nix-sync"; + description = lib.mdDoc "User account under which nix-sync units runs."; + }; + + group = lib.mkOption { + type = lib.types.str; + default = "nix-sync"; + description = lib.mdDoc "Group account under which nix-sync units runs."; + }; + + cachePath = lib.mkOption { + type = lib.types.str; + default = "/var/lib/nix-sync"; + description = lib.mdDoc '' + Where to cache git directories. + ''; + }; + + repositories = lib.mkOption { + type = with lib.types; attrsOf repositoryType; + description = '' + The repositories that should be synchronized. + ''; + }; + }; + }; + + config = lib.mkIf cfg.enable { + systemd.services = services; + }; +} +# vim: ts=2 + |