Nextcloud sync, also zapzap
This commit is contained in:
+1
-1
Submodule azos-core updated: b1e92ea6c0...2c7d32e10b
@@ -29,10 +29,10 @@
|
||||
};
|
||||
# mbsync's PassCmd shells out to `pass`, which needs the GPG smartcard to
|
||||
# decrypt. On a timer, a missing card would otherwise surface as a
|
||||
# pinentry "please insert card" prompt every run. `gpg --card-status`
|
||||
# only queries the card reader (no pinentry involved either way), so it's
|
||||
# safe to use as a silent presence check: skip the sync entirely when the
|
||||
# card isn't there, instead of letting mbsync hit that prompt.
|
||||
# pinentry "please insert card" prompt every run. azos-card-present is a
|
||||
# silent presence check (see overlays/default.nix): skip the sync
|
||||
# entirely when the card isn't there, instead of letting mbsync hit that
|
||||
# prompt.
|
||||
#
|
||||
# New mail is detected by counting files under every account's Maildir
|
||||
# "new" subdirectory before and after the sync -- that's where messages
|
||||
@@ -42,7 +42,7 @@
|
||||
# notify-send -- intentionally separate from mu4e's own "mbsync -a" (its
|
||||
# mu4e-get-mail-command), which doesn't go through this script at all.
|
||||
mbsyncSafe = pkgs.writeShellScript "mbsync-safe" ''
|
||||
if ! ${pkgs.gnupg}/bin/gpg --card-status >/dev/null 2>&1; then
|
||||
if ! ${pkgs.azos-card-present}/bin/azos-card-present; then
|
||||
exit 0
|
||||
fi
|
||||
before=$(find "$HOME/Maildir" -path '*/new/*' -type f 2>/dev/null | wc -l)
|
||||
|
||||
@@ -4,17 +4,74 @@
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
}: let
|
||||
mountDir = "synced-docs";
|
||||
remoteSubfolder = "synced-docs";
|
||||
remoteName = "ncsynceddocs";
|
||||
remoteNameEnv = lib.toUpper remoteName;
|
||||
# rclone's webdav backend needs the account's Nextcloud *user ID*, not
|
||||
# its login name, in the /dav/files/<uid>/ path -- the two differ on
|
||||
# this server. The login name ("aner") still goes in the `user` field
|
||||
# for Basic Auth. Both the uid and password come from `pass` at service
|
||||
# start, same as mbsync in features/mail, so neither lands in the Nix
|
||||
# store.
|
||||
#
|
||||
# Shares the azos-card-present silent presence check (overlays/default.nix)
|
||||
# with the mail sync timer: loop quietly until the YubiKey is plugged in
|
||||
# (no pinentry prompt either way), then exec rclone in the foreground.
|
||||
# Restart=always means unplugging/replugging the key remounts naturally.
|
||||
nextcloudMountSafe = pkgs.writeShellScript "nextcloud-mount-safe" ''
|
||||
set -eu
|
||||
mountpoint="$HOME/${mountDir}"
|
||||
mkdir -p "$mountpoint"
|
||||
while ! ${pkgs.azos-card-present}/bin/azos-card-present; do
|
||||
sleep 10
|
||||
done
|
||||
password=$(${pkgs.pass}/bin/pass zakobar.com | head -1)
|
||||
uid=$(${pkgs.pass}/bin/pass nextcloud-username/aner | head -1)
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_TYPE=webdav
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_URL="https://nextcloud.zakobar.com/remote.php/dav/files/$uid/"
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_VENDOR=nextcloud
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_USER=aner
|
||||
export RCLONE_CONFIG_${remoteNameEnv}_PASS="$(${pkgs.rclone}/bin/rclone obscure "$password")"
|
||||
exec ${pkgs.rclone}/bin/rclone mount ${remoteName}:${remoteSubfolder} "$mountpoint" \
|
||||
--vfs-cache-mode writes
|
||||
'';
|
||||
in {
|
||||
options.azos.nextcloud-client.enable = lib.mkOption {
|
||||
default = true;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
config = lib.mkIf config.azos.nextcloud-client.enable {
|
||||
home.packages = with pkgs; [nextcloud-client];
|
||||
services.nextcloud-client = {
|
||||
enable = true;
|
||||
startInBackground = false;
|
||||
};
|
||||
options.azos.nextcloud-mount.enable = lib.mkOption {
|
||||
default = true;
|
||||
type = lib.types.bool;
|
||||
};
|
||||
config = lib.mkMerge [
|
||||
(lib.mkIf config.azos.nextcloud-client.enable {
|
||||
home.packages = with pkgs; [nextcloud-client];
|
||||
services.nextcloud-client = {
|
||||
enable = true;
|
||||
startInBackground = false;
|
||||
};
|
||||
})
|
||||
(lib.mkIf config.azos.nextcloud-mount.enable {
|
||||
home.packages = with pkgs; [rclone];
|
||||
# default.target, not graphical-session.target: the latter never
|
||||
# activates under EXWM in this setup (nothing explicitly starts it),
|
||||
# which is why nextcloud-client itself silently never autostarts.
|
||||
systemd.user.services.nextcloud-mount = {
|
||||
Unit.Description = "Mount Nextcloud ${remoteSubfolder} via rclone (waits silently for YubiKey)";
|
||||
Service = {
|
||||
Type = "simple";
|
||||
Environment = "PATH=${pkgs.fuse3}/bin:${pkgs.fuse}/bin";
|
||||
ExecStart = "${nextcloudMountSafe}";
|
||||
ExecStop = "${pkgs.fuse3}/bin/fusermount3 -u %h/${mountDir}";
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
};
|
||||
})
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -98,6 +98,11 @@
|
||||
azos.printing.enable = true;
|
||||
azos.hardware-auth.enable = true;
|
||||
|
||||
# Needed for unprivileged FUSE mounts (e.g. rclone mount) -- without this,
|
||||
# fusermount3 has no setuid wrapper and mounting fails with
|
||||
# "Operation not permitted" even though /dev/fuse itself is world-writable.
|
||||
programs.fuse.enable = true;
|
||||
|
||||
home-manager = {
|
||||
extraSpecialArgs = {inherit inputs outputs suiteModules pkgs;};
|
||||
users = {
|
||||
|
||||
@@ -11,4 +11,14 @@
|
||||
config.allowUnfree = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Shared silent presence check for the GPG smartcard (the YubiKey's OpenPGP
|
||||
# applet): `gpg --card-status` only queries the reader, never invoking
|
||||
# pinentry, so it's safe to poll without ever producing a "please insert
|
||||
# card" prompt. Used by both the mail sync timer and the Nextcloud mount
|
||||
# service to gate on `pass` being decryptable.
|
||||
config.flake.overlayPkgs.azos-card-present = pkgs:
|
||||
pkgs.writeShellScriptBin "azos-card-present" ''
|
||||
exec ${pkgs.gnupg}/bin/gpg --card-status >/dev/null 2>&1
|
||||
'';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user