{ config, pkgs, ... }: let trivmixService = opts: (pkgs.callPackage ./custom/trivmix-service.nix opts).out; thermoprint-servant = (pkgs.callPackage ./custom/thermoprint {}).thermoprint-servant; in rec { imports = [ ./musnix ./bragi-hw.nix ./custom/zsh.nix ./users.nix ]; boot.loader.grub.enable = true; boot.loader.grub.version = 2; boot.loader.grub.extraConfig = "serial; terminal_output.serial"; boot.kernelParams = [ "console=ttyS0,115200" ]; boot.kernelModules = [ "usblp" ]; networking.hostName = "bragi"; networking.hostId = "2af11085"; networking.wireless.enable = true; nixpkgs.config.packageOverrides = pkgs: rec { haskellPackages = pkgs.recurseIntoAttrs ( pkgs.haskellPackages.override { overrides = self: super: let callPackage = pkgs.lib.callPackageWith ( pkgs // self ); in { trivmix = callPackage ./custom/trivmix.nix {}; # filelock = callPackage ./custom/filelock.nix {}; }; } ); jack2Full = pkgs.jack2Full.override { dbus = null; }; mpd = pkgs.symlinkJoin { name = "mpd"; paths = [ (pkgs.mpd.override { gmeSupport = false; pulseaudioSupport = false; }) ]; buildInputs = [ pkgs.makeWrapper ]; postBuild = '' wrapProgram $out/bin/mpd \ --run "umask 0" ''; }; inherit (pkgs.callPackage ./custom/thermoprint {}) thermoprint-server thermoprint-webgui tprint; inherit (haskellPackages) trivmix; }; environment.systemPackages = with pkgs; [ git mosh rsync tmux nfs-utils jack2Full trivmix zsh tprint ]; # List services that you want to enable: services.openssh = { enable = true; }; services.fcron = { enable = true; systab = '' %weekly * * nix-collect-garbage --delete-older-than '7d' ''; }; services.autofs = { enable = true; autoMaster = let mapConf = pkgs.writeText "auto" '' odin -fstype=nfs,ro odin.asgard.yggdrasil:/srv/media dellingr -fstype=vfat,ro /dev/disk/by-uuid/6436-3432 ''; in '' /media file:${mapConf} ''; }; systemd.globalEnvironment = { JACK_PROMISCUOUS_SERVER = "1"; }; environment.sessionVariables = { JACK_PROMISCUOUS_SERVER = "1"; }; musnix = { enable = true; alsaSeq.enable = false; kernel = { packages = with pkgs; linuxPackages_latest_rt; optimize = true; realtime = true; }; }; systemd.services.jack = { wantedBy = [ "sound.target" ]; serviceConfig = { Type = "simple"; ExecStart = "${pkgs.jack2Full}/bin/jackd -d alsa -d 'hw:1' -M -H -r 96000"; ExecStartPost = "${pkgs.jack2Full}/bin/jack_wait -w -t 5"; User = "jack"; Group = "audio"; UMask = "0000"; Nice = "-15"; LimitRTPRIO = "95:95"; LimitMEMLOCK = "infinity"; }; }; systemd.services."mpdmix0" = trivmixService { name = "mpdmix0"; connectOut = "system:playback_3"; group = "mpd"; }; systemd.services."mpdmix1" = trivmixService { name = "mpdmix1"; connectOut = "system:playback_4"; group = "mpd"; }; systemd.services."passmix0" = trivmixService { name = "passmix0"; connectOut = "system:playback_3"; connectIn = "system:capture_5"; group = "vali_out"; }; systemd.services."passmix1" = trivmixService { name = "passmix1"; connectOut = "system:playback_4"; connectIn = "system:capture_6"; group = "vali_out"; }; systemd.services."passmix2" = trivmixService { name = "passmix2"; connectOut = "system:playback_5"; connectIn = "system:capture_1"; group = "vali_in"; }; systemd.services."passmix3" = trivmixService { name = "passmix3"; connectOut = "system:playback_6"; connectIn = "system:capture_1"; group = "vali_in"; }; systemd.services."passmix4" = trivmixService { name = "passmix4"; connectOut = "system:playback_3"; connectIn = "system:capture_7"; group = "hel_out"; }; systemd.services."passmix5" = trivmixService { name = "passmix5"; connectOut = "system:playback_4"; connectIn = "system:capture_8"; group = "hel_out"; }; services.mpd = { enable = true; musicDirectory = "/media/odin/music"; extraConfig = '' bind_to_address "bragi.bragisheimr.yggdrasil" bind_to_address "bragi.asgard.yggdrasil" bind_to_address "localhost" bind_to_address "/var/lib/mpd/socket" audio_output { name "JACK" type "jack" client_name "mpd" destination_ports "mpdmix0:in,mpdmix1:in" } ''; user = "mpd"; group = "audio"; }; systemd.services."mpd".requires = [ "jack.service" ]; systemd.services."mpd".serviceConfig = { LimitMEMLOCK = "infinity"; }; users.extraUsers.jack = { name = "jack"; isSystemUser = true; group = "audio"; }; security.setuidPrograms = ["mount.nfs"]; programs.bash.promptInit = '' PROMPT_COLOR="1;31m" return $UID && PROMPT_COLOR="1;32m" case "$TERM" in xterm*|rxvt*|kterm|aterm|gnome*) # Others can go here. PS1="\n\[\033[$PROMPT_COLOR\][\u@\h:\w]\\$\[\033[0m\] " if test "$TERM" = "xterm"; then PS1="\[\033]2;\h:\u:\w\007\]$PS1" fi ;; *) PS1="[\u@\h:\w]$ " ;; esac ''; networking.interfaces = { "enp1s0" = { useDHCP = false; ipAddress = "10.141.4.1"; prefixLength = 24; }; }; networking.nat = { enable = true; externalIP = "10.141.1.5"; externalInterface = "wlp4s0"; internalIPs = [ "10.141.4.0/24" ]; internalInterfaces = [ "enp1s0" ]; }; networking.firewall = { enable = true; allowPing = true; allowedTCPPorts = [ 22 # SSH 80 # HTTP 6600 # MPD ]; allowedUDPPortRanges = [ { from = 60000; to = 61000; } # mosh ]; extraCommands = '' iptables -t nat -A POSTROUTING -o wlp4s0 -j MASQUERADE #iptables -A FORWARD -i wlp4s0 -o enp1s0 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i wlp4s0 -o enp1s0 -j ACCEPT iptables -A FORWARD -i enp1s0 -o wlp4s0 -j ACCEPT ''; }; services.dhcpd = { enable = true; interfaces = [ "enp1s0" ]; extraConfig = '' option subnet-mask 255.255.255.0; option domain-name-servers 10.141.1.1, 8.8.8.8, 8.8.4.4, 192.168.2.1; option domain-name "bragisheimr.yggdrasil"; option routers 10.141.4.1; subnet 10.141.4.0 netmask 255.255.255.0 { range 10.141.4.100 10.141.4.254; } group { use-host-decl-names on; host vali { hardware ethernet e0:cb:4e:f7:10:3d; fixed-address vali.bragisheimr.yggdrasil; } host printer { hardware ethernet 30:cd:a7:b0:55:8d; fixed-address printer.bragisheimr.yggdrasil; } } ''; }; services.ntp = { enable = false; }; services.chrony = { enable = true; }; users.extraUsers.root = let template = (import users/gkleen.nix); in { inherit (template) shell; openssh.authorizedKeys.keyFiles = template.openssh.authorizedKeys.keyFiles; }; users.extraUsers."thermoprint" = { name = "thermoprint"; group = "lp"; isSystemUser = true; createHome = true; home = "/var/lib/thermoprint"; }; environment.etc."thermoprint-server/thermoprint-server.hs" = { text = '' {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ImpredicativeTypes #-} module Main (main) where import Thermoprint.Server import Thermoprint.Server.Printer.Generic import Control.Monad.Trans.Resource import Control.Monad.Logger import Control.Monad.Reader import Database.Persist.Sqlite import qualified Network.Wai.Handler.Warp as Warp main :: IO () main = thermoprintServer True (Nat runSqlite) $ (\c -> c { queueManagers = queueManagers, warpSettings = wSettings }) <$> def `withPrinters` printers where runSqlite :: ReaderT ConnectionPool (LoggingT IO) a -> IO a runSqlite = runStderrLoggingT . withSqlitePool "${users.extraUsers."thermoprint".home}/thermoprint.sqlite" 1 . runReaderT printers = [ (pure $ genericPrint "/dev/usb/lp0", def :: QMConfig (ResourceT (ReaderT ConnectionPool (LoggingT IO)))) ] queueManagers _ = QMConfig { manager = union [ limitHistorySize 100 , limitHistoryAge 3600 ] , collapse = standardCollapse } wSettings = Warp.setHost "127.0.0.1" . Warp.setPort 8080 $ Warp.defaultSettings ''; }; systemd.services."thermoprint" = { environment = { THERMOPRINT_CONFIG = "/etc/thermoprint-server"; THERMOPRINT_CACHE = ''${users.extraUsers."thermoprint".home}/dyre''; }; wantedBy = [ "default.target" ]; serviceConfig = { Type = "simple"; ExecStart = ''${pkgs.thermoprint-server}/bin/thermoprint-server --force-reconf''; User = users.extraUsers."thermoprint".name; Group = users.extraUsers."thermoprint".group; }; }; systemd.services."thermoprint-webgui" = { wantedBy = [ "default.target" ]; serviceConfig = { Type = "simple"; ExecStart = ''${pkgs.thermoprint-webgui}/bin/thermoprint-webgui -P 80 -A localhost -F /thermoprint/api/ -a "localhost" -p 8081''; User = users.extraUsers."thermoprint".name; Group = users.extraUsers."thermoprint".group; }; }; services.nginx = { enable = true; httpConfig = '' default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" ' '"$gzip_ratio"'; client_header_timeout 10m; client_body_timeout 10m; send_timeout 10m; connection_pool_size 256; client_header_buffer_size 1k; large_client_header_buffers 4 2k; request_pool_size 4k; gzip on; gzip_min_length 1100; gzip_buffers 4 8k; gzip_types text/plain; output_buffers 1 32k; postpone_output 1460; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 75 20; ignore_invalid_headers on; access_log stderr; error_log stderr; server { listen *:80; server_name _; location /thermoprint/api/ { proxy_pass http://localhost:8080/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } location /thermoprint/ { proxy_pass http://localhost:8081/; } } ''; }; nix = { daemonIONiceLevel = 3; daemonNiceLevel = 10; gc = { automatic = true; }; }; system.autoUpgrade.enable = true; system.stateVersion = "16.09"; }