172 lines
5.2 KiB
Nix
172 lines
5.2 KiB
Nix
{ config, lib, pkgs, ... }:
|
|
|
|
let cfg = config.sydnix.git-annex;
|
|
in {
|
|
options = {
|
|
sydnix.git-annex = {
|
|
enable = lib.mkEnableOption "git-annex";
|
|
|
|
user = {
|
|
name = lib.mkOption {
|
|
type = lib.types.str;
|
|
};
|
|
email = lib.mkOption {
|
|
type = lib.types.str;
|
|
};
|
|
};
|
|
|
|
keyFiles = lib.mkOption {
|
|
type = lib.types.listOf lib.types.path;
|
|
default = [];
|
|
};
|
|
|
|
repos = lib.mkOption {
|
|
type = lib.types.attrsOf (lib.types.submodule ({ name, ... }: {
|
|
options = {
|
|
enable = lib.mkOption {
|
|
description = ''
|
|
Git-annex repo ${name};
|
|
'';
|
|
type = lib.types.bool;
|
|
default = true;
|
|
};
|
|
|
|
path = lib.mkOption {
|
|
description = ''
|
|
Path to the repo.
|
|
'';
|
|
type = lib.types.str;
|
|
default = name;
|
|
};
|
|
|
|
remotes = lib.mkOption {
|
|
type = lib.types.attrsOf lib.types.str;
|
|
default = {};
|
|
};
|
|
|
|
user = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "annex";
|
|
};
|
|
|
|
group = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "annex";
|
|
};
|
|
|
|
managed = lib.mkOption {
|
|
description = ''
|
|
If true, the repo will be automatically managed by Nix.
|
|
'Management' includes creating and initialising the repo and
|
|
setting permissions.
|
|
'';
|
|
type = lib.types.bool;
|
|
default = false;
|
|
};
|
|
};
|
|
}));
|
|
};
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
# Git-annex assistant requires remotes to have git-annex on the PATH.
|
|
environment.systemPackages = [
|
|
pkgs.git-annex
|
|
];
|
|
|
|
# The user that users log in as to access managed repos.
|
|
users.groups.annex = {};
|
|
users.users.annex = {
|
|
# Necessary to enable cloning over SSH.
|
|
isNormalUser = true;
|
|
group = "annex";
|
|
home = "/var/sydnix/annex";
|
|
createHome = true;
|
|
openssh.authorizedKeys.keyFiles = cfg.keyFiles;
|
|
};
|
|
|
|
system.activationScripts.initialiseUserAnnex =
|
|
let gitconfig-file = pkgs.writeText "gitconfig" ''
|
|
[user]
|
|
email = ${cfg.user.email}
|
|
name = ${cfg.user.name}
|
|
[init]
|
|
defaultBranch = main
|
|
[core]
|
|
symlinks = true
|
|
'';
|
|
in ''
|
|
set -e
|
|
|
|
annexHome="${config.users.users.annex.home}"
|
|
ln -sf "${gitconfig-file}" "$annexHome/.gitconfig"
|
|
|
|
# Symlink repos into annex's home for easy access. This is particularly nice for cloning:
|
|
# git clone annex@deertopia.net:org
|
|
# instead of
|
|
# git clone annex@deertopia.net:/persist/deertopia.net/org
|
|
# Less assumptions about the host's file system!
|
|
${lib.strings.toShellVar "repos" (builtins.attrNames cfg.repos)}
|
|
for repoPath in ''${!repos[@]}; do
|
|
target="$annexHome/$(basename "$repoPath")"
|
|
ln -sf "$repoPath" "$target"
|
|
done
|
|
'';
|
|
|
|
systemd.services =
|
|
let
|
|
init-if-necessary = repo:
|
|
pkgs.writeScript "git-annex-init-if-necessary" ''
|
|
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
[ -e .git ] || git init
|
|
[ -e .git/annex ] || git annex init
|
|
|
|
# Symlink repo into user `annex` for easy access.
|
|
ln -sf "$(pwd)" "$HOME/"
|
|
|
|
${lib.strings.toShellVar "remotes" repo.remotes}
|
|
for remoteName in ''${!remotes[@]}; do
|
|
err=0
|
|
git remote get-url "$remoteName" || err=$?
|
|
if [ $err -eq 0 ]; then
|
|
git remote set-url "$remoteName" "''${remotes["$remoteName"]}"
|
|
else
|
|
git remote add "$remoteName" "''${remotes["$remoteName"]}"
|
|
fi
|
|
done
|
|
'';
|
|
|
|
mkAssistantService = repo: {
|
|
description = "git-annex assistant (${repo.path})";
|
|
after = [ "network.target" ];
|
|
wantedBy = [ "multi-user.target" ];
|
|
serviceConfig.User = repo.user;
|
|
serviceConfig.WorkingDirectory = repo.path;
|
|
path = [ pkgs.git pkgs.git-annex pkgs.openssh ];
|
|
# Set the default file mode for new files created by this process to
|
|
# 775. Oddly, `UMask = x` will set the mode to `0777 & x`, so 002
|
|
# gets us the desired figure of 775. We want 775 because Nginx,
|
|
# running under user `nginx` needs to be able to read/write these
|
|
# files to server them over WebDAV.
|
|
serviceConfig.UMask = "002";
|
|
serviceConfig.ExecStartPre =
|
|
lib.optionalString
|
|
repo.managed
|
|
"${pkgs.bash}/bin/bash ${init-if-necessary repo}";
|
|
serviceConfig.ExecStart = ''
|
|
${pkgs.git-annex}/bin/git-annex assistant --foreground
|
|
'';
|
|
};
|
|
in builtins.listToAttrs
|
|
(builtins.map
|
|
(repo: {
|
|
name = "annex-${lib.strings.sanitizeDerivationName repo.path}";
|
|
value = mkAssistantService repo;
|
|
})
|
|
(builtins.attrValues cfg.repos));
|
|
};
|
|
}
|