summary refs log tree commit diff
diff options
context:
space:
mode:
authorFranz Pletz <fpletz@fnordicwalking.de>2017-08-30 18:50:11 +0200
committerGitHub <noreply@github.com>2017-08-30 18:50:11 +0200
commita22e1d4121c038c735d5a6e12d4b2b3e88881c79 (patch)
treecdc8a5ec2d40fcee4188f13321fc78143f36ea68
parent55a123a49db4371b9108e35b675a6924df76a04f (diff)
parent5050c5638235ee2af92dfc769ea0476bc049e62d (diff)
downloadnixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.tar
nixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.tar.gz
nixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.tar.bz2
nixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.tar.lz
nixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.tar.xz
nixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.tar.zst
nixlib-a22e1d4121c038c735d5a6e12d4b2b3e88881c79.zip
Merge pull request #28621 from elitak/ipfs
ipfs improvements
-rw-r--r--nixos/modules/services/network-filesystems/ipfs.nix181
1 files changed, 109 insertions, 72 deletions
diff --git a/nixos/modules/services/network-filesystems/ipfs.nix b/nixos/modules/services/network-filesystems/ipfs.nix
index 60822b5b547f..cd320c5c4620 100644
--- a/nixos/modules/services/network-filesystems/ipfs.nix
+++ b/nixos/modules/services/network-filesystems/ipfs.nix
@@ -1,15 +1,19 @@
 { config, lib, pkgs, ... }:
-
 with lib;
-
 let
   inherit (pkgs) ipfs runCommand makeWrapper;
 
   cfg = config.services.ipfs;
 
-  ipfsFlags = ''${if cfg.autoMigrate then "--migrate" else ""} ${if cfg.enableGC then "--enable-gc" else ""} ${toString cfg.extraFlags}'';
+  ipfsFlags = toString ([
+    #(optionalString  cfg.autoMount                   "--mount")
+    (optionalString  cfg.autoMigrate                 "--migrate")
+    (optionalString  cfg.enableGC                    "--enable-gc")
+    (optionalString (cfg.serviceFdlimit != null)     "--manage-fdlimit=false")
+    (optionalString (cfg.defaultMode == "offline")   "--offline")
+    (optionalString (cfg.defaultMode == "norouting") "--routing=none")
+  ] ++ cfg.extraFlags);
 
-  # Before Version 17.09, ipfs would always use "/var/lib/ipfs/.ipfs" as it's dataDir
   defaultDataDir = if versionAtLeast config.system.stateVersion "17.09" then
     "/var/lib/ipfs" else
     "/var/lib/ipfs/.ipfs";
@@ -17,11 +21,48 @@ let
   # Wrapping the ipfs binary with the environment variable IPFS_PATH set to dataDir because we can't set it in the user environment
   wrapped = runCommand "ipfs" { buildInputs = [ makeWrapper ]; } ''
     mkdir -p "$out/bin"
-    makeWrapper "${ipfs}/bin/ipfs" "$out/bin/ipfs" --set IPFS_PATH ${cfg.dataDir}
+    makeWrapper "${ipfs}/bin/ipfs" "$out/bin/ipfs" \
+      --set IPFS_PATH ${cfg.dataDir} \
+      --prefix PATH : /run/wrappers/bin
   '';
-in
 
-{
+
+  commonEnv = {
+    environment.IPFS_PATH = cfg.dataDir;
+    path = [ wrapped ];
+    serviceConfig.User = cfg.user;
+    serviceConfig.Group = cfg.group;
+  };
+
+  baseService = recursiveUpdate commonEnv {
+    wants = [ "ipfs-init.service" ];
+    preStart = ''
+      ipfs --local config Addresses.API ${cfg.apiAddress}
+      ipfs --local config Addresses.Gateway ${cfg.gatewayAddress}
+    '' + optionalString false/*cfg.autoMount*/ ''
+      ipfs --local config Mounts.FuseAllowOther --json true
+      ipfs --local config Mounts.IPFS ${cfg.ipfsMountDir}
+      ipfs --local config Mounts.IPNS ${cfg.ipnsMountDir}
+    '' + concatStringsSep "\n" (collect
+          isString
+          (mapAttrsRecursive
+            (path: value:
+            # Using heredoc below so that the value is never improperly quoted
+            ''
+              read value <<EOF
+              ${builtins.toJSON value}
+              EOF
+              ipfs --local config --json "${concatStringsSep "." path}" "$value"
+            '')
+            cfg.extraConfig)
+        );
+    serviceConfig = {
+      ExecStart = "${wrapped}/bin/ipfs daemon ${ipfsFlags}";
+      Restart = "on-failure";
+      RestartSec = 1;
+    } // optionalAttrs (cfg.serviceFdlimit != null) { LimitNOFILE = cfg.serviceFdlimit; };
+  };
+in {
 
   ###### interface
 
@@ -63,6 +104,24 @@ in
         '';
       };
 
+      #autoMount = mkOption {
+      #  type = types.bool;
+      #  default = false;
+      #  description = "Whether IPFS should try to mount /ipfs and /ipns at startup.";
+      #};
+
+      ipfsMountDir = mkOption {
+        type = types.str;
+        default = "/ipfs";
+        description = "Where to mount the IPFS namespace to";
+      };
+
+      ipnsMountDir = mkOption {
+        type = types.str;
+        default = "/ipns";
+        description = "Where to mount the IPNS namespace to";
+      };
+
       gatewayAddress = mkOption {
         type = types.str;
         default = "/ip4/127.0.0.1/tcp/8080";
@@ -91,11 +150,41 @@ in
         '';
       };
 
+      extraConfig = mkOption {
+        type = types.attrs;
+        description = toString [
+          "Attrset of daemon configuration to set using `ipfs config`, every time the daemon starts."
+          "These are applied last, so may override configuration set by other options in this module."
+          "Keep in mind that this configuration is stateful; i.e., unsetting anything in here does not reset the value to the default!"
+        ];
+        default = {};
+        example = {
+          Datastore.StorageMax = "100GB";
+          Discovery.MDNS.Enabled = false;
+          Bootstrap = [
+            "/ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu"
+            "/ip4/162.243.248.213/tcp/4001/ipfs/QmSoLueR4xBeUbY9WZ9xGUUxunbKWcrNFTDAadQJmocnWm"
+          ];
+          Swarm.AddrFilters = null;
+        };
+
+      };
+
       extraFlags = mkOption {
         type = types.listOf types.str;
         description = "Extra flags passed to the IPFS daemon";
         default = [];
       };
+
+      serviceFdlimit = mkOption {
+        type = types.nullOr types.int;
+        default = null;
+        description = ''
+          The fdlimit for the IPFS systemd unit or `null` to have the daemon attempt to manage it.
+        '';
+        example = 256*1024;
+      };
+
     };
   };
 
