Compare commits
69 commits
main
...
asterisk-t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
32aa08d39c | ||
|
|
fbd94fb3f9 | ||
|
|
0fd18c5b4d | ||
|
|
346cd977d7 | ||
|
|
81ad290491 | ||
|
|
0f03bb0409 | ||
|
|
3dece6dba6 | ||
|
|
0b5f6200d8 | ||
|
|
2440ea285c | ||
|
|
39655d2f37 | ||
|
|
e66b8963f1 | ||
|
|
fbbf11a8a5 | ||
|
|
2955cf4996 | ||
|
|
342bdb607c | ||
|
|
4d014c5559 | ||
|
|
7fa79f7a74 | ||
|
|
ba7f7f099c | ||
|
|
4ee194be6c | ||
|
|
462a50c120 | ||
|
|
fdab91a7f8 | ||
|
|
a4913e5f7e | ||
|
|
d12b2e51a8 | ||
|
|
3b398720dd | ||
|
|
8e5300131a | ||
|
|
82190e12e2 | ||
|
|
b9ed865a8b | ||
|
|
9f47f7c83b | ||
|
|
cc34d682de | ||
|
|
92922f75f1 | ||
|
|
5d260a84fa | ||
|
|
c00079d180 | ||
|
|
3e5e7304ee | ||
|
|
ad2d6ba39c | ||
|
|
9e8437fca5 | ||
|
|
7f3b3ed65a | ||
|
|
c3ca14295e | ||
|
|
c60656b7c3 | ||
|
|
cb2b785688 | ||
|
|
f8845321fe | ||
|
|
6662285211 | ||
|
|
1e5f10b020 | ||
|
|
8828ca4c05 | ||
|
|
3d2d2f4a2b | ||
|
|
d1bc2cb8ac | ||
|
|
fa62cf6558 | ||
|
|
54c764eb11 | ||
|
|
c6813f937e | ||
|
|
3f73d5b94c | ||
|
|
2b2dad702b | ||
|
|
35890d09eb | ||
|
|
8e0acf5568 | ||
|
|
2d13d82653 | ||
|
|
04ee07bda0 | ||
|
|
6ee2707a46 | ||
|
|
5ca3494614 | ||
|
|
e769bc6ce6 | ||
|
|
ef6e883879 | ||
|
|
93c183ee36 | ||
|
|
7168d62706 | ||
|
|
1a27405bc9 | ||
|
|
e4be66ecce | ||
|
|
07605cfe43 | ||
|
|
1f74195ae5 | ||
|
|
32e9d7f9d8 | ||
|
|
19c75eb13a | ||
|
|
4047841fc7 | ||
|
|
2f3fa5ab1d | ||
|
|
6365154220 | ||
|
|
0dd85726e0 |
93 changed files with 3072 additions and 908 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
|
@ -1,2 +1,3 @@
|
|||
**/secrets/** filter=git-crypt diff=git-crypt
|
||||
**/secrets.yaml diff=sops
|
||||
*.wav filter=lfs diff=lfs merge=lfs -text
|
||||
|
|
|
|||
33
custom-utils/default.nix
Normal file
33
custom-utils/default.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{ lib, ... }:
|
||||
|
||||
let
|
||||
filterPort = pm: port: (
|
||||
lib.attrsets.catAttrs port (
|
||||
lib.attrsets.attrValues (
|
||||
lib.attrsets.filterAttrs (n: v: v ? "${port}") pm
|
||||
)
|
||||
)
|
||||
);
|
||||
onlyUniqueItemsInList = (x: lib.lists.length x == lib.lists.length (lib.lists.unique x));
|
||||
protocols = (x: lib.lists.unique (lib.flatten (map builtins.attrNames (lib.attrValues x))));
|
||||
mkRange = (x: lib.lists.range (builtins.elemAt x 0) (builtins.elemAt x 1));
|
||||
validateList = allowed: builtins.all (x: builtins.elem x allowed);
|
||||
in
|
||||
{
|
||||
validatePortAttrset = portmap:
|
||||
if ! onlyUniqueItemsInList (lib.flatten (map
|
||||
(x:
|
||||
if lib.isInt x then x
|
||||
else if lib.isList x then x
|
||||
else if lib.isAttrs x then
|
||||
(
|
||||
if ! validateList [ "range" ] (builtins.attrNames x) then builtins.abort "found invalid attribute name"
|
||||
else if x ? "range" then if lib.lists.length x.range == 2 then mkRange x.range else builtins.abort "range needs a list with exactly two items"
|
||||
else builtins.abort "found invalid attrset"
|
||||
)
|
||||
else builtins.abort "found invalid entry in portmap"
|
||||
)
|
||||
(filterPort portmap "udp"))) then builtins.abort "Found duplicate ports."
|
||||
else if ! validateList [ "tcp" "udp" ] (protocols portmap) then builtins.abort "Found invalid protocol."
|
||||
else portmap;
|
||||
}
|
||||
33
custom-utils/ports.nix
Normal file
33
custom-utils/ports.nix
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
{ lib, ... }:
|
||||
|
||||
let
|
||||
filterPort = pm: port: (
|
||||
lib.attrsets.catAttrs port (
|
||||
lib.attrsets.attrValues (
|
||||
lib.attrsets.filterAttrs (n: v: v ? "${port}") pm
|
||||
)
|
||||
)
|
||||
);
|
||||
onlyUniqueItemsInList = (x: lib.lists.length x == lib.lists.length (lib.lists.unique x));
|
||||
protocols = (x: lib.lists.unique (lib.flatten (map builtins.attrNames (lib.attrValues x))));
|
||||
mkRange = (x: lib.lists.range (builtins.elemAt x 0) (builtins.elemAt x 1));
|
||||
validateList = allowed: builtins.all (x: builtins.elem x allowed);
|
||||
in
|
||||
{
|
||||
validatePortAttrset = portmap:
|
||||
if ! onlyUniqueItemsInList (lib.flatten (map
|
||||
(x:
|
||||
if lib.isInt x then x
|
||||
else if lib.isList x then x
|
||||
else if lib.isAttrs x then
|
||||
(
|
||||
if ! validateList [ "range" ] (builtins.attrNames x) then builtins.abort "found invalid attribute name"
|
||||
else if x ? "range" then if lib.lists.length x.range == 2 then mkRange x.range else builtins.abort "range needs a list with exactly two items"
|
||||
else builtins.abort "found invalid attrset"
|
||||
)
|
||||
else builtins.abort "found invalid entry in portmap"
|
||||
)
|
||||
(filterPort portmap "udp"))) then builtins.abort "Found duplicate ports."
|
||||
else if ! validateList [ "tcp" "udp" ] (protocols portmap) then builtins.abort "Found invalid protocol."
|
||||
else portmap;
|
||||
}
|
||||
78
flake.lock
generated
78
flake.lock
generated
|
|
@ -21,11 +21,11 @@
|
|||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1687709756,
|
||||
"narHash": "sha256-Y5wKlQSkgEK2weWdOu4J3riRd+kV/VCgHsqLNTTWQ/0=",
|
||||
"lastModified": 1694529238,
|
||||
"narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "dbabf0ca0c0c4bce6ea5eaf65af5cb694d2082c7",
|
||||
"rev": "ff7b65b44d01cf9ba6a71320833626af21126384",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -55,6 +55,29 @@
|
|||
"type": "github"
|
||||
}
|
||||
},
|
||||
"gomod2nix": {
|
||||
"inputs": {
|
||||
"flake-utils": [
|
||||
"flake-utils"
|
||||
],
|
||||
"nixpkgs": [
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1694616124,
|
||||
"narHash": "sha256-c49BVhQKw3XDRgt+y+uPAbArtgUlMXCET6VxEBmzHXE=",
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"rev": "f95720e89af6165c8c0aa77f180461fe786f3c21",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "gomod2nix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
|
|
@ -62,11 +85,11 @@
|
|||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1687871164,
|
||||
"narHash": "sha256-bBFlPthuYX322xOlpJvkjUBz0C+MOBjZdDOOJJ+G2jU=",
|
||||
"lastModified": 1695108154,
|
||||
"narHash": "sha256-gSg7UTVtls2yO9lKtP0yb66XBHT1Fx5qZSZbGMpSn2c=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "07c347bb50994691d7b0095f45ebd8838cf6bc38",
|
||||
"rev": "07682fff75d41f18327a871088d20af2710d4744",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -110,11 +133,11 @@
|
|||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1688596063,
|
||||
"narHash": "sha256-9t7RxBiKWHygsqXtiNATTJt4lim/oSYZV3RG8OjDDng=",
|
||||
"lastModified": 1699271226,
|
||||
"narHash": "sha256-8Jt1KW3xTjolD6c6OjJm9USx/jmL+VVmbooADCkdDfU=",
|
||||
"owner": "cachix",
|
||||
"repo": "pre-commit-hooks.nix",
|
||||
"rev": "c8d18ba345730019c3faf412c96a045ade171895",
|
||||
"rev": "ea758da1a6dcde6dc36db348ed690d09b9864128",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -126,11 +149,11 @@
|
|||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1685866647,
|
||||
"narHash": "sha256-4jKguNHY/edLYImB+uL8jKPL/vpfOvMmSlLAGfxSrnY=",
|
||||
"lastModified": 1689261696,
|
||||
"narHash": "sha256-LzfUtFs9MQRvIoQ3MfgSuipBVMXslMPH/vZ+nM40LkA=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a53a3bec10deef6e1cc1caba5bc60f53b959b1e8",
|
||||
"rev": "df1eee2aa65052a18121ed4971081576b25d6b5c",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -158,11 +181,11 @@
|
|||
},
|
||||
"nixpkgs-stable_2": {
|
||||
"locked": {
|
||||
"lastModified": 1688868408,
|
||||
"narHash": "sha256-RR9N5XTAxSBhK8MCvLq9uxfdkd7etC//seVXldy0k48=",
|
||||
"lastModified": 1699110214,
|
||||
"narHash": "sha256-L2TU4RgtiqF69W8Gacg2jEkEYJrW+Kp0Mp4plwQh5b8=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "510d721ce097150ae3b80f84b04b13b039186571",
|
||||
"rev": "78f3a4ae19f0e99d5323dd2e3853916b8ee4afee",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -174,11 +197,11 @@
|
|||
},
|
||||
"nixpkgsMaster": {
|
||||
"locked": {
|
||||
"lastModified": 1689015649,
|
||||
"narHash": "sha256-so1x2XDFiN6B9JO2rDmscgQ7+urdQRbnNRwiq50KJnM=",
|
||||
"lastModified": 1699437456,
|
||||
"narHash": "sha256-nYPKALWauhG5WvGhx7whUCNFTeLZEtchEre+3Mze4eI=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "72c08deeab9e6ca478aad5416e63b72bef5c11fb",
|
||||
"rev": "e556bb0b675a849371645b6b79eccd4130744967",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -190,11 +213,11 @@
|
|||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1688939073,
|
||||
"narHash": "sha256-jYhYjeK5s6k8QS3i+ovq9VZqBJaWbxm7awTKNhHL9d0=",
|
||||
"lastModified": 1699291058,
|
||||
"narHash": "sha256-5ggduoaAMPHUy4riL+OrlAZE14Kh7JWX4oLEs22ZqfU=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8df7a67abaf8aefc8a2839e0b48f92fdcf69a38b",
|
||||
"rev": "41de143fda10e33be0f47eab2bfe08a50f234267",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -206,11 +229,11 @@
|
|||
},
|
||||
"nur": {
|
||||
"locked": {
|
||||
"lastModified": 1689007503,
|
||||
"narHash": "sha256-T5oA+mq2ZXTVNWvCSvZqrjZBaVzY9hwwiI4uPiGkXM4=",
|
||||
"lastModified": 1699435759,
|
||||
"narHash": "sha256-K1G+UfpvvWFSbHdWtCOTI1MCK4ivQpu/bz9DWB66SJc=",
|
||||
"owner": "nix-community",
|
||||
"repo": "NUR",
|
||||
"rev": "46663cf4a220139e81691144278fa1f637c22615",
|
||||
"rev": "9249f2baa49a8ba139eb084128e092073ed88c4e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
@ -222,6 +245,7 @@
|
|||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"gomod2nix": "gomod2nix",
|
||||
"home-manager": "home-manager",
|
||||
"krops": "krops",
|
||||
"nix-pre-commit-hooks": "nix-pre-commit-hooks",
|
||||
|
|
@ -239,11 +263,11 @@
|
|||
"nixpkgs-stable": "nixpkgs-stable_2"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1688873469,
|
||||
"narHash": "sha256-9TMSXvXmrr7bDYi+WeskWe/yho9UP01dGbV9vW5bRVc=",
|
||||
"lastModified": 1699311858,
|
||||
"narHash": "sha256-W/sQrghPAn5J9d+9kMnHqi4NPVWVpy0V/qzQeZfS/dM=",
|
||||
"owner": "Mic92",
|
||||
"repo": "sops-nix",
|
||||
"rev": "b2047c8fc963407916ad3834165309007dc5a1f7",
|
||||
"rev": "664187539871f63857bda2d498f452792457b998",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
|
|
|||
17
flake.nix
17
flake.nix
|
|
@ -28,12 +28,22 @@
|
|||
nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
gomod2nix = {
|
||||
url = "github:nix-community/gomod2nix";
|
||||
inputs = {
|
||||
flake-utils.follows = "flake-utils";
|
||||
nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
outputs =
|
||||
{ self
|
||||
, nixpkgs
|
||||
, flake-utils
|
||||
, krops
|
||||
, gomod2nix
|
||||
, home-manager
|
||||
, nur
|
||||
, nix-pre-commit-hooks
|
||||
|
|
@ -124,7 +134,7 @@
|
|||
};
|
||||
});
|
||||
}) // {
|
||||
overlay = import ./pkgs;
|
||||
overlays.default = import ./pkgs inputs;
|
||||
|
||||
nixosConfigurations = nixpkgs.lib.mapAttrs
|
||||
(hostname: { system
|
||||
|
|
@ -141,7 +151,10 @@
|
|||
./modules
|
||||
|
||||
{
|
||||
_module.args.inputs = inputs;
|
||||
_module.args = {
|
||||
inputs = inputs;
|
||||
custom-utils = import ./custom-utils { lib = nixpkgs.lib; };
|
||||
};
|
||||
}
|
||||
|
||||
# deployment settings
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
cached-nix-shell
|
||||
file
|
||||
htop
|
||||
inetutils
|
||||
jq
|
||||
lsof
|
||||
ncdu
|
||||
|
|
@ -15,7 +16,6 @@
|
|||
speedtest-cli
|
||||
usbutils
|
||||
wget
|
||||
whois
|
||||
yt-dlp
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ nixosConfig, lib, pkgs, ... }:
|
||||
|
||||
|
||||
let dynamic-colors = pkgs.writeShellScriptBin "dynamic-colors" /* bash */ ''
|
||||
let
|
||||
dynamic-colors = pkgs.writeShellScriptBin "dynamic-colors" /* bash */ ''
|
||||
case "''$1" in
|
||||
light|dark)
|
||||
if [ -e "''$HOME/.config/alacritty/alacritty-''$1.yml" ]; then
|
||||
|
|
@ -12,7 +12,7 @@ let dynamic-colors = pkgs.writeShellScriptBin "dynamic-colors" /* bash */ ''
|
|||
echo "unknown command ''$1" >&2
|
||||
exit 1
|
||||
esac
|
||||
'';
|
||||
'';
|
||||
in
|
||||
{
|
||||
home.packages = [
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
alias.find-merge = "!sh -c 'commit=$0 && branch=\${1:-HEAD} && (git rev-list $commit..$branch --ancestry-path | cat -n; git rev-list $commit..$branch --first-parent | cat -n) | sort -k2 -s | uniq -f1 -d | sort -n | tail -1 | cut -f2'";
|
||||
alias.show-merge = "!sh -c 'merge=$(git find-merge $0 $1) && [ -n \"$merge\" ] && git show $merge'";
|
||||
};
|
||||
lfs.enable = true;
|
||||
};
|
||||
fish = {
|
||||
shellAbbrs = {
|
||||
|
|
@ -40,7 +41,7 @@
|
|||
gpll = "git pull";
|
||||
gpsh = "git push";
|
||||
grb = "git rebase --autostash";
|
||||
grbi = "git rebase --autostash --interactive --autosquash \(git merge-base HEAD origin/master\)";
|
||||
grbi = "git rebase --autostash --interactive --autosquash refs/remotes/origin/HEAD";
|
||||
gr = "git restore";
|
||||
grs = "git restore --staged";
|
||||
grst = "git reset";
|
||||
|
|
@ -95,16 +96,16 @@
|
|||
end
|
||||
'';
|
||||
};
|
||||
git_pick-commit_merge-base_origin_master = {
|
||||
git_pick-commit_merge-base_origin = {
|
||||
description = "fuzzy find a commit hash";
|
||||
body = ''
|
||||
git log --oneline (git merge-base HEAD origin/master)..HEAD | ${pkgs.fzf}/bin/fzf --preview='git show (echo {} | cut -d" " -f 1)' --preview-window=top:75% | cut -d" " -f 1
|
||||
git log --oneline refs/remotes/origin/HEAD..HEAD | ${pkgs.fzf}/bin/fzf --preview='git show (echo {} | cut -d" " -f 1)' --preview-window=top:75% | cut -d" " -f 1
|
||||
'';
|
||||
};
|
||||
gfix = {
|
||||
description = "git commit --fixup with fuzzy find commmit picker";
|
||||
body = ''
|
||||
set commit (git_pick-commit_merge-base_origin_master)
|
||||
set commit (git_pick-commit_merge-base_origin)
|
||||
commandline "git commit --fixup=$commit"
|
||||
'';
|
||||
};
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@
|
|||
builtins.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList
|
||||
(
|
||||
lang: cfg: "lsp.${lang}.setup\n" + lib.generators.toLua { asBindings = false; indent = " "; } cfg
|
||||
lang: cfg: "lsp.${lang}.setup\n" + lib.generators.toLua { } cfg
|
||||
)
|
||||
{
|
||||
# C and C++
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ in
|
|||
./gammastep.nix
|
||||
./waybar.nix
|
||||
./wofi.nix
|
||||
./wofi-bluetooth.nix
|
||||
./yubikey-touch-detector.nix
|
||||
];
|
||||
} // (lib.mkIf nixosConfig.jalr.gui.enable {
|
||||
|
|
|
|||
5
home-manager/modules/sway/wofi-bluetooth.nix
Normal file
5
home-manager/modules/sway/wofi-bluetooth.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{ nixosConfig, lib, pkgs, ... }:
|
||||
|
||||
lib.mkIf nixosConfig.jalr.bluetooth.enable {
|
||||
home.packages = [ pkgs.wofi-bluetooth ];
|
||||
}
|
||||
|
|
@ -1,10 +1,6 @@
|
|||
{ nixosConfig, lib, pkgs, ... }:
|
||||
lib.mkIf nixosConfig.jalr.gui.enable {
|
||||
home.packages = with pkgs; [
|
||||
(
|
||||
tor-browser-bundle-bin.override {
|
||||
useHardenedMalloc = false;
|
||||
}
|
||||
)
|
||||
tor-browser-bundle-bin
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ let
|
|||
userName = "jal";
|
||||
vpn_routes = [
|
||||
"10.18.0.0/16" # OEE VPC
|
||||
"10.64.64.0/20" # CPS
|
||||
"10.64.0.0/16" # CPS
|
||||
"10.158.128.0/23" # approval
|
||||
"10.158.224.0/20" # core production
|
||||
"10.158.240.0/20" # core development
|
||||
|
|
@ -12,11 +12,13 @@ let
|
|||
#"10.96.8.0/24" # Boomi
|
||||
#"10.96.10.0/24" # Boomi (new)
|
||||
"10.96.0.0/16"
|
||||
"10.170.254.30/32" # core DNS resolver
|
||||
"10.170.254.30/32" "10.170.254.40/32" # core DNS resolver
|
||||
];
|
||||
vpnc-script = pkgs.writeShellScript "vpnc-script-tb" ''
|
||||
cisco_split_inc="$CISCO_SPLIT_INC"
|
||||
export CISCO_SPLIT_INC=0
|
||||
|
||||
echo "DNS server sent by vpn: $INTERNAL_IP4_DNS"
|
||||
unset INTERNAL_IP4_DNS
|
||||
|
||||
route_in_whitelist() {
|
||||
|
|
|
|||
|
|
@ -59,33 +59,32 @@
|
|||
bootloader = "grub2";
|
||||
};
|
||||
|
||||
fileSystems."/" =
|
||||
{
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/2c5b0de0-c55f-4327-bd60-1aee6c8ae234";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=root" ];
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{
|
||||
"/proc" = {
|
||||
device = "/proc";
|
||||
options = [ "nosuid" "noexec" "nodev" "hidepid=2" ];
|
||||
};
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/2c5b0de0-c55f-4327-bd60-1aee6c8ae234";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=home" ];
|
||||
options = [ "subvol=home" "nodev" "nosuid" ];
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{
|
||||
"/nix" = {
|
||||
device = "/dev/disk/by-uuid/2c5b0de0-c55f-4327-bd60-1aee6c8ae234";
|
||||
fsType = "btrfs";
|
||||
options = [ "subvol=nix" ];
|
||||
options = [ "subvol=nix" "nodev" ];
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/695df89b-948d-4659-8f57-335e8b25a8c5";
|
||||
fsType = "ext2";
|
||||
options = [ "nodev" "nosuid" "noexec" ];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
|
|
|
|||
7
hosts/aluminium/ports.nix
Normal file
7
hosts/aluminium/ports.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
{ lib, custom-utils, ... }:
|
||||
|
||||
custom-utils.validatePortAttrset {
|
||||
asterisk-rtp = { udp.range = [ 10000 10200 ]; };
|
||||
unifi.tcp = 8443;
|
||||
doorbell-audiosocket.tcp = 9092;
|
||||
}
|
||||
|
|
@ -1,8 +1,9 @@
|
|||
duckdns-secret: ENC[AES256_GCM,data:hp4aWnmTYKZhBehY0nuRV+H9bpCdK2uNqY3J0s1w6JsiyXip,iv:X0MtN+lqDqucgHOgS1D/RrMksNydLFW1/wqD47DWhqQ=,tag:+7qsJEJYzI+UUrdC6NZr4Q==,type:str]
|
||||
pap-secrets: ENC[AES256_GCM,data:UyC63/4EXZjypFlH7MLtJXpIBgD9P/Eolg2M1A==,iv:tf8W8rpRa487PIB9NW4NyDKgCoWYV/wDgs9MmKLZ/mc=,tag:r+zgW8XI9TUyoz56irYEdQ==,type:str]
|
||||
myintercom-doorbell-password: ENC[AES256_GCM,data:waUUvHQ9BZFePQ==,iv:ev21SNOwzdNMc3Opo6Kgdd7daLNUf9e1/C9RtxQKV8U=,tag:aOi2f3VuR49J0sHNrVXW/A==,type:str]
|
||||
asterisk-pjsip: ENC[AES256_GCM,data:PMgHCdo7K1a9/OitWdUonJ66gr70uwYgylCCWAO9cYOeXdPTIFuFLHlgBIUUxfln3UqhquTzoTluZJW9vaSuzZGe1kLIYrb1hRyrM0HLCCQc8m46jN898le/9ZrEivxonWkxf4FTfpENIf7iEr5KHh4vfd4tr4IbORTFdpcbsy8pd5eyvS8G2z9dynIWS19zqrzfGrW6yZICzAJz28IQCiiHgpN16bqSwlcPm1UdX+qi0+ZJ3TAr16Px1F9VFOXtEsu4EZvJSomecJDuhjo3QzBFffXDL971of8KX05BJgtpP6SzIZXKfSWaOxaguctdFr2tScvze0o3FXpDoOn0cvinOdYQt1P2TzjFnBZ4I3N1turpD4be9xJ92coV/j1hBsZHj2mWE/iCdsrzj2uP/74b4Mo1BJZ6l1gXFg3OgyDXaVoMxAOnutelCEG0lf78hsJXF56aQ1LVSUly6ugZP4rMiPFg5oa7WfrIsVVURUt7WRFrDLCYIQVynpfeUxHshPSB+/jVvYLqie5XeNt8B8mgTJYFo5hFB28sa1beqYEA27QMT3gRvWivqDnuf8soVi/r3WREfnSCBujhzXQF/uJZEwqVEn0OQo9ICfJ8hqtvDiAw6Hb4Wn+0maoYQeKjbPHeL3kr1SUE/kU913FNig4Yn66QKYevLLIkd3uQ0GqTLcgn4Ttwu3qArlXXxrI4US8yA7XGQUutVadN7ayyZBbYnw+vUTlPfhSO+ridK3huGKnQfcPAbD31L11EeQBe2820Nba9Bb4d5QAkiGsNj5y9tZ4Vl6l2JErO63fVPKQ9fPxD3yYyZpP8Hm1e7Wl1eRsNtoWqkTRtno7hIpAYFoMYTUk2x5U/qZOgtRX0JHufi6+GXvPPlBaQNfiGzNlJjdmtTT6MGLPRQjsASGi00pSjKd4psAj9Uf8rttsHhJHvIRDRsiNSjae+JGbVlyyauU1JL44Qf+U+MaJDjkLagNqUZ9xgNFmXzr7st6bRFYCJHkmQC8bgJsdpwRMz3HjNzrKZRvRhHIiwT3d+oyrd9hoSQl3JkxcrD7AfEThrBQL9BpGCDcfr5RzfNv8Fb08tR7rlIzyb6Rw3eKlY1obfZRRNTF+iYlBDz8LLI+BwWqJiefbHB2F9nOC0of5Eqm5gjn+MXSKuSIP5ltDsjfO+m6q7c+t7udKwnJVnePtOnuf4uQpKfxjpld4e8Y1N9hyuKSjqEy83UB4yXJb1OoUAOXENvdPhGFDghmSC+ZVcCZRBG2k6d6MdXY6AkdjUAteDQLsDNMwpW8a8RwOXlDoAtxu7yEYP51BrHu2spagNfXMWHThnkcuR/TvqAPmcPlzVjcX+tnuU0k+JK5e4eWc+diTcvo8fpeaKi7A4uyGWRaZsoaauxsK1dEwIgmAAYyWc0Hl+Z49/dLW8kgr/Qh9N5SRRk/SLk4GvS0uyYYClN7G/7LdMDUwWifr32oqXEINDh0NEyehEJ9dEQsIIH5gR3OdlEAuL1C7/Js3/ZCdBREXRYt4y5y4TAO/kMmGgv7Y/Z2XVD0klXVBMvVnil4LJ0H5KF+RZC4j/C6acRBdrPaI0nlE3bfAbmizQN9D7jOj5BkkRzBaYlMaBuFKRKUA6CUanhUWhIn3ZlF3Z+o4PGB2c7EFXZN+PzOSgkQYUD7KtVW/QV94mxkcqN9mKe6mAbj87neN1IHhEkNOj7KJQP60pqDjx6N+WYFpD3sYvDcJDg2WFumR8F2v+jHx09v5AB1r6AzhPJ3TCwnHN4e1+Nexxlb91iPcoSmLRF3Fimn7307260CtaA70hngWHSRaBcKTXi3WL1v9kKOou2kKs1GMy5bjREtqheBxZ1i4x56VtANF9lo9UT+97qxuAqk08Rc4z9j5M8cJK/d1syRT0z/uAuTWlRgxdE/Fj/OlDNr/SnZw9CLkQ0SVJAuJFFg9EY0ru3PC9PDNt9CJiVy0GoeK0mv7ZkTv2o456kdzMpJPBwpKLIO9tpZBbNZrMn1HpLJrfXIvmuVDFmm3EH6FVhGoI+4yB11Eo/2aEMzUOEtn55KNeESkoVel6GgYiwrg1ZlQS7XhdCTGyCOMbFTOLHgUe4vaUfPBNOyLaLWE3ZiyGCxVb+nBltcPSDHrNtbc2fuPqVom3Z1wfmako1BGcwRzbLdaUPwuu6eRa/KxppPh/PoYTttPxOArql25BWAVTI6BIhlvGgZgqDRwihHBGt1uyXjwv4ufES5zgxhMB8mNqVnCSkcLXXyvpmCiB5kEv5+V4nCJIXSNbmym+V9tEzGh+cx8up24IHrg6gG28fHfMcV7Z+JzN86jogr+sgH9wigrcYcDqTE9lHJhaZlmNraTl8viAwEXkPC/dnQuPSTX5V1qeRtKo1oFkf9xnPhdVLq51GoVU+MhQqZsbnqymgKnPWTQq3Kyiux5go/Li0BqfiV+Wwpn+f3WXJ21aMpU2FfIR26z2DULlJUYDKoewmklq8vzk5iZ/tywPFGR1G0z8IM5jwr+qz0uEccAtulCWsQjtvw0kGLnTsoB2WNL4x0Kti/cE14purKaE65wMrBoG/mxd6R7ZHE7u/Uo1MDAsgqsS8MomCqyxC/1yH9BdhpXc6VZJpborqWQjW/kK8/OBxWFjfQgwvDGeQkgv2ShV0c8U6DgnS545Im9aAxQGvu1sXMhnVNQZdZ2Ta3Gz7bTHqkxB4/X7KGHdGSmw5s/RQfo0BkBBBLLTc49pcmJTxG5LPkRebCM8ANX57qj3u/D9wYumFKclTglNdrjaxSdh3zTb1kEQ0rn/D4z7lVNUsw7srUUZeEadg3xTZSmSustbziXvp51juiJeyPjVY2AlmbVVxU0O245kbyWA8lHcEluo+dfk0Rr9hDNHz35NxQRCslPHiSKswxfuPcqyzlSiBMLsMWrJ5/RyQJgaO/XJ/x3R2o4h+MiHtUKj91epxAIpYD8JqQ4eaUkP6GJRNDSNLK3VNP69Qecc7b6AvV5udzt2up0lp7OuzEZeT88Vg8YcZvOv1UTxmkI6dem1xi4imJs+V4OZrcSt9ZTlc34rc6/lvVxVQZs/1vADB0ZVk3jp24KWuRWFGacJqUIxW8TbI8N1DtmZcf7sqoQU1QPRzkOa/UYmzWablAP4B5M5WOjyr3YSJGOzHxN+GSSs4K4jHUon+LbpKxHL5KJUSsD+kZFTfsDauFhAzpFDhR2wW/XYLr0iTvKQ6+26dIpW65P8Egv+n/CXQE0wuJ1R5z0M4FucpUo+FTUIcww8cfqfHqMlMeKEFeu8/QNdZ0uj06Q8/j6E/OUjpxTIVRQBs4qaLWxMZv3zulCUe9Czr6c28NhewIJlLUxOnCVDo5pT1OmzZPghurNyhTBFP8PfJrRXN1h2uvXfGP46dgt9jgeqqQqP9xlq+fzo9cyEZ/n4nQvY+CBuOW9Cqo41zNB0PQ3tC9SU477gQkDrg0M6/bAk+xsqVg1DpZOSuRUQnOfbTdZ1CXhESy+dcri9BeKKcTCZ6aenvW4W4J6OV8en3L4jPFsgqEWJUk1qr9ggM5NXc7RIrR0eCsiR9V1gi4HWMF1roTZ3wK9NvdATj3HWTGssfdpXht/vjedIp+InNWBWjnBfIf7XWuPgiB/ZW9uew8g8vDLULGVtww==,iv:bFKc8e+3rLAHje8UWwY2elof5xqceTTWX1f7nkE91nM=,tag:NWMiljj8urTDoka5bkF0jg==,type:str]
|
||||
asterisk-ari: ENC[AES256_GCM,data:HnY7d3BdScb0bmsBVlsTHAMv2k8tyyA/,iv:q+NsCHcGGOCe6gdAHbFfjKvO4dyWoW/xI5jtngJmdds=,tag:e8kuEsEokf5lAAgO/coxTQ==,type:str]
|
||||
asterisk-voicemail: ENC[AES256_GCM,data:UbMjSgxZpUDzPpeVPQKfDEwKe/KgZJdMf+1q7YyPtjqiw80flSo3NqLREtuGshHVFqTSS+UFoucpJMx0qB3h4YCqJgSsJQB692q1fra1aLtnw08u1eEkqyi4EKBN4KuaD8E6zggN7Zor7IqEPrAp3H/JAWvoMqGaWZTn4vJbNnzFHp9JPvzyf0emmXTXm+SJFjoSjuT3tgrimQ9UsgUrX4Nxx6ZTMKnRU72+sEaRqtSjlYfk4aYveB82oV+s1iexGidy8vgVEJzRxkkbc87+2BrSTGW63VjIMLSYAFYOQp+hsP263lRJ8ZJYdJqrk49KXMpz8M5/lgk4P78Z/1PQ741CxpzLfo2oXij6jNPaH4jGujrsqK6lUSWi4g9rft76hYZF15absiLbvJZLIXcwTG4OsFkd+c7Ths7j/P/ttjBcnOgykz8ywW8XsSISBXehaO6FwPk37rddUHeEYOvwzKbH1qpgbtS5z/BKONKxqh+8FY5Wf3n80/0SbBQ3JlBnuTuqHQQlKCv2zkzGQv3aeu1WgqmM1+OH3BgSFM/F4o/gINWsOdU0DD9rNobb909mJspY3E1iEdPEElrMeZ/xKc2Zl1sKQtZIyZMRm0gYo/H/hODmBS3bqvTapmeMWpe5SCyw03FTp1O//brPHLdNqglkll9qqgsf4JUnCqefK5qyqqS4kPcDAzSBrYcBZLsKg5DnZbedD/rFNPDrlTaADMo4HkpwtE3U8jznVSDqAL3PfWvGk/bYLxaObXIzPpZybL/ILnnV5iifqSkhqhVwUaCX6nH0uB0mpiwXFbrFRYY6egqKrxtLoMEh5qT3wFdtKTt9a0Nnytvh/00vpv9yiHVEgkXGFkSC4Y3n3rSImWONKO+mYvlPH5kKM9vT9nIKBRBC7rmM3NRCKYCtPyOZlmTb6spADscUC6kux51Abd7GT/XWCmETB6cMNN2IQUVuJvcXX8IJay/mYYdgwY1DtVAWSkJlnJGAuvNQL4/v5v08u8GrnCO89aZwbA56zEulOBVr5iINm0BmqCAg9OHJGjlq4eK0/5bT,iv:ra1EmIfT7Pwz5GVidrlTDN/Ox4ErsAvQCe7hoQoTXRg=,tag:T7nCiJ+8djxFbTJfB9Hhxw==,type:str]
|
||||
asterisk-voicemail: ENC[AES256_GCM,data:uyXeBP+9WkfVot4Ot3vwv3OEZfoVDK2I+lvaPpGJTZp16YNtP+uxNiW2ynewQlORCTY59bP1jW3bQdT/ASGsErOrhInYSytTyfdZ51BF9+jz0TH6oWxsSuuawTrkC8jvJOpejt6XuGoYbbqlM/VL1xzgDkq3ztTxaHTfdTonQij2Q4cYddMRHWIEuBCK7FU2TlHAJeIFZvtE0MiyNNT3rEWSs1xcljTGfMjkoMd+FI1uZSQT4r0kAaPPkvCWcAGH6R+F0Ue++i9TuLhu+sDV+X6u3N/garDW74H0bOcLJysImtuPXh1aXuBkHQuC1Liss/IF4NDjtDDhpfc0eePR5MWv/Kj0q+VFJiUPY6XnWh6fG9I2yY22+I7eAAg/xWVZBXPWbFHRz8jm1owp4ln6/hcrJOw6Fzw8tZ6Jd9nciOeOmR1KtjEzklPP5kP1YQPtGio/LnOaAAhTHy16MbWf/Ey4S30+eHB+joD8OM93+YxxrdKNE6XXEcAhkdpHYecrvz4Co1fhY7ZoOnNvA8Juup/7PMyNEU/Fy4Pta34aT/j1s7de2vTpRNBeecWvgFA9Qd7Re/2XPqOAkpduxDniwsUdb52oL39MBoOCY8brmXn2J/mMDeOmoqvjRHsPZsajPTAqF/nqRB8VpwoZAKAx59DYBGgmHz7/7JRX9NXOAus1yLbMfVqDftk6+KTFQ9wCqei3jaI/K5AJrSEwlZG0BLoDefIGXT5f8bNNgSn865j2RP+FLa6W3/u5t+k=,iv:/phktIxMdDO5Nrum7hf3oLDmQO04lrkvFuHNw77aRks=,tag:7OUg0BG9X7nBHWiQNaSOEQ==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
|
|
@ -18,8 +19,8 @@ sops:
|
|||
MU41eU8zeTRRUlZyUXV0U1N6U0NRNnMKZK3vfyRRr7Iu6HfpdpmDTKzUbEnCnW9l
|
||||
rGjFmY9VX2q9w3j/4E5uUToQfeGMqqBTOFUB3hNgU8K5ZT7wMbOXAg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2022-12-06T22:00:11Z"
|
||||
mac: ENC[AES256_GCM,data:rg0vVhW4rXOJb72LDCLNTQtCHQu165knPZuGT56zoGGWHPDDTWnqt/WaBHyUoIBXWe286jW+aV0hFZMRCrS8cu+XSTztmXDIuNaYU7s8XW8ZzISUTCHDVUiYRSjaZXvCprr0cpiQoJ9dAl+Rm5m50elCdC8E7VaNGEYTIYWYLtk=,iv:7R8xt3WJKdcMrUdL/byMIbS9cv0dxlxou26Q3liIxSQ=,tag:IENmJHOSX9nLhrnSVHZltg==,type:str]
|
||||
lastmodified: "2023-11-06T23:32:51Z"
|
||||
mac: ENC[AES256_GCM,data:7lW6i4ULus4348NwnV/ovcWebspBcEBzYqLtl+8xFOfe3erIFnC3iRo0ibZJ8yishZpIUxoVu08yxQoa1qEriC57WETMaR+iGUPaY75tHraBJGY26Etk7Hy2QhQ7D+srBY+CogHhHAD8HUwT4/ZiPqKe1eQAvNg/6HWnjbQkG/Q=,iv:r43odkYgQsyK5uJJ5V98kTx7enP7TRuFoTnYfHmD/8o=,tag:hR+1zCniHs1l3qSkhQhtFw==,type:str]
|
||||
pgp:
|
||||
- created_at: "2022-11-02T22:14:19Z"
|
||||
enc: |-
|
||||
|
|
|
|||
9
hosts/aluminium/services/asterisk/README.md
Normal file
9
hosts/aluminium/services/asterisk/README.md
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
## custom voicemail greetings
|
||||
|
||||
Place `busy` and/or `unavail` file in users voicemail directory.
|
||||
|
||||
The file can be converted to the fitting format using sox
|
||||
```bash
|
||||
sox $input_file -t wav -b 16 -c 1 -r 8k -e signed-integer --endian little unavail.wav
|
||||
```
|
||||
|
||||
|
|
@ -1,25 +1,51 @@
|
|||
{ config, lib, ... }:
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../../ports.nix args;
|
||||
secretConfigFiles = [
|
||||
"ari"
|
||||
"pjsip"
|
||||
"voicemail"
|
||||
];
|
||||
rtp = {
|
||||
start = 10000;
|
||||
end = 10200;
|
||||
start = builtins.elemAt ports.asterisk-rtp.udp.range 0;
|
||||
end = builtins.elemAt ports.asterisk-rtp.udp.range 1;
|
||||
};
|
||||
in
|
||||
{
|
||||
voicemail-sounds = pkgs.callPackage ./voicemail-sounds { };
|
||||
in {
|
||||
systemd.services.asterisk-voicemail-sounds = {
|
||||
wantedBy = ["asterisk.service"];
|
||||
after = ["asterisk.service"];
|
||||
script = ''
|
||||
ln -sfn \
|
||||
${voicemail-sounds}/unavail.wav \
|
||||
/var/spool/asterisk/voicemail/lechner/876/unavail.wav
|
||||
'';
|
||||
restartTriggers = [voicemail-sounds];
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
RemainAfterExit = true;
|
||||
};
|
||||
};
|
||||
|
||||
services.asterisk = {
|
||||
enable = true;
|
||||
confFiles = {
|
||||
"extensions.conf" = ''
|
||||
[doorbell]
|
||||
exten = s,1,Set(__DYNAMIC_FEATURES=doorOpen)
|
||||
same = n,Dial(PJSIP/10&PJSIP/11,${toString config.services.myintercom-doorbell.dialTime})
|
||||
same = n,Hangup()
|
||||
|
||||
[door-open]
|
||||
exten = s,1,Verbose(0, "opening the door")
|
||||
same = n,System("${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-open-door")
|
||||
same = n,Hangup()
|
||||
|
||||
[sipgate-in]
|
||||
exten = _499846876,1,Noop(Processing an incoming call)
|
||||
;same = n,Dial(PJSIP/10)
|
||||
same = n,Dial(PJSIP/10&PJSIP/11,45,tT)
|
||||
;same = n,VoiceMail(876@lechner,u)
|
||||
same = n,Dial(PJSIP/10&PJSIP/11,25,tT)
|
||||
same = n,VoiceMail(876@lechner,uS)
|
||||
same = n,Hangup()
|
||||
|
||||
exten => _4998469779781,1,Verbose(3,Incoming fax)
|
||||
|
|
@ -41,9 +67,10 @@ in
|
|||
same = n,Hangup()
|
||||
|
||||
exten = _499846977891,1,Noop(Processing an incoming call)
|
||||
same = n,Dial(PJSIP/13&PJSIP/16,30,tT)
|
||||
same = n,VoiceMail(977891@jakob,u)
|
||||
same = n,Hangup()
|
||||
same = n,VoiceMail(876@lechner,uS)
|
||||
;same = n,Dial(PJSIP/13&PJSIP/16,30,tT)
|
||||
;same = n,VoiceMail(977891@jakob,u)
|
||||
;same = n,Hangup()
|
||||
|
||||
[dect]
|
||||
exten = 100,1,Answer()
|
||||
|
|
@ -79,10 +106,10 @@ in
|
|||
same = n,Hangup()
|
||||
|
||||
[voicemail-callback]
|
||||
exten = s,1,HasNewVoicemail(977892@pauline)
|
||||
exten = s,1,HasNewVoicemail(876@lechner)
|
||||
exten = s,2,Hangup
|
||||
exten = s,102,Dial(PJSIP/12,15)
|
||||
exten = s,n,VoiceMailMain(977892@pauline)
|
||||
exten = s,102,Dial(PJSIP/10&PJSIP/11,15)
|
||||
exten = s,n,VoiceMailMain(876@lechner)
|
||||
exten = s,n,Hangup
|
||||
|
||||
|
||||
|
|
@ -110,6 +137,10 @@ in
|
|||
; Send the fax
|
||||
exten => send,n,SendFAX(/home/jalr/fax.tif,d)
|
||||
'';
|
||||
"features.conf" = ''
|
||||
[applicationmap]
|
||||
doorOpen => #9,peer,Gosub,"door-open,s,1"
|
||||
'';
|
||||
"http.conf" = ''
|
||||
[general]
|
||||
enabled=yes
|
||||
|
|
@ -140,7 +171,7 @@ in
|
|||
|
||||
sops.secrets = (lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "asterisk-${name}" {
|
||||
sopsFile = ../secrets.yaml;
|
||||
sopsFile = ../../secrets.yaml;
|
||||
owner = config.users.users.asterisk.name;
|
||||
})
|
||||
secretConfigFiles));
|
||||
|
|
@ -158,4 +189,85 @@ in
|
|||
}
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services."asterisk-reload-endpoint@" = {
|
||||
description = "Check if asterisk endpoint is identified and reload it when it is not.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
environment = {
|
||||
ENDPOINT = "%I";
|
||||
};
|
||||
script = ''
|
||||
export PATH=${pkgs.lib.makeBinPath [pkgs.asterisk pkgs.gnused pkgs.gnugrep]}
|
||||
if ! asterisk -r -x "pjsip show endpoint $ENDPOINT" | sed -n '/^===/,/^\s*ParameterName/{//!p}' | grep -q 'Identify:'; then
|
||||
asterisk -r -x "module reload res_pjsip_endpoint_identifier_ip.so"
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.asterisk-reload-endpoint = {
|
||||
description = "Check if asterisk endpoint is identified and reload it when it is not.";
|
||||
after = [ "asterisk.service" ];
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
Persistent = true;
|
||||
OnCalendar = "*-*-* *:*:00";
|
||||
Unit = "asterisk-reload-endpoint@sipgate.service";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services."asterisk-voicemail-call@" = {
|
||||
description = "Check if voicemail exists and place a call to the voicemail application.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
scriptArgs = "%I";
|
||||
script = ''
|
||||
export PATH=${pkgs.lib.makeBinPath [pkgs.asterisk pkgs.coreutils pkgs.findutils]}
|
||||
number="$(echo "$1" | cut -d ':' -f 1)"
|
||||
user="$(echo "$1" | cut -d ':' -f 2)"
|
||||
channel="PJSIP/$(echo "$1" | cut -d ':' -f 3)"
|
||||
|
||||
if ! find "/var/spool/asterisk/voicemail/$user/$number/INBOX/" -mindepth 1 -maxdepth 1 | read; then
|
||||
exit
|
||||
fi
|
||||
|
||||
callfile="$(mktemp -p /tmp XXXXXXXXXX.call)"
|
||||
chmod 644 "$callfile"
|
||||
|
||||
cat > "$callfile" << EOF
|
||||
Channel: $channel
|
||||
WaitTime: 15
|
||||
Application: VoiceMailMain
|
||||
Data: $number@$user
|
||||
CallerID: Voicemail
|
||||
EOF
|
||||
|
||||
mv "$callfile" /var/spool/asterisk/outgoing/
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers.asterisk-voicemail-call-10 = {
|
||||
description = "Check if voicemail exists and place a call to the voicemail application.";
|
||||
after = [ "asterisk.service" ];
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
Persistent = true;
|
||||
OnCalendar = "*-*-* 07..22:00,20,40:00";
|
||||
Unit = "asterisk-voicemail-call@876:lechner:10.service";
|
||||
};
|
||||
};
|
||||
systemd.timers.asterisk-voicemail-call-11 = {
|
||||
description = "Check if voicemail exists and place a call to the voicemail application.";
|
||||
after = [ "asterisk.service" ];
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
Persistent = true;
|
||||
OnCalendar = "*-*-* 07..22:00,10,30:50";
|
||||
Unit = "asterisk-voicemail-call@876:lechner:11.service";
|
||||
};
|
||||
};
|
||||
|
||||
#voicemailCallScript
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
{ lib, stdenvNoCC }:
|
||||
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = "voicemail-sounds";
|
||||
|
||||
src = ./.;
|
||||
|
||||
dontBuild = true;
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp -r * $out
|
||||
'';
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:b9d91a693e1343a1dfdbb1e4adc89a5f58182d5c1427254f0976fa09120c9091
|
||||
size 149444
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
imports = [
|
||||
./asterisk.nix
|
||||
./asterisk
|
||||
./dnsmasq.nix
|
||||
./doorbell.nix
|
||||
./dyndns.nix
|
||||
./unifi-controller.nix
|
||||
];
|
||||
|
|
|
|||
23
hosts/aluminium/services/doorbell.nix
Normal file
23
hosts/aluminium/services/doorbell.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
sops.secrets.myintercom-doorbell-password = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = "asterisk";
|
||||
};
|
||||
services.myintercom-doorbell = {
|
||||
enable = true;
|
||||
host = "192.168.0.74";
|
||||
username = "btxpvt0002";
|
||||
passwordFile = config.sops.secrets.myintercom-doorbell-password.path;
|
||||
audiosocket = {
|
||||
address = "127.0.0.1";
|
||||
port = ports.doorbell-audiosocket.tcp;
|
||||
uuid = "4960ab41-dbef-4773-a25e-90536d97345e";
|
||||
};
|
||||
callerId = "Sprechanlage";
|
||||
};
|
||||
}
|
||||
|
|
@ -1,9 +1,13 @@
|
|||
{ pkgs, ... }:
|
||||
args@{ pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
services.unifi = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
unifiPackage = pkgs.unifi;
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 8443 ];
|
||||
networking.firewall.allowedTCPPorts = [ ports.unifi.tcp ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
imports = [
|
||||
./hardware-configuration.nix
|
||||
../../home-manager/users/jalr.nix
|
||||
./services
|
||||
];
|
||||
|
||||
networking = {
|
||||
|
|
@ -37,10 +38,6 @@
|
|||
|
||||
programs.mtr.enable = true;
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
services.blueman.enable = true;
|
||||
services.ofono.enable = true;
|
||||
|
||||
services.udisks2.enable = true;
|
||||
|
||||
# udevadm info --name /dev/foo --query all
|
||||
|
|
@ -52,6 +49,7 @@
|
|||
|
||||
jalr = {
|
||||
bootloader = "systemd-boot";
|
||||
bluetooth.enable = true;
|
||||
uefi.enable = true;
|
||||
gui.enable = true;
|
||||
workstation.enable = true;
|
||||
|
|
|
|||
|
|
@ -42,11 +42,13 @@
|
|||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/D384-54D8";
|
||||
fsType = "vfat";
|
||||
options = [ "nodev" "nosuid" "noexec" ];
|
||||
};
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/f14ae966-ac3f-467f-9263-ba9136967782";
|
||||
fsType = "ext4";
|
||||
noCheck = true;
|
||||
options = [ "nodev" "nosuid" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
119
hosts/cadmium/services/asterisk.nix
Normal file
119
hosts/cadmium/services/asterisk.nix
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
rtp = {
|
||||
start = 10000;
|
||||
end = 10200;
|
||||
};
|
||||
in
|
||||
{
|
||||
services.asterisk = {
|
||||
enable = true;
|
||||
confFiles = {
|
||||
"features.conf" = ''
|
||||
[applicationmap]
|
||||
doorOpen => #9,peer,Gosub,"door-open,s,1"
|
||||
'';
|
||||
"extensions.conf" = ''
|
||||
[door-open]
|
||||
exten => s,1,Verbose("Here we are in a subroutine!")
|
||||
same = n,System("/tmp/door-open.sh")
|
||||
same = n,Hangup()
|
||||
|
||||
[doorbell]
|
||||
exten = s,1,Set(CHANNEL(hangup_handler_push)=hdlr1,s,1(args));
|
||||
same = n,Set(__DYNAMIC_FEATURES=doorOpen)
|
||||
same = n,Dial(PJSIP/1000,60)
|
||||
same = n,Hangup()
|
||||
|
||||
[hdlr1]
|
||||
exten = s,1,Verbose(0, Executed First)
|
||||
same = n,Playback(hello-world)
|
||||
same => n,Set(HANGUPCAUSE_STRING=''${HANGUPCAUSE_KEYS()})
|
||||
same = n,Verbose(0, Channels with hangup cause information: ''${HANGUPCAUSE_STRING})
|
||||
same = n,Set(ARRAY(item)=''${HANGUPCAUSE_STRING})
|
||||
same = n,Set(HANGUPCAUSE_STRING=''${HANGUPCAUSE_STRING:''${LEN(''${item})}})
|
||||
same = n,Verbose(0, Got Channel ID ''${item} with Technology Cause Code ''${HANGUPCAUSE(''${item},tech)}, Asterisk Cause Code ''${HANGUPCAUSE(''${item},ast)})
|
||||
same = n,Return()
|
||||
|
||||
[test]
|
||||
exten = 10,1,Answer()
|
||||
same = n,Wait(1)
|
||||
same = n,Playback(hello-world)
|
||||
same = n,Hangup()
|
||||
|
||||
exten = 11,1,Answer()
|
||||
same = n,AudioSocket(c81c42bb-d640-49b1-936b-989607d1985f,127.0.0.1:9092)
|
||||
same = n,Hangup()
|
||||
|
||||
exten = 12,1,Answer()
|
||||
;same = n,Festival(‘Please record your message’)
|
||||
same = n,Record(mymessage:gsm)
|
||||
;same = n,Festival(‘You said’)
|
||||
same = n,Playback(mymessage)
|
||||
;same = n,Festival(‘Press 1 to continue or 2 to change your message’)
|
||||
same = n,Read(KEEPORTOSS||1)
|
||||
|
||||
'';
|
||||
"http.conf" = ''
|
||||
[general]
|
||||
enabled=yes
|
||||
bindaddr=127.0.0.1
|
||||
|
||||
; Port to bind to for HTTP sessions (default is 8088)
|
||||
;bindport=8088
|
||||
|
||||
tlsdisablev1=yes
|
||||
tlsdisablev11=yes
|
||||
tlsdisablev12=yes
|
||||
|
||||
tlsservercipherorder=yes
|
||||
'';
|
||||
"rtp.conf" = ''
|
||||
[general]
|
||||
rtpstart=${toString rtp.start}
|
||||
rtpend=${toString rtp.end}
|
||||
'';
|
||||
"dnsmgr.conf" = ''
|
||||
[general]
|
||||
enable=yes
|
||||
refreshinterval=300
|
||||
'';
|
||||
"pjsip.conf" = ''
|
||||
[simpletrans]
|
||||
type=transport
|
||||
protocol=udp
|
||||
bind=127.0.0.1:5070
|
||||
|
||||
[1000]
|
||||
type=endpoint
|
||||
context=test
|
||||
disallow=all
|
||||
allow=alaw
|
||||
auth=1000
|
||||
aors=1000
|
||||
direct_media=no
|
||||
language=de
|
||||
|
||||
[1000]
|
||||
type=auth
|
||||
auth_type=userpass
|
||||
password=1000
|
||||
username=1000
|
||||
|
||||
[1000]
|
||||
type=aor
|
||||
max_contacts=1
|
||||
'';
|
||||
};
|
||||
useTheseDefaultConfFiles = [ ];
|
||||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedUDPPortRanges = [
|
||||
{
|
||||
from = rtp.start;
|
||||
to = rtp.end;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
5
hosts/cadmium/services/default.nix
Normal file
5
hosts/cadmium/services/default.nix
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
imports = [
|
||||
./asterisk.nix
|
||||
];
|
||||
}
|
||||
|
|
@ -1,5 +1,11 @@
|
|||
{ lib, config, pkgs, self, system, ... }:
|
||||
|
||||
let
|
||||
tradebyteDnsServers = [
|
||||
"10.170.254.30"
|
||||
"10.170.254.40"
|
||||
];
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
./hardware-configuration.nix
|
||||
|
|
@ -42,14 +48,12 @@
|
|||
|
||||
programs.mtr.enable = true;
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
services.blueman.enable = true;
|
||||
services.ofono.enable = true;
|
||||
|
||||
services.udisks2.enable = true;
|
||||
|
||||
jalr = {
|
||||
bootloader = "systemd-boot";
|
||||
bluetooth.enable = true;
|
||||
uefi.enable = true;
|
||||
gui.enable = true;
|
||||
workstation.enable = true;
|
||||
|
|
@ -108,20 +112,20 @@
|
|||
};
|
||||
};
|
||||
|
||||
services.dnsmasq.settings.server = [
|
||||
"/vpce-0de71527ea27288f3-9op2d61c-eu-central-1b.s3.eu-central-1.vpce.amazonaws.com/10.170.254.30"
|
||||
"/vpce-0de71527ea27288f3-9op2d61c.s3.eu-central-1.vpce.amazonaws.com/10.170.254.30"
|
||||
"/ccs.tradebyte.com/10.170.254.30"
|
||||
"/corp.ad.zalando.net/10.160.19.100"
|
||||
"/develop.sys.tradebyte.com/10.0.3.1"
|
||||
"/instance.tradebyte.com/10.170.254.30"
|
||||
services.dnsmasq.settings.server = lib.lists.flatten (
|
||||
map (domain: (map (srv: "/${domain}/${srv}") tradebyteDnsServers)) [
|
||||
"vpce-0c1c169d1e33a1c2f-yugtdam1.s3.eu-central-1.vpce.amazonaws.com"
|
||||
"ccs.tradebyte.com"
|
||||
"instance.tradebyte.com"
|
||||
]) ++ [
|
||||
"/internal.production.core.tradebyte.com/10.158.224.2"
|
||||
"/internal.development.core.tradebyte.com/10.170.254.30"
|
||||
"/rds.amazonaws.com/9.9.9.9"
|
||||
"/tradebyte.com/9.9.9.9"
|
||||
"/tradebyte.org/9.9.9.9"
|
||||
"/develop.sys.tradebyte.com/10.0.3.1"
|
||||
"/corp.ad.zalando.net/10.160.19.100"
|
||||
];
|
||||
|
||||
services.actkbd = {
|
||||
enable = true;
|
||||
bindings = [
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/564E-26B4";
|
||||
fsType = "vfat";
|
||||
options = [ "nodev" "nosuid" "noexec" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -152,7 +152,8 @@ with lib; {
|
|||
];
|
||||
};
|
||||
|
||||
fileSystems = mkMerge (mapAttrsToList
|
||||
fileSystems = mkMerge
|
||||
(mapAttrsToList
|
||||
(dataset: mountpoint: {
|
||||
"${mountpoint}" = {
|
||||
device = "${dataset}";
|
||||
|
|
@ -176,8 +177,22 @@ with lib; {
|
|||
];
|
||||
};
|
||||
})
|
||||
efiSystemPartitions);
|
||||
efiSystemPartitions) // {
|
||||
"/proc" = {
|
||||
device = "/proc";
|
||||
options = [ "nosuid" "noexec" "nodev" "hidepid=2" ];
|
||||
};
|
||||
};
|
||||
|
||||
hardware.enableRedistributableFirmware = true;
|
||||
|
||||
virtualisation.containers.storage.settings = {
|
||||
storage = {
|
||||
driver = "zfs";
|
||||
graphroot = "/var/lib/containers/storage";
|
||||
runroot = "/run/containers/storage";
|
||||
options.zfs.fsname = "rpool/nixos/podman";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
16
hosts/iron/ports.nix
Normal file
16
hosts/iron/ports.nix
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
{ lib, custom-utils, ... }:
|
||||
|
||||
custom-utils.validatePortAttrset {
|
||||
jellyfin.tcp = 8096;
|
||||
matrix-synapse.tcp = 8008;
|
||||
navidrome.tcp = 4533;
|
||||
nginx-http.tcp = 80;
|
||||
nginx-https.tcp = 443;
|
||||
postfix-relay.tcp = 25;
|
||||
postfix-submission.tcp = [ 465 587 ];
|
||||
qbittorrent-torrent.tcp = 59832;
|
||||
qbittorrent-webui.tcp = 8099;
|
||||
radicale.tcp = 5232;
|
||||
unifi.tcp = 8443;
|
||||
wireguard-public-ip-tunnel.udp = 51000;
|
||||
}
|
||||
|
|
@ -1,4 +1,7 @@
|
|||
{ lib, pkgs, ... }:
|
||||
args@{ lib, pkgs, custom-utils, ... }:
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
|
|
@ -57,7 +60,7 @@
|
|||
# add_header X-XSS-Protection "1; mode=block";
|
||||
# add_header X-Content-Type-Options "nosniff";
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8096;
|
||||
proxy_pass http://127.0.0.1:${toString ports.jellyfin.tcp};
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
|
@ -67,7 +70,7 @@
|
|||
proxy_buffering off;
|
||||
}
|
||||
location = /web/ {
|
||||
proxy_pass http://127.0.0.1:8096/web/index.html;
|
||||
proxy_pass http://127.0.0.1:${toString ports.jellyfin.tcp}/web/index.html;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
|
@ -76,7 +79,7 @@
|
|||
proxy_set_header X-Forwarded-Host $http_host;
|
||||
}
|
||||
location /socket {
|
||||
proxy_pass http://127.0.0.1:8096;
|
||||
proxy_pass http://127.0.0.1:${toString ports.jellyfin.tcp};
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
{ config, pkgs, ... }:
|
||||
args@{ config, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
sops.secrets.hetzner-api-key = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
|
|
@ -12,6 +16,7 @@
|
|||
mailserver = {
|
||||
enable = true;
|
||||
fqdn = "hha.jalr.de";
|
||||
relayPort = ports.postfix-relay.tcp;
|
||||
domains = [
|
||||
{
|
||||
domain = "jalr.de";
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.matrix-synapse.settings;
|
||||
fqdn = "matrix.jalr.de";
|
||||
domain = "jalr.de";
|
||||
turnHost = "turn.jalr.de";
|
||||
ports = import ../../ports.nix args;
|
||||
in
|
||||
{
|
||||
sops.secrets = {
|
||||
|
|
@ -23,7 +25,7 @@ in
|
|||
database.name = "sqlite3";
|
||||
|
||||
listeners = lib.singleton {
|
||||
port = 8008;
|
||||
port = ports.matrix-synapse.tcp;
|
||||
bind_addresses = [ "127.0.0.1" "::1" ];
|
||||
type = "http";
|
||||
tls = false;
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
{ config, lib, pkgs, utils, ... }:
|
||||
args@{ config, lib, pkgs, utils, custom-utils, ... }:
|
||||
|
||||
let
|
||||
port = 4533;
|
||||
ports = import ../ports.nix args;
|
||||
settings = {
|
||||
# https://www.navidrome.org/docs/usage/configuration-options/#available-options
|
||||
Address = "127.0.0.1";
|
||||
Port = port;
|
||||
Port = ports.navidrome.tcp;
|
||||
DevActivityPanel = false;
|
||||
};
|
||||
passwordEncryptionKeyFile = config.sops.secrets.navidrome-password-encryption-key.path;
|
||||
|
|
@ -38,7 +39,7 @@ in
|
|||
extraConfig = ''
|
||||
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:${toString port};
|
||||
proxy_pass http://127.0.0.1:${toString ports.navidrome.tcp};
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,13 @@
|
|||
{ pkgs, ... }:
|
||||
args@{ pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
defaultHTTPListenPort = ports.nginx-http.tcp;
|
||||
defaultSSLListenPort = ports.nginx-https.tcp;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
listenPort = 51000;
|
||||
ports = import ../ports.nix args;
|
||||
listenPort = ports.wireguard-public-ip-tunnel.udp;
|
||||
remoteHost = "magnesium.jalr.de";
|
||||
remotePort = 51000;
|
||||
publicKey = "ABZCQfzlHJ1/iNbWFf6jVvdqSmqjxm3w5bpa0SYclBU=";
|
||||
|
|
|
|||
|
|
@ -1,4 +1,8 @@
|
|||
{ config, ... }:
|
||||
args@{ config, lib, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
sops.secrets.radicale-htpasswd = {
|
||||
owner = "nginx";
|
||||
|
|
@ -11,7 +15,7 @@
|
|||
forceSSL = true;
|
||||
basicAuthFile = config.sops.secrets.radicale-htpasswd.path;
|
||||
locations."/radicale/" = {
|
||||
proxyPass = "http://localhost:5232/";
|
||||
proxyPass = "http://127.0.0.1:${toString ports.radicale.tcp}/";
|
||||
recommendedProxySettings = true;
|
||||
#basicAuthFile = "";
|
||||
extraConfig = ''
|
||||
|
|
@ -28,7 +32,7 @@
|
|||
enable = true;
|
||||
settings = {
|
||||
server = {
|
||||
hosts = "127.0.0.1:5232,[::1]:5232";
|
||||
hosts = "127.0.0.1:${toString ports.radicale.tcp},[::1]:${toString ports.radicale.tcp}";
|
||||
ssl = false;
|
||||
};
|
||||
encoding = {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
args@{ config, lib, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
jalr.qbittorrent = {
|
||||
enable = true;
|
||||
downloadDir = "/sturzbach";
|
||||
fqdn = "sturzbach.jalr.de";
|
||||
webuiPort = ports.qbittorrent-webui.tcp;
|
||||
};
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = [ 59832 ];
|
||||
allowedTCPPorts = [ ports.qbittorrent-torrent.tcp ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,13 @@
|
|||
{ pkgs, ... }:
|
||||
args@{ pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
services.unifi = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
unifiPackage = pkgs.unifi;
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 8443 ];
|
||||
networking.firewall.allowedTCPPorts = [ ports.unifi.tcp ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,8 @@
|
|||
programs.mtr.enable = true;
|
||||
programs.wireshark.enable = true;
|
||||
|
||||
hardware.bluetooth.enable = true;
|
||||
|
||||
hardware.sane.enable = true;
|
||||
|
||||
services.blueman.enable = true;
|
||||
|
||||
services.udisks2.enable = true;
|
||||
|
||||
services.avahi.enable = true;
|
||||
|
|
@ -46,6 +42,7 @@
|
|||
|
||||
jalr = {
|
||||
bootloader = "grub2";
|
||||
bluetooth.enable = true;
|
||||
gui.enable = true;
|
||||
workstation.enable = true;
|
||||
sdr.enable = true;
|
||||
|
|
@ -54,32 +51,6 @@
|
|||
autologin.username = "jalr";
|
||||
};
|
||||
|
||||
networking.wg-quick.interfaces.wgkalle = {
|
||||
address = [
|
||||
"172.16.254.5/24"
|
||||
"fd00::604:0:0:ac10:fe05/96"
|
||||
];
|
||||
privateKeyFile = "/root/wireguard-keys/wgkalle";
|
||||
listenPort = 51820;
|
||||
mtu = 1296;
|
||||
|
||||
peers = [
|
||||
{
|
||||
publicKey = "52kAcBdnrFeSuVupHs0u4diUf6tpF8Esy4vzJAlT5Tc=";
|
||||
endpoint = "78.47.224.233:1194";
|
||||
#endpoint = "[2a01:4f8:190:6068::2]:1194";
|
||||
persistentKeepalive = 60;
|
||||
allowedIPs = [
|
||||
"0.0.0.0/0"
|
||||
"::/0"
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
networking.firewall.allowedUDPPorts = [
|
||||
51820 # wireguard
|
||||
];
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It‘s perfectly fine and recommended to leave
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/c4df83d7-8985-47df-b5cd-bf18bd490a50";
|
||||
fsType = "ext2";
|
||||
options = [ "nodev" "nosuid" "noexec" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/45dcac99-1f65-48ab-b5bf-8a1507f0b75a";
|
||||
fsType = "btrfs";
|
||||
options = [
|
||||
|
|
@ -20,32 +20,35 @@
|
|||
"compress=zstd"
|
||||
];
|
||||
};
|
||||
|
||||
fileSystems."/home" =
|
||||
{
|
||||
"/proc" = {
|
||||
device = "/proc";
|
||||
options = [ "nosuid" "noexec" "nodev" "hidepid=2" ];
|
||||
};
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/45dcac99-1f65-48ab-b5bf-8a1507f0b75a";
|
||||
fsType = "btrfs";
|
||||
options = [
|
||||
"subvol=home"
|
||||
"compress=zstd"
|
||||
"nodev"
|
||||
"nosuid"
|
||||
];
|
||||
};
|
||||
|
||||
fileSystems."/nix" =
|
||||
{
|
||||
"/nix" = {
|
||||
device = "/dev/disk/by-uuid/45dcac99-1f65-48ab-b5bf-8a1507f0b75a";
|
||||
fsType = "btrfs";
|
||||
options = [
|
||||
"subvol=nix"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
"nodev"
|
||||
];
|
||||
};
|
||||
|
||||
fileSystems."/boot" =
|
||||
{
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/7836-0C48";
|
||||
fsType = "vfat";
|
||||
options = [ "nodev" "nosuid" "noexec" ];
|
||||
};
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
|
|
|||
12
hosts/magnesium/ports.nix
Normal file
12
hosts/magnesium/ports.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ lib, custom-utils, ... }:
|
||||
|
||||
custom-utils.validatePortAttrset {
|
||||
coturn-cli.tcp = 5766;
|
||||
coturn-plain = { tcp = [ 3478 3479 ]; udp = [ 3478 3479 ]; };
|
||||
coturn-relay.udp.range = [ 49160 49200 ];
|
||||
coturn-tls = { tcp = [ 5349 5350 ]; udp = [ 5349 5350 ]; };
|
||||
mosquitto.tcp = 1883;
|
||||
nginx-http.tcp = 80;
|
||||
nginx-https.tcp = 443;
|
||||
wireguard-public-ip-tunnel.udp = 51000;
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
wireguard_key_hetzner-ha: ENC[AES256_GCM,data:HEW+EalHg6/mq7pRKZkasGz0nqbkSppkf0H/uV5QMJnWwKw9a9W21Y77OSw=,iv:OA6yml1T5kVafX0RYd0Es7DHcGjJazUxP2M6a5Pwkag=,tag:lX5UPIseIQ136HLrHbzZyw==,type:str]
|
||||
turn-static-auth-secret: ENC[AES256_GCM,data:rzhixUemFPwKj1BcVPZd7KtUO9OA6A2R4qEQ1BZGVG0=,iv:uYHYe4Cywxovt3b/Ho1tQVHrpgVic+AKh9AjYMYSZcM=,tag:rr8RW/if06t38GpZCYQB4w==,type:str]
|
||||
gitlab-runner_fablab-nea-hcloud-labsync: ENC[AES256_GCM,data:+znVO8cQxjDdhch7oUALZvt84iJmWnAx6lTM0+WGkGtaRWTCTPjgnst5waSJpw/Oysrd1PkXZKmLHyHuU7K/CHQij7sWH50G3ZcUum58klJc3dCPztlrLpDVHeSwyYiLpsqkQTfjqLPfrMkxuxBgTEVXlq2ZnFuyOGbFx9hubPxLeyQKakiW3qZWGjbFXYAps7Gl61AVdKJj3y1otX2JbCjG9x2i6FHZpl5ywwQCjKNM,iv:7v+I/oJtWDap6PNIJ4Qm3Si9dGs7a79SaMhnr/tbe1A=,tag:7jgoLtdWAEKMkWoXZ10owA==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
gcp_kms: []
|
||||
|
|
@ -15,8 +16,8 @@ sops:
|
|||
Vlk3Y1luTTg3bkpqNTNPUGlNYmNtMW8K9dEUwAuzvDZZoVi8FPZQ7/h75EV0L+VM
|
||||
MlTGfEt38Hi7EOw+yfXvXYHse/OKypwcrPiJDT6IT/E+O9BJCjPKCA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-07-10T19:12:04Z"
|
||||
mac: ENC[AES256_GCM,data:cDwrW1odloAedY7tdKLPg52UTehlTrs3+lAH0ksaGGDXzQCsVNlfzR86SRGQY2s98cu7+9j5azhWSU9slDZcTIk4VWL2i8ZtVpD8KFtut0WiwWaGf2/KLe80GGw3lr4Rm491YDvv7JcUsEuCG3lAQFZzAlZcfl0faFpzYvpTk30=,iv:yeyRjURArUaG0HzcVP0Wm9n0oVHb+u4zNdaQbrC+EaM=,tag:9uFNd3CSSFjToeawBtMNHg==,type:str]
|
||||
lastmodified: "2023-10-13T18:27:53Z"
|
||||
mac: ENC[AES256_GCM,data:8DPq0aGtoiMOdFyD+0NKGZ9OrDi1VXXS/6y3tH4DwlkLDpDqb2QsxunTDwoHlILQBu300nB2lUeGuGlp4/0FimFdiddlu2Ljq8vLh3wt+sz660RgfeaIcgWLSHtulyNIIQJ91wzzgbRADafFRCavVFvJALnIgeE+QDQa4ybLus0=,iv:T3xwELbHbqDszIkGs8BeJn9WV0LjagF1T+HLxCR/Aeo=,tag:NAIBPTRcnRtkGKhpWpe5Pw==,type:str]
|
||||
pgp:
|
||||
- created_at: "2023-06-22T12:44:23Z"
|
||||
enc: |
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let
|
||||
cfg = config.services.coturn;
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
cfg = config.services.coturn;
|
||||
fqdn = "turn.jalr.de";
|
||||
in
|
||||
{
|
||||
|
|
@ -10,7 +11,21 @@ in
|
|||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
|
||||
services.coturn = {
|
||||
services.coturn = (
|
||||
if ports.coturn-plain.tcp != ports.coturn-plain.udp then builtins.abort "coturn: plain TCP and UDP ports must match."
|
||||
else if ports.coturn-tls.tcp != ports.coturn-tls.udp then builtins.abort "coturn: TLS TCP and UDP ports must match."
|
||||
else if lib.lists.length ports.coturn-plain.tcp != 2 then builtins.abort "coturn: exactly two plain ports must be given."
|
||||
else if lib.lists.length ports.coturn-tls.tcp != 2 then builtins.abort "coturn: exactly two TLS ports must be given."
|
||||
else {
|
||||
listening-port = builtins.elemAt ports.coturn-plain.tcp 0;
|
||||
alt-listening-port = builtins.elemAt ports.coturn-plain.tcp 1;
|
||||
tls-listening-port = builtins.elemAt ports.coturn-tls.tcp 0;
|
||||
alt-tls-listening-port = builtins.elemAt ports.coturn-tls.tcp 1;
|
||||
cli-port = ports.coturn-cli.tcp;
|
||||
min-port = builtins.elemAt ports.coturn-relay.udp.range 0;
|
||||
max-port = builtins.elemAt ports.coturn-relay.udp.range 1;
|
||||
}
|
||||
) // {
|
||||
enable = true;
|
||||
|
||||
# config adapted from synapse’s turn howto:
|
||||
|
|
@ -25,9 +40,6 @@ in
|
|||
cert = "/run/turnserver/fullchain.pem";
|
||||
pkey = "/run/turnserver/key.pem";
|
||||
|
||||
min-port = 49160;
|
||||
max-port = 49200;
|
||||
|
||||
no-cli = true;
|
||||
|
||||
extraConfig = ''
|
||||
|
|
@ -87,12 +99,12 @@ in
|
|||
};
|
||||
|
||||
networking.firewall = {
|
||||
allowedTCPPorts = with cfg; [ listening-port alt-listening-port tls-listening-port ];
|
||||
allowedUDPPorts = with cfg; [ listening-port alt-listening-port tls-listening-port ];
|
||||
allowedTCPPorts = with cfg; [ listening-port alt-listening-port tls-listening-port alt-tls-listening-port ];
|
||||
allowedUDPPorts = with cfg; [ listening-port alt-listening-port tls-listening-port alt-tls-listening-port ];
|
||||
|
||||
allowedUDPPortRanges = lib.singleton {
|
||||
from = cfg.min-port;
|
||||
to = cfg.max-port;
|
||||
from = builtins.elemAt ports.coturn-relay.udp.range 0;
|
||||
to = builtins.elemAt ports.coturn-relay.udp.range 1;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
imports = [
|
||||
./coturn.nix
|
||||
./gitlab-runner.nix
|
||||
./mosquitto.nix
|
||||
./public-ip-tunnel.nix
|
||||
./webserver.nix
|
||||
|
|
|
|||
43
hosts/magnesium/services/gitlab-runner.nix
Normal file
43
hosts/magnesium/services/gitlab-runner.nix
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
sops.secrets.gitlab-runner_fablab-nea-hcloud-labsync = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
services.gitlab-runner = {
|
||||
enable = true;
|
||||
extraPackages = [
|
||||
#(pkgs.writeShellScriptBin "docker-machine" ''
|
||||
# exec ${pkgs.docker-machine-gitlab}/bin/docker-machine --debug "$@"
|
||||
#'')
|
||||
pkgs.docker-machine-gitlab
|
||||
];
|
||||
#settings.log_level = "debug";
|
||||
services."fablab-nea-hcloud-labsync" = {
|
||||
description = "FabLab NEA Hetzner Cloud - labsync image builder";
|
||||
limit = 5;
|
||||
executor = "docker+machine";
|
||||
registrationConfigFile = config.sops.secrets.gitlab-runner_fablab-nea-hcloud-labsync.path;
|
||||
dockerImage = "quay.io/official-images/alpine:latest";
|
||||
dockerPrivileged = true;
|
||||
tagList = [
|
||||
"labsync-image"
|
||||
];
|
||||
maximumTimeout = 6 * 60 * 60;
|
||||
registrationFlags = [
|
||||
"--docker-tlsverify"
|
||||
"--machine-idle-nodes 0"
|
||||
"--machine-idle-scale-factor 0.0"
|
||||
"--machine-idle-count-min 0"
|
||||
"--machine-idle-time 900"
|
||||
"--machine-max-builds 100"
|
||||
"--machine-machine-driver hetzner"
|
||||
"--machine-machine-name gitlabrunner-%s"
|
||||
] ++ (map (o: "--machine-machine-options=" + o) [
|
||||
"hetzner-image=debian-12"
|
||||
"hetzner-server-type=cx11"
|
||||
"hetzner-server-location=nbg1"
|
||||
]);
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
let port = 1883;
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
services.mosquitto = {
|
||||
|
|
@ -7,12 +9,12 @@ in
|
|||
persistence = true;
|
||||
listeners = [
|
||||
{
|
||||
port = port;
|
||||
port = ports.mosquitto.tcp;
|
||||
settings = {
|
||||
allow_anonymous = true;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ port ];
|
||||
networking.firewall.allowedTCPPorts = [ ports.mosquitto.tcp ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
listenPort = 51000;
|
||||
ports = import ../ports.nix args;
|
||||
listenPort = ports.wireguard-public-ip-tunnel.udp;
|
||||
publicKey = "GCmQs7upvDYFueEfqD2yJkkOZg3K7YaGluWWzdjsyTo=";
|
||||
in
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,17 +1,35 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
domain = "jalr.de";
|
||||
matrixDomain = "matrix.jalr.de";
|
||||
in
|
||||
{
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
networking.firewall.allowedTCPPorts = [ ports.nginx-http.tcp ports.nginx-https.tcp ];
|
||||
services.nginx = {
|
||||
enable = true;
|
||||
defaultHTTPListenPort = ports.nginx-http.tcp;
|
||||
defaultSSLListenPort = ports.nginx-https.tcp;
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
commonHttpConfig = ''
|
||||
map $scheme $hsts_header {
|
||||
https "max-age=31536000";
|
||||
}
|
||||
add_header Strict-Transport-Security $hsts_header;
|
||||
|
||||
add_header Referrer-Policy strict-origin;
|
||||
add_header X-Content-Type-Options nosniff;
|
||||
add_header X-Frame-Options SAMEORIGIN;
|
||||
'';
|
||||
virtualHosts = {
|
||||
"${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
root = pkgs.jalr.contact;
|
||||
locations =
|
||||
let
|
||||
# workaround for nginx dropping parent headers
|
||||
|
|
|
|||
|
|
@ -16,12 +16,18 @@
|
|||
"compress=zstd"
|
||||
];
|
||||
};
|
||||
"/proc" = {
|
||||
device = "/proc";
|
||||
options = [ "nosuid" "noexec" "nodev" "hidepid=2" ];
|
||||
};
|
||||
"/home" = {
|
||||
device = "/dev/disk/by-uuid/766739e7-2c5c-4c28-b6ee-4bf9f91e6b1f";
|
||||
fsType = "btrfs";
|
||||
options = [
|
||||
"subvol=home"
|
||||
"compress=zstd"
|
||||
"nodev"
|
||||
"nosuid"
|
||||
];
|
||||
};
|
||||
"/nix" = {
|
||||
|
|
@ -31,11 +37,13 @@
|
|||
"subvol=nix"
|
||||
"compress=zstd"
|
||||
"noatime"
|
||||
"nodev"
|
||||
];
|
||||
};
|
||||
"/boot" = {
|
||||
device = "/dev/disk/by-uuid/A586-15AC";
|
||||
fsType = "vfat";
|
||||
options = [ "nodev" "nosuid" "noexec" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
8
hosts/weinturm-pretix-prod/ports.nix
Normal file
8
hosts/weinturm-pretix-prod/ports.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{ lib, custom-utils, ... }:
|
||||
|
||||
custom-utils.validatePortAttrset {
|
||||
nginx-http.tcp = 80;
|
||||
nginx-https.tcp = 443;
|
||||
ports.postfix-relay.tcp = 25;
|
||||
ports.postfix-submission.tcp = [ 465 587 ];
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
pretix-cfg: ENC[AES256_GCM,data:AgT82cee/BHR5V2JkNdDkbS82zXntOD6dLuEm4XUgal0Jpz+3ACqrEF72U0nNTd/JUYVD1HJtphKKKLZ0zHBix+xMJ/JP5hnz7O94+xqyjODhl6XpNtKgc2bDsPWpoejeUDAQK4lWDwu7eCl3+L/HCK5oEE7d01HcfudI1XD8Qr6E4PAyrKd71d65h66OtcwgQVojtWbMSditWHEubVQEssrmZGjOzmd/JzlUBEKQ5piJquQ0RTTGynQdKpLw29CakjpxVzT1uLvuvM89I21BDeXW2A6Gn54ay7Ov9aFGbp+wexlZqGpOZ0Pkw==,iv:3CWknBvAAt0Ls45kzAaeXSsiebkWWT2UdJhoyImVoHU=,tag:yy26Txkzf/Yof+Y8R5LcJA==,type:str]
|
||||
pretix-cfg: ENC[AES256_GCM,data:sfgKDr9aNOdwlumoltRuD7u1ksykFdEKtzt3MldjQnG0b4iAEspEhjcxqaNvPpXYm8EZKtsLBBQgdd1ifyQgs3k69c/GfzQ/jZ/yQ2OUkCO7U9A=,iv:FADYpPbGEEM/pD6EI85s9wVMv8yMrGJa+miE25XQ+t8=,tag:WJ9LHCNFHSr9RmmUi6hxnw==,type:str]
|
||||
pretix-banktool-cfg: ENC[AES256_GCM,data:6tcaQwnXsA2jZYQD2BdGu7gVzlCE+cF03icOF7VIVY92+xWMw+aivJRocDQAMBslD04EoEAu74tNIcky23swtgJwbtcwSmouDqofzo/HoXrudNyvjECYd6xUzmq/OvSBSQVY3s3OxCcc0TlpPVUipDxcGaALwJdhtCB11ZrVfOoXrycZ3YLAEESK0rC4tc5E550lhxmkyOan1m9q9rI4KVhv4mIlU6nVQbDA7LcljRPAJESFmwuwx75t6uPYKH9CjaYL3XE/MmZIZ6pN3qiNyqEx8dsxWZh1KQI233TfMr6jcIXwamTFK6/yieE2nQJfyM8r8b3E3D4nJ5+nn5Cb+wxwewEPveEmFUsNXYD84fpk2fK0nvYyOi32++gfefObFVE2ejAE7iu3rIrboA/wJoSfPCDGHVtdLVXC//MjLI3JUAU+QMTwRFz53KhE+lxFsbqaX4IdLuUwMoFSW6qRWGe7/SGUChH1Wrj705MMc4dfn2qaGhDbZNkDJA==,iv:Pl8XpuGcFzLlzEVe+JQ02S2rthKz88QMZXkGEywpCTU=,tag:beSgKDPcErhJhoV59YDIsw==,type:str]
|
||||
sops:
|
||||
kms: []
|
||||
|
|
@ -15,8 +15,8 @@ sops:
|
|||
U3pyTDB4c1FWdHBPVjVjV3VpTjFWamsKDtc9C3xy/3Zu83+jQYCnHk8vatWANt4M
|
||||
+Zo5kZ5yfYVSnvMvgpWoAHk/quXSLNg2YhKUDrYP5y57Q/jZTX3YbA==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
lastmodified: "2023-03-01T13:25:37Z"
|
||||
mac: ENC[AES256_GCM,data:WcF4i8b+YpJuZj/hP8SEEvXJNlrf77ymNF6Avg4vt2JUkIoLh5EAMOjqPWWhJXS65rRSOCQOW/uRLoAMs3b1lX8r93u1wlzxnF5L/1RnAyTcCI2Aiadq6QjOKevgRwfc4vvTVN7LHKwZ9f8kCqgYiuOYtVDx3N4UPQ4SPJ3MZRw=,iv:iliNHU5y+YL2hpvWIltkhP6bkUonMakL7Ssdyf/be38=,tag:4YO93pGujwpHWjX5IAOQfw==,type:str]
|
||||
lastmodified: "2023-09-25T15:21:49Z"
|
||||
mac: ENC[AES256_GCM,data:R3uP3tH4faLEtga0E2Gh4WrLrpV7dYvxWDEJkD5ycUc2vglY3MeswMEhNEhkD7cpYiWKB8TaBeBe/mP3hOmgs3WY1sDURZSqKKFT1FfTTL86e1BAOq7S4rG2lRQyNxxDjeJCqFQbEV3feggqPFnV8x8kBObAd29akAK5jQn1TK8=,iv:4F83RXiyLDlzlDVgMWKAOc7BTGSi4F0so9Ub/uzl+VM=,tag:2Q2BRBRR9yC6Uli5TcZhEg==,type:str]
|
||||
pgp:
|
||||
- created_at: "2023-07-08T09:50:21Z"
|
||||
enc: |
|
||||
|
|
|
|||
|
|
@ -1,9 +1,23 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
args@{ config, lib, pkgs, custom-utils, ... }:
|
||||
|
||||
let
|
||||
ports = import ../ports.nix args;
|
||||
in
|
||||
{
|
||||
nixpkgs.config.permittedInsecurePackages = [
|
||||
"python3.10-requests-2.28.2"
|
||||
"python3.10-cryptography-40.0.1"
|
||||
];
|
||||
|
||||
services.pretix = {
|
||||
enable = true;
|
||||
instanceName = "Weinturm Open Air";
|
||||
domain = "tickets.weinturm-open-air.de";
|
||||
extraDomains = [
|
||||
"tickets.weinturm.jalr.de"
|
||||
"tickets.wasted-openair.de"
|
||||
"oel.wasted-openair.de"
|
||||
];
|
||||
enableTls = true;
|
||||
enableRegistration = false;
|
||||
passwordReset = true;
|
||||
|
|
@ -14,6 +28,28 @@
|
|||
enable = true;
|
||||
days = 14;
|
||||
};
|
||||
mail = {
|
||||
enable = true;
|
||||
from = "no-reply@tickets.weinturm-open-air.de";
|
||||
admins = [
|
||||
"mail@jalr.de"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
jalr.mailserver = {
|
||||
enable = true;
|
||||
fqdn = "tickets.weinturm.jalr.de";
|
||||
relayPort = ports.postfix-relay.tcp;
|
||||
domains = [
|
||||
{
|
||||
domain = "tickets.weinturm-open-air.de";
|
||||
enableDKIM = false;
|
||||
}
|
||||
];
|
||||
messageSizeLimit = 10 * 1024 * 1024;
|
||||
users = [ ];
|
||||
spam.enable = false;
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
|
|
|
|||
17
modules/bluetooth.nix
Normal file
17
modules/bluetooth.nix
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.jalr;
|
||||
in
|
||||
{
|
||||
options.jalr = {
|
||||
bluetooth.enable = pkgs.lib.mkEnableOption "Enable bluetooth" // { default = false; };
|
||||
};
|
||||
config = lib.mkIf cfg.bluetooth.enable {
|
||||
hardware.bluetooth.enable = true;
|
||||
services.blueman.enable = true;
|
||||
services.ofono.enable = true;
|
||||
services.upower.enable = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
../pkgs/modules.nix
|
||||
./autologin.nix
|
||||
./aws.nix
|
||||
./bluetooth.nix
|
||||
./bootloader
|
||||
./dji-goggles.nix
|
||||
./dnsmasq.nix
|
||||
|
|
@ -42,7 +43,17 @@
|
|||
];
|
||||
|
||||
config = {
|
||||
boot.tmp.cleanOnBoot = true;
|
||||
boot = {
|
||||
tmp.cleanOnBoot = true;
|
||||
kernel.sysctl = {
|
||||
"kernel.kptr_restrict" = 1;
|
||||
"kernel.yama.ptrace_scope" = 1;
|
||||
"kernel.kexec_load_disabled" = 1;
|
||||
};
|
||||
kernelParams = [
|
||||
"lockdown=integrity"
|
||||
];
|
||||
};
|
||||
|
||||
security.polkit.enable = true;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,12 @@
|
|||
resolveLocalQueries = true;
|
||||
settings = {
|
||||
server = [
|
||||
"127.0.0.1#9053"
|
||||
"/lechner.zz/192.168.0.1"
|
||||
"/iceportal.de/172.18.0.1"
|
||||
"/lab.fablab-nea.de/192.168.94.1"
|
||||
"/lan.bw.jalr.de/192.168.42.1"
|
||||
"/lechner.zz/192.168.0.1"
|
||||
"/login.wifionice.de/172.18.0.1"
|
||||
"127.0.0.1#9053"
|
||||
];
|
||||
no-resolv = true;
|
||||
interface = "lo";
|
||||
|
|
|
|||
|
|
@ -5,6 +5,11 @@ in
|
|||
{
|
||||
options.jalr.mailserver = with lib; with lib.types; {
|
||||
enable = mkEnableOption "simple mail server";
|
||||
relayPort = mkOption {
|
||||
description = "SMTP port for relay mail relay.";
|
||||
type = port;
|
||||
default = 25;
|
||||
};
|
||||
fqdn = mkOption {
|
||||
type = str;
|
||||
description = ''
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ lib.mkIf cfg.enable {
|
|||
services.postfix = {
|
||||
enable = true;
|
||||
|
||||
relayPort = cfg.relayPort;
|
||||
|
||||
enableSubmission = true; # plain/STARTTLS (latter is forced in submissionOptions)
|
||||
enableSubmissions = true; # submission with implicit TLS (TCP/465)
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@
|
|||
};
|
||||
|
||||
nixpkgs.overlays = with inputs; [
|
||||
self.overlay
|
||||
self.overlays.default
|
||||
(final: prev: {
|
||||
master = import inputs.nixpkgsMaster {
|
||||
inherit system;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,22 @@
|
|||
{ pkgs, inputs, ... }:
|
||||
|
||||
let
|
||||
commandsWithoutPassword = [
|
||||
"/run/current-system/sw/bin/systemctl restart tor.service"
|
||||
];
|
||||
in
|
||||
{
|
||||
security.sudo.execWheelOnly = true;
|
||||
security.sudo = {
|
||||
execWheelOnly = true;
|
||||
extraRules = [
|
||||
{
|
||||
groups = [ "wheel" ];
|
||||
commands = map
|
||||
(cmd: {
|
||||
command = cmd;
|
||||
options = [ "NOPASSWD" ];
|
||||
})
|
||||
commandsWithoutPassword;
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
{ lib, config, ... }:
|
||||
|
||||
{
|
||||
config = lib.mkIf config.jalr.workstation.enable {
|
||||
services.tor = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
|
@ -10,4 +13,5 @@
|
|||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
23
pkgs/asterisk-sounds-de/default.nix
Normal file
23
pkgs/asterisk-sounds-de/default.nix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
{ lib
|
||||
, stdenvNoCC
|
||||
, fetchurl
|
||||
, unzip
|
||||
}:
|
||||
|
||||
stdenvNoCC.mkDerivation rec {
|
||||
src = fetchurl {
|
||||
url = "https://www.asterisksounds.org/sites/asterisksounds.org/files/sounds/de/download/asterisk-sounds-core-de-${version}.zip";
|
||||
sha256 = "y97xVDBHgnD/Z/DxjKcSNjCXXfiVO+PWUFMbyQpaFLY=";
|
||||
};
|
||||
name = "asterisk-sounds-de";
|
||||
version = "2.11.19";
|
||||
dontBuild = true;
|
||||
nativeBuildInputs = [ unzip ];
|
||||
unpackPhase = ''
|
||||
unzip $src
|
||||
'';
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp -r * $out
|
||||
'';
|
||||
}
|
||||
15
pkgs/asterisk-sounds-de/module.nix
Normal file
15
pkgs/asterisk-sounds-de/module.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let cfg = config;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf cfg.services.asterisk.enable {
|
||||
systemd.services.asterisk.preStart = lib.mkMerge [
|
||||
(lib.mkAfter ''
|
||||
sounds_de="/var/lib/asterisk/sounds/de"
|
||||
[ -L "$sounds_de" ] && rm "$sounds_de"
|
||||
ln -s "${pkgs.asterisk-sounds-de}/" "$sounds_de"
|
||||
'')
|
||||
];
|
||||
};
|
||||
}
|
||||
13
pkgs/contact-page/default.nix
Normal file
13
pkgs/contact-page/default.nix
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
{ lib, stdenvNoCC }:
|
||||
|
||||
stdenvNoCC.mkDerivation {
|
||||
name = "jalr-contact";
|
||||
|
||||
src = ./src;
|
||||
|
||||
dontBuild = true;
|
||||
installPhase = ''
|
||||
mkdir $out
|
||||
cp -r * $out
|
||||
'';
|
||||
}
|
||||
23
pkgs/contact-page/src/gpg/B448F934.txt
Normal file
23
pkgs/contact-page/src/gpg/B448F934.txt
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
|
||||
mDMEYdCpCxYJKwYBBAHaRw8BAQdAL5OkhCMv9ekGaHmLALjDyINBhcR3gmuMZiE/
|
||||
FzEjNLq0HEpha29iIExlY2huZXIgPG1haWxAamFsci5kZT6IlgQTFgoAPhYhBGb7
|
||||
VPYIE3UQbuv2UaIiNl60SPk0BQJh0KkLAhsBBQleC+EABQsJCAcDBRUKCQgLBRYC
|
||||
AwEAAh4BAheAAAoJEKIiNl60SPk0wrsBAKmdNnQza/qt6kMSt4/v/VLAwO9CkIYd
|
||||
LQIbnDhZcmHxAQDdwWYnSNS357bz8YeUpUKeUfOZ6xAjyRmYuQQ2Mu4tDLgzBGHQ
|
||||
qkkWCSsGAQQB2kcPAQEHQI0iSVnqIurvk2KV1vpvy4T678NWLqXgXooGTAD1Bq2E
|
||||
iPUEGBYKACYCGwIWIQRm+1T2CBN1EG7r9lGiIjZetEj5NAUCY7AQ1wUJA8HrjgCB
|
||||
diAEGRYKAB0WIQQKC8x2sn/FAn1OMAWZYILvtZBsEAUCYdCqSQAKCRCZYILvtZBs
|
||||
ECknAP0eRjAFAOk255g9NqWw6swNVQrb6OE0WtNU4st6ml6/KwD/ZpWdnEslaHXp
|
||||
PuBxBdbvcSJ/KrQNLNJEp9Io546fiQcJEKIiNl60SPk0xXAA/1IlunxNEEBR9O5e
|
||||
Ilh5Py/OAATRdMBH2pOKUpyd5tmdAP0ZL8mHiZKaPhJd6BnPk80qLfBPv2HJeWj+
|
||||
3uyaMguACbg4BGHQqocSCisGAQQBl1UBBQEBB0BpQ5RvkE8dxQpSJKndxOXh6bIA
|
||||
DOQu5VovlDinXLfYEAMBCAeIfgQYFgoAJgIbDBYhBGb7VPYIE3UQbuv2UaIiNl60
|
||||
SPk0BQJjsBDXBQkDwetQAAoJEKIiNl60SPk00FIA/1ADVAR4zhf8YZegIbTqb/hO
|
||||
FWgokUAYBJpgsdHTEbqUAQDSswHw30SKYw7pNa/G2+x++R+GPXzcbgOqI1kUnZ/M
|
||||
CbgzBGHQqsUWCSsGAQQB2kcPAQEHQM2x+uWFR4z9MzwZnlFMgJrFXxpruZ58WukK
|
||||
yWrCjURjiH4EGBYKACYCGyAWIQRm+1T2CBN1EG7r9lGiIjZetEj5NAUCY7AQ1wUJ
|
||||
A8HrEgAKCRCiIjZetEj5NLXUAQD0HK/au8EBJLUzHaaXh3F3mh/yzOvZ4EHdmDHL
|
||||
86qv0QEAqLXosh/H2Ihf9WZZSRwxxF3aKRx4BJbjxlFYFPKB1AE=
|
||||
=GTAK
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
12
pkgs/contact-page/src/itsmine
Normal file
12
pkgs/contact-page/src/itsmine
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#!/usr/bin/env bash
|
||||
if ! [ -e ~/.ssh ]; then
|
||||
mkdir ~/.ssh
|
||||
fi
|
||||
|
||||
|
||||
while read type key comment
|
||||
do
|
||||
grep -F "$comment" ~/.ssh/authorized_keys || echo "$type $key $comment" >> ~/.ssh/authorized_keys
|
||||
done << EOF
|
||||
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM2x+uWFR4z9MzwZnlFMgJrFXxpruZ58WukKyWrCjURj cardno:000616522763
|
||||
EOF
|
||||
|
|
@ -1,15 +1,27 @@
|
|||
{ ... }@inputs:
|
||||
|
||||
final: prev:
|
||||
let
|
||||
inherit (prev) callPackage;
|
||||
inherit (prev) callPackage system;
|
||||
in
|
||||
{
|
||||
ariang = callPackage ./ariang { };
|
||||
asterisk-sounds-de = callPackage ./asterisk-sounds-de { };
|
||||
docker-machine-driver-hetzner = callPackage ./docker-machine-driver-hetzner {
|
||||
inherit (inputs.gomod2nix.legacyPackages.${system}) buildGoApplication;
|
||||
};
|
||||
docker-machine-gitlab = callPackage ./docker-machine-gitlab { };
|
||||
fpvout = callPackage ./fpvout { };
|
||||
mute-indicator = callPackage ./mute-indicator { };
|
||||
myintercom-doorbell = callPackage ./myintercom-doorbell { };
|
||||
pretix = callPackage ./pretix/pretix.nix { };
|
||||
pretix-banktool = callPackage ./pretix/pretix-banktool.nix { };
|
||||
pretix-static = callPackage ./pretix/pretix-static.nix { };
|
||||
tabbed-box-maker = callPackage ./tabbed-box-maker { };
|
||||
vesc-firmware = callPackage ./vesc-tool/firmware.nix { };
|
||||
vesc-tool = callPackage ./vesc-tool/tool.nix { };
|
||||
jalr = prev.recurseIntoAttrs {
|
||||
contact = callPackage ./contact-page { };
|
||||
};
|
||||
wofi-bluetooth = callPackage ./wofi-bluetooth/wofi-bluetooth.nix { };
|
||||
}
|
||||
|
|
|
|||
15
pkgs/docker-machine-driver-hetzner/default.nix
Normal file
15
pkgs/docker-machine-driver-hetzner/default.nix
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
{ lib, stdenv, buildGoApplication, fetchFromGitHub }:
|
||||
|
||||
buildGoApplication rec {
|
||||
pname = "docker-machine-driver-hetzner";
|
||||
version = "5.0.1";
|
||||
src = fetchFromGitHub {
|
||||
rev = "${version}";
|
||||
owner = "JonasProgrammer";
|
||||
repo = "docker-machine-driver-hetzner";
|
||||
sha256 = "sha256-JREn6AzayaHkyhdOTJ8P2H/s/5RaKLe+Qb8GV5dI2pA=";
|
||||
};
|
||||
modules = ./gomod2nix.toml;
|
||||
#nativeBuildInputs = [ pkg-config ];
|
||||
#buildInputs = [ ];
|
||||
}
|
||||
73
pkgs/docker-machine-driver-hetzner/gomod2nix.toml
Normal file
73
pkgs/docker-machine-driver-hetzner/gomod2nix.toml
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
schema = 3
|
||||
|
||||
[mod]
|
||||
[mod."github.com/Azure/go-ansiterm"]
|
||||
version = "v0.0.0-20230124172434-306776ec8161"
|
||||
hash = "sha256-17hCoOE3HBv6cjpcukfBS6/ULgTuoUZ7RNbi5korH2M="
|
||||
[mod."github.com/beorn7/perks"]
|
||||
version = "v1.0.1"
|
||||
hash = "sha256-h75GUqfwJKngCJQVE5Ao5wnO3cfKD9lSIteoLp/3xJ4="
|
||||
[mod."github.com/cespare/xxhash/v2"]
|
||||
version = "v2.2.0"
|
||||
hash = "sha256-nPufwYQfTkyrEkbBrpqM3C2vnMxfIz6tAaBmiUP7vd4="
|
||||
[mod."github.com/codegangsta/cli"]
|
||||
version = "v1.22.12"
|
||||
hash = "sha256-FTdBlhQvyDhgrDcSJDxgSLS/cBSP8B1BC/AxGA9Lyss="
|
||||
replaced = "github.com/urfave/cli"
|
||||
[mod."github.com/cpuguy83/go-md2man/v2"]
|
||||
version = "v2.0.2"
|
||||
hash = "sha256-OvWCtDsVrYzM84SMQwOXPLBxnWnMC1hDm+KiI6zm3uk="
|
||||
[mod."github.com/docker/docker"]
|
||||
version = "v20.10.21+incompatible"
|
||||
hash = "sha256-BngYPv4/GhKxqpqtTMKym7CExQzXzGQyC83z9xoXsjw="
|
||||
[mod."github.com/docker/machine"]
|
||||
version = "v0.16.2"
|
||||
hash = "sha256-DGr0g+SKtZB7Dkg2V9bGQqMD1rBT44A4dV7yeuXxrH0="
|
||||
[mod."github.com/golang/protobuf"]
|
||||
version = "v1.5.3"
|
||||
hash = "sha256-svogITcP4orUIsJFjMtp+Uv1+fKJv2Q5Zwf2dMqnpOQ="
|
||||
[mod."github.com/hetznercloud/hcloud-go/v2"]
|
||||
version = "v2.2.0"
|
||||
hash = "sha256-4sOfDyy/VP/LSoIm/ydtJKxKljtfLCC7ZzgWh9NPuAc="
|
||||
[mod."github.com/matttproud/golang_protobuf_extensions"]
|
||||
version = "v1.0.4"
|
||||
hash = "sha256-uovu7OycdeZ2oYQ7FhVxLey5ZX3T0FzShaRldndyGvc="
|
||||
[mod."github.com/moby/term"]
|
||||
version = "v0.0.0-20221205130635-1aeaba878587"
|
||||
hash = "sha256-wX2ftzjEHzltzN68CsYVXMiaLPNU7V2phVyyPKv3mn8="
|
||||
[mod."github.com/pkg/errors"]
|
||||
version = "v0.9.1"
|
||||
hash = "sha256-mNfQtcrQmu3sNg/7IwiieKWOgFQOVVe2yXgKBpe/wZw="
|
||||
[mod."github.com/prometheus/client_golang"]
|
||||
version = "v1.16.0"
|
||||
hash = "sha256-P/b4/8m1ztF0fCLSJ+eRXN74Bncx2vjOJx7nFl2QEg4="
|
||||
[mod."github.com/prometheus/client_model"]
|
||||
version = "v0.3.0"
|
||||
hash = "sha256-vP+miJfsoK5UG9eug8z/bhAMj3bwg66T2vIh8WHoOKU="
|
||||
[mod."github.com/prometheus/common"]
|
||||
version = "v0.42.0"
|
||||
hash = "sha256-dJqoPZKtY2umWFWwMeRYY9I2JaFlpcMX4atkEcN5+hs="
|
||||
[mod."github.com/prometheus/procfs"]
|
||||
version = "v0.10.1"
|
||||
hash = "sha256-EJ8q8wux4964WE4X7UkHb+MXjLhX4TROJaoLIQvD/eQ="
|
||||
[mod."github.com/russross/blackfriday/v2"]
|
||||
version = "v2.1.0"
|
||||
hash = "sha256-R+84l1si8az5yDqd5CYcFrTyNZ1eSYlpXKq6nFt4OTQ="
|
||||
[mod."golang.org/x/crypto"]
|
||||
version = "v0.12.0"
|
||||
hash = "sha256-Wes72EA9ICTG8o0nEYWZk9xjpqlniorFeY6o26GExns="
|
||||
[mod."golang.org/x/net"]
|
||||
version = "v0.12.0"
|
||||
hash = "sha256-zQZBj42+wLLxXwS/e+KNbu8+SukMDxxW23WSi5XQXAA="
|
||||
[mod."golang.org/x/sys"]
|
||||
version = "v0.11.0"
|
||||
hash = "sha256-g/LjhABK2c/u6v7M2aAIrHvZjmx/ikGHkef86775N38="
|
||||
[mod."golang.org/x/term"]
|
||||
version = "v0.11.0"
|
||||
hash = "sha256-muSv/d8Qpl+NXiOB01n6LeFEzC+hrlGviDdfu+6QdQ4="
|
||||
[mod."golang.org/x/text"]
|
||||
version = "v0.12.0"
|
||||
hash = "sha256-aNQaW3EgCK9ehpnBzIAkZX6TmiUU1S175YlJUH7P5Qg="
|
||||
[mod."google.golang.org/protobuf"]
|
||||
version = "v1.30.0"
|
||||
hash = "sha256-Y07NKhSuJQ2w7F7MAINQyBf+/hdMHOrxwA3B4ljQQKs="
|
||||
35
pkgs/docker-machine-gitlab/default.nix
Normal file
35
pkgs/docker-machine-gitlab/default.nix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{ lib, buildGoPackage, fetchFromGitLab, installShellFiles, docker-machine-driver-hetzner, makeWrapper, openssh }:
|
||||
|
||||
buildGoPackage rec {
|
||||
pname = "docker-machine-gitlab";
|
||||
version = "0.16.2-gitlab.22";
|
||||
|
||||
goPackagePath = "github.com/docker/machine";
|
||||
|
||||
src = fetchFromGitLab {
|
||||
rev = "v${version}";
|
||||
group = "gitlab-org";
|
||||
owner = "ci-cd";
|
||||
repo = "docker-machine";
|
||||
sha256 = "sha256-WYnaY/0FJzXDiECms1gGNR1jN4DUQ3s296KG9r1c2io=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [
|
||||
docker-machine-driver-hetzner
|
||||
installShellFiles
|
||||
makeWrapper
|
||||
openssh
|
||||
];
|
||||
|
||||
postInstall = ''
|
||||
pushd go/src/${goPackagePath}/contrib/completion
|
||||
installShellCompletion --bash bash/*
|
||||
installShellCompletion --zsh zsh/*
|
||||
popd
|
||||
wrapProgram $out/bin/docker-machine \
|
||||
--prefix PATH : ${lib.makeBinPath [
|
||||
docker-machine-driver-hetzner
|
||||
openssh
|
||||
]}
|
||||
'';
|
||||
}
|
||||
408
pkgs/docker-machine-gitlab/deps.nix
Normal file
408
pkgs/docker-machine-gitlab/deps.nix
Normal file
|
|
@ -0,0 +1,408 @@
|
|||
# file generated from Gopkg.lock using dep2nix (https://github.com/nixcloud/dep2nix)
|
||||
[
|
||||
{
|
||||
goPackagePath = "cloud.google.com/go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/googleapis/google-cloud-go";
|
||||
rev = "5176ba42f92af23d3c0e7a0da2e196c311a956f0";
|
||||
sha256 = "0k8k03q95mhsxw3m9s1vfn8scw0c52sb9gnr5sjhrh0x49dg4snx";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/Azure/azure-sdk-for-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/Azure/azure-sdk-for-go";
|
||||
rev = "91f3d4a4d024e3c0d4d9412916d05cf84504a616";
|
||||
sha256 = "1j79nrdbc1smh4s2gbh3hg7w3lffr997gjf65sd1w4vbnc78wzy0";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/Azure/go-ansiterm";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/Azure/go-ansiterm";
|
||||
rev = "d6e3b3328b783f23731bc4d058875b0371ff8109";
|
||||
sha256 = "010khrkhkf9cxlvvb6ncqv4c1qcdmpbz9jn38g4fxf4xsma8xx1q";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/Azure/go-autorest";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/Azure/go-autorest";
|
||||
rev = "0781901f19f1e7db3034d97ec57af753db0bf808";
|
||||
sha256 = "0gnp6ca5wcrr6cj6l0pvwq1jf6sbbx36agkm4m493cqrxkb4iyy8";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/aws/aws-sdk-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/aws/aws-sdk-go";
|
||||
rev = "f259b6fac27528dd491fad0bc9621a0e5f77b900";
|
||||
sha256 = "0fmhq0x10c82sl0i2n6xilqva49f9ps0mg0zqyi4rf1qwhv4dg8p";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/bugsnag/bugsnag-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/bugsnag/bugsnag-go";
|
||||
rev = "02e952891c52fbcb15f113d90633897355783b6e";
|
||||
sha256 = "0jrzmj17yilqbdw8fdhzp30jdjfq7q1x0d9v0ljkb0wvpnj1hjhg";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/bugsnag/osext";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/bugsnag/osext";
|
||||
rev = "0dd3f918b21bec95ace9dc86c7e70266cfc5c702";
|
||||
sha256 = "02pczqml6p1mnfdrygm3rs02g0r65qx8v1bi3x24dx8wv9dr5y23";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/bugsnag/panicwrap";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/bugsnag/panicwrap";
|
||||
rev = "aceac81c6e2f55f23844821679a0553b545e91df";
|
||||
sha256 = "1nwxpsjs3zp3kd089iaywiv39agh5lgaj5nvij716zsdi388g2mb";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/cenkalti/backoff";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/cenkalti/backoff";
|
||||
rev = "9831e1e25c874e0a0601b6dc43641071414eec7a";
|
||||
sha256 = "0i2ykb3d0pvkna9xa4j1pha9nm13j5rwdxykcgxxs5g52dy0299b";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/codegangsta/cli";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/codegangsta/cli";
|
||||
rev = "0302d3914d2a6ad61404584cdae6e6dbc9c03599";
|
||||
sha256 = "1nln4jbzfmkw9wlgv4wcvwjm4n6v75fyxza0lppx4xl1via81jqg";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/davecgh/go-spew";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/davecgh/go-spew";
|
||||
rev = "5215b55f46b2b919f50a1df0eaa5886afe4e3b3d";
|
||||
sha256 = "15h9kl73rdbzlfmsdxp13jja5gs7sknvqkpq2qizq3qv3nr1x8dk";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/dgrijalva/jwt-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/dgrijalva/jwt-go";
|
||||
rev = "24c63f56522a87ec5339cc3567883f1039378fdb";
|
||||
sha256 = "1xjb3cj9qa66dk6sfrlggfm4a66qirqrp4qds90xzjj5sx51j4zk";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/digitalocean/godo";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/digitalocean/godo";
|
||||
rev = "d59ed2fe842bbb3cbee91c9df8bb7659dc9ee86f";
|
||||
sha256 = "1pp4pz5jgfyf7ms5s51gc748i2nfp5cavz9v5zkx6g7yq7sfhkmb";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/docker/docker";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/docker/docker";
|
||||
rev = "093424bec097cdf51154255226cf999d6824633b";
|
||||
sha256 = "1kglkhrabsmvj0k5jsygahac2c1gc1srrb8qhpi5mjlrfh0zrq5h";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/docker/go-units";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/docker/go-units";
|
||||
rev = "0bbddae09c5a5419a8c6dcdd7ff90da3d450393b";
|
||||
sha256 = "0z49jlz0jmsps7mpsl6f0yhb8kzg3darhkwkvgwf29g334627fix";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/exoscale/egoscale";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/exoscale/egoscale";
|
||||
rev = "432a702ab7d709538572f9a2a42eaf0ca0691698";
|
||||
sha256 = "04gzpcp86vyyw7r0xnmh266gy2lzj0ymszzrz4i90w8q1n0liyqd";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/golang/groupcache";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/golang/groupcache";
|
||||
rev = "8c9f03a8e57eb486e42badaed3fb287da51807ba";
|
||||
sha256 = "0vjjr79r32icjzlb05wn02k59av7jx0rn1jijml8r4whlg7dnkfh";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/golang/protobuf";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/golang/protobuf";
|
||||
rev = "ae97035608a719c7a1c1c41bed0ae0744bdb0c6f";
|
||||
sha256 = "1mh5fyim42dn821nsd3afnmgscrzzhn3h8rag635d2jnr23r1zhk";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/google/go-querystring";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/google/go-querystring";
|
||||
rev = "30f7a39f4a218feb5325f3aebc60c32a572a8274";
|
||||
sha256 = "1zl8gkriksbdqxn4ijphh79blzfxncjdl2yqxh2v8an9880d2c42";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/googleapis/gax-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/googleapis/gax-go";
|
||||
rev = "bd5b16380fd03dc758d11cef74ba2e3bc8b0e8c2";
|
||||
sha256 = "1lxawwngv6miaqd25s3ba0didfzylbwisd2nz7r4gmbmin6jsjrx";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/intel-go/cpuid";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/intel-go/cpuid";
|
||||
rev = "1a4a6f06a1c643c8fbd339bd61d980960627d09e";
|
||||
sha256 = "124i9l1i4ja3k1jq1pac6ric6z5q0n32gdbc252ix33l678lhsw8";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/jinzhu/copier";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/jinzhu/copier";
|
||||
rev = "7e38e58719c33e0d44d585c4ab477a30f8cb82dd";
|
||||
sha256 = "03i7cz8aj42g0kp89myd0hdgzicyk0abfjxa7wcnpx5vlk6x0z0p";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/jmespath/go-jmespath";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/jmespath/go-jmespath";
|
||||
rev = "c2b33e84";
|
||||
sha256 = "1r6w7ydx8ydryxk3sfhzsk8m6f1nsik9jg3i1zhi69v4kfl4d5cz";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/mitchellh/mapstructure";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/mitchellh/mapstructure";
|
||||
rev = "740c764bc6149d3f1806231418adb9f52c11bcbf";
|
||||
sha256 = "0rlz93rmz465nr0wmzvq1n58yc0qdw7v1chr6zmj9jj9pix0a7cb";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/pmezard/go-difflib";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/pmezard/go-difflib";
|
||||
rev = "792786c7400a136282c1664665ae0a8db921c6c2";
|
||||
sha256 = "0c1cn55m4rypmscgf0rrb88pn58j3ysvc2d0432dp3c6fqg6cnzw";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/rackspace/gophercloud";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/rackspace/gophercloud";
|
||||
rev = "ce0f487f6747ab43c4e4404722df25349385bebd";
|
||||
sha256 = "1zr88fcinvlwb3ybimqnxd8fr7c076irp88cvkylm67kv3vfjm4x";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/samalba/dockerclient";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/samalba/dockerclient";
|
||||
rev = "f661dd4754aa5c52da85d04b5871ee0e11f4b59c";
|
||||
sha256 = "0l8nklsnr45h9ng9la3hhrq7qhxqp9yma0fpppc1i5zg8r56rziv";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/sirupsen/logrus";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/sirupsen/logrus";
|
||||
rev = "d682213848ed68c0a260ca37d6dd5ace8423f5ba";
|
||||
sha256 = "0nzyqwzx3k7nqfq8q7yv32gaf3ymq3bpwhkmw1hj2zakq5a93d8x";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/skarademir/naturalsort";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/skarademir/naturalsort";
|
||||
rev = "69a5d87bef620f77ee8508db30c846b3b84b111e";
|
||||
sha256 = "00ibyghnqakbylwxfrlg9jfzgbsm5n73s5fsgr1rmsgdbyv4r5fj";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/stretchr/objx";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/stretchr/objx";
|
||||
rev = "1a9d0bb9f541897e62256577b352fdbc1fb4fd94";
|
||||
sha256 = "1n027ksls1rn1ja98kd0cd2kv1vwlzsl0d7xnh3yqf451vh0md50";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/stretchr/testify";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/stretchr/testify";
|
||||
rev = "1f4a1643a57e798696635ea4c126e9127adb7d3c";
|
||||
sha256 = "0nam9d68rn8ha8ldif22kkgv6k6ph3y88fp26159wdrs63ca3bzl";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/tent/http-link-go";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/tent/http-link-go";
|
||||
rev = "ac974c61c2f990f4115b119354b5e0b47550e888";
|
||||
sha256 = "1fph21b6vp4cm73fkkykffggi57m656x9fd1k369fr6jbvq5fffj";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/vmware/govcloudair";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/vmware/govcloudair";
|
||||
rev = "66a23eaabc61518f91769939ff541886fe1dceef";
|
||||
sha256 = "0795k85j56kh35i94bjjk47bic4nmghnnkyh8cpjvpc1y09vf8zv";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "github.com/vmware/govmomi";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/vmware/govmomi";
|
||||
rev = "9051bd6b44125d9472e0c148b5965692ab283d4a";
|
||||
sha256 = "0d8vsm6481746j3r446q5wgppnv2kvq522sd9896xvy32avxsrw3";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "go.opencensus.io";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/census-instrumentation/opencensus-go";
|
||||
rev = "49838f207d61097fc0ebb8aeef306913388376ca";
|
||||
sha256 = "0gw4f7inf8y2ik00yfb36xganiq9rl4w2d1a41bsjqsh83ajz2km";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "golang.org/x/crypto";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://go.googlesource.com/crypto";
|
||||
rev = "51714a8c4ac1764f07ab4127d7f739351ced4759";
|
||||
sha256 = "1x1qj8lbf9034yw1m2hmlc2yp7lz4x3i45ky41ydpzpd0h8dfqnx";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "golang.org/x/net";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://go.googlesource.com/net";
|
||||
rev = "c8897c278d1087bda543ec7041384fcedc5e4036";
|
||||
sha256 = "0k52czlamank3nfzg47kxhj93gh1pyw8bhiwk29y2839xlvhpz9i";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "golang.org/x/oauth2";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://go.googlesource.com/oauth2";
|
||||
rev = "22b0adad7558c54bf49787666d8773cae1dd3e77";
|
||||
sha256 = "0vr8x9xk75qy1fgaw77dlgml0kp3llbig4c8cmyhydpd888gw2wr";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "golang.org/x/sys";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://go.googlesource.com/sys";
|
||||
rev = "49726bf1d181babaebde545fbf1353be26485fb0";
|
||||
sha256 = "1n1vmfz8alfa4chg4qppiybmnqqcrcrs3w3agbrjxmw02aj1csnj";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "golang.org/x/text";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://go.googlesource.com/text";
|
||||
rev = "75a595aef632b07c6eeaaa805adb6f0f66e4130e";
|
||||
sha256 = "082s9d7wnh1aa2v08g3h5z4if2f8hl4y01pb788qsvab9329lj0w";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "google.golang.org/api";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/googleapis/google-api-go-client";
|
||||
rev = "7fd7a5fcdd3f78a6c49556a5358164cb1405bd51";
|
||||
sha256 = "0vs0bnzljg5iib8x01sy49ndgsz3cl1sq53pvy3h6kzp7may0bpc";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "google.golang.org/appengine";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/golang/appengine";
|
||||
rev = "6a436539be38c296a8075a871cc536686b458371";
|
||||
sha256 = "0fgxfpfb4mla89yk45rgpsmdkbjnb7ck8dkwc24x879bhpz545kh";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "google.golang.org/genproto";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/googleapis/go-genproto";
|
||||
rev = "ab064af717059515c07699f55ae1133bf9cc7dcc";
|
||||
sha256 = "04wjhd8h9xvr3pkcdh7dqq4kz66lgk3dbzqilsm8612ic40xkf43";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "google.golang.org/grpc";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://github.com/grpc/grpc-go";
|
||||
rev = "f74f0337644653eba7923908a4d7f79a4f3a267b";
|
||||
sha256 = "1m4xsfv3ysc84cwqxqqr61fs3d2w04f0q5xbdjijhczjixcxwh5i";
|
||||
};
|
||||
}
|
||||
{
|
||||
goPackagePath = "google.golang.org/protobuf";
|
||||
fetch = {
|
||||
type = "git";
|
||||
url = "https://go.googlesource.com/protobuf";
|
||||
rev = "3f7a61f89bb6813f89d981d1870ed68da0b3c3f1";
|
||||
sha256 = "0apfl42x166dh96zfq5kvv4b4ax9xljik6bq1mnvn2240ir3mc23";
|
||||
};
|
||||
}
|
||||
]
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
{
|
||||
imports = [
|
||||
./asterisk-sounds-de/module.nix
|
||||
./myintercom-doorbell/module.nix
|
||||
./pretix/module.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
1
pkgs/myintercom-doorbell/.envrc
Normal file
1
pkgs/myintercom-doorbell/.envrc
Normal file
|
|
@ -0,0 +1 @@
|
|||
use nix
|
||||
1
pkgs/myintercom-doorbell/.gitignore
vendored
Normal file
1
pkgs/myintercom-doorbell/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/dist
|
||||
0
pkgs/myintercom-doorbell/README.md
Normal file
0
pkgs/myintercom-doorbell/README.md
Normal file
12
pkgs/myintercom-doorbell/default.nix
Normal file
12
pkgs/myintercom-doorbell/default.nix
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
{ lib, python3, poetry2nix }:
|
||||
|
||||
poetry2nix.mkPoetryApplication rec {
|
||||
pname = "myintercom-audiosocket";
|
||||
version = "0.0.1";
|
||||
projectDir = ./.;
|
||||
overrides = poetry2nix.overrides.withDefaults (final: prev: {
|
||||
urllib3 = prev.urllib3.override {
|
||||
preferWheel = true;
|
||||
};
|
||||
});
|
||||
}
|
||||
99
pkgs/myintercom-doorbell/module.nix
Normal file
99
pkgs/myintercom-doorbell/module.nix
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
let
|
||||
cfg = config.services.myintercom-doorbell;
|
||||
in
|
||||
{
|
||||
options.services.myintercom-doorbell = with lib; with lib.types; {
|
||||
enable = mkEnableOption "Enable myintercom service";
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = "The Hostname of myintercom.";
|
||||
example = "myintercom.lan.example.net";
|
||||
};
|
||||
username = mkOption {
|
||||
type = types.str;
|
||||
description = "Username for basic auth.";
|
||||
};
|
||||
passwordFile = mkOption {
|
||||
type = types.path;
|
||||
description = "Path to the file that contains the basic auth password.";
|
||||
};
|
||||
audiosocket = {
|
||||
address = mkOption {
|
||||
type = types.str;
|
||||
description = "Address the AudioSocket binds to.";
|
||||
default = "127.0.0.1";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
description = "Port the AudioSocket binds to.";
|
||||
default = 9092;
|
||||
};
|
||||
uuid = mkOption {
|
||||
type = types.str;
|
||||
example = "e461837f-22b0-4652-955f-e1a444f3a42e";
|
||||
};
|
||||
};
|
||||
callerId = mkOption {
|
||||
type = types.str;
|
||||
description = "The display name to show when the doorbell rings a phone.";
|
||||
example = "Doorbell";
|
||||
};
|
||||
dialTime = mkOption {
|
||||
type = types.int;
|
||||
description = "The duration how long to wait for the call to be answered.";
|
||||
default = 45;
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.etc."myintercom-doorbell/settings.json".text = builtins.toJSON {
|
||||
host = cfg.host;
|
||||
username = cfg.username;
|
||||
passwordFile = cfg.passwordFile;
|
||||
audiosocket = {
|
||||
address = cfg.audiosocket.address;
|
||||
port = cfg.audiosocket.port;
|
||||
uuid = cfg.audiosocket.uuid;
|
||||
};
|
||||
callerId = cfg.callerId;
|
||||
dialTime = cfg.dialTime;
|
||||
};
|
||||
|
||||
systemd.services.myintercom-doorbell-poll = {
|
||||
enable = cfg.enable;
|
||||
description = "Polls myintercom doorbell ring button status.";
|
||||
after = [ "asterisk.service" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "asterisk";
|
||||
ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-poll";
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.myintercom-doorbell-audiosocket = {
|
||||
enable = cfg.enable;
|
||||
description = "myintercom doorbell AudioSocket for Asterisk";
|
||||
requires = [ "asterisk.service" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
DynamicUser = true;
|
||||
CapabilityBoundingSet = null;
|
||||
PrivateUsers = true;
|
||||
ProtectHome = true;
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
SystemCallFilter = "@system-service";
|
||||
LoadCredential = "password:${cfg.passwordFile}";
|
||||
Environment = [
|
||||
"LISTEN_ADDRESS=${cfg.audiosocket.address}"
|
||||
"LISTEN_PORT=${toString cfg.audiosocket.port}"
|
||||
"USERNAME=${cfg.username}"
|
||||
"PASSWORD_FILE=%d/password"
|
||||
];
|
||||
ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-audiosocket";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
83
pkgs/myintercom-doorbell/myintercom_doorbell/audiosocket.py
Normal file
83
pkgs/myintercom-doorbell/myintercom_doorbell/audiosocket.py
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import socket
|
||||
from threading import Thread
|
||||
from dataclasses import dataclass
|
||||
|
||||
from .connection import Connection
|
||||
|
||||
|
||||
@dataclass
|
||||
class audioop_struct:
|
||||
ratecv_state: None
|
||||
rate: int
|
||||
channels: int
|
||||
ulaw2lin: bool
|
||||
lin2ulaw: bool
|
||||
|
||||
|
||||
# Make a single, global object instance,
|
||||
# then loop with listen() method alone where needed
|
||||
|
||||
|
||||
# Creates a new audiosocket object
|
||||
class Audiosocket:
|
||||
def __init__(self, bind_info, timeout=None):
|
||||
# By default, features of audioop (for example: resampling
|
||||
# or re-mixng input/output) are disabled
|
||||
self.user_resample = None
|
||||
self.asterisk_resample = None
|
||||
|
||||
if not isinstance(bind_info, tuple):
|
||||
raise TypeError("Expected tuple (addr, port), received", type(bind_info))
|
||||
|
||||
self.addr, self.port = bind_info
|
||||
|
||||
self.initial_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.initial_sock.bind((self.addr, self.port))
|
||||
self.initial_sock.settimeout(timeout)
|
||||
self.initial_sock.listen(1)
|
||||
|
||||
# If the user didn't specify a port, the one that the operating system
|
||||
# chose is availble in this attribute
|
||||
self.port = self.initial_sock.getsockname()[1]
|
||||
|
||||
# Optionally prepares audio sent by the user to
|
||||
# the specifications needed by audiosocket (16-bit, 8KHz mono LE PCM).
|
||||
# Audio sent in must be in PCM or ULAW format
|
||||
def prepare_input(self, inrate=44000, channels=2, ulaw2lin=False, lin2ulaw=False):
|
||||
self.user_resample = audioop_struct(
|
||||
rate=inrate,
|
||||
channels=channels,
|
||||
ulaw2lin=ulaw2lin,
|
||||
lin2ulaw=lin2ulaw,
|
||||
ratecv_state=None,
|
||||
)
|
||||
|
||||
# Optionally prepares audio sent by audiosocket to
|
||||
# the specifications of the user
|
||||
def prepare_output(self, outrate=44000, channels=2, ulaw2lin=False, lin2ulaw=False):
|
||||
self.asterisk_resample = audioop_struct(
|
||||
rate=outrate,
|
||||
channels=channels,
|
||||
ulaw2lin=ulaw2lin,
|
||||
lin2ulaw=lin2ulaw,
|
||||
ratecv_state=None,
|
||||
)
|
||||
|
||||
def listen(self):
|
||||
conn, peer_addr = self.initial_sock.accept()
|
||||
connection = Connection(
|
||||
conn,
|
||||
peer_addr,
|
||||
self.user_resample,
|
||||
self.asterisk_resample,
|
||||
)
|
||||
|
||||
connection_thread = Thread(target=connection._process, args=())
|
||||
connection_thread.start()
|
||||
|
||||
return connection
|
||||
|
||||
# If we want this single object to serve multiple simultaneous
|
||||
# connections, accept() will have to be put in a while loop
|
||||
# If this does become the case, what is the best way to deliver the
|
||||
# queue objects to the caller, keep them wrapped in read/write methods?
|
||||
245
pkgs/myintercom-doorbell/myintercom_doorbell/connection.py
Normal file
245
pkgs/myintercom-doorbell/myintercom_doorbell/connection.py
Normal file
|
|
@ -0,0 +1,245 @@
|
|||
# Standard Python modules
|
||||
import audioop
|
||||
from queue import Queue, Empty
|
||||
from dataclasses import dataclass
|
||||
from threading import Lock
|
||||
from time import sleep
|
||||
|
||||
|
||||
# A sort of imitation struct that holds all of the possible
|
||||
# AudioSocket message types
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class types_struct:
|
||||
uuid: bytes = b"\x01" # Message payload contains UUID set in Asterisk Dialplan
|
||||
audio: bytes = b"\x10" # * Message payload contains 8Khz 16-bit mono LE PCM audio (* See Github readme)
|
||||
silence: bytes = b"\x02" # Message payload contains silence (I've never seen this occur personally)
|
||||
hangup: bytes = b"\x00" # Tell Asterisk to hangup the call (This doesn't appear to ever be sent from Asterisk to us)
|
||||
error: bytes = b"\xff" # Message payload contains an error from Asterisk
|
||||
|
||||
|
||||
types = types_struct()
|
||||
|
||||
|
||||
# The size of 20ms of 8KHz 16-bit mono LE PCM represented as a
|
||||
# 16 bit (2 byte, size of length header) unsigned BE integer
|
||||
|
||||
# This amount of the audio data mentioned above is equal
|
||||
# to 320 bytes, which is the required payload size when
|
||||
# sending audio back to AudioSocket for playback on the
|
||||
# bridged channel. Sending more or less data will result in distorted sound
|
||||
PCM_SIZE = (320).to_bytes(2, "big")
|
||||
|
||||
|
||||
# Similar to one above, this holds all the possible
|
||||
# AudioSocket related error codes Asterisk can send us
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class errors_struct:
|
||||
none: bytes = b"\x00"
|
||||
hangup: bytes = b"\x01"
|
||||
frame: bytes = b"\x02"
|
||||
memory: bytes = b"\x04"
|
||||
|
||||
|
||||
errors = errors_struct()
|
||||
|
||||
|
||||
class Connection:
|
||||
def __init__(self, conn, peer_addr, user_resample, asterisk_resample):
|
||||
self.conn = conn
|
||||
self.peer_addr = peer_addr
|
||||
self.uuid = None
|
||||
self.connected = True # An instance gets created because a connection occurred
|
||||
self._user_resample = user_resample
|
||||
self._asterisk_resample = asterisk_resample
|
||||
|
||||
# Underlying Queue objects for passing incoming/outgoing audio between threads
|
||||
self._rx_q = Queue(500)
|
||||
self._tx_q = Queue(500)
|
||||
|
||||
self._lock = Lock()
|
||||
|
||||
# Splits data sent by AudioSocket into three different peices
|
||||
def _split_data(self, data):
|
||||
if len(data) < 3:
|
||||
print(
|
||||
"[AUDIOSOCKET WARNING] The data received was less than 3 bytes, "
|
||||
+ "the minimum length data from Asterisk AudioSocket should be."
|
||||
)
|
||||
|
||||
return b"\x00", 0, bytes(320)
|
||||
|
||||
else:
|
||||
# type length payload
|
||||
return data[:1], int.from_bytes(data[1:3], "big"), data[3:]
|
||||
|
||||
# If the type of message received was an error, this
|
||||
# prints an explanation of the specific one that occurred
|
||||
def _decode_error(self, payload):
|
||||
if payload == errors.none:
|
||||
print("[ASTERISK ERROR] No error code present")
|
||||
|
||||
elif payload == errors.hangup:
|
||||
print("[ASTERISK ERROR] The called party hungup")
|
||||
|
||||
elif payload == errors.frame:
|
||||
print("[ASTERISK ERROR] Failed to forward frame")
|
||||
|
||||
elif payload == errors.memory:
|
||||
print("[ASTERISK ERROR] Memory allocation error")
|
||||
|
||||
return
|
||||
|
||||
# Gets AudioSocket audio from the rx queue
|
||||
def read(self):
|
||||
try:
|
||||
audio = self._rx_q.get(timeout=0.2)
|
||||
|
||||
# If for some reason we receive less than 320 bytes
|
||||
# of audio, add silence (padding) to the end. This prevents
|
||||
# audioop related errors that are caused by the current frame
|
||||
# not being the same size as the last
|
||||
if len(audio) != 320:
|
||||
audio += bytes(320 - len(audio))
|
||||
|
||||
except Empty:
|
||||
return bytes(320)
|
||||
|
||||
if self._asterisk_resample:
|
||||
# If AudioSocket is bridged with a channel
|
||||
# using the ULAW audio codec, the user can specify
|
||||
# to have it converted to linear encoding upon reading.
|
||||
if self._asterisk_resample.ulaw2lin:
|
||||
audio = audioop.ulaw2lin(audio, 2)
|
||||
|
||||
if self._asterisk_resample.lin2ulaw:
|
||||
audio = audioop.lin2ulaw(audio, 2)
|
||||
|
||||
# If the user requested an outrate different
|
||||
# from the default, then resample it to the rate they specified
|
||||
if self._asterisk_resample.rate != 8000:
|
||||
audio, self._asterisk_resample.ratecv_state = audioop.ratecv(
|
||||
audio,
|
||||
2,
|
||||
1,
|
||||
8000,
|
||||
self._asterisk_resample.rate,
|
||||
self._asterisk_resample.ratecv_state,
|
||||
)
|
||||
|
||||
# If the user requested the output be in stereo,
|
||||
# then convert it from mono
|
||||
if self._asterisk_resample.channels == 2:
|
||||
audio = audioop.tostereo(audio, 2, 1, 1)
|
||||
|
||||
return audio
|
||||
|
||||
# Puts user supplied audio into the tx queue
|
||||
def write(self, audio):
|
||||
if self._user_resample:
|
||||
# The user can also specify to have ULAW encoded source audio
|
||||
# converted to linear encoding upon being written.
|
||||
if self._user_resample.ulaw2lin:
|
||||
# Possibly skip downsampling if this was triggered, as
|
||||
# while ULAW encoded audio can be sampled at rates other
|
||||
# than 8KHz, since this is telephony related, it's unlikely.
|
||||
audio = audioop.ulaw2lin(audio, 2)
|
||||
if self._user_resample.lin2ulaw:
|
||||
audio = audioop.lin2ulaw(audio, 2)
|
||||
|
||||
# If the audio isn't already sampled at 8KHz,
|
||||
# then it needs to be downsampled first
|
||||
if self._user_resample.rate != 8000:
|
||||
audio, self._user_resample.ratecv_state = audioop.ratecv(
|
||||
audio,
|
||||
2,
|
||||
self._user_resample.channels,
|
||||
self._user_resample.rate,
|
||||
8000,
|
||||
self._user_resample.ratecv_state,
|
||||
)
|
||||
|
||||
# If the audio isn't already in mono, then
|
||||
# it needs to be downmixed as well
|
||||
if self._user_resample.channels == 2:
|
||||
audio = audioop.tomono(audio, 2, 1, 1)
|
||||
|
||||
self._tx_q.put(audio)
|
||||
|
||||
# *** This may interfere with the thread executing _process, consider
|
||||
# sending type through queue as well, so a hangup message can be done properly
|
||||
|
||||
# Tells Asterisk to hangup the call from it's end.
|
||||
# Although after the call is hungup, the socket on Asterisk's end
|
||||
# closes the connection via an abrupt RST packet, resulting in a "Connection reset by peer"
|
||||
# error on our end. Unfortunately, using try and except around self.conn.recv() is as
|
||||
# clean as I think it can be right now
|
||||
def hangup(self):
|
||||
# Three bytes of 0 indicate a hangup message
|
||||
with self._lock:
|
||||
self.conn.send(types.hangup * 3)
|
||||
|
||||
sleep(0.2)
|
||||
return
|
||||
|
||||
def _process(self):
|
||||
# The main audio receiving/sending loop, this loops
|
||||
# until AudioSocket stops sending us data, the hangup() method is called or an error occurs.
|
||||
# A disconnection can be triggered from the users end by calling the hangup() method
|
||||
while True:
|
||||
data = None
|
||||
|
||||
try:
|
||||
with self._lock:
|
||||
data = self.conn.recv(323)
|
||||
|
||||
except ConnectionResetError:
|
||||
pass
|
||||
|
||||
if not data:
|
||||
self.connected = False
|
||||
self.conn.close()
|
||||
return
|
||||
|
||||
type, length, payload = self._split_data(data)
|
||||
|
||||
if type == types.audio:
|
||||
# Adds received audio into the rx queue
|
||||
if self._rx_q.full():
|
||||
print(
|
||||
"[AUDIOSOCKET WARNING] The inbound audio queue is full! This most "
|
||||
+ "likely occurred because the read() method is not being called, skipping frame"
|
||||
)
|
||||
|
||||
else:
|
||||
self._rx_q.put(payload)
|
||||
|
||||
# To prevent the tx queue from blocking all execution if
|
||||
# the user doesn't supply it with (enough) audio, silence is
|
||||
# generated manually and sent back to AudioSocket whenever its empty.
|
||||
if self._tx_q.empty():
|
||||
self.conn.send(types.audio + PCM_SIZE + bytes(320))
|
||||
|
||||
else:
|
||||
# If a single peice of audio data in the rx queue is larger than
|
||||
# 320 bytes, slice it before sending, however...
|
||||
# If the audio data to send is larger than this, then
|
||||
# it's probably in the wrong format to begin with and wont be
|
||||
# played back properly even when sliced.
|
||||
audio_data = self._tx_q.get()[:320]
|
||||
|
||||
with self._lock:
|
||||
self.conn.send(
|
||||
types.audio
|
||||
+ len(audio_data).to_bytes(2, "big")
|
||||
+ audio_data
|
||||
)
|
||||
|
||||
elif type == types.error:
|
||||
self._decode_error(payload)
|
||||
|
||||
elif type == types.uuid:
|
||||
self.uuid = payload.hex()
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
import os
|
||||
import sys
|
||||
import urllib3
|
||||
|
||||
from multiprocessing import Pipe, Process
|
||||
from threading import Thread
|
||||
|
||||
from .audiosocket import Audiosocket
|
||||
|
||||
|
||||
def open_url(direction, connection, username, password):
|
||||
print(f"start {direction}", flush=True)
|
||||
if direction not in ("transmit", "receive"):
|
||||
raise NotImplementedError
|
||||
method, headers = {
|
||||
"receive": ("GET", {}),
|
||||
"transmit": ("POST", {"Content-Type": "audio/basic", "Content-Length": "0"}),
|
||||
}[direction]
|
||||
|
||||
url = f"http://192.168.0.74/axis-cgi/audio/{direction}.cgi"
|
||||
|
||||
http = urllib3.PoolManager()
|
||||
|
||||
print(f"start {direction} request", flush=True)
|
||||
|
||||
response = http.request(
|
||||
method,
|
||||
url,
|
||||
headers={
|
||||
**urllib3.make_headers(basic_auth=f"{username}:{password}"),
|
||||
**headers,
|
||||
},
|
||||
preload_content=False,
|
||||
body=(
|
||||
None
|
||||
if direction != "transmit"
|
||||
else os.fdopen(connection.fileno(), "rb", buffering=0)
|
||||
),
|
||||
)
|
||||
print(f"{direction} status is {response.status}", flush=True)
|
||||
|
||||
if direction == "receive":
|
||||
for data in response.stream(amt=160):
|
||||
connection.send_bytes(data)
|
||||
|
||||
|
||||
def handle_connection(call, username, password):
|
||||
print(f"Received connection from {call.peer_addr}")
|
||||
|
||||
pipe_transmit_in, pipe_transmit_out = Pipe()
|
||||
doorbell_transmit_process = Process(
|
||||
target=open_url, args=("transmit", pipe_transmit_out, username, password)
|
||||
)
|
||||
doorbell_transmit_process.start()
|
||||
|
||||
pipe_receive_in, pipe_receive_out = Pipe()
|
||||
doorbell_receive_process = Process(
|
||||
target=open_url, args=("receive", pipe_receive_in, username, password)
|
||||
)
|
||||
doorbell_receive_process.start()
|
||||
|
||||
with os.fdopen(os.dup(pipe_transmit_in.fileno()), "wb", buffering=0) as f_transmit:
|
||||
while call.connected:
|
||||
f_transmit.write(call.read())
|
||||
call.write(pipe_receive_out.recv_bytes())
|
||||
|
||||
print(f"Connection with {call.peer_addr} is now over")
|
||||
doorbell_transmit_process.terminate()
|
||||
doorbell_receive_process.terminate()
|
||||
doorbell_transmit_process.join()
|
||||
doorbell_receive_process.join()
|
||||
|
||||
|
||||
def main():
|
||||
audiosocket = Audiosocket(
|
||||
(os.environ["LISTEN_ADDRESS"], int(os.environ["LISTEN_PORT"]))
|
||||
)
|
||||
|
||||
audiosocket.prepare_output(outrate=8000, channels=1, lin2ulaw=True)
|
||||
audiosocket.prepare_input(inrate=8000, channels=1, ulaw2lin=True)
|
||||
|
||||
print("Listening for new connections " f"from Asterisk on port {audiosocket.port}")
|
||||
username = os.environ["USERNAME"]
|
||||
|
||||
with open(os.environ["PASSWORD_FILE"], "r", encoding="utf-8") as f:
|
||||
password = f.read()
|
||||
|
||||
while True:
|
||||
call = audiosocket.listen()
|
||||
|
||||
call_thread = Thread(target=handle_connection, args=(call, username, password))
|
||||
call_thread.start()
|
||||
|
||||
call_thread.join()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
36
pkgs/myintercom-doorbell/myintercom_doorbell/open.py
Normal file
36
pkgs/myintercom-doorbell/myintercom_doorbell/open.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
import urllib3
|
||||
|
||||
|
||||
def open_door(host, username, password):
|
||||
urllib3.PoolManager().request(
|
||||
"GET",
|
||||
f"http://{host}/local/Doorcom/door.cgi?r=1",
|
||||
headers=urllib3.make_headers(basic_auth=f"{username}:{password}"),
|
||||
)
|
||||
|
||||
|
||||
def read_file_contents(file_name):
|
||||
with open(file_name, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def main():
|
||||
with open(
|
||||
"/etc/myintercom-doorbell/settings.json", "r", encoding="utf-8"
|
||||
) as config_file:
|
||||
config = json.load(config_file)
|
||||
|
||||
open_door(
|
||||
host=config["host"],
|
||||
username=config["username"],
|
||||
password=read_file_contents(config["passwordFile"]),
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
98
pkgs/myintercom-doorbell/myintercom_doorbell/service.py
Normal file
98
pkgs/myintercom-doorbell/myintercom_doorbell/service.py
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
import json
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import urllib3
|
||||
|
||||
import time
|
||||
|
||||
|
||||
def send_open_door_request(host, username, password):
|
||||
urllib3.PoolManager().request(
|
||||
"GET",
|
||||
f"http://{host}/local/Doorcom/door.cgi?r=1",
|
||||
headers=urllib3.make_headers(basic_auth=f"{username}:{password}"),
|
||||
)
|
||||
|
||||
|
||||
def get_ring_status(host, username, password):
|
||||
response = urllib3.PoolManager().request(
|
||||
"GET",
|
||||
f"http://{host}/local/Doorcom/monitor.cgi?ring=1",
|
||||
headers=urllib3.make_headers(basic_auth=f"{username}:{password}"),
|
||||
preload_content=False,
|
||||
decode_content=True,
|
||||
)
|
||||
|
||||
while True:
|
||||
line = response.readline()
|
||||
if line != b"--ioboundary\r\n":
|
||||
continue
|
||||
header = response.readline()
|
||||
if header != b"Content-Type: text/plain\r\n":
|
||||
continue
|
||||
if response.readline() != b"\r\n":
|
||||
continue
|
||||
data = []
|
||||
while True:
|
||||
line = response.readline()
|
||||
if line != b"\r\n":
|
||||
data.append(line.decode().rstrip())
|
||||
else:
|
||||
if data:
|
||||
yield data
|
||||
break
|
||||
|
||||
|
||||
def read_file_contents(file_name):
|
||||
with open(file_name, "r", encoding="utf-8") as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
def open_door():
|
||||
with open(
|
||||
"/etc/myintercom-doorbell/settings.json", "r", encoding="utf-8"
|
||||
) as config_file:
|
||||
config = json.load(config_file)
|
||||
|
||||
send_open_door_request(
|
||||
host=config["host"],
|
||||
username=config["username"],
|
||||
password=read_file_contents(config["passwordFile"]),
|
||||
)
|
||||
|
||||
|
||||
def poll():
|
||||
outgoing_dir = "/var/spool/asterisk/outgoing/"
|
||||
|
||||
with open(
|
||||
"/etc/myintercom-doorbell/settings.json", "r", encoding="utf-8"
|
||||
) as config_file:
|
||||
config = json.load(config_file)
|
||||
|
||||
audiosocket = f"{config['audiosocket']['address']}:{config['audiosocket']['port']}/{config['audiosocket']['uuid']}"
|
||||
callfile_content = (
|
||||
f"Channel: Audiosocket/{audiosocket}\n"
|
||||
"Context: doorbell\n"
|
||||
f"CallerID: {config['callerId']}\n"
|
||||
"Extension: s\n"
|
||||
"Priority: 1\n"
|
||||
)
|
||||
|
||||
while True:
|
||||
for status in get_ring_status(
|
||||
host=config["host"],
|
||||
username=config["username"],
|
||||
password=read_file_contents(config["passwordFile"]),
|
||||
):
|
||||
if status == ["1:H"]:
|
||||
print("ringing", flush=True)
|
||||
with tempfile.NamedTemporaryFile(dir="/var/tmp", mode="w") as f:
|
||||
f.write(callfile_content)
|
||||
os.chmod(f.name, 0o644)
|
||||
os.link(
|
||||
f.name, os.path.join(outgoing_dir, os.path.basename(f.name))
|
||||
)
|
||||
time.sleep(config["dialTime"])
|
||||
else:
|
||||
print(".", end="", flush=True)
|
||||
24
pkgs/myintercom-doorbell/poetry.lock
generated
Normal file
24
pkgs/myintercom-doorbell/poetry.lock
generated
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand.
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.0.7"
|
||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "urllib3-2.0.7-py3-none-any.whl", hash = "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e"},
|
||||
{file = "urllib3-2.0.7.tar.gz", hash = "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"]
|
||||
secure = ["certifi", "cryptography (>=1.9)", "idna (>=2.0.0)", "pyopenssl (>=17.1.0)", "urllib3-secure-extra"]
|
||||
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
|
||||
zstd = ["zstandard (>=0.18.0)"]
|
||||
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.10"
|
||||
content-hash = "cb8f26af67979881c24e243af0719b405141855256ced72c73b222b6c03d2bb8"
|
||||
20
pkgs/myintercom-doorbell/pyproject.toml
Normal file
20
pkgs/myintercom-doorbell/pyproject.toml
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
[tool.poetry]
|
||||
name = "myintercom-doorbell"
|
||||
version = "0.1.0"
|
||||
description = ""
|
||||
authors = ["Jakob Lechner <mail@jalr.de>"]
|
||||
readme = "README.md"
|
||||
packages = [{include = "myintercom_doorbell"}]
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
urllib3 = "^2.0.7"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
myintercom-doorbell-audiosocket = "myintercom_doorbell.myintercom_audiosocket:main"
|
||||
myintercom-doorbell-open-door = "myintercom_doorbell.service:open_door"
|
||||
myintercom-doorbell-poll = "myintercom_doorbell.service:poll"
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
8
pkgs/myintercom-doorbell/shell.nix
Normal file
8
pkgs/myintercom-doorbell/shell.nix
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
with import <nixpkgs> { };
|
||||
|
||||
mkShell {
|
||||
buildInputs = [
|
||||
poetry
|
||||
];
|
||||
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ let
|
|||
];
|
||||
};
|
||||
staticRoot = pkgs.pretix-static;
|
||||
environmentFile = pkgs.runCommand "pretix-environ" runCommandArgs ''
|
||||
environmentFile = pkgs.runCommand "pretix-environ" runCommandArgs (''
|
||||
cat > $out <<EOF
|
||||
DATA_DIR = /var/pretix
|
||||
DJANGO_SETTINGS_MODULE=pretix_wrapper.settings
|
||||
|
|
@ -50,9 +50,18 @@ let
|
|||
PRETIX_REDIS_LOCATION=redis://127.0.0.1:${toString redisPort}/0
|
||||
PRETIX_REDIS_SESSIONS=true
|
||||
PRETIX_STATIC_ROOT=${staticRoot}
|
||||
'' + (
|
||||
if cfg.mail.enable then
|
||||
''
|
||||
PRETIX_MAIL_FROM=${toString cfg.mail.from}
|
||||
PRETIX_MAIL_HOST="${cfg.mail.host}"
|
||||
PRETIX_MAIL_PORT=${toString cfg.mail.port}
|
||||
'' else ""
|
||||
) +
|
||||
''
|
||||
PYTHONPATH=$PYTHONPATH
|
||||
EOF
|
||||
'';
|
||||
'');
|
||||
mkTimer = { description, unit, onCalendar }: {
|
||||
inherit description;
|
||||
requires = [ "pretix-migrate.service" ];
|
||||
|
|
@ -66,7 +75,7 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
options.services.pretix = with lib; {
|
||||
options.services.pretix = with lib; with lib.types; {
|
||||
enable = mkEnableOption "Enable pretix ticket shop application";
|
||||
instanceName = mkOption {
|
||||
type = types.str;
|
||||
|
|
@ -74,7 +83,13 @@ in
|
|||
};
|
||||
domain = mkOption {
|
||||
type = types.str;
|
||||
description = "The installation’s domain";
|
||||
description = "The installation’s main domain";
|
||||
example = "pretix.example.net";
|
||||
};
|
||||
extraDomains = mkOption {
|
||||
type = listOf str;
|
||||
description = "A list of extra domains";
|
||||
default = [ ];
|
||||
};
|
||||
enableTls = mkEnableOption "Whether to use TLS or not";
|
||||
enableRegistration = mkEnableOption "Enables or disables the registration of new admin users.";
|
||||
|
|
@ -91,6 +106,30 @@ in
|
|||
type = types.path;
|
||||
description = "Path to the sops secrets file which stores pretix.cfg settings.";
|
||||
};
|
||||
mail = {
|
||||
enable = mkEnableOption "Enables or disables emailing.";
|
||||
from = mkOption {
|
||||
type = types.str;
|
||||
description = "The email address to set as From header in outgoing emails by the system.";
|
||||
};
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
description = "The SMTP Host to connect to.";
|
||||
default = "localhost";
|
||||
};
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
description = "The SMTP Port to connect to.";
|
||||
default = 25;
|
||||
};
|
||||
admins = mkOption {
|
||||
type = listOf str;
|
||||
description = ''
|
||||
Comma-separated list of email addresses that should receive a report about every error code 500 thrown by pretix.
|
||||
'';
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
banktool = {
|
||||
enable = mkEnableOption "Enable tool to query bank account and sync transaction data to pretix server.";
|
||||
days = mkOption {
|
||||
|
|
@ -124,7 +163,10 @@ in
|
|||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
virtualHosts."${cfg.domain}" = {
|
||||
virtualHosts = lib.listToAttrs (map
|
||||
(d: {
|
||||
name = d;
|
||||
value = {
|
||||
enableACME = cfg.enableTls;
|
||||
forceSSL = cfg.enableTls;
|
||||
kTLS = cfg.enableTls;
|
||||
|
|
@ -135,6 +177,9 @@ in
|
|||
${hstsHeader}
|
||||
'';
|
||||
};
|
||||
})
|
||||
([ cfg.domain ] ++ cfg.extraDomains)
|
||||
);
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
|
|
|
|||
1332
pkgs/pretix/poetry.lock
generated
1332
pkgs/pretix/poetry.lock
generated
File diff suppressed because it is too large
Load diff
|
|
@ -8,7 +8,7 @@ let
|
|||
nodeEnv = buildNpmPackage rec {
|
||||
name = "pretix-nodejs";
|
||||
src = "${pretix.passthru.pythonModule.pkgs.pretix}/lib/python3.10/site-packages/pretix/static/npm_dir";
|
||||
npmDepsHash = "sha256-wMzi48h4SFsGKi/s7FujJtsAtj8pRQX3nVo8WC0UqPY=";
|
||||
npmDepsHash = "sha256-TWRYNYku+p9w2tiyDFun2HwI69/+g+lqzvfqJqPCwiE=";
|
||||
dontNpmBuild = true;
|
||||
installPhase = ''
|
||||
mkdir -p $out
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ license = "MIT"
|
|||
|
||||
[tool.poetry.dependencies]
|
||||
python = "^3.10"
|
||||
pretix = "^2023.6.0"
|
||||
pretix = "^2023.9.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
|
||||
|
|
|
|||
30
pkgs/wofi-bluetooth/wofi-bluetooth.nix
Normal file
30
pkgs/wofi-bluetooth/wofi-bluetooth.nix
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
{ lib
|
||||
, stdenv
|
||||
, makeWrapper
|
||||
, bluez
|
||||
, wofi
|
||||
, rofi-bluetooth
|
||||
}:
|
||||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "wofi-bluetooth";
|
||||
version = rofi-bluetooth.version;
|
||||
src = rofi-bluetooth.src;
|
||||
patches = [
|
||||
./wofi-bluetooth.patch
|
||||
];
|
||||
buildInputs = [ wofi ];
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
install -D --target-directory=$out/bin/ ./rofi-bluetooth
|
||||
|
||||
mv $out/bin/rofi-bluetooth $out/bin/wofi-bluetooth
|
||||
|
||||
wrapProgram $out/bin/wofi-bluetooth \
|
||||
--prefix PATH ":" ${lib.makeBinPath [ bluez wofi ] }
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
}
|
||||
68
pkgs/wofi-bluetooth/wofi-bluetooth.patch
Normal file
68
pkgs/wofi-bluetooth/wofi-bluetooth.patch
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
--- a/rofi-bluetooth
|
||||
+++ b/rofi-bluetooth
|
||||
@@ -7,14 +7,14 @@
|
||||
#
|
||||
# Author: Nick Clyde (clydedroid)
|
||||
#
|
||||
-# A script that generates a rofi menu that uses bluetoothctl to
|
||||
+# A script that generates a wofi menu that uses bluetoothctl to
|
||||
# connect to bluetooth devices and display status info.
|
||||
#
|
||||
# Inspired by networkmanager-dmenu (https://github.com/firecat53/networkmanager-dmenu)
|
||||
# Thanks to x70b1 (https://github.com/polybar/polybar-scripts/tree/master/polybar-scripts/system-bluetooth-bluetoothctl)
|
||||
#
|
||||
# Depends on:
|
||||
-# Arch repositories: rofi, bluez-utils (contains bluetoothctl)
|
||||
+# Arch repositories: wofi, bluez-utils (contains bluetoothctl)
|
||||
|
||||
# Constants
|
||||
divider="---------"
|
||||
@@ -231,8 +231,8 @@
|
||||
trusted=$(device_trusted "$mac")
|
||||
options="$connected\n$paired\n$trusted\n$divider\n$goback\nExit"
|
||||
|
||||
- # Open rofi menu, read chosen option
|
||||
- chosen="$(echo -e "$options" | $rofi_command "$device_name")"
|
||||
+ # Open wofi menu, read chosen option
|
||||
+ chosen="$(echo -e "$options" | $wofi_command "$device_name")"
|
||||
|
||||
# Match chosen option to command
|
||||
case "$chosen" in
|
||||
@@ -254,7 +254,7 @@
|
||||
esac
|
||||
}
|
||||
|
||||
-# Opens a rofi menu with current bluetooth status and options to connect
|
||||
+# Opens a wofi menu with current bluetooth status and options to connect
|
||||
show_menu() {
|
||||
# Get menu options
|
||||
if power_on; then
|
||||
@@ -269,15 +269,16 @@
|
||||
pairable=$(pairable_on)
|
||||
discoverable=$(discoverable_on)
|
||||
|
||||
- # Options passed to rofi
|
||||
+ # Options passed to wofi
|
||||
options="$devices\n$divider\n$power\n$scan\n$pairable\n$discoverable\nExit"
|
||||
else
|
||||
power="Power: off"
|
||||
options="$power\nExit"
|
||||
fi
|
||||
|
||||
- # Open rofi menu, read chosen option
|
||||
- chosen="$(echo -e "$options" | $rofi_command "Bluetooth")"
|
||||
+ lines="$(echo -e "$options" | wc -l)"
|
||||
+ # Open wofi menu, read chosen option
|
||||
+ chosen="$(echo -e "$options" | $wofi_command "Bluetooth" -L "$lines")"
|
||||
|
||||
# Match chosen option to command
|
||||
case "$chosen" in
|
||||
@@ -305,7 +306,7 @@
|
||||
}
|
||||
|
||||
# Rofi command to pipe into, can add any options here
|
||||
-rofi_command="rofi -dmenu $* -p"
|
||||
+wofi_command="wofi -d -i -p"
|
||||
|
||||
case "$1" in
|
||||
--status)
|
||||
Loading…
Add table
Add a link
Reference in a new issue