nix default.nix

gpg-agent.nix
{ makeUnit, gnupg }:

makeUnit {
  name = "gpg-agent";
  #type = "forking";
  description = "GnuPG Agent";
  execStart = [
    {
      command = gnupg + "/bin/gpg-agent";
      args = [
        "--daemon"
      ];
    }
  ];
}
gistfile2.txt
[clever@amd-nixos:~/x/85e0e3e7ddcb26d623dd0f51bcae5478-3d27398d9a08344fa13d9a97020aac91fdb99b74]$ nix-repl default.nix 
Welcome to Nix version 1.11.2. Type :? for help.

Loading ‘default.nix’...
Added 5 variables.

nix-repl> units
[ «derivation /nix/store/b916ygzfyhiarwlj4xnc1kjdnsn3c6b2-gpg-agent.drv» ]

nix-repl> importUnitFile 
«lambda»

nix-repl> makeUnit 
«lambda»

nix-repl> :b userServices 
warning: you did not specify ‘--add-root’; the result might be removed by the garbage collector
/nix/store/4ywyzhfrr8vafsycg4ri7zpcgdpgzm27-userservices

this derivation produced the following outputs:
  out -> /nix/store/4ywyzhfrr8vafsycg4ri7zpcgdpgzm27-userservices

nix-repl> :q
gistfile1.txt
[clever@amd-nixos:~/x/85e0e3e7ddcb26d623dd0f51bcae5478-3d27398d9a08344fa13d9a97020aac91fdb99b74]$ nix-build default.nix --show-trace
these derivations will be built:
  /nix/store/b916ygzfyhiarwlj4xnc1kjdnsn3c6b2-gpg-agent.drv
  /nix/store/kshasn2jxp28sb7ydv1pgdq9dyl772k7-userservices.drv
building path(s) ‘/nix/store/kxj4l95jz8w9pv4cf8w0pj9l4inviq2h-gpg-agent’
building path(s) ‘/nix/store/4ywyzhfrr8vafsycg4ri7zpcgdpgzm27-userservices’
created 1 symlinks in user environment
/nix/store/4ywyzhfrr8vafsycg4ri7zpcgdpgzm27-userservices

[clever@amd-nixos:~/x/85e0e3e7ddcb26d623dd0f51bcae5478-3d27398d9a08344fa13d9a97020aac91fdb99b74]$ ls -ltrh result/
total 512
lrwxrwxrwx 1 root root 71 Dec 31  1969 gpg-agent.service -> /nix/store/kxj4l95jz8w9pv4cf8w0pj9l4inviq2h-gpg-agent/gpg-agent.service

[clever@amd-nixos:~/x/85e0e3e7ddcb26d623dd0f51bcae5478-3d27398d9a08344fa13d9a97020aac91fdb99b74]$ cat result/gpg-agent.service 
[Unit]
Description = GnuPG Agent
[Service]
ExecStart = /nix/store/j45xz52zawkdq0g711krkhlzfx2d749m-gnupg-2.1.11/bin/gpg-agent --daemon
default.nix
{ lib, writeTextFile, buildEnv, callPackage }:

with lib;
with builtins;
let
  makeExecStart = { command, args }:
    ''ExecStart = ${command} ${lib.concatStringsSep " " args}'';
  makeUnit = { name, description, execStart }: writeTextFile {
    name = name;
    text = ''
      [Unit]
      Description = ${description}
      [Service]
      ${lib.concatStringsSep "\n" (map makeExecStart execStart)}
    '';
    destination = "/${name}.service";
  };
  importUnitFile = fileName: callPackage (./units + "/${fileName}") { inherit makeUnit; };
  units = map importUnitFile (lib.attrNames (builtins.readDir ./units));
in {
  userServices = buildEnv {
    name = "userservices";
    paths = units;
  };
  inherit importUnitFile units makeUnit makeExecStart;
}

nix 使用git中的nixpkgs包含测试构建设置

使用git中的nixpkgs包含测试构建设置

enpass_default.nix
{stdenv, fetchurl, dpkg, patchelf, openssl, xorg
,  glib, mesa, libpulseaudio, zlib, dbus
, qt, makeWrapper
, ...}:
let
  data = import ./data.nix;
  uselibs = with xorg; [
    qt.qtbase
    qt.qtmultimedia
    qt.qtxmlpatterns
    qt.qtwebsockets
    openssl.out
    mesa
    libpulseaudio
    zlib
    dbus
    libX11
    libXext
    libXScrnSaver
    glib.out
  ];
    libPath = stdenv.lib.makeLibraryPath ([
      stdenv.cc
      stdenv.cc.cc.lib
    ] ++ uselibs);