@@ -115,108 +204,56 @@ in
     };
 
     users.extraGroups = mkIf (cfg.group == "ipfs") {
-      ipfs = {
-        gid = config.ids.gids.ipfs;
-      };
+      ipfs.gid = config.ids.gids.ipfs;
     };
 
-    systemd.services.ipfs-init = {
+    systemd.services.ipfs-init = recursiveUpdate commonEnv {
       description = "IPFS Initializer";
 
       after = [ "local-fs.target" ];
       before = [ "ipfs.service" "ipfs-offline.service" ];
 
-      environment.IPFS_PATH = cfg.dataDir;
-
-      path  = [ pkgs.ipfs pkgs.su pkgs.bash ];
-
       preStart = ''
         install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.dataDir}
+      '' + optionalString false/*cfg.autoMount*/ ''
+        install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.ipfsMountDir}
+        install -m 0755 -o ${cfg.user} -g ${cfg.group} -d ${cfg.ipnsMountDir}
       '';
-      script =  ''
+      script = ''
         if [[ ! -f ${cfg.dataDir}/config ]]; then
-          ${ipfs}/bin/ipfs init ${optionalString cfg.emptyRepo "-e"}
+          ipfs init ${optionalString cfg.emptyRepo "-e"}
         fi
-        ${ipfs}/bin/ipfs --local config Addresses.API ${cfg.apiAddress}
-        ${ipfs}/bin/ipfs --local config Addresses.Gateway ${cfg.gatewayAddress}
       '';
 
       serviceConfig = {
-        User = cfg.user;
-        Group = cfg.group;
         Type = "oneshot";
         RemainAfterExit = true;
         PermissionsStartOnly = true;
       };
     };
 
-    systemd.services.ipfs = {
-      description = "IPFS Daemon";
+    # TODO These 3 definitions possibly be further abstracted through use of a function
+    # like: mutexServices "ipfs" [ "", "offline", "norouting" ] { ... shared conf here ... }
 
+    systemd.services.ipfs = recursiveUpdate baseService {
+      description = "IPFS Daemon";
       wantedBy = mkIf (cfg.defaultMode == "online") [ "multi-user.target" ];
-
       after = [ "network.target" "local-fs.target" "ipfs-init.service" ];
-
       conflicts = [ "ipfs-offline.service" "ipfs-norouting.service"];
-      wants = [ "ipfs-init.service" ];
-
-      environment.IPFS_PATH = cfg.dataDir;
-
-      path  = [ pkgs.ipfs ];
-
-      serviceConfig = {
-        ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags}";
-        User = cfg.user;
-        Group = cfg.group;
-        Restart = "on-failure";
-        RestartSec = 1;
-      };
     };
 
-    systemd.services.ipfs-offline = {
+    systemd.services.ipfs-offline = recursiveUpdate baseService {
       description = "IPFS Daemon (offline mode)";
-
       wantedBy = mkIf (cfg.defaultMode == "offline") [ "multi-user.target" ];
-
       after = [ "local-fs.target" "ipfs-init.service" ];
-
       conflicts = [ "ipfs.service" "ipfs-norouting.service"];
-      wants = [ "ipfs-init.service" ];
-
-      environment.IPFS_PATH = cfg.dataDir;
-
-      path  = [ pkgs.ipfs ];
-
-      serviceConfig = {
-        ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags} --offline";
-        User = cfg.user;
-        Group = cfg.group;
-        Restart = "on-failure";
-        RestartSec = 1;
-      };
     };
 
-    systemd.services.ipfs-norouting = {
+    systemd.services.ipfs-norouting = recursiveUpdate baseService {
       description = "IPFS Daemon (no routing mode)";
-
       wantedBy = mkIf (cfg.defaultMode == "norouting") [ "multi-user.target" ];
-
       after = [ "local-fs.target" "ipfs-init.service" ];
-
       conflicts = [ "ipfs.service" "ipfs-offline.service"];
-      wants = [ "ipfs-init.service" ];
-
-      environment.IPFS_PATH = cfg.dataDir;
-
-      path  = [ pkgs.ipfs ];
-
-      serviceConfig = {
-        ExecStart = "${ipfs}/bin/ipfs daemon ${ipfsFlags} --routing=none";
-        User = cfg.user;
-        Group = cfg.group;
-        Restart = "on-failure";
-        RestartSec = 1;
-      };
     };
 
   };