summaryrefslogtreecommitdiffstats
path: root/lass
diff options
context:
space:
mode:
Diffstat (limited to 'lass')
-rw-r--r--lass/1systems/daedalus/config.nix1
-rw-r--r--lass/1systems/green/config.nix97
-rw-r--r--lass/1systems/green/physical.nix2
-rw-r--r--lass/1systems/green/source.nix6
-rw-r--r--lass/1systems/prism/config.nix20
-rw-r--r--lass/1systems/prism/physical.nix18
-rw-r--r--lass/1systems/shodan/config.nix10
-rw-r--r--lass/1systems/shodan/physical.nix6
-rw-r--r--lass/1systems/yellow/config.nix32
-rw-r--r--lass/2configs/IM.nix2
-rw-r--r--lass/2configs/alacritty.nix13
-rw-r--r--lass/2configs/atuin-server.nix38
-rw-r--r--lass/2configs/baseX.nix69
-rw-r--r--lass/2configs/blue-host.nix2
-rw-r--r--lass/2configs/consul.nix43
-rw-r--r--lass/2configs/default.nix2
-rw-r--r--lass/2configs/et-server.nix7
-rw-r--r--lass/2configs/green-host.nix27
-rw-r--r--lass/2configs/libvirt.nix2
-rw-r--r--lass/2configs/mumble-reminder.nix107
-rw-r--r--lass/2configs/pipewire.nix2
-rw-r--r--lass/2configs/radio/default.nix248
-rw-r--r--lass/2configs/radio/news.nix3
-rw-r--r--lass/2configs/radio/radio.liq112
-rw-r--r--lass/2configs/radio/shell.nix7
-rw-r--r--lass/2configs/radio/weather.nix6
-rw-r--r--lass/2configs/radio/weather_for_ips.py5
-rw-r--r--lass/2configs/red-host.nix167
-rw-r--r--lass/2configs/websites/util.nix2
-rw-r--r--lass/2configs/weechat.nix221
-rw-r--r--lass/2configs/xmonad.nix14
-rw-r--r--lass/2configs/zsh.nix50
-rw-r--r--lass/3modules/default.nix1
-rw-r--r--lass/3modules/drbd.nix35
-rw-r--r--lass/3modules/sync-containers3.nix313
-rw-r--r--lass/5pkgs/drbd9/default.nix35
-rw-r--r--lass/5pkgs/sxiv/default.nix27
-rw-r--r--lass/5pkgs/weechat-matrix/default.nix80
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 "" up-line-or-local-history
- bindkey "" 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 ];
+ };
+}