Compare commits

..

2 Commits

Author SHA1 Message Date
fab83a3034 kartei/mic92: update ryan's key 2023-07-01 17:38:45 +02:00
lassulus
b76bd892a0 reaktor2: use new bing api 2023-06-11 15:00:02 +00:00
237 changed files with 2843 additions and 3000 deletions

17
flake.lock generated
View File

@ -1,21 +1,5 @@
{ {
"nodes": { "nodes": {
"nix-writers": {
"flake": false,
"locked": {
"lastModified": 1677612737,
"narHash": "sha256-UaCKZ4PbMZU6UZH7XNFcjRtd5jheswl66rjZDBfQgp8=",
"ref": "refs/heads/master",
"rev": "66a1f6833464bbb121b6d94247ad769f277351f8",
"revCount": 39,
"type": "git",
"url": "https://cgit.krebsco.de/nix-writers"
},
"original": {
"type": "git",
"url": "https://cgit.krebsco.de/nix-writers"
}
},
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1686135559, "lastModified": 1686135559,
@ -34,7 +18,6 @@
}, },
"root": { "root": {
"inputs": { "inputs": {
"nix-writers": "nix-writers",
"nixpkgs": "nixpkgs" "nixpkgs": "nixpkgs"
} }
} }

View File

@ -1,41 +0,0 @@
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
nix-writers = {
url = "git+https://cgit.krebsco.de/nix-writers";
flake = false;
};
# disko.url = "github:nix-community/disko";
# disko.inputs.nixpkgs.follows = "nixpkgs";
};
description = "stockholm";
outputs = { self, nixpkgs, nix-writers }: {
nixosConfigurations.hotdog = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs.stockholm = self;
specialArgs.nix-writers = nix-writers;
specialArgs.secrets = toString ./krebs/0tests/data/secrets;
modules = [
./krebs/1systems/hotdog/config.nix
];
};
nixosModules =
let
inherit (nixpkgs) lib;
in builtins.listToAttrs
(map
(name: {name = lib.removeSuffix ".nix" name; value = import (./krebs/3modules + "/${name}");})
(lib.filter
(name: name != "default.nix" && !lib.hasPrefix "." name)
(lib.attrNames (builtins.readDir ./krebs/3modules))));
kartei = {
hosts = self.nixosConfigurations.hotdog.config.krebs.hosts;
users = self.nixosConfigurations.hotdog.config.krebs.users;
};
lib = import (self.outPath + "/lib/pure.nix") { lib = nixpkgs.lib; };
};
}

View File

