diff options
| author | makefu <github@syntax-fehler.de> | 2022-12-12 19:44:00 +0100 |
|---|---|---|
| committer | makefu <github@syntax-fehler.de> | 2022-12-12 19:44:00 +0100 |
| commit | 6eb5e44b7e5bdc8b1b3b5ffe40c146841f7afd10 (patch) | |
| tree | f706bf7c3c7a289f680ac329caa2b578e5145a56 /lass | |
| parent | 96e934dc8a353cff91ef824f6a125ed49996d058 (diff) | |
| parent | 3884243448869bdf09f6434b385e532c7c26ae88 (diff) | |
Merge remote-tracking branch 'lass/master'
Diffstat (limited to 'lass')
38 files changed, 1468 insertions, 364 deletions
diff --git a/lass/1systems/daedalus/config.nix b/lass/1systems/daedalus/config.nix index d6943c110..9ef858e28 100644 --- a/lass/1systems/daedalus/config.nix +++ b/lass/1systems/daedalus/config.nix @@ -53,6 +53,7 @@ with import <stockholm/lib>; services.xserver.enable = true; services.xserver.displayManager.lightdm.enable = true; services.xserver.desktopManager.plasma5.enable = true; + services.tlp.enable = lib.mkForce false; services.xserver.layout = "de"; } { diff --git a/lass/1systems/green/config.nix b/lass/1systems/green/config.nix index 5cf7d9242..4c98091f1 100644 --- a/lass/1systems/green/config.nix +++ b/lass/1systems/green/config.nix @@ -11,78 +11,50 @@ with import <stockholm/lib>; <stockholm/lass/2configs/syncthing.nix> <stockholm/lass/2configs/sync/sync.nix> <stockholm/lass/2configs/sync/decsync.nix> - <stockholm/lass/2configs/sync/weechat.nix> + <stockholm/lass/2configs/weechat.nix> <stockholm/lass/2configs/bitlbee.nix> - <stockholm/lass/2configs/IM.nix> + <stockholm/lass/2configs/muchsync.nix> <stockholm/lass/2configs/pass.nix> <stockholm/lass/2configs/git-brain.nix> + <stockholm/lass/2configs/et-server.nix> + <stockholm/lass/2configs/consul.nix> + + <stockholm/lass/2configs/atuin-server.nix> ]; krebs.build.host = config.krebs.hosts.green; - users.users.mainUser.openssh.authorizedKeys.keys = [ - config.krebs.users.lass-android.pubkey - "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK0rn3003CkJMk3jZrh/3MC6nVorHRymlFSI4x1brCKY" # weechat ssh tunnel - ]; - - krebs.bindfs = { - "/home/lass/.weechat" = { - source = "/var/state/lass_weechat"; - options = [ - "-M ${concatMapStringsSep ":" (u: toString config.users.users.${u}.uid) [ "syncthing" "mainUser" ]}" - "--create-for-user=${toString config.users.users.syncthing.uid}" - ]; - }; - "/home/lass/Maildir" = { - source = "/var/state/lass_mail"; - options = [ - "-M ${toString config.users.users.mainUser.uid}" - ]; - }; - "/var/lib/bitlbee" = { - source = "/var/state/bitlbee"; - options = [ - "-M ${toString config.users.users.bitlbee.uid}" - ]; - clearTarget = true; - }; - "/home/lass/.ssh" = { - source = "/var/state/lass_ssh"; - options = [ - "-M ${toString config.users.users.mainUser.uid}" - ]; - clearTarget = true; - }; - "/home/lass/.gnupg" = { - source = "/var/state/lass_gnupg"; - options = [ - "-M ${toString config.users.users.mainUser.uid}" - ]; - clearTarget = true; - }; - "/var/lib/git" = { - source = "/var/state/git"; - options = [ - "-M ${toString config.users.users.git.uid}" - ]; - clearTarget = true; - }; + lass.sync-containers3.inContainer = { + enable = true; + pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIFlUMf943qEQG64ob81p6dgoHq4jUjq7tSvmSdEOEU2y"; }; - systemd.services."bindfs-_home_lass_Maildir".serviceConfig.ExecStartPost = pkgs.writeDash "symlink-notmuch" '' - sleep 1 - mkdir -p /home/lass/notmuch - chown lass: /home/lass/notmuch - ln -sfTr /home/lass/notmuch /home/lass/Maildir/.notmuch + systemd.tmpfiles.rules = [ + "d /home/lass/.local/share 0700 lass users -" + "d /home/lass/.local 0700 lass users -" - mkdir -p /home/lass/notmuch/muchsync - chown lass: /home/lass/notmuch/muchsync - mkdir -p /home/lass/Maildir/.muchsync - ln -sfTr /home/lass/Maildir/.muchsync /home/lass/notmuch/muchsync/tmp - ''; + "d /var/state/lass_mail 0700 lass users -" + "L+ /home/lass/Maildir - - - - ../../var/state/lass_mail" + + "d /var/state/lass_ssh 0700 lass users -" + "L+ /home/lass/.ssh - - - - ../../var/state/lass_ssh" + "d /var/state/lass_gpg 0700 lass users -" + "L+ /home/lass/.gnupg - - - - ../../var/state/lass_gpg" + "d /var/state/lass_sync 0700 lass users -" + "L+ /home/lass/sync - - - - ../../var/state/lass_sync" + + "d /var/state/git 0700 git nogroup -" + "L+ /var/lib/git - - - - ../../var/state/git" + ]; + + users.users.mainUser.openssh.authorizedKeys.keys = [ + config.krebs.users.lass-android.pubkey + config.krebs.users.lass-tablet.pubkey + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKgpZwye6yavIs3gUIYvSi70spDa0apL2yHR0ASW74z8" # weechat ssh tunnel + ]; krebs.iptables.tables.nat.PREROUTING.rules = [ { predicate = "-i eth0 -p tcp -m tcp --dport 22"; target = "ACCEPT"; precedence = 101; } @@ -93,4 +65,11 @@ with import <stockholm/lib>; HostKeyAlgorithms +ssh-rsa PubkeyAcceptedAlgorithms +ssh-rsa ''; + + services.dovecot2 = { + enable = true; + mailLocation = "maildir:~/Maildir"; + }; + + networking.firewall.allowedTCPPorts = [ 143 ]; } diff --git a/lass/1systems/green/physical.nix b/lass/1systems/green/physical.nix index b6aa3a894..8577daf34 100644 --- a/lass/1systems/green/physical.nix +++ b/lass/1systems/green/physical.nix @@ -3,5 +3,5 @@ ./config.nix ]; boot.isContainer = true; - networking.useDHCP = false; + networking.useDHCP = true; } diff --git a/lass/1systems/green/source.nix b/lass/1systems/green/source.nix index da137e064..4acdb0c26 100644 --- a/lass/1systems/green/source.nix +++ b/lass/1systems/green/source.nix @@ -1,4 +1,6 @@ -{ lib, pkgs, test, ... }: -if test then {} else { +{ lib, pkgs, test, ... }: let + npkgs = lib.importJSON ../../../krebs/nixpkgs-unstable.json; +in if test then {} else { + nixpkgs.git.ref = lib.mkForce npkgs.rev; nixpkgs-unstable = lib.mkForce { file = "/var/empty"; }; } diff --git a/lass/1systems/prism/config.nix b/lass/1systems/prism/config.nix index 62c6f0b71..594a21c02 100644 --- a/lass/1systems/prism/config.nix +++ b/lass/1systems/prism/config.nix @@ -25,7 +25,6 @@ with import <stockholm/lib>; ]; } { # TODO make new hfos.nix out of this vv - boot.kernel.sysctl."net.ipv4.ip_forward" = 1; users.users.riot = { uid = genid_uint31 "riot"; isNormalUser = true; @@ -33,23 +32,10 @@ with import <stockholm/lib>; openssh.authorizedKeys.keys = [ "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6o6sdTu/CX1LW2Ff5bNDqGEAGwAsjf0iIe5DCdC7YikCct+7x4LTXxY+nDlPMeGcOF88X9/qFwdyh+9E4g0nUAZaeL14Uc14QDqDt/aiKjIXXTepxE/i4JD9YbTqStAnA/HYAExU15yqgUdj2dnHu7OZcGxk0ZR1OY18yclXq7Rq0Fd3pN3lPP1T4QHM9w66r83yJdFV9szvu5ral3/QuxQnCNohTkR6LoJ4Ny2RbMPTRtb+jPbTQYTWUWwV69mB8ot5nRTP4MRM9pu7vnoPF4I2S5DvSnx4C5zdKzsb7zmIvD4AmptZLrXj4UXUf00Xf7Js5W100Ne2yhYyhq+35 riot@lagrange" ]; - packages = [ - (pkgs.writeDashBin "kick-routing" '' - /run/wrappers/bin/sudo ${pkgs.systemd}/bin/systemctl restart krebs-iptables.service - '') - ]; }; - security.sudo.extraConfig = '' - riot ALL=(root) NOPASSWD: ${pkgs.systemd}/bin/systemctl restart krebs-iptables.service - ''; - - # TODO write function for proxy_pass (ssl/nonssl) - krebs.iptables.tables.filter.FORWARD.rules = [ - { v6 = false; precedence = 1000; predicate = "-d 192.168.122.141"; target = "ACCEPT"; } - ]; - krebs.iptables.tables.nat.PREROUTING.rules = [ - { v6 = false; precedence = 1000; predicate = "-d 95.216.1.130"; target = "DNAT --to-destination 192.168.122.141"; } + { v6 = false; precedence = 1000; predicate = "--destination 95.216.1.130"; target = "ACCEPT"; } + { v6 = false; precedence = 1000; predicate = "--source 95.216.1.130"; target = "ACCEPT"; } ]; } { @@ -125,6 +111,8 @@ with import <stockholm/lib>; <stockholm/lass/2configs/jitsi.nix> <stockholm/lass/2configs/fysiirc.nix> <stockholm/lass/2configs/bgt-bot> + <stockholm/lass/2configs/mumble-reminder.nix> + <stockholm/krebs/2configs/mastodon-proxy.nix> { services.tor = { enable = true; diff --git a/lass/1systems/prism/physical.nix b/lass/1systems/prism/physical.nix index 151cfbf41..027a27b2b 100644 --- a/lass/1systems/prism/physical.nix +++ b/lass/1systems/prism/physical.nix @@ -78,29 +78,31 @@ boot.loader.grub.version = 2; boot.loader.grub.devices = [ "/dev/sda" "/dev/sdb" ]; - boot.kernelParams = [ "net.ifnames=0" ]; + # we don't pay for power there and this might solve a problem we observed at least once + # https://www.thomas-krenn.com/de/wiki/PCIe_Bus_Error_Status_00001100_beheben + boot.kernelParams = [ "pcie_aspm=off" "net.ifnames=0" ]; networking.dhcpcd.enable = false; + + # bridge config + networking.bridges."ext-br".interfaces = [ "eth0" ]; networking = { hostId = "2283aaae"; defaultGateway = "95.216.1.129"; - defaultGateway6 = { address = "fe80::1"; interface = "eth0"; }; + defaultGateway6 = { address = "fe80::1"; interface = "ext-br"; }; # Use google's public DNS server nameservers = [ "8.8.8.8" ]; - interfaces.eth0.ipv4.addresses = [ + interfaces.ext-br.ipv4.addresses = [ { address = "95.216.1.150"; prefixLength = 26; } - { - address = "95.216.1.130"; - prefixLength = 26; - } ]; - interfaces.eth0.ipv6.addresses = [ + interfaces.ext-br.ipv6.addresses = [ { address = "2a01:4f9:2a:1e9::1"; prefixLength = 64; } ]; }; + } diff --git a/lass/1systems/shodan/config.nix b/lass/1systems/shodan/config.nix index 5d6a440e0..ef538f339 100644 --- a/lass/1systems/shodan/config.nix +++ b/lass/1systems/shodan/config.nix @@ -1,6 +1,5 @@ -{ config, pkgs, ... }: +{ config, lib, pkgs, ... }: -with import <stockholm/lib>; { imports = [ <stockholm/lass> @@ -17,11 +16,10 @@ with import <stockholm/lib>; <stockholm/lass/2configs/blue-host.nix> <stockholm/lass/2configs/green-host.nix> <stockholm/krebs/2configs/news-host.nix> - <stockholm/lass/2configs/nfs-dl.nix> + <stockholm/lass/2configs/prism-mounts/samba.nix> <stockholm/lass/2configs/fetchWallpaper.nix> - <stockholm/lass/2configs/home-media.nix> - <stockholm/lass/2configs/syncthing.nix> - <stockholm/lass/2configs/sync/sync.nix> + <stockholm/lass/2configs/consul.nix> + <stockholm/lass/2configs/red-host.nix> <stockholm/lass/2configs/snapclient.nix> ]; diff --git a/lass/1systems/shodan/physical.nix b/lass/1systems/shodan/physical.nix index 55e91b0e4..f94edcf9b 100644 --- a/lass/1systems/shodan/physical.nix +++ b/lass/1systems/shodan/physical.nix @@ -11,7 +11,6 @@ loader.grub.device = "/dev/sda"; initrd.luks.devices.lusksroot.device = "/dev/sda2"; - initrd.luks.cryptoModules = [ "aes" "sha512" "sha1" "xts" ]; initrd.availableKernelModules = [ "xhci_hcd" "ehci_pci" "ahci" "usb_storage" ]; }; fileSystems = { @@ -28,11 +27,6 @@ fsType = "btrfs"; options = ["defaults" "noatime" "ssd" "compress=lzo"]; }; - "/tmp" = { - device = "tmpfs"; - fsType = "tmpfs"; - options = ["nosuid" "nodev" "noatime"]; - }; "/bku" = { device = "/dev/pool/bku"; fsType = "btrfs"; diff --git a/lass/1systems/yellow/config.nix b/lass/1systems/yellow/config.nix index 554882bf3..c8077e5ea 100644 --- a/lass/1systems/yellow/config.nix +++ b/lass/1systems/yellow/config.nix @@ -1,6 +1,6 @@ -with import <stockholm/lib>; -{ config, lib, pkgs, ... }: -{ +{ config, lib, pkgs, ... }: let + vpnIp = "85.202.81.161"; +in { imports = [ <stockholm/lass> <stockholm/lass/2configs> @@ -11,6 +11,8 @@ with import <stockholm/lib>; users.groups.download.members = [ "transmission" ]; + networking.useHostResolvConf = false; + networking.useNetworkd = true; systemd.services.transmission.bindsTo = [ "openvpn-nordvpn.service" ]; systemd.services.transmission.after = [ "openvpn-nordvpn.service" ]; services.transmission = { @@ -154,17 +156,29 @@ with import <stockholm/lib>; tables.filter.INPUT.rules = [ { predicate = "-p tcp --dport 80"; target = "ACCEPT"; } # nginx web dir { predicate = "-p tcp --dport 9091"; target = "ACCEPT"; } # transmission-web + { predicate = "-p tcp --dport 9092"; target = "ACCEPT"; } # magnetico webinterface { predicate = "-p tcp --dport 51413"; target = "ACCEPT"; } # transmission-traffic { predicate = "-p udp --dport 51413"; target = "ACCEPT"; } # transmission-traffic { predicate = "-p tcp --dport 8096"; target = "ACCEPT"; } # jellyfin ]; + tables.filter.OUTPUT = { + policy = "DROP"; + rules = [ + { v6 = false; predicate = "-d ${vpnIp}/32"; target = "ACCEPT"; } + { predicate = "-o tun0"; target = "ACCEPT"; } + { predicate = "-o retiolum"; target = "ACCEPT"; } + { v6 = false; predicate = "-d 1.1.1.1/32"; target = "ACCEPT"; } + { v6 = false; predicate = "-d 1.0.0.1/32"; target = "ACCEPT"; } + { v6 = false; predicate = "-o eth0 -d 10.233.2.0/24"; target = "ACCEPT"; } + ]; + }; }; services.openvpn.servers.nordvpn.config = '' client dev tun proto udp - remote 196.240.57.43 1194 + remote ${vpnIp} 1194 resolv-retry infinite remote-random nobind @@ -174,7 +188,7 @@ with import <stockholm/lib>; persist-key persist-tun ping 15 - ping-restart 0 + ping-restart 15 ping-timer-rem reneg-sec 0 comp-lzo no @@ -250,7 +264,7 @@ with import <stockholm/lib>; path = [ pkgs.coreutils pkgs.findutils - pkgs.inotifyTools + pkgs.inotify-tools ]; serviceConfig = { Restart = "always"; @@ -271,4 +285,10 @@ with import <stockholm/lib>; enable = true; group = "download"; }; + + services.magnetico = { + enable = true; + web.address = "0.0.0.0"; + web.port = 9092; + }; } diff --git a/lass/2configs/IM.nix b/lass/2configs/IM.nix index 8567def02..8db2a05d6 100644 --- a/lass/2configs/IM.nix +++ b/lass/2configs/IM.nix @@ -24,7 +24,7 @@ in { restartIfChanged = false; path = [ - pkgs.rxvt_unicode.terminfo + pkgs.rxvt-unicode-unwrapped.terminfo ]; serviceConfig = { diff --git a/lass/2configs/alacritty.nix b/lass/2configs/alacritty.nix index 903ddf6cc..e5e001a4c 100644 --- a/lass/2configs/alacritty.nix +++ b/lass/2configs/alacritty.nix @@ -1,21 +1,23 @@ { config, lib, pkgs, ... }: let alacritty-cfg = extrVals: builtins.toJSON ({ - font = { + font = let + family = "Iosevka"; + in { normal = { - family = "Inconsolata"; + family = family; style = "Regular"; }; bold = { - family = "Inconsolata"; + family = family; style = "Bold"; }; italic = { - family = "Inconsolata"; + family = family; style = "Italic"; }; bold_italic = { - family = "Inconsolata"; + family = family; style = "Bold Italic"; }; size = 8; @@ -44,6 +46,7 @@ name = "alacritty"; paths = [ (pkgs.writeDashBin "alacritty" '' + ${pkgs.alacritty}/bin/alacritty --config-file /var/theme/config/alacritty.yaml msg create-window "$@" || ${pkgs.alacritty}/bin/alacritty --config-file /var/theme/config/alacritty.yaml "$@" '') pkgs.alacritty diff --git a/lass/2configs/atuin-server.nix b/lass/2configs/atuin-server.nix new file mode 100644 index 000000000..ad959a311 --- /dev/null +++ b/lass/2configs/atuin-server.nix @@ -0,0 +1,38 @@ +{ config, lib, pkgs, ... }: +{ + services.postgresql = { + enable = true; + dataDir = "/var/state/postgresql/${config.services.postgresql.package.psqlSchema}"; + ensureDatabases = [ "atuin" ]; + ensureUsers = [{ + name = "atuin"; + ensurePermissions."DATABASE atuin" = "ALL PRIVILEGES"; + }]; + }; + systemd.tmpfiles.rules = [ + "d /var/state/postgresql 0700 postgres postgres -" + ]; + users.groups.atuin = {}; + users.users.atuin = { + uid = pkgs.stockholm.lib.genid_uint31 "atuin"; + isSystemUser = true; + group = "atuin"; + home = "/run/atuin"; + createHome = true; + }; + + systemd.services.atuin = { + wantedBy = [ "multi-user.target" ]; + environment = { + ATUIN_HOST = "0.0.0.0"; + ATUIN_PORT = "8888"; + ATUIN_OPEN_REGISTRATION = "true"; + ATUIN_DB_URI = "postgres:///atuin"; + }; + serviceConfig = { + User = "atuin"; + ExecStart = "${pkgs.atuin}/bin/atuin server start"; + }; + }; + networking.firewall.allowedTCPPorts = [ 8888 ]; +} diff --git a/lass/2configs/baseX.nix b/lass/2configs/baseX.nix index e94cbbd2c..efd6c8a24 100644 --- a/lass/2configs/baseX.nix +++ b/lass/2configs/baseX.nix @@ -7,7 +7,6 @@ in { ./alacritty.nix ./mpv.nix ./power-action.nix - ./copyq.nix ./urxvt.nix ./xdg-open.nix ./yubikey.nix @@ -78,9 +77,10 @@ in { pavucontrol ponymix powertop - rxvt_unicode-with-plugins + rxvt-unicode sshvnc sxiv + nsxiv taskwarrior termite transgui @@ -105,10 +105,55 @@ in { enableGhostscriptFonts = true; fonts = with pkgs; [ - hack-font xorg.fontschumachermisc - terminus_font_ttf inconsolata + noto-fonts + (iosevka.override { + # https://typeof.net/Iosevka/customizer + privateBuildPlan = { + family = "Iosevka"; + spacing = "term"; + serifs = "slab"; + no-ligation = true; + + variants.design = { + capital-j = "serifless"; + a = "double-storey-tailed"; + b = "toothless-corner"; + d = "toothless-corner-serifless"; + f = "flat-hook-tailed"; + g = "earless-corner"; + i = "hooky"; + j = "serifless"; + l = "tailed"; + + m = "earless-corner-double-arch"; + n = "earless-corner-straight"; + p = "earless-corner"; + q = "earless-corner"; + r = "earless-corner"; + u = "toothless-rounded"; + y = "cursive-flat-hook"; + + one = "no-base-long-top-serif"; + two = "straight-neck"; + three = "flat-top"; + four = "open"; + six = "open-contour"; + seven = "straight-serifless"; + eight = "two-circles"; + nine = "open-contour"; + tilde = "low"; + asterisk = "hex-low"; + number-sign = "upright"; + at = "short"; + dollar = "open"; + percent = "dots"; + question = "corner-flat-hooked"; + }; + }; + set = "kookiefonts"; + }) ]; }; @@ -174,4 +219,20 @@ in { ''; }; }; + + services.clipmenu.enable = true; + + # synchronize all the clipboards + systemd.user.services.autocutsel = { + enable = true; + wantedBy = [ "graphical-session.target" ]; + after = [ "graphical-session.target" ]; + serviceConfig = { + Type = "forking"; + ExecStart = pkgs.writers.writeDash "autocutsel" '' + ${pkgs.autocutsel}/bin/autocutsel -fork -selection PRIMARY + ${pkgs.autocutsel}/bin/autocutsel -fork -selection CLIPBOARD + ''; + }; + }; } diff --git a/lass/2configs/blue-host.nix b/lass/2configs/blue-host.nix index 7aabf0931..532e55fe5 100644 --- a/lass/2configs/blue-host.nix +++ b/lass/2configs/blue-host.nix @@ -34,7 +34,7 @@ in { config = { ... }: { environment.systemPackages = [ pkgs.git - pkgs.rxvt_unicode.terminfo + pkgs.rxvt-unicode-unwrapped.terminfo ]; services.openssh.enable = true; users.users.root.openssh.authorizedKeys.keys = [ diff --git a/lass/2configs/consul.nix b/lass/2configs/consul.nix new file mode 100644 index 000000000..b8d925de5 --- /dev/null +++ b/lass/2configs/consul.nix @@ -0,0 +1,43 @@ +{ config, lib, pkgs, ... }: +{ + services.consul = { + enable = true; + # dropPrivileges = false; + webUi = true; + # interface.bind = "retiolum"; + extraConfig = { + bind_addr = config.krebs.build.host.nets.retiolum.ip4.addr; + bootstrap_expect = 3; + server = true; + # retry_join = config.services.consul.extraConfig.start_join; + retry_join = lib.mapAttrsToList (n: h: + lib.head h.nets.retiolum.aliases + ) (lib.filterAttrs (n: h: h.consul) config.krebs.hosts); + rejoin_after_leave = true; + + # try to fix random lock loss on leader reelection + retry_interval = "3s"; + performance = { + raft_multiplier = 8; + }; + }; + }; + + environment.etc."consul.d/testservice.json".text = builtins.toJSON { + service = { + name = "testing"; + }; + }; + + krebs.iptables.tables.filter.INPUT.rules = [ + { predicate = "-i retiolum -p tcp --dport 8300"; target = "ACCEPT"; } + { predicate = "-i retiolum -p tcp --dport 8301"; target = "ACCEPT"; } + { predicate = "-i retiolum -p udp --dport 8301"; target = "ACCEPT"; } + { predicate = "-i retiolum -p tcp --dport 8302"; target = "ACCEPT"; } + { predicate = "-i retiolum -p udp --dport 8302"; target = "ACCEPT"; } + { predicate = "-i retiolum -p tcp --dport 8400"; target = "ACCEPT"; } + { predicate = "-i retiolum -p tcp --dport 8500"; target = "ACCEPT"; } + { predicate = "-i retiolum -p tcp --dport 8600"; target = "ACCEPT"; } + { predicate = "-i retiolum -p udp --dport 8500"; target = "ACCEPT"; } + ]; +} diff --git a/lass/2configs/default.nix b/lass/2configs/default.nix index e8ac55988..49a04e9c2 100644 --- a/lass/2configs/default.nix +++ b/lass/2configs/default.nix @@ -98,7 +98,7 @@ with import <stockholm/lib>; jq #style - rxvt_unicode.terminfo + rxvt-unicode-unwrapped.terminfo #monitoring tools htop diff --git a/lass/2configs/et-server.nix b/lass/2configs/et-server.nix new file mode 100644 index 000000000..19961fb84 --- /dev/null +++ b/lass/2configs/et-server.nix @@ -0,0 +1,7 @@ +{ config, lib, pkgs, ... }: +{ + services.eternal-terminal = { + enable = true; + }; + networking.firewall.allowedTCPPorts = [ config.services.eternal-terminal.port ]; +} diff --git a/lass/2configs/green-host.nix b/lass/2configs/green-host.nix index a83ed0544..1e41e8e02 100644 --- a/lass/2configs/green-host.nix +++ b/lass/2configs/green-host.nix @@ -2,32 +2,9 @@ { imports = [ <stockholm/lass/2configs/container-networking.nix> - <stockholm/lass/2configs/syncthing.nix> ]; - krebs.sync-containers.containers.green = { - peers = [ - "echelon" - "icarus" - "littleT" - "mors" - "shodan" - "skynet" - "styx" - ]; - hostIp = "10.233.2.15"; - localIp = "10.233.2.16"; - format = "ecryptfs"; - }; - services.borgbackup.jobs.sync-green = { - encryption.mode = "none"; - paths = "/var/lib/sync-containers/green/ecryptfs"; - repo = "/var/lib/sync-containers/green/backup"; - compression = "auto,lzma"; - startAt = "daily"; - prune.keep = { - daily = 7; - weekly = 4; - }; + lass.sync-containers3.containers.green = { + sshKey = "${toString <secrets>}/green.sync.key"; }; } diff --git a/lass/2configs/libvirt.nix b/lass/2configs/libvirt.nix index 78d5ae0e9..d391e0d7b 100644 --- a/lass/2configs/libvirt.nix +++ b/lass/2configs/libvirt.nix @@ -1,8 +1,8 @@ { config, lib, pkgs, ... }: { - users.users.mainUser.extraGroups = [ "libvirtd" ]; virtualisation.libvirtd.enable = true; + security.polkit.enable = true; krebs.iptables.tables.filter.INPUT.rules = [ { v6 = false; predicate = "-i virbr0 -p udp -m udp --dport 53"; target = "ACCEPT"; } diff --git a/lass/2configs/mumble-reminder.nix b/lass/2configs/mumble-reminder.nix new file mode 100644 index 000000000..fe75a96a6 --- /dev/null +++ b/lass/2configs/mumble-reminder.nix @@ -0,0 +1,107 @@ +{ config, lib, pkgs, ... }: let + write_to_irc = chan: pkgs.writeDash "write_to_irc" '' + ${pkgs.curl}/bin/curl -fsSv --unix-socket '${lib.removePrefix "unix:" config.krebs.reaktor2.mumble-reminder.API.listen}' http://z/ \ + -H content-type:application/json \ + -d "$(${pkgs.jq}/bin/jq -n \ + --arg text "$1" '{ + command:"PRIVMSG", + params:["${chan}",$text] + }' + )" + ''; + animals = '' + Erdferkel + Paviane + Raupen + Australischen Wildhunde + Emus + Flundern + Gorillas + Kolibris + Schwarzfersenantilopen + Quallen + Kois + Faulaffen + Schraubenziegen + Nachtigalle + Okapis + Stachelschweine + Kurzschwanzkängurus + Waschbären + ''; + systemPlugin = { + plugin = "system"; + config = { + hooks.PRIVMSG = [ + { + pattern = "^erriner mich$"; + activate = "match"; + command = { + filename = pkgs.writeDash "add_remind" '' + echo "$_from" >> /var/lib/reaktor2-mumble-reminder/users + sort /var/lib/reaktor2-mumble-reminder/users | uniq > /var/lib/reaktor2-mumble-reminder/users.tmp + mv /var/lib/reaktor2-mumble-reminder/users.tmp /var/lib/reaktor2-mumble-reminder/users + echo "Ich werde $_from in zukunft an das meetup errinern" + ''; + }; + } + { + pattern = "^nerv nicht$"; + activate = "match"; + command = { + filename = pkgs.writeDash "add_remind" '' + ${pkgs.gnused}/bin/sed -i "/$_from/d" /var/lib/reaktor2-mumble-reminder/users + echo "okok, Ich werde $_from nich mehr errinern" + ''; + }; + } + ]; + }; + }; + +in { + krebs.reaktor2.mumble-reminder = { + hostname = "irc.hackint.org"; + nick = "lassulus__"; + API.listen = "unix:/var/lib/reaktor2-mumble-reminder/reaktor_hackint.sock"; + plugins = [ + { + plugin = "register"; + config = { + channels = [ + "#krebs" + "#nixos" + ]; + }; + } + systemPlugin + ]; + port = "6697"; + }; + systemd.services.mumble-reminder-nixos = { + description = "weekly reminder for nixos mumble"; + startAt = "Thu *-*-* 19:00:00 Europe/Berlin"; + serviceConfig = { + ExecStart = pkgs.writers.writeDash "mumble_reminder" '' + animals=' + ${animals} + ' + ${write_to_irc "#nixos"} "Es ist Donnerstag meine $(echo "$animals" | grep -v '^$' | shuf -n1 )!" + ${write_to_irc "#nixos"} "kommt auf mumble://lassul.us" + ''; + }; + }; + systemd.services.mumble-reminder-krebs = { + description = "weekly reminder for nixos mumble"; + startAt = "Thu *-*-* 19:00:00 Europe/Berlin"; + serviceConfig = { + ExecStart = pkgs.writers.writeDash "mumble_reminder" '' + animals=' + ${animals} + ' + ${write_to_irc "#krebs"} "Es ist Donnerstag meine $(echo "$animals" | grep -v '^$' | shuf -n1 )!" + ${write_to_irc "#krebs"} "$(cat /var/lib/reaktor2-mumble-reminder/users | ${pkgs.findutils}/bin/xargs echo) : mumble?" + ''; + }; + }; +} diff --git a/lass/2configs/pipewire.nix b/lass/2configs/pipewire.nix index f6ccd48d4..ec5a67b6e 100644 --- a/lass/2configs/pipewire.nix +++ b/lass/2configs/pipewire.nix @@ -9,7 +9,7 @@ }; environment.systemPackages = with pkgs; [ - alsaUtils + alsa-utils pulseaudio ponymix ]; diff --git a/lass/2configs/radio/default.nix b/lass/2configs/radio/default.nix index 2f503eae9..dfb3d7e0b 100644 --- a/lass/2configs/radio/default.nix +++ b/lass/2configs/radio/default.nix @@ -1,85 +1,54 @@ -{ config, pkgs, ... }: -with pkgs.stockholm.lib; +{ config, pkgs, lib, ... }: let name = "radio"; music_dir = "/home/radio/music"; - add_random = pkgs.writeDashBin "add_random" '' - ${pkgs.mpc_cli}/bin/mpc add "$(${pkgs.findutils}/bin/find "${music_dir}/the_playlist" \ - | grep -Ev '/other/|/.graveyard/' \ - | grep '\.ogg$' \ - | shuf -n1 \ - | sed 's,${music_dir}/,,' \ - )" - ''; - - get_current_track_position = pkgs.writeDash "get_current_track_position" '' - ${pkgs.mpc_cli}/bin/mpc status | ${pkgs.gawk}/bin/awk '/^\[playing\]/ { sub(/\/.+/,"",$3); split($3,a,/:/); print a[1]*60+a[2] }' - ''; - - skip_track = pkgs.writeBashBin "skip_track" '' + skip_track = pkgs.writers.writeBashBin "skip_track" '' set -eu - ${add_random}/bin/add_random - music_dir=${escapeShellArg music_dir} - current_track=$(${pkgs.mpc_cli}/bin/mpc current -f %file%) - track_infos=$(${print_current}/bin/print_current) - skip_count=$(${pkgs.attr}/bin/getfattr -n user.skip_count --only-values "$music_dir"/"$current_track" || echo 0) - if [[ "$current_track" =~ ^the_playlist/music/.* ]] && [ "$skip_count" -le 2 ]; then - skip_count=$((skip_count+1)) - ${pkgs.attr}/bin/setfattr -n user.skip_count -v "$skip_count" "$music_dir"/"$current_track" - echo skipping: "$track_infos" skip_count: "$skip_count" - else - mkdir -p "$music_dir"/the_playlist/.graveyard/ - mv "$music_dir"/"$current_track" "$music_dir"/the_playlist/.graveyard/ - echo killing: "$track_infos" - fi - ${pkgs.mpc_cli}/bin/mpc -q next + # TODO come up with new rating, without moving files + # current_track=$(${pkgs.curl}/bin/curl -fSs http://localhost:8002/current | ${pkgs.jq}/bin/jq -r .filename) + # track_infos=$(${print_current}/bin/print_current) + # skip_count=$(${pkgs.attr}/bin/getfattr -n user.skip_count --only-values "$current_track" || echo 0) + # if [[ "$current_track" =~ .*/the_playlist/music/.* ]] && [ "$skip_count" -le 2 ]; then + # skip_count=$((skip_count+1)) + # ${pkgs.attr}/bin/setfattr -n user.skip_count -v "$skip_count" "$current_track" + # echo skipping: "$track_infos" skip_count: "$skip_count" + # else + # mkdir -p "$music_dir"/the_playlist/.graveyard/ + # mv "$current_track" "$music_dir"/the_playlist/.graveyard/ + # echo killing: "$track_infos" + # fi + ${pkgs.curl}/bin/curl -fSs -X POST http://localhost:8002/skip | + ${pkgs.jq}/bin/jq -r '.filename' ''; good_track = pkgs.writeBashBin "good_track" '' set -eu - music_dir=${escapeShellArg music_dir} - current_track=$(${pkgs.mpc_cli}/bin/mpc current -f %file%) + current_track=$(${pkgs.curl}/bin/curl -fSs http://localhost:8002/current | ${pkgs.jq}/bin/jq -r .filename) track_infos=$(${print_current}/bin/print_current) - if [[ "$current_track" =~ ^the_playlist/music/.* ]]; then - ${pkgs.attr}/bin/setfattr -n user.skip_count -v 0 "$music_dir"/"$current_track" - else - mv "$music_dir"/"$current_track" "$music_dir"/the_playlist/music/ || : - fi + # TODO come up with new rating, without moving files + # if [[ "$current_track" =~ .*/the_playlist/music/.* ]]; then + # ${pkgs.attr}/bin/setfattr -n user.skip_count -v 0 "$current_track" + # else + # mv "$current_track" "$music_dir"/the_playlist/music/ || : + # fi echo good: "$track_infos" ''; - track_youtube_link = pkgs.writeDash "track_youtube_link" '' - ${pkgs.mpc_cli}/bin/mpc current -f %file% \ - | ${pkgs.gnused}/bin/sed 's@.*\(.\{11\}\)\.ogg@https://www.youtube.com/watch?v=\1@' - ''; - print_current = pkgs.writeDashBin "print_current" '' - echo "$(${pkgs.mpc_cli}/bin/mpc current -f %file%) \ - $(${track_youtube_link})" - ''; - - print_current_json = pkgs.writeDashBin "print_current_json" '' - ${pkgs.jq}/bin/jq -n -c \ - --arg name "$(${pkgs.mpc_cli}/bin/mpc current)" \ - --arg artist "$(${pkgs.mpc_cli}/bin/mpc current -f %artist%)" \ - --arg title "$(${pkgs.mpc_cli}/bin/mpc current -f %title%)" \ - --arg filename "$(${pkgs.mpc_cli}/bin/mpc current -f %file%)" \ - --arg position "$(${get_current_track_position})" \ - --arg length "$(${pkgs.mpc_cli}/bin/mpc current -f %time%)" \ - --arg youtube "$(${track_youtube_link})" '{ - name: $name, - artist: $artist, - title: $title, - filename: $filename, - position: $position, - length: $length, - youtube: $youtube - }' + file=$(${pkgs.curl}/bin/curl -fSs http://localhost:8002/current | + ${pkgs.jq}/bin/jq -r '.filename' | + ${pkgs.gnused}/bin/sed 's,^${music_dir},,' + ) + link=$(${pkgs.curl}/bin/curl http://localhost:8002/current | + ${pkgs.jq}/bin/jq -r '.filename' | + ${pkgs.gnused}/bin/sed 's@.*\(.\{11\}\)\.ogg@https://youtu.be/\1@' + ) + echo "$file": "$link" ''; set_irc_topic = pkgs.writeDash "set_irc_topic" '' @@ -113,15 +82,14 @@ in { users.users = { "${name}" = rec { inherit name; - createHome = mkForce false; + createHome = lib.mkForce false; group = name; - uid = genid_uint31 name; + uid = pkgs.stockholm.lib.genid_uint31 name; description = "radio manager"; home = "/home/${name}"; useDefaultShell = true; openssh.authorizedKeys.keys = with config.krebs.users; [ lass.pubkey - lass-mors.pubkey ]; }; }; @@ -131,50 +99,35 @@ in { }; krebs.per-user.${name}.packages = with pkgs; [ - add_random good_track skip_track print_current - print_current_json - ncmpcpp - mpc_cli ]; - services.mpd = { - enable = true; - user = "radio"; - musicDirectory = "${music_dir}"; - dataDir = "/home/radio/state"; # TODO create this somwhere - extraConfig = '' - log_level "default" - auto_update "yes" - volume_normalization "yes" + services.liquidsoap.streams.radio = ./radio.liq; + systemd.services.radio = { + environment = { + RADIO_PORT = "8002"; + HOOK_TRACK_CHANGE = pkgs.writers.writeDash "on_change" '' + set -xefu + LIMIT=1000 #how many tracks to keep in the history + HISTORY_FILE=/var/lib/radio/recent - audio_output { - type "httpd" - name "raw radio" - encoder "wave" - port "7900" - format "44100:16:2" - always_on "yes" # prevent MPD from disconnecting all listeners when playback is stopped. - tags "yes" # httpd supports sending tags to listening streams. - } - ''; + listeners=$(${pkgs.curl}/bin/curl -fSs lassul.us:8000/status-json.xsl | + ${pkgs.jq}/bin/jq '[.icestats.source[].listeners] | add' || echo 0) + echo "$(${pkgs.coreutils}/bin/date -Is)" "$filename" | ${pkgs.coreutils}/bin/tee -a "$HISTORY_FILE" + echo "$(${pkgs.coreutils}/bin/tail -$LIMIT "$HISTORY_FILE")" > "$HISTORY_FILE" + ${set_irc_topic} "playing: $filename listeners: $listeners" + ''; + MUSIC = "${music_dir}/the_playlist"; + ICECAST_HOST = "localhost"; + }; + path = [ + pkgs.yt-dlp + ]; + serviceConfig.User = lib.mkForce "radio"; }; - services.liquidsoap.streams.radio-news = pkgs.writeText "radio-news.liq" '' - source = mksafe(input.http("http://localhost:7900/raw.wave")) - output.icecast(mount = '/music.ogg', password = 'hackme', %vorbis(quality = 1), source) - output.icecast(mount = '/music.mp3', password = 'hackme', %mp3.vbr(), source) - output.icecast(mount = '/music.opus', password = 'hackme', %opus(bitrate = 96), source) - - extra_input = amplify(1.4, audio_to_stereo(input.harbor("live", port=1338))) - - o = smooth_add(normal = source, special = extra_input) - output.icecast(mount = '/radio.ogg', password = 'hackme', %vorbis(quality = 1), o) - output.icecast(mount = '/radio.mp3', password = 'hackme', %mp3.vbr(), o) - output.icecast(mount = '/radio.opus', password = 'hackme', %opus(bitrate = 96), o) - ''; services.icecast = { enable = true; hostname = "radio.lassul.us"; @@ -195,73 +148,8 @@ in { }; }; - systemd.timers.radio = { - description = "radio autoadder timer"; - wantedBy = [ "timers.target" ]; - - timerConfig = { - OnCalendar = "*:0/1"; - }; - }; - - systemd.services.radio = let - autoAdd = pkgs.writeDash "autoAdd" '' - LIMIT=$1 #in seconds - - timeLeft () { - playlistDuration=$(${pkgs.mpc_cli}/bin/mpc --format '%time%' playlist | ${pkgs.gawk}/bin/awk -F ':' 'BEGIN{t=0} {t+=$1*60+$2} END{print t}') - currentTime=$(${get_current_track_position}) - expr ''${playlistDuration:-0} - ''${currentTime:-0} - } - - if test $(timeLeft) -le $LIMIT; then - ${add_random}/bin/add_random - fi - ${pkgs.mpc_cli}/bin/mpc play > /dev/null - ''; - in { - description = "radio playlist autoadder"; - after = [ "network.target" ]; - - restartIfChanged = true; - - serviceConfig = { - ExecStart = "${autoAdd} 150"; - }; - }; - - systemd.services.radio-recent = let - recentlyPlayed = pkgs.writeDash "recentlyPlayed" '' - set -xefu - LIMIT=1000 #how many tracks to keep in the history - HISTORY_FILE=/var/lib/radio/recent - while :; do - ${pkgs.mpc_cli}/bin/mpc idle player > /dev/null - ${pkgs.mpc_cli}/bin/mpc current -f %file% - done | while read track; do - - listeners=$(${pkgs.curl}/bin/curl lassul.us:8000/status-json.xsl | - ${pkgs.jq}/bin/jq '[.icestats.source[].listeners] | add') - echo "$(date -Is)" "$track" | tee -a "$HISTORY_FILE" - echo "$(tail -$LIMIT "$HISTORY_FILE")" > "$HISTORY_FILE" - ${set_irc_topic} "playing: $track listeners: $listeners" - done - ''; - in { - description = "radio recently played"; - after = [ "mpd.service" "network.target" ]; - wantedBy = [ "multi-user.target" ]; - - restartIfChanged = true; - - serviceConfig = { - ExecStart = recentlyPlayed; - User = "radio"; - }; - }; - # allow reaktor2 to modify files - systemd.services."reaktor2-the_playlist".serviceConfig.DynamicUser = mkForce false; + systemd.services."reaktor2-the_playlist".serviceConfig.DynamicUser = lib.mkForce false; krebs.reaktor2.the_playlist = { hostname = "irc.hackint.org"; @@ -300,6 +188,12 @@ in { like.filename = "${good_track}/bin/good_track"; current.filename = "${print_current}/bin/print_current"; + wish.filename = pkgs.writeDash "wish" '' + echo "youtube-dl:$1" | ${pkgs.curl}/bin/curl -fSs http://localhost:8002/wish -d @- > /dev/null + ''; + wishlist.filename = pkgs.writeDash "wishlist" '' + ${pkgs.curl}/bin/curl -fSs http://localhost:8002/wish | ${pkgs.jq}/bin/jq -r '.[]' + ''; suggest.filename = pkgs.writeDash "suggest" '' echo "$@" >> playlist_suggest ''; @@ -316,15 +210,8 @@ in { user = { name = "radio"; }; - script = ''. ${pkgs.writeDash "radio" '' + scriptFile = pkgs.writeDash "radio" '' case "$Method $Request_URI" in - "GET /current") - printf 'HTTP/1.1 200 OK\r\n' - printf 'Connection: close\r\n' - printf '\r\n' - ${print_current_json}/bin/print_current_json - exit - ;; "POST /skip") printf 'HTTP/1.1 200 OK\r\n' printf 'Connection: close\r\n' @@ -344,7 +231,7 @@ in { exit ;; esac - ''}''; + ''; }; services.nginx = { @@ -365,7 +252,7 @@ in { alias /var/lib/radio/recent; ''; locations."= /current".extraConfig = '' - proxy_pass http://localhost:8001; + proxy_pass http://localhost:8002; ''; locations."= /skip".extraConfig = '' proxy_pass http://localhost:8001; @@ -375,10 +262,11 @@ in { ''; locations."= /radio.sh".alias = pkgs.writeScript "radio.sh" '' #!/bin/sh + trap 'exit 0' EXIT while sleep 1; do mpv \ --cache-secs=0 --demuxer-readahead-secs=0 --untimed --cache-pause=no \ - 'http://lassul.us:8000/radio.opus' + 'http://lassul.us:8000/radio.ogg' done ''; locations."= /controls".extraConfig = '' diff --git a/lass/2configs/radio/news.nix b/lass/2configs/radio/news.nix index e5b5405ff..0dc711e6c 100644 --- a/lass/2configs/radio/news.nix +++ b/lass/2configs/radio/news.nix @@ -3,7 +3,8 @@ let send_to_radio = pkgs.writers.writeDashBin "send_to_radio" '' ${pkgs.vorbis-tools}/bin/oggenc - | - ${pkgs.libshout}/bin/shout --format ogg --host localhost --port 1338 --mount /live + ${pkgs.cyberlocker-tools}/bin/cput news.ogg + ${pkgs.curl}/bin/curl -fSs -X POST http://localhost:8002/newsshow ''; gc_news = pkgs.writers.writeDashBin "gc_news" '' diff --git a/lass/2configs/radio/radio.liq b/lass/2configs/radio/radio.liq new file mode 100644 index 000000000..70d316043 --- /dev/null +++ b/lass/2configs/radio/radio.liq @@ -0,0 +1,112 @@ +log.stdout.set(true) + +# use yt-dlp +settings.protocol.youtube_dl.path.set("yt-dlp") + +## functions + +def stringify_attrs(attrs) = + let json.stringify out = (attrs : [(string * string)] as json.object) + out +end + +def filter_graveyard(req) = + filename = request.filename(req) + if string.match(pattern = '.*/\\.graveyard/.*', filename) then + false + else + true + end +end + +def queue_contents(q) = + list.map(fun (req) -> request.uri(req), q) +end +## main + +env = environment() +port = string.to_int(env["RADIO_PORT"], default = 8000) + +all_music = playlist(env["MUSIC"], check_next = filter_graveyard) +wishlist = request.queue() +tracks = fallback(track_sensitive = true, [wishlist, all_music]) +tracks = blank.eat(tracks) + +last_metadata = ref([]) +def on_metadata(m) = + last_metadata := m + print("changing tracks") + out = process.read(env["HOOK_TRACK_CHANGE"], env = m) + print(out) +end +tracks.on_metadata(on_metadata) + +# some nice effects +music = crossfade(tracks) +music = mksafe(music) +music = normalize(music) + +news = request.queue() +radio = smooth_add(normal = music, special = amplify(1.5, news)) + +if string.length(env["ICECAST_HOST"]) > 0 then + output.icecast(host = env["ICECAST_HOST"], mount = '/music.ogg', password = 'hackme', %vorbis(quality = 1), music) + output.icecast(host = env["ICECAST_HOST"], mount = '/music.mp3', password = 'hackme', %mp3.vbr(), music) + output.icecast(host = env["ICECAST_HOST"], mount = '/music.opus', password = 'hackme', %opus(bitrate = 128), music) + + output.icecast(host = env["ICECAST_HOST"], mount = '/radio.ogg', password = 'hackme', %vorbis(quality = 1), radio) + output.icecast(host = env["ICECAST_HOST"], mount = '/radio.mp3', password = 'hackme', %mp3.vbr(), radio) + output.icecast(host = env["ICECAST_HOST"], mount = '/radio.opus', password = 'hackme', %opus(bitrate = 128), radio) +else + output(fallible = true, buffer(radio)) +end + +interactive.harbor(port = port) + +def current(~protocol, ~headers, ~data, uri) = + http.response(content_type = "application/json", data = stringify_attrs( + !last_metadata + )) +end +harbor.http.register("/current", port = port, current) + +def skip(~protocol, ~headers, ~data, uri) = + tracks.skip() + http.response(content_type = "application/json", data = stringify_attrs( + !last_metadata + )) +end +harbor.http.register("/skip", method = "POST", port = port, skip) + +def all_tracks(~protocol, ~headers, ~data, uri) = + http.response(content_type = "application/json", data = json.stringify( + all_music.remaining_files() + )) +end +harbor.http.register("/all_tracks", port = port, all_tracks) + +def wish_track(~protocol, ~headers, ~data, uri) = + # disallow process: + if string.match(pattern = '^process:', data) then + http.response(code = 400) + else + # TODO report errors back + wish = request.create(data) + wishlist.push(wish) + http.response(content_type = "application/json", data = "ok") + end +end +harbor.http.register("/wish", method = "POST", port = port, wish_track) + +def wish_tracklist(~protocol, ~headers, ~data, uri) = + http.response(content_type = "application/json", data = json.stringify( + queue_contents(wishlist.queue()) + )) +end +harbor.http.register("/wish", port = port, wish_tracklist) + +def newsshow(~protocol, ~headers, ~data, uri) = + news.push(request.create("http://c.r/news.ogg")) + http.response(content_type = "application/json", data = "ok") +end +harbor.http.register("/newsshow", method = "POST", port = port, newsshow) diff --git a/lass/2configs/radio/shell.nix b/lass/2configs/radio/shell.nix new file mode 100644 index 000000000..9d00e3b06 --- /dev/null +++ b/lass/2configs/radio/shell.nix @@ -0,0 +1,7 @@ +{ pkgs ? import <nixpkgs> {} }: +pkgs.mkShell { + buildInputs = [ + pkgs.liquidsoap + pkgs.yt-dlp + ]; +} diff --git a/lass/2configs/radio/weather.nix b/lass/2configs/radio/weather.nix index 3beac6693..704bf7218 100644 --- a/lass/2configs/radio/weather.nix +++ b/lass/2configs/radio/weather.nix @@ -6,7 +6,7 @@ let } ./weather_for_ips.py; weather_report = pkgs.writers.writeDashBin "weather_report" '' - set -efu + set -efux export PATH="${lib.makeBinPath [ pkgs.coreutils pkgs.curl @@ -14,7 +14,7 @@ let pkgs.jc pkgs.jq ]}" - curl -z /tmp/GeoLite2-City.mmdb -o /tmp/GeoLite2-City.mmdb http://c.r/GeoLite2-City.mmdb + curl -fSsz /tmp/GeoLite2-City.mmdb -o /tmp/GeoLite2-City.mmdb http://c.r/GeoLite2-City.mmdb MAXMIND_GEOIP_DB="/tmp/GeoLite2-City.mmdb"; export MAXMIND_GEOIP_DB OPENWEATHER_API_KEY=$(cat "$CREDENTIALS_DIRECTORY/openweather_api"); export OPENWEATHER_API_KEY ss -no 'sport = :8000' | @@ -42,7 +42,7 @@ in { --arg to "$(date -u +'%FT%TZ' -d '+1 hours')" \ --slurp --raw-input --compact-output --ascii-output \ '{text: ., from: $from, to: $to, priority: 100}' | - retry -t 5 -d 10 -- curl -v -d@- http://radio-news.r + retry -t 5 -d 10 -- curl -fSs -d@- http://radio-news.r ''; startAt = "*:58:00"; serviceConfig = { diff --git a/lass/2configs/radio/weather_for_ips.py b/lass/2configs/radio/weather_for_ips.py index 587cc1f28..1f8489bd1 100644 --- a/lass/2configs/radio/weather_for_ips.py +++ b/lass/2configs/radio/weather_for_ips.py @@ -24,9 +24,10 @@ for ip in fileinput.input(): weather = json.loads(resp.text) output.append( f'Weather report for {location.city.name}, {location.country.name}. ' - f'Currently it is {weather["current"]["weather"][0]["description"]} outside ' + f'It is {weather["current"]["weather"][0]["description"]} outside ' f'with a temperature of {weather["current"]["temp"]:.1f} degrees, ' - f'and a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second. ' + f'a wind speed of {weather["current"]["wind_speed"]:.1f} meters per second ' + f'and a humidity of {weather["current"]["humidity"]} percent. ' f'The probability of precipitation is {weather["hourly"][0]["pop"] * 100:.0f} percent. ' ) diff --git a/lass/2configs/red-host.nix b/lass/2configs/red-host.nix new file mode 100644 index 000000000..cbd9c097e --- /dev/null +++ b/lass/2configs/red-host.nix @@ -0,0 +1,167 @@ +{ config, lib, pkgs, ... }: +let + ctr.name = "red"; +in +{ + imports = [ + <stockholm/lass/2configs/container-networking.nix> + ]; + + + lass.sync-containers3.containers.red = { + sshKey = "${toString <secrets>}/containers/red/sync.key"; + ephemeral = true; + }; + + # containers.${ctr.name} = { + # config = { + # environment.systemPackages = [ + # pkgs.dhcpcd + # pkgs.git + # pkgs.jq + # ]; + # networking.useDHCP = lib.mkForce true; + # systemd.services.autoswitch = { + # environment = { + # NIX_REMOTE = "daemon"; + # }; + # wantedBy = [ "multi-user.target" ]; + # serviceConfig.ExecStart = pkgs.writers.writeDash "autoswitch" '' + # if test -e /var/src/nixos-config; then + # /run/current-system/sw/bin/nixos-rebuild -I /var/src switch || : + # fi + # ''; + # unitConfig.X-StopOnRemoval = false; + # }; + # }; + # autoStart = false; + # enableTun = true; + # privateNetwork = true; + # hostBridge = "ctr0"; + # bindMounts = { + # "/etc/resolv.conf".hostPath = "/etc/resolv.conf"; + # "/var/lib/self-state/disk-image" = { + # hostPath = "/var/lib/sync-containers3/${ctr.name}"; + # isReadOnly = true; + # }; + # }; + # }; + + # systemd.services."${ctr.name}_scheduler" = { + # wantedBy = [ "multi-user.target" ]; + # path = with pkgs; [ + # coreutils + # consul + # cryptsetup + # mount + # util-linux + # systemd + # untilport + # ]; + # serviceConfig = { + # Restart = "always"; + # RestartSec = "15s"; + # ExecStart = "${pkgs.consul}/bin/consul lock container_${ctr.name} ${pkgs.writers.writeDash "${ctr.name}-start" '' + # set -efux + # trap ${pkgs.writers.writeDash "stop-${ctr.name}" '' + # set -efux + # /run/current-system/sw/bin/nixos-container stop ${ctr.name} || : + # umount /var/lib/nixos-containers/${ctr.name}/var/state || : + # cryptsetup luksClose ${ctr.name} || : + # ''} INT TERM EXIT + # consul kv put containers/${ctr.name}/host ${config.networking.hostName} + # cryptsetup luksOpen --key-file /var/src/secrets/containers/${ctr.name}/luks /var/lib/sync-containers3/${ctr.name}/disk ${ctr.name} + # mkdir -p /var/lib/nixos-containers/${ctr.name}/var/state + # mount /dev/mapper/${ctr.name} /var/lib/nixos-containers/${ctr.name}/var/state + # ln -frs /var/lib/nixos-containers/${ctr.name}/var/state/var_src /var/lib/nixos-containers/${ctr.name}/var/src + # /run/current-system/sw/bin/nixos-container start ${ctr.name} + # set +x + # until /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null; do sleep 5; done + # while /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null; do sleep 5; done + # ''}"; + # }; + # }; + + # users.groups."container_${ctr.name}" = {}; + # users.users."container_${ctr.name}" = { + # group = "container_${ctr.name}"; + # isSystemUser = true; + # home = "/var/lib/sync-containers3/${ctr.name}"; + # createHome = true; + # homeMode = "705"; + # openssh.authorizedKeys.keys = [ + # config.krebs.users.lass.pubkey + # ]; + # }; + + # systemd.timers."${ctr.name}_syncer" = { + # timerConfig = { + # RandomizedDelaySec = 300; + # }; + # }; + # systemd.services."${ctr.name}_syncer" = { + # path = with pkgs; [ + # coreutils + # rsync + # openssh + # systemd + # ]; + # startAt = "*:0/1"; + # serviceConfig = { + # User = "container_${ctr.name}"; + # LoadCredential = [ + # "ssh_key:${toString <secrets>}/containers/${ctr.name}/sync.key" + # ]; + # ExecCondition = pkgs.writers.writeDash "${ctr.name}_checker" '' + # set -efu + # ! systemctl is-active --quiet container@${ctr.name}.service + # ''; + # ExecStart = pkgs.writers.writeDash "${ctr.name}_syncer" '' + # set -efu + # rsync -a -e "ssh -i $CREDENTIALS_DIRECTORY/ssh_key" --inplace container_sync@${ctr.name}.r:disk-image/disk $HOME/disk + # ''; + # }; + # }; + + # # networking + # networking.networkmanager.unmanaged = [ "ctr0" ]; + # networking.interfaces.dummy0.virtual = true; + # networking.bridges.ctr0.interfaces = [ "dummy0" ]; + # networking.interfaces.ctr0.ipv4.addresses = [{ + # address = "10.233.0.1"; + # prefixLength = 24; + # }]; + # systemd.services."dhcpd-ctr0" = { + # wantedBy = [ "multi-user.target" ]; + # after = [ "network.target" ]; + # serviceConfig = { + # Type = "forking"; + # Restart = "always"; + # DynamicUser = true; + # StateDirectory = "dhcpd-ctr0"; + # User = "dhcpd-ctr0"; + # Group = "dhcpd-ctr0"; + # AmbientCapabilities = [ + # "CAP_NET_RAW" # to send ICMP messages + # "CAP_NET_BIND_SERVICE" # to bind on DHCP port (67) + # ]; + # ExecStartPre = "${pkgs.coreutils}/bin/touch /var/lib/dhcpd-ctr0/dhcpd.leases"; + # ExecStart = "${pkgs.dhcp}/bin/dhcpd -4 -lf /var/lib/dhcpd-ctr0/dhcpd.leases -cf ${pkgs.writeText "dhpd.conf" '' + # default-lease-time 600; + # max-lease-time 7200; + # authoritative; + # ddns-update-style interim; + # log-facility local1; # see dhcpd.nix + + # option subnet-mask 255.255.255.0; + # option routers 10.233.0.1; + # # option domain-name-servers 8.8.8.8; # TODO configure dns server + # subnet 10.233.0.0 netmask 255.255.255.0 { + # range 10.233.0.10 10.233.0.250; + # } + # ''} ctr0"; + # }; + # }; + +} + diff --git a/lass/2configs/websites/util.nix b/lass/2configs/websites/util.nix index 22b1669b0..bffa1036b 100644 --- a/lass/2configs/websites/util.nix +++ b/lass/2configs/websites/util.nix @@ -174,7 +174,6 @@ rec { services.phpfpm.pools."${domain}" = { user = "nginx"; group = "nginx"; - phpPackage = pkgs.php74; extraConfig = '' listen = /srv/http/${domain}/phpfpm.pool pm = dynamic @@ -228,7 +227,6 @@ rec { services.phpfpm.pools."${domain}" = { user = "nginx"; group = "nginx"; - phpPackage = pkgs.php74; extraConfig = '' listen = /srv/http/${domain}/phpfpm.pool pm = dynamic diff --git a/lass/2configs/weechat.nix b/lass/2configs/weechat.nix new file mode 100644 index 000000000..845a7e3b8 --- /dev/null +++ b/lass/2configs/weechat.nix @@ -0,0 +1,221 @@ +{ config, lib, pkgs, ... }: let + + weechat-configured = pkgs.weechat-declarative.override { + config = { + scripts = [ + pkgs.weechat-matrix + pkgs.weechatScripts.wee-slack + ]; + settings = { + irc.server_default.nicks = [ "lassulus" "hackulus" ]; + irc.server.bitlbee = { + addresses = "localhost/6666"; + command = "msg &bitlbee identify \${sec.data.bitlbee}"; + }; + irc.server.hackint = { + addresses = "irc.hackint.org/6697"; + autojoin = [ + "#c3-gsm" + "#panthermoderns" + "#36c3" + "#cccac" + "#nixos" + "#krebs" + "#c-base" + "#afra" + "#tvl" + "#eloop" + "#systemdultras" + "#rc3" + "#krebs-announce" + "#the_playlist" + "#germany" + "#hackint" + "#dezentrale" + "#hackerfleet \${sec.data.c3-gsm}" # TODO support channel passwords in a cooler way + ]; + ssl = true; + sasl_fail = "reconnect"; + sasl_username = "lassulus"; + sasl_password = "\${sec.data.hackint_sasl}"; + }; + irc.server.r = { + addresses = "irc.r"; + autojoin = [ + "#xxx" + "#autowifi" + "#brockman" + "#flix" + "#kollkoll" + "#noise" + "#mukke" + ]; + sasl_fail = "reconnect"; + sasl_username = "lassulus"; + sasl_password = "\${sec.data.r_sasl}"; + anti_flood_prio_high = 0; + anti_flood_prio_low = 0; + }; + irc.server.libera = { + addresses = "irc.libera.chat/6697"; + autojoin = [ + "#shackspace" + "#nixos" + "#krebs" + "#dezentrale" + "#tinc" + "#nixos-de" + "#fysi" + "#hillhacks" + "#nixos-rc3" + "#binaergewitter" + "#hackerfleet" + "#weechat" + ]; + ssl = true; + sasl_username = "lassulus"; + sasl_fail = "reconnect"; + sasl_password = "\${sec.data.libera_sasl}"; + }; + irc.server.news = { + addresses = "news.r"; + autojoin = [ + "#all" + "#aluhut" + "#querdenkos" + "#news" + "#drachengame" + ]; + anti_flood_prio_high = 0; + anti_flood_prio_low = 0; + }; + matrix.server.lassulus = { + address = "matrix.lassul.us"; + username = "lassulus"; + password = "\${sec.data.matrix_lassulus}"; + device_name = config.networking.hostName; + }; + matrix.server.nixos_dev = { + address = "matrix.nixos.dev"; + username = "@lassulus:nixos.dev"; + device_name = config.networking.hostName; + sso_helper_listening_port = 55123; + }; + plugins.var.python.go.short_name = true; + plugins.var.python.go.short_name_server = true; + plugins.var.python.go.fuzzy_search = true; + relay.network.password = "xxx"; # secret? + relay.port.weechat = 9998; + relay.weechat.commands = "*,!exec,!quit"; + weechat.look.buffer_time_format = "%m-%d_%H:%M:%S"; + weechat.look.item_time_format = "%m-%d_%H:%M:%S"; + irc.look.color_nicks_in_names = true; + irc.look.color_nicks_in_nicklist = true; + logger.file.mask = "$plugin.$name/%Y-%m-%d.weechatlog"; + logger.file.path = "/var/state/weechat_logs"; + logger.look.backlog = 1000; + weechat.notify.python.matrix.nixos_dev."!YLoVsCxScyQODoqIbb:hackint.org" = "none"; #c-base + weechat.notify.python.matrix.nixos_dev."!bohcSYPVoePqBDWlvE:hackint.org" = "none"; #krebs + weechat.notify.irc.news."#all" = "highlight"; + + # setting logger levels for channels is currently not possible declarativly + # because of already defined + logger.level.core.weechat = 0; + logger.level.irc = 3; + logger.level.python = 3; + weechat.bar.title.color_bg = 0; + weechat.bar.status.color_bg = 0; + alias.cmd.reload = "exec -oc cat /etc/weechat.set"; + script.scripts.download_enabled = true; + weechat.look.prefix_align = "left"; + weechat.look.prefix_align_max = 20; + irc.look.server_buffer = "independent"; + matrix.look.server_buffer = "independent"; + weechat.bar.buflist.size_max = 20; + weechat.color.chat_nick_colors = [ + 1 2 3 4 5 6 9 + 10 11 12 13 14 + 28 29 + 30 31 32 33 34 35 36 37 38 39 + 70 + 94 + 101 102 103 104 105 106 107 + 130 131 133 134 135 136 137 + 140 141 142 143 + 160 161 162 163 165 166 167 168 169 + 170 171 172 173 174 175 + 196 197 198 199 + 200 201 202 203 204 205 206 208 209 209 + 210 211 212 + ]; + }; + extraCommands = '' + /script upgrade + /script install go.py + /script install nickregain.pl + /script install autosort.py + /key bind meta-q /go + /key bind meta-t /bar toggle nicklist + /key bind meta-y /bar toggle buflist + /filter addreplace irc_smart * irc_smart_filter * + /filter addreplace playlist_topic irc.*.#the_playlist irc_topic * + /filter addreplace xxx_joinpart irc.r.#xxx irc_join,irc_part,irc_quit * + /set logger.level.irc.news 0 + /set logger.level.python.server.nixos_dev = 0; + /set logger.level.irc.hackint.#the_playlist = 0; + /connect bitlbee + /connect r + /connect news + /connect libera + /connect hackint + /matrix connect nixos_dev + /matrix connect lassulus + ''; + files."sec.conf" = toString (pkgs.writeText "sec.conf" '' + [crypt] + cipher = aes256 + hash_algo = sha256 + passphrase_command = "cat $CREDENTIALS_DIRECTORY/WEECHAT_PASSPHRASE" + salt = on + + [data] + __passphrase__ = on + hackint_sasl = "5CA242E92E7A09B180711B50C4AE2E65C42934EB4E584EC82BC1281D8C72CD411D590C16CC435687C0DA13759873CC" + libera_sasl = "9500B5AC3B29F9CAA273F1B89DC99550E038AF95C4B47442B1FB4CB9F0D6B86B26015988AD39E642CA9C4A78DED7F42D1F409B268C93E778" + r_sasl = "CB6FB1421ED5A9094CD2C05462DB1FA87C4A675628ABD9AEC9928A1A6F3F96C07D9F26472331BAF80B7B73270680EB1BBEFD" + c3-gsm = "C49DD845900CFDFA93EEBCE4F1ABF4A963EF6082B7DA6410FA701CC77A04BB6C201FCB864988C4F2B97ED7D44D5A28F162" + matrix.server.nixos_dev.access_token = "C40FE41B9B7B73553D51D8FCBD53871E940FE7FCCAB543E7F4720A924B8E1D58E2B1E1F460F5476C954A223F78CCB956337F6529159C0ECD7CB0384C13CB7170FF1270A577B1C4FF744D20FCF5C708259896F8D9" + bitlbee = "814ECAC59D9CF6E8340B566563E5D7E92AB92209B49C1EDE4CAAC32DD0DF1EC511D97C75E840C45D69BB9E3D03E79C" + matrix_lassulus = "0CA5C0F70A9F893881370F4A665B4CC40FBB1A41E53BC94916CD92B029103528611EC0B390116BE60FA79AE10F486E96E17B0824BE2DE1C97D87B88F5407330DAD70C044147533C36B09B7030CAD97" + ''); + }; + }; + +in { + users.users.mainUser.packages = [ + weechat-configured + ]; + environment.etc."weechat.set".source = "${weechat-configured}/weechat.set"; + systemd.tmpfiles.rules = [ + "d /var/state/weechat_logs 0700 lass users -" + "d /var/state/weechat 0700 lass users -" + "d /var/state/weechat_cfg 0700 lass users -" + "L+ /home/lass/.local/share/weechat - - - - ../../../../var/state/weechat" + "L+ /home/lass/.config/weechat - - - - ../../../../var/state/weechat_cfg" + ]; + + systemd.services.weechat = { + wantedBy = [ "multi-user.target" ]; + restartIfChanged = false; + serviceConfig = { + User = "lass"; + RemainAfterExit = true; + Type = "oneshot"; + LoadCredential = [ + "WEECHAT_PASSPHRASE:${toString <secrets>}/weechat_passphrase" + ]; + ExecStart = "${pkgs.tmux}/bin/tmux -2 new-session -d -s IM ${weechat-configured}/bin/weechat"; + ExecStop = "${pkgs.tmux}/bin/tmux kill-session -t IM"; # TODO run save in weechat + }; + }; +} diff --git a/lass/2configs/xmonad.nix b/lass/2configs/xmonad.nix index 3b372189c..8784da379 100644 --- a/lass/2configs/xmonad.nix +++ b/lass/2configs/xmonad.nix @@ -45,6 +45,7 @@ import XMonad.Layout.Minimize (minimize) import XMonad.Layout.NoBorders (smartBorders) import XMonad.Layout.MouseResizableTile (mouseResizableTile) import XMonad.Layout.SimplestFloat (simplestFloat) +import XMonad.Layout.StateFull import XMonad.ManageHook (composeAll) import XMonad.Prompt (autoComplete, font, searchPredicate, XPConfig) import XMonad.Prompt.Window (windowPromptGoto, windowPromptBringCopy) @@ -63,8 +64,6 @@ instance UrgencyHook LibNotifyUrgencyHook where safeSpawn "${pkgs.libnotify}/bin/notify-send" [show name, "workspace " ++ idx] myTerm :: FilePath --- myTerm = "${pkgs.rxvt_unicode-with-plugins}/bin/urxvtc -e /run/current-system/sw/bin/xonsh" --- myTerm = "${pkgs.rxvt_unicode-with-plugins}/bin/urxvtc" myTerm = "/run/current-system/sw/bin/alacritty" myFont :: String @@ -89,7 +88,7 @@ main = do myLayoutHook = defLayout where - defLayout = minimize . boringWindows $ ((avoidStruts $ Mirror (Tall 1 (3/100) (1/2))) ||| Full ||| FixedColumn 2 80 80 1 ||| Tall 1 (3/100) (1/2) ||| simplestFloat ||| mouseResizableTile ||| Grid) + defLayout = minimize . boringWindows $ ((avoidStruts $ Mirror (Tall 1 (3/100) (1/2))) ||| StateFull ||| FixedColumn 2 80 80 1 ||| Tall 1 (3/100) (1/2) ||| simplestFloat ||| mouseResizableTile ||| Grid) floatHooks = composeAll [ className =? "Pinentry" --> doCenterFloat @@ -152,7 +151,14 @@ myKeyMap = , ("M4-S-q", return ()) - , ("M4-d", floatNext True >> spawn "${pkgs.copyq}/bin/copyq show") + , ("M4-d", floatNext True >> spawn "${pkgs.writers.writeDash "clipmenu" '' + PATH=${lib.makeBinPath [ + pkgs.coreutils + pkgs.gawk + pkgs.dmenu + ]} + ${pkgs.clipmenu}/bin/clipmenu + ''}") , ("M4-<F2>", windows copyToAll) diff --git a/lass/2configs/zsh.nix b/lass/2configs/zsh.nix index 6571461ca..a7b0c372c 100644 --- a/lass/2configs/zsh.nix +++ b/lass/2configs/zsh.nix @@ -1,6 +1,17 @@ { config, lib, pkgs, ... }: { - environment.systemPackages = [ pkgs.fzf ]; + environment.systemPackages = with pkgs; [ + atuin + direnv + fzf + ]; + environment.variables.ATUIN_CONFIG_DIR = toString (pkgs.writeTextDir "/config.toml" '' + auto_sync = true + update_check = false + sync_address = "http://green.r:8888" + sync_frequency = 0 + style = "compact" + ''); programs.zsh = { enable = true; shellInit = '' @@ -12,27 +23,9 @@ setopt autocd extendedglob bindkey -e - #history magic - bindkey "[A" up-line-or-local-history - bindkey "[B" down-line-or-local-history - up-line-or-local-history() { - zle set-local-history 1 - zle up-line-or-history - zle set-local-history 0 - } - zle -N up-line-or-local-history - down-line-or-local-history() { - zle set-local-history 1 - zle down-line-or-history - zle set-local-history 0 - } - zle -N down-line-or-local-history - - setopt SHARE_HISTORY - setopt HIST_IGNORE_ALL_DUPS - # setopt inc_append_history - bindkey '^R' history-incremental-search-backward + # # setopt inc_append_history + # bindkey '^R' history-incremental-search-backward #C-x C-e open line in editor autoload -z edit-command-line @@ -43,6 +36,13 @@ source ${pkgs.fzf}/share/fzf/completion.zsh source ${pkgs.fzf}/share/fzf/key-bindings.zsh + # atuin distributed shell history + export ATUIN_NOBIND="true" # disable all keybdinings of atuin + eval "$(atuin init zsh)" + bindkey '^r' _atuin_search_widget # bind ctrl+r to atuin + # use zsh only session history + fc -p + #completion magic autoload -Uz compinit compinit @@ -65,13 +65,11 @@ bindkey "[8~" end-of-line bindkey "Oc" emacs-forward-word bindkey "Od" emacs-backward-word + + # direnv integration + eval "$(${pkgs.direnv}/bin/direnv hook zsh)" ''; promptInit = '' - # TODO: figure out why we need to set this here - HISTSIZE=900001 - HISTFILESIZE=$HISTSIZE - SAVEHIST=$HISTSIZE - autoload -U promptinit promptinit diff --git a/lass/3modules/default.nix b/lass/3modules/default.nix index 3a0b1306c..42efa8cd6 100644 --- a/lass/3modules/default.nix +++ b/lass/3modules/default.nix @@ -15,5 +15,6 @@ _: ./xjail.nix ./autowifi.nix ./browsers.nix + ./sync-containers3.nix ]; } diff --git a/lass/3modules/drbd.nix b/lass/3modules/drbd.nix index 816e58f0a..dbc3db4db 100644 --- a/lass/3modules/drbd.nix +++ b/lass/3modules/drbd.nix @@ -64,13 +64,42 @@ in { services.udev.packages = [ pkgs.drbd ]; boot.kernelModules = [ "drbd" ]; - environment.systemPackages = [ pkgs.drbd ]; + environment.systemPackages = [ + pkgs.drbd + (pkgs.writers.writeDashBin "drbd-change-nodeid" '' + # https://linbit.com/drbd-user-guide/drbd-guide-9_0-en/#s-using-truck-based-replication + set -efux + if [ "$#" -ne 2 ]; then + echo '$1 needs to be drbd volume name' + echo '$2 needs to be new node id' + exit 1 + fi + + + TMPDIR=$(mktemp -d) + trap 'rm -rf $TMPDIR' EXIT + + V=$1 + NODE_TO=$2 + META_DATA_LOCATION=internal + + ${pkgs.drbd}/bin/drbdadm -- --force dump-md $V > "$TMPDIR"/md_orig.txt + NODE_FROM=$(cat "$TMPDIR"/md_orig.txt | ${pkgs.gnused}/bin/sed -n 's/^node-id \(.*\);$/\1/p') + ${pkgs.gnused}/bin/sed -e "s/node-id $NODE_FROM/node-id $NODE_TO/" \ + -e "s/^peer.$NODE_FROM. /peer-NEW /" \ + -e "s/^peer.$NODE_TO. /peer[$NODE_FROM] /" \ + -e "s/^peer-NEW /peer[$NODE_TO] /" \ + < "$TMPDIR"/md_orig.txt > "$TMPDIR"/md.txt + + drbdmeta --force $(drbdadm sh-minor $V) v09 $(drbdadm sh-md-dev $V) $META_DATA_LOCATION restore-md "$TMPDIR"/md.txt + '') + ]; networking.firewall.allowedTCPPorts = map (device: device.port) (lib.attrValues cfg); systemd.services = lib.mapAttrs' (_: device: lib.nameValuePair "drbd-${device.name}" { - after = [ "systemd-udev.settle.service" "network.target" ]; + after = [ "systemd-udev.settle.service" "network.target" "retiolum.service" ]; wants = [ "systemd-udev.settle.service" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { @@ -88,7 +117,7 @@ in { ''} if ! ${pkgs.drbd}/bin/drbdadm adjust ${device.name}; then ${pkgs.drbd}/bin/drbdadm down ${device.name} - ${pkgs.drbd}/bin/drbdadm create-md ${device.name} + ${pkgs.drbd}/bin/drbdadm create-md ${device.name}/0 --max-peers 31 ${pkgs.drbd}/bin/drbdadm up ${device.name} fi ''; diff --git a/lass/3modules/sync-containers3.nix b/lass/3modules/sync-containers3.nix new file mode 100644 index 000000000..1371d5233 --- /dev/null +++ b/lass/3modules/sync-containers3.nix @@ -0,0 +1,313 @@ +{ config, lib, pkgs, ... }: let + cfg = config.lass.sync-containers3; + slib = pkgs.stockholm.lib; +in { + options.lass.sync-containers3 = { + inContainer = { + enable = lib.mkEnableOption "container config for syncing"; + pubkey = lib.mkOption { + type = lib.types.str; # TODO ssh key + }; + }; + containers = lib.mkOption { + default = {}; + type = lib.types.attrsOf (lib.types.submodule ({ config, ... }: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = config._module.args.name; + }; + sshKey = lib.mkOption { + type = slib.types.absolute-pathname; + }; + luksKey = lib.mkOption { + type = slib.types.absolute-pathname; + default = config.sshKey; + }; + ephemeral = lib.mkOption { + type = lib.types.bool; + default = false; + }; + }; + })); + }; + }; + config = lib.mkMerge [ + (lib.mkIf (cfg.containers != {}) { + + containers = lib.mapAttrs' (n: ctr: lib.nameValuePair ctr.name { + config = { + environment.systemPackages = [ + pkgs.dhcpcd + pkgs.git + pkgs.jq + ]; + networking.useDHCP = lib.mkForce true; + systemd.services.autoswitch = { + environment = { + NIX_REMOTE = "daemon"; + }; + wantedBy = [ "multi-user.target" ]; + serviceConfig.ExecStart = pkgs.writers.writeDash "autoswitch" '' + set -efu + ln -frs /var/state/var_src /var/src + if test -e /var/src/nixos-config; then + /run/current-system/sw/bin/nixos-rebuild -I /var/src switch || : + fi + ''; + unitConfig.X-StopOnRemoval = false; + }; + }; + autoStart = false; + enableTun = true; + ephemeral = ctr.ephemeral; + privateNetwork = true; + hostBridge = "ctr0"; + bindMounts = { + "/etc/resolv.conf".hostPath = "/etc/resolv.conf"; + "/var/lib/self/disk" = { + hostPath = "/var/lib/sync-containers3/${ctr.name}/disk"; + isReadOnly = false; + }; + "/var/state" = { + hostPath = "/var/lib/sync-containers3/${ctr.name}/state"; + isReadOnly = false; + }; + }; + }) cfg.containers; + + systemd.services = lib.foldr lib.recursiveUpdate {} (lib.flatten (map (ctr: [ + { "${ctr.name}_syncer" = { + path = with pkgs; [ + coreutils + consul + rsync + openssh + systemd + ]; + startAt = "*:0/1"; + serviceConfig = { + User = "${ctr.name}_container"; + LoadCredential = [ + "ssh_key:${ctr.sshKey}" + ]; + ExecCondition = pkgs.writers.writeDash "${ctr.name}_checker" '' + set -efu + ! systemctl is-active --quiet container@${ctr.name}.service + ''; + ExecStart = pkgs.writers.writeDash "${ctr.name}_syncer" '' + set -efux + consul lock sync_${ctr.name} ${pkgs.writers.writeDash "${ctr.name}-sync" '' + set -efux + if /run/wrappers/bin/ping -c 1 ${ctr.name}.r; then + touch "$HOME"/incomplete + rsync -a -e "ssh -i $CREDENTIALS_DIRECTORY/ssh_key" --inplace container_sync@${ctr.name}.r:disk "$HOME"/disk + rm "$HOME"/incomplete + fi + ''} + ''; + }; + }; } + { "${ctr.name}_watcher" = { + path = with pkgs; [ + coreutils + consul + cryptsetup + curl + mount + util-linux + jq + retry + ]; + serviceConfig = { + ExecStart = pkgs.writers.writeDash "${ctr.name}_watcher" '' + set -efux + while sleep 5; do + # get the payload + # check if the host reacted recently + case $(curl -s -o /dev/null --retry 10 --retry-delay 10 -w '%{http_code}' http://127.0.0.1:8500/v1/kv/containers/${ctr.name}) in + 404) + echo 'got 404 from kv, should kill the container' + break + ;; + 500) + echo 'got 500 from kv, will kill container' + break + ;; + 200) + # echo 'got 200 from kv, will check payload' + export payload=$(consul kv get containers/${ctr.name}) + if [ "$(jq -rn 'env.payload | fromjson.host')" = '${config.networking.hostName}' ]; then + # echo 'we are the host, trying to reach container' + if $(retry -t 10 -d 10 -- /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null); then + # echo 'container is reachable, continueing' + continue + else + # echo 'container seems dead, killing' + break + fi + else + echo 'we are not host, killing container' + break + fi + ;; + *) + echo 'unknown state, continuing' + continue + ;; + esac + done + /run/current-system/sw/bin/nixos-container stop ${ctr.name} || : + umount /var/lib/sync-containers3/${ctr.name}/state || : + cryptsetup luksClose ${ctr.name} || : + ''; + }; + }; } + { "${ctr.name}_scheduler" = { + wantedBy = [ "multi-user.target" ]; + path = with pkgs; [ + coreutils + consul + cryptsetup + mount + util-linux + curl + systemd + jq + retry + bc + ]; + serviceConfig = { + Restart = "always"; + RestartSec = "30s"; + ExecStart = pkgs.writers.writeDash "${ctr.name}_scheduler" '' + set -efux + # get the payload + # check if the host reacted recently + case $(curl -s -o /dev/null --retry 10 -w '%{http_code}' http://127.0.0.1:8500/v1/kv/containers/${ctr.name}) in + 404) + # echo 'got 404 from kv, will create container' + ;; + 500) + # echo 'got 500 from kv, retrying again' + exit 0 + ;; + 200) + # echo 'got 200 from kv, will check payload' + export payload=$(consul kv get containers/${ctr.name}) + if [ "$(jq -rn 'env.payload | fromjson.host')" = '${config.networking.hostName}' ]; then + echo 'we are the host, starting container' + else + # echo 'we are not host, checking timestamp' + # if [ $(echo "$(date +%s) - $(jq -rn 'env.payload | fromjson.time') > 100" | bc) -eq 1 ]; then + if [ "$(jq -rn 'env.payload | fromjson.time | now - tonumber > 100')" = 'true' ]; then + echo 'last beacon is more than 100s ago, taking over' + else + # echo 'last beacon was recent. trying again' + exit 0 + fi + fi + ;; + *) + echo 'unknown state, bailing out' + exit 0 + ;; + esac + if test -e /var/lib/sync-containers3/${ctr.name}/incomplete; then + echo 'data is inconistent, start aborted' + exit 1 + fi + consul kv put containers/${ctr.name} "$(jq -cn '{host: "${config.networking.hostName}", time: now}')" >/dev/null + consul lock -verbose -monitor-retry=100 -timeout 30s -name container_${ctr.name} container_${ctr.name} ${pkgs.writers.writeBash "${ctr.name}-start" '' + set -efu + cryptsetup luksOpen --key-file ${ctr.luksKey} /var/lib/sync-containers3/${ctr.name}/disk ${ctr.name} || : + mkdir -p /var/lib/sync-containers3/${ctr.name}/state + mountpoint /var/lib/sync-containers3/${ctr.name}/state || mount /dev/mapper/${ctr.name} /var/lib/sync-containers3/${ctr.name}/state + /run/current-system/sw/bin/nixos-container start ${ctr.name} + # wait for system to become reachable for the first time + retry -t 10 -d 10 -- /run/wrappers/bin/ping -q -c 1 ${ctr.name}.r > /dev/null + systemctl start ${ctr.name}_watcher.service + while systemctl is-active container@${ctr.name}.service >/devnull && /run/wrappers/bin/ping -q -c 3 ${ctr.name}.r >/dev/null; do + consul kv put containers/${ctr.name} "$(jq -cn '{host: "${config.networking.hostName}", time: now}')" >/dev/null + sleep 10 + done + ''} + ''; + }; + }; } + ]) (lib.attrValues cfg.containers))); + + systemd.timers = lib.mapAttrs' (n: ctr: lib.nameValuePair "${ctr.name}_syncer" { + timerConfig = { + RandomizedDelaySec = 100; + }; + }) cfg.containers; + + users.groups = lib.mapAttrs' (_: ctr: lib.nameValuePair "${ctr.name}_container" { + }) cfg.containers; + users.users = lib.mapAttrs' (_: ctr: lib.nameValuePair "${ctr.name}_container" ({ + group = "container_${ctr.name}"; + isNormalUser = true; + uid = slib.genid_uint31 "container_${ctr.name}"; + home = "/var/lib/sync-containers3/${ctr.name}"; + createHome = true; + homeMode = "705"; + })) cfg.containers; + + }) + (lib.mkIf (cfg.containers != {}) { + # networking + networking.networkmanager.unmanaged = [ "ctr0" ]; + networking.interfaces.dummy0.virtual = true; + networking.bridges.ctr0.interfaces = [ "dummy0" ]; + networking.interfaces.ctr0.ipv4.addresses = [{ + address = "10.233.0.1"; + prefixLength = 24; + }]; + systemd.services."dhcpd-ctr0" = { + wantedBy = [ "multi-user.target" ]; + after = [ "network.target" ]; + serviceConfig = { + Type = "forking"; + Restart = "always"; + DynamicUser = true; + StateDirectory = "dhcpd-ctr0"; + User = "dhcpd-ctr0"; + Group = "dhcpd-ctr0"; + AmbientCapabilities = [ + "CAP_NET_RAW" # to send ICMP messages + "CAP_NET_BIND_SERVICE" # to bind on DHCP port (67) + ]; + ExecStartPre = "${pkgs.coreutils}/bin/touch /var/lib/dhcpd-ctr0/dhcpd.leases"; + ExecStart = "${pkgs.dhcp}/bin/dhcpd -4 -lf /var/lib/dhcpd-ctr0/dhcpd.leases -cf ${pkgs.writeText "dhpd.conf" '' + default-lease-time 600; + max-lease-time 7200; + authoritative; + ddns-update-style interim; + log-facility local1; # see dhcpd.nix + + option subnet-mask 255.255.255.0; + option routers 10.233.0.1; + # option domain-name-servers 8.8.8.8; # TODO configure dns server + subnet 10.233.0.0 netmask 255.255.255.0 { + range 10.233.0.10 10.233.0.250; + } + ''} ctr0"; + }; + }; + }) + (lib.mkIf cfg.inContainer.enable { + users.groups.container_sync = {}; + users.users.container_sync = { + group = "container_sync"; + uid = slib.genid_uint31 "container_sync"; + isNormalUser = true; + home = "/var/lib/self"; + createHome = true; + openssh.authorizedKeys.keys = [ + cfg.inContainer.pubkey + ]; + }; + }) + ]; +} diff --git a/lass/5pkgs/drbd9/default.nix b/lass/5pkgs/drbd9/default.nix new file mode 100644 index 000000000..34ef0f564 --- /dev/null +++ b/lass/5pkgs/drbd9/default.nix @@ -0,0 +1,35 @@ +{ lib, stdenv, git, fetchzip, fetchFromGitHub, kernel }: let + + version = "9.1.7"; + +in stdenv.mkDerivation { + pname = "drbd"; + version = "${kernel.version}-${version}"; + + src = fetchzip { + url = "https://pkg.linbit.com//downloads/drbd/9/drbd-9.1.7.tar.gz"; + sha256 = "sha256-JsbtOrqhZkG7tFEc6tDmj3RlxZggl0HOKfCI8lYtQok="; + }; + # src = fetchFromGitHub { + # owner = "LINBIT"; + # repo = "drbd"; + # rev = "drbd-${version}"; + # sha256 = "sha256-8HAt+k0yi6XsZZ9mkVCQkv2pn65o3Zsa0KwTSBJh0yY="; + # leaveDotGit = true; + # }; + + nativeBuildInputs = [ git ] ++ kernel.moduleBuildDependencies; + + # hardeningDisable = [ "pic" ]; + + makeFlags = kernel.makeFlags ++ [ + "KDIR=${kernel.dev}/lib/modules/${kernel.modDirVersion}/build" + ]; + + installPhase = '' + install -D drbd/drbd.ko -t "$out/lib/modules/${kernel.modDirVersion}/updates/" + install -D drbd/drbd_transport_tcp.ko -t "$out/lib/modules/${kernel.modDirVersion}/updates/" + ''; + + enableParallelBuilding = true; +} diff --git a/lass/5pkgs/sxiv/default.nix b/lass/5pkgs/sxiv/default.nix new file mode 100644 index 000000000..04fc1c3f6 --- /dev/null +++ b/lass/5pkgs/sxiv/default.nix @@ -0,0 +1,27 @@ +{ nsxiv, writers }: + +writers.writeDashBin "sxiv" '' + set -efu + tmpfile="''${TMPDIR:-/tmp}/nsxiv_pipe_$$" + trap 'rm -f -- $tmpfile' EXIT + + if [ "$#" -eq 0 ]; then + if [ -t 0 ]; then + echo "sxiv: No arguments provided" >&2; exit 1 + else + # Consume stdin and put it in the temporal file + cat > "$tmpfile" + fi + fi + + for arg in "$@"; do + # if it's a pipe then drain it to $tmpfile + [ -p "$arg" ] && cat "$arg" > "$tmpfile" + done + + if [ -s "$tmpfile" ]; then + ${nsxiv}/bin/nsxiv -q "$@" "$tmpfile" # -q to silence warnings + else + ${nsxiv}/bin/nsxiv "$@" # fallback + fi +'' diff --git a/lass/5pkgs/weechat-matrix/default.nix b/lass/5pkgs/weechat-matrix/default.nix new file mode 100644 index 000000000..40848caaa --- /dev/null +++ b/lass/5pkgs/weechat-matrix/default.nix @@ -0,0 +1,80 @@ +{ python3Packages +, lib +, fetchFromGitHub +}: + +with python3Packages; + +let + scriptPython = python.withPackages (ps: with ps; [ + aiohttp + requests + python_magic + ]); + + version = "lassulus-fork"; +in python3Packages.buildPythonPackage { + pname = "weechat-matrix"; + inherit version; + + src = fetchFromGitHub { + owner = "poljar"; + repo = "weechat-matrix"; + rev = version; + hash = "sha256-o4kgneszVLENG167nWnk2FxM+PsMzi+PSyMUMIktZcc="; + }; + # src = ./weechat-matrix; + + propagatedBuildInputs = [ + pyopenssl + webcolors + future + atomicwrites + attrs + Logbook + pygments + matrix-nio + aiohttp + requests + ]; + + passthru.scripts = [ "matrix.py" ]; + + dontBuild = true; + doCheck = false; + + format = "other"; + + installPhase = '' + mkdir -p $out/share $out/bin + cp main.py $out/share/matrix.py + + cp contrib/matrix_upload.py $out/bin/matrix_upload + cp contrib/matrix_decrypt.py $out/bin/matrix_decrypt + cp contrib/matrix_sso_helper.py $out/bin/matrix_sso_helper + substituteInPlace $out/bin/matrix_upload \ + --replace '/usr/bin/env -S python3' '${scriptPython}/bin/python' + substituteInPlace $out/bin/matrix_sso_helper \ + --replace '/usr/bin/env -S python3' '${scriptPython}/bin/python' + substituteInPlace $out/bin/matrix_decrypt \ + --replace '/usr/bin/env python3' '${scriptPython}/bin/python' + + mkdir -p $out/${python.sitePackages} + cp -r matrix $out/${python.sitePackages}/matrix + ''; + + dontPatchShebangs = true; + postFixup = '' + addToSearchPath program_PYTHONPATH $out/${python.sitePackages} + patchPythonScript $out/share/matrix.py + substituteInPlace $out/${python.sitePackages}/matrix/server.py --replace \"matrix_sso_helper\" \"$out/bin/matrix_sso_helper\" + ''; + + meta = with lib; { + description = "A Python plugin for Weechat that lets Weechat communicate over the Matrix protocol"; + homepage = "https://github.com/poljar/weechat-matrix"; + license = licenses.isc; + platforms = platforms.unix; + maintainers = with maintainers; [ tilpner emily ]; + }; +} |
