Mount sshf as a user using home-manager

I have the following config in my ~/.config/home-manager/home.nix

{  pkgs, lib, config, security, ... }:
let 
    mountdir_testhost = "${config.home.homeDirectory}/cs/test";
in
{
...
  systemd.user = {
    mounts = {
      mount-test = {
          Unit = {
              Description = "mount test home";
          };
          Mount = {
            What="papanito@test.home:/home";
            Where="${mountdir_testhost}";
            Type="sshfs";
            Options="x-systemd.automount,_netdev,reconnect,allow_other,identityfile=/home/papanito/.ssh/id_rsa";
            #SloppyOptions=
            #LazyUnmount=
            #ReadWriteOnly=
            #ForceUnmount=
            #DirectoryMode=
            #TimeoutSec=
          };
      };
    };
  };
}

and

$ home-manager switch
/nix/store/7rafw8v4snb3a168f0hw31qsd4yrish8-home-manager-generation
Starting Home Manager activation
Activating checkFilesChanged
Activating checkLinkTargets
Activating writeBoundary
Activating installPackages
replacing old 'home-manager-path'
installing 'home-manager-path'
Activating linkGeneration
Cleaning up orphan links from /home/papanito
No change so reusing latest profile generation 3
Creating home file links in /home/papanito
Activating onFilesChange
Activating reloadSystemd

But it seems it’s neither mounted nor is there any service which I could start. Not sure if I miss something or I do misunderstand the concept of mounting fileshares as user.

I have just set up an sshfs mount using home-manager for the first time and used your code as a starting point. Here are the changes I made and that work for me (probably not all required):

  • The name of the mount needs to be derived from the Where path. So in your case instead of mount-test the name needs to be something like home-papanito-cs-test. This is a systemd requirement.
  • Need Unit.Wants and Unit.After to be set to ["network.online"] so that mounting is only attempted after we are online.
  • Install.WantedBy needs to be set to ["default.target"] if you want automatic mounting
  • The _netdev option is not needed, systemd already knows it’s a network device from the Type
  • Used IdentityFile option instead of the lowercase version

Hope this helps!

2 Likes

Thanks, I’ve been able to make it work with the following changes:

  • "network-online.target" instead of "network.online" in Unit.After= and Unit.Wants=
  • Mount.Type="fuse.sshfs" instead of Mount.Type="sshfs"

Alas, user mounts cannot be automounted.
Hence I am still following the way documented in the NixOS manual:

{
  fileSystems =
    let
      # Use the user's gpg-agent session to query
      # for the password of the SSH key when auto-mounting.
      sshAsUser =
        pkgs.writeScript "sshAsUser" ''
          user="$1"; shift
          exec ${pkgs.sudo}/bin/sudo -i -u "$user" \
            ${pkgs.openssh}/bin/ssh "$@"
        '';
      options =
        [
          "user"
          "uid=julm"
          "gid=users"
          "allow_other"
          "exec" # Override "user"'s noexec
          "noatime"
          "nosuid"
          "_netdev"
          "ssh_command=${sshAsUser}\\040julm"
          "noauto"
          "x-gvfs-hide"
          "x-systemd.automount"
          #"Compression=yes" # YMMV
          # Disconnect approximately 2*15=30 seconds after a network failure
          "ServerAliveCountMax=1"
          "ServerAliveInterval=15"
          "dir_cache=no"
          #"reconnect"
        ];
    in
    {
      "/mnt/aubergine" = {
        device = "${pkgs.sshfs-fuse}/bin/sshfs#julm@aubergine.wg:/";
        fsType = "fuse";
        inherit options;
      };
    };
  systemd.automounts = [
    { where = "/mnt/aubergine"; automountConfig.TimeoutIdleSec = "5 min"; }
  ];
}
2 Likes

Ah right, it should be network-online.target. The filesystem gets mounted automatically on my end, though that is not the same as automount which is mounting on demand.