hosts/common: port /mnt/servo/* from NFS -> FTP
fuse ftp seems to be easier to debug than kernel nfs so far
This commit is contained in:
parent
701e10b121
commit
e855be4796
|
@ -5,6 +5,31 @@
|
|||
{ lib, pkgs, sane-lib, ... }:
|
||||
|
||||
let
|
||||
curlftpfs = pkgs.curlftpfs.overrideAttrs (upstream: {
|
||||
# apply a timeout not just to the connect operation, but to every operation.
|
||||
# without this, operations will hang for 2*<TCP timeout>, e.g. 4m20s.
|
||||
# better would be to use CURLOPT_LOW_SPEED_TIME/CURLOPT_LOW_SPEED_LIMIT,
|
||||
# but those options don't seem to apply.
|
||||
postPatch = (upstream.postPatch or "") + ''
|
||||
substituteInPlace ftpfs.c --replace-fail \
|
||||
'curl_easy_setopt_or_die(easy, CURLOPT_CONNECTTIMEOUT, ftpfs.connect_timeout);' \
|
||||
'curl_easy_setopt_or_die(easy, CURLOPT_CONNECTTIMEOUT, ftpfs.connect_timeout); curl_easy_setopt_or_die(easy, CURLOPT_TIMEOUT, ftpfs.connect_timeout);'
|
||||
''
|
||||
# fuse mount programs need to ignore certain "meta" keys that could be in /etc/fstab.
|
||||
# see: <https://github.com/libfuse/sshfs/issues/96>
|
||||
+ ''
|
||||
substituteInPlace ftpfs.c --replace-fail \
|
||||
'FUSE_OPT_END' \
|
||||
'/* These may come in from /etc/fstab - we just ignore them */ FUSE_OPT_KEY("auto", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("noauto", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("user", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("nouser", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("users", FUSE_OPT_KEY_DISCARD), FUSE_OPT_KEY("_netdev", FUSE_OPT_KEY_DISCARD), FUSE_OPT_END'
|
||||
'';
|
||||
# `mount` clears PATH before calling the mount helper (see util-linux/lib/env.c),
|
||||
# so the traditional /etc/fstab approach of fstype=fuse and device = curlftpfs#URI doesn't work.
|
||||
# instead, install a `mount.curlftpfs` mount helper. this is what programs like `gocryptfs` do.
|
||||
postInstall = (upstream.postInstall or "") + ''
|
||||
ln -s curlftpfs $out/bin/mount.fuse.curlftpfs
|
||||
ln -s curlftpfs $out/bin/mount.curlftpfs
|
||||
'';
|
||||
});
|
||||
fsOpts = rec {
|
||||
common = [
|
||||
"_netdev"
|
||||
|
@ -31,8 +56,7 @@ let
|
|||
"x-systemd.after=wireguard-wg-home.service"
|
||||
];
|
||||
|
||||
ssh = common ++ [
|
||||
"identityfile=/home/colin/.ssh/id_ed25519"
|
||||
fuse = [
|
||||
"allow_other" # allow users other than the one who mounts it to access it. needed, if systemd is the one mounting this fs (as root)
|
||||
# allow_root: allow root to access files on this fs (if mounted by non-root, else it can always access them).
|
||||
# N.B.: if both allow_root and allow_other are specified, then only allow_root takes effect.
|
||||
|
@ -45,7 +69,18 @@ let
|
|||
# with default_permissions, sshfs doesn't tunnel file ops from users until checking that said user could perform said op on an equivalent local fs.
|
||||
"default_permissions"
|
||||
];
|
||||
sshColin = ssh ++ [
|
||||
fuseColin = fuse ++ [
|
||||
"uid=1000"
|
||||
"gid=100"
|
||||
];
|
||||
|
||||
ssh = common ++ fuse ++ [
|
||||
"identityfile=/home/colin/.ssh/id_ed25519"
|
||||
# i *think* idmap=user means that `colin` on `localhost` and `colin` on the remote are actually treated as the same user, even if their uid/gid differs?
|
||||
# i.e., local colin's id is translated to/from remote colin's id on every operation?
|
||||
"idmap=user"
|
||||
];
|
||||
sshColin = ssh ++ fuseColin ++ [
|
||||
# follow_symlinks: remote files which are symlinks are presented to the local system as ordinary files (as the target of the symlink).
|
||||
# if the symlink target does not exist, the presentation is unspecified.
|
||||
# symlinks which point outside the mount ARE followed. so this is more capable than `transform_symlinks`
|
||||
|
@ -53,9 +88,6 @@ let
|
|||
# symlinks on the remote fs which are absolute paths are presented to the local system as relative symlinks pointing to the expected data on the remote fs.
|
||||
# only symlinks which would point inside the mountpoint are translated.
|
||||
"transform_symlinks"
|
||||
"idmap=user"
|
||||
"uid=1000"
|
||||
"gid=100"
|
||||
];
|
||||
# sshRoot = ssh ++ [
|
||||
# # we don't transform_symlinks because that breaks the validity of remote /nix stores
|
||||
|
@ -94,6 +126,14 @@ let
|
|||
# "nfsvers=3" # NFSv4+ doesn't support UDP at *all*. it's ok to omit nfsvers -- server + client will negotiate v3 based on udp requirement. but omitting causes confusing mount errors when the server is *offline*, because the client defaults to v4 and thinks the udp option is a config error.
|
||||
# "x-systemd.idle-timeout=10" # auto-unmount after this much inactivity
|
||||
];
|
||||
|
||||
# manually perform a ftp mount via e.g.
|
||||
# curlftpfs -o ftpfs_debug=2,user=anonymous:anonymous,connect_timeout=10 -f -s ftp://servo-hn /mnt/my-ftp
|
||||
ftp = common ++ fuseColin ++ [
|
||||
# "ftpfs_debug=2"
|
||||
"user=colin:ipauth"
|
||||
"connect_timeout=10"
|
||||
];
|
||||
};
|
||||
remoteHome = host: {
|
||||
fileSystems."/mnt/${host}/home" = {
|
||||
|
@ -142,29 +182,35 @@ lib.mkMerge [
|
|||
# but it decreases working memory under the heaviest of loads by however much space the compressed memory occupies (e.g. 50% if 2:1; 25% if 4:1)
|
||||
zramSwap.memoryPercent = 100;
|
||||
|
||||
# fileSystems."/mnt/servo-nfs" = {
|
||||
# device = "servo-hn:/";
|
||||
# fileSystems."/mnt/servo/media" = {
|
||||
# device = "servo-hn:/media";
|
||||
# noCheck = true;
|
||||
# fsType = "nfs";
|
||||
# options = fsOpts.nfs ++ fsOpts.automount ++ fsOpts.wg;
|
||||
# options = fsOpts.nfs ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||
# };
|
||||
# fileSystems."/mnt/servo/playground" = {
|
||||
# device = "servo-hn:/playground";
|
||||
# noCheck = true;
|
||||
# fsType = "nfs";
|
||||
# options = fsOpts.nfs ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||
# };
|
||||
fileSystems."/mnt/servo/media" = {
|
||||
device = "servo-hn:/media";
|
||||
noCheck = true;
|
||||
fsType = "nfs";
|
||||
options = fsOpts.nfs ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||
fsType = "fuse.curlftpfs";
|
||||
options = fsOpts.ftp ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||
};
|
||||
fileSystems."/mnt/servo/playground" = {
|
||||
device = "servo-hn:/playground";
|
||||
noCheck = true;
|
||||
fsType = "fuse.curlftpfs";
|
||||
options = fsOpts.ftp ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||
};
|
||||
sane.fs."/mnt/servo/media" = sane-lib.fs.wanted {
|
||||
dir.acl.user = "colin";
|
||||
dir.acl.group = "users";
|
||||
dir.acl.mode = "0750";
|
||||
};
|
||||
fileSystems."/mnt/servo/playground" = {
|
||||
device = "servo-hn:/playground";
|
||||
noCheck = true;
|
||||
fsType = "nfs";
|
||||
options = fsOpts.nfs ++ fsOpts.lazyMount ++ fsOpts.wg;
|
||||
};
|
||||
sane.fs."/mnt/servo/playground" = sane-lib.fs.wanted {
|
||||
dir.acl.user = "colin";
|
||||
dir.acl.group = "users";
|
||||
|
@ -180,6 +226,7 @@ lib.mkMerge [
|
|||
programs.fuse.userAllowOther = true; #< necessary for `allow_other` or `allow_root` options.
|
||||
environment.systemPackages = [
|
||||
pkgs.sshfs-fuse
|
||||
curlftpfs
|
||||
];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user