diff --git a/default.nix b/default.nix
index 52e8924cd..cab55d40a 100644
--- a/default.nix
+++ b/default.nix
@@ -3,3 +3,20 @@ import <nixpkgs/nixos/lib/eval-config.nix> {
     (import <nixpkgs/nixos/lib/from-env.nix> "NIXOS_CONFIG" <nixos-config>)
   ];
 }
+//
+{
+  lib = import ./lib;
+  systems = with import ./lib; let
+    ns = getEnv "LOGNAME";
+  in
+    genAttrs
+      (attrNames (filterAttrs (_: eq "directory") (readDir (<stockholm> + "/${ns}/1systems"))))
+      (name: let
+        config = import (<stockholm> + "/${ns}/1systems/${name}/config.nix");
+        source = import (<stockholm> + "/${ns}/1systems/${name}/source.nix");
+      in import <nixpkgs/nixos/lib/eval-config.nix> {
+        modules = [ config ];
+      } // {
+        inherit source;
+      });
+}
diff --git a/jeschli/1systems/bln/config.nix b/jeschli/1systems/bln/config.nix
index 8a3090a49..c9a7a34e2 100644
--- a/jeschli/1systems/bln/config.nix
+++ b/jeschli/1systems/bln/config.nix
@@ -1,42 +1,19 @@
-# 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, ... }:
 # bln config file
 {
   imports =
-    [ # Include the results of the hardware scan.
-      <stockholm/jeschli>
+    [ <stockholm/jeschli>
       <stockholm/jeschli/2configs/virtualbox.nix>
       <stockholm/jeschli/2configs/urxvt.nix>
+      <stockholm/jeschli/2configs/emacs.nix>
       ./hardware-configuration.nix
-      # ./dcso-vpn.nix
     ];
+
+  boot.loader.systemd-boot.enable = true;
+  boot.loader.efi.canTouchEfiVariables = true;
+
   jeschliFontSize = 20;
-  # Use the GRUB 2 boot loader.
-  boot.loader.grub.enable = true;
-  boot.loader.grub.version = 2;
-  # boot.loader.grub.efiSupport = true;
-  # boot.loader.grub.efiInstallAsRemovable = true;
-  # boot.loader.efi.efiSysMountPoint = "/boot/efi";
-  # Define on which hard drive you want to install Grub.
-  boot.loader.grub.device = "/dev/sda"; # or "nodev" for efi only
-  boot.loader.grub.extraEntries = ''
-    menuentry "Debian GNU/Linux, kernel 4.9.0-4-amd64" {
-      search --set=drive1 --fs-uuid f169fd32-bf96-4da0-bc34-294249ffa606
-      linux ($drive1)/vmlinuz-4.9.0-4-amd64 root=/dev/mapper/pool-debian ro
-      initrd ($drive1)/initrd.img-4.9.0-4-amd64
-    }
-  '';
-  boot.initrd.luks.devices = [
-    {
-      name = "root";
-      device = "/dev/disk/by-uuid/cba5d550-c3c8-423e-a913-14b5210bdd32";
-      preLVM = true;
-      allowDiscards = true;
-    }
-  ];
+
   environment.shellAliases = {
     n = "nix-shell";
     gd = "cd /home/markus/go/src/gitlab.dcso.lolcat";
@@ -46,23 +23,13 @@
       LOGNAME=jeschli exec nix-shell -I stockholm="$PWD" --run 'deploy  --system="bln"'
     '';
   };
-  networking.hostName = lib.mkForce "BLN02NB0154"; # Define your hostname.
+  networking.hostName = lib.mkForce "BLN02NB0232";
   networking.networkmanager.enable = true;
-  # networking.wireless.enable = true;  # Enables wireless support via wpa_supplicant.
-
-  # Select internationalisation properties.
-  # i18n = {
-  #   consoleFont = "Lat2-Terminus16";
-  #   consoleKeyMap = "us";
-  #   defaultLocale = "en_US.UTF-8";
-  # };
 
   # Set your time zone.
   time.timeZone = "Europe/Berlin";
 
-
-  # List packages installed in system profile. To search by name, run:
-  # $ nix-env -qaP | grep wget
+  # Setup Packages
   nixpkgs.config.allowUnfree = true;
   environment.variables = { GOROOT= [ "${pkgs.go.out}/share/go" ]; };
   environment.systemPackages = with pkgs; [
@@ -85,7 +52,7 @@
     emacs
   # databases
     sqlite
-  # internet 
+  # internet
     thunderbird
     hipchat
     chromium
@@ -114,79 +81,44 @@
   ];
 
 
-
-  # Some programs need SUID wrappers, can be configured further or are
-  # started in user sessions.
   programs.bash.enableCompletion = true;
   programs.vim.defaultEditor = true;
-  # programs.mtr.enable = true;
-  # programs.gnupg.agent = { enable = true; enableSSHSupport = true; };
 
-  # List services that you want to enable:
-
-  # Enable the OpenSSH daemon.
   services.openssh.enable = true;
 
-  # Open ports in the firewall.
-  # networking.firewall.allowedTCPPorts = [ ... ];
-  # networking.firewall.allowedUDPPorts = [ ... ];
-  # Or disable the firewall altogether.
-  # networking.firewall.enable = false;
-
   # Enable CUPS to print documents.
   services.printing.enable = true;
   services.printing.drivers = [ pkgs.postscript-lexmark ];
+
   # Enable the X11 windowing system.
   services.xserver.enable = true;
-  # services.xserver.xrandrHeads = [
-  #  { output = "eDP1"; }
-  #  { output = "DP-2-2-8"; primary = true; }
-  #  { output = "DP-2-1-8"; monitorConfig = ''Option "Rotate" "left"''; }
-  # ];
-  # services.xserver.layout = "us";
-  # services.xserver.xkbOptions = "eurosign:e";
+  services.xserver.videoDrivers = [ "nvidia" ];
 
-  # Enable touchpad support.
-  # services.xserver.libinput.enable = true;
-
-  # Enable the KDE Desktop Environment.
-#  services.xserver.displayManager.lightdm.enable = true;
   services.xserver.windowManager.xmonad.enable = true;
   services.xserver.windowManager.xmonad.enableContribAndExtras = true;
-#   services.xserver.desktopManager.gnome3.enable = true;
-  # services.xserver.displayManager.gdm.enable = true;
   services.xserver.displayManager.sddm.enable = true;
-  #services.xserver.desktopManager.plasma5.enable = true;
-#  services.xserver.displayManager.sessionCommands = ''
-#    (sleep 1 && ${pkgs.xorg.xrandr}/bin/xrandr --output VIRTUAL1 --off --output eDP1 --mode 1920x1080 --pos 5120x688 --rotate normal --output DP1 --off --output DP2-1 --mode 2560x1440 --pos 2560x328 --rotate normal --output DP2-2 --primary --mode 2560x1440 --pos 0x328 --rotate normal --output DP2-3 --off --output HDMI2 --off --output HDMI1 --off --output DP2 --off
-#'';
+  services.xserver.dpi = 100;
+  fonts.fontconfig.dpi = 100;
 
-  # Define a user account. Don't forget to set a password with ‘passwd’.
-  users.extraUsers.markus = {
+  users.extraUsers.jeschli = {
     isNormalUser = true;
-    extraGroups = ["docker"];
+    extraGroups = ["docker" "vboxusers"];
     uid = 1000;
   };
 
-  # This value determines the NixOS release with which your system is to be
-  # compatible, in order to avoid breaking some software such as database
-  # servers. You should change this only after NixOS release notes say you
-  # should.
-  system.stateVersion = "17.09"; # Did you read the comment?
-
+  system.stateVersion = "17.09";
   # Gogland Debugger workaround
-#  nixpkgs.config.packageOverrides = super: {
-#    idea.gogland = lib.overrideDerivation super.idea.gogland (attrs: {
-#      postFixup = ''
-#	interp="$(cat $NIX_CC/nix-support/dynamic-linker)"
-#	patchelf --set-interpreter $interp $out/gogland*/plugins/intellij-go-plugin/lib/dlv/linux/dlv
-#        chmod +x $out/gogland*/plugins/intellij-go-plugin/lib/dlv/linux/dlv
-#     '';
-#    });
-#  };
+  #  nixpkgs.config.packageOverrides = super: {
+  #    idea.gogland = lib.overrideDerivation super.idea.gogland (attrs: {
+  #      postFixup = ''
+  #	interp="$(cat $NIX_CC/nix-support/dynamic-linker)"
+  #	patchelf --set-interpreter $interp $out/gogland*/plugins/intellij-go-plugin/lib/dlv/linux/dlv
+  #        chmod +x $out/gogland*/plugins/intellij-go-plugin/lib/dlv/linux/dlv
+  #     '';
+  #    });
+  #  };
 
-#  virtualisation.docker.enable = true;
-  
+  virtualisation.docker.enable = true;
 
   # DCSO Certificates
   security.pki.certificateFiles = [
@@ -197,7 +129,7 @@
    (pkgs.fetchurl { url = "http://pki.dcso.de/ca/PEM/DCSOCACOMPC3G1.pem"; sha256 = "0w88qaqhwxzvdkx40kzj2gka1yi85ipppjdkxah4mscwfhlryrnk"; })
    (pkgs.fetchurl { url = "http://pki.dcso.de/ca/PEM/DCSOCAIDENC2G1.pem"; sha256 = "1z2qkyhgjvri13bvi06ynkb7mjmpcznmc9yw8chx1lnwc3cxa7kf"; })
    (pkgs.fetchurl { url = "http://pki.dcso.de/ca/PEM/DCSOCAIDENC3G1.pem"; sha256 = "0smdjjvz95n652cb45yhzdb2lr83zg52najgbzf6lm3w71f8mv7f"; })
-  ]; 
+  ];
 
   hardware.bluetooth.enable = true;
   krebs.build.host = config.krebs.hosts.bln;
diff --git a/jeschli/1systems/bln/hardware-configuration.nix b/jeschli/1systems/bln/hardware-configuration.nix
index 714162271..b774bfc19 100644
--- a/jeschli/1systems/bln/hardware-configuration.nix
+++ b/jeschli/1systems/bln/hardware-configuration.nix
@@ -1,6 +1,3 @@
-# Do not modify this file!  It was generated by ‘nixos-generate-config’
-# and may be overwritten by future invocations.  Please make changes
-# to /etc/nixos/configuration.nix instead.
 { config, lib, pkgs, ... }:
 
 {
@@ -8,27 +5,29 @@
     [ <nixpkgs/nixos/modules/installer/scan/not-detected.nix>
     ];
 
-  boot.initrd.availableKernelModules = [ "xhci_pci" "ahci" "usbhid" "sd_mod" "rtsx_pci_sdmmc" ];
+  boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sr_mod" "rtsx_pci_sdmmc" ];
   boot.kernelModules = [ "kvm-intel" ];
   boot.extraModulePackages = [ ];
 
+  boot.initrd.luks.devices.crypted.device = "/dev/disk/by-uuid/25534522-5748-4dcc-a5ca-80a3ac70f59d";
+
   fileSystems."/" =
-    { device = "/dev/disk/by-uuid/02144ea4-947d-440e-bbf9-99cab0dccf05";
+    { device = "/dev/disk/by-uuid/496c8889-96db-446d-9bac-60d4347faeac";
+      fsType = "ext4";
+    };
+
+  fileSystems."/home" =
+    { device = "/dev/disk/by-uuid/2785adf5-a99e-49d7-86d6-99f393f457ea";
       fsType = "ext4";
     };
 
   fileSystems."/boot" =
-    { device = "/dev/disk/by-uuid/f169fd32-bf96-4da0-bc34-294249ffa606";
-      fsType = "ext2";
-    };
-
-  fileSystems."/home" =
-    { device = "/dev/disk/by-uuid/68ef2163-7b3d-4dbb-add9-d3543ad7c738";
-      fsType = "ext4";
+    { device = "/dev/disk/by-uuid/927E-01A0";
+      fsType = "vfat";
     };
 
   swapDevices = [ ];
 
-  nix.maxJobs = lib.mkDefault 4;
+  nix.maxJobs = lib.mkDefault 8;
   powerManagement.cpuFreqGovernor = "powersave";
 }
diff --git a/jeschli/1systems/bolide/config.nix b/jeschli/1systems/bolide/config.nix
index 83640801f..699a85b58 100644
--- a/jeschli/1systems/bolide/config.nix
+++ b/jeschli/1systems/bolide/config.nix
@@ -10,6 +10,7 @@
       ./hardware-configuration.nix
       <stockholm/jeschli>
       <stockholm/jeschli/2configs/urxvt.nix>
+      <stockholm/jeschli/2configs/emacs.nix>
     ];
 
   krebs.build.host = config.krebs.hosts.bolide;
diff --git a/jeschli/1systems/brauerei/config.nix b/jeschli/1systems/brauerei/config.nix
index eb2bb11d2..49f439a06 100644
--- a/jeschli/1systems/brauerei/config.nix
+++ b/jeschli/1systems/brauerei/config.nix
@@ -5,6 +5,9 @@
     <stockholm/jeschli>
     ./hardware-configuration.nix
     <stockholm/jeschli/2configs/urxvt.nix>
+    <stockholm/jeschli/2configs/emacs.nix>
+    <stockholm/jeschli/2configs/xdg.nix>
+    <stockholm/jeschli/2configs/xserver>
   ];
 
   krebs.build.host = config.krebs.hosts.brauerei;
@@ -56,7 +59,6 @@
     terminator
     tmux
     wget
-  #  rxvt_unicode
   # editors
     emacs
   # internet
@@ -64,6 +66,7 @@
     chromium
     google-chrome
   # programming languages
+    exercism
     go
     gcc
     ghc
@@ -72,6 +75,9 @@
   # go tools
     golint
     gotools
+  # rust
+    cargo
+    rustc
   # dev tools
     gnumake
     jetbrains.pycharm-professional
@@ -104,8 +110,8 @@
   # services.printing.enable = true;
 
   # Enable the X11 windowing system.
-  services.xserver.enable = true;
-  services.xserver.layout = "us";
+  # services.xserver.enable = true;
+  # services.xserver.layout = "us";
   # services.xserver.xkbOptions = "eurosign:e";
 
   # Enable touchpad support.
@@ -114,18 +120,18 @@
   # Enable the KDE Desktop Environment.
   # services.xserver.displayManager.sddm.enable = true;
   # services.xserver.desktopManager.plasma5.enable = true;
-  services.xserver.displayManager.sddm.enable = true;
-  services.xserver.windowManager.xmonad.enable = true;
-  services.xserver.windowManager.xmonad.enableContribAndExtras = true;
-#
+  #  services.xserver.displayManager.sddm.enable = true;
+  #  services.xserver.windowManager.xmonad.enable = true;
+  #  services.xserver.windowManager.xmonad.enableContribAndExtras = true;
+  #
   # Define a user account. Don't forget to set a password with ‘passwd’.
-  users.extraUsers.jeschli = {
+  users.extraUsers.jeschli = { # TODO: define as krebs.users
     isNormalUser = true;
     uid = 1000;
   };
   users.extraUsers.jamie = {
     isNormalUser = true;
-    uid = 1001;
+    uid = 1001; # TODO genid
   };
 
   users.users.root.openssh.authorizedKeys.keys = [
@@ -138,4 +144,11 @@
   # should.
   system.stateVersion = "17.09"; # Did you read the comment?
 
+  hardware.trackpoint = {
+    enable = true;
+    sensitivity = 220;
+    speed = 0;
+    emulateWheel = true;
+  };
+
 }
diff --git a/jeschli/2configs/emacs.nix b/jeschli/2configs/emacs.nix
new file mode 100644
index 000000000..4c52432d3
--- /dev/null
+++ b/jeschli/2configs/emacs.nix
@@ -0,0 +1,74 @@
+{ config, pkgs, ... }:
+
+let
+  packageRepos = ''
+    (require 'package) ;; You might already have this line
+    (let* ((no-ssl (and (memq system-type '(windows-nt ms-dos))
+                        (not (gnutls-available-p))))
+           (url (concat (if no-ssl "http" "https") "://melpa.org/packages/")))
+      (add-to-list 'package-archives (cons "melpa" url) t)
+      (add-to-list 'package-archives
+                 '("org" . "http://orgmode.org/elpa/") t)
+    )
+    (when (< emacs-major-version 24)
+      ;; For important compatibility libraries like cl-lib
+      (add-to-list 'package-archives '("gnu" . "http://elpa.gnu.org/packages/")))
+    (package-initialize)
+  '';
+  evilMode = ''
+    ;; Evil Mode
+    (add-to-list 'load-path "~/.emacs.d/evil")
+    (require 'evil)
+    (evil-mode 1)
+    (require 'evil-org)
+    (add-hook 'org-mode-hook 'evil-org-mode)
+    (evil-org-set-key-theme '(navigation insert textobjects additional calendar))
+    (require 'evil-org-agenda)
+    (evil-org-agenda-set-keys)
+  '';
+  windowCosmetics = ''
+    (tool-bar-mode -1)                  ; Disable the button bar atop screen
+    (scroll-bar-mode -1)                ; Disable scroll bar
+    (setq inhibit-startup-screen t)     ; Disable startup screen with graphics
+    (setq-default indent-tabs-mode nil) ; Use spaces instead of tabs
+    (setq default-tab-width 2)          ; Two spaces is a tab
+    (setq tab-width 2)                  ; Four spaces is a tab
+    (setq visible-bell nil)             ; Disable annoying visual bell graphic
+    (setq ring-bell-function 'ignore)   ; Disable super annoying audio bell
+  '';
+  orgMode = ''
+    (add-to-list 'auto-mode-alist '("\\.\\(org\\|org_archive\\|txt\\)$" . org-mode))
+    (global-set-key "\C-cl" 'org-store-link)
+    (global-set-key "\C-ca" 'org-agenda)
+    (global-set-key "\C-cb" 'org-iswitchb)
+    (if (boundp 'org-user-agenda-files)
+      (setq org-agenda-files org-user-agenda-files)
+      (setq org-agenda-files (quote ("~/projects/notes")))
+    )
+  '';
+  recentFiles = ''
+    (recentf-mode 1)
+    (setq recentf-max-menu-items 25)
+    (global-set-key "\C-x\ \C-r" 'recentf-open-files)
+  '';
+  dotEmacs = pkgs.writeText "dot-emacs" ''
+    ${packageRepos}
+    ${orgMode}
+    ${recentFiles}
+    ${windowCosmetics}
+  '';
+  emacsWithCustomPackages = (pkgs.emacsPackagesNgGen pkgs.emacs).emacsWithPackages (epkgs: [
+    epkgs.melpaStablePackages.magit
+    epkgs.melpaPackages.mmm-mode
+    epkgs.melpaPackages.nix-mode
+    epkgs.melpaPackages.go-mode
+    epkgs.melpaPackages.google-this
+  ]);
+  myEmacs = pkgs.writeDashBin "my-emacs" ''
+    exec ${emacsWithCustomPackages}/bin/emacs -q -l ${dotEmacs} "$@"
+  '';
+in {
+  environment.systemPackages = [
+    myEmacs
+  ];
+}
diff --git a/jeschli/2configs/virtualbox.nix b/jeschli/2configs/virtualbox.nix
index b2cb851a1..c9bb8c41f 100644
--- a/jeschli/2configs/virtualbox.nix
+++ b/jeschli/2configs/virtualbox.nix
@@ -1,7 +1,7 @@
 { config, pkgs, ... }:
 
 let
-  mainUser = config.users.extraUsers.markus;
+  mainUser = config.users.extraUsers.jeschli;
 
 in {
   #services.virtualboxHost.enable = true;
diff --git a/jeschli/2configs/xdg.nix b/jeschli/2configs/xdg.nix
new file mode 100644
index 000000000..18bac9b38
--- /dev/null
+++ b/jeschli/2configs/xdg.nix
@@ -0,0 +1,14 @@
+{ config, lib, pkgs, ... }:
+
+with import <stockholm/lib>;
+
+{
+  environment.variables.XDG_RUNTIME_DIR = "/run/xdg/$LOGNAME";
+
+  systemd.tmpfiles.rules = let
+    forUsers = flip map users;
+    isUser = { name, group, ... }:
+      name == "root" || hasSuffix "users" group;
+    users = filter isUser (mapAttrsToList (_: id) config.users.users);
+  in forUsers (u: "d /run/xdg/${u.name} 0700 ${u.name} ${u.group} -");
+}
diff --git a/jeschli/2configs/xserver/Xmodmap.nix b/jeschli/2configs/xserver/Xmodmap.nix
new file mode 100644
index 000000000..d2b1b2604
--- /dev/null
+++ b/jeschli/2configs/xserver/Xmodmap.nix
@@ -0,0 +1,27 @@
+{ config, pkgs, ... }:
+
+with import <stockholm/lib>;
+
+pkgs.writeText "Xmodmap" ''
+  !keycode 66 = Caps_Lock
+  !remove Lock = Caps_Lock
+  clear Lock
+
+  ! caps lock
+  keycode  66 = Mode_switch
+
+  keycode  13 = 4 dollar EuroSign cent
+  keycode  30 = u U udiaeresis Udiaeresis
+  keycode  32 = o O odiaeresis Odiaeresis
+  keycode  38 = a A adiaeresis Adiaeresis
+  keycode  39 = s S ssharp
+
+  keycode  33 = p P Greek_pi Greek_PI
+  keycode  46 = l L Greek_lambda Greek_LAMBDA
+
+  keycode  54 = c C cacute Cacute
+
+  !                       BULLET OPERATOR
+  keycode 17 = 8 asterisk U2219
+  keycode 27 = r R r U211D
+''
diff --git a/jeschli/2configs/xserver/Xresources.nix b/jeschli/2configs/xserver/Xresources.nix
new file mode 100644
index 000000000..e433a855e
--- /dev/null
+++ b/jeschli/2configs/xserver/Xresources.nix
@@ -0,0 +1,52 @@
+{ config, lib, pkgs, ... }:
+
+with import <stockholm/lib>;
+
+pkgs.writeText "Xresources" /* xdefaults */ ''
+  URxvt*cutchars: "\\`\"'&()*,;<=>?@[]^{|}‘’"
+  URxvt*eightBitInput: false
+  URxvt*font: -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1
+  URxvt*boldFont: -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1
+  URxvt*scrollBar: false
+  URxvt*background: #050505
+  URxvt*foreground: #d0d7d0
+  URxvt*cursorColor: #f042b0
+  URxvt*cursorColor2: #f0b000
+  URxvt*cursorBlink: off
+  URxvt*jumpScroll: true
+  URxvt*allowSendEvents: false
+  URxvt*charClass: 33:48,37:48,45-47:48,64:48,38:48,61:48,63:48
+  URxvt*cutNewline: False
+  URxvt*cutToBeginningOfLine: False
+
+  URxvt*color0: #232342
+  URxvt*color3: #c07000
+  URxvt*color4: #4040c0
+  URxvt*color7: #c0c0c0
+  URxvt*color8: #707070
+  URxvt*color9: #ff6060
+  URxvt*color10: #70ff70
+  URxvt*color11: #ffff70
+  URxvt*color12: #7070ff
+  URxvt*color13: #ff50ff
+  URxvt*color14: #70ffff
+  URxvt*color15: #ffffff
+
+  URxvt*iso14755: False
+
+  URxvt*urgentOnBell: True
+  URxvt*visualBell: True
+
+  ! ref https://github.com/muennich/urxvt-perls
+  URxvt*perl-ext: default,url-select
+  URxvt*keysym.M-u: perl:url-select:select_next
+  URxvt*url-select.underline: true
+  URxvt*colorUL: #4682B4
+  URxvt.perl-lib: ${pkgs.urxvt_perls}/lib/urxvt/perl
+  URxvt*saveLines: 10000
+
+  root-urxvt*background: #230000
+  root-urxvt*foreground: #e0c0c0
+  root-urxvt*BorderColor: #400000
+  root-urxvt*color0: #800000
+''
diff --git a/jeschli/2configs/xserver/default.nix b/jeschli/2configs/xserver/default.nix
new file mode 100644
index 000000000..df06000f3
--- /dev/null
+++ b/jeschli/2configs/xserver/default.nix
@@ -0,0 +1,141 @@
+{ config, pkgs, ... }@args:
+with import <stockholm/lib>;
+let
+  cfg = {
+    cacheDir = cfg.dataDir;
+    configDir = "/var/empty";
+    dataDir = "/run/xdg/${cfg.user.name}/xmonad";
+    user = config.krebs.users.jeschli;
+  };
+in {
+
+  environment.systemPackages = [
+    pkgs.font-size
+    pkgs.gitAndTools.qgit
+    pkgs.mpv
+    pkgs.sxiv
+    pkgs.xdotool
+    pkgs.xsel
+    pkgs.zathura
+  ];
+
+  fonts.fonts = [
+    pkgs.xlibs.fontschumachermisc
+  ];
+
+  # TODO dedicated group, i.e. with a single user [per-user-setuid]
+  # TODO krebs.setuid.slock.path vs /run/wrappers/bin
+  krebs.setuid.slock = {
+    filename = "${pkgs.slock}/bin/slock";
+    group = "wheel";
+    envp = {
+      DISPLAY = ":${toString config.services.xserver.display}";
+      USER = cfg.user.name;
+    };
+  };
+
+  services.xserver = {
+  
+    # Don't install feh into systemPackages
+    # refs <nixpkgs/nixos/modules/services/x11/desktop-managers>
+    desktopManager.session = mkForce [];
+  
+    enable = true;
+    display = 11;
+    tty = 11;
+  
+    synaptics = {
+      enable = true;
+      twoFingerScroll = true;
+      accelFactor = "0.035";
+    };
+  };
+
+  systemd.services.display-manager.enable = false;
+
+  systemd.services.xmonad = {
+    wantedBy = [ "multi-user.target" ];
+    requires = [ "xserver.service" ];
+    environment = {
+      DISPLAY = ":${toString config.services.xserver.display}";
+
+      XMONAD_CACHE_DIR = cfg.cacheDir;
+      XMONAD_CONFIG_DIR = cfg.configDir;
+      XMONAD_DATA_DIR = cfg.dataDir;
+
+      XMONAD_STARTUP_HOOK = pkgs.writeDash "xmonad-startup-hook" ''
+        ${pkgs.xorg.xhost}/bin/xhost +LOCAL: &
+        ${pkgs.xorg.xmodmap}/bin/xmodmap ${import ./Xmodmap.nix args} &
+        ${pkgs.xorg.xrdb}/bin/xrdb ${import ./Xresources.nix args} &
+        ${pkgs.xorg.xsetroot}/bin/xsetroot -solid '#1c1c1c' &
+        wait
+      '';
+
+      # XXX JSON is close enough :)
+      XMONAD_WORKSPACES0_FILE = pkgs.writeText "xmonad.workspaces0" (toJSON [
+        "dashboard" # we start here
+        "stockholm"
+        "pycharm"
+        "chromium"
+        "iRC"
+        "git"
+        "hipbird"
+      ]);
+    };
+    serviceConfig = {
+      SyslogIdentifier = "xmonad";
+      ExecStartPre = "${pkgs.coreutils}/bin/mkdir -p ${toString [
+        "\${XMONAD_CACHE_DIR}"
+        "\${XMONAD_CONFIG_DIR}"
+        "\${XMONAD_DATA_DIR}"
+      ]}";
+      ExecStart = "${pkgs.xmonad-jeschli}/bin/xmonad";
+      ExecStop = "${pkgs.xmonad-jeschli}/bin/xmonad --shutdown";
+      User = cfg.user.name;
+      WorkingDirectory = cfg.user.home;
+    };
+  };
+
+  systemd.services.xserver = {
+    after = [
+      "systemd-udev-settle.service"
+      "local-fs.target"
+      "acpid.service"
+    ];
+    reloadIfChanged = true;
+    environment = {
+      XKB_BINDIR = "${pkgs.xorg.xkbcomp}/bin"; # Needed for the Xkb extension.
+      XORG_DRI_DRIVER_PATH = "/run/opengl-driver/lib/dri"; # !!! Depends on the driver selected at runtime.
+      LD_LIBRARY_PATH = concatStringsSep ":" (
+        [ "${pkgs.xorg.libX11}/lib" "${pkgs.xorg.libXext}/lib" ]
+        ++ concatLists (catAttrs "libPath" config.services.xserver.drivers));
+    };
+    serviceConfig = {
+      SyslogIdentifier = "xserver";
+      ExecReload = "${pkgs.coreutils}/bin/echo NOP";
+      ExecStart = toString [
+        "${pkgs.xorg.xorgserver}/bin/X"
+        ":${toString config.services.xserver.display}"
+        "vt${toString config.services.xserver.tty}"
+        "-config ${import ./xserver.conf.nix args}"
+        "-logfile /dev/null -logverbose 0 -verbose 3"
+        "-nolisten tcp"
+        "-xkbdir ${pkgs.xkeyboard_config}/etc/X11/xkb"
+      ];
+    };
+  };
+
+  systemd.services.urxvtd = {
+    wantedBy = [ "multi-user.target" ];
+    reloadIfChanged = true;
+    serviceConfig = {
+      SyslogIdentifier = "urxvtd";
+      ExecReload = "${pkgs.coreutils}/bin/echo NOP";
+      ExecStart = "${pkgs.rxvt_unicode}/bin/urxvtd";
+      Restart = "always";
+      RestartSec = "2s";
+      StartLimitBurst = 0;
+      User = cfg.user.name;
+    };
+  };
+}
diff --git a/jeschli/2configs/xserver/xserver.conf.nix b/jeschli/2configs/xserver/xserver.conf.nix
new file mode 100644
index 000000000..6f34e0150
--- /dev/null
+++ b/jeschli/2configs/xserver/xserver.conf.nix
@@ -0,0 +1,40 @@
+{ config, lib, pkgs, ... }:
+
+with import <stockholm/lib>;
+
+let
+  cfg = config.services.xserver;
+in
+
+pkgs.stdenv.mkDerivation {
+  name = "xserver.conf";
+
+  xfs = optionalString (cfg.useXFS != false)
+    ''FontPath "${toString cfg.useXFS}"'';
+
+  inherit (cfg) config;
+
+  buildCommand =
+    ''
+      echo 'Section "Files"' >> $out
+      echo $xfs >> $out
+
+      for i in ${toString config.fonts.fonts}; do
+        if test "''${i:0:''${#NIX_STORE}}" == "$NIX_STORE"; then
+          for j in $(find $i -name fonts.dir); do
+            echo "  FontPath \"$(dirname $j)\"" >> $out
+          done
+        fi
+      done
+
+      for i in $(find ${toString cfg.modules} -type d); do
+        if test $(echo $i/*.so* | wc -w) -ne 0; then
+          echo "  ModulePath \"$i\"" >> $out
+        fi
+      done
+
+      echo 'EndSection' >> $out
+
+      echo "$config" >> $out
+    '';
+}
diff --git a/jeschli/5pkgs/default.nix b/jeschli/5pkgs/default.nix
new file mode 100644
index 000000000..3fa5b5e85
--- /dev/null
+++ b/jeschli/5pkgs/default.nix
@@ -0,0 +1,11 @@
+with import <stockholm/lib>;
+
+self: super:
+
+# Import files and subdirectories like they are overlays.
+foldl' mergeAttrs {}
+  (map
+    (name: import (./. + "/${name}") self super)
+    (filter
+      (name: name != "default.nix" && !hasPrefix "." name)
+      (attrNames (readDir ./.))))
diff --git a/jeschli/5pkgs/simple/default.nix b/jeschli/5pkgs/simple/default.nix
new file mode 100644
index 000000000..1b9d8c235
--- /dev/null
+++ b/jeschli/5pkgs/simple/default.nix
@@ -0,0 +1,24 @@
+with import <stockholm/lib>;
+
+self: super:
+
+let
+  # This callPackage will try to detect obsolete overrides.
+  callPackage = path: args: let
+    override = self.callPackage path args;
+    upstream = optionalAttrs (override ? "name")
+      (super.${(parseDrvName override.name).name} or {});
+  in if upstream ? "name" &&
+        override ? "name" &&
+        compareVersions upstream.name override.name != -1
+    then trace "Upstream `${upstream.name}' gets overridden by `${override.name}'." override
+    else override;
+in
+
+  listToAttrs
+    (map
+      (name: nameValuePair (removeSuffix ".nix" name)
+                           (callPackage (./. + "/${name}") {}))
+      (filter
+        (name: name != "default.nix" && !hasPrefix "." name)
+        (attrNames (readDir ./.))))
diff --git a/jeschli/5pkgs/simple/xmonad-jeschli/default.nix b/jeschli/5pkgs/simple/xmonad-jeschli/default.nix
new file mode 100644
index 000000000..5bb391f98
--- /dev/null
+++ b/jeschli/5pkgs/simple/xmonad-jeschli/default.nix
@@ -0,0 +1,294 @@
+{ pkgs, ... }:
+pkgs.writeHaskell "xmonad-jeschli" {
+  executables.xmonad = {
+    extra-depends = [
+      "containers"
+      "extra"
+      "unix"
+      "X11"
+      "xmonad"
+      "xmonad-contrib"
+      "xmonad-stockholm"
+    ];
+    text = /* haskell */ ''
+{-# LANGUAGE DeriveDataTypeable #-} -- for XS
+{-# LANGUAGE FlexibleContexts #-} -- for xmonad'
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+
+
+module Main where
+
+import Control.Exception
+import Control.Monad.Extra (whenJustM)
+import Graphics.X11.ExtraTypes.XF86
+import Text.Read (readEither)
+import XMonad
+import System.IO (hPutStrLn, stderr)
+import System.Environment (getArgs, withArgs, getEnv, getEnvironment, lookupEnv)
+import System.Posix.Process (executeFile)
+import XMonad.Actions.DynamicWorkspaces ( addWorkspacePrompt, renameWorkspace
+                                        , removeEmptyWorkspace)
+import XMonad.Actions.GridSelect
+import XMonad.Actions.CycleWS (toggleWS)
+--import XMonad.Actions.CopyWindow ( copy )
+import XMonad.Layout.NoBorders ( smartBorders )
+import qualified XMonad.StackSet as W
+import Data.Map (Map)
+import qualified Data.Map as Map
+-- TODO import XMonad.Layout.WorkspaceDir
+import XMonad.Hooks.UrgencyHook (SpawnUrgencyHook(..), withUrgencyHook)
+-- import XMonad.Layout.Tabbed
+--import XMonad.Layout.MouseResizableTile
+import XMonad.Layout.Reflect (reflectVert)
+import XMonad.Layout.FixedColumn (FixedColumn(..))
+import XMonad.Hooks.Place (placeHook, smart)
+import XMonad.Hooks.FloatNext (floatNextHook)
+import XMonad.Actions.PerWorkspaceKeys (chooseAction)
+import XMonad.Layout.PerWorkspace (onWorkspace)
+--import XMonad.Layout.BinarySpacePartition
+
+--import XMonad.Actions.Submap
+import XMonad.Stockholm.Pager
+import XMonad.Stockholm.Rhombus
+import XMonad.Stockholm.Shutdown
+
+
+amixerPath :: FilePath
+amixerPath = "${pkgs.alsaUtils}/bin/amixer"
+
+urxvtcPath :: FilePath
+urxvtcPath = "${pkgs.rxvt_unicode}/bin/urxvtc"
+
+myFont :: String
+myFont = "-schumacher-*-*-*-*-*-*-*-*-*-*-*-iso10646-*"
+
+main :: IO ()
+main = getArgs >>= \case
+    ["--shutdown"] -> sendShutdownEvent
+    _ -> mainNoArgs
+
+mainNoArgs :: IO ()
+mainNoArgs = do
+    workspaces0 <- getWorkspaces0
+    xmonad
+        -- $ withUrgencyHookC dzenUrgencyHook { args = ["-bg", "magenta", "-fg", "magenta", "-h", "2"], duration = 500000 }
+        --                   urgencyConfig { remindWhen = Every 1 }
+        -- $ withUrgencyHook borderUrgencyHook "magenta"
+        -- $ withUrgencyHookC BorderUrgencyHook { urgencyBorderColor = "magenta" } urgencyConfig { suppressWhen = Never }
+        $ withUrgencyHook (SpawnUrgencyHook "echo emit Urgency ")
+        $ def
+            { terminal          = urxvtcPath
+            , modMask           = mod4Mask
+            , keys              = myKeys
+            , workspaces        = workspaces0
+            , layoutHook        = smartBorders $ FixedColumn 1 20 80 10 ||| Full
+            -- , handleEventHook   = myHandleEventHooks <+> handleTimerEvent
+            --, handleEventHook   = handleTimerEvent
+            , manageHook        = placeHook (smart (1,0)) <+> floatNextHook
+            , startupHook =
+                whenJustM (liftIO (lookupEnv "XMONAD_STARTUP_HOOK"))
+                          (\path -> forkFile path [] Nothing)
+            , normalBorderColor  = "#1c1c1c"
+            , focusedBorderColor = "#f000b0"
+            , handleEventHook = handleShutdownEvent
+            }
+
+
+getWorkspaces0 :: IO [String]
+getWorkspaces0 =
+    try (getEnv "XMONAD_WORKSPACES0_FILE") >>= \case
+      Left e -> warn (displaySomeException e)
+      Right p -> try (readFile p) >>= \case
+        Left e -> warn (displaySomeException e)
+        Right x -> case readEither x of
+          Left e -> warn e
+          Right y -> return y
+  where
+    warn msg = hPutStrLn stderr ("getWorkspaces0: " ++ msg) >> return []
+
+displaySomeException :: SomeException -> String
+displaySomeException = displayException
+
+
+forkFile :: FilePath -> [String] -> Maybe [(String, String)] -> X ()
+forkFile path args env =
+    xfork (executeFile path False args env) >> return ()
+
+spawnRootTerm :: X ()
+spawnRootTerm =
+    forkFile
+        urxvtcPath
+        ["-name", "root-urxvt", "-e", "/run/wrappers/bin/su", "-"]
+        Nothing
+
+spawnTermAt :: String -> X ()
+spawnTermAt ws = do
+    env <- liftIO getEnvironment
+    let env' = ("XMONAD_SPAWN_WORKSPACE", ws) : env
+    forkFile urxvtcPath [] (Just env')
+
+myKeys :: XConfig Layout -> Map (KeyMask, KeySym) (X ())
+myKeys conf = Map.fromList $
+    [ ((_4  , xK_Escape ), forkFile "/run/wrappers/bin/slock" [] Nothing)
+    , ((_4S , xK_c      ), kill)
+
+    , ((_4  , xK_p      ), forkFile "${pkgs.pass}/bin/passmenu" ["--type"] Nothing)
+
+    , ((_4  , xK_x      ), chooseAction spawnTermAt)
+    , ((_4C , xK_x      ), spawnRootTerm)
+
+    --, ((_4  , xK_F1     ), withFocused jojo)
+    --, ((_4  , xK_F1     ), printAllGeometries)
+
+    , ((0   , xK_Print   ), gets windowset >>= allWorkspaceNames >>= pager pagerConfig (windows . W.view) )
+    , ((_S  , xK_Print   ), gets windowset >>= allWorkspaceNames >>= pager pagerConfig (windows . W.shift) )
+    , ((_C  , xK_Print   ), toggleWS)
+    , ((_4  , xK_Print   ), rhombus horseConfig (liftIO . hPutStrLn stderr) ["Correct", "Horse", "Battery", "Staple", "Stuhl", "Tisch"] )
+    
+    -- %! Rotate through the available layout algorithms
+    , ((_4  , xK_space  ), sendMessage NextLayout)
+    , ((_4S , xK_space  ), setLayout $ XMonad.layoutHook conf) -- reset layout
+
+    ---- BinarySpacePartition
+    --, ((_4  , xK_l), sendMessage $ ExpandTowards R)
+    --, ((_4  , xK_h), sendMessage $ ExpandTowards L)
+    --, ((_4  , xK_j), sendMessage $ ExpandTowards D)
+    --, ((_4  , xK_k), sendMessage $ ExpandTowards U)
+    --, ((_4S , xK_l), sendMessage $ ShrinkFrom R)
+    --, ((_4S , xK_h), sendMessage $ ShrinkFrom L)
+    --, ((_4S , xK_j), sendMessage $ ShrinkFrom D)
+    --, ((_4S , xK_k), sendMessage $ ShrinkFrom U)
+    --, ((_4  , xK_n), sendMessage Rotate)
+    --, ((_4S , xK_n), sendMessage Swap)
+
+    ---- mouseResizableTile
+    --, ((_4    , xK_u), sendMessage ShrinkSlave)
+    --, ((_4    , xK_i), sendMessage ExpandSlave)
+
+    -- move focus up or down the window stack
+    --, ((_4  , xK_m      ), windows W.focusMaster)
+    , ((_4  , xK_j      ), windows W.focusDown)
+    , ((_4  , xK_k      ), windows W.focusUp)
+
+    -- modifying the window order
+    , ((_4S , xK_m      ), windows W.swapMaster)
+    , ((_4S , xK_j      ), windows W.swapDown)
+    , ((_4S , xK_k      ), windows W.swapUp)
+
+    -- resizing the master/slave ratio
+    , ((_4  , xK_h      ), sendMessage Shrink) -- %! Shrink the master area
+    , ((_4  , xK_l      ), sendMessage Expand) -- %! Expand the master area
+
+    -- floating layer support
+    , ((_4  , xK_t      ), withFocused $ windows . W.sink)  -- make tiling
+
+    -- increase or decrease number of windows in the master area
+    , ((_4  , xK_comma  ), sendMessage $ IncMasterN 1)
+    , ((_4  , xK_period ), sendMessage $ IncMasterN (-1))
+
+    , ((_4  , xK_a      ), addWorkspacePrompt def)
+    , ((_4  , xK_r      ), renameWorkspace def)
+    , ((_4  , xK_Delete ), removeEmptyWorkspace)
+
+    , ((_4  , xK_Return ), toggleWS)
+    --,  (0   , xK_Print   ) & \k -> (k, gridselectWorkspace wsGSConfig { gs_navigate = makeGSNav k } W.view)
+    --,  (_4  , xK_v      ) & \k -> (k, gridselectWorkspace wsGSConfig { gs_navigate = makeGSNav k } W.view)
+    --,  (_4S , xK_v      ) & \k -> (k, gridselectWorkspace wsGSConfig { gs_navigate = makeGSNav k } W.shift)
+    --,  (_4  , xK_b      ) & \k -> (k, goToSelected        wGSConfig  { gs_navigate = makeGSNav k })
+    , ((noModMask, xF86XK_AudioLowerVolume), amixer ["sset", "Master", "5%-"])
+    , ((noModMask, xF86XK_AudioRaiseVolume), amixer ["sset", "Master", "5%+"])
+    , ((noModMask, xF86XK_AudioMute), amixer ["sset", "Master", "toggle"])
+    ]
+    where
+    _4 = mod4Mask
+    _C = controlMask
+    _S = shiftMask
+    _M = mod1Mask
+    _4C = _4 .|. _C
+    _4S = _4 .|. _S
+    _4M = _4 .|. _M
+    _4CM = _4 .|. _C .|. _M
+    _4SM = _4 .|. _S .|. _M
+
+    amixer args = forkFile amixerPath args Nothing
+
+
+pagerConfig :: PagerConfig
+pagerConfig = def
+    { pc_font           = myFont
+    , pc_cellwidth      = 64
+    --, pc_cellheight     = 36 -- TODO automatically keep screen aspect
+    --, pc_borderwidth    = 1
+    --, pc_matchcolor     = "#f0b000"
+    , pc_matchmethod    = MatchPrefix
+    --, pc_colors         = pagerWorkspaceColors
+    , pc_windowColors   = windowColors
+    }
+    where
+    windowColors _ _ _ True _ = ("#ef4242","#ff2323")
+    windowColors wsf m c u wf = do
+        let y = defaultWindowColors wsf m c u wf
+        if m == False && wf == True
+            then ("#402020", snd y)
+            else y
+
+horseConfig :: RhombusConfig
+horseConfig = def
+    { rc_font           = myFont
+    , rc_cellwidth      = 64
+    --, rc_cellheight     = 36 -- TODO automatically keep screen aspect
+    --, rc_borderwidth    = 1
+    --, rc_matchcolor     = "#f0b000"
+    , rc_matchmethod    = MatchPrefix
+    --, rc_colors         = pagerWorkspaceColors
+    --, rc_paint          = myPaint
+    }
+
+wGSConfig :: GSConfig Window
+wGSConfig = def
+    { gs_cellheight = 20
+    , gs_cellwidth = 192
+    , gs_cellpadding = 5
+    , gs_font = myFont
+    , gs_navigate = navNSearch
+    }
+
+-- wsGSConfig = def
+--     { gs_cellheight = 20
+--     , gs_cellwidth = 64
+--     , gs_cellpadding = 5
+--     , gs_font = myFont
+--     , gs_navigate = navNSearch
+--     }
+
+-- custom navNSearch
+--makeGSNav :: (KeyMask, KeySym) -> TwoD a (Maybe a)
+--makeGSNav esc = nav
+--    where
+--    nav = makeXEventhandler $ shadowWithKeymap keyMap navNSearchDefaultHandler
+--    keyMap = Map.fromList
+--        [ (esc              , cancel)
+--        , ((0,xK_Escape)    , cancel)
+--        , ((0,xK_Return)    , select)
+--        , ((0,xK_Left)      , move (-1, 0) >> nav)
+--        , ((0,xK_Right)     , move ( 1, 0) >> nav)
+--        , ((0,xK_Down)      , move ( 0, 1) >> nav)
+--        , ((0,xK_Up)        , move ( 0,-1) >> nav)
+--        , ((0,xK_BackSpace) , transformSearchString (\s -> if (s == "") then "" else init s) >> nav)
+--        ]
+--    -- The navigation handler ignores unknown key symbols, therefore we const
+--    navNSearchDefaultHandler (_,s,_) = do
+--        transformSearchString (++ s)
+--        nav
+
+
+(&) :: a -> (a -> c) -> c
+(&) = flip ($)
+
+allWorkspaceNames :: W.StackSet i l a sid sd -> X [i]
+allWorkspaceNames ws =
+    return $ map W.tag (W.hidden ws) ++ [W.tag $ W.workspace $ W.current ws]
+  '';
+  };
+}
diff --git a/jeschli/default.nix b/jeschli/default.nix
index 7886fef49..b57932719 100644
--- a/jeschli/default.nix
+++ b/jeschli/default.nix
@@ -1,9 +1,9 @@
-_:
+{ pkgs, ... }:
 {
   imports = [
     ../krebs
     ./2configs
-#    ./3modules
-#    ./5pkgs
   ];
+
+  nixpkgs.config.packageOverrides = import ./5pkgs pkgs;
 }
diff --git a/jeschli/source.nix b/jeschli/source.nix
index fe1de8fd1..29cf9d818 100644
--- a/jeschli/source.nix
+++ b/jeschli/source.nix
@@ -13,10 +13,7 @@ in
   evalSource (toString _file) [
     {
       nixos-config.symlink = "stockholm/jeschli/1systems/${name}/config.nix";
-      nixpkgs.git = {
-        url = https://github.com/nixos/nixpkgs;
-        ref = "0653b73";
-      };
+      nixpkgs = (import <stockholm/krebs/source.nix> host).nixpkgs;
       secrets.file = getAttr builder {
         buildbot = toString <stockholm/jeschli/2configs/tests/dummy-secrets>;
         jeschli = "${getEnv "HOME"}/secrets/${name}";
diff --git a/krebs/1systems/hotdog/config.nix b/krebs/1systems/hotdog/config.nix
index 98fb88702..662e094d1 100644
--- a/krebs/1systems/hotdog/config.nix
+++ b/krebs/1systems/hotdog/config.nix
@@ -21,4 +21,5 @@
   boot.isContainer = true;
   networking.useDHCP = false;
   krebs.ci.stockholmSrc = "http://cgit.prism.r/stockholm";
+  environment.variables.NIX_REMOTE = "daemon";
 }
diff --git a/krebs/1systems/onebutton/config.nix b/krebs/1systems/onebutton/config.nix
new file mode 100644
index 000000000..c634d73ce
--- /dev/null
+++ b/krebs/1systems/onebutton/config.nix
@@ -0,0 +1,44 @@
+{ config, pkgs, lib, ... }:
+{
+  imports = [
+    <stockholm/krebs>
+    <stockholm/krebs/2configs>
+    { # minimal disk usage
+      environment.noXlibs = true;
+      nix.gc.automatic = true;
+      nix.gc.dates = "03:10";
+      programs.info.enable = false;
+      programs.man.enable = false;
+      services.journald.extraConfig = "SystemMaxUse=50M";
+      services.nixosManual.enable = false;
+    }
+  ];
+  krebs.build.host = config.krebs.hosts.onebutton;
+  # NixOS wants to enable GRUB by default
+  boot.loader.grub.enable = false;
+  # Enables the generation of /boot/extlinux/extlinux.conf
+  boot.loader.generic-extlinux-compatible.enable = true;
+
+  # !!! If your board is a Raspberry Pi 1, select this:
+  boot.kernelPackages = pkgs.linuxPackages_rpi;
+
+  nix.binaryCaches = [ "http://nixos-arm.dezgeg.me/channel" ];
+  nix.binaryCachePublicKeys = [ "nixos-arm.dezgeg.me-1:xBaUKS3n17BZPKeyxL4JfbTqECsT+ysbDJz29kLFRW0=%" ];
+
+  # !!! Needed for the virtual console to work on the RPi 3, as the default of 16M doesn't seem to be enough.
+  # boot.kernelParams = ["cma=32M"];
+
+  fileSystems = {
+    "/boot" = {
+      device = "/dev/disk/by-label/NIXOS_BOOT";
+      fsType = "vfat";
+    };
+    "/" = {
+      device = "/dev/disk/by-label/NIXOS_SD";
+      fsType = "ext4";
+    };
+  };
+
+  swapDevices = [ { device = "/swapfile"; size = 1024; } ];
+  services.openssh.enable = true;
+}
diff --git a/krebs/1systems/onebutton/source.nix b/krebs/1systems/onebutton/source.nix
new file mode 100644
index 000000000..8f25881c9
--- /dev/null
+++ b/krebs/1systems/onebutton/source.nix
@@ -0,0 +1,16 @@
+with import <stockholm/lib>;
+let
+  pkgs = import <nixpkgs> {};
+  nixpkgs = pkgs.fetchFromGitHub {
+    owner = "nixos";
+    repo = "nixpkgs-channels";
+    rev = "6c064e6b"; # only binary cache for unstable arm6
+    sha256 = "1rqzh475xn43phagrr30lb0fd292c1s8as53irihsnd5wcksnbyd";
+  };
+in import <stockholm/krebs/source.nix> {
+  name = "onebutton";
+  override.nixpkgs = mkForce {
+    file = toString nixpkgs;
+  };
+
+}
diff --git a/krebs/2configs/buildbot-all.nix b/krebs/2configs/buildbot-all.nix
index 5ea78f227..d85cde175 100644
--- a/krebs/2configs/buildbot-all.nix
+++ b/krebs/2configs/buildbot-all.nix
@@ -5,6 +5,5 @@ with import <stockholm/lib>;
   krebs.ci.enable = true;
   krebs.ci.treeStableTimer = 1;
   krebs.ci.hosts = filter (getAttr "ci") (attrValues config.krebs.hosts);
-  krebs.ci.tests = [ "deploy" ];
 }
 
diff --git a/krebs/2configs/news-spam.nix b/krebs/2configs/news-spam.nix
index 63848c234..69c503bf9 100644
--- a/krebs/2configs/news-spam.nix
+++ b/krebs/2configs/news-spam.nix
@@ -2,6 +2,7 @@
 
 {
   krebs.newsbot-js.news-spam = {
+    urlShortenerHost = "go.lassul.us";
     feeds = pkgs.writeText "feeds" ''
       [SPAM]aje|http://www.aljazeera.com/Services/Rss/?PostingId=2007731105943979989|#snews
       [SPAM]allafrica|http://allafrica.com/tools/headlines/rdf/latest/headlines.rdf|#snews
@@ -120,7 +121,7 @@
       [SPAM]sciencemag|http://news.sciencemag.org/rss/current.xml|#snews
       [SPAM]scmp|http://www.scmp.com/rss/91/feed|#snews
       [SPAM]sec-db|http://feeds.security-database.com/SecurityDatabaseToolsWatch|#snews
-      [SPAM]shackspace|http://blog.shackspace.de/?feed=rss2|#snews
+      [SPAM]shackspace|http://shackspace.de/atom.xml|#snews
       [SPAM]shz_news|http://www.shz.de/nachrichten/newsticker/rss|#snews
       [SPAM]sky_busi|http://feeds.skynews.com/feeds/rss/business.xml|#snews
       [SPAM]sky_pol|http://feeds.skynews.com/feeds/rss/politics.xml|#snews
diff --git a/krebs/2configs/news.nix b/krebs/2configs/news.nix
index 2628c7986..49a5e3459 100644
--- a/krebs/2configs/news.nix
+++ b/krebs/2configs/news.nix
@@ -11,7 +11,7 @@
       painload|https://github.com/krebscode/painload/commits/master.atom|#news
       reddit_haskell|http://www.reddit.com/r/haskell/.rss|#news
       reddit_nix|http://www.reddit.com/r/nixos/.rss|#news
-      shackspace|http://blog.shackspace.de/?feed=rss2|#news
+      shackspace|http://shackspace.de/atom.xml|#news
       tinc|http://tinc-vpn.org/news/index.rss|#news
       vimperator|https://sites.google.com/a/vimperator.org/www/blog/posts.xml|#news
       weechat|http://dev.weechat.org/feed/atom|#news
diff --git a/krebs/2configs/shack/worlddomination.nix b/krebs/2configs/shack/worlddomination.nix
index 828b6cd70..838c1958e 100644
--- a/krebs/2configs/shack/worlddomination.nix
+++ b/krebs/2configs/shack/worlddomination.nix
@@ -2,8 +2,56 @@
 
 with import <stockholm/lib>;
 let
+  pkg = pkgs.stdenv.mkDerivation {
+    name = "worlddomination-2018-04-21";
+    src = pkgs.fetchgit {
+      url = "https://github.com/shackspace/worlddomination/";
+      rev = "1b32403b9";
+      sha256 = "10x7aiil13k3x9wqy95mi1ys999d6fxg5sys3jwv7a1p930gkl1i";
+    };
+    buildInputs = [
+      (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
+        docopt
+        LinkHeader
+        aiocoap
+        grequests
+        paramiko
+        python
+      ]))
+    ];
+    installPhase = ''
+      install -m755 -D backend/push_led.py  $out/bin/push-led
+      install -m755 -D backend/loop_single.py  $out/bin/loop-single
+      # copy the provided file to the package
+      install -m755 -D backend/wd.lst  $out/${wdpath}
+    '';
+  };
   pythonPackages = pkgs.python3Packages;
   # https://github.com/chrysn/aiocoap
+  grequests = pythonPackages.buildPythonPackage rec {
+    pname = "grequests";
+    version = "0.3.1";
+    name = "${pname}-${version}";
+
+    src = pkgs.fetchFromGitHub {
+      owner = "kennethreitz";
+      repo = "grequests";
+      rev =  "d1e70eb";
+      sha256 = "0drfx4fx65k0g5sj0pw8z3q1s0sp7idn2yz8xfb45nd6v82i37hc";
+    };
+
+    doCheck = false;
+
+    propagatedBuildInputs = with pythonPackages; [ requests gevent ];
+
+    meta = with lib;{
+      description = "Asynchronous HTTP requests";
+      homepage = https://github.com/kennethreitz/grequests;
+      license = with licenses; [ bsd2 ];
+      maintainers = with maintainers; [ matejc ];
+    };
+  };
+
   aiocoap = pythonPackages.buildPythonPackage {
       name = "aiocoap-0.3";
       src = pkgs.fetchurl { url = "https://pypi.python.org/packages/9c/f6/d839e4b14258d76e74a39810829c13f8dd31de2bfe0915579b2a609d1bbe/aiocoap-0.3.tar.gz"; sha256 = "402d4151db6d8d0b1d66af5b6e10e0de1521decbf12140637e5b8d2aa9c5aef6"; };
@@ -25,30 +73,6 @@ let
       description = "Parse and format link headers according to RFC 5988 \"Web Linking\"";
     };
   };
-  pkg = pkgs.stdenv.mkDerivation {
-    name = "worlddomination-2017-06-10";
-    src = pkgs.fetchgit {
-      url = "https://github.com/shackspace/worlddomination/";
-      rev = "72fc9b5";
-      sha256 = "05h500rswzypcxy4i22qc1vkc8izbzfqa9m86xg289hjxh133xyf";
-    };
-    buildInputs = [
-      (pkgs.python3.withPackages (pythonPackages: with pythonPackages; [
-        docopt
-        LinkHeader
-        aiocoap
-        requests
-        paramiko
-        python
-      ]))
-    ];
-    installPhase = ''
-      install -m755 -D backend/push_led.py  $out/bin/push-led
-      install -m755 -D backend/loop_single.py  $out/bin/loop-single
-      # copy the provided file to the package
-      install -m755 -D backend/wd.lst  $out/${wdpath}
-    '';
-  };
   wdpath = "/usr/worlddomination/wd.lst";
   esphost = "10.42.24.7"; # esp8266
   timeout = 10; # minutes
diff --git a/krebs/3modules/krebs/default.nix b/krebs/3modules/krebs/default.nix
index 1e626f0a0..a916c1873 100644
--- a/krebs/3modules/krebs/default.nix
+++ b/krebs/3modules/krebs/default.nix
@@ -91,6 +91,37 @@ in {
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxFkBln23wUxt4RhIHE3GvdKeBpJbjn++6maupHqUHp";
     };
+    onebutton = {
+      cores = 1;
+      owner = config.krebs.users.krebs;
+      nets = {
+        retiolum = {
+          ip4.addr = "10.243.0.101";
+          ip6.addr = "42:0:0:0:0:0:0:101";
+          aliases = [
+            "onebutton.r"
+          ];
+          tinc.pubkey = ''
+            -----BEGIN PUBLIC KEY-----
+            MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA11w6votRExwE0ZEiQmPa
+            9WGNsMfNAZEd14iHaHCZH7UPQEH+cH/T6isGPpaysindroMnqFe9mUf/cdYChb6N
+            aaFreApwGBQaJPUcdy4cfphrFpzmOClpOFuFbnV7ZvAk/wefBad3kUzsq/lK4HvB
+            7nPKeOB9kljphLrkzuLL/h2yOenMpO2ZdvwxyWN8HKmUNgvpBQjIr+Hka6cgy7Gp
+            pBVFHfSnad/eHeEvq91O/bHxrAxzH5N5DVagPDpkbiWYGl+0XVGP/h0CApr15Ael
+            +j2pJYc0ZlaXIp4KmNRqbd/fLe52JLrWbnFX4rRuY/DhoMqK8kjECEZ7gLiNSpCC
+            KlnlJ2LXX9c+d79ubzl5yLAJ3d6T4IJqkbAWJDuCrj821M9ZDk/qZwerayhrrvkF
+            tMYkQoGSe8MvSOU0rTEoH5iSRwDC7M0XzUe4l8/yZLFyD4Prz/dq6coqANfk/tlE
+            DnH3vDu9lmFvYrLcd6yDWzFfI3mWDJoUa6AKKoScCOaCkRfIM4Aew0i73+h1nJLO
+            59AAbZIkDYyWs53QniIG4EQteI9y/9j/628nPAVj68V5oIN76RDXfFHWDWq4DxmU
+            PpGVmoIKcKZmnl7RrDomRVpuGMdyQ+kCzIGH3XYe12v8Y5beHZBrd3OajgHZ/Tfp
+            jP873cT6h0hsGm9glgOYho8CAwEAAQ==
+            -----END PUBLIC KEY-----
+          '';
+        };
+      };
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAcZg+iLaPZ0SpLM+nANxIjZC/RIsansjyutK0+gPhIe ";
+    };
     puyak = {
       ci = true;
       owner = config.krebs.users.krebs;
diff --git a/krebs/3modules/lass/default.nix b/krebs/3modules/lass/default.nix
index e269d1fa1..48df04bcb 100644
--- a/krebs/3modules/lass/default.nix
+++ b/krebs/3modules/lass/default.nix
@@ -9,6 +9,7 @@ with import <stockholm/lib>;
   hosts = mapAttrs (_: recursiveUpdate {
     owner = config.krebs.users.lass;
     ci = true;
+    monitoring = true;
   }) {
     dishfire = {
       cores = 4;
@@ -43,39 +44,6 @@ with import <stockholm/lib>;
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIGv0JMp0y+E5433GRSFKVK3cQmP0AAlS9aH9fk49yFxy";
     };
-    echelon = {
-      cores = 2;
-      nets = rec {
-        internet = {
-          ip4.addr = "64.137.242.41";
-          aliases = [
-            "echelon.i"
-          ];
-          ssh.port = 45621;
-        };
-        retiolum = {
-          via = internet;
-          ip4.addr = "10.243.206.103";
-          ip6.addr = "42:941e:2816:35f4:5c5e:206b:3f0b:f763";
-          aliases = [
-            "echelon.r"
-            "cgit.echelon.r"
-          ];
-          tinc.pubkey = ''
-            -----BEGIN RSA PUBLIC KEY-----
-            MIIBCgKCAQEAuscWOYdHu0bpWacvwTNd6bcmrAQ0YFxJWHZF8kPZr+bMKIhnXLkJ
-            oJheENIM6CA9lQQQFUxh2P2pxZavW5rgVlJxIKeiB+MB4v6ZO60LmZgpCsWGD/dX
-            MipM2tLtQxYhvLJIJxEBWn3rxIgeEnCtZsH1KLWyLczb+QpvTjMJ4TNh1nEBPE/f
-            4LUH1JHaGhcaHl2dLemR9wnnDIjmSj0ENJp2al+hWnIggcA/Zp0e4b86Oqbbs5wA
-            n++n5j971cTrBdA89nJDYOEtepisglScVRbgLqJG81lDA+n24RWFynn+U3oD/L8p
-            do+kxlwZUEDRbPU4AO5L+UeIbimsuIfXiQIDAQAB
-            -----END RSA PUBLIC KEY-----
-          '';
-        };
-      };
-      ssh.privkey.path = <secrets/ssh.id_ed25519>;
-      ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL21QDOEFdODFh6WAfNp6odrXo15pEsDQuGJfMu/cKzK";
-    };
     prism = rec {
       cores = 4;
       extraZones = {
@@ -86,14 +54,17 @@ with import <stockholm/lib>;
         "lassul.us" = ''
           $TTL 3600
           @ IN SOA dns16.ovh.net. tech.ovh.net. (2017093001 86400 3600 3600000 300)
-                          60 IN NS     ns16.ovh.net.
-                          60 IN NS     dns16.ovh.net.
-                          60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
-                          60 IN TXT    v=spf1 mx -all
-          cgit            60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
-          io              60 IN NS     ions.lassul.us.
-          ions            60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
-          paste           60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
+                              60 IN NS     ns16.ovh.net.
+                              60 IN NS     dns16.ovh.net.
+                              60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
+                              60 IN TXT    v=spf1 mx a:lassul.us -all
+                              60 IN TXT    ( "v=DKIM1; k=rsa; t=s; s=*; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUv3DMndFellqu208feABEzT/PskOfTSdJCOF/HELBR0PHnbBeRoeHEm9XAcOe/Mz2t/ysgZ6JFXeFxCtoM5fG20brUMRzsVRxb9Ur5cEvOYuuRrbChYcKa+fopu8pYrlrqXD3miHISoy6ErukIYCRpXWUJHi1TlNQhLWFYqAaywIDAQAB" )
+          default._domainkey  60 IN TXT    "k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDUv3DMndFellqu208feABEzT/PskOfTSdJCOF/HELBR0PHnbBeRoeHEm9XAcOe/Mz2t/ysgZ6JFXeFxCtoM5fG20brUMRzsVRxb9Ur5cEvOYuuRrbChYcKa+fopu8pYrlrqXD3miHISoy6ErukIYCRpXWUJHi1TlNQhLWFYqAaywIDAQAB"
+          cgit                60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
+          go                  60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
+          io                  60 IN NS     ions.lassul.us.
+          ions                60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
+          paste               60 IN A      ${config.krebs.hosts.prism.nets.internet.ip4.addr}
         '';
       };
       nets = rec {
@@ -149,6 +120,7 @@ with import <stockholm/lib>;
     };
     domsen-nas = {
       ci = false;
+      monitoring = false;
       external = true;
       nets = rec {
         internet = {
@@ -161,6 +133,7 @@ with import <stockholm/lib>;
       };
     };
     uriel = {
+      monitoring = false;
       cores = 1;
       nets = {
         gg23 = {
@@ -399,10 +372,12 @@ with import <stockholm/lib>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJzb9BPFClubs6wSOi/ivqPFVPlowXwAxBS0jHaB29hX";
     };
     iso = {
+      monitoring = false;
       ci = false;
       cores = 1;
     };
     sokrateslaptop = {
+      monitoring = false;
       ci = false;
       external = true;
       nets = {
@@ -426,6 +401,7 @@ with import <stockholm/lib>;
       };
     };
     turingmachine = {
+      monitoring = false;
       ci = false;
       external = true;
       nets = {
@@ -454,6 +430,7 @@ with import <stockholm/lib>;
       };
     };
     eddie = {
+      monitoring = false;
       ci = false;
       external = true;
       nets = rec {
@@ -494,6 +471,7 @@ with import <stockholm/lib>;
       };
     };
     borg = {
+      monitoring = false;
       ci = false;
       external = true;
       nets = {
@@ -521,6 +499,7 @@ with import <stockholm/lib>;
       };
     };
     inspector = {
+      monitoring = false;
       ci = false;
       external = true;
       nets = rec {
@@ -552,6 +531,7 @@ with import <stockholm/lib>;
       };
     };
     dpdkm = {
+      monitoring = false;
       ci = false;
       external = true;
       nets = rec {
@@ -618,6 +598,78 @@ with import <stockholm/lib>;
       ssh.privkey.path = <secrets/ssh.id_ed25519>;
       ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIE5HyLyaIvVH0qHIQ4ciKhDiElhSqsK+uXcA6lTvL+5n";
     };
+    cabal = {
+      cores = 2;
+      nets = rec {
+        retiolum = {
+          ip4.addr = "10.243.1.4";
+          ip6.addr = "42::1:4";
+          aliases = [
+            "cabal.r"
+          ];
+          tinc.pubkey = ''
+            -----BEGIN RSA PUBLIC KEY-----
+            MIIECgKCBAEAukXm8xPpC6/F+wssYqQbqt1QDwsPrF3TJ9ToLFcN1WgDlhDhjM3A
+            SuRDMNjRT1fvVTuXyplH5g16eokW/yLOpNnznMS3/VR372pLPEOqfuRf7wAy18jj
+            rZkW3EO7nyZ8KMb+SXA8Q0KIpHY50Ezh+tqGoTZDICwoK6N5dKLgAZShS55JXwwK
+            qRG3vyzV3mDjgVyT0FNfyL1/BN1qvJ+tQQ40lEbkcQauMunMzNbH058kAd6H2/0e
+            LK4JkxI9XpZHE6Pf1epXyClHW7vT7APFRp9gL9tZS/XMC18+aEMFfQrNW9jb3FIq
+            rU5MfJ7aubboe7dT6CRaRSWpduiKLVzY/JCoGvUziyvmR7qHsQWTEjtNuQX9joc3
+            6iq1o+gmLV0G8Xwq8cEcg5USlLxNsGBQPwYnTG6iTPPHqOv7BKucekE/opnVZseE
+            fSNCGl1+tGwa3soSMI97LkpQTZxdeqf+jWZve0RbSa2Ihyod91ldFCqi1+PZx68v
+            yBI0PJamlt+dBx6WQKbPngWYeD8hXo7tg0XVRVa3ZQyX+Mq6uCCb2GM8ewMUPl+A
+            kcY1osFt6+sdkFGdiv3FMyijAiZumPoPprXC/4SGIsMnkoI4JfSAbTpHi2QuesqR
+            KMeairdB7XGUYlMvWpDLKN2dbMdRc+l3kDUKT7hALjKeyWS/27WYeK/STxvZXEXi
+            TZGHopvOFv6wcrb6nI49vIJo5mDLFamAPN3ZjeR20wP95UP7cUUSaTYX49M4lX6U
+            oL5BaFrcLn2PTvS84pUxcXKAp70FgTpvGJbaWwETgDjW+H+qlGmI/BTejpL7flVs
+            TOtaP/uCMxhVZSFv9bzo0ih10o+4gtU8lqxfJsVxlf2K7LVZ++LQba/u+XxRY+xw
+            3IFBfg34tnO6zYlV8XgAiJ6IUOHUZANsuBD4iMoFSVOig6t5eIOkgXR6GEkP8FBD
+            rkroRMmxcu4lTCOzWIuAVOxCd4XXguoGQ4HAzpGd5ccdcb8Ev4RYEvNJY7B5tIQZ
+            4J0F9ECzJuSu1HvWTL+T6a36d2MDTkXU2IJ2tSHciXqiP+QMMF7p9Ux0tiAq4mtf
+            luA94uKWg3cSyTyEM/jF66CgO6Ts3AivNE0MRNupV6AbUdr+TjzotGn9rxi168py
+            w/49OVbpR9EIGC2wxx7qcSEk5chFOcgvNQMRqgIx51bbOL7JYb0f4XuA38GUqLkG
+            09PXmPeyqGzR9HsV2XZDprZdD3Dy4ojdexw0+YILg9bHaAxLHYs6WFZvzfaLLsf1
+            K2I39vvrEEOy8tHi4jvMk7oVX6RWG+DOZMeXTvyUCaBHyYkA0eDlC6NeKOHxnW/g
+            ZtN1W93UdklEqc5okM0/ZIke1HDRt3ZLdQIDAQAB
+            -----END RSA PUBLIC KEY-----
+          '';
+        };
+      };
+      secure = true;
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPsTeSAedrbp7/KmZX8Mvka702fIUy77Mvqo9HwzCbym";
+    };
+    red = {
+      monitoring = false;
+      cores = 1;
+      nets = {
+        retiolum = {
+          ip4.addr = "10.243.0.13";
+          ip6.addr = "42:0:0:0:0:0:0:12ed";
+          aliases = [
+            "red.r"
+          ];
+          tinc.pubkey = ''
+            -----BEGIN PUBLIC KEY-----
+            MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArAN/62V2MV18wsZ9VMTG
+            4/cqsjvHlffAN8jYDq+GImgREvbiLlFhhHgxwKh0gcDTR8P1xX/00P3/fx/g5bRF
+            Te7LZT2AFmVFFFfx1n9NBweN/gG2/hzB9J8epbWLNT+RzpzHuAoREvDZ+jweSXaI
+            phdmQY2s36yrR3TAShqq0q4cwlXuHT00J+InDutM0mTftBQG/fvYkBhHOfq4WSY0
+            FeMK7DTKNbsqQiKKQ/kvWi7KfTW0F0c7SDpi7BLwbQzP2WbogtGy9MIrw9ZhE6Ox
+            TVdAksPKw0TlYdb16X/MkbzBqTYbxFlmWzpMJABMxIVwAfQx3ZGYvJDdDXmQS2qa
+            mDN2xBb/5pj3fbfp4wbwWlRVSd/AJQtRvaNY24F+UsRJb0WinIguDI6oRZx7Xt8w
+            oYirKqqq1leb3EYUt8TMIXQsOw0/Iq+JJCwB+ZyLLGVNB19XOxdR3RN1JYeZANpE
+            cMSS3SdFGgZ//ZAdhIN5kw9yMeKo6Rnt+Vdz3vZWTuSVp/xYO3IMGXNGAdIWIwrJ
+            7fwSl/rfXGG816h0sD46U0mxd+i68YOtHlzOKe+vMZ4/FJZYd/E5/IDQluV8HLwa
+            5lODfZXUmfStdV+GDA9KVEGUP5xSkC3rMnir66NgHzKpIL002/g/HfGu7O3MrvpW
+            ng7AMvRv5vbsYcJBj2HUhKUCAwEAAQ==
+            -----END PUBLIC KEY-----
+          '';
+        };
+      };
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKd/6eCR8yxC14zBJLIQgVa4Zbutv5yr2S8k08ztmBpp";
+    };
   };
   users = {
     lass = {
diff --git a/krebs/3modules/makefu/default.nix b/krebs/3modules/makefu/default.nix
index e137da7ca..d7a750c6e 100644
--- a/krebs/3modules/makefu/default.nix
+++ b/krebs/3modules/makefu/default.nix
@@ -539,6 +539,7 @@ with import <stockholm/lib>;
           dl.euer           IN A      ${nets.internet.ip4.addr}
           boot.euer         IN A      ${nets.internet.ip4.addr}
           wiki.euer         IN A      ${nets.internet.ip4.addr}
+          mon.euer          IN A      ${nets.internet.ip4.addr}
           graph             IN A      ${nets.internet.ip4.addr}
           ghook             IN A      ${nets.internet.ip4.addr}
           dockerhub         IN A      ${nets.internet.ip4.addr}
diff --git a/krebs/3modules/newsbot-js.nix b/krebs/3modules/newsbot-js.nix
index d372081ee..00e346f8e 100644
--- a/krebs/3modules/newsbot-js.nix
+++ b/krebs/3modules/newsbot-js.nix
@@ -93,6 +93,7 @@ let
           User = "newsbot-js";
           Restart = "always";
           ExecStart = "${newsbot.package}/bin/newsbot";
+          WatchdogSec = "86400";
         };
       }
     ) cfg;
diff --git a/krebs/3modules/os-release.nix b/krebs/3modules/os-release.nix
index 8f71a357f..5fbfe6614 100644
--- a/krebs/3modules/os-release.nix
+++ b/krebs/3modules/os-release.nix
@@ -1,8 +1,11 @@
 { config, ... }:
 with import <stockholm/lib>;
 let
-  nixos-version-id = "${config.system.nixosVersion}";
-  nixos-version = "${nixos-version-id} (${config.system.nixosCodeName})";
+  nixos-version-id = if (hasAttr "nixos" config.system) then
+    "${config.system.nixos.version}" else "${config.system.nixosVersion}";
+  nixos-codeName = if (hasAttr "nixos" config.system) then
+    "${config.system.nixos.codeName}" else "${config.system.nixosCodeName}";
+  nixos-version = "${nixos-version-id} (${nixos-codeName})";
   nixos-pretty-name = "NixOS ${nixos-version}";
 
   stockholm-version-id = let
diff --git a/krebs/5pkgs/haskell/nix-diff/default.nix b/krebs/5pkgs/haskell/nix-diff/default.nix
deleted file mode 100644
index df0315048..000000000
--- a/krebs/5pkgs/haskell/nix-diff/default.nix
+++ /dev/null
@@ -1,25 +0,0 @@
-{ mkDerivation, attoparsec, base, containers, Diff, fetchgit, mtl
-, nix-derivation, optparse-generic, stdenv, system-filepath, text
-, unix, vector
-}:
-mkDerivation {
-  pname = "nix-diff";
-  version = "1.0.0-krebs1";
-  src = fetchgit {
-    url = "https://github.com/Gabriel439/nix-diff";
-    sha256 = "1k00nx8pannqmpzadkwfrs6bf79yk22ynhd033z5rsyw0m8fcz9k";
-    rev = "e32ffa2c7f38b47a71325a042c1d887fb46cdf7d";
-  };
-  patches = [
-    ./nixos-system.patch
-  ];
-  isLibrary = false;
-  isExecutable = true;
-  executableHaskellDepends = [
-    attoparsec base containers Diff mtl nix-derivation optparse-generic
-    system-filepath text unix vector
-  ];
-  homepage = "https://github.com/Gabriel439/nix-diff";
-  description = "Explain why two Nix derivations differ";
-  license = stdenv.lib.licenses.bsd3;
-}
diff --git a/krebs/5pkgs/haskell/nix-diff/nixos-system.patch b/krebs/5pkgs/haskell/nix-diff/nixos-system.patch
deleted file mode 100644
index 03e186aa9..000000000
--- a/krebs/5pkgs/haskell/nix-diff/nixos-system.patch
+++ /dev/null
@@ -1,18 +0,0 @@
-diff --git a/src/Main.hs b/src/Main.hs
-index 959ab8e..d3b6077 100644
---- a/src/Main.hs
-+++ b/src/Main.hs
-@@ -95,7 +95,12 @@ pathToText path =
-     underneath `/nix/store`, but this is the overwhelmingly common use case
- -}
- derivationName :: FilePath -> Text
--derivationName = Data.Text.dropEnd 4 . Data.Text.drop 44 . pathToText
-+derivationName p =
-+    if Data.Text.isPrefixOf "nixos-system" s
-+      then "nixos-system"
-+      else s
-+  where
-+    s = Data.Text.dropEnd 4 . Data.Text.drop 44 . pathToText $ p
- 
- -- | Group input derivations by their name
- groupByName :: Map FilePath (Set Text) -> Map Text (Map FilePath (Set Text))
diff --git a/krebs/5pkgs/simple/Reaktor/plugins.nix b/krebs/5pkgs/simple/Reaktor/plugins.nix
index bcfcbf76b..f3b771190 100644
--- a/krebs/5pkgs/simple/Reaktor/plugins.nix
+++ b/krebs/5pkgs/simple/Reaktor/plugins.nix
@@ -120,11 +120,24 @@ rec {
   url-title = (buildSimpleReaktorPlugin "url-title" {
     pattern = "^.*(?P<args>http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+).*$$";
     path = with pkgs; [ curl perl ];
-    script = pkgs.writeDash "lambda-pl" ''
-      if [ "$#" -gt 0 ]; then
-        curl -SsL --max-time 5 "$1" |
-          perl -l -0777 -ne 'print $1 if /<title.*?>\s*(.*?)\s*<\/title/si'
-      fi
+    script = pkgs.writePython3 [ "beautifulsoup4" "lxml" ] "url-title" ''
+      import sys
+      import urllib.request
+      from bs4 import BeautifulSoup
+
+      try:
+          soup = BeautifulSoup(urllib.request.urlopen(sys.argv[1]), "lxml")
+          title = soup.find('title').string
+
+          if title:
+              if len(title) > 512:
+                  print('message to long, skipped')
+              elif len(title.split('\n')) > 5:
+                  print('to many lines, skipped')
+              else:
+                  print(title)
+      except:  # noqa: E722
+          pass
     '';
   });
 
diff --git a/krebs/5pkgs/simple/Reaktor/scripts/sed-plugin.py b/krebs/5pkgs/simple/Reaktor/scripts/sed-plugin.py
index da8e2f726..51ac7a071 100644
--- a/krebs/5pkgs/simple/Reaktor/scripts/sed-plugin.py
+++ b/krebs/5pkgs/simple/Reaktor/scripts/sed-plugin.py
@@ -18,20 +18,27 @@ def is_regex(line):
     myre = re.compile(r'^s/(?:\\/|[^/])+/(?:\\/|[^/])*/[ig]?$')
     return myre.match(line)
 
+
 line = argv[1]
 
 if is_regex(line):
     last = d.get(usr, None)
     if last:
         from subprocess import Popen, PIPE
-        p = Popen(['sed', line], stdin=PIPE, stdout=PIPE)
+        p = Popen(['sed', line], stdin=PIPE, stdout=PIPE, stderr=PIPE)
         so, se = p.communicate(bytes("{}\n".format(last), "UTF-8"))
         if p.returncode:
-            print("something went wrong when trying to process your regex: {}".format(se.decode()))
+            print("something went wrong when trying to process your regex: {}".format(line.strip()))
         ret = so.decode()
-        print("\x1b[1m{}\x1b[0m meant: {}".format(usr, ret.strip()))
-        if ret:
-            d[usr] = ret
+        if len(ret) > 512:
+            print('message to long, skipped')
+        elif len(ret.split('\n')) > 5:
+            print('to many lines, skipped')
+        else:
+            if last.strip() != ret.strip():
+                print("\x1b[1m{}\x1b[0m meant: {}".format(usr, ret.strip()))
+                if ret:
+                    d[usr] = ret
 
     else:
         print("no last message")
diff --git a/krebs/5pkgs/simple/buildbot-classic/default.nix b/krebs/5pkgs/simple/buildbot-classic/default.nix
index 9eeccee64..3cb691f53 100644
--- a/krebs/5pkgs/simple/buildbot-classic/default.nix
+++ b/krebs/5pkgs/simple/buildbot-classic/default.nix
@@ -2,16 +2,15 @@
 
 python2Packages.buildPythonApplication rec {
   name = "buildbot-classic-${version}";
-  version = "0.8.14";
+  version = "0.8.16";
   namePrefix = "";
   patches = [];
 
   src = fetchFromGitHub {
     owner = "krebscode";
     repo = "buildbot-classic";
-    # rev = "v${version}";
-    rev = "843463911";
-    sha256 = "1ybl52ybjw5p09yik6bck9i1pvnvg94i0d32zqrwy67s77yx1mfd";
+    rev = version;
+    sha256 = "0g686n6m0cjfyympl0ksansllx503gby3hx9gmc8hiyx6x5fkjha";
   };
   postUnpack = "sourceRoot=\${sourceRoot}/master";
 
diff --git a/krebs/5pkgs/simple/ejabberd/default.nix b/krebs/5pkgs/simple/ejabberd/default.nix
new file mode 100644
index 000000000..9e4ed3df5
--- /dev/null
+++ b/krebs/5pkgs/simple/ejabberd/default.nix
@@ -0,0 +1,123 @@
+{ stdenv, writeScriptBin, lib, fetchurl, git, cacert
+, erlang, openssl, expat, libyaml, bash, gnused, gnugrep, coreutils, utillinux, procps, gd
+, flock
+, withMysql ? false
+, withPgsql ? false
+, withSqlite ? false, sqlite
+, withPam ? false, pam
+, withZlib ? true, zlib
+, withRiak ? false
+, withElixir ? false, elixir
+, withIconv ? true
+, withTools ? false
+, withRedis ? false
+}:
+
+let
+  fakegit = writeScriptBin "git" ''
+    #! ${stdenv.shell} -e
+    if [ "$1" = "describe" ]; then
+      [ -r .rev ] && cat .rev || true
+    fi
+  '';
+
+  ctlpath = lib.makeBinPath [ bash gnused gnugrep coreutils utillinux procps ];
+
+in stdenv.mkDerivation rec {
+  version = "18.01";
+  name = "ejabberd-${version}";
+
+  src = fetchurl {
+    url = "http://www.process-one.net/downloads/ejabberd/${version}/${name}.tgz";
+    sha256 = "01i2n8mlgw293jdf4172f9q8ca8m35vysjws791p7nynpfdb4cn6";
+  };
+
+  nativeBuildInputs = [ fakegit ];
+
+  buildInputs = [ erlang openssl expat libyaml gd ]
+    ++ lib.optional withSqlite sqlite
+    ++ lib.optional withPam pam
+    ++ lib.optional withZlib zlib
+    ++ lib.optional withElixir elixir
+    ;
+
+  # Apparently needed for Elixir
+  LANG = "en_US.UTF-8";
+
+  deps = stdenv.mkDerivation {
+    name = "ejabberd-deps-${version}";
+
+    inherit src;
+
+    configureFlags = [ "--enable-all" "--with-sqlite3=${sqlite.dev}" ];
+
+    nativeBuildInputs = [ git erlang openssl expat libyaml sqlite pam zlib elixir ];
+
+    GIT_SSL_CAINFO = "${cacert}/etc/ssl/certs/ca-bundle.crt";
+
+    makeFlags = [ "deps" ];
+
+    phases = [ "unpackPhase" "configurePhase" "buildPhase" "installPhase" ];
+
+    installPhase = ''
+      for i in deps/*; do
+        ( cd $i
+          git reset --hard
+          git clean -ffdx
+          git describe --always --tags > .rev
+          rm -rf .git
+        )
+      done
+      rm deps/.got
+
+      cp -r deps $out
+    '';
+
+    outputHashMode = "recursive";
+    outputHashAlgo = "sha256";
+    outputHash = "1v3h0c7kfifb6wsfxyv5j1wc7rlxbb7r0pgd4s340wiyxnllzzhk";
+  };
+
+  configureFlags =
+    [ (lib.enableFeature withMysql "mysql")
+      (lib.enableFeature withPgsql "pgsql")
+      (lib.enableFeature withSqlite "sqlite")
+      (lib.enableFeature withPam "pam")
+      (lib.enableFeature withZlib "zlib")
+      (lib.enableFeature withRiak "riak")
+      (lib.enableFeature withElixir "elixir")
+      (lib.enableFeature withIconv "iconv")
+      (lib.enableFeature withTools "tools")
+      (lib.enableFeature withRedis "redis")
+    ] ++ lib.optional withSqlite "--with-sqlite3=${sqlite.dev}";
+
+  enableParallelBuilding = true;
+
+  patches = [
+    ./ejabberdctl.patch
+  ];
+
+  preBuild = ''
+    cp -r $deps deps
+    chmod -R +w deps
+    patchShebangs deps
+  '';
+
+  postInstall = ''
+    sed -i \
+      -e '2iexport PATH=${ctlpath}:$PATH' \
+      -e 's,\(^ *FLOCK=\).*,\1${flock}/bin/flock,' \
+      -e 's,\(^ *JOT=\).*,\1,' \
+      -e 's,\(^ *CONNLOCKDIR=\).*,\1/var/lock/ejabberdctl,' \
+      $out/sbin/ejabberdctl
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Open-source XMPP application server written in Erlang";
+    license = licenses.gpl2;
+    homepage = http://www.ejabberd.im;
+    platforms = platforms.linux;
+    maintainers = with maintainers; [ sander abbradar ];
+    broken = withElixir;
+  };
+}
diff --git a/krebs/5pkgs/simple/ejabberd/ejabberdctl.patch b/krebs/5pkgs/simple/ejabberd/ejabberdctl.patch
new file mode 100644
index 000000000..f7c842b7b
--- /dev/null
+++ b/krebs/5pkgs/simple/ejabberd/ejabberdctl.patch
@@ -0,0 +1,32 @@
+--- a/ejabberdctl.template  1970-01-01 01:00:01.000000000 +0100
++++ b/ejabberdctl.template  2018-04-24 23:06:54.127715441 +0200
+@@ -42,19 +42,18 @@
+ esac
+ 
+ # parse command line parameters
+-for arg; do
+-    case $arg in
+-        -n|--node) ERLANG_NODE_ARG=$2; shift;;
+-        -s|--spool) SPOOL_DIR=$2; shift;;
+-        -l|--logs) LOGS_DIR=$2; shift;;
+-        -f|--config) EJABBERD_CONFIG_PATH=$2; shift;;
+-        -c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift;;
+-        -d|--config-dir) ETC_DIR=$2; shift;;
+-        -t|--no-timeout) NO_TIMEOUT="--no-timeout";;
+-        --) :;;
++while test $# -gt 0; do
++    case $1 in
++        -n|--node) ERLANG_NODE_ARG=$2; shift 2;;
++        -s|--spool) SPOOL_DIR=$2; shift 2;;
++        -l|--logs) LOGS_DIR=$2; shift 2;;
++        -f|--config) EJABBERD_CONFIG_PATH=$2; shift 2;;
++        -c|--ctl-config) EJABBERDCTL_CONFIG_PATH=$2; shift 2;;
++        -d|--config-dir) ETC_DIR=$2; shift 2;;
++        -t|--no-timeout) NO_TIMEOUT="--no-timeout"; shift 1;;
++        # --) :;; what is this for?
+         *) break;;
+     esac
+-    shift
+ done
+ 
+ # define ejabberd variables if not already defined from the command line
diff --git a/krebs/5pkgs/simple/electron-cash/default.nix b/krebs/5pkgs/simple/electron-cash/default.nix
deleted file mode 100644
index e51136c60..000000000
--- a/krebs/5pkgs/simple/electron-cash/default.nix
+++ /dev/null
@@ -1,64 +0,0 @@
-{ stdenv, fetchFromGitHub, python2Packages }:
-
-python2Packages.buildPythonApplication rec {
-  name = "electron-cash-${src.rev}";
-
-  src = fetchFromGitHub {
-    owner = "fyookball";
-    repo = "electrum";
-    rev = "a2245ea";
-    sha256 = "1a0ym94azfd1yn97n2jcky344ajbj2amr9l6jpx30pqxndffpbgv";
-  };
-
-  propagatedBuildInputs = with python2Packages; [
-    dns
-    ecdsa
-    jsonrpclib
-    pbkdf2
-    pyaes
-    pycrypto
-    pyqt4
-    pysocks
-    qrcode
-    requests
-    tlslite
-
-    # plugins
-    keepkey
-    trezor
-  ];
-
-  preBuild = ''
-    sed -i 's,usr_share = .*,usr_share = "'$out'/share",g' setup.py
-    pyrcc4 icons.qrc -o gui/qt/icons_rc.py
-    # Recording the creation timestamps introduces indeterminism to the build
-    sed -i '/Created: .*/d' gui/qt/icons_rc.py
-  '';
-
-  postInstall = ''
-    # Despite setting usr_share above, these files are installed under
-    # $out/nix ...
-    mv $out/lib/python2.7/site-packages/nix/store"/"*/share $out
-    rm -rf $out/lib/python2.7/site-packages/nix
-
-    substituteInPlace $out/share/applications/electron.desktop \
-      --replace "Exec=electrum %u" "Exec=$out/bin/electrum %u"
-  '';
-
-  doInstallCheck = true;
-  installCheckPhase = ''
-    $out/bin/electrum help >/dev/null
-  '';
-
-  meta = with stdenv.lib; {
-    description = "A lightweight Bitcoin wallet";
-    longDescription = ''
-      An easy-to-use Bitcoin client featuring wallets generated from
-      mnemonic seeds (in addition to other, more advanced, wallet options)
-      and the ability to perform transactions without downloading a copy
-      of the blockchain.
-    '';
-    homepage = https://electrum.org/;
-    license = licenses.mit;
-  };
-}
diff --git a/krebs/5pkgs/simple/font-size.nix b/krebs/5pkgs/simple/font-size.nix
new file mode 100644
index 000000000..21097ed6a
--- /dev/null
+++ b/krebs/5pkgs/simple/font-size.nix
@@ -0,0 +1,26 @@
+{ writeDashBin }:
+writeDashBin "font-size" ''
+  set -efu
+
+  # set_font NORMAL_FONT BOLD_FONT
+  set_font() {
+    printf '\033]710;%s\007' "$1"
+    printf '\033]711;%s\007' "$2"
+  }
+
+  case ''${1-} in
+    '''|0|--reset)
+      set_font \
+          -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1 \
+          -*-clean-*-*-*-*-*-*-*-*-*-*-iso10646-1 \
+      ;;
+    [1-9]|[1-9][0-9]|[1-9][0-9][0-9])
+      set_font \
+          xft:Monospace:size=$1 \
+          xft:Monospace:size=$1:bold \
+      ;;
+    *)
+      echo "$0: bad argument: $1" >&2
+      exit 1
+  esac
+''
diff --git a/krebs/5pkgs/simple/generate-secrets/default.nix b/krebs/5pkgs/simple/generate-secrets/default.nix
new file mode 100644
index 000000000..a800ff543
--- /dev/null
+++ b/krebs/5pkgs/simple/generate-secrets/default.nix
@@ -0,0 +1,46 @@
+{ pkgs }:
+pkgs.writeDashBin "generate-secrets" ''
+  HOSTNAME="$1"
+  TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d)
+  PASSWORD=$(${pkgs.pwgen}/bin/pwgen 25 1)
+  HASHED_PASSWORD=$(echo $PASSWORD | ${pkgs.hashPassword}/bin/hashPassword -s) > /dev/null
+
+  ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f $TMPDIR/ssh.id_ed25519 -P "" -C "" >/dev/null
+  ${pkgs.openssl}/bin/openssl genrsa -out $TMPDIR/retiolum.rsa_key.priv 4096 2>/dev/null > /dev/null
+  ${pkgs.openssl}/bin/openssl rsa -in $TMPDIR/retiolum.rsa_key.priv -pubout -out $TMPDIR/retiolum.rsa_key.pub 2>/dev/null > /dev/null
+  cat <<EOF > $TMPDIR/hashedPasswords.nix
+  {
+    root = "$HASHED_PASSWORD";
+  }
+  EOF
+
+  cd $TMPDIR
+  for x in *; do
+    ${pkgs.coreutils}/bin/cat $x | ${pkgs.brain}/bin/brain insert -m krebs-secrets/$HOSTNAME/$x > /dev/null
+  done
+  echo $PASSWORD | ${pkgs.brain}/bin/brain insert -m hosts/$HOSTNAME/root > /dev/null
+
+  cat <<EOF
+    $HOSTNAME = {
+      cores = 1;
+      owner = config.krebs.users.krebs;
+      nets = {
+        retiolum = {
+          ip4.addr = "10.243.0.changeme";
+          ip6.addr = "42:0:0:0:0:0:0:changeme";
+          aliases = [
+            "$HOSTNAME.r"
+          ];
+          tinc.pubkey = ${"''"}
+  $(cat $TMPDIR/retiolum.rsa_key.pub)
+          ${"''"};
+        };
+      };
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "$(cat $TMPDIR/ssh.id_ed25519.pub)";
+    };
+  EOF
+
+  rm -rf $TMPDIR
+''
+
diff --git a/krebs/5pkgs/simple/go-shortener/default.nix b/krebs/5pkgs/simple/go-shortener/default.nix
index 996f7072a..4d1bef2be 100644
--- a/krebs/5pkgs/simple/go-shortener/default.nix
+++ b/krebs/5pkgs/simple/go-shortener/default.nix
@@ -1,25 +1,26 @@
-{ stdenv, makeWrapper, callPackage, lib, buildEnv, fetchgit, nodePackages, nodejs }:
+{ stdenv, makeWrapper, lib, buildEnv, fetchgit, nodejs-8_x, pkgs }:
 
 with lib;
 
 let
-  np = (callPackage <nixpkgs/pkgs/top-level/node-packages.nix>) {
-    generated = ./packages.nix;
-    self = np;
+  nodeEnv = import <nixpkgs/pkgs/development/node-packages/node-env.nix> {
+    inherit (pkgs) stdenv python2 utillinux runCommand writeTextFile;
+    nodejs = nodejs-8_x;
+    libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
   };
 
-  node_env = buildEnv {
-    name = "node_env";
-    paths = [
-      np.redis
-      np."formidable"
-    ];
-    pathsToLink = [ "/lib" ];
-    ignoreCollisions = true;
+  node_env = pkgs.buildEnv {
+    name = "go-node_env";
+    paths = attrValues (import ./node-packages.nix {
+      inherit (pkgs) fetchurl fetchgit;
+      inherit nodeEnv;
+    });
   };
 
-in np.buildNodePackage {
+in stdenv.mkDerivation {
+  packageName = "go";
   name = "go-shortener";
+  version = "0.0.0";
 
   src = fetchgit {
     url = "http://cgit.lassul.us/go/";
@@ -32,10 +33,8 @@ in np.buildNodePackage {
     "installPhase"
   ];
 
-  deps = (filter (v: nixType v == "derivation") (attrValues np));
-
   buildInputs = [
-    nodejs
+    nodejs-8_x
     makeWrapper
   ];
 
@@ -44,14 +43,14 @@ in np.buildNodePackage {
 
     cp index.js $out/
     cat > $out/go << EOF
-      ${nodejs}/bin/node $out/index.js
+      ${nodejs-8_x}/bin/node $out/index.js
     EOF
     chmod +x $out/go
 
     wrapProgram $out/go \
       --prefix NODE_PATH : ${node_env}/lib/node_modules
 
-     ln -s $out/go /$out/bin/go
+    ln -s $out/go /$out/bin/go
   '';
 
 }
diff --git a/krebs/5pkgs/simple/go-shortener/node-packages.nix b/krebs/5pkgs/simple/go-shortener/node-packages.nix
new file mode 100644
index 000000000..526cd5a11
--- /dev/null
+++ b/krebs/5pkgs/simple/go-shortener/node-packages.nix
@@ -0,0 +1,76 @@
+# This file has been generated by node2nix 1.5.3. Do not edit!
+
+{nodeEnv, fetchurl, fetchgit, globalBuildInputs ? []}:
+
+let
+  sources = {
+    "double-ended-queue-2.1.0-0" = {
+      name = "double-ended-queue";
+      packageName = "double-ended-queue";
+      version = "2.1.0-0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz";
+        sha1 = "103d3527fd31528f40188130c841efdd78264e5c";
+      };
+    };
+    "redis-commands-1.3.5" = {
+      name = "redis-commands";
+      packageName = "redis-commands";
+      version = "1.3.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.5.tgz";
+        sha512 = "2q8pai3gf0dczb03jjig3mpaz4j2kvw8icpgf8hp4fryr3d6c0mjkvxxdmlyhainybx4zhgqsw9ghc9p986alzdzd2n2p4cxvr8b0by";
+      };
+    };
+    "redis-parser-2.6.0" = {
+      name = "redis-parser";
+      packageName = "redis-parser";
+      version = "2.6.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz";
+        sha1 = "52ed09dacac108f1a631c07e9b69941e7a19504b";
+      };
+    };
+  };
+in
+{
+  formidable = nodeEnv.buildNodePackage {
+    name = "formidable";
+    packageName = "formidable";
+    version = "1.2.1";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz";
+      sha512 = "1x0n2rfaiasdjbw1mm7s29z84f68c7iji7lb1gkxvpknvv6q7bwns7z55ijcf4vkh4kvis12rbgaaih49jf9lj53s30mllb1d35bkqn";
+    };
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "A node.js module for parsing form data, especially file uploads.";
+      homepage = https://github.com/felixge/node-formidable;
+      license = "MIT";
+    };
+    production = true;
+    bypassCache = true;
+  };
+  redis = nodeEnv.buildNodePackage {
+    name = "redis";
+    packageName = "redis";
+    version = "2.8.0";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz";
+      sha512 = "3a3044ax6qdvss83xgjfx10h5q91ls0mwgs3wpsnxcdsiipq3cnmqzsh6glyq0r7vsmpw49jp84c2jnfrhi2bgycrkd9hhhf6ia8lrk";
+    };
+    dependencies = [
+      sources."double-ended-queue-2.1.0-0"
+      sources."redis-commands-1.3.5"
+      sources."redis-parser-2.6.0"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "Redis client library";
+      homepage = https://github.com/NodeRedis/node_redis;
+      license = "MIT";
+    };
+    production = true;
+    bypassCache = true;
+  };
+}
\ No newline at end of file
diff --git a/krebs/5pkgs/simple/go-shortener/packages.nix b/krebs/5pkgs/simple/go-shortener/packages.nix
deleted file mode 100644
index 9acfd7658..000000000
--- a/krebs/5pkgs/simple/go-shortener/packages.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{ self, fetchurl, fetchgit ? null, lib }:
-
-{
-  by-spec."formidable"."*" =
-    self.by-version."formidable"."1.0.17";
-  by-version."formidable"."1.0.17" = self.buildNodePackage {
-    name = "formidable-1.0.17";
-    version = "1.0.17";
-    bin = false;
-    src = fetchurl {
-      url = "http://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz";
-      name = "formidable-1.0.17.tgz";
-      sha1 = "ef5491490f9433b705faa77249c99029ae348559";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "formidable" = self.by-version."formidable"."1.0.17";
-  by-spec."redis"."*" =
-    self.by-version."redis"."2.1.0";
-  by-version."redis"."2.1.0" = self.buildNodePackage {
-    name = "redis-2.1.0";
-    version = "2.1.0";
-    bin = false;
-    src = fetchurl {
-      url = "http://registry.npmjs.org/redis/-/redis-2.1.0.tgz";
-      name = "redis-2.1.0.tgz";
-      sha1 = "38acb208f90750250f9451219b73ff08ae907f94";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "redis" = self.by-version."redis"."2.1.0";
-}
diff --git a/krebs/5pkgs/simple/go-shortener/pkgs.json b/krebs/5pkgs/simple/go-shortener/pkgs.json
new file mode 100644
index 000000000..f53ce3745
--- /dev/null
+++ b/krebs/5pkgs/simple/go-shortener/pkgs.json
@@ -0,0 +1,4 @@
+[
+  "formidable",
+  "redis"
+]
diff --git a/krebs/5pkgs/simple/go-shortener/update.sh b/krebs/5pkgs/simple/go-shortener/update.sh
new file mode 100755
index 000000000..0c1ecc58c
--- /dev/null
+++ b/krebs/5pkgs/simple/go-shortener/update.sh
@@ -0,0 +1,2 @@
+node2nix -8 -i pkgs.json -c combine.nix
+rm node-env.nix combine.nix
diff --git a/krebs/5pkgs/simple/hashPassword/default.nix b/krebs/5pkgs/simple/hashPassword/default.nix
index 3da65ad79..3c604be80 100644
--- a/krebs/5pkgs/simple/hashPassword/default.nix
+++ b/krebs/5pkgs/simple/hashPassword/default.nix
@@ -1,7 +1,7 @@
 { lib, pkgs, ... }:
 
 pkgs.writeDashBin "hashPassword" ''
-  # usage: hashPassword
+  # usage: hashPassword [...]
   set -euf
 
   export PATH=${lib.makeBinPath (with pkgs; [
@@ -11,5 +11,5 @@ pkgs.writeDashBin "hashPassword" ''
   ])}
 
   salt=$(openssl rand -base64 16 | tr -d '+=' | head -c 16)
-  exec mkpasswd -m sha-512 -S "$salt"
+  exec mkpasswd -m sha-512 -S "$salt" "$@"
 ''
diff --git a/krebs/5pkgs/simple/kops.nix b/krebs/5pkgs/simple/kops.nix
new file mode 100644
index 000000000..8db4b8ddd
--- /dev/null
+++ b/krebs/5pkgs/simple/kops.nix
@@ -0,0 +1,7 @@
+{ fetchgit, ... }:
+
+fetchgit {
+  url = https://cgit.krebsco.de/kops;
+  rev = "refs/tags/v1.1.0";
+  sha256 = "0k3zhv2830z4bljcdvf6ciwjihk2zzcn9y23p49c6sba5hbsd6jb";
+}
diff --git a/krebs/5pkgs/simple/newsbot-js/default.nix b/krebs/5pkgs/simple/newsbot-js/default.nix
index fa39823d3..cc362b86a 100644
--- a/krebs/5pkgs/simple/newsbot-js/default.nix
+++ b/krebs/5pkgs/simple/newsbot-js/default.nix
@@ -1,27 +1,27 @@
-{ stdenv, makeWrapper, callPackage, lib, buildEnv, fetchgit, nodePackages, nodejs }:
+{ stdenv, makeWrapper, lib, buildEnv, fetchgit, nodejs-8_x, pkgs, icu }:
 
 with lib;
 
 let
-  np = (callPackage <nixpkgs/pkgs/top-level/node-packages.nix>) {
-    generated = ./packages.nix;
-    self = np;
+  nodeEnv = import <nixpkgs/pkgs/development/node-packages/node-env.nix> {
+    inherit (pkgs) stdenv python2 utillinux runCommand writeTextFile;
+    nodejs = nodejs-8_x;
+    libtool = if pkgs.stdenv.isDarwin then pkgs.darwin.cctools else null;
   };
 
-  node_env = buildEnv {
-    name = "node_env";
-    paths = [
-      np.feedparser
-      np.form-data
-      np.irc
-      np.request
-      np.shell-quote
-    ];
-    pathsToLink = [ "/lib" ];
-    ignoreCollisions = true;
+  node_env = pkgs.buildEnv {
+    name = "go-node_env";
+    paths = attrValues (import ./node-packages.nix {
+      inherit (pkgs) fetchurl fetchgit;
+      inherit nodeEnv;
+      globalBuildInputs = [
+        icu.dev
+      ];
+    });
   };
 
-in np.buildNodePackage {
+
+in stdenv.mkDerivation {
   name = "newsbot-js";
 
   src = fetchgit {
@@ -32,14 +32,11 @@ in np.buildNodePackage {
 
   phases = [
     "unpackPhase"
-    "patchPhase"
     "installPhase"
   ];
 
-  deps = (filter (v: nixType v == "derivation") (attrValues np));
-
   buildInputs = [
-    nodejs
+    nodejs-8_x
     makeWrapper
   ];
 
@@ -48,7 +45,7 @@ in np.buildNodePackage {
 
     cp newsbot.js $out/
     cat > $out/newsbot << EOF
-      ${nodejs}/bin/node $out/newsbot.js
+      ${nodejs-8_x}/bin/node $out/newsbot.js
     EOF
     chmod +x $out/newsbot
 
diff --git a/krebs/5pkgs/simple/newsbot-js/node-packages.nix b/krebs/5pkgs/simple/newsbot-js/node-packages.nix
new file mode 100644
index 000000000..d6b2a06dd
--- /dev/null
+++ b/krebs/5pkgs/simple/newsbot-js/node-packages.nix
@@ -0,0 +1,844 @@
+# This file has been generated by node2nix 1.5.3. Do not edit!
+
+{nodeEnv, fetchurl, fetchgit, globalBuildInputs ? []}:
+
+let
+  sources = {
+    "addressparser-1.0.1" = {
+      name = "addressparser";
+      packageName = "addressparser";
+      version = "1.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz";
+        sha1 = "47afbe1a2a9262191db6838e4fd1d39b40821746";
+      };
+    };
+    "ajv-5.5.2" = {
+      name = "ajv";
+      packageName = "ajv";
+      version = "5.5.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz";
+        sha1 = "73b5eeca3fab653e3d3f9422b341ad42205dc965";
+      };
+    };
+    "array-filter-0.0.1" = {
+      name = "array-filter";
+      packageName = "array-filter";
+      version = "0.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz";
+        sha1 = "7da8cf2e26628ed732803581fd21f67cacd2eeec";
+      };
+    };
+    "array-indexofobject-0.0.1" = {
+      name = "array-indexofobject";
+      packageName = "array-indexofobject";
+      version = "0.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/array-indexofobject/-/array-indexofobject-0.0.1.tgz";
+        sha1 = "aaa128e62c9b3c358094568c219ff64fe489d42a";
+      };
+    };
+    "array-map-0.0.0" = {
+      name = "array-map";
+      packageName = "array-map";
+      version = "0.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz";
+        sha1 = "88a2bab73d1cf7bcd5c1b118a003f66f665fa662";
+      };
+    };
+    "array-reduce-0.0.0" = {
+      name = "array-reduce";
+      packageName = "array-reduce";
+      version = "0.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz";
+        sha1 = "173899d3ffd1c7d9383e4479525dbe278cab5f2b";
+      };
+    };
+    "asn1-0.2.3" = {
+      name = "asn1";
+      packageName = "asn1";
+      version = "0.2.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz";
+        sha1 = "dac8787713c9966849fc8180777ebe9c1ddf3b86";
+      };
+    };
+    "assert-plus-1.0.0" = {
+      name = "assert-plus";
+      packageName = "assert-plus";
+      version = "1.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz";
+        sha1 = "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525";
+      };
+    };
+    "asynckit-0.4.0" = {
+      name = "asynckit";
+      packageName = "asynckit";
+      version = "0.4.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz";
+        sha1 = "c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79";
+      };
+    };
+    "aws-sign2-0.7.0" = {
+      name = "aws-sign2";
+      packageName = "aws-sign2";
+      version = "0.7.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz";
+        sha1 = "b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8";
+      };
+    };
+    "aws4-1.6.0" = {
+      name = "aws4";
+      packageName = "aws4";
+      version = "1.6.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz";
+        sha1 = "83ef5ca860b2b32e4a0deedee8c771b9db57471e";
+      };
+    };
+    "bcrypt-pbkdf-1.0.1" = {
+      name = "bcrypt-pbkdf";
+      packageName = "bcrypt-pbkdf";
+      version = "1.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz";
+        sha1 = "63bc5dcb61331b92bc05fd528953c33462a06f8d";
+      };
+    };
+    "boom-4.3.1" = {
+      name = "boom";
+      packageName = "boom";
+      version = "4.3.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz";
+        sha1 = "4f8a3005cb4a7e3889f749030fd25b96e01d2e31";
+      };
+    };
+    "boom-5.2.0" = {
+      name = "boom";
+      packageName = "boom";
+      version = "5.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz";
+        sha512 = "19h20yqpvca08dns1rs4f057f10w63v0snxfml4h5khsk266x3x1im0w72bza4k2xn0kfz6jlv001dhcvxsjr09bmbqnysils9m7437";
+      };
+    };
+    "caseless-0.12.0" = {
+      name = "caseless";
+      packageName = "caseless";
+      version = "0.12.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz";
+        sha1 = "1b681c21ff84033c826543090689420d187151dc";
+      };
+    };
+    "co-4.6.0" = {
+      name = "co";
+      packageName = "co";
+      version = "4.6.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/co/-/co-4.6.0.tgz";
+        sha1 = "6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184";
+      };
+    };
+    "combined-stream-1.0.6" = {
+      name = "combined-stream";
+      packageName = "combined-stream";
+      version = "1.0.6";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz";
+        sha1 = "723e7df6e801ac5613113a7e445a9b69cb632818";
+      };
+    };
+    "core-util-is-1.0.2" = {
+      name = "core-util-is";
+      packageName = "core-util-is";
+      version = "1.0.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz";
+        sha1 = "b5fd54220aa2bc5ab57aab7140c940754503c1a7";
+      };
+    };
+    "cryptiles-3.1.2" = {
+      name = "cryptiles";
+      packageName = "cryptiles";
+      version = "3.1.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz";
+        sha1 = "a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe";
+      };
+    };
+    "dashdash-1.14.1" = {
+      name = "dashdash";
+      packageName = "dashdash";
+      version = "1.14.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz";
+        sha1 = "853cfa0f7cbe2fed5de20326b8dd581035f6e2f0";
+      };
+    };
+    "delayed-stream-1.0.0" = {
+      name = "delayed-stream";
+      packageName = "delayed-stream";
+      version = "1.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz";
+        sha1 = "df3ae199acadfb7d440aaae0b29e2272b24ec619";
+      };
+    };
+    "ecc-jsbn-0.1.1" = {
+      name = "ecc-jsbn";
+      packageName = "ecc-jsbn";
+      version = "0.1.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz";
+        sha1 = "0fc73a9ed5f0d53c38193398523ef7e543777505";
+      };
+    };
+    "extend-3.0.1" = {
+      name = "extend";
+      packageName = "extend";
+      version = "3.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz";
+        sha1 = "a755ea7bc1adfcc5a31ce7e762dbaadc5e636444";
+      };
+    };
+    "extsprintf-1.3.0" = {
+      name = "extsprintf";
+      packageName = "extsprintf";
+      version = "1.3.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz";
+        sha1 = "96918440e3041a7a414f8c52e3c574eb3c3e1e05";
+      };
+    };
+    "fast-deep-equal-1.1.0" = {
+      name = "fast-deep-equal";
+      packageName = "fast-deep-equal";
+      version = "1.1.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz";
+        sha1 = "c053477817c86b51daa853c81e059b733d023614";
+      };
+    };
+    "fast-json-stable-stringify-2.0.0" = {
+      name = "fast-json-stable-stringify";
+      packageName = "fast-json-stable-stringify";
+      version = "2.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz";
+        sha1 = "d5142c0caee6b1189f87d3a76111064f86c8bbf2";
+      };
+    };
+    "forever-agent-0.6.1" = {
+      name = "forever-agent";
+      packageName = "forever-agent";
+      version = "0.6.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz";
+        sha1 = "fbc71f0c41adeb37f96c577ad1ed42d8fdacca91";
+      };
+    };
+    "form-data-2.3.2" = {
+      name = "form-data";
+      packageName = "form-data";
+      version = "2.3.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz";
+        sha1 = "4970498be604c20c005d4f5c23aecd21d6b49099";
+      };
+    };
+    "getpass-0.1.7" = {
+      name = "getpass";
+      packageName = "getpass";
+      version = "0.1.7";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz";
+        sha1 = "5eff8e3e684d569ae4cb2b1282604e8ba62149fa";
+      };
+    };
+    "har-schema-2.0.0" = {
+      name = "har-schema";
+      packageName = "har-schema";
+      version = "2.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz";
+        sha1 = "a94c2224ebcac04782a0d9035521f24735b7ec92";
+      };
+    };
+    "har-validator-5.0.3" = {
+      name = "har-validator";
+      packageName = "har-validator";
+      version = "5.0.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz";
+        sha1 = "ba402c266194f15956ef15e0fcf242993f6a7dfd";
+      };
+    };
+    "hawk-6.0.2" = {
+      name = "hawk";
+      packageName = "hawk";
+      version = "6.0.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz";
+        sha512 = "1nl2hjr2mnhj5jlaz8mh54z7acwz5j5idkch04qgjk78756gw5d0fjk4a2immil5ij9ijdssb9ndpryvnh2xpcbgcjv8lxybn330als";
+      };
+    };
+    "hoek-4.2.1" = {
+      name = "hoek";
+      packageName = "hoek";
+      version = "4.2.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz";
+        sha512 = "1y8kprb3qldxqj31zai5n8dvhydsl9nn5w4rskhnbzzhldn6pm6n5lcyam3sfkb61a62d5m58k8im7z6ngwbd9cw9zp4zm4y7ckrf20";
+      };
+    };
+    "http-signature-1.2.0" = {
+      name = "http-signature";
+      packageName = "http-signature";
+      version = "1.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz";
+        sha1 = "9aecd925114772f3d95b65a60abb8f7c18fbace1";
+      };
+    };
+    "iconv-2.2.3" = {
+      name = "iconv";
+      packageName = "iconv";
+      version = "2.2.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/iconv/-/iconv-2.2.3.tgz";
+        sha1 = "e084d60eeb7d73da7f0a9c096e4c8abe090bfaed";
+      };
+    };
+    "inherits-2.0.3" = {
+      name = "inherits";
+      packageName = "inherits";
+      version = "2.0.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz";
+        sha1 = "633c2c83e3da42a502f52466022480f4208261de";
+      };
+    };
+    "irc-colors-1.4.2" = {
+      name = "irc-colors";
+      packageName = "irc-colors";
+      version = "1.4.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/irc-colors/-/irc-colors-1.4.2.tgz";
+        sha512 = "0f75yhavbhr8lbh3lh83rvyfrrrcxjawnd2rz7sacjd3zxj5524xr28j66f2l11vlngdkbplxz5xsq9dnwrcyqa0jh64k2pvzhn17a1";
+      };
+    };
+    "is-typedarray-1.0.0" = {
+      name = "is-typedarray";
+      packageName = "is-typedarray";
+      version = "1.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz";
+        sha1 = "e479c80858df0c1b11ddda6940f96011fcda4a9a";
+      };
+    };
+    "isarray-1.0.0" = {
+      name = "isarray";
+      packageName = "isarray";
+      version = "1.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz";
+        sha1 = "bb935d48582cba168c06834957a54a3e07124f11";
+      };
+    };
+    "isstream-0.1.2" = {
+      name = "isstream";
+      packageName = "isstream";
+      version = "0.1.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz";
+        sha1 = "47e63f7af55afa6f92e1500e690eb8b8529c099a";
+      };
+    };
+    "jsbn-0.1.1" = {
+      name = "jsbn";
+      packageName = "jsbn";
+      version = "0.1.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz";
+        sha1 = "a5e654c2e5a2deb5f201d96cefbca80c0ef2f513";
+      };
+    };
+    "json-schema-0.2.3" = {
+      name = "json-schema";
+      packageName = "json-schema";
+      version = "0.2.3";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz";
+        sha1 = "b480c892e59a2f05954ce727bd3f2a4e882f9e13";
+      };
+    };
+    "json-schema-traverse-0.3.1" = {
+      name = "json-schema-traverse";
+      packageName = "json-schema-traverse";
+      version = "0.3.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz";
+        sha1 = "349a6d44c53a51de89b40805c5d5e59b417d3340";
+      };
+    };
+    "json-stringify-safe-5.0.1" = {
+      name = "json-stringify-safe";
+      packageName = "json-stringify-safe";
+      version = "5.0.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz";
+        sha1 = "1296a2d58fd45f19a0f6ce01d65701e2c735b6eb";
+      };
+    };
+    "jsonify-0.0.0" = {
+      name = "jsonify";
+      packageName = "jsonify";
+      version = "0.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz";
+        sha1 = "2c74b6ee41d93ca51b7b5aaee8f503631d252a73";
+      };
+    };
+    "jsprim-1.4.1" = {
+      name = "jsprim";
+      packageName = "jsprim";
+      version = "1.4.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz";
+        sha1 = "313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2";
+      };
+    };
+    "lodash.assign-4.2.0" = {
+      name = "lodash.assign";
+      packageName = "lodash.assign";
+      version = "4.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz";
+        sha1 = "0d99f3ccd7a6d261d19bdaeb9245005d285808e7";
+      };
+    };
+    "lodash.get-4.4.2" = {
+      name = "lodash.get";
+      packageName = "lodash.get";
+      version = "4.4.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz";
+        sha1 = "2d177f652fa31e939b4438d5341499dfa3825e99";
+      };
+    };
+    "lodash.has-4.5.2" = {
+      name = "lodash.has";
+      packageName = "lodash.has";
+      version = "4.5.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz";
+        sha1 = "d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862";
+      };
+    };
+    "lodash.uniq-4.5.0" = {
+      name = "lodash.uniq";
+      packageName = "lodash.uniq";
+      version = "4.5.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz";
+        sha1 = "d0225373aeb652adc1bc82e4945339a842754773";
+      };
+    };
+    "mime-db-1.33.0" = {
+      name = "mime-db";
+      packageName = "mime-db";
+      version = "1.33.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz";
+        sha512 = "36xnw59ik9fqym00cmwb5nyzg0l03k70cp413f7639j93wgmzk1mh0xjc7i6zz3r6k9xnwh0g5cm5a1f3y8c6plgy4qld7fm887ywh4";
+      };
+    };
+    "mime-types-2.1.18" = {
+      name = "mime-types";
+      packageName = "mime-types";
+      version = "2.1.18";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz";
+        sha512 = "22krj1kw7n9z10zdyx7smcaim4bzwqsqzhspwha06q58gcrxfp93hw2cd0vk5crhq5p2dwzqlpacg32lrmp5sjzb798zdzy35mdmkwm";
+      };
+    };
+    "mri-1.1.0" = {
+      name = "mri";
+      packageName = "mri";
+      version = "1.1.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/mri/-/mri-1.1.0.tgz";
+        sha1 = "5c0a3f29c8ccffbbb1ec941dcec09d71fa32f36a";
+      };
+    };
+    "nan-2.10.0" = {
+      name = "nan";
+      packageName = "nan";
+      version = "2.10.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz";
+        sha512 = "349rr7x0djrlkav4gbhkg355852ingn965r0kkch8rr4cwp7qki9676zpq8cq988yszzd2hld6szsbbnd1v6rghzf11abn1nyzlj1vc";
+      };
+    };
+    "node-icu-charset-detector-0.2.0" = {
+      name = "node-icu-charset-detector";
+      packageName = "node-icu-charset-detector";
+      version = "0.2.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/node-icu-charset-detector/-/node-icu-charset-detector-0.2.0.tgz";
+        sha1 = "c2320da374ddcb671fc54cb4a0e041e156ffd639";
+      };
+    };
+    "oauth-sign-0.8.2" = {
+      name = "oauth-sign";
+      packageName = "oauth-sign";
+      version = "0.8.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz";
+        sha1 = "46a6ab7f0aead8deae9ec0565780b7d4efeb9d43";
+      };
+    };
+    "performance-now-2.1.0" = {
+      name = "performance-now";
+      packageName = "performance-now";
+      version = "2.1.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz";
+        sha1 = "6309f4e0e5fa913ec1c69307ae364b4b377c9e7b";
+      };
+    };
+    "process-nextick-args-2.0.0" = {
+      name = "process-nextick-args";
+      packageName = "process-nextick-args";
+      version = "2.0.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz";
+        sha512 = "0rw8xpqqkhs91722slvzf8icxfaimqp4w8zb3840jxr7r8n8035byl6dhdi5bm0yr6x7sdws0gf3m025fg6hqgaklwlbl4d7bah5l9j";
+      };
+    };
+    "punycode-1.4.1" = {
+      name = "punycode";
+      packageName = "punycode";
+      version = "1.4.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz";
+        sha1 = "c0d5a63b2718800ad8e1eb0fa5269c84dd41845e";
+      };
+    };
+    "qs-6.5.1" = {
+      name = "qs";
+      packageName = "qs";
+      version = "6.5.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz";
+        sha512 = "3waqapyj1k4g135sgj636rmswiaixq19is1rw0rpv4qp6k7dl0a9nwy06m7yl5lbdk9p6xpwwngnggbzlzaz6rh11c86j2nvnnf273r";
+      };
+    };
+    "readable-stream-2.3.6" = {
+      name = "readable-stream";
+      packageName = "readable-stream";
+      version = "2.3.6";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz";
+        sha512 = "0mj9b6190amln9rg89x5pq2n195s3v0gzicpdamv1kbabg69aw5m71l34jsjn7bqil7405l6l35x9ijnb3h4jz5vx2i00l8sl1ll2xm";
+      };
+    };
+    "safe-buffer-5.1.1" = {
+      name = "safe-buffer";
+      packageName = "safe-buffer";
+      version = "5.1.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz";
+        sha512 = "1p28rllll1w65yzq5azi4izx962399xdsdlfbaynn7vmp981hiss05jhiy9hm7sbbfk3b4dhlcv0zy07fc59mnc07hdv6wcgqkcvawh";
+      };
+    };
+    "sax-1.2.4" = {
+      name = "sax";
+      packageName = "sax";
+      version = "1.2.4";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz";
+        sha512 = "1dn291mjsda42w8kldlbmngk6dhjxfbvvd5lckyqmwbjaj6069iq3wx0nvcfglwnpddz2qa93lzf4hv77iz43bd2qixa079sjzl799n";
+      };
+    };
+    "sntp-2.1.0" = {
+      name = "sntp";
+      packageName = "sntp";
+      version = "2.1.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz";
+        sha512 = "0k2smmr24w5hb1cpql6vcgh58vzp4pmh9anf0bgz3arlsgq1mapnlq9fjqr6xs10aq1cmxaw987fwknqi62frax0fvs9bj3q3kmpg8l";
+      };
+    };
+    "sshpk-1.14.1" = {
+      name = "sshpk";
+      packageName = "sshpk";
+      version = "1.14.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz";
+        sha1 = "130f5975eddad963f1d56f92b9ac6c51fa9f83eb";
+      };
+    };
+    "string_decoder-1.1.1" = {
+      name = "string_decoder";
+      packageName = "string_decoder";
+      version = "1.1.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz";
+        sha512 = "315yd4vzwrwk3vwj1klf46y1cj2jbvf88066y2rnwhksb98phj46jkxixbwsp3h607w7czy7cby522s7sx8mvspdpdm3s72y2ga3x4z";
+      };
+    };
+    "stringstream-0.0.5" = {
+      name = "stringstream";
+      packageName = "stringstream";
+      version = "0.0.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz";
+        sha1 = "4e484cd4de5a0bbbee18e46307710a8a81621878";
+      };
+    };
+    "tough-cookie-2.3.4" = {
+      name = "tough-cookie";
+      packageName = "tough-cookie";
+      version = "2.3.4";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz";
+        sha512 = "0ncm6j3cjq1f26mzjf04k9bkw1b08w53s4qa3a11c1bdj4pgnqv1422c1xs5jyy6y1psppjx52fhagq5zkjkgrcpdkxcdiry96r77jd";
+      };
+    };
+    "tunnel-agent-0.6.0" = {
+      name = "tunnel-agent";
+      packageName = "tunnel-agent";
+      version = "0.6.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz";
+        sha1 = "27a5dea06b36b04a0a9966774b290868f0fc40fd";
+      };
+    };
+    "tweetnacl-0.14.5" = {
+      name = "tweetnacl";
+      packageName = "tweetnacl";
+      version = "0.14.5";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz";
+        sha1 = "5ae68177f192d4456269d108afa93ff8743f4f64";
+      };
+    };
+    "util-deprecate-1.0.2" = {
+      name = "util-deprecate";
+      packageName = "util-deprecate";
+      version = "1.0.2";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz";
+        sha1 = "450d4dc9fa70de732762fbd2d4a28981419a0ccf";
+      };
+    };
+    "uuid-3.2.1" = {
+      name = "uuid";
+      packageName = "uuid";
+      version = "3.2.1";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz";
+        sha512 = "0843vl1c974n8kw5kn0kvhvhwk8y8jydr0xkwwl2963xxmkw4ingk6xj9c8m48jw2i95giglxzq5aw5v5mij9kv7fzln8pxav1cr6cd";
+      };
+    };
+    "verror-1.10.0" = {
+      name = "verror";
+      packageName = "verror";
+      version = "1.10.0";
+      src = fetchurl {
+        url = "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz";
+        sha1 = "3a105ca17053af55d6e270c1f8288682e18da400";
+      };
+    };
+  };
+in
+{
+  feedparser = nodeEnv.buildNodePackage {
+    name = "feedparser";
+    packageName = "feedparser";
+    version = "2.2.9";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/feedparser/-/feedparser-2.2.9.tgz";
+      sha1 = "9138197dafdae05fcadde0036beeaf6066c2c5e9";
+    };
+    dependencies = [
+      sources."addressparser-1.0.1"
+      sources."array-indexofobject-0.0.1"
+      sources."core-util-is-1.0.2"
+      sources."inherits-2.0.3"
+      sources."isarray-1.0.0"
+      sources."lodash.assign-4.2.0"
+      sources."lodash.get-4.4.2"
+      sources."lodash.has-4.5.2"
+      sources."lodash.uniq-4.5.0"
+      sources."mri-1.1.0"
+      sources."process-nextick-args-2.0.0"
+      sources."readable-stream-2.3.6"
+      sources."safe-buffer-5.1.1"
+      sources."sax-1.2.4"
+      sources."string_decoder-1.1.1"
+      sources."util-deprecate-1.0.2"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "Robust RSS Atom and RDF feed parsing using sax js";
+      homepage = http://github.com/danmactough/node-feedparser;
+      license = "MIT";
+    };
+    production = true;
+    bypassCache = true;
+  };
+  form-data = nodeEnv.buildNodePackage {
+    name = "form-data";
+    packageName = "form-data";
+    version = "2.3.2";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz";
+      sha1 = "4970498be604c20c005d4f5c23aecd21d6b49099";
+    };
+    dependencies = [
+      sources."asynckit-0.4.0"
+      sources."combined-stream-1.0.6"
+      sources."delayed-stream-1.0.0"
+      sources."mime-db-1.33.0"
+      sources."mime-types-2.1.18"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "A library to create readable \"multipart/form-data\" streams. Can be used to submit forms and file uploads to other web applications.";
+      license = "MIT";
+    };
+    production = true;
+    bypassCache = true;
+  };
+  irc = nodeEnv.buildNodePackage {
+    name = "irc";
+    packageName = "irc";
+    version = "0.5.2";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/irc/-/irc-0.5.2.tgz";
+      sha1 = "3714f4768365a96d0b2f776bc91166beb2464bbc";
+    };
+    dependencies = [
+      sources."iconv-2.2.3"
+      sources."irc-colors-1.4.2"
+      sources."nan-2.10.0"
+      sources."node-icu-charset-detector-0.2.0"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "An IRC client library for node";
+      homepage = "https://github.com/martynsmith/node-irc#readme";
+      license = "GPL-3.0";
+    };
+    production = true;
+    bypassCache = true;
+  };
+  request = nodeEnv.buildNodePackage {
+    name = "request";
+    packageName = "request";
+    version = "2.85.0";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/request/-/request-2.85.0.tgz";
+      sha512 = "2d3hg10zs5ycnr8prmiwdhacf88fl0x0bi6szs0z2r07zcbk419laixwpjp8sqapbc2ifyyih7p3r60wgr58bmcncz3pqnx523c8zph";
+    };
+    dependencies = [
+      sources."ajv-5.5.2"
+      sources."asn1-0.2.3"
+      sources."assert-plus-1.0.0"
+      sources."asynckit-0.4.0"
+      sources."aws-sign2-0.7.0"
+      sources."aws4-1.6.0"
+      sources."bcrypt-pbkdf-1.0.1"
+      sources."boom-4.3.1"
+      sources."caseless-0.12.0"
+      sources."co-4.6.0"
+      sources."combined-stream-1.0.6"
+      sources."core-util-is-1.0.2"
+      (sources."cryptiles-3.1.2" // {
+        dependencies = [
+          sources."boom-5.2.0"
+        ];
+      })
+      sources."dashdash-1.14.1"
+      sources."delayed-stream-1.0.0"
+      sources."ecc-jsbn-0.1.1"
+      sources."extend-3.0.1"
+      sources."extsprintf-1.3.0"
+      sources."fast-deep-equal-1.1.0"
+      sources."fast-json-stable-stringify-2.0.0"
+      sources."forever-agent-0.6.1"
+      sources."form-data-2.3.2"
+      sources."getpass-0.1.7"
+      sources."har-schema-2.0.0"
+      sources."har-validator-5.0.3"
+      sources."hawk-6.0.2"
+      sources."hoek-4.2.1"
+      sources."http-signature-1.2.0"
+      sources."is-typedarray-1.0.0"
+      sources."isstream-0.1.2"
+      sources."jsbn-0.1.1"
+      sources."json-schema-0.2.3"
+      sources."json-schema-traverse-0.3.1"
+      sources."json-stringify-safe-5.0.1"
+      sources."jsprim-1.4.1"
+      sources."mime-db-1.33.0"
+      sources."mime-types-2.1.18"
+      sources."oauth-sign-0.8.2"
+      sources."performance-now-2.1.0"
+      sources."punycode-1.4.1"
+      sources."qs-6.5.1"
+      sources."safe-buffer-5.1.1"
+      sources."sntp-2.1.0"
+      sources."sshpk-1.14.1"
+      sources."stringstream-0.0.5"
+      sources."tough-cookie-2.3.4"
+      sources."tunnel-agent-0.6.0"
+      sources."tweetnacl-0.14.5"
+      sources."uuid-3.2.1"
+      sources."verror-1.10.0"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "Simplified HTTP request client.";
+      homepage = "https://github.com/request/request#readme";
+      license = "Apache-2.0";
+    };
+    production = true;
+    bypassCache = true;
+  };
+  shell-quote = nodeEnv.buildNodePackage {
+    name = "shell-quote";
+    packageName = "shell-quote";
+    version = "1.6.1";
+    src = fetchurl {
+      url = "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz";
+      sha1 = "f4781949cce402697127430ea3b3c5476f481767";
+    };
+    dependencies = [
+      sources."array-filter-0.0.1"
+      sources."array-map-0.0.0"
+      sources."array-reduce-0.0.0"
+      sources."jsonify-0.0.0"
+    ];
+    buildInputs = globalBuildInputs;
+    meta = {
+      description = "quote and parse shell commands";
+      homepage = "https://github.com/substack/node-shell-quote#readme";
+      license = "MIT";
+    };
+    production = true;
+    bypassCache = true;
+  };
+}
\ No newline at end of file
diff --git a/krebs/5pkgs/simple/newsbot-js/packages.nix b/krebs/5pkgs/simple/newsbot-js/packages.nix
deleted file mode 100644
index 62921cb8f..000000000
--- a/krebs/5pkgs/simple/newsbot-js/packages.nix
+++ /dev/null
@@ -1,1747 +0,0 @@
-{ self, fetchurl, fetchgit ? null, lib }:
-
-{
-  by-spec."addressparser"."^1.0.1" =
-    self.by-version."addressparser"."1.0.1";
-  by-version."addressparser"."1.0.1" = self.buildNodePackage {
-    name = "addressparser-1.0.1";
-    version = "1.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/addressparser/-/addressparser-1.0.1.tgz";
-      name = "addressparser-1.0.1.tgz";
-      sha1 = "47afbe1a2a9262191db6838e4fd1d39b40821746";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."ansi-regex"."^2.0.0" =
-    self.by-version."ansi-regex"."2.1.1";
-  by-version."ansi-regex"."2.1.1" = self.buildNodePackage {
-    name = "ansi-regex-2.1.1";
-    version = "2.1.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz";
-      name = "ansi-regex-2.1.1.tgz";
-      sha1 = "c3b33ab5ee360d86e0e628f0468ae7ef27d654df";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."ansi-styles"."^2.2.1" =
-    self.by-version."ansi-styles"."2.2.1";
-  by-version."ansi-styles"."2.2.1" = self.buildNodePackage {
-    name = "ansi-styles-2.2.1";
-    version = "2.2.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz";
-      name = "ansi-styles-2.2.1.tgz";
-      sha1 = "b432dd3358b634cf75e1e4664368240533c1ddbe";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."array-filter"."~0.0.0" =
-    self.by-version."array-filter"."0.0.1";
-  by-version."array-filter"."0.0.1" = self.buildNodePackage {
-    name = "array-filter-0.0.1";
-    version = "0.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz";
-      name = "array-filter-0.0.1.tgz";
-      sha1 = "7da8cf2e26628ed732803581fd21f67cacd2eeec";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."array-indexofobject"."~0.0.1" =
-    self.by-version."array-indexofobject"."0.0.1";
-  by-version."array-indexofobject"."0.0.1" = self.buildNodePackage {
-    name = "array-indexofobject-0.0.1";
-    version = "0.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/array-indexofobject/-/array-indexofobject-0.0.1.tgz";
-      name = "array-indexofobject-0.0.1.tgz";
-      sha1 = "aaa128e62c9b3c358094568c219ff64fe489d42a";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."array-map"."~0.0.0" =
-    self.by-version."array-map"."0.0.0";
-  by-version."array-map"."0.0.0" = self.buildNodePackage {
-    name = "array-map-0.0.0";
-    version = "0.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz";
-      name = "array-map-0.0.0.tgz";
-      sha1 = "88a2bab73d1cf7bcd5c1b118a003f66f665fa662";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."array-reduce"."~0.0.0" =
-    self.by-version."array-reduce"."0.0.0";
-  by-version."array-reduce"."0.0.0" = self.buildNodePackage {
-    name = "array-reduce-0.0.0";
-    version = "0.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz";
-      name = "array-reduce-0.0.0.tgz";
-      sha1 = "173899d3ffd1c7d9383e4479525dbe278cab5f2b";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."asn1"."~0.2.3" =
-    self.by-version."asn1"."0.2.3";
-  by-version."asn1"."0.2.3" = self.buildNodePackage {
-    name = "asn1-0.2.3";
-    version = "0.2.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz";
-      name = "asn1-0.2.3.tgz";
-      sha1 = "dac8787713c9966849fc8180777ebe9c1ddf3b86";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."assert-plus"."^0.2.0" =
-    self.by-version."assert-plus"."0.2.0";
-  by-version."assert-plus"."0.2.0" = self.buildNodePackage {
-    name = "assert-plus-0.2.0";
-    version = "0.2.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz";
-      name = "assert-plus-0.2.0.tgz";
-      sha1 = "d74e1b87e7affc0db8aadb7021f3fe48101ab234";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."assert-plus"."^1.0.0" =
-    self.by-version."assert-plus"."1.0.0";
-  by-version."assert-plus"."1.0.0" = self.buildNodePackage {
-    name = "assert-plus-1.0.0";
-    version = "1.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz";
-      name = "assert-plus-1.0.0.tgz";
-      sha1 = "f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."asynckit"."^0.4.0" =
-    self.by-version."asynckit"."0.4.0";
-  by-version."asynckit"."0.4.0" = self.buildNodePackage {
-    name = "asynckit-0.4.0";
-    version = "0.4.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz";
-      name = "asynckit-0.4.0.tgz";
-      sha1 = "c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."aws-sign2"."~0.6.0" =
-    self.by-version."aws-sign2"."0.6.0";
-  by-version."aws-sign2"."0.6.0" = self.buildNodePackage {
-    name = "aws-sign2-0.6.0";
-    version = "0.6.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz";
-      name = "aws-sign2-0.6.0.tgz";
-      sha1 = "14342dd38dbcc94d0e5b87d763cd63612c0e794f";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."aws4"."^1.2.1" =
-    self.by-version."aws4"."1.5.0";
-  by-version."aws4"."1.5.0" = self.buildNodePackage {
-    name = "aws4-1.5.0";
-    version = "1.5.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/aws4/-/aws4-1.5.0.tgz";
-      name = "aws4-1.5.0.tgz";
-      sha1 = "0a29ffb79c31c9e712eeb087e8e7a64b4a56d755";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."bcrypt-pbkdf"."^1.0.0" =
-    self.by-version."bcrypt-pbkdf"."1.0.1";
-  by-version."bcrypt-pbkdf"."1.0.1" = self.buildNodePackage {
-    name = "bcrypt-pbkdf-1.0.1";
-    version = "1.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz";
-      name = "bcrypt-pbkdf-1.0.1.tgz";
-      sha1 = "63bc5dcb61331b92bc05fd528953c33462a06f8d";
-    };
-    deps = {
-      "tweetnacl-0.14.5" = self.by-version."tweetnacl"."0.14.5";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."boom"."2.x.x" =
-    self.by-version."boom"."2.10.1";
-  by-version."boom"."2.10.1" = self.buildNodePackage {
-    name = "boom-2.10.1";
-    version = "2.10.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz";
-      name = "boom-2.10.1.tgz";
-      sha1 = "39c8918ceff5799f83f9492a848f625add0c766f";
-    };
-    deps = {
-      "hoek-2.16.3" = self.by-version."hoek"."2.16.3";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."buffer-shims"."^1.0.0" =
-    self.by-version."buffer-shims"."1.0.0";
-  by-version."buffer-shims"."1.0.0" = self.buildNodePackage {
-    name = "buffer-shims-1.0.0";
-    version = "1.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/buffer-shims/-/buffer-shims-1.0.0.tgz";
-      name = "buffer-shims-1.0.0.tgz";
-      sha1 = "9978ce317388c649ad8793028c3477ef044a8b51";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."caseless"."~0.11.0" =
-    self.by-version."caseless"."0.11.0";
-  by-version."caseless"."0.11.0" = self.buildNodePackage {
-    name = "caseless-0.11.0";
-    version = "0.11.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/caseless/-/caseless-0.11.0.tgz";
-      name = "caseless-0.11.0.tgz";
-      sha1 = "715b96ea9841593cc33067923f5ec60ebda4f7d7";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."chalk"."^1.1.1" =
-    self.by-version."chalk"."1.1.3";
-  by-version."chalk"."1.1.3" = self.buildNodePackage {
-    name = "chalk-1.1.3";
-    version = "1.1.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz";
-      name = "chalk-1.1.3.tgz";
-      sha1 = "a8115c55e4a702fe4d150abd3872822a7e09fc98";
-    };
-    deps = {
-      "ansi-styles-2.2.1" = self.by-version."ansi-styles"."2.2.1";
-      "escape-string-regexp-1.0.5" = self.by-version."escape-string-regexp"."1.0.5";
-      "has-ansi-2.0.0" = self.by-version."has-ansi"."2.0.0";
-      "strip-ansi-3.0.1" = self.by-version."strip-ansi"."3.0.1";
-      "supports-color-2.0.0" = self.by-version."supports-color"."2.0.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."combined-stream"."^1.0.5" =
-    self.by-version."combined-stream"."1.0.5";
-  by-version."combined-stream"."1.0.5" = self.buildNodePackage {
-    name = "combined-stream-1.0.5";
-    version = "1.0.5";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz";
-      name = "combined-stream-1.0.5.tgz";
-      sha1 = "938370a57b4a51dea2c77c15d5c5fdf895164009";
-    };
-    deps = {
-      "delayed-stream-1.0.0" = self.by-version."delayed-stream"."1.0.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."combined-stream"."~1.0.5" =
-    self.by-version."combined-stream"."1.0.5";
-  by-spec."commander"."^2.9.0" =
-    self.by-version."commander"."2.9.0";
-  by-version."commander"."2.9.0" = self.buildNodePackage {
-    name = "commander-2.9.0";
-    version = "2.9.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz";
-      name = "commander-2.9.0.tgz";
-      sha1 = "9c99094176e12240cb22d6c5146098400fe0f7d4";
-    };
-    deps = {
-      "graceful-readlink-1.0.1" = self.by-version."graceful-readlink"."1.0.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."core-util-is"."~1.0.0" =
-    self.by-version."core-util-is"."1.0.2";
-  by-version."core-util-is"."1.0.2" = self.buildNodePackage {
-    name = "core-util-is-1.0.2";
-    version = "1.0.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz";
-      name = "core-util-is-1.0.2.tgz";
-      sha1 = "b5fd54220aa2bc5ab57aab7140c940754503c1a7";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."cryptiles"."2.x.x" =
-    self.by-version."cryptiles"."2.0.5";
-  by-version."cryptiles"."2.0.5" = self.buildNodePackage {
-    name = "cryptiles-2.0.5";
-    version = "2.0.5";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz";
-      name = "cryptiles-2.0.5.tgz";
-      sha1 = "3bdfecdc608147c1c67202fa291e7dca59eaa3b8";
-    };
-    deps = {
-      "boom-2.10.1" = self.by-version."boom"."2.10.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."dashdash"."^1.12.0" =
-    self.by-version."dashdash"."1.14.1";
-  by-version."dashdash"."1.14.1" = self.buildNodePackage {
-    name = "dashdash-1.14.1";
-    version = "1.14.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz";
-      name = "dashdash-1.14.1.tgz";
-      sha1 = "853cfa0f7cbe2fed5de20326b8dd581035f6e2f0";
-    };
-    deps = {
-      "assert-plus-1.0.0" = self.by-version."assert-plus"."1.0.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."delayed-stream"."~1.0.0" =
-    self.by-version."delayed-stream"."1.0.0";
-  by-version."delayed-stream"."1.0.0" = self.buildNodePackage {
-    name = "delayed-stream-1.0.0";
-    version = "1.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz";
-      name = "delayed-stream-1.0.0.tgz";
-      sha1 = "df3ae199acadfb7d440aaae0b29e2272b24ec619";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."ecc-jsbn"."~0.1.1" =
-    self.by-version."ecc-jsbn"."0.1.1";
-  by-version."ecc-jsbn"."0.1.1" = self.buildNodePackage {
-    name = "ecc-jsbn-0.1.1";
-    version = "0.1.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz";
-      name = "ecc-jsbn-0.1.1.tgz";
-      sha1 = "0fc73a9ed5f0d53c38193398523ef7e543777505";
-    };
-    deps = {
-      "jsbn-0.1.0" = self.by-version."jsbn"."0.1.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."escape-string-regexp"."^1.0.2" =
-    self.by-version."escape-string-regexp"."1.0.5";
-  by-version."escape-string-regexp"."1.0.5" = self.buildNodePackage {
-    name = "escape-string-regexp-1.0.5";
-    version = "1.0.5";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz";
-      name = "escape-string-regexp-1.0.5.tgz";
-      sha1 = "1b61c0562190a8dff6ae3bb2cf0200ca130b86d4";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."extend"."~3.0.0" =
-    self.by-version."extend"."3.0.0";
-  by-version."extend"."3.0.0" = self.buildNodePackage {
-    name = "extend-3.0.0";
-    version = "3.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz";
-      name = "extend-3.0.0.tgz";
-      sha1 = "5a474353b9f3353ddd8176dfd37b91c83a46f1d4";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."extsprintf"."1.0.2" =
-    self.by-version."extsprintf"."1.0.2";
-  by-version."extsprintf"."1.0.2" = self.buildNodePackage {
-    name = "extsprintf-1.0.2";
-    version = "1.0.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz";
-      name = "extsprintf-1.0.2.tgz";
-      sha1 = "e1080e0658e300b06294990cc70e1502235fd550";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."feedparser"."*" =
-    self.by-version."feedparser"."2.1.0";
-  by-version."feedparser"."2.1.0" = self.buildNodePackage {
-    name = "feedparser-2.1.0";
-    version = "2.1.0";
-    bin = true;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/feedparser/-/feedparser-2.1.0.tgz";
-      name = "feedparser-2.1.0.tgz";
-      sha1 = "4cd98bf04e18db5b8644f91e98da89dd179f1fe7";
-    };
-    deps = {
-      "addressparser-1.0.1" = self.by-version."addressparser"."1.0.1";
-      "array-indexofobject-0.0.1" = self.by-version."array-indexofobject"."0.0.1";
-      "lodash.assign-4.2.0" = self.by-version."lodash.assign"."4.2.0";
-      "lodash.get-4.4.2" = self.by-version."lodash.get"."4.4.2";
-      "lodash.has-4.5.2" = self.by-version."lodash.has"."4.5.2";
-      "lodash.uniq-4.5.0" = self.by-version."lodash.uniq"."4.5.0";
-      "readable-stream-2.2.2" = self.by-version."readable-stream"."2.2.2";
-      "sax-1.2.1" = self.by-version."sax"."1.2.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "feedparser" = self.by-version."feedparser"."2.1.0";
-  by-spec."forever-agent"."~0.6.1" =
-    self.by-version."forever-agent"."0.6.1";
-  by-version."forever-agent"."0.6.1" = self.buildNodePackage {
-    name = "forever-agent-0.6.1";
-    version = "0.6.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz";
-      name = "forever-agent-0.6.1.tgz";
-      sha1 = "fbc71f0c41adeb37f96c577ad1ed42d8fdacca91";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."form-data"."*" =
-    self.by-version."form-data"."2.1.2";
-  by-version."form-data"."2.1.2" = self.buildNodePackage {
-    name = "form-data-2.1.2";
-    version = "2.1.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/form-data/-/form-data-2.1.2.tgz";
-      name = "form-data-2.1.2.tgz";
-      sha1 = "89c3534008b97eada4cbb157d58f6f5df025eae4";
-    };
-    deps = {
-      "asynckit-0.4.0" = self.by-version."asynckit"."0.4.0";
-      "combined-stream-1.0.5" = self.by-version."combined-stream"."1.0.5";
-      "mime-types-2.1.14" = self.by-version."mime-types"."2.1.14";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "form-data" = self.by-version."form-data"."2.1.2";
-  by-spec."form-data"."~2.1.1" =
-    self.by-version."form-data"."2.1.2";
-  by-spec."generate-function"."^2.0.0" =
-    self.by-version."generate-function"."2.0.0";
-  by-version."generate-function"."2.0.0" = self.buildNodePackage {
-    name = "generate-function-2.0.0";
-    version = "2.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz";
-      name = "generate-function-2.0.0.tgz";
-      sha1 = "6858fe7c0969b7d4e9093337647ac79f60dfbe74";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."generate-object-property"."^1.1.0" =
-    self.by-version."generate-object-property"."1.2.0";
-  by-version."generate-object-property"."1.2.0" = self.buildNodePackage {
-    name = "generate-object-property-1.2.0";
-    version = "1.2.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz";
-      name = "generate-object-property-1.2.0.tgz";
-      sha1 = "9c0e1c40308ce804f4783618b937fa88f99d50d0";
-    };
-    deps = {
-      "is-property-1.0.2" = self.by-version."is-property"."1.0.2";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."getpass"."^0.1.1" =
-    self.by-version."getpass"."0.1.6";
-  by-version."getpass"."0.1.6" = self.buildNodePackage {
-    name = "getpass-0.1.6";
-    version = "0.1.6";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/getpass/-/getpass-0.1.6.tgz";
-      name = "getpass-0.1.6.tgz";
-      sha1 = "283ffd9fc1256840875311c1b60e8c40187110e6";
-    };
-    deps = {
-      "assert-plus-1.0.0" = self.by-version."assert-plus"."1.0.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."graceful-readlink".">= 1.0.0" =
-    self.by-version."graceful-readlink"."1.0.1";
-  by-version."graceful-readlink"."1.0.1" = self.buildNodePackage {
-    name = "graceful-readlink-1.0.1";
-    version = "1.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz";
-      name = "graceful-readlink-1.0.1.tgz";
-      sha1 = "4cafad76bc62f02fa039b2f94e9a3dd3a391a725";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."har-validator"."~2.0.6" =
-    self.by-version."har-validator"."2.0.6";
-  by-version."har-validator"."2.0.6" = self.buildNodePackage {
-    name = "har-validator-2.0.6";
-    version = "2.0.6";
-    bin = true;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz";
-      name = "har-validator-2.0.6.tgz";
-      sha1 = "cdcbc08188265ad119b6a5a7c8ab70eecfb5d27d";
-    };
-    deps = {
-      "chalk-1.1.3" = self.by-version."chalk"."1.1.3";
-      "commander-2.9.0" = self.by-version."commander"."2.9.0";
-      "is-my-json-valid-2.15.0" = self.by-version."is-my-json-valid"."2.15.0";
-      "pinkie-promise-2.0.1" = self.by-version."pinkie-promise"."2.0.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."has-ansi"."^2.0.0" =
-    self.by-version."has-ansi"."2.0.0";
-  by-version."has-ansi"."2.0.0" = self.buildNodePackage {
-    name = "has-ansi-2.0.0";
-    version = "2.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz";
-      name = "has-ansi-2.0.0.tgz";
-      sha1 = "34f5049ce1ecdf2b0649af3ef24e45ed35416d91";
-    };
-    deps = {
-      "ansi-regex-2.1.1" = self.by-version."ansi-regex"."2.1.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."hawk"."~3.1.3" =
-    self.by-version."hawk"."3.1.3";
-  by-version."hawk"."3.1.3" = self.buildNodePackage {
-    name = "hawk-3.1.3";
-    version = "3.1.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz";
-      name = "hawk-3.1.3.tgz";
-      sha1 = "078444bd7c1640b0fe540d2c9b73d59678e8e1c4";
-    };
-    deps = {
-      "hoek-2.16.3" = self.by-version."hoek"."2.16.3";
-      "boom-2.10.1" = self.by-version."boom"."2.10.1";
-      "cryptiles-2.0.5" = self.by-version."cryptiles"."2.0.5";
-      "sntp-1.0.9" = self.by-version."sntp"."1.0.9";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."hoek"."2.x.x" =
-    self.by-version."hoek"."2.16.3";
-  by-version."hoek"."2.16.3" = self.buildNodePackage {
-    name = "hoek-2.16.3";
-    version = "2.16.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz";
-      name = "hoek-2.16.3.tgz";
-      sha1 = "20bb7403d3cea398e91dc4710a8ff1b8274a25ed";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."http-signature"."~1.1.0" =
-    self.by-version."http-signature"."1.1.1";
-  by-version."http-signature"."1.1.1" = self.buildNodePackage {
-    name = "http-signature-1.1.1";
-    version = "1.1.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz";
-      name = "http-signature-1.1.1.tgz";
-      sha1 = "df72e267066cd0ac67fb76adf8e134a8fbcf91bf";
-    };
-    deps = {
-      "assert-plus-0.2.0" = self.by-version."assert-plus"."0.2.0";
-      "jsprim-1.3.1" = self.by-version."jsprim"."1.3.1";
-      "sshpk-1.10.2" = self.by-version."sshpk"."1.10.2";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."iconv"."~2.2.1" =
-    self.by-version."iconv"."2.2.1";
-  by-version."iconv"."2.2.1" = self.buildNodePackage {
-    name = "iconv-2.2.1";
-    version = "2.2.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/iconv/-/iconv-2.2.1.tgz";
-      name = "iconv-2.2.1.tgz";
-      sha1 = "39b13fdd98987d26aef26c0a2f2a900911fa4584";
-    };
-    deps = {
-      "nan-2.5.1" = self.by-version."nan"."2.5.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."inherits"."~2.0.1" =
-    self.by-version."inherits"."2.0.3";
-  by-version."inherits"."2.0.3" = self.buildNodePackage {
-    name = "inherits-2.0.3";
-    version = "2.0.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz";
-      name = "inherits-2.0.3.tgz";
-      sha1 = "633c2c83e3da42a502f52466022480f4208261de";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."irc"."*" =
-    self.by-version."irc"."0.5.2";
-  by-version."irc"."0.5.2" = self.buildNodePackage {
-    name = "irc-0.5.2";
-    version = "0.5.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/irc/-/irc-0.5.2.tgz";
-      name = "irc-0.5.2.tgz";
-      sha1 = "3714f4768365a96d0b2f776bc91166beb2464bbc";
-    };
-    deps = {
-      "irc-colors-1.3.1" = self.by-version."irc-colors"."1.3.1";
-    };
-    optionalDependencies = {
-      "iconv-2.2.1" = self.by-version."iconv"."2.2.1";
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "irc" = self.by-version."irc"."0.5.2";
-  by-spec."irc-colors"."^1.1.0" =
-    self.by-version."irc-colors"."1.3.1";
-  by-version."irc-colors"."1.3.1" = self.buildNodePackage {
-    name = "irc-colors-1.3.1";
-    version = "1.3.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/irc-colors/-/irc-colors-1.3.1.tgz";
-      name = "irc-colors-1.3.1.tgz";
-      sha1 = "a6fccee5d9ecdc010c2b1cde3fbdff1f7134aff6";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."is-my-json-valid"."^2.12.4" =
-    self.by-version."is-my-json-valid"."2.15.0";
-  by-version."is-my-json-valid"."2.15.0" = self.buildNodePackage {
-    name = "is-my-json-valid-2.15.0";
-    version = "2.15.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.15.0.tgz";
-      name = "is-my-json-valid-2.15.0.tgz";
-      sha1 = "936edda3ca3c211fd98f3b2d3e08da43f7b2915b";
-    };
-    deps = {
-      "generate-function-2.0.0" = self.by-version."generate-function"."2.0.0";
-      "generate-object-property-1.2.0" = self.by-version."generate-object-property"."1.2.0";
-      "jsonpointer-4.0.1" = self.by-version."jsonpointer"."4.0.1";
-      "xtend-4.0.1" = self.by-version."xtend"."4.0.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."is-property"."^1.0.0" =
-    self.by-version."is-property"."1.0.2";
-  by-version."is-property"."1.0.2" = self.buildNodePackage {
-    name = "is-property-1.0.2";
-    version = "1.0.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz";
-      name = "is-property-1.0.2.tgz";
-      sha1 = "57fe1c4e48474edd65b09911f26b1cd4095dda84";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."is-typedarray"."~1.0.0" =
-    self.by-version."is-typedarray"."1.0.0";
-  by-version."is-typedarray"."1.0.0" = self.buildNodePackage {
-    name = "is-typedarray-1.0.0";
-    version = "1.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz";
-      name = "is-typedarray-1.0.0.tgz";
-      sha1 = "e479c80858df0c1b11ddda6940f96011fcda4a9a";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."isarray"."~1.0.0" =
-    self.by-version."isarray"."1.0.0";
-  by-version."isarray"."1.0.0" = self.buildNodePackage {
-    name = "isarray-1.0.0";
-    version = "1.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz";
-      name = "isarray-1.0.0.tgz";
-      sha1 = "bb935d48582cba168c06834957a54a3e07124f11";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."isstream"."~0.1.2" =
-    self.by-version."isstream"."0.1.2";
-  by-version."isstream"."0.1.2" = self.buildNodePackage {
-    name = "isstream-0.1.2";
-    version = "0.1.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz";
-      name = "isstream-0.1.2.tgz";
-      sha1 = "47e63f7af55afa6f92e1500e690eb8b8529c099a";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."jodid25519"."^1.0.0" =
-    self.by-version."jodid25519"."1.0.2";
-  by-version."jodid25519"."1.0.2" = self.buildNodePackage {
-    name = "jodid25519-1.0.2";
-    version = "1.0.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/jodid25519/-/jodid25519-1.0.2.tgz";
-      name = "jodid25519-1.0.2.tgz";
-      sha1 = "06d4912255093419477d425633606e0e90782967";
-    };
-    deps = {
-      "jsbn-0.1.0" = self.by-version."jsbn"."0.1.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."jsbn"."~0.1.0" =
-    self.by-version."jsbn"."0.1.0";
-  by-version."jsbn"."0.1.0" = self.buildNodePackage {
-    name = "jsbn-0.1.0";
-    version = "0.1.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/jsbn/-/jsbn-0.1.0.tgz";
-      name = "jsbn-0.1.0.tgz";
-      sha1 = "650987da0dd74f4ebf5a11377a2aa2d273e97dfd";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."json-schema"."0.2.3" =
-    self.by-version."json-schema"."0.2.3";
-  by-version."json-schema"."0.2.3" = self.buildNodePackage {
-    name = "json-schema-0.2.3";
-    version = "0.2.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz";
-      name = "json-schema-0.2.3.tgz";
-      sha1 = "b480c892e59a2f05954ce727bd3f2a4e882f9e13";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."json-stringify-safe"."~5.0.1" =
-    self.by-version."json-stringify-safe"."5.0.1";
-  by-version."json-stringify-safe"."5.0.1" = self.buildNodePackage {
-    name = "json-stringify-safe-5.0.1";
-    version = "5.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz";
-      name = "json-stringify-safe-5.0.1.tgz";
-      sha1 = "1296a2d58fd45f19a0f6ce01d65701e2c735b6eb";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."jsonify"."~0.0.0" =
-    self.by-version."jsonify"."0.0.0";
-  by-version."jsonify"."0.0.0" = self.buildNodePackage {
-    name = "jsonify-0.0.0";
-    version = "0.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz";
-      name = "jsonify-0.0.0.tgz";
-      sha1 = "2c74b6ee41d93ca51b7b5aaee8f503631d252a73";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."jsonpointer"."^4.0.0" =
-    self.by-version."jsonpointer"."4.0.1";
-  by-version."jsonpointer"."4.0.1" = self.buildNodePackage {
-    name = "jsonpointer-4.0.1";
-    version = "4.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz";
-      name = "jsonpointer-4.0.1.tgz";
-      sha1 = "4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."jsprim"."^1.2.2" =
-    self.by-version."jsprim"."1.3.1";
-  by-version."jsprim"."1.3.1" = self.buildNodePackage {
-    name = "jsprim-1.3.1";
-    version = "1.3.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/jsprim/-/jsprim-1.3.1.tgz";
-      name = "jsprim-1.3.1.tgz";
-      sha1 = "2a7256f70412a29ee3670aaca625994c4dcff252";
-    };
-    deps = {
-      "extsprintf-1.0.2" = self.by-version."extsprintf"."1.0.2";
-      "json-schema-0.2.3" = self.by-version."json-schema"."0.2.3";
-      "verror-1.3.6" = self.by-version."verror"."1.3.6";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."lodash.assign"."^4.2.0" =
-    self.by-version."lodash.assign"."4.2.0";
-  by-version."lodash.assign"."4.2.0" = self.buildNodePackage {
-    name = "lodash.assign-4.2.0";
-    version = "4.2.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz";
-      name = "lodash.assign-4.2.0.tgz";
-      sha1 = "0d99f3ccd7a6d261d19bdaeb9245005d285808e7";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."lodash.get"."^4.4.2" =
-    self.by-version."lodash.get"."4.4.2";
-  by-version."lodash.get"."4.4.2" = self.buildNodePackage {
-    name = "lodash.get-4.4.2";
-    version = "4.4.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz";
-      name = "lodash.get-4.4.2.tgz";
-      sha1 = "2d177f652fa31e939b4438d5341499dfa3825e99";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."lodash.has"."^4.5.2" =
-    self.by-version."lodash.has"."4.5.2";
-  by-version."lodash.has"."4.5.2" = self.buildNodePackage {
-    name = "lodash.has-4.5.2";
-    version = "4.5.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/lodash.has/-/lodash.has-4.5.2.tgz";
-      name = "lodash.has-4.5.2.tgz";
-      sha1 = "d19f4dc1095058cccbe2b0cdf4ee0fe4aa37c862";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."lodash.uniq"."^4.5.0" =
-    self.by-version."lodash.uniq"."4.5.0";
-  by-version."lodash.uniq"."4.5.0" = self.buildNodePackage {
-    name = "lodash.uniq-4.5.0";
-    version = "4.5.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz";
-      name = "lodash.uniq-4.5.0.tgz";
-      sha1 = "d0225373aeb652adc1bc82e4945339a842754773";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."mime-db"."~1.26.0" =
-    self.by-version."mime-db"."1.26.0";
-  by-version."mime-db"."1.26.0" = self.buildNodePackage {
-    name = "mime-db-1.26.0";
-    version = "1.26.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/mime-db/-/mime-db-1.26.0.tgz";
-      name = "mime-db-1.26.0.tgz";
-      sha1 = "eaffcd0e4fc6935cf8134da246e2e6c35305adff";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."mime-types"."^2.1.12" =
-    self.by-version."mime-types"."2.1.14";
-  by-version."mime-types"."2.1.14" = self.buildNodePackage {
-    name = "mime-types-2.1.14";
-    version = "2.1.14";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/mime-types/-/mime-types-2.1.14.tgz";
-      name = "mime-types-2.1.14.tgz";
-      sha1 = "f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee";
-    };
-    deps = {
-      "mime-db-1.26.0" = self.by-version."mime-db"."1.26.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."mime-types"."~2.1.7" =
-    self.by-version."mime-types"."2.1.14";
-  by-spec."nan"."^2.3.3" =
-    self.by-version."nan"."2.5.1";
-  by-version."nan"."2.5.1" = self.buildNodePackage {
-    name = "nan-2.5.1";
-    version = "2.5.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/nan/-/nan-2.5.1.tgz";
-      name = "nan-2.5.1.tgz";
-      sha1 = "d5b01691253326a97a2bbee9e61c55d8d60351e2";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."nan"."^2.3.5" =
-    self.by-version."nan"."2.5.1";
-  by-spec."oauth-sign"."~0.8.1" =
-    self.by-version."oauth-sign"."0.8.2";
-  by-version."oauth-sign"."0.8.2" = self.buildNodePackage {
-    name = "oauth-sign-0.8.2";
-    version = "0.8.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz";
-      name = "oauth-sign-0.8.2.tgz";
-      sha1 = "46a6ab7f0aead8deae9ec0565780b7d4efeb9d43";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."pinkie"."^2.0.0" =
-    self.by-version."pinkie"."2.0.4";
-  by-version."pinkie"."2.0.4" = self.buildNodePackage {
-    name = "pinkie-2.0.4";
-    version = "2.0.4";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz";
-      name = "pinkie-2.0.4.tgz";
-      sha1 = "72556b80cfa0d48a974e80e77248e80ed4f7f870";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."pinkie-promise"."^2.0.0" =
-    self.by-version."pinkie-promise"."2.0.1";
-  by-version."pinkie-promise"."2.0.1" = self.buildNodePackage {
-    name = "pinkie-promise-2.0.1";
-    version = "2.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz";
-      name = "pinkie-promise-2.0.1.tgz";
-      sha1 = "2135d6dfa7a358c069ac9b178776288228450ffa";
-    };
-    deps = {
-      "pinkie-2.0.4" = self.by-version."pinkie"."2.0.4";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."process-nextick-args"."~1.0.6" =
-    self.by-version."process-nextick-args"."1.0.7";
-  by-version."process-nextick-args"."1.0.7" = self.buildNodePackage {
-    name = "process-nextick-args-1.0.7";
-    version = "1.0.7";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz";
-      name = "process-nextick-args-1.0.7.tgz";
-      sha1 = "150e20b756590ad3f91093f25a4f2ad8bff30ba3";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."punycode"."^1.4.1" =
-    self.by-version."punycode"."1.4.1";
-  by-version."punycode"."1.4.1" = self.buildNodePackage {
-    name = "punycode-1.4.1";
-    version = "1.4.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz";
-      name = "punycode-1.4.1.tgz";
-      sha1 = "c0d5a63b2718800ad8e1eb0fa5269c84dd41845e";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."qs"."~6.3.0" =
-    self.by-version."qs"."6.3.0";
-  by-version."qs"."6.3.0" = self.buildNodePackage {
-    name = "qs-6.3.0";
-    version = "6.3.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/qs/-/qs-6.3.0.tgz";
-      name = "qs-6.3.0.tgz";
-      sha1 = "f403b264f23bc01228c74131b407f18d5ea5d442";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."readable-stream"."^2.2.2" =
-    self.by-version."readable-stream"."2.2.2";
-  by-version."readable-stream"."2.2.2" = self.buildNodePackage {
-    name = "readable-stream-2.2.2";
-    version = "2.2.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/readable-stream/-/readable-stream-2.2.2.tgz";
-      name = "readable-stream-2.2.2.tgz";
-      sha1 = "a9e6fec3c7dda85f8bb1b3ba7028604556fc825e";
-    };
-    deps = {
-      "buffer-shims-1.0.0" = self.by-version."buffer-shims"."1.0.0";
-      "core-util-is-1.0.2" = self.by-version."core-util-is"."1.0.2";
-      "isarray-1.0.0" = self.by-version."isarray"."1.0.0";
-      "inherits-2.0.3" = self.by-version."inherits"."2.0.3";
-      "process-nextick-args-1.0.7" = self.by-version."process-nextick-args"."1.0.7";
-      "string_decoder-0.10.31" = self.by-version."string_decoder"."0.10.31";
-      "util-deprecate-1.0.2" = self.by-version."util-deprecate"."1.0.2";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."request"."*" =
-    self.by-version."request"."2.79.0";
-  by-version."request"."2.79.0" = self.buildNodePackage {
-    name = "request-2.79.0";
-    version = "2.79.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/request/-/request-2.79.0.tgz";
-      name = "request-2.79.0.tgz";
-      sha1 = "4dfe5bf6be8b8cdc37fcf93e04b65577722710de";
-    };
-    deps = {
-      "aws-sign2-0.6.0" = self.by-version."aws-sign2"."0.6.0";
-      "aws4-1.5.0" = self.by-version."aws4"."1.5.0";
-      "caseless-0.11.0" = self.by-version."caseless"."0.11.0";
-      "combined-stream-1.0.5" = self.by-version."combined-stream"."1.0.5";
-      "extend-3.0.0" = self.by-version."extend"."3.0.0";
-      "forever-agent-0.6.1" = self.by-version."forever-agent"."0.6.1";
-      "form-data-2.1.2" = self.by-version."form-data"."2.1.2";
-      "har-validator-2.0.6" = self.by-version."har-validator"."2.0.6";
-      "hawk-3.1.3" = self.by-version."hawk"."3.1.3";
-      "http-signature-1.1.1" = self.by-version."http-signature"."1.1.1";
-      "is-typedarray-1.0.0" = self.by-version."is-typedarray"."1.0.0";
-      "isstream-0.1.2" = self.by-version."isstream"."0.1.2";
-      "json-stringify-safe-5.0.1" = self.by-version."json-stringify-safe"."5.0.1";
-      "mime-types-2.1.14" = self.by-version."mime-types"."2.1.14";
-      "oauth-sign-0.8.2" = self.by-version."oauth-sign"."0.8.2";
-      "qs-6.3.0" = self.by-version."qs"."6.3.0";
-      "stringstream-0.0.5" = self.by-version."stringstream"."0.0.5";
-      "tough-cookie-2.3.2" = self.by-version."tough-cookie"."2.3.2";
-      "tunnel-agent-0.4.3" = self.by-version."tunnel-agent"."0.4.3";
-      "uuid-3.0.1" = self.by-version."uuid"."3.0.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "request" = self.by-version."request"."2.79.0";
-  by-spec."sax"."^1.2.1" =
-    self.by-version."sax"."1.2.1";
-  by-version."sax"."1.2.1" = self.buildNodePackage {
-    name = "sax-1.2.1";
-    version = "1.2.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz";
-      name = "sax-1.2.1.tgz";
-      sha1 = "7b8e656190b228e81a66aea748480d828cd2d37a";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."shell-quote"."*" =
-    self.by-version."shell-quote"."1.6.1";
-  by-version."shell-quote"."1.6.1" = self.buildNodePackage {
-    name = "shell-quote-1.6.1";
-    version = "1.6.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz";
-      name = "shell-quote-1.6.1.tgz";
-      sha1 = "f4781949cce402697127430ea3b3c5476f481767";
-    };
-    deps = {
-      "jsonify-0.0.0" = self.by-version."jsonify"."0.0.0";
-      "array-filter-0.0.1" = self.by-version."array-filter"."0.0.1";
-      "array-reduce-0.0.0" = self.by-version."array-reduce"."0.0.0";
-      "array-map-0.0.0" = self.by-version."array-map"."0.0.0";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  "shell-quote" = self.by-version."shell-quote"."1.6.1";
-  by-spec."sntp"."1.x.x" =
-    self.by-version."sntp"."1.0.9";
-  by-version."sntp"."1.0.9" = self.buildNodePackage {
-    name = "sntp-1.0.9";
-    version = "1.0.9";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz";
-      name = "sntp-1.0.9.tgz";
-      sha1 = "6541184cc90aeea6c6e7b35e2659082443c66198";
-    };
-    deps = {
-      "hoek-2.16.3" = self.by-version."hoek"."2.16.3";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."sshpk"."^1.7.0" =
-    self.by-version."sshpk"."1.10.2";
-  by-version."sshpk"."1.10.2" = self.buildNodePackage {
-    name = "sshpk-1.10.2";
-    version = "1.10.2";
-    bin = true;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/sshpk/-/sshpk-1.10.2.tgz";
-      name = "sshpk-1.10.2.tgz";
-      sha1 = "d5a804ce22695515638e798dbe23273de070a5fa";
-    };
-    deps = {
-      "asn1-0.2.3" = self.by-version."asn1"."0.2.3";
-      "assert-plus-1.0.0" = self.by-version."assert-plus"."1.0.0";
-      "dashdash-1.14.1" = self.by-version."dashdash"."1.14.1";
-      "getpass-0.1.6" = self.by-version."getpass"."0.1.6";
-    };
-    optionalDependencies = {
-      "jsbn-0.1.0" = self.by-version."jsbn"."0.1.0";
-      "tweetnacl-0.14.5" = self.by-version."tweetnacl"."0.14.5";
-      "jodid25519-1.0.2" = self.by-version."jodid25519"."1.0.2";
-      "ecc-jsbn-0.1.1" = self.by-version."ecc-jsbn"."0.1.1";
-      "bcrypt-pbkdf-1.0.1" = self.by-version."bcrypt-pbkdf"."1.0.1";
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."string_decoder"."~0.10.x" =
-    self.by-version."string_decoder"."0.10.31";
-  by-version."string_decoder"."0.10.31" = self.buildNodePackage {
-    name = "string_decoder-0.10.31";
-    version = "0.10.31";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz";
-      name = "string_decoder-0.10.31.tgz";
-      sha1 = "62e203bc41766c6c28c9fc84301dab1c5310fa94";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."stringstream"."~0.0.4" =
-    self.by-version."stringstream"."0.0.5";
-  by-version."stringstream"."0.0.5" = self.buildNodePackage {
-    name = "stringstream-0.0.5";
-    version = "0.0.5";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz";
-      name = "stringstream-0.0.5.tgz";
-      sha1 = "4e484cd4de5a0bbbee18e46307710a8a81621878";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."strip-ansi"."^3.0.0" =
-    self.by-version."strip-ansi"."3.0.1";
-  by-version."strip-ansi"."3.0.1" = self.buildNodePackage {
-    name = "strip-ansi-3.0.1";
-    version = "3.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz";
-      name = "strip-ansi-3.0.1.tgz";
-      sha1 = "6a385fb8853d952d5ff05d0e8aaf94278dc63dcf";
-    };
-    deps = {
-      "ansi-regex-2.1.1" = self.by-version."ansi-regex"."2.1.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."supports-color"."^2.0.0" =
-    self.by-version."supports-color"."2.0.0";
-  by-version."supports-color"."2.0.0" = self.buildNodePackage {
-    name = "supports-color-2.0.0";
-    version = "2.0.0";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz";
-      name = "supports-color-2.0.0.tgz";
-      sha1 = "535d045ce6b6363fa40117084629995e9df324c7";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."tough-cookie"."~2.3.0" =
-    self.by-version."tough-cookie"."2.3.2";
-  by-version."tough-cookie"."2.3.2" = self.buildNodePackage {
-    name = "tough-cookie-2.3.2";
-    version = "2.3.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz";
-      name = "tough-cookie-2.3.2.tgz";
-      sha1 = "f081f76e4c85720e6c37a5faced737150d84072a";
-    };
-    deps = {
-      "punycode-1.4.1" = self.by-version."punycode"."1.4.1";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."tunnel-agent"."~0.4.1" =
-    self.by-version."tunnel-agent"."0.4.3";
-  by-version."tunnel-agent"."0.4.3" = self.buildNodePackage {
-    name = "tunnel-agent-0.4.3";
-    version = "0.4.3";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz";
-      name = "tunnel-agent-0.4.3.tgz";
-      sha1 = "6373db76909fe570e08d73583365ed828a74eeeb";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."tweetnacl"."^0.14.3" =
-    self.by-version."tweetnacl"."0.14.5";
-  by-version."tweetnacl"."0.14.5" = self.buildNodePackage {
-    name = "tweetnacl-0.14.5";
-    version = "0.14.5";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz";
-      name = "tweetnacl-0.14.5.tgz";
-      sha1 = "5ae68177f192d4456269d108afa93ff8743f4f64";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."tweetnacl"."~0.14.0" =
-    self.by-version."tweetnacl"."0.14.5";
-  by-spec."util-deprecate"."~1.0.1" =
-    self.by-version."util-deprecate"."1.0.2";
-  by-version."util-deprecate"."1.0.2" = self.buildNodePackage {
-    name = "util-deprecate-1.0.2";
-    version = "1.0.2";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz";
-      name = "util-deprecate-1.0.2.tgz";
-      sha1 = "450d4dc9fa70de732762fbd2d4a28981419a0ccf";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."uuid"."^3.0.0" =
-    self.by-version."uuid"."3.0.1";
-  by-version."uuid"."3.0.1" = self.buildNodePackage {
-    name = "uuid-3.0.1";
-    version = "3.0.1";
-    bin = true;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/uuid/-/uuid-3.0.1.tgz";
-      name = "uuid-3.0.1.tgz";
-      sha1 = "6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."verror"."1.3.6" =
-    self.by-version."verror"."1.3.6";
-  by-version."verror"."1.3.6" = self.buildNodePackage {
-    name = "verror-1.3.6";
-    version = "1.3.6";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz";
-      name = "verror-1.3.6.tgz";
-      sha1 = "cff5df12946d297d2baaefaa2689e25be01c005c";
-    };
-    deps = {
-      "extsprintf-1.0.2" = self.by-version."extsprintf"."1.0.2";
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-  by-spec."xtend"."^4.0.0" =
-    self.by-version."xtend"."4.0.1";
-  by-version."xtend"."4.0.1" = self.buildNodePackage {
-    name = "xtend-4.0.1";
-    version = "4.0.1";
-    bin = false;
-    src = fetchurl {
-      url = "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz";
-      name = "xtend-4.0.1.tgz";
-      sha1 = "a5c6d532be656e23db820efb943a1f04998d63af";
-    };
-    deps = {
-    };
-    optionalDependencies = {
-    };
-    peerDependencies = [];
-    os = [ ];
-    cpu = [ ];
-  };
-}
diff --git a/krebs/5pkgs/simple/newsbot-js/pkgs.json b/krebs/5pkgs/simple/newsbot-js/pkgs.json
new file mode 100644
index 000000000..95b60854d
--- /dev/null
+++ b/krebs/5pkgs/simple/newsbot-js/pkgs.json
@@ -0,0 +1,7 @@
+[
+  "feedparser",
+  "form-data",
+  "irc",
+  "request",
+  "shell-quote"
+]
diff --git a/krebs/5pkgs/simple/newsbot-js/update.sh b/krebs/5pkgs/simple/newsbot-js/update.sh
new file mode 100755
index 000000000..0c1ecc58c
--- /dev/null
+++ b/krebs/5pkgs/simple/newsbot-js/update.sh
@@ -0,0 +1,2 @@
+node2nix -8 -i pkgs.json -c combine.nix
+rm node-env.nix combine.nix
diff --git a/krebs/5pkgs/simple/pass-otp/default.nix b/krebs/5pkgs/simple/pass-otp/default.nix
new file mode 100644
index 000000000..33411180a
--- /dev/null
+++ b/krebs/5pkgs/simple/pass-otp/default.nix
@@ -0,0 +1,30 @@
+{ stdenv, fetchFromGitHub, oathToolkit }:
+stdenv.mkDerivation rec {
+  name = "pass-otp-${version}";
+  version = "1.1.0";
+
+  src = fetchFromGitHub {
+    owner = "tadfisher";
+    repo = "pass-otp";
+    rev = "v${version}";
+    sha256 = "1cgj4zc8fq88n3h6c0vkv9i5al785mdprpgpbv5m22dz9p1wqvbb";
+  };
+
+  buildInputs = [ oathToolkit ];
+
+  patchPhase = ''
+    sed -i -e 's|OATH=\$(which oathtool)|OATH=${oathToolkit}/bin/oathtool|' otp.bash
+  '';
+
+  installPhase = ''
+    make PREFIX=$out install
+  '';
+
+  meta = with stdenv.lib; {
+    description = "A pass extension for managing one-time-password (OTP) tokens";
+    homepage = https://github.com/tadfisher/pass-otp;
+    license = licenses.gpl3;
+    maintainers = with maintainers; [ jwiegley tadfisher ];
+    platforms = platforms.unix;
+  };
+}
diff --git a/krebs/5pkgs/simple/pass/default.nix b/krebs/5pkgs/simple/pass/default.nix
new file mode 100644
index 000000000..3b6928087
--- /dev/null
+++ b/krebs/5pkgs/simple/pass/default.nix
@@ -0,0 +1,121 @@
+{ stdenv, lib, fetchurl, fetchFromGitHub
+, coreutils, gnused, getopt, git, tree, gnupg, which, procps, qrencode
+, makeWrapper
+
+, pass-otp
+
+, xclip ? null, xdotool ? null, dmenu ? null
+, x11Support ? !stdenv.isDarwin
+, tombPluginSupport ? false, tomb
+}:
+
+with lib;
+
+assert x11Support -> xclip != null
+                  && xdotool != null
+                  && dmenu != null;
+
+let
+  plugins = map (p: (fetchFromGitHub {
+    owner  = "roddhjav";
+    repo   = "pass-${p.name}";
+    inherit (p) rev sha256;
+  }))
+  ([
+    { name = "import";
+      rev = "491935bd275f29ceac2b876b3a288011d1ce31e7";
+      sha256 = "02mbh05ab8h7kc30hz718d1d1vkjz43b96c7p0xnd92610d2q66q"; }
+    { name = "update";
+      rev = "cf576c9036fd18efb9ed29e0e9f811207b556fde";
+      sha256 = "1hhbrg6a2walrvla6q4cd3pgrqbcrf9brzjkb748735shxfn52hd"; }
+    ] ++ stdenv.lib.optional tombPluginSupport {
+      name = "tomb";
+      rev = "3368134898a42c1b758fabac625ec240e125c6be";
+      sha256 = "0qqmxfg4w3r088qhlkhs44036mya82vjflsjjhw2hk8y0wd2i6ds"; }
+  );
+
+in stdenv.mkDerivation rec {
+  version = "1.7.1";
+  name    = "pass-${version}";
+
+  src = fetchurl {
+    url    = "http://git.zx2c4.com/password-store/snapshot/${name}.tar.xz";
+    sha256 = "0scqkpll2q8jhzcgcsh9kqz0gwdpvynivqjmmbzax2irjfaiklpn";
+  };
+
+  patches = [ ./set-correct-program-name-for-sleep.patch
+            ] ++ stdenv.lib.optional stdenv.isDarwin ./no-darwin-getopt.patch;
+
+  nativeBuildInputs = [ makeWrapper ];
+
+  installFlags = [ "PREFIX=$(out)" "WITH_ALLCOMP=yes" ];
+
+  postInstall = ''
+    # plugins
+    ${stdenv.lib.concatStringsSep "\n" (map (plugin: ''
+      pushd ${plugin}
+      PREFIX=$out make install
+      popd
+    '') plugins)}
+
+    ln -s \
+        ${pass-otp}/lib/password-store/extensions/otp.bash \
+        $out/lib/password-store/extensions/
+
+    ln -s \
+        ${pass-otp}/share/man/man1/pass-otp.1.gz \
+        $out/share/man/man1/
+
+    # Install Emacs Mode. NOTE: We can't install the necessary
+    # dependencies (s.el and f.el) here. The user has to do this
+    # himself.
+    mkdir -p "$out/share/emacs/site-lisp"
+    cp "contrib/emacs/password-store.el" "$out/share/emacs/site-lisp/"
+  '' + optionalString x11Support ''
+    cp "contrib/dmenu/passmenu" "$out/bin/"
+  '';
+
+  wrapperPath = with stdenv.lib; makeBinPath ([
+    coreutils
+    getopt
+    git
+    gnupg
+    gnused
+    tree
+    which
+    qrencode
+  ] ++ optional tombPluginSupport tomb
+    ++ optional stdenv.isLinux procps
+    ++ ifEnable x11Support [ dmenu xclip xdotool ]);
+
+  postFixup = ''
+    # Fix program name in --help
+    substituteInPlace $out/bin/pass \
+      --replace 'PROGRAM="''${0##*/}"' "PROGRAM=pass"
+
+    # Ensure all dependencies are in PATH
+    wrapProgram $out/bin/pass \
+      --prefix PATH : "${wrapperPath}"
+  '' + stdenv.lib.optionalString x11Support ''
+    # We just wrap passmenu with the same PATH as pass. It doesn't
+    # need all the tools in there but it doesn't hurt either.
+    wrapProgram $out/bin/passmenu \
+      --prefix PATH : "$out/bin:${wrapperPath}"
+  '';
+
+  meta = with stdenv.lib; {
+    description = "Stores, retrieves, generates, and synchronizes passwords securely";
+    homepage    = https://www.passwordstore.org/;
+    license     = licenses.gpl2Plus;
+    maintainers = with maintainers; [ lovek323 the-kenny fpletz ];
+    platforms   = platforms.unix;
+
+    longDescription = ''
+      pass is a very simple password store that keeps passwords inside gpg2
+      encrypted files inside a simple directory tree residing at
+      ~/.password-store. The pass utility provides a series of commands for
+      manipulating the password store, allowing the user to add, remove, edit,
+      synchronize, generate, and manipulate passwords.
+    '';
+  };
+}
diff --git a/krebs/5pkgs/simple/pass/no-darwin-getopt.patch b/krebs/5pkgs/simple/pass/no-darwin-getopt.patch
new file mode 100644
index 000000000..e8f7e138f
--- /dev/null
+++ b/krebs/5pkgs/simple/pass/no-darwin-getopt.patch
@@ -0,0 +1,9 @@
+diff -Naur password-store-1.6.5-orig/src/platform/darwin.sh password-store-1.6.5/src/platform/darwin.sh
+--- password-store-1.6.5-orig/src/platform/darwin.sh	2015-01-28 16:43:02.000000000 +0000
++++ password-store-1.6.5/src/platform/darwin.sh	2015-02-15 16:09:02.000000000 +0000
+@@ -31,5 +31,4 @@
+ 	mount -t hfs -o noatime -o nobrowse "$DARWIN_RAMDISK_DEV" "$SECURE_TMPDIR" || die "Error: could not mount filesystem on ramdisk."
+ }
+ 
+-GETOPT="$(brew --prefix gnu-getopt 2>/dev/null || { which port &>/dev/null && echo /opt/local; } || echo /usr/local)/bin/getopt"
+ SHRED="srm -f -z"
diff --git a/krebs/5pkgs/simple/pass/rofi-pass.nix b/krebs/5pkgs/simple/pass/rofi-pass.nix
new file mode 100644
index 000000000..61f51973e
--- /dev/null
+++ b/krebs/5pkgs/simple/pass/rofi-pass.nix
@@ -0,0 +1,57 @@
+{ stdenv, fetchFromGitHub, pass, rofi, coreutils, utillinux, xdotool, gnugrep
+, libnotify, pwgen, findutils, gawk, gnused, xclip, makeWrapper
+}:
+
+stdenv.mkDerivation rec {
+  name = "rofi-pass-${version}";
+  version = "1.5.3";
+
+  src = fetchFromGitHub {
+    owner = "carnager";
+    repo = "rofi-pass";
+    rev = version;
+    sha256 = "1fn1j2rf3abc5qb44zfc8z8ffw6rva4xfp7597hwr1g3szacazpq";
+  };
+
+  buildInputs = [ makeWrapper ];
+
+  dontBuild = true;
+
+  installPhase = ''
+    mkdir -p $out/bin
+    cp -a rofi-pass $out/bin/rofi-pass
+
+    mkdir -p $out/share/doc/rofi-pass/
+    cp -a config.example $out/share/doc/rofi-pass/config.example
+  '';
+
+  wrapperPath = with stdenv.lib; makeBinPath [
+    coreutils
+    findutils
+    gawk
+    gnugrep
+    gnused
+    libnotify
+    pass
+    pwgen
+    rofi
+    utillinux
+    xclip
+    xdotool
+  ];
+
+  fixupPhase = ''
+    patchShebangs $out/bin
+
+    wrapProgram $out/bin/rofi-pass \
+      --prefix PATH : "${wrapperPath}"
+  '';
+
+  meta = {
+    description = "A script to make rofi work with password-store";
+    homepage = https://github.com/carnager/rofi-pass;
+    maintainers = with stdenv.lib.maintainers; [ the-kenny garbas ];
+    license = stdenv.lib.licenses.gpl3;
+    platforms = with stdenv.lib.platforms; linux;
+  };
+}
diff --git a/krebs/5pkgs/simple/pass/set-correct-program-name-for-sleep.patch b/krebs/5pkgs/simple/pass/set-correct-program-name-for-sleep.patch
new file mode 100644
index 000000000..782e06e20
--- /dev/null
+++ b/krebs/5pkgs/simple/pass/set-correct-program-name-for-sleep.patch
@@ -0,0 +1,69 @@
+From 25b44e00ed5df8ffe2782d38ad5cd9f514379599 Mon Sep 17 00:00:00 2001
+From: "Andrew R. M" <andrewmiller237@gmail.com>
+Date: Sat, 8 Apr 2017 13:50:01 -0400
+Subject: [PATCH] Patch the clip() function to work even when using
+ single-binary coreutils
+
+---
+ src/password-store.sh  | 4 ++--
+ src/platform/cygwin.sh | 4 ++--
+ src/platform/darwin.sh | 4 ++--
+ 3 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/src/password-store.sh b/src/password-store.sh
+index 6a4172d..4dbd6b8 100755
+--- a/src/password-store.sh
++++ b/src/password-store.sh
+@@ -155,11 +155,11 @@ clip() {
+ 	# variable. Specifically, it cannot store nulls nor (non-trivally) store
+ 	# trailing new lines.
+ 	local sleep_argv0="password store sleep on display $DISPLAY"
+-	pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5
++	pkill -P $(pgrep -f "^$sleep_argv0") 2>/dev/null && sleep 0.5
+ 	local before="$(xclip -o -selection "$X_SELECTION" 2>/dev/null | base64)"
+ 	echo -n "$1" | xclip -selection "$X_SELECTION" || die "Error: Could not copy data to the clipboard"
+ 	(
+-		( exec -a "$sleep_argv0" bash <<<"trap 'kill %1' TERM; sleep '$CLIP_TIME' & wait" )
++		( exec -a "$sleep_argv0" bash <(echo trap 'kill %1' TERM\; sleep "$CLIP_TIME & wait") )
+ 		local now="$(xclip -o -selection "$X_SELECTION" | base64)"
+ 		[[ $now != $(echo -n "$1" | base64) ]] && before="$now"
+ 
+diff --git a/src/platform/cygwin.sh b/src/platform/cygwin.sh
+index 6e5dd86..f3574c4 100644
+--- a/src/platform/cygwin.sh
++++ b/src/platform/cygwin.sh
+@@ -3,11 +3,11 @@
+ 
+ clip() {
+ 	local sleep_argv0="password store sleep on display $DISPLAY"
+-	pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5
++	pkill -P $(pgrep -f "^$sleep_argv0") 2>/dev/null && sleep 0.5
+ 	local before="$(base64 < /dev/clipboard)"
+ 	echo -n "$1" > /dev/clipboard
+ 	(
+-		( exec -a "$sleep_argv0" sleep "$CLIP_TIME" )
++		( exec -a "$sleep_argv0" bash <(echo sleep "$CLIP_TIME") )
+ 		local now="$(base64 < /dev/clipboard)"
+ 		[[ $now != $(echo -n "$1" | base64) ]] && before="$now"
+ 		echo "$before" | base64 -d > /dev/clipboard
+diff --git a/src/platform/darwin.sh b/src/platform/darwin.sh
+index 86eb325..deb04c4 100644
+--- a/src/platform/darwin.sh
++++ b/src/platform/darwin.sh
+@@ -3,11 +3,11 @@
+ 
+ clip() {
+ 	local sleep_argv0="password store sleep for user $(id -u)"
+-	pkill -f "^$sleep_argv0" 2>/dev/null && sleep 0.5
++	pkill -P $(pgrep -f "^$sleep_argv0") 2>/dev/null && sleep 0.5
+ 	local before="$(pbpaste | openssl base64)"
+ 	echo -n "$1" | pbcopy
+ 	(
+-		( exec -a "$sleep_argv0" sleep "$CLIP_TIME" )
++		( exec -a "$sleep_argv0" bash <(echo sleep "$CLIP_TIME") )
+ 		local now="$(pbpaste | openssl base64)"
+ 		[[ $now != $(echo -n "$1" | openssl base64) ]] && before="$now"
+ 		echo "$before" | openssl base64 -d | pbcopy
+-- 
+2.12.2
+
diff --git a/krebs/5pkgs/simple/pssh/default.nix b/krebs/5pkgs/simple/pssh/default.nix
deleted file mode 100644
index 2676af0cf..000000000
--- a/krebs/5pkgs/simple/pssh/default.nix
+++ /dev/null
@@ -1,36 +0,0 @@
-{ writeDashBin }:
-
-writeDashBin "pssh" ''
-  set -efu
-  case ''${1-} in
-
-  # TODO create plog with -o json | jq ... | map date
-
-  # usage: pssh {-j,--journal} host...
-  # Follow journal at each host.
-  -j|--journal)
-    shift
-    "$0" journalctl -n0 -ocat --follow --all ::: "$@" \
-      | while read line; do
-          printf '%s %s\n' "$(date --rfc-3339=s)" "$line"
-        done
-    ;;
-
-  -*)
-    echo $0: unknown option: $1 >&2
-    exit 1
-    ;;
-
-  # usage: pssh command [arg...] ::: host...
-  # Run command at each host.
-  *)
-    exec parallel \
-      --line-buffer \
-      -j0 \
-      --no-notice \
-      --tagstring {} \
-      ssh -T {} "$@"
-    ;;
-
-  esac
-''
diff --git a/krebs/5pkgs/simple/stockholm/default.nix b/krebs/5pkgs/simple/stockholm/default.nix
index 4d15e7ac2..9afe79510 100644
--- a/krebs/5pkgs/simple/stockholm/default.nix
+++ b/krebs/5pkgs/simple/stockholm/default.nix
@@ -9,7 +9,6 @@
   #
 
   cmds.deploy = pkgs.withGetopt {
-    diff = { default = /* sh */ "false"; switch = true; };
     force-populate = { default = /* sh */ "false"; switch = true; };
     quiet = { default = /* sh */ "false"; switch = true; };
     source_file = {
@@ -25,65 +24,6 @@
     . ${init.env}
     . ${init.proxy "deploy" opts}
 
-    if \test ${opts.diff.ref} = true; then
-
-      system_profile=/nix/var/nix/profiles/system
-      system_drv_cur=/etc/system.drv
-
-      system_drv_new=$(
-        ${pkgs.nix}/bin/nix-instantiate \
-            -Q \
-            -I "$target_path" \
-            -E '
-              (import <nixpkgs/nixos/lib/eval-config.nix> {
-                modules = [ <nixos-config> ];
-              }).config.system.build.toplevel
-            '
-      )
-
-      if \test -e "$system_drv_cur"; then
-
-        system_drv_cur_c=$(${pkgs.coreutils}/bin/readlink -f "$system_drv_cur")
-        system_drv_new_c=$(${pkgs.coreutils}/bin/readlink -f "$system_drv_new")
-
-        if \test "$system_drv_cur_c" = "$system_drv_new_c"; then
-          echo "$0: system up to date" >&2
-          exit 0
-        fi
-
-        system_drv_cur=$system_drv_cur_c \
-        system_drv_new=$system_drv_new_c \
-        ${pkgs.utillinux}/bin/script \
-            --command '
-              ${pkgs.haskellPackages.nix-diff}/bin/nix-diff \
-                  "$system_drv_cur" "$system_drv_new"
-            ' \
-            --quiet \
-            --return \
-            /dev/null
-
-        printf 'deploy? [N/y] ' >&2
-        read -r REPLY
-        if \test "$REPLY" != y; then
-          echo "$0: abort!" >&2
-          exit 1
-        fi
-      else
-        echo "$0: --${opts.diff.long} has no effect because "$system_drv_cur" doesn't exist" >&2
-      fi
-
-      new_system=$(${pkgs.nix}/bin/nix-store --realize "$system_drv_new")
-
-      ${pkgs.nix}/bin/nix-env -p "$system_profile" --set "$new_system"
-      PATH=${lib.makeBinPath [
-        pkgs.systemd
-      ]} \
-      "$system_profile"/bin/switch-to-configuration switch
-
-      ${pkgs.coreutils}/bin/ln -fns "$system_drv_new" "$system_drv_cur"
-      exit
-    fi
-
     # Use system's nixos-rebuild, which is not self-contained
     export PATH=/run/current-system/sw/bin
     exec ${utils.with-whatsupnix} \
diff --git a/krebs/5pkgs/simple/ucspi-tcp/chmod.patch b/krebs/5pkgs/simple/ucspi-tcp/chmod.patch
deleted file mode 100644
index dd6933208..000000000
--- a/krebs/5pkgs/simple/ucspi-tcp/chmod.patch
+++ /dev/null
@@ -1,15 +0,0 @@
-diff --git a/hier.c b/hier.c
-index 5663ada..1d73b84 100644
---- a/hier.c
-+++ b/hier.c
-@@ -2,8 +2,8 @@
- 
- void hier()
- {
--  h(auto_home,-1,-1,02755);
--  d(auto_home,"bin",-1,-1,02755);
-+  h(auto_home,-1,-1,0755);
-+  d(auto_home,"bin",-1,-1,0755);
- 
-   c(auto_home,"bin","tcpserver",-1,-1,0755);
-   c(auto_home,"bin","tcprules",-1,-1,0755);
diff --git a/krebs/5pkgs/simple/ucspi-tcp/default.nix b/krebs/5pkgs/simple/ucspi-tcp/default.nix
deleted file mode 100644
index 3b043be06..000000000
--- a/krebs/5pkgs/simple/ucspi-tcp/default.nix
+++ /dev/null
@@ -1,86 +0,0 @@
-{ stdenv, fetchurl }:
-
-stdenv.mkDerivation rec {
-  name = "ucspi-tcp-0.88";
-
-  src = fetchurl {
-    url = "http://cr.yp.to/ucspi-tcp/${name}.tar.gz";
-    sha256 = "171yl9kfm8w7l17dfxild99mbf877a9k5zg8yysgb1j8nz51a1ja";
-  };
-
-  # Plain upstream tarball doesn't build, get patches from Debian
-  patches = [
-    (fetchurl {
-      url = "http://ftp.de.debian.org/debian/pool/main/u/ucspi-tcp/ucspi-tcp_0.88-3.diff.gz";
-      sha256 = "0mzmhz8hjkrs0khmkzs5i0s1kgmgaqz07h493bd5jj5fm5njxln6";
-    })
-    ./chmod.patch
-  ];
-
-  # Apply Debian patches
-  postPatch = ''
-    for fname in debian/diff/*.diff; do
-        echo "Applying patch $fname"
-        patch < "$fname"
-    done
-  '';
-
-  # The build system is weird; 'make install' doesn't install anything, instead
-  # it builds an executable called ./install (from C code) which installs
-  # binaries to the directory given on line 1 in ./conf-home.
-  #
-  # Also, assume getgroups and setgroups work, instead of doing a build time
-  # test that breaks on NixOS (I think because nixbld users lack CAP_SETGID
-  # capability).
-  preBuild = ''
-    echo "$out" > conf-home
-
-    echo "main() { return 0; }" > chkshsgr.c
-  '';
-
-  installPhase = ''
-    mkdir -p "$out/bin"
-    mkdir -p "$out/share/man/man1"
-
-    # run the newly built installer
-    ./install
-
-    # Install Debian man pages (upstream has none)
-    cp debian/ucspi-tcp-man/*.1 "$out/share/man/man1"
-  '';
-
-  meta = with stdenv.lib; {
-    description = "Command-line tools for building TCP client-server applications";
-    longDescription = ''
-      tcpserver waits for incoming connections and, for each connection, runs a
-      program of your choice. Your program receives environment variables
-      showing the local and remote host names, IP addresses, and port numbers.
-
-      tcpserver offers a concurrency limit to protect you from running out of
-      processes and memory. When you are handling 40 (by default) simultaneous
-      connections, tcpserver smoothly defers acceptance of new connections.
-
-      tcpserver also provides TCP access control features, similar to
-      tcp-wrappers/tcpd's hosts.allow but much faster. Its access control rules
-      are compiled into a hashed format with cdb, so it can easily deal with
-      thousands of different hosts.
-
-      This package includes a recordio tool that monitors all the input and
-      output of a server.
-
-      tcpclient makes a TCP connection and runs a program of your choice. It
-      sets up the same environment variables as tcpserver.
-
-      This package includes several sample clients built on top of tcpclient:
-      who@, date@, finger@, http@, tcpcat, and mconnect.
-
-      tcpserver and tcpclient conform to UCSPI, the UNIX Client-Server Program
-      Interface, using the TCP protocol. UCSPI tools are available for several
-      different networks.
-    '';
-    homepage = http://cr.yp.to/ucspi-tcp.html;
-    license = licenses.publicDomain;
-    platforms = platforms.linux;
-    maintainers = [ maintainers.bjornfor ];
-  };
-}
diff --git a/krebs/5pkgs/simple/urlwatch/default.nix b/krebs/5pkgs/simple/urlwatch/default.nix
deleted file mode 100644
index 64f3ad1ac..000000000
--- a/krebs/5pkgs/simple/urlwatch/default.nix
+++ /dev/null
@@ -1,29 +0,0 @@
-{ stdenv, fetchFromGitHub, python3Packages }:
-
-python3Packages.buildPythonApplication rec {
-  name = "urlwatch-${version}";
-  version = "2.8";
-
-  src = fetchFromGitHub {
-    owner  = "thp";
-    repo   = "urlwatch";
-    rev    = version;
-    sha256 = "1nja7n6pc45azd3l1xyvav89855lvcgwabrvf34rps81dbl8cnl4";
-  };
-
-  propagatedBuildInputs = with python3Packages; [
-    appdirs
-    keyring
-    minidb
-    pycodestyle
-    pyyaml
-    requests
-  ];
-
-  meta = with stdenv.lib; {
-    description = "A tool for monitoring webpages for updates";
-    homepage = https://thp.io/2008/urlwatch/;
-    license = licenses.bsd3;
-    maintainers = with maintainers; [ tv ];
-  };
-}
diff --git a/krebs/5pkgs/simple/zandronum-bin/default.nix b/krebs/5pkgs/simple/zandronum-bin/default.nix
deleted file mode 100644
index e97f46add..000000000
--- a/krebs/5pkgs/simple/zandronum-bin/default.nix
+++ /dev/null
@@ -1,83 +0,0 @@
-{ stdenv
-, atk
-, bzip2
-, cairo
-, fetchurl
-, fluidsynth
-, fontconfig
-, freetype
-, gdk_pixbuf
-, glib
-, gtk2
-, libjpeg_turbo
-, mesa_glu
-, mesa_noglu
-, openssl
-, pango
-, SDL
-, zlib
-, makeWrapper
-}:
-
-stdenv.mkDerivation rec {
-  name = "zandronum-3.0";
-
-  src = fetchurl {
-    url = "http://zandronum.com/downloads/testing/3.0/ZandroDev3.0-170205-2117linux-x86_64.tar.bz2";
-    sha256 = "17vrzk0m5b17sp3sqcg57r7812ma97lp3qxn9hmd39fwl1z40fz3";
-  };
-
-  libPath = stdenv.lib.makeLibraryPath [
-    atk
-    bzip2
-    cairo
-    fluidsynth
-    fontconfig
-    freetype
-    gdk_pixbuf
-    glib
-    gtk2
-    libjpeg_turbo
-    mesa_glu
-    mesa_noglu
-    openssl
-    pango
-    SDL
-    stdenv.cc.cc
-    zlib
-  ];
-
-  nativeBuildInputs = [ makeWrapper ];
-
-  phases = [ "unpackPhase" "installPhase" ];
-
-  sourceRoot = ".";
-
-  installPhase = ''
-    mkdir -p $out/bin
-    mkdir -p $out/share/zandronum
-    cp *.so *.pk3 zandronum zandronum-server $out/share/zandronum
-
-    patchelf \
-      --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) \
-      --set-rpath $libPath:$out/share/zandronum \
-      $out/share/zandronum/zandronum
-    patchelf \
-      --set-interpreter $(cat ${stdenv.cc}/nix-support/dynamic-linker) \
-      --set-rpath $libPath \
-      $out/share/zandronum/zandronum-server
-
-    # If we don't set absolute argv0, zandronum.wad file is not found.
-    makeWrapper $out/share/zandronum/zandronum $out/bin/zandronum
-    makeWrapper $out/share/zandronum/zandronum-server $out/bin/zandronum-server
-  '';
-
-  meta = {
-    homepage = http://zandronum.com/;
-    description = "Multiplayer oriented port, based off Skulltag, for Doom and Doom II by id Software. Binary version for online play";
-    maintainers = [ stdenv.lib.maintainers.lassulus ];
-    # Binary version has different version string than source code version.
-    license = stdenv.lib.licenses.unfreeRedistributable;
-    platforms = [ "x86_64-linux" ];
-  };
-}
diff --git a/krebs/5pkgs/writers.nix b/krebs/5pkgs/writers.nix
index a48fc0f87..1939bf854 100644
--- a/krebs/5pkgs/writers.nix
+++ b/krebs/5pkgs/writers.nix
@@ -57,7 +57,8 @@ with import <stockholm/lib>;
       passAsFile = [ "text" ];
     } /* sh */ ''
       PATH=${makeBinPath (with pkgs; [
-        binutils
+        # TODO remove if everyone migrated to 18.03
+        (if hasAttr "binutils-unwrapped" pkgs then binutils-unwrapped else binutils)
         coreutils
         gcc
       ])}
diff --git a/krebs/kops.nix b/krebs/kops.nix
new file mode 100644
index 000000000..abd60ee5a
--- /dev/null
+++ b/krebs/kops.nix
@@ -0,0 +1,64 @@
+{ name }: rec {
+
+  kops = (import <nixpkgs> {}).fetchgit {
+    url = https://cgit.krebsco.de/kops/;
+    rev = "e89cf20d4310070a877c2e24a287659546b561c9";
+    sha256 = "0wg8d80sxa46z4i7ir79sci2hwmv3qskzqdg0si64p6vazy8vckb";
+  };
+
+  lib = import "${kops}/lib";
+
+  # TODO document why pkgs should be used like this
+  pkgs = import "${kops}/pkgs" {};
+
+  krebs-source = {
+    nixpkgs.git = {
+      ref = "b50443b5c4ac0f382c49352a892b9d5d970eb4e7";
+      url = https://github.com/NixOS/nixpkgs;
+    };
+    stockholm.file = toString ../.;
+    stockholm-version.pipe = toString (pkgs.writeDash "${name}-version" ''
+      set -efu
+      cd $HOME/stockholm
+      V=$(${pkgs.coreutils}/bin/date +%y.%m)
+      if test -d .git; then
+        V=$V.git.$(${pkgs.git}/bin/git describe --always --dirty)
+        case $V in (*-dirty)
+          V=$V@''${HOSTNAME-$(${pkgs.nettools}/bin/hostname)}
+        esac
+      fi
+      printf %s "$V"
+    '');
+  };
+
+  source ={ test }: lib.evalSource [
+    krebs-source
+    {
+      nixos-config.symlink = "stockholm/krebs/1systems/${name}/config.nix";
+      secrets =
+        if test
+          then {
+            file = toString <stockholm/krebs/6tests/data/secrets>;
+          }
+          else {
+            pass = {
+              dir = "${lib.getEnv "HOME"}/brain";
+              name = "krebs-secrets/${name}";
+            };
+          }
+        ;
+    }
+  ];
+
+  # usage: $(nix-build --no-out-link --argstr name HOSTNAME -A deploy)
+  deploy = pkgs.kops.writeDeploy "${name}-deploy" {
+    source = source { test = false; };
+    target = "root@${name}/var/src";
+  };
+
+  # usage: $(nix-build --no-out-link --argstr name HOSTNAME -A test)
+  test = pkgs.kops.writeTest "${name}-test" {
+    source = source { test = true; };
+    target = "${lib.getEnv "HOME"}/tmp/${name}-kops-test-src";
+  };
+}
diff --git a/krebs/source.nix b/krebs/source.nix
index 7e0ea7e47..3ee12b37f 100644
--- a/krebs/source.nix
+++ b/krebs/source.nix
@@ -22,10 +22,7 @@ in
       };
       stockholm.file = toString <stockholm>;
       stockholm-version.pipe = "${pkgs.stockholm}/bin/get-version";
-      nixpkgs.git = {
-        url = https://github.com/NixOS/nixpkgs;
-        ref = "c5bc83b503dfb29eb27c1deb0268f15c1858e7ce"; # nixos-17.09 @ 2018-02-27
-      };
+      nixpkgs = (import ./kops.nix { name = ""; }).krebs-source.nixpkgs;
     }
     override
   ]
diff --git a/lass/1systems/cabal/config.nix b/lass/1systems/cabal/config.nix
new file mode 100644
index 000000000..88f642d6b
--- /dev/null
+++ b/lass/1systems/cabal/config.nix
@@ -0,0 +1,34 @@
+{ config, pkgs, ... }:
+
+{
+  imports = [
+    <stockholm/lass>
+    <stockholm/lass/2configs/hw/x220.nix>
+    <stockholm/lass/2configs/boot/stock-x220.nix>
+
+    <stockholm/lass/2configs/mouse.nix>
+    <stockholm/lass/2configs/retiolum.nix>
+    <stockholm/lass/2configs/exim-retiolum.nix>
+    <stockholm/lass/2configs/baseX.nix>
+    <stockholm/lass/2configs/browsers.nix>
+    <stockholm/lass/2configs/programs.nix>
+    <stockholm/lass/2configs/fetchWallpaper.nix>
+    <stockholm/lass/2configs/games.nix>
+    <stockholm/lass/2configs/bitcoin.nix>
+  ];
+
+  krebs.build.host = config.krebs.hosts.cabal;
+
+  #fileSystems = {
+  #  "/bku" = {
+  #    device = "/dev/mapper/pool-bku";
+  #    fsType = "btrfs";
+  #    options = ["defaults" "noatime" "ssd" "compress=lzo"];
+  #  };
+  #};
+
+  #services.udev.extraRules = ''
+  #  SUBSYSTEM=="net", ATTR{address}=="00:24:d7:f0:a0:0c", NAME="wl0"
+  #  SUBSYSTEM=="net", ATTR{address}=="f0:de:f1:71:cb:35", NAME="et0"
+  #'';
+}
diff --git a/lass/1systems/cabal/source.nix b/lass/1systems/cabal/source.nix
new file mode 100644
index 000000000..5d9507f3d
--- /dev/null
+++ b/lass/1systems/cabal/source.nix
@@ -0,0 +1,4 @@
+import <stockholm/lass/source.nix> {
+  name = "cabal";
+  secure = true;
+}
diff --git a/lass/1systems/daedalus/config.nix b/lass/1systems/daedalus/config.nix
index 609fae3c8..c15fcdc21 100644
--- a/lass/1systems/daedalus/config.nix
+++ b/lass/1systems/daedalus/config.nix
@@ -8,9 +8,9 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/boot/coreboot.nix>
 
     <stockholm/lass/2configs/retiolum.nix>
-    <stockholm/lass/2configs/backups.nix>
     <stockholm/lass/2configs/games.nix>
     <stockholm/lass/2configs/steam.nix>
+    <stockholm/lass/2configs/backup.nix>
     {
       # bubsy config
       users.users.bubsy = {
diff --git a/lass/1systems/echelon/config.nix b/lass/1systems/echelon/config.nix
deleted file mode 100644
index 6f96883bf..000000000
--- a/lass/1systems/echelon/config.nix
+++ /dev/null
@@ -1,50 +0,0 @@
-{ config, lib, pkgs, ... }:
-
-let
-  inherit (import <stockholm/lass/4lib> { inherit pkgs lib; }) getDefaultGateway;
-  ip = config.krebs.build.host.nets.internet.ip4.addr;
-in {
-  imports = [
-    <stockholm/lass>
-    <stockholm/lass/2configs/retiolum.nix>
-    <stockholm/lass/2configs/os-templates/CAC-CentOS-7-64bit.nix>
-    <stockholm/lass/2configs/exim-retiolum.nix>
-    <stockholm/lass/2configs/privoxy-retiolum.nix>
-    <stockholm/lass/2configs/git.nix>
-    {
-      networking.interfaces.enp2s1.ip4 = [
-        {
-          address = ip;
-          prefixLength = 24;
-        }
-      ];
-      networking.defaultGateway = getDefaultGateway ip;
-      networking.nameservers = [
-        "8.8.8.8"
-      ];
-
-    }
-    {
-      sound.enable = false;
-    }
-    {
-      users.extraUsers = {
-        satan = {
-          name = "satan";
-          uid = 1338;
-          home = "/home/satan";
-          group = "users";
-          createHome = true;
-          useDefaultShell = true;
-          extraGroups = [
-          ];
-          openssh.authorizedKeys.keys = [
-            "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC+l3ajjOd80uJBM8oHO9HRbtA5hK6hvrpxxnk7qWW7OloT9IXcoM8bbON755vK0O6XyxZo1JZ1SZ7QIaOREGVIRDjcbJbqD3O+nImc6Rzxnrz7hvE+tuav9Yylwcw5HeQi82UIMGTEAwMHwLvsW6R/xyMCuOTbbzo9Ib8vlJ8IPDECY/05RhL7ZYFR0fdphI7jq7PobnO8WEpCZDhMvSYjO9jf3ac53wyghT3gH7AN0cxTR9qgQlPHhTbw+nZEI0sUKtrIhjfVE80wgK3NQXZZj7YAplRs/hYwSi7i8V0+8CBt2epc/5RKnJdDHFQnaTENq9kYQPOpUCP6YUwQIo8X nineinchnade@gmail.com"
-          ];
-        };
-      };
-    }
-  ];
-
-  krebs.build.host = config.krebs.hosts.echelon;
-}
diff --git a/lass/1systems/helios/config.nix b/lass/1systems/helios/config.nix
index c4d99cb2c..557fce1e8 100644
--- a/lass/1systems/helios/config.nix
+++ b/lass/1systems/helios/config.nix
@@ -17,6 +17,7 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/dcso-dev.nix>
     <stockholm/lass/2configs/steam.nix>
     <stockholm/lass/2configs/rtl-sdr.nix>
+    <stockholm/lass/2configs/backup.nix>
     { # automatic hardware detection
       boot.initrd.availableKernelModules = [ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
       boot.kernelModules = [ "kvm-intel" ];
@@ -131,7 +132,7 @@ with import <stockholm/lib>;
   ];
 
   services.xserver.displayManager.sessionCommands = ''
-    ${pkgs.xorg.xrandr}/bin/xrandr --output DP-6 --off --output DP-5 --off --output DP-4 --mode 2560x1440 --pos 3840x0 --rotate left --output DP-3 --off --output DP-2 --primary --mode 3840x2160 --pos 0x400 --rotate normal --output DP-1 --off --output DP-0 --mode 2560x1440 --pos 5280x1120 --rotate normal
+    ${pkgs.xorg.xrandr}/bin/xrandr --output DP-6 --off --output DP-5 --off --output DP-4 --mode 2560x1440 --pos 3840x0 --rotate left --output DP-3 --off --output DP-2 --primary --mode 3840x2160 --scale 0.5x0.5 --pos 0x400 --rotate normal --output DP-1 --off --output DP-0 --mode 2560x1440 --pos 5280x1120 --rotate normal
   '';
 
   networking.hostName = lib.mkForce "BLN02NB0162";
@@ -168,8 +169,6 @@ with import <stockholm/lib>;
     '')
   ];
 
-  lass.screenlock.command = "${pkgs.i3lock}/bin/i3lock -i /home/lass/lock.png -t -f";
-
   programs.adb.enable = true;
   users.users.mainUser.extraGroups = [ "adbusers" "docker" ];
 
diff --git a/lass/1systems/icarus/config.nix b/lass/1systems/icarus/config.nix
index 46dc5e873..b6a0822b9 100644
--- a/lass/1systems/icarus/config.nix
+++ b/lass/1systems/icarus/config.nix
@@ -14,9 +14,9 @@
     <stockholm/lass/2configs/browsers.nix>
     <stockholm/lass/2configs/programs.nix>
     <stockholm/lass/2configs/fetchWallpaper.nix>
-    <stockholm/lass/2configs/backups.nix>
     <stockholm/lass/2configs/games.nix>
     <stockholm/lass/2configs/bitcoin.nix>
+    <stockholm/lass/2configs/backup.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.icarus;
diff --git a/lass/1systems/littleT/config.nix b/lass/1systems/littleT/config.nix
index 7211c78eb..ef19e8d16 100644
--- a/lass/1systems/littleT/config.nix
+++ b/lass/1systems/littleT/config.nix
@@ -8,7 +8,7 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/boot/stock-x220.nix>
 
     <stockholm/lass/2configs/retiolum.nix>
-    <stockholm/lass/2configs/backups.nix>
+    <stockholm/lass/2configs/backup.nix>
     <stockholm/lass/2configs/steam.nix>
     {
       users.users.blacky = {
diff --git a/lass/1systems/mors/config.nix b/lass/1systems/mors/config.nix
index cbb71ab24..f8a16ad2e 100644
--- a/lass/1systems/mors/config.nix
+++ b/lass/1systems/mors/config.nix
@@ -33,6 +33,7 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/ableton.nix>
     <stockholm/lass/2configs/dunst.nix>
     <stockholm/lass/2configs/rtl-sdr.nix>
+    <stockholm/lass/2configs/backup.nix>
     {
       #risk of rain port
       krebs.iptables.tables.filter.INPUT.rules = [
@@ -140,6 +141,18 @@ with import <stockholm/lib>;
     dpass
 
     dnsutils
+    woeusb
+    l-gen-secrets
+    generate-secrets
+    (pkgs.writeDashBin "btc-coinbase" ''
+      ${pkgs.curl}/bin/curl -Ss 'https://api.coinbase.com/v2/prices/spot?currency=EUR' | ${pkgs.jq}/bin/jq '.data.amount'
+    '')
+    (pkgs.writeDashBin "btc-wex" ''
+      ${pkgs.curl}/bin/curl -Ss 'https://wex.nz/api/3/ticker/btc_eur' | ${pkgs.jq}/bin/jq '.btc_eur.avg'
+    '')
+    (pkgs.writeDashBin "btc-kraken" ''
+      ${pkgs.curl}/bin/curl -Ss  'https://api.kraken.com/0/public/Ticker?pair=BTCEUR' | ${pkgs.jq}/bin/jq '.result.XXBTZEUR.a[0]'
+    '')
   ];
 
   #TODO: fix this shit
@@ -167,34 +180,8 @@ with import <stockholm/lib>;
   environment.shellAliases = {
     deploy = pkgs.writeDash "deploy" ''
       set -eu
-      export PATH=${makeBinPath [
-        pkgs.bash
-        pkgs.coreutils
-        pkgs.nix
-        (pkgs.writeDashBin "is-git-crypt-locked" ''
-          magic=$(dd status=none if="$1" skip=1 bs=1 count=8)
-          test "$magic" = GITCRYPT
-        '')
-      ]}
-      cd ~/stockholm
       export SYSTEM="$1"
-      if is-git-crypt-locked ~/secrets/ready; then
-        echo 'secrets are crypted' >&2
-        exit 23
-      else
-        exec nix-shell -I stockholm="$PWD" --run 'deploy --system="$SYSTEM"'
-      fi
-    '';
-    predeploy = pkgs.writeDash "predeploy" ''
-      set -eu
-      export PATH=${makeBinPath [
-        pkgs.bash
-        pkgs.coreutils
-        pkgs.nix
-      ]}
-      cd ~/stockholm
-      export SYSTEM="$1"
-      exec nix-shell -I stockholm="$PWD" --run 'test --system="$SYSTEM" --target="$SYSTEM/var/test/" --force-populate'
+      $(nix-build $HOME/stockholm/lass/kops.nix --no-out-link --argstr name "$SYSTEM" -A deploy)
     '';
   };
 
@@ -202,4 +189,38 @@ with import <stockholm/lib>;
   programs.adb.enable = true;
   users.users.mainUser.extraGroups = [ "adbusers" "docker" ];
   virtualisation.docker.enable = true;
+  services.redshift = {
+    enable = true;
+    provider = "geoclue2";
+  };
+
+  lass.restic = genAttrs [
+    "daedalus"
+    "icarus"
+    "littleT"
+    "prism"
+    "shodan"
+    "skynet"
+  ] (dest: {
+    dirs = [
+      "/home/lass/src"
+      "/home/lass/work"
+      "/home/lass/.gnupg"
+      "/home/lass/Maildir"
+      "/home/lass/stockholm"
+      "/home/lass/.password-store"
+      "/home/bitcoin"
+      "/home/bch"
+    ];
+    passwordFile = (toString <secrets>) + "/restic/${dest}";
+    repo = "sftp:backup@${dest}.r:/backups/mors";
+    #sshPrivateKey = config.krebs.build.host.ssh.privkey.path;
+    extraArguments = [
+      "sftp.command='ssh backup@${dest}.r -i ${config.krebs.build.host.ssh.privkey.path} -s sftp'"
+    ];
+    timerConfig = {
+      OnCalendar = "00:05";
+      RandomizedDelaySec = "5h";
+    };
+  });
 }
diff --git a/lass/1systems/prism/config.nix b/lass/1systems/prism/config.nix
index c0e4620cc..89ea749c5 100644
--- a/lass/1systems/prism/config.nix
+++ b/lass/1systems/prism/config.nix
@@ -8,11 +8,15 @@ in {
   imports = [
     <stockholm/lass>
     {
-      networking.interfaces.et0.ip4 = [
+      networking.interfaces.et0.ipv4.addresses = [
         {
           address = ip;
           prefixLength = 27;
         }
+        {
+          address = "46.4.114.243";
+          prefixLength = 27;
+        }
       ];
       networking.defaultGateway = "46.4.114.225";
       networking.nameservers = [
@@ -100,6 +104,7 @@ in {
       ];
     }
     { # TODO make new hfos.nix out of this vv
+      boot.kernel.sysctl."net.ipv4.ip_forward" = 1;
       users.users.riot = {
         uid = genid "riot";
         isNormalUser = true;
@@ -110,29 +115,13 @@ in {
       };
 
       # TODO write function for proxy_pass (ssl/nonssl)
-      services.nginx.virtualHosts."hackerfleet.de" = {
-        serverAliases = [
-          "*.hackerfleet.de"
-        ];
-        locations."/".extraConfig = ''
-          proxy_pass http://192.168.122.92:80;
-        '';
-      };
-      services.nginx.virtualHosts."hackerfleet.de-s" = {
-        serverName = "hackerfleet.de";
-        listen = [
-          {
-            addr = "0.0.0.0";
-            port = 443;
-          }
-        ];
-        serverAliases = [
-          "*.hackerfleet.de"
-        ];
-        locations."/".extraConfig = ''
-          proxy_pass http://192.168.122.92:443;
-        '';
-      };
+
+      krebs.iptables.tables.filter.FORWARD.rules = [
+        { v6 = false; precedence = 1000; predicate = "-d 192.168.122.92"; target = "ACCEPT"; }
+      ];
+      krebs.iptables.tables.nat.PREROUTING.rules = [
+        { v6 = false; precedence = 1000; predicate = "-d 46.4.114.243"; target = "DNAT --to-destination 192.168.122.92"; }
+      ];
     }
     {
       users.users.tv = {
@@ -201,26 +190,6 @@ in {
         localAddress = "10.233.2.2";
       };
     }
-    {
-      #kaepsele
-      systemd.services."container@kaepsele".reloadIfChanged = mkForce false;
-      containers.kaepsele = {
-        config = { ... }: {
-          imports = [ <stockholm/lass/2configs/rebuild-on-boot.nix> ];
-          environment.systemPackages = [ pkgs.git ];
-          services.openssh.enable = true;
-          users.users.root.openssh.authorizedKeys.keys = with config.krebs.users; [
-            lass.pubkey
-            tv.pubkey
-          ];
-        };
-        autoStart = true;
-        enableTun = true;
-        privateNetwork = true;
-        hostAddress = "10.233.2.3";
-        localAddress = "10.233.2.4";
-      };
-    }
     {
       #onondaga
       systemd.services."container@onondaga".reloadIfChanged = mkForce false;
@@ -249,13 +218,12 @@ in {
     <stockholm/lass/2configs/repo-sync.nix>
     <stockholm/lass/2configs/binary-cache/server.nix>
     <stockholm/lass/2configs/iodined.nix>
-    <stockholm/lass/2configs/monitoring/server.nix>
-    <stockholm/lass/2configs/monitoring/monit-alarms.nix>
     <stockholm/lass/2configs/paste.nix>
     <stockholm/lass/2configs/syncthing.nix>
     <stockholm/lass/2configs/reaktor-coders.nix>
     <stockholm/lass/2configs/ciko.nix>
     <stockholm/lass/2configs/container-networking.nix>
+    <stockholm/lass/2configs/monitoring/prometheus-server.nix>
     { # quasi bepasty.nix
       imports = [
         <stockholm/lass/2configs/bepasty.nix>
@@ -336,6 +304,35 @@ in {
         { predicate = "-p tcp --dport 53589"; target = "ACCEPT"; }
       ];
     }
+    <stockholm/lass/2configs/go.nix>
+    {
+      environment.systemPackages = [ pkgs.cryptsetup ];
+      systemd.services."container@red".reloadIfChanged = mkForce false;
+      containers.red = {
+        config = { ... }: {
+          environment.systemPackages = [ pkgs.git ];
+          services.openssh.enable = true;
+          users.users.root.openssh.authorizedKeys.keys = [
+            config.krebs.users.lass.pubkey
+          ];
+        };
+        autoStart = false;
+        enableTun = true;
+        privateNetwork = true;
+        hostAddress = "10.233.2.3";
+        localAddress = "10.233.2.4";
+      };
+      services.nginx.virtualHosts."rote-allez-fraktion.de" = {
+        enableACME = true;
+        addSSL = true;
+        locations."/" = {
+          extraConfig = ''
+            proxy_set_header Host rote-allez-fraktion.de;
+            proxy_pass http://10.233.2.4;
+          '';
+        };
+      };
+    }
   ];
 
   krebs.build.host = config.krebs.hosts.prism;
diff --git a/lass/1systems/red/config.nix b/lass/1systems/red/config.nix
new file mode 100644
index 000000000..31e2de966
--- /dev/null
+++ b/lass/1systems/red/config.nix
@@ -0,0 +1,31 @@
+with import <stockholm/lib>;
+{ config, lib, pkgs, ... }:
+let
+  inherit (import <stockholm/lass/2configs/websites/util.nix> {inherit lib pkgs;})
+    servephpBB
+  ;
+in
+{
+  imports = [
+    <stockholm/lass>
+    <stockholm/lass/2configs>
+    <stockholm/lass/2configs/retiolum.nix>
+    <stockholm/lass/2configs/websites>
+    <stockholm/lass/2configs/websites/sqlBackup.nix>
+    (servephpBB [ "rote-allez-fraktion.de" ])
+  ];
+
+  krebs.iptables.tables.filter.INPUT.rules = [
+    { predicate = "-p tcp --dport 80"; target = "ACCEPT"; }
+  ];
+
+  krebs.build.host = config.krebs.hosts.red;
+  boot.isContainer = true;
+  networking.useDHCP = false;
+
+  services.nginx.enable = true;
+  environment.variables.NIX_REMOTE = "daemon";
+  environment.systemPackages = [
+    pkgs.mk_sql_pair
+  ];
+}
diff --git a/lass/1systems/echelon/source.nix b/lass/1systems/red/source.nix
similarity index 54%
rename from lass/1systems/echelon/source.nix
rename to lass/1systems/red/source.nix
index 96888d5a8..f2bad743c 100644
--- a/lass/1systems/echelon/source.nix
+++ b/lass/1systems/red/source.nix
@@ -1,3 +1,4 @@
 import <stockholm/lass/source.nix> {
-  name = "echelon";
+  name = "red";
+  secure = true;
 }
diff --git a/lass/1systems/shodan/config.nix b/lass/1systems/shodan/config.nix
index 7fb57544f..42a46c5f5 100644
--- a/lass/1systems/shodan/config.nix
+++ b/lass/1systems/shodan/config.nix
@@ -15,9 +15,9 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/browsers.nix>
     <stockholm/lass/2configs/programs.nix>
     <stockholm/lass/2configs/fetchWallpaper.nix>
-    <stockholm/lass/2configs/backups.nix>
     <stockholm/lass/2configs/wine.nix>
     <stockholm/lass/2configs/bitcoin.nix>
+    <stockholm/lass/2configs/backup.nix>
   ];
 
   krebs.build.host = config.krebs.hosts.shodan;
diff --git a/lass/1systems/skynet/config.nix b/lass/1systems/skynet/config.nix
index 0b9499982..b2210282f 100644
--- a/lass/1systems/skynet/config.nix
+++ b/lass/1systems/skynet/config.nix
@@ -9,7 +9,6 @@ with import <stockholm/lib>;
     <stockholm/lass/2configs/retiolum.nix>
     #<stockholm/lass/2configs/exim-retiolum.nix>
     <stockholm/lass/2configs/fetchWallpaper.nix>
-    <stockholm/lass/2configs/backups.nix>
     {
       # discordius config
       services.xserver.enable = true;
diff --git a/lass/1systems/xerxes/source.nix b/lass/1systems/xerxes/source.nix
index 11f5bf796..d256b885b 100644
--- a/lass/1systems/xerxes/source.nix
+++ b/lass/1systems/xerxes/source.nix
@@ -2,10 +2,4 @@ with import <stockholm/lib>;
 import <stockholm/lass/source.nix> {
   name = "xerxes";
   secure = true;
-  override = {
-    nixpkgs.git = mkForce {
-      url = https://github.com/lassulus/nixpkgs;
-      ref = "3eccd0b";
-    };
-  };
 }
diff --git a/lass/2configs/backup.nix b/lass/2configs/backup.nix
new file mode 100644
index 000000000..27adf6d2a
--- /dev/null
+++ b/lass/2configs/backup.nix
@@ -0,0 +1,20 @@
+{ config, lib, ... }:
+with import <stockholm/lib>;
+
+{
+  fileSystems = {
+    "/backups" = {
+      device = "/dev/pool/backup";
+      fsType = "ext4";
+    };
+  };
+  users.users.backup = {
+    useDefaultShell = true;
+    home = "/backups";
+    createHome = true;
+    openssh.authorizedKeys.keys = with config.krebs.hosts; [
+      mors.ssh.pubkey
+      prism.ssh.pubkey
+    ];
+  };
+}
diff --git a/lass/2configs/backups.nix b/lass/2configs/backups.nix
deleted file mode 100644
index c4fb85420..000000000
--- a/lass/2configs/backups.nix
+++ /dev/null
@@ -1,173 +0,0 @@
-{ config, lib, ... }:
-with import <stockholm/lib>;
-{
-
-  # TODO add timerConfig to krebs.backup and randomize startup
-  # TODO define plans more abstract
-  krebs.backup.plans = {
-  } // mapAttrs (_: recursiveUpdate {
-    snapshots = {
-      daily    = { format = "%Y-%m-%d"; retain =  7; };
-      weekly   = { format = "%YW%W";    retain =  4; };
-      monthly  = { format = "%Y-%m";    retain = 12; };
-      yearly   = { format = "%Y";                    };
-    };
-  }) {
-    dishfire-http-prism = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.prism;    path = "/bku/dishfire-http"; };
-      startAt = "03:00";
-    };
-    dishfire-http-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.icarus;   path = "/bku/dishfire-http"; };
-      startAt = "03:10";
-    };
-    dishfire-http-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.mors;     path = "/bku/dishfire-http"; };
-      startAt = "03:05";
-    };
-    dishfire-http-shodan = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.shodan;   path = "/bku/dishfire-http"; };
-      startAt = "03:10";
-    };
-    dishfire-sql-prism = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.prism;    path = "/bku/dishfire-sql"; };
-      startAt = "03:15";
-    };
-    dishfire-sql-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.icarus;   path = "/bku/dishfire-sql"; };
-      startAt = "03:25";
-    };
-    dishfire-sql-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.mors;     path = "/bku/dishfire-sql"; };
-      startAt = "03:20";
-    };
-    dishfire-sql-shodan = {
-      method = "pull";
-      src = { host = config.krebs.hosts.dishfire; path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.shodan;   path = "/bku/dishfire-sql"; };
-      startAt = "03:25";
-    };
-    prism-bitlbee-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/var/lib/bitlbee"; };
-      dst = { host = config.krebs.hosts.icarus; path = "/bku/prism-bitlbee"; };
-      startAt = "03:25";
-    };
-    prism-bitlbee-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism; path = "/var/lib/bitlbee"; };
-      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-bitlbee"; };
-      startAt = "03:25";
-    };
-    prism-bitlbee-shodan = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/var/lib/bitlbee"; };
-      dst = { host = config.krebs.hosts.shodan; path = "/bku/prism-bitlbee"; };
-      startAt = "03:25";
-    };
-    prism-chat-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/home/chat"; };
-      dst = { host = config.krebs.hosts.icarus; path = "/bku/prism-chat"; };
-      startAt = "03:35";
-    };
-    prism-chat-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism; path = "/home/chat"; };
-      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-chat"; };
-      startAt = "03:30";
-    };
-    prism-chat-shodan = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/home/chat"; };
-      dst = { host = config.krebs.hosts.shodan; path = "/bku/prism-chat"; };
-      startAt = "03:35";
-    };
-    prism-sql-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.icarus; path = "/bku/prism-sql_dumps"; };
-      startAt = "03:45";
-    };
-    prism-sql-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism; path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-sql_dumps"; };
-      startAt = "03:40";
-    };
-    prism-sql-shodan = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/bku/sql_dumps"; };
-      dst = { host = config.krebs.hosts.shodan; path = "/bku/prism-sql_dumps"; };
-      startAt = "03:45";
-    };
-    prism-http-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.icarus; path = "/bku/prism-http"; };
-      startAt = "03:55";
-    };
-    prism-http-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism; path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.mors;  path = "/bku/prism-http"; };
-      startAt = "03:50";
-    };
-    prism-http-shodan = {
-      method = "pull";
-      src = { host = config.krebs.hosts.prism;  path = "/srv/http"; };
-      dst = { host = config.krebs.hosts.shodan; path = "/bku/prism-http"; };
-      startAt = "03:55";
-    };
-    icarus-home-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.icarus; path = "/home"; };
-      dst = { host = config.krebs.hosts.mors;   path = "/bku/icarus-home"; };
-      startAt = "05:00";
-    };
-    icarus-home-shodan = {
-      method = "push";
-      src = { host = config.krebs.hosts.icarus; path = "/home"; };
-      dst = { host = config.krebs.hosts.shodan; path = "/bku/icarus-home"; };
-      startAt = "05:00";
-    };
-    mors-home-icarus = {
-      method = "push";
-      src = { host = config.krebs.hosts.mors;   path = "/home"; };
-      dst = { host = config.krebs.hosts.icarus; path = "/bku/mors-home"; };
-      startAt = "05:00";
-    };
-    mors-home-shodan = {
-      method = "push";
-      src = { host = config.krebs.hosts.mors;   path = "/home"; };
-      dst = { host = config.krebs.hosts.shodan; path = "/bku/mors-home"; };
-      startAt = "05:00";
-    };
-    shodan-home-icarus = {
-      method = "pull";
-      src = { host = config.krebs.hosts.shodan; path = "/home"; };
-      dst = { host = config.krebs.hosts.icarus; path = "/bku/shodan-home"; };
-      startAt = "04:00";
-    };
-    shodan-home-mors = {
-      method = "pull";
-      src = { host = config.krebs.hosts.shodan; path = "/home"; };
-      dst = { host = config.krebs.hosts.mors;   path = "/bku/shodan-home"; };
-      startAt = "04:00";
-    };
-  };
-}
diff --git a/lass/2configs/baseX.nix b/lass/2configs/baseX.nix
index ed179ded6..e2e44b6fc 100644
--- a/lass/2configs/baseX.nix
+++ b/lass/2configs/baseX.nix
@@ -9,7 +9,6 @@ in {
     ./power-action.nix
     ./copyq.nix
     ./livestream.nix
-    ./dns-stuff.nix
     ./urxvt.nix
     ./network-manager.nix
     {
diff --git a/lass/2configs/bitcoin.nix b/lass/2configs/bitcoin.nix
index a405addfc..9f6fd3bf0 100644
--- a/lass/2configs/bitcoin.nix
+++ b/lass/2configs/bitcoin.nix
@@ -10,9 +10,6 @@ in {
   krebs.per-user.bitcoin.packages = [
     pkgs.electrum
   ];
-  krebs.per-user.ethereum.packages = [
-    pkgs.go-ethereum
-  ];
   users.extraUsers = {
     bch = {
       name = "bch";
@@ -28,13 +25,6 @@ in {
       useDefaultShell = true;
       createHome = true;
     };
-    ethereum = {
-      name = "ethereum";
-      description = "user for ethereum stuff";
-      home = "/home/ethereum";
-      useDefaultShell = true;
-      createHome = true;
-    };
   };
   security.sudo.extraConfig = ''
     ${mainUser.name} ALL=(bitcoin) NOPASSWD: ALL
diff --git a/lass/2configs/browsers.nix b/lass/2configs/browsers.nix
index cbbd54b6b..3030d8faf 100644
--- a/lass/2configs/browsers.nix
+++ b/lass/2configs/browsers.nix
@@ -21,59 +21,37 @@ let
     $BIN "$@"
   '';
 
-  createChromiumUser = name: extraGroups: precedence:
-    let
-      bin = pkgs.writeScriptBin name ''
-        /var/run/wrappers/bin/sudo -u ${name} -i ${pkgs.chromium}/bin/chromium $@
-      '';
-    in {
-      users.extraUsers.${name} = {
-        inherit name;
-        inherit extraGroups;
-        home = "/home/${name}";
-        uid = genid name;
-        useDefaultShell = true;
-        createHome = true;
+  createUser = script: name: groups: precedence: dpi:
+    {
+      lass.xjail.${name} = {
+        inherit script groups dpi;
       };
+      environment.systemPackages = [
+        config.lass.xjail-bins.${name}
+        (pkgs.writeDashBin "cx-${name}" ''
+          DISPLAY=:${toString (genid_signed name)} ${pkgs.xclip}/bin/xclip -o | DISPLAY=:0 ${pkgs.xclip}/bin/xclip
+        '')
+      ];
       lass.browser.paths.${name} = {
-        path = bin;
+        path = config.lass.xjail-bins.${name};
         inherit precedence;
       };
-      security.sudo.extraConfig = ''
-        ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
-      '';
-      environment.systemPackages = [
-        bin
-      ];
     };
 
-  createFirefoxUser = name: extraGroups: precedence:
-    let
-      bin = pkgs.writeScriptBin name ''
-        /var/run/wrappers/bin/sudo -u ${name} -i ${pkgs.firefox-devedition-bin}/bin/firefox-devedition $@
-      '';
-    in {
-      users.extraUsers.${name} = {
-        inherit name;
-        inherit extraGroups;
-        home = "/home/${name}";
-        uid = genid name;
-        useDefaultShell = true;
-        createHome = true;
-      };
-      lass.browser.paths.${name} = {
-        path = bin;
-        inherit precedence;
-      };
-      security.sudo.extraConfig = ''
-        ${mainUser.name} ALL=(${name}) NOPASSWD: ALL
-      '';
-      environment.systemPackages = [
-        bin
-      ];
-    };
+  createChromiumUser = name: groups: precedence:
+    createUser (pkgs.writeDash name ''
+      ${pkgs.chromium}/bin/chromium "$@"
+    '') name groups precedence 80;
 
-  #TODO: abstract this
+  createFirefoxUser = name: groups: precedence:
+    createUser (pkgs.writeDash name ''
+      ${pkgs.firefox-devedition-bin}/bin/firefox-devedition "$@"
+    '') name groups precedence 80;
+
+  createQuteUser = name: groups: precedence:
+    createUser (pkgs.writeDash name ''
+      ${pkgs.qutebrowser}/bin/qutebrowser "$@"
+    '') name groups precedence 60;
 
 in {
 
@@ -110,12 +88,13 @@ in {
         }));
       };
     }
+    ( createQuteUser "qb" [ "audio" ] 20 )
     ( createFirefoxUser "ff" [ "audio" ] 10 )
-    ( createChromiumUser "cr" [ "video" "audio" ] 9 )
+    ( createChromiumUser "cr" [ "audio" ] 9 )
     ( createChromiumUser "gm" [ "video" "audio" ] 8 )
-    ( createChromiumUser "wk" [ "video" "audio" ] 0 )
-    ( createChromiumUser "fb" [ "video" "audio" ] 0 )
-    ( createChromiumUser "com" [ "video" "audio" ] 0 )
+    ( createChromiumUser "wk" [ "audio" ] 0 )
+    ( createChromiumUser "fb" [ "audio" ] 0 )
+    ( createChromiumUser "com" [ "audio" ] 0 )
     ( createChromiumUser "fin" [] (-1) )
   ];
 }
diff --git a/lass/2configs/dcso-dev.nix b/lass/2configs/dcso-dev.nix
index ae1c7bc8d..b985b67b3 100644
--- a/lass/2configs/dcso-dev.nix
+++ b/lass/2configs/dcso-dev.nix
@@ -9,6 +9,7 @@ in {
     dev = {
       name = "dev";
       uid = genid "dev";
+      extraGroups = [ "docker" ];
       description = "user for collaborative development";
       home = "/home/dev";
       useDefaultShell = true;
diff --git a/lass/2configs/default.nix b/lass/2configs/default.nix
index 5a5f1b347..12a814605 100644
--- a/lass/2configs/default.nix
+++ b/lass/2configs/default.nix
@@ -6,10 +6,9 @@ with import <stockholm/lib>;
     ./gc.nix
     ./mc.nix
     ./vim.nix
-    ./monitoring/client.nix
+    ./monitoring/node-exporter.nix
     ./zsh.nix
     ./htop.nix
-    ./backups.nix
     ./security-workarounds.nix
     {
       users.extraUsers =
diff --git a/lass/2configs/dns-stuff.nix b/lass/2configs/dns-stuff.nix
deleted file mode 100644
index cbcce8df9..000000000
--- a/lass/2configs/dns-stuff.nix
+++ /dev/null
@@ -1,16 +0,0 @@
-{ config, pkgs, ... }:
-with import <stockholm/lib>;
-{
-  services.dnscrypt-proxy = {
-    enable = true;
-    localAddress = "127.1.0.1";
-    customResolver = {
-      address = config.krebs.hosts.gum.nets.internet.ip4.addr;
-      port = 15251;
-      name = "2.dnscrypt-cert.euer.krebsco.de";
-      key = "1AFC:E58D:F242:0FBB:9EE9:4E51:47F4:5373:D9AE:C2AB:DD96:8448:333D:5D79:272C:A44C";
-    };
-  };
-  services.resolved.enable = true;
-  services.resolved.fallbackDns = [ "127.1.0.1" ];
-}
diff --git a/lass/2configs/exim-smarthost.nix b/lass/2configs/exim-smarthost.nix
index ae652722a..e05ed2427 100644
--- a/lass/2configs/exim-smarthost.nix
+++ b/lass/2configs/exim-smarthost.nix
@@ -78,6 +78,8 @@ with import <stockholm/lib>;
       { from = "github@lassul.us"; to = lass.mail; }
       { from = "ovh@lassul.us"; to = lass.mail; }
       { from = "hetzner@lassul.us"; to = lass.mail; }
+      { from = "allygator@lassul.us"; to = lass.mail; }
+      { from = "immoscout@lassul.us"; to = lass.mail; }
     ];
     system-aliases = [
       { from = "mailer-daemon"; to = "postmaster"; }
diff --git a/lass/2configs/games.nix b/lass/2configs/games.nix
index 50362cda4..3ee3a98a5 100644
--- a/lass/2configs/games.nix
+++ b/lass/2configs/games.nix
@@ -3,7 +3,7 @@
 let
   mainUser = config.users.extraUsers.mainUser;
   vdoom = pkgs.writeDash "vdoom" ''
-    ${pkgs.zandronum-bin}/bin/zandronum \
+    ${pkgs.zandronum}/bin/zandronum \
       -fov 120 \
       "$@"
   '';
@@ -50,7 +50,7 @@ let
   vdoomserver = pkgs.writeDashBin "vdoomserver" ''
     DOOM_DIR=''${DOOM_DIR:-~/doom/}
 
-    ${pkgs.zandronum-bin}/bin/zandronum-server \
+    ${pkgs.zandronum}/bin/zandronum-server \
     +exec ${doomservercfg} \
     "$@"
   '';
diff --git a/lass/2configs/gc.nix b/lass/2configs/gc.nix
index ad015180a..c5073e384 100644
--- a/lass/2configs/gc.nix
+++ b/lass/2configs/gc.nix
@@ -3,6 +3,6 @@
 with import <stockholm/lib>;
 {
   nix.gc = {
-    automatic = ! elem config.krebs.build.host.name [ "prism" "mors" "helios" ];
+    automatic = ! (elem config.krebs.build.host.name [ "prism" "mors" "helios" ] || config.boot.isContainer);
   };
 }
diff --git a/lass/2configs/git.nix b/lass/2configs/git.nix
index 1fe87c666..43085ba5e 100644
--- a/lass/2configs/git.nix
+++ b/lass/2configs/git.nix
@@ -57,6 +57,16 @@ let
       cgit.desc = "Fork of nix-user-chroot my lethalman";
       cgit.section = "software";
     };
+    nixos-aws = {
+      collaborators = [ {
+        name = "fabio";
+        pubkey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDFst8DvnfOu4pQJYxcwdf//jWTvP+jj0iSrOdt59c9Gbujm/8K1mBXhcSQhHj/GBRC1Qc1wipf9qZsWnEHMI+SRwq6tDr8gqlAcdWmHAs1bU96jJtc8EgmUKbXTFG/VmympMPi4cEbNUtH93v6NUjQKwq9szvDhhqSW4Y8zE32xLkySwobQapNaUrGAtQp3eTxu5Lkx+cEaaartaAspt8wSosXjUHUJktg0O5/XOP+CiWAx89AXxbQCy4XTQvUExoRGdw9sdu0lF0/A0dF4lFF/dDUS7+avY8MrKEcQ8Fwk8NcW1XrKMmCdNdpvou0whL9aHCdTJ+522dsSB1zZWh63Si4CrLKlc1TiGKCXdvzmCYrD+6WxbPJdRpMM4dFNtpAwhCm/dM+CBXfDkP0s5veFiYvp1ri+3hUqV/sep9r5/+d+5/R1gQs8WDNjWqcshveFbD5LxE6APEySB4QByGxIrw7gFbozE+PNxtlVP7bq4MyE6yIzL6ofQgO1e4THquPcqSCfCvyib5M2Q1phi5DETlMemWp84AsNkqbhRa4BGRycuOXXrBzE+RgQokcIY7t3xcu3q0xJo2+HxW/Lqi72zYU1NdT4nJMETEaG49FfIAnUuoVaQWWvOz8mQuVEmmdw2Yzo2ikILYSUdHTp1VPOeo6aNPvESkPw1eM0xDRlQ== ada";
+      } ];
+    };
+    krops = {
+      cgit.desc = "krebs deployment";
+      cgit.section = "software";
+    };
   } // mapAttrs make-public-repo-silent {
   };
 
@@ -70,8 +80,8 @@ let
     import <secrets/repos.nix> { inherit config lib pkgs; }
   );
 
-  make-public-repo = name: { cgit ? {}, ... }: {
-    inherit cgit name;
+  make-public-repo = name: { cgit ? {}, collaborators ? [], ... }: {
+    inherit cgit collaborators name;
     public = true;
     hooks = {
       post-receive = pkgs.git-hooks.irc-announce {
diff --git a/lass/2configs/go.nix b/lass/2configs/go.nix
new file mode 100644
index 000000000..ecf89b298
--- /dev/null
+++ b/lass/2configs/go.nix
@@ -0,0 +1,19 @@
+{ config, lib, pkgs, ... }:
+{
+  krebs.go = {
+    enable = true;
+  };
+  services.nginx = {
+    enable = true;
+    virtualHosts.go = {
+      locations."/".extraConfig = ''
+        proxy_set_header Host go.lassul.us;
+        proxy_pass http://localhost:1337;
+      '';
+      serverAliases = [
+        "go.lassul.us"
+      ];
+    };
+  };
+}
+
diff --git a/lass/2configs/mail.nix b/lass/2configs/mail.nix
index 03d39ef75..2bb51b50a 100644
--- a/lass/2configs/mail.nix
+++ b/lass/2configs/mail.nix
@@ -8,6 +8,16 @@ let
       logfile ~/.msmtp.log
     account prism
       host prism.r
+    account c-base
+      from lassulus@c-base.org
+      host c-mail.c-base.org
+      port 465
+      tls on
+      tls_starttls off
+      tls_fingerprint 8C:10:A6:AB:1F:82:C4:8F:B1:B4:22:D5:8B:8B:49:9B:59:0B:22:A4
+      auth on
+      user lassulus
+      passwordeval pass show c-base/pass
     account default: prism
   '';
 
@@ -36,9 +46,11 @@ let
     ];
     dezentrale = [ "to:dezentrale.space" ];
     dhl = [ "to:dhl@lassul.us" ];
+    eloop = [ "to:eloop.org" ];
     github = [ "to:github@lassul.us" ];
     gmail = [ "to:gmail@lassul.us" "to:lassulus@gmail.com" "lassulus@googlemail.com" ];
     kaosstuff = [ "to:gearbest@lassul.us" "to:banggood@lassul.us" "to:tomtop@lassul.us" ];
+    lugs = [ "to:lugs@lug-s.org" ];
     nix-devel = [ "to:nix-devel@googlegroups.com" ];
     patreon = [ "to:patreon@lassul.us" ];
     paypal = [ "to:paypal@lassul.us" ];
@@ -63,9 +75,9 @@ let
 
   muttrc = pkgs.writeText "muttrc" ''
     # gpg
-    source ${pkgs.neomutt}/share/doc/mutt/samples/gpg.rc
+    source ${pkgs.neomutt}/share/doc/neomutt/samples/gpg.rc
     set pgp_use_gpg_agent = yes
-    set pgp_sign_as = 0x976A7E4D
+    set pgp_sign_as = 0xDC2A43EF4F11E854B44D599A89E82952976A7E4D
     set crypt_autosign = yes
     set crypt_replyencrypt = yes
     set crypt_verify_sig = yes
@@ -183,7 +195,7 @@ let
     name = "mutt";
     paths = [
       (pkgs.writeDashBin "mutt" ''
-        exec ${pkgs.neomutt}/bin/mutt -F ${muttrc} $@
+        exec ${pkgs.neomutt}/bin/neomutt -F ${muttrc} $@
       '')
       pkgs.neomutt
     ];
@@ -194,8 +206,11 @@ in {
     msmtp
     mutt
     pkgs.much
-    pkgs.notmuch
     tag-new-mails
     tag-old-mails
   ];
+
+  nixpkgs.config.packageOverrides = opkgs: {
+    notmuch = (opkgs.notmuch.overrideAttrs (o: { doCheck = false; }));
+  };
 }
diff --git a/lass/2configs/monitoring/client.nix b/lass/2configs/monitoring/client.nix
deleted file mode 100644
index b8c245215..000000000
--- a/lass/2configs/monitoring/client.nix
+++ /dev/null
@@ -1,26 +0,0 @@
-{pkgs, config, ...}:
-with import <stockholm/lib>;
-{
-  services.telegraf = {
-    enable = true;
-
-    extraConfig = {
-      agent.interval = "1s";
-      outputs = {
-        influxdb = {
-          urls = ["http://prism:8086"];
-          database = "telegraf_db";
-          user_agent = "telegraf";
-        };
-      };
-      inputs = {
-        cpu = {
-          percpu = false;
-          totalcpu = true;
-        };
-        mem = {};
-        net = {};
-      };
-    };
-  };
-}
diff --git a/lass/2configs/monitoring/monit-alarms.nix b/lass/2configs/monitoring/monit-alarms.nix
deleted file mode 100644
index 2cfc292e5..000000000
--- a/lass/2configs/monitoring/monit-alarms.nix
+++ /dev/null
@@ -1,44 +0,0 @@
-{pkgs, config, ...}:
-with import <stockholm/lib>;
-let
-  echoToIrc = msg:
-    pkgs.writeDash "echo_irc" ''
-      set -euf
-      export LOGNAME=prism-alarm
-      ${pkgs.irc-announce}/bin/irc-announce \
-        irc.r 6667 ${config.networking.hostName}-alarm \#noise "${msg}" >/dev/null
-    '';
-
-in {
-  krebs.monit = {
-    enable = true;
-    http.enable = true;
-    alarms = {
-      nirwanabluete = {
-        test = "${pkgs.curl}/bin/curl -sf 'https://nirwanabluete.de/'";
-        alarm = echoToIrc "test nirwanabluete failed";
-      };
-      ubik = {
-        test = "${pkgs.curl}/bin/curl -sf 'https://ubikmedia.de'";
-        alarm = echoToIrc "test ubik failed";
-      };
-      cac-panel = {
-        test = "${pkgs.curl}/bin/curl -sf 'https://panel.cloudatcost.com/login.php'";
-        alarm = echoToIrc "test cac-panel failed";
-      };
-      radio = {
-        test = pkgs.writeBash "check_stream" ''
-          ${pkgs.curl}/bin/curl -sif http://lassul.us:8000/radio.ogg \
-          | ${pkgs.gawk}/bin/awk '/^\r$/{exit}{print $0}' \
-          | ${pkgs.gnugrep}/bin/grep -q "200 OK" || exit "''${PIPESTATUS[0]}"
-        '';
-        alarm = echoToIrc "test radio failed";
-      };
-    };
-  };
-
-  krebs.iptables.tables.filter.INPUT.rules = [
-    { predicate = "-p tcp -i retiolum --dport 9093"; target = "ACCEPT"; }
-  ];
-}
-
diff --git a/lass/2configs/monitoring/node-exporter.nix b/lass/2configs/monitoring/node-exporter.nix
new file mode 100644
index 000000000..561e3a25c
--- /dev/null
+++ b/lass/2configs/monitoring/node-exporter.nix
@@ -0,0 +1,15 @@
+{ config, lib, pkgs, ... }:
+{
+  krebs.iptables.tables.filter.INPUT.rules = [
+    { predicate = "-i retiolum -p tcp --dport 9100 -s ${config.krebs.hosts.prism.nets.retiolum.ip4.addr}"; target = "ACCEPT"; v6 = false; }
+    { predicate = "-i retiolum -p tcp --dport 9100 -s ${config.krebs.hosts.prism.nets.retiolum.ip6.addr}"; target = "ACCEPT"; v4 = false; }
+  ];
+  services.prometheus.exporters = {
+    node = {
+      enable = true;
+      enabledCollectors = [
+        "systemd"
+      ];
+    };
+  };
+}
diff --git a/lass/2configs/monitoring/prometheus-server.nix b/lass/2configs/monitoring/prometheus-server.nix
new file mode 100644
index 000000000..1f9419e1a
--- /dev/null
+++ b/lass/2configs/monitoring/prometheus-server.nix
@@ -0,0 +1,217 @@
+{ pkgs, lib, config, ... }:
+{
+  #networking = {
+  #  firewall.allowedTCPPorts = [
+  #    3000  # grafana
+  #    9090  # prometheus
+  #    9093  # alertmanager
+  #  ];
+  #  useDHCP = true;
+  #};
+
+  krebs.iptables.tables.filter.INPUT.rules = [
+    { predicate = "-i retiolum -p tcp --dport 3000"; target = "ACCEPT"; }
+    { predicate = "-i retiolum -p tcp --dport 9090"; target = "ACCEPT"; }
+    { predicate = "-i retiolum -p tcp --dport 9093"; target = "ACCEPT"; }
+  ];
+
+  services = {
+    prometheus = {
+      enable = true;
+      extraFlags = [
+        "-storage.local.retention 8760h"
+        "-storage.local.series-file-shrink-ratio 0.3"
+        "-storage.local.memory-chunks 2097152"
+        "-storage.local.max-chunks-to-persist 1048576"
+        "-storage.local.index-cache-size.fingerprint-to-metric 2097152"
+        "-storage.local.index-cache-size.fingerprint-to-timerange 1048576"
+        "-storage.local.index-cache-size.label-name-to-label-values 2097152"
+        "-storage.local.index-cache-size.label-pair-to-fingerprints 41943040"
+      ];
+      alertmanagerURL = [ "http://localhost:9093" ];
+      rules = [
+        ''
+          ALERT node_down
+          IF up == 0
+          FOR 5m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}}: Node is down.",
+            description = "{{$labels.alias}} has been down for more than 5 minutes."
+          }
+          ALERT node_systemd_service_failed
+          IF node_systemd_unit_state{state="failed"} == 1
+          FOR 4m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}}: Service {{$labels.name}} failed to start.",
+            description = "{{$labels.alias}} failed to (re)start service {{$labels.name}}."
+          }
+          ALERT node_filesystem_full_90percent
+          IF sort(node_filesystem_free{device!="ramfs"} < node_filesystem_size{device!="ramfs"} * 0.1) / 1024^3
+          FOR 5m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}}: Filesystem is running out of space soon.",
+            description = "{{$labels.alias}} device {{$labels.device}} on {{$labels.mountpoint}} got less than 10% space left on its filesystem."
+          }
+          ALERT node_filesystem_full_in_4h
+          IF predict_linear(node_filesystem_free{device!="ramfs"}[1h], 4*3600) <= 0
+          FOR 5m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}}: Filesystem is running out of space in 4 hours.",
+            description = "{{$labels.alias}} device {{$labels.device}} on {{$labels.mountpoint}} is running out of space of in approx. 4 hours"
+          }
+          ALERT node_filedescriptors_full_in_3h
+          IF predict_linear(node_filefd_allocated[1h], 3*3600) >= node_filefd_maximum
+          FOR 20m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}} is running out of available file descriptors in 3 hours.",
+            description = "{{$labels.alias}} is running out of available file descriptors in approx. 3 hours"
+          }
+          ALERT node_load1_90percent
+          IF node_load1 / on(alias) count(node_cpu{mode="system"}) by (alias) >= 0.9
+          FOR 1h
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}}: Running on high load.",
+            description = "{{$labels.alias}} is running with > 90% total load for at least 1h."
+          }
+          ALERT node_cpu_util_90percent
+          IF 100 - (avg by (alias) (irate(node_cpu{mode="idle"}[5m])) * 100) >= 90
+          FOR 1h
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary = "{{$labels.alias}}: High CPU utilization.",
+            description = "{{$labels.alias}} has total CPU utilization over 90% for at least 1h."
+          }
+          ALERT node_ram_using_90percent
+          IF node_memory_MemFree + node_memory_Buffers + node_memory_Cached < node_memory_MemTotal * 0.1
+          FOR 30m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary="{{$labels.alias}}: Using lots of RAM.",
+            description="{{$labels.alias}} is using at least 90% of its RAM for at least 30 minutes now.",
+          }
+          ALERT node_swap_using_80percent
+          IF node_memory_SwapTotal - (node_memory_SwapFree + node_memory_SwapCached) > node_memory_SwapTotal * 0.8
+          FOR 10m
+          LABELS {
+            severity="page"
+          }
+          ANNOTATIONS {
+            summary="{{$labels.alias}}: Running out of swap soon.",
+            description="{{$labels.alias}} is using 80% of its swap space for at least 10 minutes now."
+          }
+        ''
+      ];
+      scrapeConfigs = [
+        {
+          job_name = "node";
+          scrape_interval = "10s";
+          static_configs = [
+            {
+              targets = [
+              ] ++ map (host: "${host}:9100") (lib.attrNames (lib.filterAttrs (_: host: host.owner.name == "lass" && host.monitoring) config.krebs.hosts));
+              #labels = {
+              #  alias = "prometheus.example.com";
+              #};
+            }
+          ];
+        }
+      ];
+      alertmanager = {
+        enable = true;
+        listenAddress = "0.0.0.0";
+        configuration = {
+          "global" = {
+            "smtp_smarthost" = "smtp.example.com:587";
+            "smtp_from" = "alertmanager@example.com";
+          };
+          "route" = {
+            "group_by" = [ "alertname" "alias" ];
+            "group_wait" = "30s";
+            "group_interval" = "2m";
+            "repeat_interval" = "4h";
+            "receiver" = "team-admins";
+          };
+          "receivers" = [
+            {
+              "name" = "team-admins";
+              "email_configs" = [
+                {
+                  "to" = "devnull@example.com";
+                  "send_resolved" = true;
+                }
+              ];
+              "webhook_configs" = [
+                {
+                  "url" = "https://example.com/prometheus-alerts";
+                  "send_resolved" = true;
+                }
+              ];
+            }
+          ];
+        };
+      };
+    };
+    grafana = {
+      enable = true;
+      addr = "0.0.0.0";
+      domain = "grafana.example.com";
+      rootUrl = "https://grafana.example.com/";
+      security = import <secrets/grafana_security.nix>; # { AdminUser = ""; adminPassword = ""}
+    };
+  };
+  services.logstash = {
+    enable = true;
+    inputConfig = ''
+      http {
+        port => 14813
+        host => "127.0.0.1"
+      }
+    '';
+    filterConfig = ''
+      if ([alerts]) {
+        ruby {
+          code => '
+            lines = []
+            event["alerts"].each {|p|
+              lines << "#{p["labels"]["instance"]}#{p["annotations"]["summary"]} #{p["status"]}"
+            }
+            event["output"] = lines.join("\n")
+          '
+        }
+      }
+    '';
+    outputConfig = ''
+      file { path => "/tmp/logs.json" codec => "json_lines" }
+      irc {
+        channels => [ "#noise" ]
+        host => "irc.r"
+        nick => "alarm"
+        codec => "json_lines"
+        format => "%{output}"
+      }
+    '';
+    #plugins = [ ];
+  };
+}
diff --git a/lass/2configs/monitoring/server.nix b/lass/2configs/monitoring/server.nix
deleted file mode 100644
index adaecde2c..000000000
--- a/lass/2configs/monitoring/server.nix
+++ /dev/null
@@ -1,87 +0,0 @@
-{pkgs, config, ...}:
-with import <stockholm/lib>;
-{
-  services.influxdb.enable = true;
-
-  services.influxdb.extraConfig = {
-    meta.hostname = config.krebs.build.host.name;
-    # meta.logging-enabled = true;
-    http.bind-address = ":8086";
-    admin.bind-address = ":8083";
-    http.log-enabled = false;
-    monitoring = {
-      enabled = false;
-      # write-interval = "24h";
-    };
-    collectd = [{
-      enabled = true;
-      typesdb = "${pkgs.collectd}/share/collectd/types.db";
-      database = "collectd_db";
-      port = 25826;
-    }];
-  };
-
-  krebs.kapacitor =
-    let
-      db = "telegraf_db";
-      echoToIrc = pkgs.writeDash "echo_irc" ''
-        set -euf
-        data="$(${pkgs.jq}/bin/jq -r .message)"
-        export LOGNAME=prism-alarm
-        ${pkgs.irc-announce}/bin/irc-announce \
-          irc.r 6667 prism-alarm \#noise "$data" >/dev/null
-      '';
-    in {
-      enable = true;
-      alarms = {
-        cpu = {
-          database = db;
-          text = ''
-            var data = batch
-              |query(${"'''"}
-                SELECT mean("usage_user") AS mean
-                FROM "${db}"."default"."cpu"
-              ${"'''"})
-              .period(10m)
-              .every(1m)
-              .groupBy('host')
-              data |alert()
-                .crit(lambda: "mean" > 90)
-                .exec('${echoToIrc}')
-              data |deadman(1.0,5m)
-                .stateChangesOnly()
-                .exec('${echoToIrc}')
-          '';
-        };
-        ram = {
-          database = db;
-          text = ''
-            var data = batch
-              |query(${"'''"}
-                SELECT mean("used_percent") AS mean
-                FROM "${db}"."default"."mem"
-              ${"'''"})
-              .period(10m)
-              .every(1m)
-              .groupBy('host')
-              data |alert()
-                .crit(lambda: "mean" > 90)
-                .exec('${echoToIrc}')
-          '';
-        };
-      };
-  };
-
-  services.grafana = {
-    enable = true;
-    addr = "0.0.0.0";
-    auth.anonymous.enable = true;
-    security = import <secrets/grafana_security.nix>; # { AdminUser = ""; adminPassword = ""}
-  };
-
-  krebs.iptables.tables.filter.INPUT.rules = [
-    { predicate = "-p tcp -i retiolum --dport 8086"; target = "ACCEPT"; }
-    { predicate = "-p tcp -i retiolum --dport 3000"; target = "ACCEPT"; }
-    { predicate = "-p udp -i retiolum --dport 25826"; target = "ACCEPT"; }
-  ];
-}
diff --git a/lass/2configs/network-manager.nix b/lass/2configs/network-manager.nix
index c4f757de1..5b890b591 100644
--- a/lass/2configs/network-manager.nix
+++ b/lass/2configs/network-manager.nix
@@ -14,7 +14,13 @@
       RestartSec = "5";
     };
   };
-  networking.networkmanager.enable = true;
+  networking.networkmanager = {
+    enable = true;
+    unmanaged = [
+      "docker*"
+      "vboxnet*"
+    ];
+  };
   users.users.mainUser = {
     extraGroups = [ "networkmanager" ];
     packages = with pkgs; [
diff --git a/lass/2configs/privoxy.nix b/lass/2configs/privoxy.nix
index 33e8d1e46..e0a086421 100644
--- a/lass/2configs/privoxy.nix
+++ b/lass/2configs/privoxy.nix
@@ -3,10 +3,5 @@
 {
   services.privoxy = {
     enable = true;
-    extraConfig = ''
-      #use polipo
-      forward / localhost:8123
-    '';
   };
-  services.polipo.enable = true;
 }
diff --git a/lass/2configs/reaktor-coders.nix b/lass/2configs/reaktor-coders.nix
index 2541df3a6..5a39f7115 100644
--- a/lass/2configs/reaktor-coders.nix
+++ b/lass/2configs/reaktor-coders.nix
@@ -4,7 +4,7 @@ with import <stockholm/lib>;
 {
   krebs.Reaktor.coders = {
     nickname = "Reaktor|lass";
-    channels = [ "#coders" "#germany" ];
+    channels = [ "#coders" "#germany" "#panthermoderns" ];
     extraEnviron = {
       REAKTOR_HOST = "irc.hackint.org";
     };
@@ -84,7 +84,20 @@ with import <stockholm/lib>;
       (buildSimpleReaktorPlugin "ping" {
         pattern = "^!ping (?P<args>.*)$$";
         script = pkgs.writeDash "ping" ''
-          exec /var/setuid-wrappers/ping -q -c1 "$1" 2>&1 | tail -1
+          exec /run/wrappers/bin/ping -q -c1 "$1" 2>&1 | tail -1
+        '';
+      })
+      (buildSimpleReaktorPlugin "google" {
+        pattern = "^!g (?P<args>.*)$$";
+        script = pkgs.writeDash "google" ''
+          exec ${pkgs.ddgr}/bin/ddgr -C -n1 --json "$@" | \
+            ${pkgs.jq}/bin/jq '@text "\(.[0].abstract) \(.[0].url)"'
+        '';
+      })
+      (buildSimpleReaktorPlugin "blockchain" {
+        pattern = ".*[Bb]lockchain.*$$";
+        script = pkgs.writeDash "blockchain" ''
+          exec echo 'DID SOMEBODY SAY BLOCKCHAIN? https://paste.krebsco.de/r99pMoQq/+inline'
         '';
       })
     ];
diff --git a/lass/2configs/repo-sync.nix b/lass/2configs/repo-sync.nix
index 98dbdc227..ad44c67e1 100644
--- a/lass/2configs/repo-sync.nix
+++ b/lass/2configs/repo-sync.nix
@@ -61,6 +61,21 @@ let
             origin.url = "http://cgit.lassul.us/${name}";
             mirror.url = "${mirror}${name}";
           };
+          makefu-staging = {
+            origin.url = "http://cgit.gum/${name}";
+            origin.ref = "heads/staging";
+            mirror.url = "${mirror}${name}";
+          };
+          tv-staging = {
+            origin.url = "http://cgit.ni.r/${name}";
+            origin.ref = "heads/staging";
+            mirror.url = "${mirror}${name}";
+          };
+          nin-staging = {
+            origin.url = "http://cgit.onondaga.r/${name}";
+            origin.ref = "heads/staging";
+            mirror.url = "${mirror}${name}";
+          };
         };
         latest = {
           url = "${mirror}${name}";
diff --git a/lass/2configs/security-workarounds.nix b/lass/2configs/security-workarounds.nix
index c3d07d5fe..537c8a59b 100644
--- a/lass/2configs/security-workarounds.nix
+++ b/lass/2configs/security-workarounds.nix
@@ -5,6 +5,4 @@ with import <stockholm/lib>;
   boot.extraModprobeConfig = ''
     install dccp /run/current-system/sw/bin/false
   '';
-
-  boot.kernelPackages = pkgs.linuxPackages_latest;
 }
diff --git a/lass/2configs/syncthing.nix b/lass/2configs/syncthing.nix
index cef43d1e6..17debf822 100644
--- a/lass/2configs/syncthing.nix
+++ b/lass/2configs/syncthing.nix
@@ -3,7 +3,6 @@ with import <stockholm/lib>;
 {
   services.syncthing = {
     enable = true;
-    useInotify = true;
   };
   krebs.iptables.tables.filter.INPUT.rules = [
     { predicate = "-p tcp --dport 22000"; target = "ACCEPT";}
diff --git a/lass/2configs/virtualbox.nix b/lass/2configs/virtualbox.nix
index f7d196057..8171def2d 100644
--- a/lass/2configs/virtualbox.nix
+++ b/lass/2configs/virtualbox.nix
@@ -6,6 +6,8 @@ let
 in {
   #services.virtualboxHost.enable = true;
   virtualisation.virtualbox.host.enable = true;
+  nixpkgs.config.virtualbox.enableExtensionPack = true;
+  virtualisation.virtualbox.host.enableHardening = false;
 
   users.extraUsers = {
     virtual = {
diff --git a/lass/2configs/websites/domsen.nix b/lass/2configs/websites/domsen.nix
index 9ece2af77..7a72499c9 100644
--- a/lass/2configs/websites/domsen.nix
+++ b/lass/2configs/websites/domsen.nix
@@ -49,6 +49,7 @@ in {
       "www.ubikmedia.eu"
       "www.youthtube.xyz"
       "www.ubikmedia.de"
+      "www.joemisch.com"
       "www.weirdwednesday.de"
 
       "aldona2.ubikmedia.de"
@@ -63,6 +64,7 @@ in {
       "weirdwednesday.ubikmedia.de"
       "freemonkey.ubikmedia.de"
       "jarugadesign.ubikmedia.de"
+      "crypto4art.ubikmedia.de"
     ])
   ];
 
diff --git a/lass/2configs/websites/fritz.nix b/lass/2configs/websites/fritz.nix
index aa57a9857..14d6ce9ec 100644
--- a/lass/2configs/websites/fritz.nix
+++ b/lass/2configs/websites/fritz.nix
@@ -12,9 +12,8 @@ let
   ;
 
   msmtprc = pkgs.writeText "msmtprc" ''
-    account localhost
+    account default
       host localhost
-    account default: localhost
   '';
 
   sendmail = pkgs.writeDash "msmtp" ''
diff --git a/lass/2configs/websites/lassulus.nix b/lass/2configs/websites/lassulus.nix
index 25ca1f455..53f1eea5c 100644
--- a/lass/2configs/websites/lassulus.nix
+++ b/lass/2configs/websites/lassulus.nix
@@ -6,66 +6,10 @@ let
     genid
   ;
 
-  servephpBB = domains:
-    let
-      domain = head domains;
-
-    in {
-      services.nginx.virtualHosts."${domain}" = {
-        enableACME = true;
-        forceSSL = true;
-        serverAliases = domains;
-        extraConfig = ''
-          index index.php;
-          root /srv/http/${domain}/;
-          access_log /tmp/nginx_acc.log;
-          error_log /tmp/nginx_err.log;
-          error_page 404 /404.html;
-          error_page 500 502 503 504 /50x.html;
-          client_max_body_size 100m;
-        '';
-        locations."/".extraConfig = ''
-          try_files $uri $uri/ /index.php?$args;
-        '';
-        locations."~ \.php(?:$|/)".extraConfig =  ''
-          fastcgi_split_path_info ^(.+\.php)(/.+)$;
-          include ${pkgs.nginx}/conf/fastcgi_params;
-          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
-          fastcgi_param PATH_INFO $fastcgi_path_info;
-          fastcgi_param HTTPS on;
-          fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
-          fastcgi_pass unix:/srv/http/${domain}/phpfpm.pool;
-          fastcgi_intercept_errors on;
-        '';
-        #Directives to send expires headers and turn off 404 error logging.
-        locations."~* ^.+\.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$".extraConfig = ''
-          access_log off;
-          log_not_found off;
-          expires max;
-        '';
-      };
-      services.phpfpm.poolConfigs."${domain}" = ''
-        listen = /srv/http/${domain}/phpfpm.pool
-        user = nginx
-        group = nginx
-        pm = dynamic
-        pm.max_children = 25
-        pm.start_servers = 5
-        pm.min_spare_servers = 3
-        pm.max_spare_servers = 20
-        listen.owner = nginx
-        listen.group = nginx
-        php_admin_value[error_log] = 'stderr'
-        php_admin_flag[log_errors] = on
-        catch_workers_output = yes
-      '';
-    };
-
 in {
   imports = [
     ./default.nix
     ../git.nix
-    (servephpBB [ "rote-allez-fraktion.de" ])
   ];
 
   security.acme = {
diff --git a/lass/2configs/websites/util.nix b/lass/2configs/websites/util.nix
index 62055d0fd..61b5543ce 100644
--- a/lass/2configs/websites/util.nix
+++ b/lass/2configs/websites/util.nix
@@ -16,7 +16,7 @@ rec {
     in {
       services.nginx.virtualHosts.${domain} = {
         enableACME = true;
-        enableSSL = true;
+        onlySSL = true;
         extraConfig = ''
           listen 80;
           listen [::]:80;
@@ -28,13 +28,66 @@ rec {
       };
     };
 
+  servephpBB = domains:
+    let
+      domain = head domains;
+
+    in {
+      services.nginx.virtualHosts."${domain}" = {
+        serverAliases = domains;
+        extraConfig = ''
+          index index.php;
+          root /srv/http/${domain}/;
+          access_log /tmp/nginx_acc.log;
+          error_log /tmp/nginx_err.log;
+          error_page 404 /404.html;
+          error_page 500 502 503 504 /50x.html;
+          client_max_body_size 100m;
+        '';
+        locations."/".extraConfig = ''
+          try_files $uri $uri/ /index.php?$args;
+        '';
+        locations."~ \.php(?:$|/)".extraConfig =  ''
+          fastcgi_split_path_info ^(.+\.php)(/.+)$;
+          include ${pkgs.nginx}/conf/fastcgi_params;
+          fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+          fastcgi_param PATH_INFO $fastcgi_path_info;
+          fastcgi_param HTTPS on;
+          fastcgi_param modHeadersAvailable true; #Avoid sending the security headers twice
+          fastcgi_pass unix:/srv/http/${domain}/phpfpm.pool;
+          fastcgi_intercept_errors on;
+        '';
+        #Directives to send expires headers and turn off 404 error logging.
+        locations."~* ^.+\.(xml|ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|css|rss|atom|js|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$".extraConfig = ''
+          access_log off;
+          log_not_found off;
+          expires max;
+        '';
+      };
+      services.phpfpm.poolConfigs."${domain}" = ''
+        listen = /srv/http/${domain}/phpfpm.pool
+        user = nginx
+        group = nginx
+        pm = dynamic
+        pm.max_children = 25
+        pm.start_servers = 5
+        pm.min_spare_servers = 3
+        pm.max_spare_servers = 20
+        listen.owner = nginx
+        listen.group = nginx
+        php_admin_value[error_log] = 'stderr'
+        php_admin_flag[log_errors] = on
+        catch_workers_output = yes
+      '';
+    };
+
   serveOwncloud = domains:
     let
       domain = head domains;
     in {
       services.nginx.virtualHosts."${domain}" = {
         enableACME = true;
-        enableSSL = true;
+        onlySSL = true;
         serverAliases = domains;
         extraConfig = ''
           listen 80;
@@ -148,7 +201,7 @@ rec {
     in {
       services.nginx.virtualHosts."${domain}" = {
         enableACME = true;
-        enableSSL = true;
+        onlySSL = true;
         serverAliases = domains;
         extraConfig = ''
           listen 80;
diff --git a/lass/2configs/zsh.nix b/lass/2configs/zsh.nix
index aa3e6731d..76cac9f56 100644
--- a/lass/2configs/zsh.nix
+++ b/lass/2configs/zsh.nix
@@ -54,8 +54,8 @@
       eval $(dircolors -b ${pkgs.fetchFromGitHub {
         owner = "trapd00r";
         repo = "LS_COLORS";
-        rev = "master";
-        sha256="05lh5w3bgj9h8d8lrbbwbzw8788709cnzzkl8yh7m1dawkpf6nlp";
+        rev = "a75fca8545f91abb8a5f802981033ef54bf1eac0";
+        sha256="1lzj0qnj89mzh76ha137mnz2hf86k278rh0y9x124ghxj9yqsnb4";
       }}/LS_COLORS)
       alias ls='ls --color'
       zstyle ':completion:*:default' list-colors ''${(s.:.)LS_COLORS}
diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix
index fd77b2262..5e7e6dff3 100644
--- a/lass/3modules/default.nix
+++ b/lass/3modules/default.nix
@@ -8,9 +8,11 @@ _:
     ./mysql-backup.nix
     ./news.nix
     ./pyload.nix
+    ./restic.nix
     ./screenlock.nix
     ./umts.nix
     ./usershadow.nix
+    ./xjail.nix
     ./xserver
   ];
 }
diff --git a/lass/3modules/restic.nix b/lass/3modules/restic.nix
new file mode 100644
index 000000000..c720793b1
--- /dev/null
+++ b/lass/3modules/restic.nix
@@ -0,0 +1,119 @@
+{ config, lib, pkgs, ... }:
+
+with import <stockholm/lib>;
+
+{
+  options.lass.restic = mkOption {
+    type = types.attrsOf (types.submodule ({ config, ... }: {
+      options = {
+        name = mkOption {
+          type = types.str;
+          default = config._module.args.name;
+        };
+        passwordFile = mkOption {
+          type = types.str;
+          default = toString <secrets/restic-password>;
+          description = ''
+            read the repository password from a file.
+          '';
+          example = "/etc/nixos/restic-password";
+
+        };
+        repo = mkOption {
+          type = types.str;
+          default = "sftp:backup@prism.r:/backups/${config.name}";
+          description = ''
+            repository to backup to.
+          '';
+          example = "sftp:backup@192.168.1.100:/backups/${config.name}";
+        };
+        dirs = mkOption {
+          type = types.listOf types.str;
+          default = [];
+          description = ''
+            which directories to backup.
+          '';
+          example = [
+            "/var/lib/postgresql"
+            "/home/user/backup"
+          ];
+        };
+        timerConfig = mkOption {
+          type = types.attrsOf types.str;
+          default = {
+            OnCalendar = "daily";
+          };
+          description = ''
+            When to run the backup. See man systemd.timer for details.
+          '';
+          example = {
+            OnCalendar = "00:05";
+            RandomizedDelaySec = "5h";
+          };
+        };
+        user = mkOption {
+          type = types.str;
+          default = "root";
+          description = ''
+            As which user the backup should run.
+          '';
+          example = "postgresql";
+        };
+        extraArguments = mkOption {
+          type = types.listOf types.str;
+          default = [];
+          description = ''
+            Extra arguments to append to the restic command.
+          '';
+          example = [
+            "sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp"
+          ];
+        };
+        initialize = mkOption {
+          type = types.bool;
+          default = false;
+          description = ''
+            Create the repository if it doesn't exist.
+          '';
+        };
+      };
+    }));
+    default = {};
+  };
+
+  config = {
+    systemd.services =
+      mapAttrs' (_: plan:
+        let
+          extraArguments = concatMapStringsSep " " (arg: "-o ${arg}") plan.extraArguments;
+          connectTo = elemAt (splitString ":" plan.repo) 1;
+          resticCmd = "${pkgs.restic}/bin/restic ${extraArguments}";
+        in nameValuePair "backup.${plan.name}" {
+          environment = {
+            RESTIC_PASSWORD_FILE = plan.passwordFile;
+            RESTIC_REPOSITORY = plan.repo;
+          };
+          path = with pkgs; [
+            openssh
+          ];
+          restartIfChanged = false;
+          serviceConfig = {
+            ExecStartPre = mkIf plan.initialize (pkgs.writeScript "rustic-${plan.name}-init" ''
+              #! ${pkgs.bash}/bin/bash
+              ${resticCmd} snapshots || ${resticCmd} init
+            '');
+            ExecStart = pkgs.writeDash "rustic-${plan.name}" (
+              "#! ${pkgs.bash}/bin/bash\n" +
+              concatMapStringsSep "\n" (dir: "${resticCmd} backup ${dir}") plan.dirs
+            );
+            User = plan.user;
+          };
+        }
+      ) config.lass.restic;
+    systemd.timers =
+      mapAttrs' (_: plan: nameValuePair "backup.${plan.name}" {
+        wantedBy = [ "timers.target" ];
+        timerConfig = plan.timerConfig;
+      }) config.lass.restic;
+  };
+}
diff --git a/lass/3modules/screenlock.nix b/lass/3modules/screenlock.nix
index e16ce9868..29c3861f2 100644
--- a/lass/3modules/screenlock.nix
+++ b/lass/3modules/screenlock.nix
@@ -14,7 +14,7 @@ let
     enable = mkEnableOption "screenlock";
     command = mkOption {
       type = types.str;
-      default = "${pkgs.i3lock}/bin/i3lock -i /var/lib/wallpaper/wallpaper -f";
+      default = "${pkgs.xlockmore}/bin/xlock -mode life1d -size 1";
     };
   };
 
@@ -28,7 +28,7 @@ let
       serviceConfig = {
         SyslogIdentifier = "screenlock";
         ExecStart = cfg.command;
-        Type = "forking";
+        Type = "simple";
         User = "lass";
       };
     };
diff --git a/lass/3modules/xjail.nix b/lass/3modules/xjail.nix
new file mode 100644
index 000000000..325ebcc99
--- /dev/null
+++ b/lass/3modules/xjail.nix
@@ -0,0 +1,164 @@
+{ config, pkgs, lib, ... }:
+
+with import <stockholm/lib>;
+{
+  options.lass.xjail = mkOption {
+    type = types.attrsOf (types.submodule ({ config, ...}: {
+      options = {
+        name = mkOption {
+          type = types.string;
+          default = config._module.args.name;
+        };
+        user = mkOption {
+          type = types.string;
+          default = config.name;
+        };
+        groups = mkOption {
+          type = types.listOf types.str;
+          default = [];
+        };
+        from = mkOption {
+          type = types.string;
+          default = "lass";
+        };
+        display = mkOption {
+          type = types.string;
+          default = toString (genid_signed config._module.args.name);
+        };
+        dpi = mkOption {
+          type = types.int;
+          default = 90;
+        };
+        extraXephyrArgs = mkOption {
+          type = types.str;
+          default = "";
+        };
+        extraVglrunArgs = mkOption {
+          type = types.str;
+          default = "";
+        };
+        script = mkOption {
+          type = types.path;
+          default = pkgs.writeScript "echo_lol" "echo lol";
+        };
+        wm = mkOption {
+          #TODO find type
+          type = types.string;
+          default = "${pkgs.writeHaskell "xephyrify-xmonad" {
+            executables.xmonad = {
+              extra-depends = [
+                "containers"
+                "unix"
+                "xmonad"
+              ];
+              text = /* haskell */ ''
+                module Main where
+                import XMonad
+                import Data.Monoid
+                import System.Posix.Process (executeFile)
+                import qualified Data.Map as Map
+
+                main :: IO ()
+                main = do
+                  xmonad def
+                    { workspaces = [ "1" ]
+                    , layoutHook = myLayoutHook
+                    , keys = myKeys
+                    , normalBorderColor  = "#000000"
+                    , focusedBorderColor = "#000000"
+                    , handleEventHook = myEventHook
+                    }
+
+                myEventHook :: Event -> X All
+
+                myEventHook (ConfigureEvent { ev_event_type = 22 }) = do
+                  spawn "${pkgs.xorg.xrandr}/bin/xrandr >/dev/null 2>&1"
+                  return (All True)
+
+                myEventHook _ = do
+                  return (All True)
+
+                myLayoutHook = Full
+                myKeys _ = Map.fromList []
+              '';
+            };
+          }}/bin/xmonad";
+        };
+      };
+    }));
+    default = {};
+  };
+
+  options.lass.xjail-bins = mkOption {
+    type = types.attrsOf types.path;
+  };
+
+  # implementation
+  config = let
+    scripts = mapAttrs' (name: cfg:
+      let
+        newOrExisting = pkgs.writeDash "${cfg.name}-existing" ''
+          DISPLAY=:${cfg.display} ${pkgs.xorg.xrandr}/bin/xrandr
+          if test $? -eq 0; then
+            echo using existing xephyr
+            ${sudo_} "$@"
+          else
+            echo starting new xephyr
+            ${xephyr_} "$@"
+          fi
+        '';
+        xephyr_ = pkgs.writeDash "${cfg.name}-xephyr" ''
+          ${pkgs.xorg.xorgserver}/bin/Xephyr -br -ac -reset -terminate -resizeable -nolisten local -dpi ${toString cfg.dpi} ${cfg.extraXephyrArgs} :${cfg.display} &
+          XEPHYR_PID=$!
+          DISPLAY=:${cfg.display} ${cfg.wm} &
+          WM_PID=$!
+          ${sudo_} "$@"
+          ${pkgs.coreutils}/bin/kill $WM_PID
+          ${pkgs.coreutils}/bin/kill $XEPHYR_PID
+        '';
+        sudo_ = pkgs.writeDash "${cfg.name}-sudo" ''
+          /var/run/wrappers/bin/sudo -u ${cfg.name} -i ${vglrun_} "$@"
+        '';
+        vglrun_ = pkgs.writeDash "${cfg.name}-vglrun" ''
+          DISPLAY=:${cfg.display} ${pkgs.virtualgl}/bin/vglrun ${cfg.extraVglrunArgs} ${cfg.script} "$@"
+        '';
+      in nameValuePair name {
+        existing = newOrExisting;
+        xephyr = xephyr_;
+        sudo = sudo_;
+        vglrun = vglrun_;
+      }
+    ) config.lass.xjail;
+  in {
+
+    users.users = mapAttrs' (_: cfg:
+      nameValuePair cfg.name {
+        uid = genid cfg.name;
+        home = "/home/${cfg.name}";
+        useDefaultShell = true;
+        createHome = true;
+        extraGroups = cfg.groups;
+      }
+    ) config.lass.xjail;
+
+    users.groups = mapAttrs' (_: cfg:
+      nameValuePair cfg.name {
+        members = [
+          cfg.name
+          cfg.from
+        ];
+      }
+    ) config.lass.xjail;
+
+    security.sudo.extraConfig = (concatStringsSep "\n" (mapAttrsToList (_: cfg:
+      # TODO allow just the right script with sudo
+      "${cfg.from} ALL=(${cfg.name}) NOPASSWD: ALL"
+    ) config.lass.xjail));
+
+    lass.xjail-bins = mapAttrs' (name: cfg:
+      nameValuePair name (pkgs.writeScriptBin cfg.name ''
+        ${scripts.${name}.existing} "$@"
+      '')
+    ) config.lass.xjail;
+  };
+}
diff --git a/lass/5pkgs/custom/xmonad-lass/default.nix b/lass/5pkgs/custom/xmonad-lass/default.nix
index e658897da..18cb25b5b 100644
--- a/lass/5pkgs/custom/xmonad-lass/default.nix
+++ b/lass/5pkgs/custom/xmonad-lass/default.nix
@@ -147,6 +147,10 @@ myKeyMap =
       export PATH=$PATH:${pkgs.dmenu}/bin:${pkgs.networkmanagerapplet}/bin
       exec ${pkgs.networkmanager_dmenu}/bin/networkmanager_dmenu "$@"
     ''}")
+    , ("M4-<Insert>", spawn "${pkgs.writeDash "paste" ''
+      ${pkgs.coreutils}/bin/sleep 0.1
+      ${pkgs.xclip}/bin/xclip -o | ${pkgs.xdotool}/bin/xdotool type -f -
+    ''}")
 
     , ("M4-<F5>", spawn "${pkgs.xorg.xbacklight}/bin/xbacklight -set 1")
     , ("M4-<F6>", spawn "${pkgs.xorg.xbacklight}/bin/xbacklight -set 10")
diff --git a/lass/5pkgs/default.nix b/lass/5pkgs/default.nix
index 28482eb91..fd6a555d4 100644
--- a/lass/5pkgs/default.nix
+++ b/lass/5pkgs/default.nix
@@ -31,7 +31,6 @@ in {
       fi
       ${self.coreutils}/bin/rm $tmp
     '';
-    rtl8814au = callPackage ./custom/rtl8814au { kernel = self.linux; };
 }
 
 // mapAttrs (_: flip callPackage {})
diff --git a/lass/5pkgs/l-gen-secrets/default.nix b/lass/5pkgs/l-gen-secrets/default.nix
new file mode 100644
index 000000000..4b25fbd4c
--- /dev/null
+++ b/lass/5pkgs/l-gen-secrets/default.nix
@@ -0,0 +1,46 @@
+{ pkgs }:
+pkgs.writeDashBin "l-gen-secrets" ''
+  HOSTNAME="$1"
+  TMPDIR=$(${pkgs.coreutils}/bin/mktemp -d)
+  PASSWORD=$(${pkgs.pwgen}/bin/pwgen 25 1)
+  HASHED_PASSWORD=$(echo $PASSWORD | ${pkgs.hashPassword}/bin/hashPassword -s) > /dev/null
+
+  ${pkgs.openssh}/bin/ssh-keygen -t ed25519 -f $TMPDIR/ssh.id_ed25519 -P "" -C "" >/dev/null
+  ${pkgs.openssl}/bin/openssl genrsa -out $TMPDIR/retiolum.rsa_key.priv 4096 2>/dev/null > /dev/null
+  ${pkgs.openssl}/bin/openssl rsa -in $TMPDIR/retiolum.rsa_key.priv -pubout -out $TMPDIR/retiolum.rsa_key.pub 2>/dev/null > /dev/null
+  cat <<EOF > $TMPDIR/hashedPasswords.nix
+  {
+    root = "$HASHED_PASSWORD";
+    mainUser = "$HASHED_PASSWORD";
+  }
+  EOF
+
+  cd $TMPDIR
+  for x in *; do
+    ${pkgs.coreutils}/bin/cat $x | ${pkgs.pass}/bin/pass insert -m krebs-secrets/$HOSTNAME/$x > /dev/null
+  done
+  echo $PASSWORD | ${pkgs.pass}/bin/pass insert -m hosts/$HOSTNAME/pass > /dev/null
+
+  cat <<EOF
+    $HOSTNAME = {
+      cores = 1;
+      nets = {
+        retiolum = {
+          ip4.addr = "10.243.0.changeme";
+          ip6.addr = "42:0:0:0:0:0:0:changeme";
+          aliases = [
+            "$HOSTNAME.r"
+          ];
+          tinc.pubkey = ${"''"}
+  $(cat $TMPDIR/retiolum.rsa_key.pub)
+          ${"''"};
+        };
+      };
+      ssh.privkey.path = <secrets/ssh.id_ed25519>;
+      ssh.pubkey = "$(cat $TMPDIR/ssh.id_ed25519.pub)";
+    };
+  EOF
+
+  rm -rf $TMPDIR
+''
+
diff --git a/lass/5pkgs/xephyrify/default.nix b/lass/5pkgs/xephyrify/default.nix
index 8b18ea949..8d6036843 100644
--- a/lass/5pkgs/xephyrify/default.nix
+++ b/lass/5pkgs/xephyrify/default.nix
@@ -2,15 +2,18 @@
 
 let
 
-  minimalXmonad = writeHaskell "minimalXmonad" {
+  xephyrify-xmonad = writeHaskell "xephyrify-xmonad" {
     executables.xmonad = {
       extra-depends = [
         "containers"
+        "unix"
         "xmonad"
       ];
       text = /* haskell */ ''
         module Main where
         import XMonad
+        import Data.Monoid
+        import System.Posix.Process (executeFile)
         import qualified Data.Map as Map
 
         main :: IO ()
@@ -21,8 +24,18 @@ let
             , keys = myKeys
             , normalBorderColor  = "#000000"
             , focusedBorderColor = "#000000"
+            , handleEventHook = myEventHook
             }
 
+        myEventHook :: Event -> X All
+
+        myEventHook (ConfigureEvent { ev_event_type = 22 }) = do
+          spawn "${xorg.xrandr}/bin/xrandr >/dev/null 2>&1"
+          return (All True)
+
+        myEventHook _ = do
+          return (All True)
+
         myLayoutHook = Full
         myKeys _ = Map.fromList []
       '';
@@ -30,13 +43,20 @@ let
   };
 
 in writeDashBin "xephyrify" ''
-  NDISPLAY=:$(${coreutils}/bin/shuf -i 100-65536 -n 1)
+  NDISPLAY=''${NDISPLAY:-$(${coreutils}/bin/shuf -i 100-65536 -n 1)}
   echo "using DISPLAY $NDISPLAY"
-  ${xorg.xorgserver}/bin/Xephyr -br -ac -reset -terminate -resizeable $NDISPLAY &
+  ${xorg.xorgserver}/bin/Xephyr -br -ac -reset -terminate -resizeable -dpi 60 -nolisten local :$NDISPLAY &
+  if test -n $DROP_TO_USER; then
+    sleep 1
+    ls /tmp/.X11-unix/
+    id
+    ${coreutils}/bin/chgrp "$DROP_TO_USER" "/tmp/.X11-unix/X$NDISPLAY"
+    ${coreutils}/bin/chmod 770 "/tmp/.X11-unix/X$NDISPLAY"
+  fi
   XEPHYR_PID=$!
-  DISPLAY=$NDISPLAY ${minimalXmonad}/bin/xmonad &
+  DISPLAY=:$NDISPLAY ${xephyrify-xmonad}/bin/xmonad &
   XMONAD_PID=$!
-  DISPLAY=$NDISPLAY ${virtualgl}/bin/vglrun "$@"
+  DISPLAY=:$NDISPLAY ${virtualgl}/bin/vglrun "$@"
   kill $XMONAD_PID
   kill $XEPHYR_PID
 ''
diff --git a/lass/kops.nix b/lass/kops.nix
new file mode 100644
index 000000000..9d0ab911a
--- /dev/null
+++ b/lass/kops.nix
@@ -0,0 +1,35 @@
+{ name }: let
+  inherit (import ../krebs/kops.nix { inherit name; })
+    krebs-source
+    lib
+    pkgs
+  ;
+
+  source = { test }: lib.evalSource [
+    krebs-source
+    {
+      nixos-config.symlink = "stockholm/lass/1systems/${name}/config.nix";
+      secrets = if test then {
+        file = "/home/lass/stockholm/lass/2configs/tests/dummy-secrets";
+      } else {
+        pass = {
+          dir = "${lib.getEnv "HOME"}/.password-store";
+          name = "hosts/${name}";
+        };
+      };
+    }
+  ];
+
+in {
+  # usage: $(nix-build --no-out-link --argstr name HOSTNAME -A deploy)
+  deploy = pkgs.kops.writeDeploy "${name}-deploy" {
+    source = source { test = false; };
+    target = "root@${name}/var/src";
+  };
+
+  # usage: $(nix-build --no-out-link --argstr name HOSTNAME -A test)
+  test = pkgs.kops.writeTest "${name}-test" {
+    source = source { test = true; };
+    target = "${lib.getEnv "HOME"}/tmp/${name}-kops-test-src";
+  };
+}
diff --git a/lib/types.nix b/lib/types.nix
index 1cf2d96c9..d663d2512 100644
--- a/lib/types.nix
+++ b/lib/types.nix
@@ -50,6 +50,14 @@ rec {
         default = false;
       };
 
+      monitoring = mkOption {
+        description = ''
+          Whether the host should be monitored by monitoring tools like Prometheus.
+        '';
+        type = bool;
+        default = false;
+      };
+
       owner = mkOption {
         type = user;
       };
diff --git a/makefu/1systems/drop/source.nix b/makefu/1systems/drop/source.nix
index 74de846c0..45bd6f97e 100644
--- a/makefu/1systems/drop/source.nix
+++ b/makefu/1systems/drop/source.nix
@@ -1,3 +1,4 @@
 import <stockholm/makefu/source.nix> {
   name="drop";
+  torrent = true;
 }
diff --git a/makefu/1systems/fileleech/source.nix b/makefu/1systems/fileleech/source.nix
index 699267e21..caca1fbcb 100644
--- a/makefu/1systems/fileleech/source.nix
+++ b/makefu/1systems/fileleech/source.nix
@@ -1,3 +1,4 @@
 import <stockholm/makefu/source.nix> {
-  name="fileleech";
+  name = "fileleech";
+  torrent = true;
 }
diff --git a/makefu/1systems/gum/config.nix b/makefu/1systems/gum/config.nix
index b859efc94..578e4add8 100644
--- a/makefu/1systems/gum/config.nix
+++ b/makefu/1systems/gum/config.nix
@@ -52,7 +52,7 @@ in {
 
       # network
       <stockholm/makefu/2configs/vpn/openvpn-server.nix>
-      <stockholm/makefu/2configs/vpn/vpnws/server.nix>
+      # <stockholm/makefu/2configs/vpn/vpnws/server.nix>
       <stockholm/makefu/2configs/dnscrypt/server.nix>
       <stockholm/makefu/2configs/iodined.nix>
 
@@ -64,8 +64,10 @@ in {
       <stockholm/makefu/2configs/nginx/euer.test.nix>
       <stockholm/makefu/2configs/nginx/euer.wiki.nix>
       <stockholm/makefu/2configs/nginx/euer.blog.nix>
+      # <stockholm/makefu/2configs/nginx/gum.krebsco.de.nix>
       <stockholm/makefu/2configs/nginx/public_html.nix>
       <stockholm/makefu/2configs/nginx/update.connector.one.nix>
+      <stockholm/makefu/2configs/nginx/misa-felix-hochzeit.ml.nix>
 
       <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
       <stockholm/makefu/2configs/deployment/graphs.nix>
@@ -222,6 +224,8 @@ in {
           25
           # http
           80 443
+          # httptunnel
+          8080 8443
           # tinc
           655
           # tinc-shack
diff --git a/makefu/1systems/omo/config.nix b/makefu/1systems/omo/config.nix
index 01438397e..bed6ae9fd 100644
--- a/makefu/1systems/omo/config.nix
+++ b/makefu/1systems/omo/config.nix
@@ -9,7 +9,7 @@ let
   keyFile = byid "usb-Verbatim_STORE_N_GO_070B3CEE0B223954-0:0";
   rootDisk = byid "ata-SanDisk_SD8SNAT128G1122_162099420904";
   rootPartition = byid "ata-SanDisk_SD8SNAT128G1122_162099420904-part2";
-  primaryInterface = "enp1s0";
+  primaryInterface = "enp2s0";
   # cryptsetup luksFormat $dev --cipher aes-xts-plain64 -s 512 -h sha512
   # cryptsetup luksAddKey $dev tmpkey
   # cryptsetup luksOpen $dev crypt0 --key-file tmpkey --keyfile-size=4096
@@ -54,6 +54,7 @@ in {
       #<stockholm/makefu/2configs/graphite-standalone.nix>
       #<stockholm/makefu/2configs/share-user-sftp.nix>
       <stockholm/makefu/2configs/share/omo.nix>
+      # <stockholm/makefu/2configs/share/omo-timemachine.nix>
       <stockholm/makefu/2configs/tinc/retiolum.nix>
 
 
@@ -65,6 +66,7 @@ in {
       <stockholm/makefu/2configs/stats/external/aralast.nix>
       <stockholm/makefu/2configs/stats/telegraf>
       <stockholm/makefu/2configs/stats/telegraf/europastats.nix>
+      <stockholm/makefu/2configs/stats/arafetch.nix>
 
       # services
       <stockholm/makefu/2configs/syncthing.nix>
@@ -72,6 +74,11 @@ in {
       <stockholm/makefu/2configs/remote-build/slave.nix>
       <stockholm/makefu/2configs/deployment/google-muell.nix>
       <stockholm/makefu/2configs/virtualisation/docker.nix>
+      <stockholm/makefu/2configs/bluetooth-mpd.nix>
+      {
+        hardware.pulseaudio.systemWide = true;
+        makefu.mpd.musicDirectory = "/media/cryptX/music";
+      }
 
 
       # security
diff --git a/makefu/1systems/wbob/config.nix b/makefu/1systems/wbob/config.nix
index 637d8e2d8..42f3bddb1 100644
--- a/makefu/1systems/wbob/config.nix
+++ b/makefu/1systems/wbob/config.nix
@@ -32,66 +32,10 @@ in {
       <stockholm/makefu/2configs/hydra/stockholm.nix>
 
       <stockholm/makefu/2configs/share/wbob.nix>
-      (let
-        musicDirectory = "/data/music";
-      in {
-        services.mpd = {
-          enable = true;
-          inherit musicDirectory;
-          # dataDir = "/home/anders/.mpd";
-          network.listenAddress = "any";
-          extraConfig = ''
-            audio_output {
-              type    "pulse"
-              name    "Local MPD"
-              server  "127.0.0.1"
-            }
-          '';
-        };
-        # open because of truestedInterfaces
-        # networking.firewall.allowedTCPPorts = [ 6600 4713 ];
-        services.samba.shares.music = {
-          path = musicDirectory;
-          "read only" = "no";
-          browseable = "yes";
-          "guest ok" = "yes";
-        };
-
-        sound.enable = true;
-        hardware.pulseaudio = {
-          enable = true;
-          package = pkgs.pulseaudioFull;
-          # systemWide = true;
-          support32Bit = true;
-          zeroconf.discovery.enable = true;
-          zeroconf.publish.enable = true;
-          tcp = {
-            enable = true;
-            anonymousClients.allowAll = true;
-            anonymousClients.allowedIpRanges =  [ "127.0.0.1" "192.168.8.0/24" ];
-          };
-          configFile = pkgs.writeText "default.pa" ''
-            load-module module-udev-detect
-            load-module module-bluetooth-policy
-            load-module module-bluetooth-discover
-            load-module module-native-protocol-unix
-            load-module module-always-sink
-            load-module module-console-kit
-            load-module module-systemd-login
-            load-module module-intended-roles
-            load-module module-position-event-sounds
-            load-module module-filter-heuristics
-            load-module module-filter-apply
-            load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1
-            load-module module-switch-on-connect
-            # may be required for "system-wide" pulse to connect to bluetooth
-            #module-bluez5-device
-            #module-bluez5-discover
-            '';
-        };
-        # connect via https://nixos.wiki/wiki/Bluetooth#Using_Bluetooth_headsets_with_PulseAudio
-        hardware.bluetooth.enable = true;
-      })
+      <stockholm/makefu/2configs/bluetooth-mpd.nix>
+      {
+        users.users.makefu.extraGroups = [ "pulse" ];
+      }
 
       # Sensors
       <stockholm/makefu/2configs/stats/telegraf>
@@ -180,6 +124,7 @@ in {
   networking.firewall.allowedTCPPorts = [
     655
     8081 #smokeping
+    8086 #influx
     49152
   ];
   networking.firewall.trustedInterfaces = [ "enp0s25" ];
diff --git a/makefu/1systems/x/config.nix b/makefu/1systems/x/config.nix
index ad2ad8779..93bb27efe 100644
--- a/makefu/1systems/x/config.nix
+++ b/makefu/1systems/x/config.nix
@@ -11,6 +11,8 @@ with import <stockholm/lib>;
       <stockholm/makefu/2configs/main-laptop.nix>
       <stockholm/makefu/2configs/extra-fonts.nix>
       <stockholm/makefu/2configs/tools/all.nix>
+      <stockholm/makefu/2configs/tools/mic92.nix>
+
       <stockholm/makefu/2configs/laptop-backup.nix>
       <stockholm/makefu/2configs/dnscrypt/client.nix>
       <stockholm/makefu/2configs/avahi.nix>
@@ -27,6 +29,8 @@ with import <stockholm/lib>;
       # <stockholm/makefu/2configs/vncserver.nix>
       # <stockholm/makefu/2configs/deployment/led-fader>
       # <stockholm/makefu/2configs/deployment/hound>
+      # <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
+      # <stockholm/makefu/2configs/deployment/bureautomation/hass.nix>
 
       # Krebs
       <stockholm/makefu/2configs/tinc/retiolum.nix>
@@ -40,7 +44,7 @@ with import <stockholm/lib>;
       # Virtualization
       <stockholm/makefu/2configs/virtualisation/libvirt.nix>
       <stockholm/makefu/2configs/virtualisation/docker.nix>
-      # <stockholm/makefu/2configs/virtualisation/virtualbox.nix>
+      <stockholm/makefu/2configs/virtualisation/virtualbox.nix>
       {
         networking.firewall.allowedTCPPorts = [ 8080 ];
         networking.nat = {
@@ -78,7 +82,6 @@ with import <stockholm/lib>;
       # <stockholm/makefu/2configs/lanparty/lancache-dns.nix>
       # <stockholm/makefu/2configs/lanparty/samba.nix>
       # <stockholm/makefu/2configs/lanparty/mumble-server.nix>
-      # <stockholm/makefu/2configs/deployment/photostore.krebsco.de.nix>
 
       {
         networking.wireguard.interfaces.wg0 = {
@@ -123,6 +126,7 @@ with import <stockholm/lib>;
             load-module module-filter-heuristics
             load-module module-filter-apply
             load-module module-switch-on-connect
+            load-module module-switch-on-port-available
             '';
         };
 
@@ -137,15 +141,6 @@ with import <stockholm/lib>;
         # connect via https://nixos.wiki/wiki/Bluetooth#Using_Bluetooth_headsets_with_PulseAudio
         hardware.bluetooth.enable = true;
       }
-      { # auto-mounting
-        services.udisks2.enable = true;
-        services.devmon.enable = true;
-        # services.gnome3.gvfs.enable = true;
-        users.users.makefu.packages = with pkgs;[
-          gvfs pcmanfm lxmenu-data
-        ];
-        environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.gvfs}/lib/gio/modules" ];
-      }
 
     ];
 
@@ -166,6 +161,7 @@ with import <stockholm/lib>;
 
   networking.extraHosts = ''
     192.168.1.11  omo.local
+    80.92.65.53 www.wifionice.de wifionice.de
   '';
   # hard dependency because otherwise the device will not be unlocked
   boot.initrd.luks.devices = [ { name = "luksroot"; device = "/dev/sda2"; allowDiscards=true; }];
diff --git a/makefu/1systems/x/source.nix b/makefu/1systems/x/source.nix
index 6278877c3..ab6429dc1 100644
--- a/makefu/1systems/x/source.nix
+++ b/makefu/1systems/x/source.nix
@@ -3,5 +3,7 @@ import <stockholm/makefu/source.nix> {
   full = true;
   python = true;
   hw = true;
+  unstable = true;
+  mic92 = true;
   # torrent = true;
 }
diff --git a/makefu/2configs/bluetooth-mpd.nix b/makefu/2configs/bluetooth-mpd.nix
new file mode 100644
index 000000000..b59d3ce10
--- /dev/null
+++ b/makefu/2configs/bluetooth-mpd.nix
@@ -0,0 +1,71 @@
+{ pkgs, config, lib, ... }:
+
+let
+  cfg = config.makefu.mpd;
+in {
+  options.makefu.mpd.musicDirectory = lib.mkOption {
+    description = "music Directory";
+    default = "/data/music";
+    type = lib.types.str;
+  };
+  config = {
+    services.mpd = {
+      enable = true;
+      inherit (cfg) musicDirectory;
+      network.listenAddress = "0.0.0.0";
+      extraConfig = ''
+        audio_output {
+          type    "pulse"
+          name    "Local MPD"
+          server  "127.0.0.1"
+        }
+      '';
+    };
+  # open because of truestedInterfaces
+  # networking.firewall.allowedTCPPorts = [ 6600 4713 ];
+    services.samba.shares.music = {
+      path = cfg.musicDirectory;
+      "read only" = "no";
+      browseable = "yes";
+      "guest ok" = "yes";
+    };
+
+    sound.enable = true;
+    hardware.pulseaudio = {
+      enable = true;
+      package = pkgs.pulseaudioFull;
+      # systemWide = true;
+      support32Bit = true;
+      zeroconf.discovery.enable = true;
+      zeroconf.publish.enable = true;
+      tcp = {
+        enable = true;
+        # PULSE_SERVER=192.168.1.11 pavucontrol
+        anonymousClients.allowAll = true;
+        anonymousClients.allowedIpRanges =  [ "127.0.0.1" "192.168.0.0/16" ];
+      };
+      configFile = pkgs.writeText "default.pa" ''
+        load-module module-udev-detect
+        load-module module-bluetooth-policy
+        load-module module-bluetooth-discover
+        load-module module-native-protocol-unix auth-anonymous=1
+        load-module module-always-sink
+        load-module module-console-kit
+        load-module module-systemd-login
+        load-module module-intended-roles
+        load-module module-position-event-sounds
+        load-module module-filter-heuristics
+        load-module module-filter-apply
+        load-module module-switch-on-connect
+        #load-module module-bluez5-device
+        #load-module module-bluez5-discover
+      '';
+    };
+    # connect via https://nixos.wiki/wiki/Bluetooth#Using_Bluetooth_headsets_with_PulseAudio
+    hardware.bluetooth.enable = true;
+    # environment.etc."bluetooth/audio.conf".text = ''
+    #   [General]
+    #   Enable = Source,Sink,Media,Socket
+    # '';
+  };
+}
diff --git a/makefu/2configs/deployment/bureautomation/hass.nix b/makefu/2configs/deployment/bureautomation/hass.nix
new file mode 100644
index 000000000..b62f37bdb
--- /dev/null
+++ b/makefu/2configs/deployment/bureautomation/hass.nix
@@ -0,0 +1,75 @@
+{ pkgs, lib, ... }:
+let
+  firetv = "192.168.1.238";
+in {
+  imports = [
+    <nixpkgs-unstable/nixos/modules/services/misc/home-assistant.nix>
+  ];
+  systemd.services.firetv = {
+    wantedBy = [ "multi-user.target" ];
+    serviceConfig = {
+      User = "nobody";
+      ExecStart = "${pkgs.python-firetv}/bin/firetv-server -d ${firetv}:5555";
+    };
+  };
+  nixpkgs.config.packageOverrides = oldpkgs: {
+    home-assistant = (import <nixpkgs-unstable> {}).home-assistant;
+  };
+  ids.uids.hass = 286;
+  ids.gids.hass = 286;
+  services.home-assistant = {
+  #panel_iframe:
+  #configurator:
+  #  title: Configurator
+  #  icon: mdi:wrench
+  #  url: http://hassio.local:3218
+  # sensor:
+  # - platform: random
+    enable = true;
+    config = {
+      homeassistant = {
+        name = "Bureautomation";
+        time_zone = "Europe/Berlin";
+      };
+      panel_iframe = {
+        euer_blog = {
+          title = "Euer Blog";
+          icon =  "mdi:wrench";
+          url = "https://euer.krebsco.de";
+        };
+      };
+      media_player = [
+        { platform = "kodi";
+          host = firetv;
+        }
+        { platform = "firetv";
+          # assumes python-firetv running
+        }
+      ];
+      sensor = [
+        {
+          platform = "luftdaten";
+          name = "Shack 1";
+          sensorid = "50";
+          monitored_conditions = [ "P1" "P2" ];
+        }
+        {
+          platform = "luftdaten";
+          name = "Shack 2";
+          sensorid = "658";
+          monitored_conditions = [ "P1" "P2" ];
+        }
+        {
+          platform = "luftdaten";
+          name = "Ditzingen";
+          sensorid = "5341";
+          monitored_conditions = [ "P1" "P2" ];
+        }
+        { platform = "random"; }
+      ];
+      frontend = { };
+      http = { };
+      feedreader.urls = [ "https://nixos.org/blogs.xml" ];
+    };
+  };
+}
diff --git a/makefu/2configs/deployment/photostore.krebsco.de.nix b/makefu/2configs/deployment/photostore.krebsco.de.nix
index ecbca9ea3..19a8df235 100644
--- a/makefu/2configs/deployment/photostore.krebsco.de.nix
+++ b/makefu/2configs/deployment/photostore.krebsco.de.nix
@@ -30,6 +30,7 @@ in {
       forceSSL = true;
       locations = {
         "/".extraConfig = ''
+        expires -1;
         uwsgi_pass                  unix://${wsgi-sock};
         uwsgi_param UWSGI_CHDIR     ${workdir};
         uwsgi_param UWSGI_MODULE    cuserver.main;
diff --git a/makefu/2configs/git/cgit-retiolum.nix b/makefu/2configs/git/cgit-retiolum.nix
index 1109e2519..c209b83f6 100644
--- a/makefu/2configs/git/cgit-retiolum.nix
+++ b/makefu/2configs/git/cgit-retiolum.nix
@@ -3,10 +3,15 @@
 with import <stockholm/lib>;
 let
 
-  repos = priv-repos // krebs-repos // connector-repos ;
+  repos = priv-repos // krebs-repos // connector-repos // krebsroot-repos;
   rules = concatMap krebs-rules (attrValues krebs-repos)
     ++ concatMap priv-rules (attrValues priv-repos)
-    ++ concatMap connector-rules (attrValues connector-repos);
+    ++ concatMap connector-rules (attrValues connector-repos)
+    ++ concatMap krebsroot-rules (attrValues krebsroot-repos);
+
+  krebsroot-repos = mapAttrs make-krebs-repo {
+    hydra-stockholm = { };
+  };
 
   krebs-repos = mapAttrs make-krebs-repo {
     stockholm = {
@@ -25,10 +30,10 @@ let
     euer_blog = { };
     ampel = { };
     europastats = { };
+    arafetch = { };
     init-stockholm = {
       cgit.desc = "Init stuff for stockholm";
     };
-    hydra-stockholm = { };
   };
 
   priv-repos = mapAttrs make-priv-repo {
@@ -70,6 +75,9 @@ let
   krebs-rules = repo:
     set-owners repo all-makefu ++ set-ro-access repo krebsminister;
 
+  krebsroot-rules = repo:
+    set-owners repo (all-makefu ++ krebsminister);
+
   set-ro-access = with git; repo: user:
       optional repo.public {
         inherit user;
diff --git a/makefu/2configs/gui/automatic-diskmount.nix b/makefu/2configs/gui/automatic-diskmount.nix
new file mode 100644
index 000000000..19933111a
--- /dev/null
+++ b/makefu/2configs/gui/automatic-diskmount.nix
@@ -0,0 +1,44 @@
+{ pkgs, ... }:
+with import <stockholm/lib>; #genid
+{ # auto-mounting via polkit
+  services.udisks2.enable = true;
+## automount all disks:
+# services.devmon.enable = true;
+# services.gnome3.gvfs.enable = true;
+  users.groups.storage = {
+    gid = genid "storage";
+    members = [ "makefu" ];
+  };
+  users.users.makefu.packages = with pkgs;[
+    gvfs pcmanfm lxmenu-data
+  ];
+  environment.variables.GIO_EXTRA_MODULES = [ "${pkgs.gvfs}/lib/gio/modules" ];
+
+## allow users in group "storage" to mount disk
+# https://github.com/coldfix/udiskie/wiki/Permissions
+  security.polkit.extraConfig =
+    ''
+    polkit.addRule(function(action, subject) {
+        var YES = polkit.Result.YES;
+        var permission = {
+        "org.freedesktop.udisks.filesystem-mount": YES,
+        "org.freedesktop.udisks.luks-unlock": YES,
+        "org.freedesktop.udisks.drive-eject": YES,
+        "org.freedesktop.udisks.drive-detach": YES,
+        "org.freedesktop.udisks2.filesystem-mount": YES,
+        "org.freedesktop.udisks2.encrypted-unlock": YES,
+        "org.freedesktop.udisks2.eject-media": YES,
+        "org.freedesktop.udisks2.power-off-drive": YES,
+        "org.freedesktop.udisks2.filesystem-mount-other-seat": YES,
+        "org.freedesktop.udisks2.filesystem-unmount-others": YES,
+        "org.freedesktop.udisks2.encrypted-unlock-other-seat": YES,
+        "org.freedesktop.udisks2.eject-media-other-seat": YES,
+        "org.freedesktop.udisks2.power-off-drive-other-seat": YES
+        };
+        if (subject.isInGroup("storage")) {
+        return permission[action.id];
+        }
+    });
+  '';
+
+}
diff --git a/makefu/2configs/hw/tp-x2x0.nix b/makefu/2configs/hw/tp-x2x0.nix
index f33c12a8f..98fe30daf 100644
--- a/makefu/2configs/hw/tp-x2x0.nix
+++ b/makefu/2configs/hw/tp-x2x0.nix
@@ -38,7 +38,7 @@ with import <stockholm/lib>;
   services.tlp.enable = true;
   services.tlp.extraConfig = ''
     # BUG: http://linrunner.de/en/tlp/docs/tlp-faq.html#erratic-battery
-    START_CHARGE_THRESH_BAT0=67
+    START_CHARGE_THRESH_BAT0=95
     STOP_CHARGE_THRESH_BAT0=100
 
 
diff --git a/makefu/2configs/hydra/stockholm.nix b/makefu/2configs/hydra/stockholm.nix
index 4bdb09213..35999ae57 100644
--- a/makefu/2configs/hydra/stockholm.nix
+++ b/makefu/2configs/hydra/stockholm.nix
@@ -5,7 +5,6 @@
 {
 
   # TODO postgres backup
-  services.postgresql.enable = true;
 
   services.hydra = {
     enable = true;
diff --git a/makefu/2configs/main-laptop.nix b/makefu/2configs/main-laptop.nix
index 827da0c8d..315fc4706 100644
--- a/makefu/2configs/main-laptop.nix
+++ b/makefu/2configs/main-laptop.nix
@@ -16,6 +16,7 @@ in {
     ./zsh-user.nix
     ./tools/core.nix
     ./tools/core-gui.nix
+    ./gui/automatic-diskmount.nix
   ];
 
   users.users.${config.krebs.build.user.name}.extraGroups = [ "dialout" ];
diff --git a/makefu/2configs/nginx/euer.wiki.nix b/makefu/2configs/nginx/euer.wiki.nix
index 08bc5659f..99533b25c 100644
--- a/makefu/2configs/nginx/euer.wiki.nix
+++ b/makefu/2configs/nginx/euer.wiki.nix
@@ -17,6 +17,7 @@ let
   # contains:
   #  user1 = pass1
   #  userN = passN
+  # afterwards put /var/www/<ext-dom>/user1.html as tiddlywiki
   tw-pass-file = "${sec}/tw-pass.ini";
 
 in {
@@ -45,7 +46,7 @@ in {
 
   systemd.services.prepare-tw = {
     wantedBy = [ "local-fs.target" ];
-    before = [ "phpfpm.service" ];
+    before = [ "phpfpm.service" "nginx.service" ];
     serviceConfig = {
       ExecStart = pkgs.writeScript "prepare-tw-service" ''
         #!/bin/sh
@@ -92,6 +93,7 @@ in {
         locations = {
           "/" = {
             root = wiki-dir;
+            index = "makefu.html";
             extraConfig = ''
               expires -1;
               autoindex on;
diff --git a/makefu/2configs/nginx/misa-felix-hochzeit.ml.nix b/makefu/2configs/nginx/misa-felix-hochzeit.ml.nix
new file mode 100644
index 000000000..d0881a934
--- /dev/null
+++ b/makefu/2configs/nginx/misa-felix-hochzeit.ml.nix
@@ -0,0 +1,17 @@
+{ config, lib, pkgs, ... }:
+{
+  services.nginx = {
+    enable = lib.mkDefault true;
+    virtualHosts."misa-felix-hochzeit.ml" = {
+      serverAliases = [ "www.misa-felix-hochzeit.ml" "misa-felix.ml" "www.misa-felix.ml" ];
+      forceSSL = true;
+      enableACME = true;
+      locations = {
+        "/" = {
+          index = "index.html";
+          root =  "/var/www/misa-felix-hochzeit.ml";
+        };
+      };
+    };
+  };
+}
diff --git a/makefu/2configs/printer.nix b/makefu/2configs/printer.nix
index 51e69d8b7..d5fa65ef9 100644
--- a/makefu/2configs/printer.nix
+++ b/makefu/2configs/printer.nix
@@ -9,6 +9,7 @@ in {
       pkgs.samsungUnifiedLinuxDriver
       pkgs.cups-dymo # dymo labelwriter
       pkgs.foo2zjs # magicolor 1690mf
+      pkgs.zj-58
     ];
   };
 
diff --git a/makefu/2configs/remote-build/master.nix b/makefu/2configs/remote-build/master.nix
deleted file mode 100644
index 2a2c68119..000000000
--- a/makefu/2configs/remote-build/master.nix
+++ /dev/null
@@ -1,14 +0,0 @@
-{ pkgs, ...}:
-let
-  sshKey = (toString <secrets>) + "/id_nixBuild";
-in {
-  nix.distributedBuilds = true;
-  # TODO: iterate over krebs.hosts
-  nix.buildMachines = map ( hostName:
-  {   inherit hostName sshKey;
-      sshUser = "nixBuild";
-      system = "x86_64-linux";
-      maxJobs = 8;
-  }) [ "hotdog.r" ];
-  # puyak.r "wbob.r" "omo.r"  "gum.r" "latte.r"
-}
diff --git a/makefu/2configs/stats/arafetch.nix b/makefu/2configs/stats/arafetch.nix
new file mode 100644
index 000000000..422676b24
--- /dev/null
+++ b/makefu/2configs/stats/arafetch.nix
@@ -0,0 +1,49 @@
+{ pkgs, lib, ...}:
+with import <stockholm/lib>;
+let
+  pkg = with pkgs.python3Packages;buildPythonPackage rec {
+    rev = "762d747";
+    name = "arafetch-${rev}";
+    propagatedBuildInputs = [
+      requests
+      docopt
+      influxdb
+      beautifulsoup4
+    ];
+    src = pkgs.fetchgit {
+      url = "http://cgit.euer.krebsco.de/arafetch";
+      inherit rev;
+      sha256 = "164xiqbrr914lz0nh3i1dxz8iwg6vm2af3i3803cd3242nznw0ws";
+    };
+  };
+  home = "/var/lib/arafetch";
+in {
+  users.users.arafetch = {
+    uid = genid "arafetch";
+    inherit home;
+    createHome = true;
+  };
+
+  systemd.services.arafetch = {
+    startAt = "Mon,Wed,Fri 09:15:00";
+    wantedBy = [ "multi-user.target" ];
+    environment = {
+      OUTDIR = home;
+    };
+    path = [ pkg  pkgs.git pkgs.wget ];
+    serviceConfig = {
+      User = "arafetch";
+      WorkingDirectory = home;
+      PrivateTmp = true;
+      ExecStart = pkgs.writeDash "start-weekrun" ''
+        set -x
+        weekrun || echo "weekrun failed!"
+        find $OUTDIR/db -name \*.json | while read path;do
+          file=''${path##*/}
+          cantine=''${file%%.json}
+          ara2influx $path --cantine $cantine --host wbob.r
+        done
+      '';
+    };
+  };
+}
diff --git a/makefu/2configs/tools/mic92.nix b/makefu/2configs/tools/mic92.nix
new file mode 100644
index 000000000..176e461c7
--- /dev/null
+++ b/makefu/2configs/tools/mic92.nix
@@ -0,0 +1,9 @@
+{ pkgs, ... }:
+{
+  nixpkgs.overlays = [
+    (import <mic92/nixos/overlays/mypackages>)
+  ];
+  users.users.makefu.packages = [
+    pkgs.nix-review
+  ];
+}
diff --git a/makefu/2configs/urlwatch/default.nix b/makefu/2configs/urlwatch/default.nix
index d0fb4fe41..f93d47caa 100644
--- a/makefu/2configs/urlwatch/default.nix
+++ b/makefu/2configs/urlwatch/default.nix
@@ -25,7 +25,6 @@ in {
       # pypi
       https://pypi.python.org/simple/bepasty/
       https://pypi.python.org/simple/devpi-client/
-      https://pypi.python.org/simple/oslo.config/
       https://pypi.python.org/simple/sqlalchemy_migrate/
       https://pypi.python.org/simple/xstatic/
       https://pypi.python.org/simple/pyserial/
diff --git a/makefu/3modules/awesome-extra.nix b/makefu/3modules/awesome-extra.nix
index e4a79aa87..6f19f8f72 100644
--- a/makefu/3modules/awesome-extra.nix
+++ b/makefu/3modules/awesome-extra.nix
@@ -21,7 +21,9 @@ let
         This module will use substituteAll to replace strings before writing to
         /etc/xdg/awesome/rc.lua
       '';
-      default = pkgs.awesomecfg.full;
+      default = pkgs.awesomecfg.full.override {
+        locker = "${pkgs.i3lock}/bin/i3lock -i /var/lib/wallpaper/wallpaper";
+      };
     };
   };
   imp = {
diff --git a/makefu/5pkgs/ampel/default.nix b/makefu/5pkgs/ampel/default.nix
index 86518b9b8..9792c2c59 100644
--- a/makefu/5pkgs/ampel/default.nix
+++ b/makefu/5pkgs/ampel/default.nix
@@ -2,7 +2,7 @@
 
 with pkgs.python3Packages;buildPythonPackage rec {
   name = "ampel-${version}";
-  version = "0.2";
+  version = "0.2.1";
 
   propagatedBuildInputs = [
     docopt
@@ -16,8 +16,8 @@ with pkgs.python3Packages;buildPythonPackage rec {
 
   src = pkgs.fetchgit {
       url = "http://cgit.euer.krebsco.de/ampel";
-      rev = "d8a0250";
-      sha256 = "0n36lc17ca5db6pl6dswdqd5w9f881rfqck9yc4w33a5qpsxj85f";
+      rev = "92321d7";
+      sha256 = "0mvpbpf1rx8sc589qjb73gl8z6fir2zs3gl3br1pbhg5jgn0ij4n";
   };
   meta = {
     homepage = http://cgit.euer.krebsco.de/ampel;
diff --git a/makefu/5pkgs/awesomecfg/default.nix b/makefu/5pkgs/awesomecfg/default.nix
index 7e9724ec8..e5f62e910 100644
--- a/makefu/5pkgs/awesomecfg/default.nix
+++ b/makefu/5pkgs/awesomecfg/default.nix
@@ -1,23 +1,23 @@
 { pkgs
 , lib
 , alsaUtils
-, xlockmore
 , xbacklight
 , modkey?"Mod4"
+, locker? "${pkgs.xlock}/bin/xlock -mode blank"
 , ... }:
 
 {
   # replace: @alsaUtils@ @xlockmore@ @xbacklight@ @modkey@
   full = lib.makeOverridable pkgs.substituteAll {
     name = "awesome_full_config";
-    inherit alsaUtils xlockmore xbacklight modkey;
+    inherit alsaUtils locker xbacklight modkey;
     isExecutable = false;
     src = ./full.cfg;
   };
 
   kiosk = lib.makeOverridable pkgs.substituteAll {
     name = "awesome_kiosk_config";
-    inherit alsaUtils xlockmore xbacklight modkey;
+    inherit alsaUtils locker xbacklight modkey;
     isExecutable = false;
     src = ./kiosk.lua;
   };
diff --git a/makefu/5pkgs/awesomecfg/full.cfg b/makefu/5pkgs/awesomecfg/full.cfg
index 3488d0102..e49a88697 100644
--- a/makefu/5pkgs/awesomecfg/full.cfg
+++ b/makefu/5pkgs/awesomecfg/full.cfg
@@ -243,7 +243,7 @@ awful.screen.connect_for_each_screen(function(s)
     set_wallpaper(s)
 
     -- Each screen has its own tag table.
-		awful.tag({ "tmp", "news", "www", "im", "work1","work2","net","misc","remote" }, s, awful.layout.layouts[1])
+    awful.tag({ "tmp", "news", "www", "im", "work1","work2","net","misc","remote" }, s, awful.layout.layouts[1])
 
     -- Create a promptbox for each screen
     s.mypromptbox = awful.widget.prompt()
@@ -277,10 +277,10 @@ awful.screen.connect_for_each_screen(function(s)
         { -- Right widgets
             layout = wibox.layout.fixed.horizontal,
             mykeyboardlayout,
-						mailwidget,
+            mailwidget,
             wibox.widget.systray(),
-						cpuwidget,
-						batwidget,
+            cpuwidget,
+            batwidget,
             mytextclock,
             s.mylayoutbox,
         },
@@ -379,19 +379,19 @@ globalkeys = awful.util.table.join(
     -- Prompt
     awful.key({ modkey },            "r",     function () awful.screen.focused().mypromptbox:run() end,
               {description = "run prompt", group = "launcher"}),
-    awful.key({ modkey,"Control"  }, "BackSpace",  function ()  awful.util.spawn("@xlockmore@/bin/xlock -mode blank")   end),
-    awful.key({ }, "XF86ScreenSaver",  function ()  awful.util.spawn("@xlockmore@/bin/xlock -mode blank")   end),
+    awful.key({ modkey,"Control"  }, "BackSpace",  function () awful.util.spawn("@locker@")   end),
+    awful.key({ }, "XF86ScreenSaver",  function () awful.util.spawn("@locker@")   end),
 
-		awful.key({ modkey }, "x",
-									function ()
-											awful.prompt.run {
-												prompt       = "Run Lua code: ",
-												textbox      = awful.screen.focused().mypromptbox.widget,
-												exe_callback = awful.util.eval,
-												history_path = awful.util.get_cache_dir() .. "/history_eval"
-											}
-									end,
-									{description = "lua execute prompt", group = "awesome"}),
+    awful.key({ modkey }, "x",
+                  function ()
+                      awful.prompt.run {
+                        prompt       = "Run Lua code: ",
+                        textbox      = awful.screen.focused().mypromptbox.widget,
+                        exe_callback = awful.util.eval,
+                        history_path = awful.util.get_cache_dir() .. "/history_eval"
+                      }
+                  end,
+                  {description = "lua execute prompt", group = "awesome"}),
 
     -- Menubar
     awful.key({ modkey }, "p", function() menubar.show() end)
@@ -412,8 +412,7 @@ clientkeys = awful.util.table.join(
         end),
     awful.key({ modkey,           }, "m",
         function (c)
-            c.maximized_horizontal = not c.maximized_horizontal
-            c.maximized_vertical   = not c.maximized_vertical
+            c.maximized = not c.maximized
         end)
 )
 
diff --git a/makefu/5pkgs/awesomecfg/kiosk.lua b/makefu/5pkgs/awesomecfg/kiosk.lua
index ec255a8af..d0261f798 100644
--- a/makefu/5pkgs/awesomecfg/kiosk.lua
+++ b/makefu/5pkgs/awesomecfg/kiosk.lua
@@ -331,8 +331,8 @@ globalkeys = awful.util.table.join(
     -- Prompt
     awful.key({ modkey },                 "r",     function () mypromptbox[mouse.screen]:run() end),
     -- awful.key({ modkey },            "r",    function () awful.util.spawn( "dmenu_run" ) end ),
-    awful.key({ modkey,"Control"  }, "BackSpace",  function ()  awful.util.spawn("xlock -mode blank")   end),
-    awful.key({ }, "XF86ScreenSaver",  function ()  awful.util.spawn("xlock -mode blank")   end),
+    awful.key({ modkey,"Control"  }, "BackSpace",  function ()  awful.util.spawn("@locker@")   end),
+    awful.key({ }, "XF86ScreenSaver",  function ()  awful.util.spawn("@locker@")   end),
 
     awful.key({ modkey }, "x",
               function ()
diff --git a/makefu/5pkgs/devpi/default.nix b/makefu/5pkgs/devpi/default.nix
index 3ddcd9641..6515ea3d1 100644
--- a/makefu/5pkgs/devpi/default.nix
+++ b/makefu/5pkgs/devpi/default.nix
@@ -16,16 +16,17 @@ let
   };
   devpi-web = pkgs.python3Packages.buildPythonPackage rec {
     name = "devpi-web";
-    version = "3.1.1";
+    version = "3.2.2";
 
 
     src = pkgs.fetchurl {
       url = "mirror://pypi/d/devpi-web/devpi-web-${version}.tar.gz";
-      sha256 = "0bvqv52jmasfm4sdyccwsgvk9a663d3grj7zjw8r9x7xm7l3svqv";
+      sha256 = "1mwg2fcw88rn47ypnhg5f4s1r066129z922113shyinwrwfddhay";
     };
 
-    propagatedBuildInputs = with pkgs.python3Packages;
-      [ pkgs.devpi-server pyramid_chameleon beautifulsoup4 defusedxml readme-renderer ];
+    propagatedBuildInputs = with pkgs.python3Packages; builtins.trace pkgs.devpi-server.version
+      [ pkgs.devpi-server pyramid_chameleon pygments docutils devpi-common
+      whoosh beautifulsoup4 defusedxml readme-renderer ];
 
     meta = {
       homepage = https://bitbucket.org/hpk42/devpi;
@@ -37,6 +38,6 @@ let
 
 in {
   devpi-web =  pkgs.python3.buildEnv.override {
-      extraLibs = [ devpi-web devpi-server ];
-    };
+      extraLibs = [ devpi-web pkgs.devpi-server ];
+  };
 }
diff --git a/makefu/5pkgs/nodemcu-uploader/default.nix b/makefu/5pkgs/nodemcu-uploader/default.nix
index 64476be6e..f3e47be55 100644
--- a/makefu/5pkgs/nodemcu-uploader/default.nix
+++ b/makefu/5pkgs/nodemcu-uploader/default.nix
@@ -1,19 +1,22 @@
-{ lib, pkgs, pythonPackages, fetchurl, ... }:
+{ lib, pkgs, pythonPackages, ... }:
 
 with pythonPackages; buildPythonPackage rec {
   name = "nodemcu-uploader-${version}";
-  version = "0.2.2";
-  disabled = isPy3k || isPyPy;
+  version = "0.4.1";
   propagatedBuildInputs = [
     pyserial
+    wrapt
   ];
-  src = fetchurl {
-    url = "https://pypi.python.org/packages/source/n/nodemcu-uploader/nodemcu-uploader-${version}.tar.gz";
-    sha256 = "090giz84y9y3idgifp0yh80qqyv2czv6h3y55wyrlgf7qfbwbrvn";
+
+  src = pkgs.fetchFromGitHub {
+    owner = "kmpm";
+    repo = "nodemcu-uploader";
+    rev = "v${version}";
+    sha256 = "055pvlg544vb97kaqnnq51fs9f9g75vwgbazc293f3g1sk263gmn";
   };
-  # ImportError: No module named tests
-  # not sure what to do here
+
   doCheck = false;
+
   meta = {
     homepage = https://github.com/kmpm/nodemcu-uploader;
     description = "tool for uploading files to NodeMCU filesystem";
diff --git a/makefu/5pkgs/python-firetv/default.nix b/makefu/5pkgs/python-firetv/default.nix
new file mode 100644
index 000000000..1fb772f1f
--- /dev/null
+++ b/makefu/5pkgs/python-firetv/default.nix
@@ -0,0 +1,40 @@
+{ lib, pkgs, python2Packages, ... }:
+# requires libusb1 from unstable
+with (import <nixpkgs-unstable> {}).python2Packages; let
+
+ python-adb = buildPythonPackage rec {
+    pname = "adb";
+    version = "1.2.0";
+
+    src = fetchPypi {
+      inherit pname version;
+      sha256 = "0v4my47ikgkbq04gdllpx6kql5cfh7dnpq2fk72x03z74mqri7v8";
+    };
+
+    propagatedBuildInputs = [ libusb1 m2crypto ];
+    meta = {
+      homepage = https://github.com/google/python-adb;
+      description = "Python ADB + Fastboot implementation";
+      license = lib.licenses.asl20;
+    };
+  };
+in
+ buildPythonPackage rec {
+  name = "python-firetv-${version}";
+  version = "1.0.5";
+
+  src = pkgs.fetchFromGitHub {
+    owner = "happyleavesaoc";
+    repo = "python-firetv";
+    # rev = version;
+    rev = "55406c6";
+    sha256 = "1r2yighilchs0jvcvbngkjxkk7gp588ikcl64x7afqzxc6zxv7wp";
+  };
+
+  propagatedBuildInputs = [ python-adb flask pyyaml ];
+  meta = {
+    homepage = https://github.com/happyleavesaoc/python-firetv;
+    description = "provides state informations and some control of an amazon firetv";
+    license = lib.licenses.mit;
+  };
+}
diff --git a/makefu/5pkgs/zj-58/default.nix b/makefu/5pkgs/zj-58/default.nix
new file mode 100644
index 000000000..6eda84959
--- /dev/null
+++ b/makefu/5pkgs/zj-58/default.nix
@@ -0,0 +1,30 @@
+{stdenv, fetchFromGitHub, cups}:
+
+stdenv.mkDerivation rec {
+  name = "cups-zj58-2018-02-22";
+
+  src = fetchFromGitHub {
+    owner = "klirichek";
+    repo = "zj-58";
+    rev = "e4212cd";
+    sha256 = "1w2qkspm4qqg5h8n6gmakzhiww7gag64chvy9kf89xsl3wsyp6pi";
+  };
+
+  buildInputs = [cups];
+
+  installPhase = ''
+    mkdir -p $out/lib/cups/filter
+
+    cp rastertozj $out/lib/cups/filter
+
+
+    mkdir -p $out/share/cups/model/zjiang
+    cp ZJ-58.ppd $out/share/cups/model/zjiang/
+  '';
+
+  meta = {
+    description = "CUPS filter for thermal printer Zjiang ZJ-58";
+    homepage = https://github.com/klirichek/zj-58;
+    platforms = stdenv.lib.platforms.linux;
+  };
+}
diff --git a/makefu/6tests/data/secrets/torrent-secrets/auth.nix b/makefu/6tests/data/secrets/torrent-secrets/auth.nix
deleted file mode 100644
index 0967ef424..000000000
--- a/makefu/6tests/data/secrets/torrent-secrets/auth.nix
+++ /dev/null
@@ -1 +0,0 @@
-{}
diff --git a/makefu/source.nix b/makefu/source.nix
index 79a2c535f..bcdb66a66 100644
--- a/makefu/source.nix
+++ b/makefu/source.nix
@@ -1,12 +1,14 @@
 with import <stockholm/lib>;
 host@{ name,
-  override ? {},
-  secure ? false,
-  full ? false,
-  torrent ? false,
-  hw ? false,
-  musnix ? false,
-  python ? false
+  override ? {}
+,  secure ? false
+,  full ? false
+,  torrent ? false
+,  hw ? false
+,  musnix ? false
+,  python ? false
+,  unstable ? false #unstable channel checked out
+,  mic92 ? false
 }:
 let
   builder = if getEnv "dummy_secrets" == "true"
@@ -19,9 +21,8 @@ let
     ];
   };
   # TODO: automate updating of this ref + cherry-picks
-  ref = "51810e0"; # nixos-17.09 @ 2018-02-14
-                   # + do_sqlite3 ruby: 55a952be5b5
-                   # + signal: 0f19beef3
+  ref = "a09afbfb8a4"; # nixos-18.03 @ 2018-04-04
+                       # + do_sqlite3 ruby: 55a952be5b5
 
 in
   evalSource (toString _file) [
@@ -52,28 +53,44 @@ in
     (mkIf ( musnix ) {
       musnix.git = {
         url = https://github.com/musnix/musnix.git;
-        ref = "d8b989f";
+        ref = "master"; # follow the musnix channel, lets see how this works out
       };
     })
 
     (mkIf ( hw ) {
       nixos-hardware.git = {
         url = https://github.com/nixos/nixos-hardware.git;
-        ref = "8a05dc9";
+        ref = "30fdd53";
       };
     })
 
     (mkIf ( python ) {
       python.git = {
         url = https://github.com/garbas/nixpkgs-python;
-        ref = "cac319b";
+        ref = "cac319b7";
       };
     })
+
     (mkIf ( torrent ) {
       torrent-secrets.file = getAttr builder {
         buildbot = toString <stockholm/makefu/6tests/data/secrets>;
         makefu = "/home/makefu/secrets/torrent" ;
       };
     })
+
+    (mkIf ( unstable ) {
+      nixpkgs-unstable.git = {
+        url = https://github.com/nixos/nixpkgs-channels;
+        ref = "nixos-unstable";
+      };
+    })
+
+    (mkIf ( mic92 ) {
+      mic92.git = {
+        url = https://github.com/Mic92/dotfiles/;
+        ref = "48a1f49";
+      };
+    })
+
     override
   ]
diff --git a/nin/2configs/games.nix b/nin/2configs/games.nix
index a7edae078..15e17238d 100644
--- a/nin/2configs/games.nix
+++ b/nin/2configs/games.nix
@@ -3,7 +3,7 @@
 let
   mainUser = config.users.extraUsers.mainUser;
   vdoom = pkgs.writeDash "vdoom" ''
-    ${pkgs.zandronum-bin}/bin/zandronum \
+    ${pkgs.zandronum}/bin/zandronum \
       -fov 120 \
       "$@"
   '';
@@ -50,7 +50,7 @@ let
   vdoomserver = pkgs.writeDashBin "vdoomserver" ''
     DOOM_DIR=''${DOOM_DIR:-~/doom/}
 
-    ${pkgs.zandronum-bin}/bin/zandronum-server \
+    ${pkgs.zandronum}/bin/zandronum-server \
     +exec ${doomservercfg} \
     "$@"
   '';
diff --git a/tv/2configs/urlwatch.nix b/tv/2configs/urlwatch.nix
index 509257c48..897def8c9 100644
--- a/tv/2configs/urlwatch.nix
+++ b/tv/2configs/urlwatch.nix
@@ -13,11 +13,6 @@ with import <stockholm/lib>;
 
       http://www.exim.org/
 
-      {
-        url = https://api.github.com/repos/Gabriel439/nix-diff/git/refs/heads/master;
-        filter = "system:${pkgs.jq}/bin/jq -r .object.sha";
-      }
-
       # ref src/nixpkgs/pkgs/tools/admin/sec/default.nix
       {
         url = https://api.github.com/repos/simple-evcorr/sec/tags;
diff --git a/tv/2configs/xserver/default.nix b/tv/2configs/xserver/default.nix
index 7ba78b974..6ef8a8768 100644
--- a/tv/2configs/xserver/default.nix
+++ b/tv/2configs/xserver/default.nix
@@ -11,6 +11,7 @@ in {
 
   environment.systemPackages = [
     pkgs.ff
+    pkgs.font-size
     pkgs.gitAndTools.qgit
     pkgs.mpv
     pkgs.sxiv
diff --git a/tv/5pkgs/simple/xmonad-tv/default.nix b/tv/5pkgs/simple/xmonad-tv/default.nix
index 94c70153d..d474b7edd 100644
--- a/tv/5pkgs/simple/xmonad-tv/default.nix
+++ b/tv/5pkgs/simple/xmonad-tv/default.nix
@@ -133,6 +133,8 @@ myKeys conf = Map.fromList $
     [ ((_4  , xK_Escape ), forkFile "/run/wrappers/bin/slock" [] Nothing)
     , ((_4S , xK_c      ), kill)
 
+    , ((_4  , xK_p      ), forkFile "${pkgs.pass}/bin/passmenu" ["--type"] Nothing)
+
     , ((_4  , xK_x      ), chooseAction spawnTermAt)
     , ((_4C , xK_x      ), spawnRootTerm)