persist: allow persisting of individual files, not just directories
i actually do already, with ~/.ssh/id_ed25519 -- it works only as a fluke
This commit is contained in:
parent
8e4dc0c6ae
commit
0a519eddb4
|
@ -44,7 +44,7 @@
|
|||
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: this is overly broad; only need media and share directories to be persisted
|
||||
{ user = "colin"; group = "users"; directory = "/var/lib/uninsane"; }
|
||||
{ user = "colin"; group = "users"; path = "/var/lib/uninsane"; }
|
||||
];
|
||||
# make sure large media is stored to the HDD
|
||||
sane.persist.sys.ext = [
|
||||
|
@ -52,19 +52,19 @@
|
|||
user = "colin";
|
||||
group = "users";
|
||||
mode = "0777";
|
||||
directory = "/var/lib/uninsane/media/Videos";
|
||||
path = "/var/lib/uninsane/media/Videos";
|
||||
}
|
||||
{
|
||||
user = "colin";
|
||||
group = "users";
|
||||
mode = "0777";
|
||||
directory = "/var/lib/uninsane/media/freeleech";
|
||||
path = "/var/lib/uninsane/media/freeleech";
|
||||
}
|
||||
{
|
||||
user = "colin";
|
||||
group = "users";
|
||||
mode = "0777";
|
||||
directory = "/var/lib/uninsane/media/datasets";
|
||||
path = "/var/lib/uninsane/media/datasets";
|
||||
}
|
||||
];
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ in
|
|||
lib.mkIf false
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ inherit user group; mode = "0700"; directory = svc-dir; }
|
||||
{ inherit user group; mode = "0700"; path = svc-dir; }
|
||||
];
|
||||
|
||||
services.calibre-web.enable = true;
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
# lib.mkIf false
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "ejabberd"; group = "ejabberd"; directory = "/var/lib/ejabberd"; }
|
||||
{ user = "ejabberd"; group = "ejabberd"; path = "/var/lib/ejabberd"; }
|
||||
];
|
||||
sane.ports.ports."3478" = {
|
||||
protocol = [ "tcp" "udp" ];
|
||||
|
|
|
@ -20,9 +20,9 @@ in
|
|||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode? could be more granular
|
||||
{ user = "opendkim"; group = "opendkim"; directory = "/var/lib/opendkim"; }
|
||||
{ user = "root"; group = "root"; directory = "/var/lib/postfix"; }
|
||||
{ user = "root"; group = "root"; directory = "/var/spool/mail"; }
|
||||
{ user = "opendkim"; group = "opendkim"; path = "/var/lib/opendkim"; }
|
||||
{ user = "root"; group = "root"; path = "/var/lib/postfix"; }
|
||||
{ user = "root"; group = "root"; path = "/var/spool/mail"; }
|
||||
# *probably* don't need these dirs:
|
||||
# "/var/lib/dhparams" # https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/security/dhparams.nix
|
||||
# "/var/lib/dovecot"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
mode = "0400";
|
||||
};
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "freshrss"; group = "freshrss"; directory = "/var/lib/freshrss"; }
|
||||
{ user = "freshrss"; group = "freshrss"; path = "/var/lib/freshrss"; }
|
||||
];
|
||||
|
||||
services.freshrss.enable = true;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode? could be more granular
|
||||
{ user = "git"; group = "gitea"; directory = "/var/lib/gitea"; }
|
||||
{ user = "git"; group = "gitea"; path = "/var/lib/gitea"; }
|
||||
];
|
||||
services.gitea.enable = true;
|
||||
services.gitea.user = "git"; # default is 'gitea'
|
||||
|
|
|
@ -12,7 +12,7 @@ lib.mkIf false # i don't actively use ipfs anymore
|
|||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode? could be more granular
|
||||
{ user = "261"; group = "261"; directory = "/var/lib/ipfs"; }
|
||||
{ user = "261"; group = "261"; path = "/var/lib/ipfs"; }
|
||||
];
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 4001 ];
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode? we only need this to save Indexer creds ==> migrate to config?
|
||||
{ user = "root"; group = "root"; directory = "/var/lib/jackett"; }
|
||||
{ user = "root"; group = "root"; path = "/var/lib/jackett"; }
|
||||
];
|
||||
services.jackett.enable = true;
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
};
|
||||
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; directory = "/var/lib/jellyfin"; }
|
||||
{ user = "jellyfin"; group = "jellyfin"; mode = "0700"; path = "/var/lib/jellyfin"; }
|
||||
];
|
||||
sane.fs."/var/lib/jellyfin/config/logging.json" = {
|
||||
# "Emby.Dlna" logging: <https://jellyfin.org/docs/general/networking/dlna>
|
||||
|
|
|
@ -5,7 +5,7 @@ let
|
|||
in
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ inherit user group; mode = "0700"; directory = stateDir; }
|
||||
{ inherit user group; mode = "0700"; path = stateDir; }
|
||||
];
|
||||
|
||||
services.komga.enable = true;
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
];
|
||||
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/matrix-synapse"; }
|
||||
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/matrix-synapse"; }
|
||||
];
|
||||
services.matrix-synapse.enable = true;
|
||||
# this changes the default log level from INFO to WARN.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
lib.mkIf false
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "matrix-synapse"; group = "matrix-synapse"; directory = "/var/lib/mx-puppet-discord"; }
|
||||
{ user = "matrix-synapse"; group = "matrix-synapse"; path = "/var/lib/mx-puppet-discord"; }
|
||||
];
|
||||
|
||||
services.matrix-synapse.settings.app_service_config_files = [
|
||||
|
|
|
@ -104,7 +104,7 @@ in
|
|||
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode?
|
||||
{ user = "matrix-appservice-irc"; group = "matrix-appservice-irc"; directory = "/var/lib/matrix-appservice-irc"; }
|
||||
{ user = "matrix-appservice-irc"; group = "matrix-appservice-irc"; path = "/var/lib/matrix-appservice-irc"; }
|
||||
];
|
||||
|
||||
# XXX: matrix-appservice-irc PreStart tries to chgrp the registration.yml to matrix-synapse,
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
{ config, pkgs, ... }:
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "mautrix-signal"; group = "mautrix-signal"; directory = "/var/lib/mautrix-signal"; }
|
||||
{ user = "signald"; group = "signald"; directory = "/var/lib/signald"; }
|
||||
{ user = "mautrix-signal"; group = "mautrix-signal"; path = "/var/lib/mautrix-signal"; }
|
||||
{ user = "signald"; group = "signald"; path = "/var/lib/signald"; }
|
||||
];
|
||||
|
||||
# allow synapse to read the registration file
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "navidrome"; group = "navidrome"; directory = "/var/lib/navidrome"; }
|
||||
{ user = "navidrome"; group = "navidrome"; path = "/var/lib/navidrome"; }
|
||||
];
|
||||
services.navidrome.enable = true;
|
||||
services.navidrome.settings = {
|
||||
|
|
|
@ -134,8 +134,8 @@ in
|
|||
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode?
|
||||
{ user = "acme"; group = "acme"; directory = "/var/lib/acme"; }
|
||||
{ user = "colin"; group = "users"; directory = "/var/www/sites"; }
|
||||
{ user = "acme"; group = "acme"; path = "/var/lib/acme"; }
|
||||
{ user = "colin"; group = "users"; path = "/var/www/sites"; }
|
||||
];
|
||||
|
||||
# let's encrypt default chain looks like:
|
||||
|
|
|
@ -6,7 +6,7 @@ let
|
|||
in
|
||||
{
|
||||
sane.persist.sys.plaintext = lib.mkIf cfg.enable [
|
||||
{ user = "pict-rs"; group = "pict-rs"; directory = cfg.dataDir; }
|
||||
{ user = "pict-rs"; group = "pict-rs"; path = cfg.dataDir; }
|
||||
];
|
||||
|
||||
systemd.services.pict-rs.serviceConfig = {
|
||||
|
|
|
@ -15,7 +15,7 @@ let
|
|||
in
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "pleroma"; group = "pleroma"; directory = "/var/lib/pleroma"; }
|
||||
{ user = "pleroma"; group = "pleroma"; path = "/var/lib/pleroma"; }
|
||||
];
|
||||
services.pleroma.enable = true;
|
||||
services.pleroma.secretConfigFile = config.sops.secrets.pleroma_secrets.path;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode?
|
||||
{ user = "postgres"; group = "postgres"; directory = "/var/lib/postgresql"; }
|
||||
{ user = "postgres"; group = "postgres"; path = "/var/lib/postgresql"; }
|
||||
];
|
||||
services.postgresql.enable = true;
|
||||
# services.postgresql.dataDir = "/opt/postgresql/13";
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
lib.mkIf false
|
||||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
{ user = "prosody"; group = "prosody"; directory = "/var/lib/prosody"; }
|
||||
{ user = "prosody"; group = "prosody"; path = "/var/lib/prosody"; }
|
||||
];
|
||||
sane.ports.ports."5222" = {
|
||||
protocol = [ "tcp" ];
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
{
|
||||
sane.persist.sys.plaintext = [
|
||||
# TODO: mode? we need this specifically for the stats tracking in .config/
|
||||
{ user = "transmission"; group = "transmission"; directory = "/var/lib/transmission"; }
|
||||
{ user = "transmission"; group = "transmission"; path = "/var/lib/transmission"; }
|
||||
];
|
||||
services.transmission.enable = true;
|
||||
services.transmission.settings = {
|
||||
|
|
|
@ -27,7 +27,7 @@ in
|
|||
|
||||
sane.persist.sys.plaintext = lib.mkIf cfg.enable [
|
||||
# intentionally allow other users to write to the guest folder
|
||||
{ directory = "/home/guest"; user = "guest"; group = "users"; mode = "0775"; }
|
||||
{ path = "/home/guest"; user = "guest"; group = "users"; mode = "0775"; }
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ in
|
|||
programs.ccache.enable = true;
|
||||
nix.settings.extra-sandbox-paths = [ cacheDir ];
|
||||
sane.persist.sys.plaintext = [
|
||||
{ group = "nixbld"; mode = "0775"; directory = config.programs.ccache.cacheDir; }
|
||||
{ group = "nixbld"; mode = "0775"; path = config.programs.ccache.cacheDir; }
|
||||
];
|
||||
sane.fs."${cacheDir}/ccache.conf" = sane-lib.fs.wantedText ''
|
||||
max_size = 50G
|
||||
|
|
|
@ -50,6 +50,7 @@ let path = rec {
|
|||
walk = start: end: if start == end then
|
||||
[ start ]
|
||||
else
|
||||
assert end != "/"; # else there's no path from `start` to `end`!
|
||||
(walk start (parent end)) ++ [ end ]
|
||||
;
|
||||
};
|
||||
|
|
|
@ -76,6 +76,14 @@ let
|
|||
how to link the store entry into the fs
|
||||
'';
|
||||
};
|
||||
type = mkOption {
|
||||
type = types.enum [ "dir" "file" ];
|
||||
default = "dir";
|
||||
description = ''
|
||||
whether the thing being persisted is a whole directory,
|
||||
or just one file.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -84,16 +92,16 @@ let
|
|||
entryOpts
|
||||
{
|
||||
options = {
|
||||
directory = mkOption {
|
||||
path = mkOption {
|
||||
type = types.str;
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
# allow "bar/baz" as shorthand for { directory = "bar/baz"; }
|
||||
# allow "bar/baz" as shorthand for { path = "bar/baz"; }
|
||||
entryInStoreOrShorthand = types.coercedTo
|
||||
types.str
|
||||
(d: { directory = d; })
|
||||
(d: { path = d; })
|
||||
entryInStore;
|
||||
|
||||
# allow the user to provide the `acl` field inline: we pop acl sub-attributes placed at the
|
||||
|
@ -123,11 +131,12 @@ let
|
|||
# this submodule creates one attr per store, so that the user can specify something like:
|
||||
# <option>.private.".cache/vim" = { mode = "0700"; };
|
||||
# to place ".cache/vim" into the private store and create with the appropriate mode
|
||||
dirsSubModule = types.submodule ({ config, ... }: {
|
||||
entrySubmodule = types.submodule ({ config, ... }: {
|
||||
# TODO: this should be a plain-old `attrsOf (convertInlineAcl entryInStoreOrShorthand)` with downstream checks,
|
||||
# rather than being filled in based on *other* settings.
|
||||
# otherwise, it behaves poorly when `sane.persist.enable = false`
|
||||
options = lib.attrsets.unionOfDisjoint
|
||||
# create one option per store:
|
||||
(mapAttrs (store: store-cfg: mkOption {
|
||||
default = [];
|
||||
type = types.listOf (convertInlineAcl entryInStoreOrShorthand);
|
||||
|
@ -135,8 +144,9 @@ let
|
|||
suffix = if store-cfg.storeDescription != null then
|
||||
": ${store-cfg.storeDescription}"
|
||||
else "";
|
||||
in "directories to persist in ${store}${suffix}";
|
||||
in "directories/files to persist in ${store}${suffix}";
|
||||
}) cfg.stores)
|
||||
# or allow direct access by path
|
||||
{
|
||||
byPath = mkOption {
|
||||
type = types.attrsOf (convertInlineAcl entryAtPath);
|
||||
|
@ -150,11 +160,11 @@ let
|
|||
config = let
|
||||
# set the `store` attribute on one dir attrset
|
||||
annotateWithStore = store: dir: {
|
||||
"${dir.directory}".store = store;
|
||||
"${dir.path}".store = store;
|
||||
};
|
||||
# convert an `entryInStore` to an `entryAtPath` (less the `store` item)
|
||||
dirToAttrs = dir: {
|
||||
"${dir.directory}" = builtins.removeAttrs dir ["directory"];
|
||||
"${dir.path}" = builtins.removeAttrs dir ["path"];
|
||||
};
|
||||
store-names = attrNames cfg.stores;
|
||||
# :: (store -> entry -> AttrSet) -> [AttrSet]
|
||||
|
@ -183,9 +193,9 @@ in
|
|||
description = "define / fs root to be a tmpfs. make sure to mount some other device to /nix";
|
||||
};
|
||||
sane.persist.sys = mkOption {
|
||||
description = "directories to persist to disk, relative to the fs root /";
|
||||
description = "directories (or files) to persist to disk, relative to the fs root /";
|
||||
default = {};
|
||||
type = dirsSubModule;
|
||||
type = entrySubmodule;
|
||||
};
|
||||
sane.persist.stores = mkOption {
|
||||
type = types.attrsOf storeType;
|
||||
|
@ -202,6 +212,7 @@ in
|
|||
];
|
||||
|
||||
config = let
|
||||
# String => entryAtPath => generated toplevel config
|
||||
cfgFor = fspath: opt:
|
||||
let
|
||||
store = opt.store;
|
||||
|
@ -221,10 +232,19 @@ in
|
|||
symlink.acl = opt.acl;
|
||||
symlink.target = fsPathToBackingPath fspath;
|
||||
});
|
||||
|
||||
# create the backing path as a dir
|
||||
sane.fs."${fsPathToBackingPath fspath}".dir = {};
|
||||
}
|
||||
(lib.optionalAttrs (opt.type == "dir") {
|
||||
# create the backing path as a dir
|
||||
sane.fs."${fsPathToBackingPath fspath}".dir = {
|
||||
acl = config.sane.fs."${fspath}".generated.acl;
|
||||
};
|
||||
})
|
||||
(lib.optionalAttrs (opt.type == "file") {
|
||||
# ensure the backing path of this file's parent exists.
|
||||
# XXX: this forces the backing parent to be a directory
|
||||
# this is almost always what is wanted, but it's sometimes an arbitrary constraint
|
||||
sane.fs."${path.parent (fsPathToBackingPath fspath)}".dir = {};
|
||||
})
|
||||
{
|
||||
# default each item along the backing path to have the same acl as the location it would be mounted.
|
||||
sane.fs = lib.mkMerge (builtins.map
|
||||
|
@ -233,7 +253,7 @@ in
|
|||
generated.acl = config.sane.fs."${fsSubpath}".generated.acl;
|
||||
};
|
||||
})
|
||||
(path.walk store.prefix fspath)
|
||||
(path.walk store.prefix (path.parent fspath))
|
||||
);
|
||||
}
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue
Block a user