in stdenv.mkDerivation rec {

    version = data.version;
    name = "enpass-${version}";

    src = fetchurl {
      url = "http://repo.sinew.in/${data.path}";
      sha256 = data.sha256;
    };

    buildInputs = [makeWrapper dpkg patchelf qt.makeQtWrapper ];
    phases = [ "unpackPhase" "installPhase" "fixupPhase" ];

    unpackPhase = "dpkg -X $src .";
    installPhase=''
    mkdir $out
    cp -r opt/Enpass/*  $out
    rm $out/lib -r
    rm -r $out/plugins/platforms/

    patchelf  \
      --set-interpreter $(cat $NIX_CC/nix-support/dynamic-linker) \
      $out/bin/Enpass


    wrapQtProgram $out/bin/Enpass --set LD_LIBRARY_PATH "${libPath}:$out/plugins/sqldrivers/"
    '';


}
enpass_data.nix
{
  version = "5.2.1.1";
  path = "pool/main/e/enpass/enpass_5.2.1.1_amd64.deb";
  sha256 = "772cb5656c55605f1c7ac58203ab0cf07894c57c19f1709dac36455287cbd953";
}
build.nix

with import <nixpkgs> {};
callPackage ./enpass {  qt = qt56; }

nix 路由器设置

路由器设置

router.nix
{ lib, config, pkgs, ... }:

let
  passwords = import ./passwords.nix;
  builders = import ./builders.nix;
  keys = import ./keys.nix;
in
{
  imports = [ ./core.nix ./router.nat.nix /root/hydra/hydra-module.nix ./snmpd.nix ];
  networking = {
    hostId = "136e6c46";
    firewall = {
      enable = true;
      allowPing = true;
      allowedUDPPorts = [ ];
      allowedTCPPorts = [ ];
      trustedInterfaces = [ "tox_master0" ]; # a VPN
    };
    search = [ "localnet" ];
  };
  services = {
    radvd = {
      enable = true;
      config = ''
        interface enp4s2f1 {
          AdvSendAdvert on;
          AdvHomeAgentFlag off;
          MinRtrAdvInterval 30;
          MaxRtrAdvInterval 100;
          AdvDefaultPreference high;
          prefix 2001:470:1d:19a::/64 {
            AdvOnLink on;
            AdvAutonomous on;
            AdvRouterAddr on;
          };
        };
      '';
    };
  };
}
router.nat.nix
{ lib, config, pkgs, ... }:

let
  WANMASTER = "enp4s2f0";
  WAN = "wan";
  LAN = "enp4s2f1";
in
{
  networking = {
    defaultMailServer.directDelivery = true;
    defaultMailServer.hostName = "c2d.localnet";
    vlans = {
      wan = {
        interface = "${WANMASTER}";
        id = 35;
      };
    };
    firewall = {
      enable = true;
      extraCommands = lib.mkMerge [ (lib.mkAfter ''
        iptables -w -t filter -A nixos-fw -s 192.168.2.0/24 -p udp --dport 53 -i ${LAN} -j nixos-fw-accept
      '') ];
    };
    interfaces = {
      ${WANMASTER} = {
        useDHCP = false;
      };
      ${WAN} = {
        useDHCP = true;
      };
      ${LAN} = {
        ipAddress = "192.168.2.1";
        prefixLength = 24;
      };
    };
    nat = {
      enable = true;
      externalInterface = "${WAN}";
      internalIPs = [ "192.168.2.0/24" "10.67.15.0/24" ];
      internalInterfaces = [ "${LAN}" ];
      forwardPorts = [
        { destination = "192.168.2.61"; sourcePort = 25; }      # email
        { destination = "192.168.2.62"; sourcePort = 80; }      # http
      ];
    };
  };
  services = {
    bind = {
      enable = true;
      cacheNetworks = [ "192.168.2.0/24" "127.0.0.0/8" ];
      zones = [
        {
          name = "localnet";
          slaves = [ ];
          file = ./localnet;
        }
        {
          name = "2.168.192.in-addr.arpa";
          slaves = [ ];
          file = ./lan.reverse;
        }
      ];
    };
    dhcpd = {
      interfaces = [ "${LAN}" ]; 
      enable = true;
      machines = [
        { hostName = "ramboot"; ethernetAddress = "00:1c:23:16:4b:b3"; ipAddress = "192.168.2.10"; }
        { hostName = "nas";     ethernetAddress = "d0:50:99:7a:80:21"; ipAddress = "192.168.2.11"; }
        { hostName = "amd";     ethernetAddress = "40:16:7e:b3:32:48"; ipAddress = "192.168.2.15"; }
        { hostName = "nix1";    ethernetAddress = "92:C5:E2:BB:12:A9"; ipAddress = "192.168.2.30"; }
        { hostName = "nix2";    ethernetAddress = "5E:88:5B:D7:6E:BC"; ipAddress = "192.168.2.31"; }
      ];
      extraConfig = ''
        subnet 192.168.2.0 netmask 255.255.255.0 {
          option domain-search "localnet";
          option subnet-mask 255.255.255.0;
          option broadcast-address 192.168.2.255;
          option routers 192.168.2.1;
          option domain-name-servers 192.168.2.1;
          range 192.168.2.100 192.168.2.200;
          next-server 192.168.2.61;
          if exists user-class and option user-class = "iPXE" {
            filename "http://c2d.localnet/boot.php?mac=''${net0/mac}&asset=''${asset:uristring}";
            #option root-path "iscsi:192.168.2.61:::1:iqn.2015-10.com.laptop-root";
          } else {
            filename = "undionly.kpxe";
          }
        }
      '';
    };
  };
}

nix builders.nix

router.nix
{ lib, config, pkgs, ... }:

let
  passwords = import ./passwords.nix;
  builders = import ./builders.nix;
  keys = import ./keys.nix;
in
{
  imports = [ ./core.nix ./router.nat.nix /root/hydra/hydra-module.nix ./snmpd.nix ];
  services = {
    nix-serve = {
      secretKeyFile = "/etc/nix/signing-key.sec";
      enable = true;
    };
    hydra = {
      enable = true;
      package = (import /root/hydra/release.nix {}).build.x86_64-linux;
      hydraURL = "http://router.localnet:3000";
      notificationSender = "clever@ext.earthtools.ca";
    };
    postgresql.enable = true;
    postgresql.package = pkgs.postgresql;
    openssh.passwordAuthentication = false;
  };
  nix = {
    buildMachines = builders.arm ++ builders."64bit";
    buildCores = 2;
    extraOptions = ''
      gc-keep-derivations = true
      gc-keep-outputs = true
    '';
  };
}
builders.nix
let
  key = "/etc/nixos/keys/distro";
in
{
  arm = [
    {
      hostName = "192.168.2.30";
      maxJobs = 1;
      sshUser = "builder";
      system = "armv6l-linux";
      sshKey = key;
    }
#    {
#      hostName = "192.168.2.31";
#      maxJobs = 1;
#      sshUser = "builder";
#      system = "armv6l-linux";
#      sshKey = key;
#    }
  ];
  "32bit" = [
    {
      hostName = "ramboot";
      maxJobs = 1;
      sshUser = "clever";
      system = "i686-linux";
      sshKey = key;
    }
    {
      hostName = "router.localnet";
      maxJobs = 1;
      sshUser = "builder";
      system = "i686-linux";
      sshKey = key;
    }
  ];

nix iscsi启动

iscsi启动

iscsi-boot.nix
{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.boot.initrd.iscsi;
  fileSystems = attrValues config.fileSystems ++ config.swapDevices;
  iscsiDevs = filter (dev: dev.iscsi.enable) fileSystems;
  anyiscsi = fold (j: v: v || j.iscsi.enable) false iscsiDevs;
  iscsiOptions = {
    iscsi = {
      enable = mkOption { default = false; type = types.bool; description = "The block device is backed by iscsi, adds this device as a initrd entry"; };
      host = mkOption { example = "192.168.2.61"; type = types.string; description = "the iscsi target"; };
      lun = mkOption { example = "iqn.2015-01.com.example:san.img"; type = types.string; description = "the LUN to connect"; };
    };
  };
in
{
  options = {
    fileSystems = mkOption {
      options = [ iscsiOptions ];
    };
    swapDevices = mkOption {
      options = [ iscsiOptions ];
    };
    boot.initrd.iscsi = {
      initiatorName = mkOption {
        example = "iqn.2015-09.com.example:3255a7223b2";
        type = types.string;
        description = "the initiator name used when connecting";
      };

      netDev = mkOption {
        example = "eth0";
        type = types.string;
        description = "the network device the initrd will setup for iscsi";
      };
    }; # iscsi
  }; # options
  config = mkIf anyiscsi (
    let
      ipAddress = config.networking.interfaces.${cfg.netDev}.ipAddress;
      prefixLength = config.networking.interfaces.${cfg.netDev}.prefixLength;
      defaultGateway = config.networking.defaultGateway;
    in
    {
      boot.initrd = {
        kernelModules = [ "iscsi_tcp" ];
        availableKernelModules = [ "crc32c" ];
        extraUtilsCommands = ''
          copy_bin_and_libs ${pkgs.openiscsi}/bin/iscsistart
        '';
        extraUtilsCommandsTest = ''
          $out/bin/iscsistart -v 
        '';
        preLVMCommands = ''
          ip link set ${cfg.netDev} up
          ip addr add ${ipAddress}/${toString prefixLength} dev ${cfg.netDev}
          # todo, make this optional
          ip route add via ${defaultGateway} dev ${cfg.netDev}
        '' + concatMapStrings (dev: "iscsistart -t ${dev.iscsi.lun} -a ${dev.iscsi.host} -i ${config.boot.initrd.iscsi.initiatorName} -g 0\n") iscsiDevs;
      }; # initrd
  }); # config
}

nix box1.nix

router.nix
  virtualisation = {
    memorySize = 1024;
    qemu.networkingOptions = [
      "-net nic,vlan=0,macaddr=52:54:00:12:34:00"
      "-net vde,vlan=0,sock=/run/vde.ctl"
    ];
  };
box2.nix
  virtualisation = {
    memorySize = 512;
    graphics = false;
    qemu.networkingOptions = [ "-net nic,macaddr=52:54:00:12:34:02" "-net vde,sock=/run/vde.ctl" ];
  };
box1.nix
  virtualisation = {
    memorySize = 512;
    graphics = false;
    qemu.networkingOptions = [ "-net nic,macaddr=52:54:00:12:34:01" "-net vde,sock=/run/vde.ctl" ];
  };

nix iSCSI的boot.nix

tgt_service.nix
{ config, lib, pkgs, ... }:

with lib;

let
  targetOpts = { name, config, ... }: {
    options = {
      name = mkOption {
        type = types.str;
      };
      backingStore = mkOption {
        type = types.str;
      };
      index = mkOption {
        type = types.int;
        description = "the index of the target, must be unique within the server";
      };
    };
    config = {
      name = mkDefault name;
    };
  };
      makeService = target: {
        name = target.name;
        value = {
          description = target.name+" auto-starter";
          wantedBy = [ "basic.target" ];
          partOf = [ "tgtd.service" ];
          script = ''
            ${pkgs.tgt}/bin/tgtadm --lld iscsi --op new --mode target --tid ${builtins.toString target.index} -T ${target.name}
            ${pkgs.tgt}/bin/tgtadm --lld iscsi --op new --mode logicalunit --tid ${builtins.toString target.index} --lun 1 -b ${target.backingStore}
            ${pkgs.tgt}/bin/tgtadm --lld iscsi --op bind --mode target --tid ${builtins.toString target.index} -I ALL # gives everybody access
          '';
          serviceConfig = {
            Type = "oneshot";
            RemainAfterExit = true;
            ExecStop = "${pkgs.tgt}/bin/tgtadm --lld iscsi --op delete --mode target --tid ${builtins.toString target.index}";
          };
        };
      };
in
{
  options = {
    services.tgtd = {
      enable = mkOption {
        type = types.bool;
        default = false;
        description = "enable tgtd running on startup";
      };
      targets = mkOption {
        default = [];
        type = types.loaOf types.optionSet;
        options = targetOpts;
      };
    };
  };
  config = let
      LUNs = builtins.listToAttrs (map makeService (attrValues config.services.tgtd.targets));
      tgtd = {
        description = "tgtd daemon";
        wantedBy = [ "basic.target" ];
        serviceConfig = {
          ExecStart = "${pkgs.tgt}/bin/tgtd -f --iscsi nop_interval=30 --iscsi nop_count=10";
          ExecStop = "${pkgs.coreutils}/bin/sleep 30 ; ${pkgs.tgt}/bin/tgtadm --op delete --mode system";
          KillMode = "process";
          Restart = "on-success";
        };
      };
    in
     mkIf config.services.tgtd.enable {
      systemd.services = LUNs // { tgtd = tgtd; };
    };
}
repl example
[root@nas:~]# cat /etc/nixos/nixcfg/nas.nix 
{ ... }:

let
  keys = import ./keys.nix;
in
{
...
  services = {
    tgtd = {
      enable = true;
      targets = {
        "iqn.2016-01.laptop-root" = { backingStore = "/dev/naspool/laptop-root"; index = 1; };
        "iqn.2016-02.windows-extra" = { backingStore = "/dev/naspool/windows-extra"; index = 2; };
      };
    };
  };
}
[root@nas:~]# nix-repl '<nixos>'
Welcome to Nix version 1.11.2. Type :? for help.

Loading ‘<nixos>’...
Added 6 variables.

nix-repl> config.systemd.services."iqn.2016-01.laptop-root".description
"iqn.2016-01.laptop-root auto-starter"

nix-repl> config.systemd.services."iqn.2016-01.laptop-root".serviceConfig.ExecStart
"/nix/store/r5jddxlql2hkahaphl06yqclh0ahp5zi-unit-script/bin/iqn.2016-01.laptop-root-start "

nix-repl> config.systemd.services."iqn.2016-01.laptop-root".script
"/nix/store/vkz0bkpki3ha7p5h0b9wav35lnn4aj4v-tgt-1.0.60/bin/tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2016-01.laptop-root\n/nix/store/vkz0bkpki3ha7p5h0b9wav35lnn4aj4v-tgt-1.0.60/bin/tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /dev/naspool/laptop-root\n/nix/store/vkz0bkpki3ha7p5h0b9wav35lnn4aj4v-tgt-1.0.60/bin/tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL # gives everybody access\n"

motion_module.nix
{ lib, config, pkgs, ... }:

with lib;

let
  cfg = config.services.motion;
  camera_list = builtins.attrValues cfg.cameras;
  final_config = concatStringsSep "\n" ([ cfg.config ] ++ (map (cam: "thread ${cam}") thread_config_files));
  config_file = pkgs.writeText "motion.conf" final_config;
  thread_configs = (listToAttrs (map (cam: {
    name = "motion/${cam.name}.conf";
    value = { text = cfg.camera_common_config + "\n" + cam.config;};
  }) camera_list));
  thread_config_files = map (cam: pkgs.writeText "thread-${cam.name}.conf" (cfg.camera_common_config + "\n" + cam.config)) camera_list;
  camera_options = { name, config, ... }:
  {
    options = {
      name = mkOption { type = types.str; };
      config = mkOption { type = types.str; };
    };
    config = {
      name = mkDefault name;
    };
  };
in
{
  options = {
    services.motion = {
      enable = mkEnableOption "motion";
      config = mkOption {
        type = types.str;
        default = "";
        description = "the raw contents of motion.conf";
      };
      cameras = mkOption {
        type = types.loaOf types.optionSet;
        options = camera_options;
        default = [];
      };
      camera_common_config = mkOption {
        type = types.str;
        default = "";
        description = "lines inserted into every thread file";
      };
    };
  };
  config = mkIf config.services.motion.enable {
    systemd.services.motion = {
      description = builtins.trace "reading description" "Motion daemon";
      wantedBy = [ "basic.target" ];
      serviceConfig = {
        ExecStart = "${pkgs.motion}/bin/motion -c ${config_file}";
        KillMode = "process";
        Restart = "always";
        User = "motion";
      };
    };
    environment.etc = {
      "motion.conf".text = final_config;
    } // thread_configs;
    users.users = {
      motion = {
        uid = 1012;
      };
    };
  };
}
iscsi-boot.nix
{ config, lib, pkgs, ... }:

with lib;

let
  cfg = config.boot.initrd.iscsi;
  fileSystems = attrValues config.fileSystems ++ config.swapDevices;
  iscsiDevs = filter (dev: dev.iscsi.enable) fileSystems;
  anyiscsi = fold (j: v: v || j.iscsi.enable) false iscsiDevs;
  iscsiOptions = {
    iscsi = {
      enable = mkOption { default = false; type = types.bool; description = "The block device is backed by iscsi, adds this device as a initrd entry"; };
      host = mkOption { example = "192.168.2.61"; type = types.string; description = "the iscsi target"; };
      lun = mkOption { example = "iqn.2015-01.com.example:san.img"; type = types.string; description = "the LUN to connect"; };
    };
  };
in
{
  options = {
    fileSystems = mkOption {
      options = [ iscsiOptions ];
    };
    swapDevices = mkOption {
      options = [ iscsiOptions ];
    };
    boot.initrd.iscsi = {
      initiatorName = mkOption {
        example = "iqn.2015-09.com.example:3255a7223b2";
        type = types.string;
        description = "the initiator name used when connecting";
      };

      netDev = mkOption {
        example = "eth0";
        type = types.string;
        description = "the network device the initrd will setup for iscsi";
      };
    }; # iscsi
  }; # options
  config = mkIf anyiscsi (
    let
      ipAddress = config.networking.interfaces.${cfg.netDev}.ipAddress;
      prefixLength = config.networking.interfaces.${cfg.netDev}.prefixLength;
      defaultGateway = config.networking.defaultGateway;
    in
    {
      boot.initrd = {
        kernelModules = [ "iscsi_tcp" ];
        availableKernelModules = [ "crc32c" ];
        preLVMCommands = ''
          export PATH=$PATH:${pkgs.openiscsi.iscsistart}/bin/
          ip link set ${cfg.netDev} up
          ip addr add ${ipAddress}/${toString prefixLength} dev ${cfg.netDev}
          # todo, make this optional
          ip route add via ${defaultGateway} dev ${cfg.netDev}
        '' + concatMapStrings (dev: "iscsistart -t ${dev.iscsi.lun} -a ${dev.iscsi.host} -i ${config.boot.initrd.iscsi.initiatorName} -g 0\n") iscsiDevs;
      }; # initrd
  }); # config
}

nix gistfile1.nix

gistfile1.nix
# Edit this configuration file to define what should be installed on
# your system.  Help is available in the configuration.nix(5) man page
# and in the NixOS manual (accessible by running ‘nixos-help’).

{ config, lib, pkgs, ... }:

let
      local_dwm  = lib.overrideDerivation pkgs.dwm (o: {
        nativeBuildInputs = o.nativeBuildInputs ++ [ pkgs.xorg.libXcursor ];
        patches = [
          ../pkgs/dwm/dwm-6.1-xcursor-fix.diff
          ../pkgs/dwm/dwm-6.1-gaps.diff
          ../pkgs/dwm/dwm-6.1-htile.diff
          ../pkgs/dwm/dwm-6.1-pertag_without_bar.diff
          ../pkgs/dwm/dwm-6.1-push.diff
          ../pkgs/dwm/dwm-6.1-attachabove.diff
          ../pkgs/dwm/dwm-6.1-gaplessgrid.diff
          ../pkgs/dwm/dwm-6.1-config.diff
          ../pkgs/dwm/dwm-6.1-bar-padding.diff
          ../pkgs/dwm/dwm-6.1-config.laptop.diff
          ../pkgs/dwm/dwm-6.1-config.colors.diff
        ];
      });
in
{
  imports = [
    ../profiles/common.nix
    ../profiles/desktop.nix
    ../profiles/develop.nix
    ../profiles/network.nix
    ../profiles/documents.nix
  ];
    
  boot = {
    loader.grub = {
      enable = true;
      device = "/dev/sdb";
      version = 2;
      memtest86.enable = true;
      extraEntries = ''
        menuentry "Windows 10" {
          chainloader (hd1,1)+1
        }

       menuentry 'Arch Linux' --class arch --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-ccaec69b-c4c5-4fa6-96e6-3af7523cafcb' {
          load_video
          set gfxpayload=keep
          insmod gzio
          insmod part_msdos 
          insmod ext2
          set root='hd1,msdos1'
          if [ x$feature_platform_search_hint = xy ]; then
            search --no-floppy --fs-uuid --set=root --hint-bios=hd1,msdos1 --hint-efi=hd1,msdos1 --hint-baremetal=ahci1,msdos1  b1f6d398-fe1e-4195-8d9b-baca3df4f61b
          else
            search --no-floppy --fs-uuid --set=root b1f6d398-fe1e-4195-8d9b-baca3df4f61b
          fi
          echo	'Loading Linux linux ...'
          linux	/vmlinuz-linux root=UUID=ccaec69b-c4c5-4fa6-96e6-3af7523cafcb rw  quiet
          echo	'Loading initial ramdisk ...'
          initrd	 /initramfs-linux.img
       }
      '';
      extraConfig = ''
        set gfxpayload=1920x1080x32
      '';
    };
    kernelPackages = pkgs.linuxPackages_4_3;
    kernelModules = [ 
      "acpi-cpufreq"
      "msr" 
      "i951"
    ];
  };


  # TODO: Move to proper service .nix file
  systemd.services.powertopTune = {
    description = "Auto-tune tunables with powertop";
    wantedBy = [ "multi-user.target" ];
    path = [ pkgs.powertop ];
    serviceConfig = {
      Type = "idle";
      ExecStart = "${pkgs.powertop}/bin/powertop --auto-tune";
      User = "root";
    };
    restartIfChanged = false;
  };

  hardware.enableAllFirmware = true;
  networking = {
    hostName = "h04x-laptop"; 
    wireless.enable = true;  
  };

  environment.systemPackages = with pkgs; [
    powertop 
    xorg.xbacklight xorg.xf86inputsynaptics
    audacity inkscape mpv librecad openscad #freecad
  ];

  i18n = {
    consoleFont = "Lat2-Terminus16";
    consoleKeyMap = /etc/nixos/files/us-capswap.map.gz;
    defaultLocale = "en_US.UTF-8";
  };

  services = { 
    redshift = {
      enable = true;
      latitude = "53.3";
      longitude = "10";
      temperature = {
        day = 6500;
        night = 3400;
      };
    };

    xserver = {
      videoDrivers = [ "intel" ];
      vaapiDrivers = [ pkgs.vaapiIntel pkgs.vaapiVdpau ];
      modules = [ pkgs.xorg.xf86inputsynaptics ];
      desktopManager.session = [{
        name = "laptop";
        start = ''
          export XCURSOR_PATH=${config.system.path}/share/icons
          export XCURSOR_THEME="Vanilla-DMZ"
          export XCURSOR_SIZE=32
          #${pkgs.xorg.xsetroot}/bin/xsetroot -cursor_name left_ptr
          #${pkgs.compton}/bin/compton -b --config ${../dotfiles/compton.conf}
          ${pkgs.feh}/bin/feh --bg-scale ${../files/bg.jpg} &
          ${pkgs.xlibs.xrdb}/bin/xrdb -load ${../dotfiles/Xresources_laptop}
          (${pkgs.conky}/bin/conky -c ${../dotfiles/bar_laptop} | while read LINE; \
            do ${pkgs.xorg.xsetroot}/bin/xsetroot -name "$LINE"; \
          done) & 

          ${local_dwm}/bin/dwm &
          waitPID=$!
        '';
      }];
      deviceSection = ''
        Option  "TearFree"    "true"
        Option  "AccelMethod" "SNA"
        #Option  "DRI"         "3"
      '';
      config = ''
        Section "InputClass"
           Identifier "Clickpad"
           MatchIsTouchpad "on"
           MatchDevicePath "/dev/input/event*"
           Driver "synaptics"
           # Synaptics options come here.
            Option "TapButton1" "1"
            Option "TapButton2" "3"
            Option "TapButton3" "2"
            Option "SoftButtonAreas" "60% 0 0 40% 40% 60% 0 40%"
           Option "AreaTopEdge"          "30%"
           Option "AreaBottomEdge"       "0"
        
        
           Option "VertTwoFingerScroll"  "1"
           Option "HorizTwoFingerScroll"  "1"
           Option "VertScrollDelta"	   "-99"
           Option "HorizScrollDelta"	   "-99"
           
           Option "AccelFactor"       "0"
           Option "MaxSpeed"          "1"
           Option "MinSpeed"          "15"
        
           Option "VertResolution" "100"
           Option "HorizResolution" "65"
           # disable synaptics driver pointer acceleration
           Option "MinSpeed" "1"
           Option "MaxSpeed" "1"
           # tweak the X-server pointer acceleration
           Option "AccelerationProfile" "2"
           Option "AdaptiveDeceleration" "16"
           Option "ConstantDeceleration" "16"
           Option "VelocityScale" "272"
        
        EndSection
        
        Section "InputClass"
           Identifier   "TrackPoint"
           MatchProduct "TrackPoint"
           MatchDriver  "synaptics"
           #MatchDevicePath  "/dev/input/event*"
           Option       "EmulateWheel"       "true"
           Option       "EmulateWheelButton" "2"
           Option       "Emulate3Buttons"    "false"
           Option       "XAxisMapping" 	  "6 7"
           Option       "YAxisMapping" 	  "4 5"
        EndSection
      '';
    }; 
  };
}

nix 网络启动nixos

网络启动nixos

tgt_service.nix
{ config, lib, pkgs, ... }:

with lib;

let
  targetOpts = { name, config, ... }: {
    options = {
      name = mkOption {
        type = types.str;
      };
      backingStore = mkOption {
        type = types.str;
      };
      index = mkOption {
        type = types.int;
        description = "the index of the target, must be unique within the server";
      };
    };
    config = {
      name = mkDefault name;
    };
  };
      makeService = target: {
        name = target.name;
        value = {
          description = target.name+" auto-starter";
          wantedBy = [ "basic.target" ];
          partOf = [ "tgtd.service" ];
          script = ''
            ${pkgs.tgt}/bin/tgtadm --lld iscsi --op new --mode target --tid ${builtins.toString target.index} -T ${target.name}
            ${pkgs.tgt}/bin/tgtadm --lld iscsi --op new --mode logicalunit --tid ${builtins.toString target.index} --lun 1 -b ${target.backingStore}
            ${pkgs.tgt}/bin/tgtadm --lld iscsi --op bind --mode target --tid ${builtins.toString target.index} -I ALL # gives everybody access
          '';
          serviceConfig = {
            Type = "oneshot";
            RemainAfterExit = true;
            ExecStop = "${pkgs.tgt}/bin/tgtadm --lld iscsi --op delete --mode target --tid ${builtins.toString target.index}";
          };
        };
      };
in
{
  options = {
    services.tgtd = {
      enable = mkOption {
        type = types.bool;
        default = false;
        description = "enable tgtd running on startup";
      };
      targets = mkOption {
        default = [];
        type = types.loaOf types.optionSet;
        options = targetOpts;
      };
    };
  };
  config = let
      LUNs = builtins.listToAttrs (map makeService (attrValues config.services.tgtd.targets));
      tgtd = {
        description = "tgtd daemon";
        wantedBy = [ "basic.target" ];
        serviceConfig = {
          ExecStart = "${pkgs.tgt}/bin/tgtd -f --iscsi nop_interval=30 --iscsi nop_count=10";
          ExecStop = "${pkgs.coreutils}/bin/sleep 30 ; ${pkgs.tgt}/bin/tgtadm --op delete --mode system";
          KillMode = "process";
          Restart = "on-success";
        };
      };
    in
     mkIf config.services.tgtd.enable {
      systemd.services = LUNs // { tgtd = tgtd; };
    };
}
dhcp fragment
        subnet 192.168.2.0 netmask 255.255.255.0 {
          option subnet-mask 255.255.255.0;
          option broadcast-address 192.168.2.255;
          option routers 192.168.2.1;
          range 192.168.2.100 192.168.2.200;
          next-server 192.168.2.61;
          if exists user-class and option user-class = "iPXE" {
            filename "http://192.168.2.61/boot.php?mac=${net0/mac}&asset=${asset:uristring}";
          } else {
            filename = "undionly.kpxe";
          }
        }
#3
setup dhcp to direct users to the tftp server with ipxe using the dhcp fragment

192.168.2.61 is the IP of the tftp and http server
#2
setup a tgt daemon using the tgt_module and tftp server
configure and rebuild-switch the server with server-configuration.nix
#1
[root@amd-nixos:~]# nix-build '<nixpkgs>' -A ipxe
these paths will be fetched (0.60 MiB download, 1.20 MiB unpacked):
  /nix/store/1xw30y28dfc1wz62wgcjifsp58c8wdkk-ipxe-20141124-5cbdc41
fetching path ‘/nix/store/1xw30y28dfc1wz62wgcjifsp58c8wdkk-ipxe-20141124-5cbdc41’...

*** Downloading ‘https://cache.nixos.org/nar/1sksixb1cc57ypjmm99k274wfmc3mqbrvnbvyilz0sd8h8bnyn0l.nar.xz’ (signed by ‘cache.nixos.org-1’) to ‘/nix/store/1xw30y28dfc1wz62wgcjifsp58c8wdkk-ipxe-20141124-5cbdc41’...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  614k  100  614k    0     0  1170k      0 --:--:-- --:--:-- --:--:-- 1172k

/nix/store/1xw30y28dfc1wz62wgcjifsp58c8wdkk-ipxe-20141124-5cbdc41

[root@amd-nixos:~]# mkdir /tftproot/

[root@amd-nixos:~]# cp -vi result/undionly.kpxe /tftproot/
server-configuration.nix
{ ... }:

{
  imports = [ ./tgt_service.nix ];
  services = {
    atftpd.enable = true;
    atftpd.root = "/tftproot";
    tgtd = {
      enable = true;
      targets = {
        # backing store can be a file made with truncate(1)
        "iqn.2016-01.laptop-root" = { backingStore = "/dev/naspool/laptop-root"; index = 1; };
      };
    };
  };
}

nix core.nix

snmpd.nix
{ pkgs, ... }:

let
  passwords = import ./passwords.nix;
in
{
  systemd.services.snmpd = let
    snmpconfig = pkgs.writeTextFile {
      name = "snmpd.conf";
      text = ''
        rocommunity ${passwords.snmp}
        disk / 10000
        extend cputemp ${pkgs.stdenv.shell} -c "${pkgs.acpi}/bin/acpi -t|egrep -o '[0-9\.]{3,}'"
      '';
    };
  in {
    description = "net-snmp daemon";
    wantedBy = [ "multi-user.target" ];
    serviceConfig = {
      ExecStart = "${pkgs.net_snmp}/bin/snmpd -f -c ${snmpconfig}";
      KillMode = "process";
      Restart = "always";
    };
  };
}
rpi.nix
{config,pkgs,...}:

let
  builders = import ./builders.nix;
in
{
  imports = [ ./core.nix ./snmpd.nix ];
  services.xserver = {
    videoDrivers = [ "fbdev" ];
  };
  hardware.opengl.enable = false;
  boot = {
    loader = {
      grub.enable = false;
      raspberryPi.enable = false;
      raspberryPi.version = 1;
      generic-extlinux-compatible.enable = true;
    };
  };
  hardware.sane.enable = false;
  services.nixosManual.enable = false; # FIXME: workaround SANE not evaluating on ARM
  sound.enable = false;
  nix = {
    #buildMachines = builders.arm;
  };
}

nix1.nix
{ pkgs, lib, config, ... }:

{
  imports = [ ./rpi.nix ./headless.nix ];
  services = {
    avahi = {
      enable = true;
      nssmdns = true;
    };
    xserver = {
      enable = false;
      displayManager.slim.enable = false;
      desktopManager.xfce.enable = false;
      desktopManager.xterm.enable = false;
    };
    toxvpn.enable = true;  
    toxvpn.localip = "192.168.123.21";
  };
  fileSystems = {
    "/" = {
      device = "UUID=d230cc98-8f33-457f-9fee-b65558165188";
      fsType = "ext4";
      iscsi = {
        enable = true;
        host = "192.168.2.61";
        lun = "iqn.2001-04.com.c2d-nix3";
      };
    };
    "/boot" = { device = "UUID=DCF1-5AC3"; };
  };
  environment.noXlibs = lib.mkDefault true;
  #i18n.supportedLocales = [ config.i18n.defaultLocale ];
  networking = {
    firewall.enable = false;
    hostName = "nix1";
    interfaces.eth0.ipAddress = "192.168.2.30";
    interfaces.eth0.prefixLength = 24;
    defaultGateway = "192.168.2.1";
    nameservers = [ "192.168.2.61" ];
    dhcpcd.persistent = true;
    nat = {
      enable = true;
      internalInterfaces = [ "ve-+" ];
      externalInterface = "eth0";
    };
  };
  nixpkgs.system = "armv6l-linux";
  nixpkgs.config = {
    allowUnfree = true;
    packageOverrides = pkgs: rec {
#      mesa_noglu = pkgs.callPackage ./mesa.nix {
#        grsecEnabled = true;
#        llvmPackages = pkgs.llvmPackages_36;
#      };
    };
  };
  environment.systemPackages = with pkgs; [ sysstat gdb git lsof ];
  boot = {
    initrd = {
      iscsi = {
        initiatorName = "iqn.2015-09.com.example:3255a7223b2";
        netDev = "eth0";
      };
    };
  };
}
headless.nix
{ config, pkgs, ... }:

{
  boot = {
    kernelParams = [ "boot.panic_on_fail" ];
  };
}
core.nix
{ config, pkgs, ...}:

let
  pixfix = if (builtins.currentSystem == "armv6l-linux") then
    [ ./pixman.nix ]
  else
    [];
  passwords = import ./passwords.nix;
  keys = import ./keys.nix;
in
{
  imports = [ ./vim.nix ./iscsi-boot.nix ./toxvpn_module.nix ./iscsi_module.nix ] ++ pixfix;
  environment.systemPackages = with pkgs; [ sqlite screen git util nix-repl utillinuxCurses psmisc ];
  programs = {
    screen.screenrc = ''
      defscrollback 5000
      caption always
    '';
    ssh = {
      knownHosts = [
        { hostNames = [ "192.168.2.1" "router.localnet" ]; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMSvyvC18BHfivZJDhWSm7VU3kEElfNfMIfeohkil614"; }
        { hostNames = [ "192.168.2.15" "amd.localnet" ]; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJhJRINrY5cFcqZ76GsAK7FU+wQhErlS6APdOIm7xcnW"; }
        { hostNames = [ "192.168.2.30" ]; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN3cnHv8e6v3mQvVLc7f7YgbeHKqQY2UtySeNL8Ew4ro"; }
        { hostNames = [ "192.168.2.31" ]; publicKey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGG8XsjV3ufF2+SWc1isnYqry3tdIqA01GA4d+SSak/F"; }
        { hostNames = [ "c2d.localnet" ]; publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBAeIKSyO23iQey8rfwqYdRrcn2sY/Uxcy/OogAZKYNBAeLdwWDmX73d/TZA/rLJtImKPjZYl1VyCIylnNaogvNs="; }
        { hostNames = [ "192.168.123.24" "gamah" ]; publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBJpj4w4nvVhxRlJOsdn1anlOjpmwgeAZqRAhYwtg3RY96Dv3gDnJTsOU5z4DoKOVq5YNfeTGI5HJTGZuV6BSik0="; }
        { hostNames = [ "andoria.angeldsis.com" ]; publicKey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHX1VUOiMc14jztdHArChYyUaLlTygtUSuH7qU+SD8DqnCmlmbTgeuRDEnsMCBGfWIRSftGi1VG7gC5cZwQxsiY="; }
      ];
    };
  };
  nixpkgs.config = {
    sqlite.interactive = true;
    packageOverrides = (import ./overrides.nix).packageOverrides;
  };
  services = {
    openssh = {
      enable = true;
      permitRootLogin = "yes";
    };
  };
  nix = {
    trustedUsers = [ "builder" ];
    distributedBuilds = true;
    binaryCaches = [
      "http://nixcache.localnet"
      "https://cache.nixos.org"
      #"http://hydra.nixos.org/"
    ];
    binaryCachePublicKeys = [
      "c2d.localnet-1:YTVKcy9ZO3tqPNxRqeYEYxSpUH5C8ykZ9ImUKuugf4c="
      "hydra.nixos.org-1:CNHJZBh9K4tP3EKF6FkkgeVYsS3ohTl+oS0Qa8bezVs="
    ];
  };
  users.extraUsers = {
    clever = {
      home = "/home/clever";
      isNormalUser = true;
      extraGroups = [ "wheel" "wireshark" ];
      uid = 1000;
      openssh.authorizedKeys.keys = [ keys.ramboot ];
      initialHashedPassword = passwords.hashedPw;
    };
    builder = {
      uid = 1001;
      isNormalUser = true;
      openssh.authorizedKeys.keys = [ keys.dual.distro keys.nix1.distro keys.router.distro keys.nix2 keys.amd_distro ];
    };
    root.openssh.authorizedKeys.keys = [ keys.dual.distro keys.amd ];
  };
  users.extraGroups.wireshark.gid = 500;
}