@ -1,13 +1,12 @@
{ config, lib, ... }: let with import ../../lib;
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate; { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
external = true; external = true;
monitoring = false; monitoring = false;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}); });
in { in {
users = { users = {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; }; lib = import ../../lib;
in { in {
users.dave = { users.dave = {
mail = "hsngrmpf@gmail.com"; mail = "hsngrmpf@gmail.com";
@ -8,7 +8,7 @@ in {
owner = config.krebs.users.dave; owner = config.krebs.users.dave;
nets.retiolum = { nets.retiolum = {
aliases = [ "dave.r" ]; aliases = [ "dave.r" ];
ip6.addr = (slib.krebs.genipv6 "retiolum" "dave" { hostName = "dave"; }).address; ip6.addr = (lib.krebs.genipv6 "retiolum" "dave" { hostName = "dave"; }).address;
ip4.addr = "10.243.0.6"; ip4.addr = "10.243.0.6";
tinc.pubkey = '' tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----

View File

@ -1,7 +1,6 @@
{ config, lib, ... }: with import ../../lib;
{ config, ... }:
let let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
external = true; external = true;
@ -9,11 +8,11 @@ let
owner = config.krebs.users.dbalan; owner = config.krebs.users.dbalan;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum = { nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}; };
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = { nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}; };
}); });
in in

View File

@ -9,7 +9,7 @@ in {
(name: _type: let (name: _type: let
path = ./. + "/${name}"; path = ./. + "/${name}";
in { in {
krebs = import path { inherit config lib; }; krebs = import path { inherit config; };
}) })
(removeTemplate (removeTemplate
(lib.filterAttrs (lib.filterAttrs

View File

@ -1,6 +1,5 @@
{ config, lib, ... }: let with import ../../lib;
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate; { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
owner = config.krebs.users.feliks; owner = config.krebs.users.feliks;
ci = false; ci = false;
@ -8,10 +7,10 @@
monitoring = false; monitoring = false;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill.ip6.addr = nets.wiregrill.ip6.addr =
(slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}); });
in { in {
users.feliks = { users.feliks = {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; }; lib = import ../../lib;
in { in {
users.jan = { users.jan = {
@ -39,7 +39,6 @@ in {
nets = { nets = {
retiolum = { retiolum = {
ip4.addr = "10.243.143.11"; ip4.addr = "10.243.143.11";
ip6.addr = (slib.krebs.genipv6 "retiolum" "jan" { hostName = "petrosilia"; }).address;
aliases = [ aliases = [
"petrosilia.r" "petrosilia.r"
]; ];
@ -68,7 +67,7 @@ in {
nets.retiolum = { nets.retiolum = {
aliases = [ "grill.r" ]; aliases = [ "grill.r" ];
ip4.addr = "10.243.217.217"; ip4.addr = "10.243.217.217";
ip6.addr = (slib.krebs.genipv6 "retiolum" "jan" { hostName = "grill"; }).address; ip6.addr = (lib.krebs.genipv6 "retiolum" "jan" { hostName = "grill"; }).address;
tinc.pubkey = '' tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAs4P6CfRcwFGCqkfv1tyTbbk2eHh08kEqxPNQ655sMKWxMhgRnRII MIICCgKCAgEAs4P6CfRcwFGCqkfv1tyTbbk2eHh08kEqxPNQ655sMKWxMhgRnRII

View File

@ -1,12 +1,12 @@
{ config, lib, ... }: let with import ../../lib;
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate; { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = true; ci = true;
owner = config.krebs.users.jeschli; owner = config.krebs.users.jeschli;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "jeschli" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "jeschli" { inherit hostName; }).address;
}); });
in { in {

View File

@ -1,7 +1,6 @@
{ config, lib, ... }: with import ../../lib;
{ config, ... }:
let let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
maybeEmpty = attrset: key: if (attrset?key) then attrset.${key} else []; maybeEmpty = attrset: key: if (attrset?key) then attrset.${key} else [];
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
@ -10,11 +9,11 @@ let
owner = config.krebs.users.kmein; owner = config.krebs.users.kmein;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum = { nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}; };
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = { nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}; };
}); });
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub"); ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");

View File

@ -1,12 +1,11 @@
{ config, lib, ... }: let with import ../../lib;
inherit (lib) flip genAttrs mapAttrs optionalAttrs recursiveUpdate; { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
owner = config.krebs.users.krebs; owner = config.krebs.users.krebs;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "krebs" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "krebs" { inherit hostName; }).address;
}); });
testHosts = genAttrs [ testHosts = genAttrs [
@ -67,6 +66,7 @@ in {
tinc.pubkey_ed25519 = "D5TYSZW9OAkdnvQ/NL98UgheRC2Zg4SMNZ8M4/KwdeL"; tinc.pubkey_ed25519 = "D5TYSZW9OAkdnvQ/NL98UgheRC2Zg4SMNZ8M4/KwdeL";
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKRpjW68lSlTL8jBQcXKOTdGa+olQw5ghaU5df2yAE64"; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKRpjW68lSlTL8jBQcXKOTdGa+olQw5ghaU5df2yAE64";
}; };
hotdog = { hotdog = {
@ -100,6 +100,7 @@ in {
tinc.pubkey_ed25519 = "ugy/sGReVro3YzjDuroV/5hdeBdqD18no9dMhTy9DYL"; tinc.pubkey_ed25519 = "ugy/sGReVro3YzjDuroV/5hdeBdqD18no9dMhTy9DYL";
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxFkBln23wUxt4RhIHE3GvdKeBpJbjn++6maupHqUHp"; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICxFkBln23wUxt4RhIHE3GvdKeBpJbjn++6maupHqUHp";
}; };
news = { news = {
@ -132,6 +133,7 @@ in {
''; '';
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHl5cDF9QheXyMlNYIX17ILbgd94K50fZy7w0fDLvZlo "; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHl5cDF9QheXyMlNYIX17ILbgd94K50fZy7w0fDLvZlo ";
}; };
onebutton = { onebutton = {
@ -159,6 +161,7 @@ in {
''; '';
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAcZg+iLaPZ0SpLM+nANxIjZC/RIsansjyutK0+gPhIe "; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAcZg+iLaPZ0SpLM+nANxIjZC/RIsansjyutK0+gPhIe ";
}; };
ponte = { ponte = {
@ -205,6 +208,7 @@ in {
}; };
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEw9fo8Qtb/DTLacdrJP7Ti7c4UXTm6wUUX+iRFweEo "; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJEw9fo8Qtb/DTLacdrJP7Ti7c4UXTm6wUUX+iRFweEo ";
}; };
puyak = { puyak = {
@ -230,6 +234,7 @@ in {
''; '';
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPpVwKv9mQGfcn5oFwuitq+b6Dz4jBG9sGhVoCYFw5RY"; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPpVwKv9mQGfcn5oFwuitq+b6Dz4jBG9sGhVoCYFw5RY";
syncthing.id = "DK5CEE2-PNUXYCE-Q42H2HP-623GART-B7KS4VK-HU2RBGQ-EK6QPUP-HUL3PAR"; syncthing.id = "DK5CEE2-PNUXYCE-Q42H2HP-623GART-B7KS4VK-HU2RBGQ-EK6QPUP-HUL3PAR";
}; };
@ -254,6 +259,7 @@ in {
''; '';
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOu6EVN3928qWiWszqBUzOjeQJRvFozTBl4xAhBP/Ymc"; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOu6EVN3928qWiWszqBUzOjeQJRvFozTBl4xAhBP/Ymc";
}; };
wolf = { wolf = {
@ -290,6 +296,7 @@ in {
''; '';
}; };
}; };
ssh.privkey.path = <secrets/ssh.id_ed25519>;
ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKYMXMWZIK0jjnZDM9INiYAKcwjXs2241vew54K8veCR"; ssh.pubkey = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKYMXMWZIK0jjnZDM9INiYAKcwjXs2241vew54K8veCR";
}; };
} // testHosts); } // testHosts);

View File

@ -1,8 +1,8 @@
{ config, lib, ... }: let with import ../../lib;
slib = import ../../lib/pure.nix { inherit lib; }; { config, ... }: let
r6 = ip: (slib.krebs.genipv6 "retiolum" "lass" ip).address; r6 = ip: (krebs.genipv6 "retiolum" "lass" ip).address;
w6 = ip: (slib.krebs.genipv6 "wiregrill" "lass" ip).address; w6 = ip: (krebs.genipv6 "wiregrill" "lass" ip).address;
hostFiles = hostFiles =
builtins.map (lib.removeSuffix ".nix") ( builtins.map (lib.removeSuffix ".nix") (
builtins.filter builtins.filter
@ -14,17 +14,14 @@ in {
dns.providers = { dns.providers = {
"lassul.us" = "zones"; "lassul.us" = "zones";
}; };
hosts = lib.mapAttrs (_: lib.recursiveUpdate { hosts = mapAttrs (_: recursiveUpdate {
owner = config.krebs.users.lass; owner = config.krebs.users.lass;
consul = true; consul = true;
ci = true; ci = true;
monitoring = true; monitoring = true;
ssh.privkey.path = <secrets/ssh.id_ed25519>; ssh.privkey.path = <secrets/ssh.id_ed25519>;
}) ( }) (
lib.genAttrs hostFiles (host: import (./. + "/${host}.nix") { lib.genAttrs hostFiles (host: import (./. + "/${host}.nix") { inherit config krebs lib r6 w6; })
inherit config lib r6 w6;
inherit (slib) krebs;
})
); );
users = rec { users = rec {
lass = lass-yubikey; lass = lass-yubikey;

View File

@ -2,10 +2,8 @@
# tinc generate-keys # tinc generate-keys
# ssh-keygen -f ssh.id_ed25519 -t ed25519 -C host # ssh-keygen -f ssh.id_ed25519 -t ed25519 -C host
{ config, lib, ... }: let with import ../../lib;
inherit (builtins) foldl' mapAttrs pathExists readFile; { config, ... }: let
inherit (lib) optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: foldl' recursiveUpdate {} [ hostDefaults = hostName: host: foldl' recursiveUpdate {} [
{ {
@ -21,7 +19,7 @@
"${hostName}.r" "${hostName}.r"
]; ];
ip6.addr = ip6.addr =
(slib.krebs.genipv6 "retiolum" "makefu" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "makefu" { inherit hostName; }).address;
}; };
}) })
# Retiolum ed25519 keys # Retiolum ed25519 keys
@ -39,7 +37,7 @@
"${hostName}.w" "${hostName}.w"
]; ];
ip6.addr = ip6.addr =
(slib.krebs.genipv6 "wiregrill" "makefu" { inherit hostName; }).address; (krebs.genipv6 "wiregrill" "makefu" { inherit hostName; }).address;
wireguard.pubkey = readFile pubkey-path; wireguard.pubkey = readFile pubkey-path;
}; };
}) })
@ -56,7 +54,7 @@
]; ];
pub-for = name: builtins.readFile (./ssh + "/${name}.pub"); pub-for = name: builtins.readFile (./ssh + "/${name}.pub");
w6 = ip: (slib.krebs.genipv6 "wiregrill" "makefu" ip).address; w6 = ip: (krebs.genipv6 "wiregrill" "makefu" ip).address;
in { in {
hosts = mapAttrs hostDefaults { hosts = mapAttrs hostDefaults {
cake = rec { cake = rec {
@ -106,8 +104,7 @@ in {
nets = { nets = {
retiolum.ip4.addr = "10.243.0.91"; retiolum.ip4.addr = "10.243.0.91";
wiregrill = { wiregrill = {
ip4.addr = "10.243.245.6"; # defaults
aliases = [ "x.w" ];
}; };
}; };
@ -123,12 +120,6 @@ in {
ci = true; ci = true;
syncthing.id = "Y5OTK3S-JOJLAUU-KTBXKUW-M7S5UEQ-MMQPUK2-7CXO5V6-NOUDLKP-PRGAFAK"; syncthing.id = "Y5OTK3S-JOJLAUU-KTBXKUW-M7S5UEQ-MMQPUK2-7CXO5V6-NOUDLKP-PRGAFAK";
nets = { nets = {
wiregrill = {
aliases = ["omo.w" "hass.omo.w" "jelly.omo.w" "jelly.makefu.w" ];
ip6.addr = (slib.krebs.genipv6 "wiregrill" "makefu" { hostName = "omo"; }).address;
ip4.addr = "10.244.245.5";
};
retiolum = { retiolum = {
ip4.addr = "10.243.0.89"; ip4.addr = "10.243.0.89";
aliases = [ aliases = [
@ -158,7 +149,7 @@ in {
# pixel3a # pixel3a
telex.nets.wiregrill = { telex.nets.wiregrill = {
aliases = ["telex.w"]; aliases = ["telex.w"];
ip6.addr = (slib.krebs.genipv6 "wiregrill" "makefu" { hostName = "telex"; }).address; ip6.addr = (krebs.genipv6 "wiregrill" "makefu" { hostName = "telex"; }).address;
ip4.addr = "10.244.245.4"; ip4.addr = "10.244.245.4";
}; };
@ -248,7 +239,6 @@ in {
play.work.euer IN A ${nets.internet.ip4.addr} play.work.euer IN A ${nets.internet.ip4.addr}
ul.work.euer IN A ${nets.internet.ip4.addr} ul.work.euer IN A ${nets.internet.ip4.addr}
music.euer IN A ${nets.internet.ip4.addr} music.euer IN A ${nets.internet.ip4.addr}
ntfy.euer IN A ${nets.internet.ip4.addr}
''; '';
}; };
nets = rec { nets = rec {
@ -265,7 +255,7 @@ in {
ip6.addr = w6 "1"; ip6.addr = w6 "1";
wireguard.port = 51821; wireguard.port = 51821;
wireguard.subnets = [ wireguard.subnets = [
(slib.krebs.genipv6 "wiregrill" "makefu" 0).subnetCIDR (krebs.genipv6 "wiregrill" "makefu" 0).subnetCIDR
"10.244.245.0/24" # required for routing directly to gum via rockit "10.244.245.0/24" # required for routing directly to gum via rockit
]; ];
}; };

View File

@ -1 +1 @@
lKMWnuEVjcSoSEUWrj+51pwDQrQj2TqloL3aBKVWBbO Ed25519PublicKey = lKMWnuEVjcSoSEUWrj+51pwDQrQj2TqloL3aBKVWBbO

View File

@ -1 +0,0 @@
JmcpzkwgKymVecZqaV0ODQactoVwGGlEHcfYIOCkx3A=

View File

@ -1,13 +1,12 @@
{ config, lib, ... }: let with import ../../lib;
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate; { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
external = true; external = true;
monitoring = false; monitoring = false;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}); });
in { in {
hosts = mapAttrs hostDefaults { hosts = mapAttrs hostDefaults {

View File

@ -1,6 +1,5 @@
{ config, lib, ... }: let with import ../../lib;
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate; { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
@ -8,10 +7,10 @@
monitoring = false; monitoring = false;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill.ip6.addr = nets.wiregrill.ip6.addr =
(slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}); });
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub"); ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");
tinc-for = name: builtins.readFile (./tinc + "/${name}.pub"); tinc-for = name: builtins.readFile (./tinc + "/${name}.pub");

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; }; lib = import ../../lib;
in { in {
users.oxzi = { users.oxzi = {
mail = "post@0x21.biz"; mail = "post@0x21.biz";
@ -13,7 +13,7 @@ in {
"gosh.r" "gosh.r"
]; ];
ip4.addr = "10.243.32.1"; ip4.addr = "10.243.32.1";
ip6.addr = (slib.krebs.genipv6 "retiolum" "oxzi" { hostName = "ancha"; }).address; ip6.addr = (lib.krebs.genipv6 "retiolum" "oxzi" { hostName = "ancha"; }).address;
tinc.pubkey = '' tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEA5RSP7nWZ1c04kvQBxoHqcdRKpJuRDzD3f0Nl2KhS7QsAqHJGdK7T MIICCgKCAgEA5RSP7nWZ1c04kvQBxoHqcdRKpJuRDzD3f0Nl2KhS7QsAqHJGdK7T
@ -39,7 +39,7 @@ in {
"marohu.oxzi.r" "marohu.oxzi.r"
]; ];
ip4.addr = "10.243.32.2"; ip4.addr = "10.243.32.2";
ip6.addr = (slib.krebs.genipv6 "retiolum" "oxzi" { hostName = "marohu"; }).address; ip6.addr = (lib.krebs.genipv6 "retiolum" "oxzi" { hostName = "marohu"; }).address;
tinc.pubkey = '' tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEAxHLkvuH9JMXay/fEmoWTEqLHg9A50EzkxPVBn4nyezgp5vxsUqJz MIICCgKCAgEAxHLkvuH9JMXay/fEmoWTEqLHg9A50EzkxPVBn4nyezgp5vxsUqJz

View File

@ -1,7 +1,6 @@
{ config, lib, ... }: with import ../../lib;
{ config, ... }:
let let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
@ -9,10 +8,10 @@ let
monitoring = false; monitoring = false;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill.ip6.addr = nets.wiregrill.ip6.addr =
(slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}); });
in in

View File

@ -1,8 +1,6 @@
{ config, lib, ... }: with import ../../lib;
{ config, ... }:
let let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
external = true; external = true;
@ -10,11 +8,11 @@ let
owner = config.krebs.users.rtunreal; owner = config.krebs.users.rtunreal;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum = { nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}; };
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = { nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}; };
}); });
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub"); ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");

View File

@ -1,12 +1,13 @@
{ config, lib, ... }: let { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; }; lib = import ../../lib;
hostDefaults = hostName: host: lib.flip lib.recursiveUpdate host ({ hostDefaults = hostName: host: lib.flip lib.recursiveUpdate host ({
ci = false; ci = false;
external = true; external = true;
monitoring = false; monitoring = false;
} // lib.optionalAttrs (host.nets?retiolum) { } // lib.optionalAttrs (host.nets?retiolum) {
nets.retiolum.ip6.addr = nets.retiolum.ip6.addr =
(slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; (lib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}); });
in { in {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: let { config, ... }: let
slib = import ../../lib/pure.nix { inherit lib; }; lib = import ../../lib;
in { in {
users.DUMMYUSER = { users.DUMMYUSER = {
mail = "DUMMYUSER@example.ork"; mail = "DUMMYUSER@example.ork";
@ -8,7 +8,7 @@ in {
owner = config.krebs.users.DUMMYUSER; owner = config.krebs.users.DUMMYUSER;
nets.retiolum = { nets.retiolum = {
aliases = [ "DUMMYHOST.DUMMYUSER.r" ]; aliases = [ "DUMMYHOST.DUMMYUSER.r" ];
ip6.addr = (slib.krebs.genipv6 "retiolum" "DUMMYUSER" { hostName = "DUMMYHOST"; }).address; ip6.addr = (lib.krebs.genipv6 "retiolum" "DUMMYUSER" { hostName = "DUMMYHOST"; }).address;
tinc.pubkey = '' tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----
DUMMYTINCPUBKEYRSA DUMMYTINCPUBKEYRSA

View File

@ -1,11 +1,5 @@
{ config, lib, ... }@attrs: let with import ../../lib;
inherit (builtins) { config, ... }: {
getAttr head mapAttrs match pathExists readDir readFile typeOf;
inherit (lib)
const hasAttrByPath mapAttrs' mkDefault mkIf optionalAttrs removeSuffix
toList;
slib = import ../../lib/pure.nix { inherit lib; };
in {
dns.providers = { dns.providers = {
"viljetic.de" = "regfish"; "viljetic.de" = "regfish";
}; };
@ -14,10 +8,10 @@ in {
(hostName: hostFile: let (hostName: hostFile: let
hostSource = import hostFile; hostSource = import hostFile;
hostConfig = getAttr (typeOf hostSource) { hostConfig = getAttr (typeOf hostSource) {
lambda = hostSource attrs; lambda = hostSource { inherit config lib; };
set = hostSource; set = hostSource;
}; };
in slib.evalSubmodule slib.types.host [ in evalSubmodule types.host [
hostConfig hostConfig
{ {
name = hostName; name = hostName;
@ -26,7 +20,7 @@ in {
(optionalAttrs (hasAttrByPath ["nets" "retiolum"] hostConfig) { (optionalAttrs (hasAttrByPath ["nets" "retiolum"] hostConfig) {
nets.retiolum = { nets.retiolum = {
ip6.addr = ip6.addr =
(slib.krebs.genipv6 "retiolum" "tv" { inherit hostName; }).address; (krebs.genipv6 "retiolum" "tv" { inherit hostName; }).address;
}; };
}) })
(let (let
@ -37,14 +31,14 @@ in {
"${hostName}.w" "${hostName}.w"
]; ];
ip6.addr = ip6.addr =
(slib.krebs.genipv6 "wiregrill" "tv" { inherit hostName; }).address; (krebs.genipv6 "wiregrill" "tv" { inherit hostName; }).address;
wireguard.pubkey = readFile pubkey-path; wireguard.pubkey = readFile pubkey-path;
}; };
}) })
(host: mkIf (host.config.ssh.pubkey != null) { (host: mkIf (host.config.ssh.pubkey != null) {
ssh.privkey = mapAttrs (const mkDefault) { ssh.privkey = mapAttrs (const mkDefault) {
path = config.krebs.secret.file "ssh.id_${host.config.ssh.privkey.type}"; path = config.krebs.secret.file "ssh.id_${host.config.ssh.privkey.type}";
type = head (toList (builtins.match "ssh-([^ ]+) .*" host.config.ssh.pubkey)); type = head (toList (match "ssh-([^ ]+) .*" host.config.ssh.pubkey));
}; };
}) })
]) ])

View File

@ -1,6 +1,4 @@
{ config, lib, ... }: let { config, lib, ... }: {
slib = import ../../../lib/pure.nix { inherit lib; };
in {
extraZones = { extraZones = {
"krebsco.de" = '' "krebsco.de" = ''
ni 60 IN A ${config.krebs.hosts.ni.nets.internet.ip4.addr} ni 60 IN A ${config.krebs.hosts.ni.nets.internet.ip4.addr}
@ -62,7 +60,7 @@ in {
via = config.krebs.hosts.ni.nets.internet; via = config.krebs.hosts.ni.nets.internet;
ip4.addr = "10.244.3.1"; ip4.addr = "10.244.3.1";
wireguard.subnets = [ wireguard.subnets = [
(slib.krebs.genipv6 "wiregrill" "tv" 0).subnetCIDR (lib.krebs.genipv6 "wiregrill" "tv" 0).subnetCIDR
]; ];
}; };
}; };

View File

@ -1,7 +1,6 @@
{ config, lib, ... }: with import ../../lib;
{ config, ... }:
let let
inherit (lib) flip mapAttrs optionalAttrs recursiveUpdate;
slib = import ../../lib/pure.nix { inherit lib; };
maybeEmpty = attrset: key: if (attrset?key) then attrset.${key} else []; maybeEmpty = attrset: key: if (attrset?key) then attrset.${key} else [];
hostDefaults = hostName: host: flip recursiveUpdate host ({ hostDefaults = hostName: host: flip recursiveUpdate host ({
ci = false; ci = false;
@ -10,11 +9,11 @@ let
owner = config.krebs.users.xkey; owner = config.krebs.users.xkey;
} // optionalAttrs (host.nets?retiolum) { } // optionalAttrs (host.nets?retiolum) {
nets.retiolum = { nets.retiolum = {
ip6.addr = (slib.krebs.genipv6 "retiolum" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "retiolum" "external" { inherit hostName; }).address;
}; };
} // optionalAttrs (host.nets?wiregrill) { } // optionalAttrs (host.nets?wiregrill) {
nets.wiregrill = { nets.wiregrill = {
ip6.addr = (slib.krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address; ip6.addr = (krebs.genipv6 "wiregrill" "external" { inherit hostName; }).address;
}; };
}); });
ssh-for = name: builtins.readFile (./ssh + "/${name}.pub"); ssh-for = name: builtins.readFile (./ssh + "/${name}.pub");

View File

@ -1,6 +1,6 @@
{ config, lib, ... }: { config, ... }:
let let
slib = import ../../lib/pure.nix { inherit lib; }; lib = import ../../lib;
in in
{ {
users.ynnel = { users.ynnel = {
@ -10,7 +10,7 @@ in
owner = config.krebs.users.ynnel; owner = config.krebs.users.ynnel;
nets.retiolum = { nets.retiolum = {
aliases = [ "mokemoke.ynnel.r" ]; aliases = [ "mokemoke.ynnel.r" ];
ip6.addr = (slib.krebs.genipv6 "retiolum" "ynnel" { hostName = "mokemoke"; }).address; ip6.addr = (lib.krebs.genipv6 "retiolum" "ynnel" { hostName = "mokemoke"; }).address;
tinc.pubkey = '' tinc.pubkey = ''
-----BEGIN RSA PUBLIC KEY----- -----BEGIN RSA PUBLIC KEY-----
MIICCgKCAgEA7rS560SZEPcSekW30dRF6ZTHOnb8WvuVgt3BFLRWhTgV5DqLqFa8 MIICCgKCAgEA7rS560SZEPcSekW30dRF6ZTHOnb8WvuVgt3BFLRWhTgV5DqLqFa8

View File

@ -9,15 +9,15 @@ in
{ {
imports = [ imports = [
./hw.nix ./hw.nix
../../../krebs <stockholm/krebs>
../../../krebs/2configs <stockholm/krebs/2configs>
#../../../krebs/2configs/binary-cache/nixos.nix #<stockholm/krebs/2configs/binary-cache/nixos.nix>
#../../../krebs/2configs/binary-cache/prism.nix #<stockholm/krebs/2configs/binary-cache/prism.nix>
../../../krebs/2configs/shack/ssh-keys.nix <stockholm/krebs/2configs/shack/ssh-keys.nix>
../../../krebs/2configs/save-diskspace.nix <stockholm/krebs/2configs/save-diskspace.nix>
../../../krebs/2configs/shack/prometheus/node.nix <stockholm/krebs/2configs/shack/prometheus/node.nix>
]; ];
# use your own binary cache, fallback use cache.nixos.org (which is used by # use your own binary cache, fallback use cache.nixos.org (which is used by

View File

@ -5,16 +5,16 @@ in
{ {
imports = [ imports = [
./hardware-configuration.nix ./hardware-configuration.nix
../../../krebs <stockholm/krebs>
../../../krebs/2configs <stockholm/krebs/2configs>
# ../../../krebs/2configs/secret-passwords.nix # <stockholm/krebs/2configs/secret-passwords.nix>
# ../../../krebs/2configs/binary-cache/nixos.nix # <stockholm/krebs/2configs/binary-cache/nixos.nix>
# ../../../krebs/2configs/binary-cache/prism.nix # <stockholm/krebs/2configs/binary-cache/prism.nix>
../../../krebs/2configs/shack/ssh-keys.nix <stockholm/krebs/2configs/shack/ssh-keys.nix>
../../../krebs/2configs/shack/prometheus/node.nix <stockholm/krebs/2configs/shack/prometheus/node.nix>
# provides access to /home/share for smbuser via smb # provides access to /home/share for smbuser via smb
../../../krebs/2configs/shack/share.nix <stockholm/krebs/2configs/shack/share.nix>
{ {
fileSystems."/home/share" = fileSystems."/home/share" =
{ device = "/serve"; { device = "/serve";
@ -23,8 +23,8 @@ in
} }
## Collect local statistics via collectd and send to collectd ## Collect local statistics via collectd and send to collectd
# ../../../krebs/2configs/stats/shack-client.nix # <stockholm/krebs/2configs/stats/shack-client.nix>
# ../../../krebs/2configs/stats/shack-debugging.nix # <stockholm/krebs/2configs/stats/shack-debugging.nix>
]; ];
krebs.build.host = config.krebs.hosts.filebitch; krebs.build.host = config.krebs.hosts.filebitch;
@ -35,13 +35,12 @@ in
''; '';
networking = { networking = {
firewall.enable = true; firewall.enable = true;
interfaces.et0.useDHCP = true; interfaces.et0.ipv4.addresses = [
#interfaces.et0.ipv4.addresses = [ {
# { address = shack-ip;
# address = shack-ip; prefixLength = 20;
# prefixLength = 20; }
# } ];
#];
defaultGateway = "10.42.0.1"; defaultGateway = "10.42.0.1";
nameservers = [ "10.42.0.100" "10.42.0.200" ]; nameservers = [ "10.42.0.100" "10.42.0.200" ];

View File

@ -2,23 +2,23 @@
{ {
imports = [ imports = [
../../../krebs <stockholm/krebs>
../../../krebs/2configs <stockholm/krebs/2configs>
../../../krebs/2configs/buildbot-stockholm.nix <stockholm/krebs/2configs/buildbot-stockholm.nix>
../../../krebs/2configs/binary-cache/nixos.nix <stockholm/krebs/2configs/binary-cache/nixos.nix>
../../../krebs/2configs/ircd.nix <stockholm/krebs/2configs/ircd.nix>
../../../krebs/2configs/reaktor2.nix <stockholm/krebs/2configs/reaktor2.nix>
../../../krebs/2configs/wiki.nix <stockholm/krebs/2configs/wiki.nix>
../../../krebs/2configs/acme.nix <stockholm/krebs/2configs/acme.nix>
../../../krebs/2configs/mud.nix <stockholm/krebs/2configs/mud.nix>
../../../krebs/2configs/repo-sync.nix <stockholm/krebs/2configs/repo-sync.nix>
../../../krebs/2configs/cal.nix <stockholm/krebs/2configs/cal.nix>
../../../krebs/2configs/mastodon.nix <stockholm/krebs/2configs/mastodon.nix>
## (shackie irc bot ## shackie irc bot
../../../krebs/2configs/shack/reaktor.nix <stockholm/krebs/2configs/shack/reaktor.nix>
]; ];
krebs.build.host = config.krebs.hosts.hotdog; krebs.build.host = config.krebs.hosts.hotdog;

View File

@ -2,15 +2,15 @@
{ {
imports = [ imports = [
../../../krebs <stockholm/krebs>
../../../krebs/2configs <stockholm/krebs/2configs>
../../../krebs/2configs/ircd.nix <stockholm/krebs/2configs/ircd.nix>
../../../krebs/2configs/go.nix <stockholm/krebs/2configs/go.nix>
#### NEWS #### #### NEWS ####
../../../krebs/2configs/ircd.nix <stockholm/krebs/2configs/ircd.nix>
../../../krebs/2configs/news.nix <stockholm/krebs/2configs/news.nix>
]; ];
krebs.build.host = config.krebs.hosts.news; krebs.build.host = config.krebs.hosts.news;

View File

@ -46,8 +46,10 @@
# light.shack web-ui # light.shack web-ui
<stockholm/krebs/2configs/shack/light.shack.nix> #light.shack <stockholm/krebs/2configs/shack/light.shack.nix> #light.shack
# fetch the u300 power stats # powerraw usb serial to mqtt and raw socket
<stockholm/krebs/2configs/shack/power/u300-power.nix> <stockholm/krebs/2configs/shack/powerraw.nix> # powerraw.shack standby.shack
# send power stats to s3
<stockholm/krebs/2configs/shack/s3-power.nix> # powerraw.shack must be available
{ # do not log to /var/spool/log { # do not log to /var/spool/log

View File

@ -7,7 +7,6 @@ in {
SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0" SUBSYSTEM=="net", ATTR{address}=="8c:70:5a:b2:84:58", NAME="wl0"
SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="${ext-if}" SUBSYSTEM=="net", ATTR{address}=="3c:97:0e:07:b9:14", NAME="${ext-if}"
''; '';
networking.wireless.enable = true;
networking = { networking = {
firewall.enable = true; firewall.enable = true;
firewall.allowedTCPPorts = [ 80 443 8088 8086 8083 5901 ]; firewall.allowedTCPPorts = [ 80 443 8088 8086 8083 5901 ];

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: { config, lib, ... }:
with lib; with import <stockholm/lib>;
{ {
krebs.backup.plans = { krebs.backup.plans = {
} // mapAttrs (_: recursiveUpdate { } // mapAttrs (_: recursiveUpdate {

View File

@ -1,5 +1,5 @@
{ config, lib, ... }: { config, ... }: with import <stockholm/lib>;
with import ../../lib/pure.nix { inherit lib; };
{ {
networking.firewall.allowedTCPPorts = [ 80 ]; networking.firewall.allowedTCPPorts = [ 80 ];
services.nginx = { services.nginx = {

View File

@ -1,5 +1,4 @@
{ config, lib, pkgs, ... }: let { config, lib, pkgs, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
setupGit = '' setupGit = ''
export PATH=${lib.makeBinPath [ export PATH=${lib.makeBinPath [
@ -24,13 +23,13 @@
git add .gitignore git add .gitignore
''; '';
pushCal = pkgs.writers.writeDash "push_cal" '' pushCal = pkgs.writeDash "push_cal" ''
${setupGit} ${setupGit}
git fetch origin git fetch origin
git merge --ff-only origin/master || : git merge --ff-only origin/master || :
''; '';
pushCgit = pkgs.writers.writeDash "push_cgit" '' pushCgit = pkgs.writeDash "push_cgit" ''
${setupGit} ${setupGit}
git push origin master git push origin master
''; '';
@ -74,7 +73,7 @@ in {
cgit.settings = { cgit.settings = {
root-title = "krebs repos"; root-title = "krebs repos";
}; };
rules = with slib.git; [ rules = with pkgs.stockholm.lib.git; [
{ {
user = [ user = [
{ {

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
{ {
imports = [ imports = [
./backup.nix ./backup.nix

View File

@ -1,6 +1,5 @@
{ config, lib, ... }: with import <stockholm/lib>;
with import ../../lib/pure.nix { inherit lib; }; { config, ... }: let
let
format = from: to: { format = from: to: {
inherit from; inherit from;

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import <stockholm/lib>;
{ {
krebs.go = { krebs.go = {
enable = true; enable = true;

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import <stockholm/lib>;
{ {
networking.wireless.enable = lib.mkDefault true; networking.wireless.enable = lib.mkDefault true;

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }: with import <stockholm/lib>;
with import ../../lib/pure.nix { inherit lib; }; { config, pkgs, ... }:
let let
#for shared state directory #for shared state directory
@ -22,7 +22,7 @@ let
# TODO; get state as argument # TODO; get state as argument
state_file = "${stateDir}/ledger"; state_file = "${stateDir}/ledger";
}; };
filename = pkgs.writers.writeDash "bedger-add" '' filename = pkgs.writeDash "bedger-add" ''
set -x set -x
tonick=$1 tonick=$1
amt=$2 amt=$2
@ -42,7 +42,7 @@ let
env = { env = {
state_file = "${stateDir}/ledger"; state_file = "${stateDir}/ledger";
}; };
filename = pkgs.writers.writeDash "bedger-balance" '' filename = pkgs.writeDash "bedger-balance" ''
${pkgs.hledger}/bin/hledger -f $state_file bal -N -O csv \ ${pkgs.hledger}/bin/hledger -f $state_file bal -N -O csv \
| ${pkgs.coreutils}/bin/tail +2 \ | ${pkgs.coreutils}/bin/tail +2 \
| ${pkgs.miller}/bin/mlr --icsv --opprint cat \ | ${pkgs.miller}/bin/mlr --icsv --opprint cat \
@ -57,7 +57,7 @@ let
arguments = [1]; arguments = [1];
timeoutSec = 1337; timeoutSec = 1337;
command = { command = {
filename = pkgs.writers.writeDash "bing" '' filename = pkgs.writeDash "bing" ''
set -efu set -efu
report_error() { report_error() {
printf '%s' "$*" | printf '%s' "$*" |
@ -97,7 +97,7 @@ let
arguments = [1]; arguments = [1];
timeoutSec = 1337; timeoutSec = 1337;
command = { command = {
filename = pkgs.writers.writeDash "bing-img" '' filename = pkgs.writeDash "bing-img" ''
set -efu set -efu
report_error() { report_error() {
printf '%s' "$*" | printf '%s' "$*" |
@ -142,7 +142,7 @@ let
activate = "match"; activate = "match";
arguments = [1]; arguments = [1];
command = { command = {
filename = pkgs.writers.writeDash "confuse" '' filename = pkgs.writeDash "confuse" ''
set -efux set -efux
export PATH=${makeBinPath [ export PATH=${makeBinPath [
@ -164,7 +164,7 @@ let
activate = "match"; activate = "match";
arguments = [1]; arguments = [1];
command = { command = {
filename = pkgs.writers.writeDash "interrogate" '' filename = pkgs.writeDash "interrogate" ''
set -efux set -efux
export PATH=${makeBinPath [ export PATH=${makeBinPath [
@ -181,7 +181,7 @@ let
activate = "match"; activate = "match";
arguments = [1]; arguments = [1];
command = { command = {
filename = pkgs.writers.writeDash "confuse" '' filename = pkgs.writeDash "confuse" ''
set -efu set -efu
export PATH=${makeBinPath [ export PATH=${makeBinPath [
pkgs.coreutils pkgs.coreutils
@ -204,7 +204,7 @@ let
activate = "match"; activate = "match";
arguments = [1]; arguments = [1];
command = { command = {
filename = pkgs.writers.writeDash "say" '' filename = pkgs.writeDash "say" ''
set -efu set -efu
export PATH=${makeBinPath [ export PATH=${makeBinPath [
@ -234,20 +234,20 @@ let
arguments = [2]; arguments = [2];
env.TASKDATA = "${stateDir}/${name}"; env.TASKDATA = "${stateDir}/${name}";
commands = rec { commands = rec {
add.filename = pkgs.writers.writeDash "${name}-task-add" '' add.filename = pkgs.writeDash "${name}-task-add" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} add "$1" ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} add "$1"
''; '';
list.filename = pkgs.writers.writeDash "${name}-task-list" '' list.filename = pkgs.writeDash "${name}-task-list" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} export \ ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} export \
| ${pkgs.jq}/bin/jq -r ' | ${pkgs.jq}/bin/jq -r '
.[] | select(.id != 0) | "\(.id) \(.description)" .[] | select(.id != 0) | "\(.id) \(.description)"
' '
''; '';
delete.filename = pkgs.writers.writeDash "${name}-task-delete" '' delete.filename = pkgs.writeDash "${name}-task-delete" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} delete "$1" ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} delete "$1"
''; '';
del = delete; del = delete;
done.filename = pkgs.writers.writeDash "${name}-task-done" '' done.filename = pkgs.writeDash "${name}-task-done" ''
${pkgs.taskwarrior}/bin/task rc:${taskRcFile} done "$1" ${pkgs.taskwarrior}/bin/task rc:${taskRcFile} done "$1"
''; '';
}; };
@ -293,7 +293,8 @@ let
{ {
activate = "always"; activate = "always";
command = { command = {
filename = ../5pkgs/simple/Reaktor/scripts/tell-on_join.sh; filename =
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_join.sh>;
env = { env = {
PATH = makeBinPath [ PATH = makeBinPath [
pkgs.coreutils # XXX env, touch pkgs.coreutils # XXX env, touch
@ -310,7 +311,7 @@ let
pattern = "^list-locations"; pattern = "^list-locations";
activate = "match"; activate = "match";
command = { command = {
filename = pkgs.writers.writeDash "list-locations" '' filename = pkgs.writeDash "list-locations" ''
export PATH=${makeBinPath [ export PATH=${makeBinPath [
pkgs.curl pkgs.curl
pkgs.jq pkgs.jq
@ -327,7 +328,7 @@ let
activate = "match"; activate = "match";
arguments = [1 2 3]; arguments = [1 2 3];
command = { command = {
filename = pkgs.writers.writeDash "add-location" '' filename = pkgs.writeDash "add-location" ''
export PATH=${makeBinPath [ export PATH=${makeBinPath [
pkgs.curl pkgs.curl
pkgs.jq pkgs.jq
@ -344,7 +345,7 @@ let
activate = "match"; activate = "match";
arguments = [1]; arguments = [1];
command = { command = {
filename = pkgs.writers.writeDash "add-location" '' filename = pkgs.writeDash "add-location" ''
export PATH=${makeBinPath [ export PATH=${makeBinPath [
pkgs.curl pkgs.curl
pkgs.jq pkgs.jq
@ -373,7 +374,7 @@ let
sha256 = "sha256-J7jGWZeAULDA1EkO50qx+hjl+5IsUj389pUUMreKeNE="; sha256 = "sha256-J7jGWZeAULDA1EkO50qx+hjl+5IsUj389pUUMreKeNE=";
}; };
osm-restaurants = pkgs.callPackage "${osm-restaurants-src}/osm-restaurants" {}; osm-restaurants = pkgs.callPackage "${osm-restaurants-src}/osm-restaurants" {};
in pkgs.writers.writeDash "krebsfood" '' in pkgs.writeDash "krebsfood" ''
set -efu set -efu
export PATH=${makeBinPath [ export PATH=${makeBinPath [
osm-restaurants osm-restaurants
@ -416,7 +417,8 @@ let
(generators.command_hook { (generators.command_hook {
inherit (commands) dance random-emoji nixos-version; inherit (commands) dance random-emoji nixos-version;
tell = { tell = {
filename = ../5pkgs/simple/Reaktor/scripts/tell-on_privmsg.sh; filename =
<stockholm/krebs/5pkgs/simple/Reaktor/scripts/tell-on_privmsg.sh>;
env = { env = {
PATH = makeBinPath [ PATH = makeBinPath [
pkgs.coreutils # XXX date, env pkgs.coreutils # XXX date, env
@ -450,7 +452,7 @@ in {
name = "reaktor2"; name = "reaktor2";
home = stateDir; home = stateDir;
}; };
script = ''. ${pkgs.writers.writeDash "agenda" '' script = ''. ${pkgs.writeDash "agenda" ''
echo "$Method $Request_URI" >&2 echo "$Method $Request_URI" >&2
case "$Method" in case "$Method" in
"GET") "GET")

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let let
konsens-user = { konsens-user = {

View File

@ -1,5 +1,4 @@
{ lib, ... }: { ... }: with import <stockholm/lib>;
with lib;
{ {
users.extraUsers = users.extraUsers =
mapAttrs (_: h: { hashedPassword = h; }) mapAttrs (_: h: { hashedPassword = h; })

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }: { config, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
root = "/var/srv/drivedroid"; root = "/var/srv/drivedroid";
in in

View File

@ -0,0 +1,23 @@
# needs:
# binary_sensor.lounge_ampel_status
# light.lounge_ampel_licht_rot
let
glados = import ../lib;
in
{
services.home-assistant.config.automation =
[
{
alias = "Ampel Rotes Licht";
initial_state = true;
trigger = {
platform = "state";
entity_id = "binary_sensor.lounge_ampel_status";
};
action = { service = "light.turn_on";
data.entity_id = "light.lounge_ampel_licht_rot";
};
}
];
}

View File

@ -0,0 +1,28 @@
Willkommen werter Keyholder {{ states("sensor.keyholder") }} in deinem Lieblingshackerspace.
Es ist {{states("sensor.fablab_feinstaub_temperature") | round(1) | replace('.',' Komma ')}} Grad {% if states("sensor.fablab_feinstaub_temperature")|float > 25 %}heiss{%elif states("sensor.fablab_feinstaub_temperature")|float > 15%}warm{%else%}kalt{%endif%} bei {% if states(" sensor.rz_feinstaub_humidity") | int <45 %}trockenen{% elif states(" sensor.rz_feinstaub_humidity") | int <65 %}angenehmen{%else%}feuchten{%endif%} {{states(" sensor.rz_feinstaub_humidity") | int }} Prozent Luftfeuchtigkeit.
{% if (states("sensor.fullstand_mate_1")|int == 0) and
states("sensor.fullstand_mate_2")|int == 0 %}ES IST MAHTECALYPSE, BEIDE MAHTESCHÄCHTE SIND LEER! {%if states("sensor.fullstand_mate_cola")| int == 0%} UND SOGAR DIE COLA IST ALLE. Ihr seid sowas von am Arsch!{%else%}Zum Glück gibt es noch Cola, Phew!{%endif%}
{% elif (states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int) < 5 %}
Der Mahtestand im Automaten ist mit {{states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int }} verbleibenden Flaschen kritisch!
{% else %}
Im Automaten sind noch {{states("sensor.fullstand_mate_1")|int + states("sensor.fullstand_mate_2")|int }} Flaschen Mahte und {{states("sensor.fullstand_mate_cola")}} Flaschen Cola.
{%endif%}
Die Wettervorhersage: {{states("sensor.dark_sky_hourly_summary")}} Aktuell {{states("sensor.dark_sky_summary")}} bei {{states("sensor.dark_sky_temperature") | round(1) | replace('.',' Komma ')}} Grad.
Der Stromverbrauch liegt bei {{ (( states("sensor.l1_power")|int + states("sensor.l2_power")|int + states("sensor.l3_power")|int ) / 1000 )| round(1) | replace('.',' Komma ')}} Kilowatt.
Im Fablab ist die Feinstaubbelastung {% if states("sensor.fablab_particulate_matter_2_5um_concentration") | float > 50 %}hoch!{%elif states("sensor.fablab_particulate_matter_2_5um_concentration") | float > 25 %}mäßig.{% else %}gering.{%endif%}
{% if is_state("binary_sensor.door_rzl",'on') and is_state("binary_sensor.door_entropia",'on') %}
Das Raumzeitlabor und Entropia haben geöffnet.
{% elif is_state("binary_sensor.door_rzl",'off') and is_state("binary_sensor.door_entropia",'off') %}
Das Raumzeitlabor und Entropia haben geschlossen.
{% elif is_state("binary_sensor.door_rzl",'on') and is_state("binary_sensor.door_entropia",'off') %}
Das Raumzeitlabor hat geöffnet und Entropia hat geschlossen.
{% elif is_state("binary_sensor.door_rzl",'off') and is_state("binary_sensor.door_entropia",'on') %}
Das Raumzeitlabor hat geschlossen und Entropia hat geöffnet.
{%endif%}
Die Glados Hackerspace Automation wünscht dir und allen Anwesenden einen produktiven und angenehmen Aufenthalt!

View File

@ -0,0 +1,24 @@
# needs:
# light.fablab_led
{
services.home-assistant.config.automation =
[
{ alias = "State on HA start-up";
trigger = {
platform = "homeassistant";
event = "start";
};
# trigger good/bad air
action = [
{ service = "light.turn_on";
data = {
entity_id = "light.fablab_led";
effect = "Rainbow";
color_name = "purple";
};
}
];
}
];
}

View File

@ -0,0 +1,32 @@
# Needs:
# sun.sunset
# switch.lounge_diskoschalter_relay
let
glados = import ../lib;
disko_schalter = "switch.lounge_diskoschalter_relay";
player = "media_player.lounge";
in
{
services.home-assistant.config.automation =
[
{ alias = "Party um 21 Uhr";
trigger = {
platform = "sun";
event = "sunset";
};
action =
( glados.say.kiosk "Die Sonne geht unter. Und jetzt geht die Party im shack erst richtig los. Partybeleuchtung, aktiviert!" )
++
[
{
service = "homeassistant.turn_on";
entity_id = disko_schalter;
}
{
service = "media_player.turn_on";
data.entity_id = player;
} # TODO: also start playlist if nothing is running?
];
}
];
}

View File

@ -0,0 +1,100 @@
# needs:
# binary_sensor.portal_lock
# sensor.keyholder
# media_player.lounge
# additional state required on:
# mpd.shack:
# playlist "ansage"
# playlist "lassulus"
# lounge.kiosk.shack:
# playlist "ansage"
let
glados = import ../lib;
in
{
services.home-assistant.config.automation =
[
{
alias = "Bedanken bei Übernahme von Key";
initial_state = true;
trigger = {
platform = "state";
entity_id = "sensor.keyholder";
};
condition = {
condition = "template";
value_template = "{{ (trigger.from_state.state != 'No Keyholder') and (trigger.from_state.state != 'No Keyholder') }}";
};
action = glados.say.kiosk "Danke {{ trigger.to_state.state }} für das Übernehmen des Keys von {{ trigger.from_state.state }}";
}
{
alias = "Keyholder Begrüßen wenn MPD hoch fährt";
initial_state = true;
trigger = {
platform = "state";
from = "unavailable";
entity_id = "media_player.kiosk";
};
action = glados.say.kiosk (builtins.readFile ./announcement.j2);
}
{
alias = "Start Music on portal lock on";
trigger = {
platform = "state";
entity_id = "binary_sensor.portal_lock";
to = "on";
for.seconds = 30;
};
condition = {
condition = "and";
conditions =
[
{ # only start if a keyholder opened the door and if the lounge mpd is currently not playing anything
condition = "template";
value_template = "{{ state('sensor.keyholder') != 'No Keyholder' }}";
}
{
condition = "state";
entity_id = "media_player.lounge";
state = "idle";
}
];
};
action = [
{
service = "media_player.volume_set";
data = {
entity_id = "media_player.lounge";
volume_level = 1.0;
};
}
{
service = "media_player.play_media";
data = {
entity_id = "media_player.lounge";
media_content_type = "playlist";
media_content_id = "ansage";
};
}
{ delay.seconds = 8.5; }
{
service = "media_player.volume_set";
data = {
entity_id = "media_player.lounge";
volume_level = 0.6;
};
}
{
service = "media_player.play_media";
data = {
entity_id = "media_player.lounge";
media_content_type = "playlist";
media_content_id = "lassulus";
};
}
];
}
];
}

View File

@ -1,33 +1,12 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
let let
kodi-host = "192.168.8.11"; unstable = import (pkgs.fetchFromGitHub {
confdir = "/var/lib/homeassistant-docker"; owner = "nixos";
repo = "nixpkgs";
rev = (lib.importJSON ../../../nixpkgs-unstable.json).rev;
sha256 = (lib.importJSON ../../../nixpkgs-unstable.json).sha256;
}) {};
in { in {
imports = [
];
# networking.firewall.allowedTCPPorts = [ 8123 ];
virtualisation.oci-containers.containers.hass = {
image = "homeassistant/home-assistant:latest";
environment = {
TZ = "Europe/Berlin";
# TODO create unique users
PUID = toString config.users.users.news_container.uid;
PGID = toString config.users.groups.news_container.gid;
UMASK = "007";
};
extraOptions = ["--net=host" ];
volumes = [
"${confdir}:/config"
#"${confdir}/docker-run:/etc/services.d/home-assistant/run:"
];
};
systemd.tmpfiles.rules = [
#"f ${confdir}/docker-run 0770 kiosk kiosk - -"
# TODO:
"d ${confdir} 0770 news_container news_container - -"
];
services.nginx.virtualHosts."hass.shack" = { services.nginx.virtualHosts."hass.shack" = {
serverAliases = [ "glados.shack" ]; serverAliases = [ "glados.shack" ];
locations."/" = { locations."/" = {
@ -44,4 +23,127 @@ in {
''; '';
}; };
}; };
imports = [
./multi/shackopen.nix
./multi/wasser.nix
./multi/schlechte_luft.nix
./multi/rollos.nix
./switch/power.nix
./sensors/power.nix
./sensors/mate.nix
./sensors/darksky.nix
./sensors/spaceapi.nix
./sensors/sensemap.nix
./automation/shack-startup.nix
./automation/party-time.nix
./automation/hass-restart.nix
./automation/ampel.nix
];
services.home-assistant =
{
enable = true;
package = unstable.home-assistant.overrideAttrs (old: {
doInstallCheck = false;
});
config = {
homeassistant = {
name = "Glados";
time_zone = "Europe/Berlin";
latitude = "48.8265";
longitude = "9.0676";
elevation = 303;
auth_providers = [
{ type = "homeassistant";}
{ type = "trusted_networks";
trusted_networks = [
"127.0.0.1/32"
"10.42.0.0/16"
"::1/128"
"fd00::/8"
];
}
];
};
# https://www.home-assistant.io/components/influxdb/
influxdb = {
database = "glados";
host = "influx.shack";
component_config_glob = {
"sensor.*particulate_matter_2_5um_concentration".override_measurement = "2_5um particles";
"sensor.*particulate_matter_10_0um_concentration".override_measurement ="10um particles";
};
tags = {
instance = "wolf";
source = "glados";
};
};
esphome = {};
api = {};
mqtt = {
broker = "localhost";
port = 1883;
client_id = "home-assistant";
keepalive = 60;
protocol = 3.1;
discovery = true; #enable esphome discovery
discovery_prefix = "homeassistant";
birth_message = {
topic = "glados/hass/status/LWT";
payload = "Online";
qos = 1;
retain = true;
};
will_message = {
topic = "glados/hass/status/LWT";
payload = "Offline";
qos = 1;
retain = true;
};
};
light = [];
media_player = [
{ platform = "mpd";
name = "lounge";
host = "lounge.mpd.shack";
}
{ platform = "mpd";
name = "kiosk";
#host = "lounge.kiosk.shack";
host = "kiosk.shack";
}
];
camera = [];
frontend = { };
config = { };
sun = {};
http = {
base_url = "http://hass.shack";
use_x_forwarded_for = true;
trusted_proxies = [ "127.0.0.1" "::1" ];
};
#conversation = {};
history = {};
logbook = {};
#recorder = {};
logger.default = "info";
tts = [
{ platform = "google_translate";
service_name = "say";
language = "de";
cache = true;
time_memory = 57600;
base_url = "http://hass.shack";
}
];
device_tracker = [];
};
};
} }

View File

@ -0,0 +1,27 @@
{ lib
, buildPythonPackage
, fetchPypi
, requests
}:
buildPythonPackage rec {
pname = "gtts-token";
version = "1.1.3";
src = fetchPypi {
pname = "gTTS-token";
inherit version;
sha256 = "9d6819a85b813f235397ef931ad4b680f03d843c9b2a9e74dd95175a4bc012c5";
};
propagatedBuildInputs = [
requests
];
meta = with lib; {
description = "Calculates a token to run the Google Translate text to speech";
homepage = https://github.com/boudewijn26/gTTS-token;
license = licenses.mit;
# maintainers = [ maintainers. ];
};
}

View File

@ -0,0 +1,33 @@
{ lib
, buildPythonPackage
, fetchpatch
, fetchPypi
, aiohttp
, async-timeout
}:
buildPythonPackage rec {
pname = "pyhaversion";
version = "2.2.1";
src = fetchPypi {
inherit pname version;
sha256 = "72b65aa25d7b2dbb839a4d0218df2005c2335e93526035904d365bb668030b9f";
};
patches = [
(fetchpatch { url = "https://github.com/makefu/pyhaversion/commit/f3bdc38970272cd345c2cfbde3037ea492ca27c4.patch";
sha256 =
"1rhq4z7mdgnwhwpf5fmarnbc1ba3qysk1wqjdr0hvbzi8vmvbfcc";})
];
doCheck = false;
propagatedBuildInputs = [
aiohttp
async-timeout
];
meta = with lib; {
description = "";
homepage = https://github.com/ludeeus/pyhaversion;
# maintainers = [ maintainers. ];
};
}

View File

@ -0,0 +1,66 @@
let
prefix = "glados";
in
{
say = let
# returns a list of actions to be performed on an mpd to say something
tts = { message, entity }:
[
{
service = "media_player.turn_on";
data.entity_id = "media_player.${entity}";
}
{ service = "media_player.play_media";
data = {
entity_id = "media_player.${entity}";
media_content_type = "playlist";
media_content_id = "ansage";
};
}
{
service = "media_player.turn_on";
data.entity_id = "media_player.${entity}";
}
{ delay.seconds = 4.5; }
{ service = "tts.say";
entity_id = "media_player.${entity}";
data_template = {
inherit message;
language = "de";
};
}
];
in
{
lounge = message: tts {
inherit message;
entity = "lounge";
};
herrenklo = message: tts {
inherit message;
entity = "herrenklo";
};
kiosk = message: tts {
inherit message;
entity = "kiosk";
};
};
tasmota =
{
plug = {host, name ? host, topic ? host}:
{
platform = "mqtt";
inherit name;
state_topic = "sonoff/stat/${topic}/POWER1";
command_topic = "sonoff/cmnd/${topic}/POWER1";
availability_topic = "sonoff/tele/${topic}/LWT";
payload_on= "ON";
payload_off= "OFF";
payload_available= "Online";
payload_not_available= "Offline";
retain = false;
qos = 1;
};
};
}

View File

@ -0,0 +1,59 @@
#
let
glados = import ../lib;
tempsensor = "sensor.dark_sky_temperature";
all_covers = [
"cover.crafting_rollo"
"cover.elab_rollo"
"cover.or2_rollo"
"cover.retroraum_rollo"
];
in
{
services.home-assistant.config =
{
automation =
[
{ alias = "Rollos fahren Runter";
trigger = [
{
platform = "numeric_state";
entity_id = tempsensor;
above = 25;
for = "00:30:00";
}
];
condition =
[
{
condition = "state";
entity_id = "sun.sun";
state = "above_horizon";
}
];
action =
[
{ service = "cover.close_cover";
entity_id = all_covers;
}
];
}
{ alias = "Rollos fahren Hoch";
trigger = [
{
platform = "sun";
event = "sunset";
}
];
condition = [ ];
action =
[
{ service = "cover.open_cover";
entity_id = all_covers;
}
];
}
];
};
}

View File

@ -0,0 +1,109 @@
let
glados = import ../lib;
feinstaub_sensor = "sensor.fablab_particulate_matter_2_5um_concentration";
ledring = "light.fablab_led_ring";
in
{
services.home-assistant.config =
{
automation =
[
{ alias = "Gute Luft Fablab";
trigger = [
{
platform = "numeric_state";
entity_id = feinstaub_sensor;
below = 3;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Twinkle";
color_name = "green";
};
}
];
}
{ alias = "mäßige Luft Fablab";
trigger = [
{
platform = "numeric_state";
above = 3;
below = 10;
entity_id = feinstaub_sensor;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Twinkle";
color_name = "yellow";
};
}
];
}
{ alias = "schlechte Luft Fablab";
trigger = [
{
platform = "numeric_state";
above = 10;
entity_id = feinstaub_sensor;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Fireworks";
color_name = "red";
};
}
];
}
{ alias = "Luft Sensor nicht verfügbar";
trigger = [
{
platform = "state";
to = "unavailable";
entity_id = feinstaub_sensor;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Rainbow";
color_name = "blue";
};
}
];
}
{ alias = "Fablab Licht Reboot";
trigger = [
{
platform = "state";
from = "unavailable";
entity_id = ledring;
}
];
action =
[
{ service = "light.turn_on";
data = {
entity_id = ledring;
effect = "Rainbow";
color_name = "orange";
};
}
];
}
];
};
}

View File

@ -0,0 +1,26 @@
{
services.home-assistant.config =
{
binary_sensor = [
{ platform = "mqtt";
name = "Portal Lock";
device_class = "door";
state_topic = "portal/gateway/status";
availability_topic = "portal/gateway/lwt";
payload_on = "open";
payload_off = "closed";
payload_available = "online";
payload_not_available = "offline";
}
];
sensor = [
{ platform = "mqtt";
name = "Keyholder";
state_topic = "portal/gateway/keyholder";
availability_topic = "portal/gateway/lwt";
payload_available = "online";
payload_not_available = "offline";
}
];
};
}

View File

@ -0,0 +1,113 @@
# uses:
# switch.crafting_giesskanne_relay
let
glados = import ../lib;
seconds = 20;
wasser = "switch.crafting_giesskanne_relay";
brotbox = {
minutes = 10;
pump = "switch.crafting_brotbox_pumpe";
sensor = "sensor.statistics_for_sensor_crafting_brotbox_soil_moisture";
};
in
{
services.home-assistant.config =
{
sensor = map ( entity_id: {
platform = "statistics";
name = "Statistics for ${entity_id}";
inherit entity_id;
max_age.minutes = "60";
sampling_size = 1000;
}) ["sensor.crafting_brotbox_soil_moisture"];
automation =
[
### Brotbox #####
#{ alias = "Brotbox: water for ${toString brotbox.minutes} minutes every hour";
# trigger =
# { # Trigger once every hour at :42
# platform = "time_pattern";
# minutes = 42;
# };
# condition = {
# condition = "numeric_state";
# entity_id = brotbox.sensor;
# value_template = "{{ state_attr('${brotbox.sensor}', 'median') }}";
# below = 75;
# };
# action =
# [
# {
# service = "homeassistant.turn_on";
# entity_id = brotbox.pump;
# }
# { delay.minutes = brotbox.minutes; }
# {
# service = "homeassistant.turn_off";
# entity_id = brotbox.pump ;
# }
# ];
#}
{ alias = "Brotbox: Always turn off water after ${toString (brotbox.minutes * 2)} minutes";
trigger =
{
platform = "state";
entity_id = brotbox.pump;
to = "on";
for.minutes = brotbox.minutes*2;
};
action =
{
service = "homeassistant.turn_off";
entity_id = brotbox.pump;
};
}
##### Kaffeemaschine
{ alias = "Water the plant for ${toString seconds} seconds";
trigger = [
{ # trigger at 20:00 no matter what
# TODO: retry or run only if switch.wasser is available
platform = "time";
at = "20:00:00";
}
];
action =
[
{
service = "homeassistant.turn_on";
entity_id = [
wasser
];
}
{ delay.seconds = seconds; }
{
service = "homeassistant.turn_off";
entity_id = [
wasser
];
}
];
}
{ alias = "Always turn off water after ${toString (seconds * 2)}seconds";
trigger = [
{
platform = "state";
entity_id = wasser;
to = "on";
for.seconds = seconds*2;
}
];
action =
[
{
service = "homeassistant.turn_off";
entity_id = [ wasser ];
}
];
}
];
};
}

View File

@ -0,0 +1,24 @@
{lib,...}:
{
services.home-assistant.config.sensor =
[
{ platform = "darksky";
api_key = lib.removeSuffix "\n"
(builtins.readFile <secrets/hass/darksky.apikey>);
language = "de";
monitored_conditions = [
"summary" "icon"
"nearest_storm_distance" "precip_probability"
"precip_intensity"
"temperature" # "temperature_high" "temperature_low"
"apparent_temperature"
"hourly_summary" # next 24 hours text
"humidity"
"pressure"
"uv_index"
];
units = "si" ;
scan_interval = "00:15:00";
}
];
}

View File

@ -0,0 +1,20 @@
let
fuellstand = name: id: {
platform = "rest";
resource = "https://ora5.tutschonwieder.net/ords/lick_prod/v1/get/fuellstand/1/${toString id}";
method = "GET";
name = "Füllstand ${name}";
value_template = "{{ value_json.fuellstand }}";
};
in
{
services.home-assistant.config.sensor =
[
(fuellstand "Wasser" 1)
(fuellstand "Mate Cola" 2)
(fuellstand "Apfelschorle" 3)
(fuellstand "Zitronensprudel" 4)
(fuellstand "Mate 1" 26)
(fuellstand "Mate 2" 27)
];
}

View File

@ -0,0 +1,29 @@
let
power_x = name: phase:
{ platform = "mqtt";
name = "${phase} ${name}";
state_topic = "/power/total/${phase}/${name}";
availability_topic = "/power/lwt";
payload_available = "Online";
payload_not_available = "Offline";
};
power_consumed =
{ platform = "mqtt";
name = "Power Consumed";
device_class = "power";
state_topic = "/power/total/consumed";
availability_topic = "/power/lwt";
payload_available = "Online";
payload_not_available = "Offline";
};
power_volt = power_x "Voltage";
power_watt = (power_x "Power") ;
power_curr = power_x "Current";
in
{
services.home-assistant.config.sensor =
(map power_volt [ "L1" "L2" "L3" ])
++ (map (x: ((power_watt x) // { device_class = "power"; })) [ "L1" "L2" "L3" ])
++ (map power_curr [ "L1" "L2" "L3" ])
++ [ power_consumed ];
}

View File

@ -0,0 +1,9 @@
{
services.home-assistant.config.air_quality =
[
{
platform = "opensensemap";
station_id = "56a0de932cb6e1e41040a68b";
}
];
}

View File

@ -0,0 +1,55 @@
{
services.home-assistant.config.binary_sensor =
[
{
platform = "rest";
resource = "https://spaceapi.afra-berlin.de/v1/status.json";
method = "GET";
name = "Door AFRA Berlin";
device_class = "door";
value_template = "{{ value_json.open }}";
}
{
platform = "rest";
resource = "http://club.entropia.de/spaceapi";
method = "GET";
name = "Door Entropia";
device_class = "door";
value_template = "{{ value_json.open }}";
}
{
platform = "rest";
resource = "http://www.c-base.org/status.json";
method = "GET";
name = "Door C-Base Berlin";
device_class = "door";
value_template = "{{ value_json.open }}";
}
{
platform = "rest";
resource = "https://status.raumzeitlabor.de/api/full.json";
method = "GET";
name = "Door RZL";
device_class = "door";
value_template = "{{ value_json.status }}";
}
{
platform = "rest";
resource = "https://datenobservatorium.de/";
method = "GET";
name = "Door Datenobservatorium";
device_class = "door";
value_template = "false";
scan_interval = 2592000;
}
{
platform = "rest";
resource = "https://infuanfu.de/";
method = "GET";
name = "Door Infuanfu";
device_class = "door";
value_template = "false";
scan_interval = 2592000;
}
];
}

View File

@ -0,0 +1,6 @@
{
controllers = {
host = "unifi.shack";
site = "shackspace";
};
}

View File

@ -0,0 +1,44 @@
# 1 - haupt
# 2 - dusche
# 3 - warmwasser
# 4 - or
# 5 - kueche
let
nodelight = type: ident: name: {
platform = "mqtt";
name = "${type} ${name}";
command_topic = "${type}/${toString ident}/command";
state_topic = "${type}/${toString ident}/state";
payload_on = "on";
payload_off = "off";
};
power = nodelight "power";
light = ident: name: { icon = "mdi:lightbulb";} // nodelight "light" ident name;
in
{
services.home-assistant.config.switch =
[
# These commands we see with a shutdown:
# power/143/state on
# power/142/state on
# power/141/state on
# power/142/state off
# power/141/state off
# power/10/state off
# power/main/state off
(power "10" "Hauptschalter")
(power 1 "Dusche") # ???
(power 2 "Warmwasser") # ???
(power 3 "Optionsräume") # ???
(power 4 "Küche") # ???
(light 1 "Decke Lounge 1")
(light 2 "Decke Lounge 2")
(light 3 "Decke Lounge 3")
(light 4 "Decke Lounge 4")
(light 5 "Decke Lounge 5")
(light 6 "Decke Lounge 6")
(light 7 "Decke Lounge 7")
(light 8 "Decke Lounge 8")
];
}

View File

@ -4,18 +4,7 @@ in {
networking.firewall.allowedTCPPorts = [ port ]; # legacy networking.firewall.allowedTCPPorts = [ port ]; # legacy
services.nginx.virtualHosts."grafana.shack" = { services.nginx.virtualHosts."grafana.shack" = {
locations."/" = { locations."/".proxyPass = "http://localhost:${toString port}";
proxyPass = "http://localhost:${toString port}";
extraConfig =''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
'';
};
}; };
services.grafana = { services.grafana = {
enable = true; enable = true;

View File

@ -15,16 +15,6 @@ in
''; '';
locations."/" = { locations."/" = {
proxyPass = "http://localhost:${toString port}/"; proxyPass = "http://localhost:${toString port}/";
extraConfig = ''
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
'';
}; };
}; };
nixpkgs.overlays = [ nixpkgs.overlays = [

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
pkg = pkgs.stdenv.mkDerivation { pkg = pkgs.stdenv.mkDerivation {
name = "mqtt2graphite-2017-05-29"; name = "mqtt2graphite-2017-05-29";

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
pkg = pkgs.stdenv.mkDerivation { pkg = pkgs.stdenv.mkDerivation {
name = "muell_caller-2017-06-01"; name = "muell_caller-2017-06-01";

View File

@ -1,5 +1,5 @@
{ config, pkgs, ... }: { config, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
cfg = config.krebs.apt-cacher-ng; cfg = config.krebs.apt-cacher-ng;
in in

View File

@ -1,29 +0,0 @@
{ pkgs, ... }:
let
src = pkgs.fetchFromGitHub {
repo = "shackstrom";
owner = "samularity";
rev = "adfbdc7d12000fbc9fd9367c8ef0a53b7d0a9fad";
hash = "sha256-77vSX2+1XXaBVgLka+tSEK/XYZASEk9iq+uEuO1aOUQ=";
};
pkg = pkgs.writers.writePython3 "test_python3" {
libraries = [ pkgs.python3Packages.requests pkgs.python3Packages.paho-mqtt ];
} (builtins.readFile "${src}/shackstrom.py");
in
{
systemd.services = {
u300-power = {
enable = true;
environment = {
DATA_URL = "http://10.42.20.255/csv.html";
BROKER = "mqtt.shack";
};
serviceConfig = {
Restart = "always";
ExecStart = pkg;
RestartSec = "15s";
};
wantedBy = [ "multi-user.target" ];
};
};
}

View File

@ -1,12 +1,28 @@
{ lib,... }: { lib,... }:
let let
disk_free_threshold = "5"; # at least this much free disk percentage disk_free_threshold = "10"; # at least this much free disk percentage
in { in {
services.prometheus.rules = [(builtins.toJSON services.prometheus.rules = [(builtins.toJSON
{ {
groups = [ groups = [
{ name = "shack-env"; { name = "shack-env";
rules = [ rules = [
{
alert = "Wolf RootPartitionFull";
for = "30m";
expr = ''(node_filesystem_avail_bytes{alias="wolf.shack",mountpoint="/"} * 100) / node_filesystem_size_bytes{alias="wolf.shack",mountpoint="/"} < ${disk_free_threshold}'';
labels.severity = "warning";
annotations.summary = "{{ $labels.alias }} root disk full";
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=wolf";
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%). CI for deploying new configuration will seize working. Log in to the system and try to clean up the obsolete files on the machine. There are a couple of things you can do:
1. `nix-collect-garbage -d`
2. clean up the shack share folder in `/home/share`
3. check `du -hs /var/ | sort -h`.
4. run `docker system prune`
5. `find /var/lib/containers/news/var/lib/htgen-go/items -mtime +7 -delete;` to clean up the link shortener data
5. If you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete
6. as a last resort the root disk can be expanded via `lvresize -L +10G /dev/pool/root && btrfs filesystem resize max /` '';
}
{ {
alert = "Puyak RootPartitionFull"; alert = "Puyak RootPartitionFull";
for = "30m"; for = "30m";
@ -16,8 +32,9 @@ in {
annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=puyak"; annotations.url = "http://grafana.shack/d/hb7fSE0Zz/shack-system-dashboard?orgId=1&var-job=node&var-hostname=All&var-node=wolf.shack:9100&var-device=All&var-maxmount=%2F&var-show_hostname=puyak";
annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%).Prometheus will not be able to create new alerts and CI for deploying new configuration will also seize working. Log in to the system and run `nix-collect-garbage -d` and if this does not help you can check `du -hs /var/ | sort -h`, run `docker system prune` or if you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete''; annotations.description = ''The root disk of {{ $labels.alias }} has {{ $value | printf "%.2f" }}% free disk space (Threshold at ${disk_free_threshold}%).Prometheus will not be able to create new alerts and CI for deploying new configuration will also seize working. Log in to the system and run `nix-collect-garbage -d` and if this does not help you can check `du -hs /var/ | sort -h`, run `docker system prune` or if you are really desperate run `du -hs / | sort -h` and go through the folders recursively until you've found something to delete'';
} }
# wolf.shack is not worth supervising anymore
{ {
alert = "Infra01 down"; alert = "HostDown";
expr = ''up{alias="infra01.shack"} == 0''; expr = ''up{alias="infra01.shack"} == 0'';
for = "5m"; for = "5m";
labels.severity = "page"; labels.severity = "page";

View File

@ -1,207 +0,0 @@
import base64
import cgi
import json
import os
import re
import socket
import ssl
import sys
from http.server import BaseHTTPRequestHandler
from typing import List, Optional, Tuple
from urllib.parse import urlparse
DEBUG = os.environ.get("DEBUG") is not None
def _irc_send(
server: str,
nick: str,
channel: str,
sasl_password: Optional[str] = None,
server_password: Optional[str] = None,
tls: bool = True,
port: int = 6697,
messages: List[str] = [],
) -> None:
if not messages:
return
sock = socket.socket()
if tls:
sock = ssl.wrap_socket(
sock, cert_reqs=ssl.CERT_NONE, ssl_version=ssl.PROTOCOL_TLSv1_2
)
def _send(command: str) -> int:
if DEBUG:
print(command)
return sock.send((f"{command}\r\n").encode())
def _pong(ping: str):
if ping.startswith("PING"):
sock.send(ping.replace("PING", "PONG").encode("ascii"))
recv_file = sock.makefile(mode="r")
print(f"connect {server}:{port}")
sock.connect((server, port))
if server_password:
_send(f"PASS {server_password}")
_send(f"USER {nick} 0 * :{nick}")
_send(f"NICK {nick}")
for line in recv_file.readline():
if re.match(r"^:[^ ]* (MODE|221|376|422) ", line):
break
else:
_pong(line)
if sasl_password:
_send("CAP REQ :sasl")
_send("AUTHENTICATE PLAIN")
auth = base64.encodebytes(f"{nick}\0{nick}\0{sasl_password}".encode("utf-8"))
_send(f"AUTHENTICATE {auth.decode('ascii')}")
_send("CAP END")
_send(f"JOIN :{channel}")
for m in messages:
_send(f"PRIVMSG {channel} :{m}")
_send("INFO")
for line in recv_file:
if DEBUG:
print(line, end="")
# Assume INFO reply means we are done
if "End of /INFO" in line:
break
else:
_pong(line)
sock.send(b"QUIT")
print("disconnect")
sock.close()
def irc_send(
url: str, notifications: List[str], password: Optional[str] = None
) -> None:
parsed = urlparse(f"{url}")
username = parsed.username or "prometheus"
server = parsed.hostname or "chat.freenode.net"
if parsed.fragment != "":
channel = f"#{parsed.fragment}"
else:
channel = "#krebs-announce"
port = parsed.port or 6697
if not password:
password = parsed.password
if len(notifications) == 0:
return
_irc_send(
server=server,
nick=username,
sasl_password=password,
channel=channel,
port=port,
messages=notifications,
tls=parsed.scheme == "irc+tls",
)
class PrometheusWebHook(BaseHTTPRequestHandler):
def __init__(
self,
irc_url: str,
conn: socket.socket,
addr: Tuple[str, int],
password: Optional[str] = None,
) -> None:
self.irc_url = irc_url
self.password = password
self.rfile = conn.makefile("rb")
self.wfile = conn.makefile("wb")
self.client_address = addr
self.handle()
# for testing
def do_GET(self) -> None:
if DEBUG:
print("GET: Request Received")
self.send_response(200)
self.send_header("Content-type", "text/plain")
self.end_headers()
self.wfile.write(b"ok")
def do_POST(self) -> None:
if DEBUG:
print("POST: Request Received")
content_type, _ = cgi.parse_header(self.headers.get("content-type"))
# refuse to receive non-json content
if content_type != "application/json":
if DEBUG:
print(f"POST: wrong content type {content_type}")
self.send_response(400)
self.end_headers()
return
length = int(self.headers.get("content-length"))
payload = json.loads(self.rfile.read(length))
messages = []
for alert in payload["alerts"]:
description = alert["annotations"]["description"]
messages.append(f"{alert['status']}: {description}")
irc_send(self.irc_url, messages, password=self.password)
self.do_GET()
def systemd_socket_response() -> None:
irc_url = os.environ.get("IRC_URL", None)
if irc_url is None:
print(
"IRC_URL environment variable not set: i.e. IRC_URL=irc+tls://mic92-prometheus@chat.freenode.net/#krebs-announce",
file=sys.stderr,
)
sys.exit(1)
password = None
irc_password_file = os.environ.get("IRC_PASSWORD_FILE", None)
if irc_password_file:
with open(irc_password_file) as f:
password = f.read()
msgs = sys.argv[1:]
if msgs != []:
irc_send(irc_url, msgs, password=password)
return
nfds = os.environ.get("LISTEN_FDS", None)
if nfds is None:
print(
"LISTEN_FDS not set. Run me with systemd(TM) socket activation?",
file=sys.stderr,
)
sys.exit(1)
fds = range(3, 3 + int(nfds))
for fd in fds:
sock = socket.fromfd(fd, socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(0)
try:
while True:
PrometheusWebHook(irc_url, *sock.accept(), password=password)
except BlockingIOError:
# no more connections
pass
if __name__ == "__main__":
if DEBUG:
print("Starting in DEBUG mode")
if len(sys.argv) == 3:
print(f"{sys.argv[1]} {sys.argv[2]}")
irc_send(sys.argv[1], [sys.argv[2]])
else:
systemd_socket_response()

View File

@ -1,59 +0,0 @@
{ config
, lib
, pkgs
, ...
}:
let
irc-alerts = pkgs.writers.writePython3 "irc-alerts" {
flakeIgnore = [ "E501" ];
} (builtins.readFile ./irc-alerts.py);
endpoints = {
binaergewitter = {
url = "irc+tls://puyak-alerts@irc.libera.chat:6697/#binaergewitter-alerts";
port = 9223;
};
};
in
{
systemd.sockets =
lib.mapAttrs'
(name: opts:
lib.nameValuePair "irc-alerts-${name}" {
description = "Receive http hook and send irc message for ${name}";
wantedBy = [ "sockets.target" ];
listenStreams = [ "[::]:${builtins.toString opts.port}" ];
}) endpoints;
systemd.services =
lib.mapAttrs'
(name: opts:
let
serviceName = "irc-alerts-${name}";
hasPassword = opts.passwordFile or null != null;
in
lib.nameValuePair serviceName {
description = "Receive http hook and send irc message for ${name}";
requires = [ "irc-alerts-${name}.socket" ];
serviceConfig =
{
Environment =
[
"IRC_URL=${opts.url}"
"DEBUG=y"
]
++ lib.optional hasPassword "IRC_PASSWORD_FILE=/run/${serviceName}/password";
DynamicUser = true;
User = serviceName;
ExecStart = irc-alerts;
}
// lib.optionalAttrs hasPassword {
PermissionsStartOnly = true;
ExecStartPre =
"${pkgs.coreutils}/bin/install -m400 "
+ "-o ${serviceName} -g ${serviceName} "
+ "${config.sops.secrets.prometheus-irc-password.path} "
+ "/run/${serviceName}/password";
RuntimeDirectory = serviceName;
};
}) endpoints;
}

View File

@ -3,7 +3,6 @@
{ {
imports = [ imports = [
./alert-rules.nix ./alert-rules.nix
./irc-hooks.nix
]; ];
networking = { networking = {
firewall.allowedTCPPorts = [ firewall.allowedTCPPorts = [
@ -130,11 +129,11 @@
"group_wait" = "30s"; "group_wait" = "30s";
"group_interval" = "2m"; "group_interval" = "2m";
"repeat_interval" = "4h"; "repeat_interval" = "4h";
"receiver" = "shack-admins"; "receiver" = "team-admins";
}; };
"receivers" = [ "receivers" = [
{ {
"name" = "shack-admins"; "name" = "team-admins";
"email_configs" = [ ]; "email_configs" = [ ];
"webhook_configs" = [ "webhook_configs" = [
{ {

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
pkg = pkgs.stdenv.mkDerivation { pkg = pkgs.stdenv.mkDerivation {
name = "radioactive-2017-06-01"; name = "radioactive-2017-06-01";

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
pkg = pkgs.stdenv.mkDerivation { pkg = pkgs.stdenv.mkDerivation {
name = "worlddomination-2020-12-01"; name = "worlddomination-2020-12-01";

View File

@ -1,7 +1,7 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
# TODO: krebs.collectd.plugins # TODO: krebs.collectd.plugins
with import ../../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
connect-time-cfg = with pkgs; writeText "collectd-connect-time.conf" '' connect-time-cfg = with pkgs; writeText "collectd-connect-time.conf" ''
LoadPlugin python LoadPlugin python

View File

@ -1,6 +1,4 @@
{ config, lib, options, pkgs, ... }: { options, config, pkgs, ... }: with import <stockholm/lib>; let
with import ../../lib/pure.nix { inherit lib; };
let
mk_peers = mapAttrs (n: v: { id = v.syncthing.id; }); mk_peers = mapAttrs (n: v: { id = v.syncthing.id; });
all_peers = filterAttrs (n: v: v.syncthing.id != null) config.krebs.hosts; all_peers = filterAttrs (n: v: v.syncthing.id != null) config.krebs.hosts;

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }: { config, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
setupGit = '' setupGit = ''
@ -14,13 +14,13 @@ let
fi fi
''; '';
pushGollum = pkgs.writers.writeDash "push_gollum" '' pushGollum = pkgs.writeDash "push_gollum" ''
${setupGit} ${setupGit}
git fetch origin git fetch origin
git merge --ff-only origin/master git merge --ff-only origin/master
''; '';
pushCgit = pkgs.writers.writeDash "push_cgit" '' pushCgit = pkgs.writeDash "push_cgit" ''
${setupGit} ${setupGit}
git push origin master git push origin master
''; '';

View File

@ -1,7 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with import <stockholm/lib>; #genid
let let
slib = import ../../lib/pure.nix { inherit lib; };
cfg = config.krebs.airdcpp; cfg = config.krebs.airdcpp;
out = { out = {
@ -266,14 +265,14 @@ let
}; };
users = lib.mkIf (cfg.user == "airdcpp") { users = lib.mkIf (cfg.user == "airdcpp") {
users.airdcpp = { users.airdcpp = {
uid = slib.genid "airdcpp"; uid = genid "airdcpp";
home = cfg.stateDir; home = cfg.stateDir;
createHome = true; createHome = true;
isSystemUser = true; isSystemUser = true;
group = "airdcpp"; group = "airdcpp";
inherit (cfg) extraGroups; inherit (cfg) extraGroups;
}; };
groups.airdcpp.gid = slib.genid "airdcpp"; groups.airdcpp.gid = genid "airdcpp";
}; };
}; };
in in

View File

@ -1,21 +1,20 @@
{ config, pkgs, lib, ... }: with import <stockholm/lib>;
let { config, pkgs, ... }: let
slib = import ../../lib/pure.nix { inherit lib; };
cfg = config.krebs.announce-activation; cfg = config.krebs.announce-activation;
announce-activation = pkgs.writeDash "announce-activation" '' announce-activation = pkgs.writeDash "announce-activation" ''
set -efu set -efu
message=$(${cfg.get-message}) message=$(${cfg.get-message})
exec ${pkgs.irc-announce}/bin/irc-announce \ exec ${pkgs.irc-announce}/bin/irc-announce \
${slib.shell.escape cfg.irc.server} \ ${shell.escape cfg.irc.server} \
${slib.shell.escape (toString cfg.irc.port)} \ ${shell.escape (toString cfg.irc.port)} \
${slib.shell.escape cfg.irc.nick} \ ${shell.escape cfg.irc.nick} \
${slib.shell.escape cfg.irc.channel} \ ${shell.escape cfg.irc.channel} \
${lib.escapeShellArg cfg.irc.tls} \ ${escapeShellArg cfg.irc.tls} \
"$message" "$message"
''; '';
default-get-message = pkgs.writeDash "announce-activation-get-message" '' default-get-message = pkgs.writeDash "announce-activation-get-message" ''
set -efu set -efu
PATH=${lib.makeBinPath [ PATH=${makeBinPath [
pkgs.coreutils pkgs.coreutils
pkgs.gawk pkgs.gawk
pkgs.gnused pkgs.gnused
@ -29,37 +28,37 @@ let
''; '';
in { in {
options.krebs.announce-activation = { options.krebs.announce-activation = {
enable = lib.mkEnableOption "announce-activation"; enable = mkEnableOption "announce-activation";
get-message = lib.mkOption { get-message = mkOption {
default = default-get-message; default = default-get-message;
type = lib.types.package; type = types.package;
}; };
irc = { irc = {
# TODO rename channel to target? # TODO rename channel to target?
channel = lib.mkOption { channel = mkOption {
default = "#xxx"; default = "#xxx";
type = lib.types.str; # TODO types.irc-channel type = types.str; # TODO types.irc-channel
}; };
nick = lib.mkOption { nick = mkOption {
default = config.krebs.build.host.name; default = config.krebs.build.host.name;
type = slib.types.label; type = types.label;
}; };
port = lib.mkOption { port = mkOption {
default = 6667; default = 6667;
type = lib.types.int; type = types.int;
}; };
server = lib.mkOption { server = mkOption {
default = "irc.r"; default = "irc.r";
type = slib.types.hostname; type = types.hostname;
}; };
tls = lib.mkOption { tls = mkOption {
default = false; default = false;
type = lib.types.bool; type = types.bool;
}; };
}; };
}; };
config = lib.mkIf cfg.enable { config = mkIf cfg.enable {
system.activationScripts.announce-activation = lib.stringAfter [ "etc" ] '' system.activationScripts.announce-activation = stringAfter [ "etc" ] ''
${announce-activation} ${announce-activation}
''; '';
}; };

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
with lib; with import <stockholm/lib>;
let let
acng-config = pkgs.writeTextFile { acng-config = pkgs.writeTextFile {
name = "acng-configuration"; name = "acng-configuration";

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
out = { out = {
options.krebs.backup = api; options.krebs.backup = api;

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with import <stockholm/lib>;
let let
gunicorn = pkgs.python3Packages.gunicorn; gunicorn = pkgs.python3Packages.gunicorn;
bepasty = pkgs.bepasty; bepasty = pkgs.bepasty;

View File

@ -1,5 +1,5 @@
{ config, pkgs, lib, ... }: with import <stockholm/lib>;
with lib; { config, pkgs, ... }:
let let
cfg = config.krebs.bindfs; cfg = config.krebs.bindfs;
in { in {

View File

@ -1,7 +1,6 @@
{ pkgs, config, lib, ... }: { pkgs, config, ... }:
with lib; with import <stockholm/lib>;
let let
slib = import ../../lib/pure.nix { inherit lib; };
cfg = config.krebs.brockman; cfg = config.krebs.brockman;
in { in {
options.krebs.brockman = { options.krebs.brockman = {
@ -15,7 +14,7 @@ in {
group = "brockman"; group = "brockman";
createHome = true; createHome = true;
isSystemUser = true; isSystemUser = true;
uid = slib.genid_uint31 "brockman"; uid = genid_uint31 "brockman";
}; };
users.groups.brockman = {}; users.groups.brockman = {};

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, ... }:
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
{ {
options.krebs.build = { options.krebs.build = {

View File

@ -1,5 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../../lib/pure.nix { inherit lib; };
with import <stockholm/lib>;
let let
cfg = config.krebs.ci; cfg = config.krebs.ci;
@ -24,7 +25,7 @@ let
}; };
hostname = config.networking.hostName; hostname = config.networking.hostName;
getJobs = pkgs.writers.writeDash "get_jobs" '' getJobs = pkgs.writeDash "get_jobs" ''
set -efu set -efu
${pkgs.nix}/bin/nix-build --no-out-link --quiet --show-trace -Q ./ci.nix >&2 ${pkgs.nix}/bin/nix-build --no-out-link --quiet --show-trace -Q ./ci.nix >&2
json="$(${pkgs.nix}/bin/nix-instantiate --quiet -Q --eval --strict --json ./ci.nix)" json="$(${pkgs.nix}/bin/nix-instantiate --quiet -Q --eval --strict --json ./ci.nix)"
@ -115,7 +116,7 @@ let
build_script = stages[stage], build_script = stages[stage],
), ),
timeout = 3600, timeout = 3600,
command="${pkgs.writers.writeDash "build.sh" '' command="${pkgs.writeDash "build.sh" ''
set -xefu set -xefu
profile=${shell.escape profileRoot}/$build_name profile=${shell.escape profileRoot}/$build_name
result=$("$build_script") result=$("$build_script")

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
with lib; with import <stockholm/lib>;
let let
cfg = config.krebs.current; cfg = config.krebs.current;

View File

@ -1,62 +1,170 @@
{ config, lib, ... }: { config, lib, ... }:
{
imports = [ with import <stockholm/lib>;
../../kartei let
./acl.nix cfg = config.krebs;
./airdcpp.nix
./announce-activation.nix out = {
./apt-cacher-ng.nix imports = [
./backup.nix ../../kartei
./bepasty-server.nix ../../submodules/disko/module.nix
./bindfs.nix ./acl.nix
./brockman.nix ./airdcpp.nix
./build.nix ./announce-activation.nix
./cachecache.nix ./apt-cacher-ng.nix
./ci ./backup.nix
./current.nix ./bepasty-server.nix
./dns.nix ./bindfs.nix
./exim-retiolum.nix ./brockman.nix
./exim-smarthost.nix ./build.nix
./exim.nix ./cachecache.nix
./fetchWallpaper.nix ./ci
./git.nix ./current.nix
./github ./dns.nix
./go.nix ./exim-retiolum.nix
./hidden-ssh.nix ./exim-smarthost.nix
./hosts.nix ./exim.nix
./htgen.nix ./fetchWallpaper.nix
./iana-etc.nix ./git.nix
./iptables.nix ./github
./kapacitor.nix ./go.nix
./konsens.nix ./hidden-ssh.nix
./krebs.nix ./hosts.nix
./krebs-pages.nix ./htgen.nix
./monit.nix ./iana-etc.nix
./nixpkgs.nix ./iptables.nix
./on-failure.nix ./kapacitor.nix
./os-release.nix ./konsens.nix
./per-user.nix ./krebs-pages.nix
./permown.nix ./monit.nix
./power-action.nix ./nixpkgs.nix
./reaktor2.nix ./on-failure.nix
./realwallpaper.nix ./os-release.nix
./repo-sync.nix ./per-user.nix
./retiolum-bootstrap.nix ./permown.nix
./secret.nix ./power-action.nix
./setuid.nix ./reaktor2.nix
./shadow.nix ./realwallpaper.nix
./ssh.nix ./repo-sync.nix
./sitemap.nix ./retiolum-bootstrap.nix
./ssl.nix ./secret.nix
./sync-containers.nix ./setuid.nix
./sync-containers3.nix ./shadow.nix
./systemd.nix ./sitemap.nix
./tinc.nix ./ssl.nix
./tinc_graphs.nix ./sync-containers.nix
./upstream ./sync-containers3.nix
./urlwatch.nix ./systemd.nix
./users.nix ./tinc.nix
./xresources.nix ./tinc_graphs.nix
./zones.nix ./upstream
./urlwatch.nix
./users.nix
./xresources.nix
./zones.nix
];
options.krebs = api;
config = lib.mkIf cfg.enable imp;
};
api = {
enable = mkEnableOption "krebs";
zone-head-config = mkOption {
type = with types; attrsOf str;
description = ''
The zone configuration head which is being used to create the
zone files. The string for each key is pre-pended to the zone file.
'';
# TODO: configure the default somewhere else,
# maybe use krebs.dns.providers
default = {
# github.io -> 192.30.252.154
"krebsco.de" = ''
$TTL 86400
@ IN SOA dns19.ovh.net. tech.ovh.net. (2015052000 86400 3600 3600000 86400)
IN NS ns19.ovh.net.
IN NS dns19.ovh.net.
'';
};
};
};
imp = lib.mkMerge [
{
services.openssh.hostKeys =
let inherit (config.krebs.build.host.ssh) privkey; in
mkIf (privkey != null) [privkey];
services.openssh.knownHosts =
filterAttrs
(knownHostName: knownHost:
knownHost.publicKey != null &&
knownHost.hostNames != []
)
(mapAttrs
(hostName: host: {
hostNames =
concatLists
(mapAttrsToList
(netName: net:
let
aliases =
concatLists [
shortAliases
net.aliases
net.addrs
];
shortAliases =
optionals
(cfg.dns.search-domain != null)
(map (removeSuffix ".${cfg.dns.search-domain}")
(filter (hasSuffix ".${cfg.dns.search-domain}")
net.aliases));
addPort = alias:
if net.ssh.port != 22
then "[${alias}]:${toString net.ssh.port}"
else alias;
in
map addPort aliases
)
host.nets);
publicKey = host.ssh.pubkey;
})
(foldl' mergeAttrs {} [
cfg.hosts
{
localhost = {
nets.local = {
addrs = [ "127.0.0.1" "::1" ];
aliases = [ "localhost" ];
ssh.port = 22;
};
ssh.pubkey = config.krebs.build.host.ssh.pubkey;
};
}
]));
programs.ssh.extraConfig = concatMapStrings
(net: ''
Host ${toString (net.aliases ++ net.addrs)}
Port ${toString net.ssh.port}
'')
(filter
(net: net.ssh.port != 22)
(concatMap (host: attrValues host.nets)
(mapAttrsToList
(_: host: recursiveUpdate host
(optionalAttrs (cfg.dns.search-domain != null &&
hasAttr cfg.dns.search-domain host.nets) {
nets."" = host.nets.${cfg.dns.search-domain} // {
aliases = [host.name];
addrs = [];
};
}))
config.krebs.hosts)));
}
]; ];
}
in out

View File

@ -1,5 +1,5 @@
{ config, lib, pkgs, ... }: with import <stockholm/lib>;
with import ../../lib/pure.nix { inherit lib; }; { { config, ... }: {
options = { options = {
krebs.dns.providers = mkOption { krebs.dns.providers = mkOption {
type = types.attrsOf types.str; type = types.attrsOf types.str;
@ -8,7 +8,7 @@ with import ../../lib/pure.nix { inherit lib; }; {
type = types.nullOr types.hostname; type = types.nullOr types.hostname;
}; };
}; };
config = lib.mkIf config.krebs.enable { config = mkIf config.krebs.enable {
krebs.dns.providers = { krebs.dns.providers = {
"krebsco.de" = "zones"; "krebsco.de" = "zones";
shack = "hosts"; shack = "hosts";

View File

@ -1,5 +1,5 @@
{ config, pkgs, lib, ... }: with import <stockholm/lib>;
with import ../../lib/pure.nix { inherit lib; }; let { config, pkgs, lib, ... }: let
cfg = config.krebs.exim-retiolum; cfg = config.krebs.exim-retiolum;
# Due to improvements to the JSON notation, braces around top-level objects # Due to improvements to the JSON notation, braces around top-level objects

View File

@ -1,6 +1,6 @@
{ config, pkgs, lib, ... }: { config, pkgs, lib, ... }:
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
cfg = config.krebs.exim-smarthost; cfg = config.krebs.exim-smarthost;

View File

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }: with import ../../lib/pure.nix { inherit lib; }; let { config, lib, pkgs, ... }: with import <stockholm/lib>; let
cfg = config.krebs.exim; cfg = config.krebs.exim;
in { in {
options.krebs.exim = { options.krebs.exim = {

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
cfg = config.krebs.fetchWallpaper; cfg = config.krebs.fetchWallpaper;

View File

@ -6,14 +6,14 @@
# TODO when authorized_keys changes, then restart ssh # TODO when authorized_keys changes, then restart ssh
# (or kill already connected users somehow) # (or kill already connected users somehow)
with import ../../lib/pure.nix { inherit lib; }; with import <stockholm/lib>;
let let
cfg = config.krebs.git; cfg = config.krebs.git;
out = { out = {
options.krebs.git = api; options.krebs.git = api;
config = with lib; lib.mkIf cfg.enable (mkMerge [ config = with lib; mkIf cfg.enable (mkMerge [
(lib.mkIf cfg.cgit.enable cgit-imp) (mkIf cfg.cgit.enable cgit-imp)
git-imp git-imp
]); ]);
}; };
@ -446,7 +446,7 @@ let
]; ];
locations."/".extraConfig = '' locations."/".extraConfig = ''
include ${pkgs.nginx}/conf/fastcgi_params; include ${pkgs.nginx}/conf/fastcgi_params;
fastcgi_param SCRIPT_FILENAME ${pkgs.writers.writeDash "cgit-wrapper" '' fastcgi_param SCRIPT_FILENAME ${pkgs.writeDash "cgit-wrapper" ''
set -efu set -efu
exec 3>&1 exec 3>&1
${pkgs.cgit}/cgit/cgit.cgi "$@" 2>&1 >&3 3>&- \ ${pkgs.cgit}/cgit/cgit.cgi "$@" 2>&1 >&3 3>&- \

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with import <stockholm/lib>;
let let
cfg = config.krebs.github-hosts-sync; cfg = config.krebs.github-hosts-sync;

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with import <stockholm/lib>;
let let
cfg = config.krebs.go; cfg = config.krebs.go;

View File

@ -1,6 +1,6 @@
{ config, lib, pkgs, ... }: { config, lib, pkgs, ... }:
with lib; with import <stockholm/lib>;
let let
cfg = config.krebs.hidden-ssh; cfg = config.krebs.hidden-ssh;

View File

@ -1,19 +1,17 @@
{ config, lib, pkgs, ... }: with import <stockholm/lib>;
with lib; let { config, ... }: let
check = hostname: any (domain: hasSuffix ".${domain}" hostname) domains; check = hostname: any (domain: hasSuffix ".${domain}" hostname) domains;
domains = attrNames (filterAttrs (_: slib.eq "hosts") config.krebs.dns.providers); domains = attrNames (filterAttrs (_: eq "hosts") config.krebs.dns.providers);
# we need this import because we have infinite recursion otherwise
slib = import ../../lib/pure.nix { inherit lib; };
in { in {
options = { options = {
krebs.hosts = mkOption { krebs.hosts = mkOption {
default = {}; default = {};
type = types.attrsOf slib.types.host; type = types.attrsOf types.host;
}; };
}; };
config = lib.mkIf config.krebs.enable { config = mkIf config.krebs.enable {
networking.hosts = networking.hosts =
filterAttrs filterAttrs
(_name: value: value != []) (_name: value: value != [])
@ -93,7 +91,7 @@ in {
(concatLists (attrValues netAliases)); (concatLists (attrValues netAliases));
} }
// //
slib.genAttrs' (attrNames netAliases) (netname: rec { genAttrs' (attrNames netAliases) (netname: rec {
name = "krebs-hosts-${netname}"; name = "krebs-hosts-${netname}";
value = writeHosts name netAliases.${netname}; value = writeHosts name netAliases.${netname};
}); });

Some files were not shown because too many files have changed in this diff Show More