aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorOphestra <cat@gensokyo.uk>2025-12-27 22:52:12 +0900
committerOphestra <cat@gensokyo.uk>2025-12-27 23:14:08 +0900
commite42ea32dbe9283d14a7c0e8746059bc5ef97f6cd (patch)
tree9ddc8d4bb6438d00a8e04b1cdf07df5e3570f7eb
parente7982b4ee9cc935d6b89f291087524cdee229d09 (diff)
nix: configure sharefs via fileSystems
Turns out this did not work because in the vm test harness, virtualisation.fileSystems completely and silently overrides fileSystems, causing its contents to not even be evaluated anymore. This is not documented as far as I can tell, and is not obvious by any stretch of the imagination. The current hack is cargo culted from nix-community/impermanence and hopefully lasts until this project fully replaces nix. Signed-off-by: Ophestra <cat@gensokyo.uk>
-rw-r--r--cmd/sharefs/test/configuration.nix5
-rw-r--r--cmd/sharefs/test/test.py10
-rw-r--r--flake.nix4
-rw-r--r--nixos.nix62
-rw-r--r--options.md90
-rw-r--r--options.nix6
6 files changed, 136 insertions, 41 deletions
diff --git a/cmd/sharefs/test/configuration.nix b/cmd/sharefs/test/configuration.nix
index 388071b6..e1f43b72 100644
--- a/cmd/sharefs/test/configuration.nix
+++ b/cmd/sharefs/test/configuration.nix
@@ -1,4 +1,4 @@
-{ pkgs, config, ... }:
+{ pkgs, ... }:
{
users.users = {
alice = {
@@ -17,9 +17,6 @@
environment = {
# For benchmarking sharefs:
systemPackages = [ pkgs.fsmark ];
-
- # For sharefs option checks without adding to PATH:
- etc.sharefs.source = "${config.environment.hakurei.package}/libexec/sharefs";
};
virtualisation = {
diff --git a/cmd/sharefs/test/test.py b/cmd/sharefs/test/test.py
index 666feb5a..4b925c9c 100644
--- a/cmd/sharefs/test/test.py
+++ b/cmd/sharefs/test/test.py
@@ -2,14 +2,14 @@ start_all()
machine.wait_for_unit("multi-user.target")
# To check sharefs version:
-print(machine.succeed("/etc/sharefs -V"))
+print(machine.succeed("sharefs -V"))
-# Make sure sharefs did not terminate:
-machine.wait_for_unit("sharefs.service")
+# Make sure sharefs started:
+machine.wait_for_unit("sdcard.mount")
machine.succeed("mkdir /mnt")
def check_bad_opts_output(opts, want, source="/etc", privileged=False):
- output = machine.fail(("" if privileged else "sudo -u alice -i ") + f"/etc/sharefs -f -o source={source},{opts} /mnt 2>&1")
+ output = machine.fail(("" if privileged else "sudo -u alice -i ") + f"sharefs -f -o source={source},{opts} /mnt 2>&1")
if output != want:
raise Exception(f"unexpected output: {output}")
@@ -40,7 +40,7 @@ machine.succeed("rmdir /mnt")
# Unprivileged mount/unmount:
machine.succeed("sudo -u alice -i mkdir /home/alice/{sdcard,persistent}")
-machine.succeed("sudo -u alice -i /etc/sharefs -o source=/home/alice/persistent /home/alice/sdcard")
+machine.succeed("sudo -u alice -i sharefs -o source=/home/alice/persistent /home/alice/sdcard")
machine.succeed("sudo -u alice -i touch /home/alice/sdcard/check")
machine.succeed("sudo -u alice -i umount /home/alice/sdcard")
machine.succeed("sudo -u alice -i rm /home/alice/persistent/check")
diff --git a/flake.nix b/flake.nix
index fff1df35..9e09c61b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -138,6 +138,10 @@
;
};
hsu = pkgs.callPackage ./cmd/hsu/package.nix { inherit (self.packages.${system}) hakurei; };
+ sharefs = pkgs.linkFarm "sharefs" {
+ "bin/sharefs" = "${hakurei}/libexec/sharefs";
+ "bin/mount.fuse.sharefs" = "${hakurei}/libexec/sharefs";
+ };
dist = pkgs.runCommand "${hakurei.name}-dist" { buildInputs = hakurei.targetPkgs ++ [ pkgs.pkgsStatic.musl ]; } ''
# go requires XDG_CACHE_HOME for the build cache
diff --git a/nixos.nix b/nixos.nix
index 35486679..800c81e3 100644
--- a/nixos.nix
+++ b/nixos.nix
@@ -24,11 +24,38 @@ let
getsubuid = userid: appid: userid * 100000 + 10000 + appid;
getsubname = userid: appid: "u${toString userid}_a${toString appid}";
getsubhome = userid: appid: "${cfg.stateDir}/u${toString userid}/a${toString appid}";
+
+ mountpoints = {
+ ${cfg.sharefs.name} = mkIf (cfg.sharefs.source != null) {
+ depends = [ cfg.sharefs.source ];
+ device = "sharefs";
+ fsType = "fuse.sharefs";
+ noCheck = true;
+ options = [
+ "rw"
+ "noexec"
+ "nosuid"
+ "nodev"
+ "noatime"
+ "allow_other"
+ "mkdir"
+ "source=${cfg.sharefs.source}"
+ "setuid=${toString config.users.users.${cfg.sharefs.user}.uid}"
+ "setgid=${toString config.users.groups.${cfg.sharefs.group}.gid}"
+ ];
+ };
+ };
in
{
imports = [ (import ./options.nix packages) ];
+ options = {
+ # Forward declare a dummy option for VM filesystems since the real one won't exist
+ # unless the VM module is actually imported.
+ virtualisation.fileSystems = lib.mkOption { };
+ };
+
config = mkIf cfg.enable {
assertions = [
(
@@ -66,38 +93,9 @@ in
) "" cfg.users;
};
- systemd.services = {
- sharefs = mkIf (cfg.sharefs.source != null) {
- unitConfig.RequiresMountsFor = cfg.sharefs.source;
- serviceConfig = {
- NoNewPrivileges = true;
- };
- script = ''
- ${pkgs.coreutils}/bin/install -dm0 ${cfg.sharefs.name}
-
- exec ${cfg.package}/libexec/sharefs -f \
- -o ${
- lib.join "," [
- "noexec"
- "nosuid"
- "nodev"
- "noatime"
- "auto_unmount"
- "allow_other"
- "setuid=$(id -u ${cfg.sharefs.user})"
- "setgid=$(id -g ${cfg.sharefs.group})"
- "source=${cfg.sharefs.source}"
- "mkdir"
- ]
- } ${cfg.sharefs.name}
- '';
-
- # do not unmount on configuration changes
- restartIfChanged = false;
-
- wantedBy = [ "multi-user.target" ];
- };
- };
+ environment.systemPackages = optional (cfg.sharefs.source != null) cfg.sharefs.package;
+ fileSystems = mountpoints;
+ virtualisation.fileSystems = mountpoints;
home-manager =
let
diff --git a/options.md b/options.md
index fe3b187d..a87a8ac1 100644
--- a/options.md
+++ b/options.md
@@ -809,6 +809,96 @@ package
+## environment\.hakurei\.sharefs\.package
+
+
+
+The sharefs package to use\.
+
+
+
+*Type:*
+package
+
+
+
+*Default:*
+` <derivation sharefs> `
+
+
+
+## environment\.hakurei\.sharefs\.group
+
+
+
+Name of the group to run the sharefs daemon as\.
+
+
+
+*Type:*
+string
+
+
+
+*Default:*
+` "sharefs" `
+
+
+
+## environment\.hakurei\.sharefs\.name
+
+
+
+Host path to mount sharefs on\.
+
+
+
+*Type:*
+string
+
+
+
+*Default:*
+` "/sdcard" `
+
+
+
+## environment\.hakurei\.sharefs\.source
+
+
+
+Writable backing directory\. Setting this to null disables sharefs\.
+
+
+
+*Type:*
+null or string
+
+
+
+*Default:*
+` null `
+
+
+
+## environment\.hakurei\.sharefs\.user
+
+
+
+Name of the user to run the sharefs daemon as\.
+
+
+
+*Type:*
+string
+
+
+
+*Default:*
+` "sharefs" `
+
+
+
## environment\.hakurei\.shell
diff --git a/options.nix b/options.nix
index 15e6f9f6..02d69f59 100644
--- a/options.nix
+++ b/options.nix
@@ -41,6 +41,12 @@ in
};
sharefs = {
+ package = mkOption {
+ type = types.package;
+ default = packages.${pkgs.stdenv.hostPlatform.system}.sharefs;
+ description = "The sharefs package to use.";
+ };
+
user = mkOption {
type = types.str;
default = "sharefs";