at 24.11-pre 3.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 cfg = config.services.cgminer; 7 8 convType = with builtins; 9 v: if isBool v then boolToString v else toString v; 10 mergedHwConfig = 11 mapAttrsToList (n: v: ''"${n}": "${(concatStringsSep "," (map convType v))}"'') 12 (foldAttrs (n: a: [n] ++ a) [] cfg.hardware); 13 mergedConfig = with builtins; 14 mapAttrsToList (n: v: ''"${n}": ${if isBool v then convType v else ''"${convType v}"''}'') 15 cfg.config; 16 17 cgminerConfig = pkgs.writeText "cgminer.conf" '' 18 { 19 ${concatStringsSep ",\n" mergedHwConfig}, 20 ${concatStringsSep ",\n" mergedConfig}, 21 "pools": [ 22 ${concatStringsSep ",\n" 23 (map (v: ''{"url": "${v.url}", "user": "${v.user}", "pass": "${v.pass}"}'') 24 cfg.pools)}] 25 } 26 ''; 27in 28{ 29 ###### interface 30 options = { 31 32 services.cgminer = { 33 34 enable = mkEnableOption "cgminer, an ASIC/FPGA/GPU miner for bitcoin and litecoin"; 35 36 package = mkPackageOption pkgs "cgminer" { }; 37 38 user = mkOption { 39 type = types.str; 40 default = "cgminer"; 41 description = "User account under which cgminer runs"; 42 }; 43 44 pools = mkOption { 45 default = []; # Run benchmark 46 type = types.listOf (types.attrsOf types.str); 47 description = "List of pools where to mine"; 48 example = [{ 49 url = "http://p2pool.org:9332"; 50 username = "17EUZxTvs9uRmPsjPZSYUU3zCz9iwstudk"; 51 password="X"; 52 }]; 53 }; 54 55 hardware = mkOption { 56 default = []; # Run without options 57 type = types.listOf (types.attrsOf (types.either types.str types.int)); 58 description= "List of config options for every GPU"; 59 example = [ 60 { 61 intensity = 9; 62 gpu-engine = "0-985"; 63 gpu-fan = "0-85"; 64 gpu-memclock = 860; 65 gpu-powertune = 20; 66 temp-cutoff = 95; 67 temp-overheat = 85; 68 temp-target = 75; 69 } 70 { 71 intensity = 9; 72 gpu-engine = "0-950"; 73 gpu-fan = "0-85"; 74 gpu-memclock = 825; 75 gpu-powertune = 20; 76 temp-cutoff = 95; 77 temp-overheat = 85; 78 temp-target = 75; 79 }]; 80 }; 81 82 config = mkOption { 83 default = {}; 84 type = types.attrsOf (types.either types.bool types.int); 85 description = "Additional config"; 86 example = { 87 auto-fan = true; 88 auto-gpu = true; 89 expiry = 120; 90 failover-only = true; 91 gpu-threads = 2; 92 log = 5; 93 queue = 1; 94 scan-time = 60; 95 temp-histeresys = 3; 96 }; 97 }; 98 }; 99 }; 100 101 102 ###### implementation 103 104 config = mkIf config.services.cgminer.enable { 105 106 users.users = optionalAttrs (cfg.user == "cgminer") { 107 cgminer = { 108 isSystemUser = true; 109 group = "cgminer"; 110 description = "Cgminer user"; 111 }; 112 }; 113 users.groups = optionalAttrs (cfg.user == "cgminer") { 114 cgminer = {}; 115 }; 116 117 environment.systemPackages = [ cfg.package ]; 118 119 systemd.services.cgminer = { 120 path = [ pkgs.cgminer ]; 121 122 after = [ "network.target" "display-manager.service" ]; 123 wantedBy = [ "multi-user.target" ]; 124 125 environment = { 126 LD_LIBRARY_PATH = "/run/opengl-driver/lib:/run/opengl-driver-32/lib"; 127 DISPLAY = ":${toString config.services.xserver.display}"; 128 GPU_MAX_ALLOC_PERCENT = "100"; 129 GPU_USE_SYNC_OBJECTS = "1"; 130 }; 131 132 startLimitIntervalSec = 60; # 1 min 133 serviceConfig = { 134 ExecStart = "${pkgs.cgminer}/bin/cgminer --syslog --text-only --config ${cgminerConfig}"; 135 User = cfg.user; 136 RestartSec = "30s"; 137 Restart = "always"; 138 }; 139 }; 140 141 }; 142 143}