diff --git a/README.org b/README.org index a289b9b..a79dd43 100755 --- a/README.org +++ b/README.org @@ -219,6 +219,8 @@ CLOSED: [2025-02-02 Sun 14:06] **** TODO [[https://github.com/promethial/paxedit][Paxedit]] +Seems old and broken? + **** TODO Evil stuff **** TODO Text objects diff --git a/hosts/deertopia/configuration.nix b/hosts/deertopia/configuration.nix index ead93b9..a4489fc 100755 --- a/hosts/deertopia/configuration.nix +++ b/hosts/deertopia/configuration.nix @@ -10,6 +10,7 @@ users.users = [ "lain" + "besties" ]; impermanence = { @@ -46,17 +47,32 @@ ../../public-keys/lain-at-deertopia.pub ]; repos = { + "/persist/vault/jellyfin/Documents" = { + managed = true; + symlinkToAnnexHome = "documents"; + remotes = { + "guix-rebound" = "crumb@guix-rebound:Documents"; + }; + }; + "/persist/vault/jellyfin/Music" = { + managed = true; + symlinkToAnnexHome = "music"; + remotes = { + "guix-rebound" = "crumb@guix-rebound:Music"; + }; + }; "/persist/deertopia.net/dav/org" = { managed = true; + symlinkToAnnexHome = "org"; remotes = { "guix-rebound" = "crumb@guix-rebound:org"; - # "fruitbook" = "crumble@fruitbook:org"; }; }; }; }; deertopia = { + jellyfin.enable = true; nginx.enable = true; webdav.enable = true; bepasty.enable = true; diff --git a/modules/nixos/deertopia/jellyfin.nix b/modules/nixos/deertopia/jellyfin.nix new file mode 100644 index 0000000..41b92d8 --- /dev/null +++ b/modules/nixos/deertopia/jellyfin.nix @@ -0,0 +1,39 @@ +{ config, lib, pkgs, ... }: + +with lib; + +let cfg = config.sydnix.deertopia.jellyfin; +in { + options = { + sydnix.deertopia.jellyfin = { + enable = mkEnableOption "Deertopia's Jellyfin media server"; + }; + }; + + config = mkIf cfg.enable { + sydnix.impermanence = + let jcfg = config.services.jellyfin; + in { + directories = [ + jcfg.dataDir + jcfg.configDir + ]; + cache.directories = [ + jcfg.cacheDir + ]; + }; + + services.jellyfin = { + enable = true; + openFirewall = true; + }; + + sydnix.deertopia.nginx.vhosts."watch".vhost = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://localhost:8096"; # Uses default port. + }; + }; + }; +} diff --git a/modules/nixos/git-annex.nix b/modules/nixos/git-annex.nix index fa2ae55..ab21c27 100644 --- a/modules/nixos/git-annex.nix +++ b/modules/nixos/git-annex.nix @@ -31,6 +31,11 @@ in { default = true; }; + symlinkToAnnexHome = lib.mkOption { + default = null; + type = lib.types.nullOr lib.types.str; + }; + path = lib.mkOption { description = '' Path to the repo. @@ -47,6 +52,9 @@ in { user = lib.mkOption { type = lib.types.str; default = "annex"; + description = '' + The user that the Git-annex assistant will be run as. + ''; }; group = lib.mkOption { @@ -81,11 +89,21 @@ in { # Necessary to enable cloning over SSH. isNormalUser = true; group = "annex"; + # TODO: Don't hardcode extra groups! + extraGroups = [ "jellyfin" ]; home = "/var/sydnix/annex"; + homeMode = "770"; createHome = true; openssh.authorizedKeys.keyFiles = cfg.keyFiles; }; + # HACK: Some Jellyfin libraries are served by Git-annex. Give Jellyfin + # permission to symlink some of those libraries into the annex user's home + # dir. + users.users.${config.services.jellyfin.user}.extraGroups = + lib.mkIf config.sydnix.deertopia.jellyfin.enable + [ "annex" ]; + system.activationScripts.initialiseUserAnnex = let gitconfig-file = pkgs.writeText "gitconfig" '' [user] @@ -95,23 +113,16 @@ in { defaultBranch = main [core] symlinks = true + [safe] + ${lib.strings.concatMapStrings + (repo: "\tdirectory = ${repo.path}\n") + (builtins.attrValues cfg.repos)} ''; 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 = @@ -124,8 +135,18 @@ in { [ -e .git ] || git init [ -e .git/annex ] || git annex init - # Symlink repo into user `annex` for easy access. - ln -sf "$(pwd)" "$HOME/" + # git config set user.name "${cfg.user.name}" + # git config set user.email "${cfg.user.email}" + + # 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/dav/org + # Less assumptions about the host's file system! + annexHome="${config.users.users.annex.home}" + ${lib.optionalString (repo.symlinkToAnnexHome != null) + ''ln -sf "$PWD" "$annexHome/${repo.symlinkToAnnexHome}"''} ${lib.strings.toShellVar "remotes" repo.remotes} for remoteName in ''${!remotes[@]}; do @@ -140,26 +161,26 @@ in { ''; 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 - ''; - }; + 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: { diff --git a/modules/nixos/impermanence.nix b/modules/nixos/impermanence.nix index 499a3d7..286ce02 100755 --- a/modules/nixos/impermanence.nix +++ b/modules/nixos/impermanence.nix @@ -38,6 +38,28 @@ in { Name of the group whose members have access to the persist directory. ''; }; + + cache = { + directories = mkOption { + description = '' + While functionally identical to `directories` (at the moment), + `cache.directories` carries additional semantics: these directories + /can/ be erased, but typically /shouldn't/ be. + ''; + default = []; + type = types.listOf types.anything; + }; + + files = mkOption { + description = '' + While functionally identical to `files` (at the moment), + `cache.files` carries additional semantics: these files /can/ be + erased, but typically /shouldn't/ be. + ''; + default = []; + type = types.listOf types.anything; + }; + }; }; }; @@ -72,8 +94,8 @@ in { programs.fuse.userAllowOther = true; environment.persistence."${cfg.persistDirectory}/root" = { - directories = cfg.directories; - files = cfg.files; + directories = cfg.directories ++ cfg.cache.directories; + files = cfg.files ++ cfg.cache.files; }; }; } diff --git a/users/lain/default.nix b/users/lain/default.nix index b4addd5..ac24072 100755 --- a/users/lain/default.nix +++ b/users/lain/default.nix @@ -3,7 +3,18 @@ isNormalUser = true; # TODO: Don't hard-code `persist`. Use # config.sydnix.impermanence.persistGroupName. - extraGroups = [ "wheel" "persist" "nginx" "annex" ]; + extraGroups = [ + # Admin account. + "wheel" + # Default permissions to modify /persist. + "persist" + # Can modify the files served by Nginx. + "nginx" + # Can modify Deertopia's git-annex repos. + "annex" + # Can modify Deertopia's Jellyfin libraries. + "jellyfin" + ]; initialHashedPassword = "$y$j9T$aEFDDwdTZbAc6VQRXrkBJ0$K8wxTGTWDihyX1wxJ.ZMH//wmQFfrGGUkLkxIU0Lyq8";