Refactoring
This commit is contained in:
parent
209526d7c0
commit
8e8041e423
51 changed files with 1414 additions and 1368 deletions
|
|
@ -8,9 +8,9 @@ let
|
|||
)
|
||||
)
|
||||
);
|
||||
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));
|
||||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ let
|
|||
)
|
||||
)
|
||||
);
|
||||
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));
|
||||
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
|
||||
{
|
||||
|
|
|
|||
56
flake.nix
56
flake.nix
|
|
@ -5,24 +5,34 @@
|
|||
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
|
||||
gomod2nix.inputs.flake-utils.follows = "flake-utils";
|
||||
gomod2nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
gomod2nix.url = "github:nix-community/gomod2nix";
|
||||
gomod2nix = {
|
||||
url = "github:nix-community/gomod2nix";
|
||||
inputs.flake-utils.follows = "flake-utils";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
||||
home-manager.url = "github:nix-community/home-manager/release-24.11";
|
||||
home-manager = {
|
||||
url = "github:nix-community/home-manager/release-24.11";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
impermanence.url = "github:nix-community/impermanence";
|
||||
|
||||
krops.inputs.flake-utils.follows = "flake-utils";
|
||||
krops.inputs.nixpkgs.follows = "nixpkgs";
|
||||
krops.url = "github:Mic92/krops";
|
||||
krops = {
|
||||
url = "github:Mic92/krops";
|
||||
inputs.flake-utils.follows = "flake-utils";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
lanzaboote.url = "github:nix-community/lanzaboote/v0.4.1";
|
||||
lanzaboote.inputs.nixpkgs.follows = "nixpkgs";
|
||||
lanzaboote = {
|
||||
url = "github:nix-community/lanzaboote/v0.4.1";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nix-pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs";
|
||||
nix-pre-commit-hooks.url = "github:cachix/git-hooks.nix/master";
|
||||
nix-pre-commit-hooks = {
|
||||
url = "github:cachix/git-hooks.nix/master";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
nixos-hardware.url = "github:nixos/nixos-hardware/master";
|
||||
|
||||
|
|
@ -32,12 +42,16 @@
|
|||
|
||||
nur.url = "github:nix-community/NUR";
|
||||
|
||||
poetry2nix.inputs.flake-utils.follows = "flake-utils";
|
||||
poetry2nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
poetry2nix.url = "github:nix-community/poetry2nix";
|
||||
poetry2nix = {
|
||||
url = "github:nix-community/poetry2nix";
|
||||
inputs.flake-utils.follows = "flake-utils";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
|
||||
sops-nix.inputs.nixpkgs.follows = "nixpkgs";
|
||||
sops-nix.url = "github:Mic92/sops-nix";
|
||||
sops-nix = {
|
||||
url = "github:Mic92/sops-nix";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
};
|
||||
outputs =
|
||||
{ self
|
||||
|
|
@ -74,14 +88,14 @@
|
|||
};
|
||||
};
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = (with pkgs; [
|
||||
buildInputs = with pkgs; [
|
||||
black
|
||||
just
|
||||
nixpkgs-fmt
|
||||
shellcheck
|
||||
sops
|
||||
ssh-to-age
|
||||
]);
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
${self.checks.${system}.pre-commit-check.shellHook}
|
||||
|
|
@ -159,8 +173,8 @@
|
|||
|
||||
{
|
||||
_module.args = {
|
||||
inputs = inputs;
|
||||
custom-utils = import ./custom-utils { lib = nixpkgs.lib; };
|
||||
inherit inputs;
|
||||
custom-utils = import ./custom-utils { inherit (nixpkgs) lib; };
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@
|
|||
./services
|
||||
];
|
||||
|
||||
networking.hostName = "aluminium";
|
||||
services.openssh.enable = true;
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
networking = {
|
||||
hostName = "aluminium";
|
||||
useDHCP = false;
|
||||
vlans = {
|
||||
lechner = {
|
||||
|
|
@ -78,6 +78,15 @@
|
|||
iifname "voice" udp dport 5059 accept
|
||||
ip saddr 217.10.68.150 udp dport 5060 accept
|
||||
'';
|
||||
nftables.tables.pppoe = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain clamp {
|
||||
type filter hook forward priority mangle;
|
||||
oifname "ppp0" tcp flags syn tcp option maxseg size set rt mtu comment "clamp MSS to Path MTU"
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -116,16 +125,6 @@
|
|||
};
|
||||
};
|
||||
|
||||
networking.nftables.tables.pppoe = {
|
||||
family = "ip";
|
||||
content = ''
|
||||
chain clamp {
|
||||
type filter hook forward priority mangle;
|
||||
oifname "ppp0" tcp flags syn tcp option maxseg size set rt mtu comment "clamp MSS to Path MTU"
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
zramSwap = {
|
||||
enable = true;
|
||||
algorithm = "zstd";
|
||||
|
|
|
|||
|
|
@ -14,21 +14,6 @@ let
|
|||
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 = {
|
||||
|
|
@ -169,12 +154,12 @@ in
|
|||
useTheseDefaultConfFiles = [ ];
|
||||
};
|
||||
|
||||
sops.secrets = (lib.listToAttrs (map
|
||||
sops.secrets = lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "asterisk-${name}" {
|
||||
sopsFile = ../../secrets.yaml;
|
||||
owner = config.users.users.asterisk.name;
|
||||
})
|
||||
secretConfigFiles));
|
||||
secretConfigFiles);
|
||||
environment.etc = lib.mapAttrs'
|
||||
(name: _: lib.nameValuePair
|
||||
"asterisk/${name}.conf"
|
||||
|
|
@ -194,84 +179,99 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
systemd.services."asterisk-reload-endpoint@" = {
|
||||
description = "Check if asterisk endpoint is identified and reload it when it is not.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
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
|
||||
'';
|
||||
};
|
||||
environment = {
|
||||
ENDPOINT = "%I";
|
||||
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;
|
||||
};
|
||||
};
|
||||
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
|
||||
'';
|
||||
};
|
||||
"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)"
|
||||
|
||||
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";
|
||||
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.services."asterisk-voicemail-call@" = {
|
||||
description = "Check if voicemail exists and place a call to the voicemail application.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
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";
|
||||
};
|
||||
};
|
||||
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";
|
||||
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";
|
||||
};
|
||||
};
|
||||
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";
|
||||
};
|
||||
};
|
||||
};
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,8 +78,8 @@ in
|
|||
unit_system = "metric";
|
||||
time_zone = "Europe/Berlin";
|
||||
temperature_unit = "C";
|
||||
longitude = config.location.longitude;
|
||||
latitude = config.location.latitude;
|
||||
inherit (config.location) longitude;
|
||||
inherit (config.location) latitude;
|
||||
};
|
||||
default_config = { };
|
||||
"automation nix" = [
|
||||
|
|
|
|||
|
|
@ -8,8 +8,6 @@
|
|||
./services
|
||||
];
|
||||
|
||||
services.fstrim.enable = true;
|
||||
|
||||
networking = {
|
||||
hostName = "copper";
|
||||
extraHosts = lib.concatStringsSep "\n" (
|
||||
|
|
@ -32,24 +30,28 @@
|
|||
priority = 1;
|
||||
};
|
||||
|
||||
services.snapper.configs = {
|
||||
home = {
|
||||
SUBVOLUME = "/home";
|
||||
ALLOW_USERS = [ "jalr" ];
|
||||
TIMELINE_CREATE = true;
|
||||
TIMELINE_CLEANUP = true;
|
||||
TIMELINE_LIMIT_HOURLY = 12;
|
||||
TIMELINE_LIMIT_DAILY = 7;
|
||||
TIMELINE_LIMIT_WEEKLY = 4;
|
||||
TIMELINE_LIMIT_MONTHLY = 3;
|
||||
TIMELINE_LIMIT_YEARLY = 0;
|
||||
BACKGROUND_COMPARISON = "yes";
|
||||
NUMBER_CLEANUP = "no";
|
||||
NUMBER_MIN_AGE = "1800";
|
||||
NUMBER_LIMIT = "100";
|
||||
NUMBER_LIMIT_IMPORTANT = "10";
|
||||
EMPTY_PRE_POST_CLEANUP = "yes";
|
||||
EMPTY_PRE_POST_MIN_AGE = "1800";
|
||||
services = {
|
||||
fstrim.enable = true;
|
||||
flatpak.enable = true;
|
||||
snapper.configs = {
|
||||
home = {
|
||||
SUBVOLUME = "/home";
|
||||
ALLOW_USERS = [ "jalr" ];
|
||||
TIMELINE_CREATE = true;
|
||||
TIMELINE_CLEANUP = true;
|
||||
TIMELINE_LIMIT_HOURLY = 12;
|
||||
TIMELINE_LIMIT_DAILY = 7;
|
||||
TIMELINE_LIMIT_WEEKLY = 4;
|
||||
TIMELINE_LIMIT_MONTHLY = 3;
|
||||
TIMELINE_LIMIT_YEARLY = 0;
|
||||
BACKGROUND_COMPARISON = "yes";
|
||||
NUMBER_CLEANUP = "no";
|
||||
NUMBER_MIN_AGE = "1800";
|
||||
NUMBER_LIMIT = "100";
|
||||
NUMBER_LIMIT_IMPORTANT = "10";
|
||||
EMPTY_PRE_POST_CLEANUP = "yes";
|
||||
EMPTY_PRE_POST_MIN_AGE = "1800";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -68,7 +70,5 @@
|
|||
};
|
||||
|
||||
system.stateVersion = "24.05";
|
||||
|
||||
services.flatpak.enable = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }@inputs:
|
||||
inputs:
|
||||
let
|
||||
hardware = inputs.nixos-hardware.nixosModules;
|
||||
in
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ let
|
|||
luksDev = "-part3";
|
||||
biosBoot = "-part4";
|
||||
};
|
||||
efiSystemPartitions = (map (diskName: diskName + partitionScheme.efiBoot) (lib.attrValues disks));
|
||||
efiSystemPartitions = map (diskName: diskName + partitionScheme.efiBoot) (lib.attrValues disks);
|
||||
in
|
||||
with lib; {
|
||||
imports = [
|
||||
|
|
@ -154,19 +154,19 @@ with lib; {
|
|||
};
|
||||
supportedFilesystems = [ "zfs" ];
|
||||
zfs = {
|
||||
devNodes = devNodes;
|
||||
inherit devNodes;
|
||||
forceImportRoot = false;
|
||||
};
|
||||
loader = {
|
||||
efi = {
|
||||
canTouchEfiVariables = (if removableEfi then false else true);
|
||||
efiSysMountPoint = ("/boot/efis/" + (head (lib.attrValues disks))
|
||||
+ partitionScheme.efiBoot);
|
||||
canTouchEfiVariables = if removableEfi then false else true;
|
||||
efiSysMountPoint = "/boot/efis/" + (head (lib.attrValues disks))
|
||||
+ partitionScheme.efiBoot;
|
||||
};
|
||||
generationsDir.copyKernels = true;
|
||||
grub = {
|
||||
enable = true;
|
||||
devices = (map (diskName: devNodes + diskName) (attrValues disks));
|
||||
devices = map (diskName: devNodes + diskName) (attrValues disks);
|
||||
efiInstallAsRemovable = removableEfi;
|
||||
copyKernels = true;
|
||||
efiSupport = true;
|
||||
|
|
@ -176,11 +176,11 @@ with lib; {
|
|||
terminal_input --append serial
|
||||
terminal_output --append serial
|
||||
'';
|
||||
extraInstallCommands = (toString (map
|
||||
extraInstallCommands = toString (map
|
||||
(diskName: ''
|
||||
${pkgs.coreutils-full}/bin/cp -r ${config.boot.loader.efi.efiSysMountPoint}/EFI /boot/efis/${diskName}${partitionScheme.efiBoot}
|
||||
'')
|
||||
(tail (attrValues disks))));
|
||||
(tail (attrValues disks)));
|
||||
};
|
||||
};
|
||||
kernelParams = [
|
||||
|
|
|
|||
|
|
@ -6,11 +6,13 @@ in
|
|||
services.avahi = {
|
||||
enable = true;
|
||||
allowInterfaces = [ interfaces.lan ];
|
||||
publish.domain = true;
|
||||
publish.enable = true;
|
||||
publish.userServices = true;
|
||||
publish.workstation = true;
|
||||
openFirewall = false;
|
||||
publish = {
|
||||
domain = true;
|
||||
enable = true;
|
||||
userServices = true;
|
||||
workstation = true;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces."${interfaces.lan}".allowedUDPPorts = [
|
||||
|
|
|
|||
|
|
@ -8,23 +8,29 @@ in
|
|||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
|
||||
services.calibre-server = {
|
||||
enable = true;
|
||||
port = ports.calibre-server.tcp;
|
||||
host = "127.0.0.1";
|
||||
};
|
||||
|
||||
services.calibre-web = {
|
||||
enable = true;
|
||||
user = config.services.calibre-server.user;
|
||||
group = config.services.calibre-server.group;
|
||||
listen = {
|
||||
ip = "127.0.0.1";
|
||||
port = ports.calibre-web.tcp;
|
||||
services = {
|
||||
calibre-server = {
|
||||
enable = true;
|
||||
port = ports.calibre-server.tcp;
|
||||
host = "127.0.0.1";
|
||||
};
|
||||
|
||||
calibre-web = {
|
||||
enable = true;
|
||||
inherit (config.services.calibre-server) user;
|
||||
inherit (config.services.calibre-server) group;
|
||||
listen = {
|
||||
ip = "127.0.0.1";
|
||||
port = ports.calibre-web.tcp;
|
||||
};
|
||||
options = {
|
||||
enableBookUploading = true;
|
||||
reverseProxyAuth = {
|
||||
enable = true;
|
||||
header = "X-Remote-User";
|
||||
};
|
||||
};
|
||||
};
|
||||
options.enableBookUploading = true;
|
||||
options.reverseProxyAuth.enable = true;
|
||||
options.reverseProxyAuth.header = "X-Remote-User";
|
||||
};
|
||||
|
||||
systemd.services.calibre-web = {
|
||||
|
|
|
|||
|
|
@ -5,256 +5,264 @@ let
|
|||
domain = "hass.jalr.de";
|
||||
in
|
||||
{
|
||||
sops.secrets.home-assistant = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = "root";
|
||||
group = "hass";
|
||||
mode = "0640";
|
||||
};
|
||||
sops.secrets."mqtt-users/home-assistant" = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
sops.secrets."mqtt-users/valetudo" = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
services.home-assistant = {
|
||||
enable = true;
|
||||
lovelaceConfig = {
|
||||
title = "Home";
|
||||
views = [
|
||||
{
|
||||
path = "default_view";
|
||||
title = "Home";
|
||||
cards = [
|
||||
{
|
||||
title = "Eingang";
|
||||
type = "entities";
|
||||
entities = [
|
||||
{
|
||||
entity = "light.eingang_deckenleuchte_deckenleuchte";
|
||||
name = "Deckenleuchte";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "Esstisch";
|
||||
type = "entities";
|
||||
entities = [
|
||||
{
|
||||
entity = "light.yeelight_meteorite_ambient_light";
|
||||
name = "Ambient light";
|
||||
}
|
||||
{
|
||||
entity = "light.yeelight_meteorite_ceiling_light";
|
||||
name = "Ceiling light";
|
||||
}
|
||||
{
|
||||
entity = "light.yeelight_meteorite_night_light";
|
||||
name = "Night light";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
sops.secrets = {
|
||||
home-assistant = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
owner = "root";
|
||||
group = "hass";
|
||||
mode = "0640";
|
||||
};
|
||||
extraComponents = [
|
||||
# See https://www.home-assistant.io/integrations
|
||||
"bthome"
|
||||
"caldav"
|
||||
"esphome"
|
||||
"local_todo"
|
||||
"openweathermap"
|
||||
"wyoming"
|
||||
"xiaomi_ble"
|
||||
"vlc_telnet"
|
||||
];
|
||||
customComponents = with pkgs.home-assistant-custom-components; [
|
||||
adaptive_lighting
|
||||
];
|
||||
customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [
|
||||
valetudo-map-card
|
||||
];
|
||||
lovelaceConfigWritable = false;
|
||||
configWritable = false;
|
||||
config = {
|
||||
http = {
|
||||
server_host = [ "127.0.0.1" ];
|
||||
server_port = ports.home-assistant.tcp;
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [ "127.0.0.1" ];
|
||||
};
|
||||
homeassistant = {
|
||||
unit_system = "metric";
|
||||
time_zone = "Europe/Berlin";
|
||||
temperature_unit = "C";
|
||||
longitude = config.location.longitude;
|
||||
latitude = config.location.latitude;
|
||||
external_url = "https://${domain}/";
|
||||
internal_url = "https://${domain}/";
|
||||
};
|
||||
default_config = { };
|
||||
adaptive_lighting = {
|
||||
lights = [
|
||||
"light.yeelight_meteorite_ceiling_light"
|
||||
"light.eingang_deckenleuchte_deckenleuchte"
|
||||
"light.led_panel_schreibtisch_panel"
|
||||
"light.kueche_leiste_led_light"
|
||||
"light.badspiegel_background_light"
|
||||
"light.badspiegel_front_light"
|
||||
"mqtt-users/home-assistant" = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
"mqtt-users/valetudo" = {
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.interfaces = {
|
||||
"${interfaces.lan}".allowedTCPPorts = [ ports.mqtt.tcp ];
|
||||
iot.allowedTCPPorts = [ ports.mqtt.tcp ];
|
||||
};
|
||||
|
||||
services = {
|
||||
home-assistant = {
|
||||
enable = true;
|
||||
lovelaceConfig = {
|
||||
title = "Home";
|
||||
views = [
|
||||
{
|
||||
path = "default_view";
|
||||
title = "Home";
|
||||
cards = [
|
||||
{
|
||||
title = "Eingang";
|
||||
type = "entities";
|
||||
entities = [
|
||||
{
|
||||
entity = "light.eingang_deckenleuchte_deckenleuchte";
|
||||
name = "Deckenleuchte";
|
||||
}
|
||||
];
|
||||
}
|
||||
{
|
||||
name = "Esstisch";
|
||||
type = "entities";
|
||||
entities = [
|
||||
{
|
||||
entity = "light.yeelight_meteorite_ambient_light";
|
||||
name = "Ambient light";
|
||||
}
|
||||
{
|
||||
entity = "light.yeelight_meteorite_ceiling_light";
|
||||
name = "Ceiling light";
|
||||
}
|
||||
{
|
||||
entity = "light.yeelight_meteorite_night_light";
|
||||
name = "Night light";
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
};
|
||||
"automation nix" = [
|
||||
{
|
||||
alias = "Waschmaschine fertig Benachrichtigung";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "sensor.waschmaschine_aktueller_vorgang";
|
||||
to = "Knitterschutz/Ende";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "notify.mobile_app_shift6mq";
|
||||
data = {
|
||||
message = "Die Waschmaschine hat das Programm beendet.";
|
||||
title = "Wäsche fertig";
|
||||
};
|
||||
}
|
||||
extraComponents = [
|
||||
# See https://www.home-assistant.io/integrations
|
||||
"bthome"
|
||||
"caldav"
|
||||
"esphome"
|
||||
"local_todo"
|
||||
"openweathermap"
|
||||
"wyoming"
|
||||
"xiaomi_ble"
|
||||
"vlc_telnet"
|
||||
];
|
||||
customComponents = with pkgs.home-assistant-custom-components; [
|
||||
adaptive_lighting
|
||||
];
|
||||
customLovelaceModules = with pkgs.home-assistant-custom-lovelace-modules; [
|
||||
valetudo-map-card
|
||||
];
|
||||
lovelaceConfigWritable = false;
|
||||
configWritable = false;
|
||||
config = {
|
||||
http = {
|
||||
server_host = [ "127.0.0.1" ];
|
||||
server_port = ports.home-assistant.tcp;
|
||||
use_x_forwarded_for = true;
|
||||
trusted_proxies = [ "127.0.0.1" ];
|
||||
};
|
||||
homeassistant = {
|
||||
unit_system = "metric";
|
||||
time_zone = "Europe/Berlin";
|
||||
temperature_unit = "C";
|
||||
inherit (config.location) longitude;
|
||||
inherit (config.location) latitude;
|
||||
external_url = "https://${domain}/";
|
||||
internal_url = "https://${domain}/";
|
||||
};
|
||||
default_config = { };
|
||||
adaptive_lighting = {
|
||||
lights = [
|
||||
"light.yeelight_meteorite_ceiling_light"
|
||||
"light.eingang_deckenleuchte_deckenleuchte"
|
||||
"light.led_panel_schreibtisch_panel"
|
||||
"light.kueche_leiste_led_light"
|
||||
"light.badspiegel_background_light"
|
||||
"light.badspiegel_front_light"
|
||||
];
|
||||
}
|
||||
];
|
||||
"automation ui" = "!include automations.yaml";
|
||||
"scene nix" = [
|
||||
];
|
||||
"scene ui" = "!include scenes.yaml";
|
||||
bluetooth = { };
|
||||
device_tracker = [
|
||||
{
|
||||
platform = "bluetooth_le_tracker";
|
||||
}
|
||||
];
|
||||
"script nix" = [
|
||||
{
|
||||
lights_off_except = {
|
||||
icon = "mdi:home-lightbulb";
|
||||
fields.exclude_lights.description = "Excluded lights as list";
|
||||
sequence = [
|
||||
};
|
||||
"automation nix" = [
|
||||
{
|
||||
alias = "Waschmaschine fertig Benachrichtigung";
|
||||
trigger = {
|
||||
platform = "state";
|
||||
entity_id = "sensor.waschmaschine_aktueller_vorgang";
|
||||
to = "Knitterschutz/Ende";
|
||||
};
|
||||
action = [
|
||||
{
|
||||
service = "logbook.log";
|
||||
data_template = {
|
||||
entity_id = "script.turn_off_lights";
|
||||
name = "Exclude log";
|
||||
message = "Turning of all lights except: {{ exclude_lights }}";
|
||||
service = "notify.mobile_app_shift6mq";
|
||||
data = {
|
||||
message = "Die Waschmaschine hat das Programm beendet.";
|
||||
title = "Wäsche fertig";
|
||||
};
|
||||
}
|
||||
{
|
||||
service = "light.turn_off";
|
||||
data_template.entity_id = ''
|
||||
{{ states.light | rejectattr('entity_id', 'in', exclude_lights) | rejectattr('state', 'in', 'off') | join(',', attribute='entity_id') }}
|
||||
'';
|
||||
}
|
||||
];
|
||||
}
|
||||
];
|
||||
"automation ui" = "!include automations.yaml";
|
||||
"scene nix" = [
|
||||
];
|
||||
"scene ui" = "!include scenes.yaml";
|
||||
bluetooth = { };
|
||||
device_tracker = [
|
||||
{
|
||||
platform = "bluetooth_le_tracker";
|
||||
}
|
||||
];
|
||||
"script nix" = [
|
||||
{
|
||||
lights_off_except = {
|
||||
icon = "mdi:home-lightbulb";
|
||||
fields.exclude_lights.description = "Excluded lights as list";
|
||||
sequence = [
|
||||
{
|
||||
service = "logbook.log";
|
||||
data_template = {
|
||||
entity_id = "script.turn_off_lights";
|
||||
name = "Exclude log";
|
||||
message = "Turning of all lights except: {{ exclude_lights }}";
|
||||
};
|
||||
}
|
||||
{
|
||||
service = "light.turn_off";
|
||||
data_template.entity_id = ''
|
||||
{{ states.light | rejectattr('entity_id', 'in', exclude_lights) | rejectattr('state', 'in', 'off') | join(',', attribute='entity_id') }}
|
||||
'';
|
||||
}
|
||||
];
|
||||
};
|
||||
}
|
||||
];
|
||||
"script ui" = "!include scripts.yaml";
|
||||
calendar = [
|
||||
{
|
||||
platform = "caldav";
|
||||
username = "jalr@jalr.de";
|
||||
password = "!secret radicale";
|
||||
url = "https://cal.jalr.de/radicale";
|
||||
}
|
||||
];
|
||||
mqtt = { };
|
||||
media_player = [
|
||||
{
|
||||
platform = "mpd";
|
||||
name = "mpd@iron";
|
||||
host = "127.0.0.1";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
mosquitto = {
|
||||
enable = true;
|
||||
persistence = true;
|
||||
listeners = [
|
||||
{
|
||||
port = ports.mqtt.tcp;
|
||||
users = {
|
||||
valetudo = {
|
||||
passwordFile = config.sops.secrets."mqtt-users/valetudo".path;
|
||||
acl = [
|
||||
"readwrite homeassistant/+/donald/#"
|
||||
"readwrite valetudo/donald/#"
|
||||
];
|
||||
};
|
||||
home-assistant = {
|
||||
passwordFile = config.sops.secrets."mqtt-users/home-assistant".path;
|
||||
acl = [ "readwrite #" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
"script ui" = "!include scripts.yaml";
|
||||
calendar = [
|
||||
{
|
||||
platform = "caldav";
|
||||
username = "jalr@jalr.de";
|
||||
password = "!secret radicale";
|
||||
url = "https://cal.jalr.de/radicale";
|
||||
}
|
||||
];
|
||||
mqtt = { };
|
||||
media_player = [
|
||||
{
|
||||
platform = "mpd";
|
||||
name = "mpd@iron";
|
||||
host = "127.0.0.1";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.mosquitto = {
|
||||
enable = true;
|
||||
persistence = true;
|
||||
listeners = [
|
||||
{
|
||||
port = ports.mqtt.tcp;
|
||||
users = {
|
||||
valetudo = {
|
||||
passwordFile = config.sops.secrets."mqtt-users/valetudo".path;
|
||||
acl = [
|
||||
"readwrite homeassistant/+/donald/#"
|
||||
"readwrite valetudo/donald/#"
|
||||
];
|
||||
};
|
||||
home-assistant = {
|
||||
passwordFile = config.sops.secrets."mqtt-users/home-assistant".path;
|
||||
acl = [ "readwrite #" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
systemd.services = {
|
||||
home-assistant.serviceConfig.ExecStartPre = [
|
||||
(
|
||||
pkgs.writeShellScript "home-assistant-secrets" ''
|
||||
ln -sf "${config.sops.secrets.home-assistant.path}" "${config.services.home-assistant.configDir}/secrets.yaml"
|
||||
''
|
||||
)
|
||||
];
|
||||
};
|
||||
|
||||
systemd.services.hass-vlc = {
|
||||
script = ''
|
||||
exec ${pkgs.vlc}/bin/cvlc \
|
||||
--no-video \
|
||||
-I telnet \
|
||||
--telnet-password=vlc \
|
||||
--sout='#transcode{acodec=s16le,channels=2,samplerate=48000}:std{access=file,mux=raw,dst=/run/snapserver/hass.fifo}' \
|
||||
--aout=none
|
||||
'';
|
||||
wants = [ "snapserver.service" ];
|
||||
after = [ "snapserver.service" ];
|
||||
serviceConfig = {
|
||||
BindPaths = [ "/run/snapserver/hass.fifo" ];
|
||||
BindReadOnlyPaths = [ "/nix/store" "/etc/ssl/certs" "/etc/static/ssl/certs" ];
|
||||
CapabilityBoundingSet = "";
|
||||
DynamicUser = "true";
|
||||
Group = "snapserver";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = lib.mkForce true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RootDirectory = "/run/hass-vlc";
|
||||
RuntimeDirectory = "hass-vlc";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
hass-vlc = {
|
||||
script = ''
|
||||
exec ${pkgs.vlc}/bin/cvlc \
|
||||
--no-video \
|
||||
-I telnet \
|
||||
--telnet-password=vlc \
|
||||
--sout='#transcode{acodec=s16le,channels=2,samplerate=48000}:std{access=file,mux=raw,dst=/run/snapserver/hass.fifo}' \
|
||||
--aout=none
|
||||
'';
|
||||
wants = [ "snapserver.service" ];
|
||||
after = [ "snapserver.service" ];
|
||||
serviceConfig = {
|
||||
BindPaths = [ "/run/snapserver/hass.fifo" ];
|
||||
BindReadOnlyPaths = [ "/nix/store" "/etc/ssl/certs" "/etc/static/ssl/certs" ];
|
||||
CapabilityBoundingSet = "";
|
||||
DynamicUser = "true";
|
||||
Group = "snapserver";
|
||||
LockPersonality = true;
|
||||
MemoryDenyWriteExecute = true;
|
||||
NoNewPrivileges = true;
|
||||
PrivateDevices = lib.mkForce true;
|
||||
PrivateUsers = true;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHome = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
ProtectProc = "noaccess";
|
||||
ProtectSystem = "strict";
|
||||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ];
|
||||
RestrictNamespaces = true;
|
||||
RestrictRealtime = true;
|
||||
RestrictSUIDSGID = true;
|
||||
RootDirectory = "/run/hass-vlc";
|
||||
RuntimeDirectory = "hass-vlc";
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [ "@system-service" "~@privileged" ];
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
|
||||
networking.firewall.interfaces."${interfaces.lan}".allowedTCPPorts = [ ports.mqtt.tcp ];
|
||||
networking.firewall.interfaces.iot.allowedTCPPorts = [ ports.mqtt.tcp ];
|
||||
|
||||
systemd.services.home-assistant.serviceConfig.ExecStartPre = [
|
||||
(
|
||||
pkgs.writeShellScript "home-assistant-secrets" ''
|
||||
ln -sf "${config.sops.secrets.home-assistant.path}" "${config.services.home-assistant.configDir}/secrets.yaml"
|
||||
''
|
||||
)
|
||||
];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"f ${config.services.home-assistant.configDir}/automations.yaml 0755 hass hass"
|
||||
"f ${config.services.home-assistant.configDir}/scenes.yaml 0755 hass hass"
|
||||
|
|
|
|||
|
|
@ -13,27 +13,27 @@ let
|
|||
};
|
||||
in
|
||||
{
|
||||
sops.secrets = (
|
||||
lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "wireguard_key_${name}" {
|
||||
sopsFile = ../secrets.yaml;
|
||||
})
|
||||
[
|
||||
"hetzner-ha"
|
||||
]
|
||||
)
|
||||
sops.secrets = lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "wireguard_key_${name}" {
|
||||
sopsFile = ../secrets.yaml;
|
||||
})
|
||||
[
|
||||
"hetzner-ha"
|
||||
]
|
||||
);
|
||||
|
||||
networking.iproute2.enable = true;
|
||||
networking.iproute2.rttablesExtraConfig = ''
|
||||
${toString rtTable.id} ${rtTable.name}
|
||||
'';
|
||||
|
||||
networking.wireguard.interfaces = {
|
||||
hetzner-ha = {
|
||||
networking = {
|
||||
iproute2 = {
|
||||
enable = true;
|
||||
rttablesExtraConfig = ''
|
||||
${toString rtTable.id} ${rtTable.name}
|
||||
'';
|
||||
};
|
||||
firewall.allowedUDPPorts = [ listenPort ];
|
||||
wireguard.interfaces.hetzner-ha = {
|
||||
ips = [ "${externalIp}/32" ];
|
||||
privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path;
|
||||
listenPort = listenPort;
|
||||
inherit listenPort;
|
||||
table = rtTable.name;
|
||||
postSetup = ''
|
||||
${pkgs.iproute2}/bin/ip rule add from ${externalIp} to 192.168.0.0/16 table main priority 10
|
||||
|
|
@ -44,7 +44,7 @@ in
|
|||
${pkgs.iproute2}/bin/ip rule del from ${externalIp} table ${rtTable.name} priority 20
|
||||
'';
|
||||
peers = [{
|
||||
publicKey = publicKey;
|
||||
inherit publicKey;
|
||||
endpoint = "${remoteHost}:${toString remotePort}";
|
||||
persistentKeepalive = 25;
|
||||
allowedIPs = [
|
||||
|
|
@ -53,6 +53,4 @@ in
|
|||
}];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ listenPort ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,19 +14,21 @@ in
|
|||
enableACME = true;
|
||||
forceSSL = true;
|
||||
basicAuthFile = config.sops.secrets.radicale-htpasswd.path;
|
||||
locations."/radicale/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString ports.radicale.tcp}/";
|
||||
recommendedProxySettings = true;
|
||||
#basicAuthFile = "";
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Script-Name /radicale;
|
||||
proxy_set_header X-Remote-User $remote_user;
|
||||
'';
|
||||
# proxy_pass_request_headers = on;
|
||||
# underscores_in_headers = on;
|
||||
locations = {
|
||||
"/radicale/" = {
|
||||
proxyPass = "http://127.0.0.1:${toString ports.radicale.tcp}/";
|
||||
recommendedProxySettings = true;
|
||||
#basicAuthFile = "";
|
||||
extraConfig = ''
|
||||
proxy_set_header X-Script-Name /radicale;
|
||||
proxy_set_header X-Remote-User $remote_user;
|
||||
'';
|
||||
# proxy_pass_request_headers = on;
|
||||
# underscores_in_headers = on;
|
||||
};
|
||||
"/.well-known/caldav".return = "301 $scheme://$host:$server_port/radicale";
|
||||
"/.well-known/carddav".return = "301 $scheme://$host:$server_port/radicale";
|
||||
};
|
||||
locations."/.well-known/caldav".return = "301 $scheme://$host:$server_port/radicale";
|
||||
locations."/.well-known/carddav".return = "301 $scheme://$host:$server_port/radicale";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@ let
|
|||
ports = import ../ports.nix args;
|
||||
domain = "rmfakecloud.jalr.de";
|
||||
cfg = config.services.rmfakecloud;
|
||||
mkEnvironment = (settings: lib.strings.concatLines (
|
||||
mkEnvironment = settings: lib.strings.concatLines (
|
||||
lib.attrsets.mapAttrsToList (name: value: "export ${name}='${value}'") settings
|
||||
));
|
||||
);
|
||||
managementScript = pkgs.writeShellScriptBin "rmfakecloud" ''
|
||||
[[ $(id -u) == "rmfakecloud" ]] || exec sudo -u rmfakecloud -- "$0" "$@"
|
||||
set -a
|
||||
|
|
|
|||
|
|
@ -24,54 +24,44 @@
|
|||
|
||||
services.blueman.enable = true;
|
||||
|
||||
systemd.services.bluetooth-auto-pair = {
|
||||
wantedBy = [
|
||||
"bluetooth.service"
|
||||
];
|
||||
after = [
|
||||
"bluetooth.service"
|
||||
];
|
||||
bindsTo = [
|
||||
"bluetooth.service"
|
||||
];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = pkgs.writeShellScript "exec-start" ''
|
||||
${pkgs.bluez}/bin/bluetoothctl <<EOF
|
||||
discoverable on
|
||||
pairable on
|
||||
EOF
|
||||
systemd.services = {
|
||||
bluetooth-auto-pair = {
|
||||
wantedBy = [ "bluetooth.service" ];
|
||||
after = [ "bluetooth.service" ];
|
||||
bindsTo = [ "bluetooth.service" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = pkgs.writeShellScript "exec-start" ''
|
||||
${pkgs.bluez}/bin/bluetoothctl <<EOF
|
||||
discoverable on
|
||||
pairable on
|
||||
EOF
|
||||
|
||||
${pkgs.coreutils}/bin/yes | ${pkgs.bluez-tools}/bin/bt-agent -c NoInputNoOutput
|
||||
'';
|
||||
ExecStop = pkgs.writeShellScript "exec-stop" ''
|
||||
kill -s SIGINT $MAINPID
|
||||
'';
|
||||
Restart = "on-failure";
|
||||
${pkgs.coreutils}/bin/yes | ${pkgs.bluez-tools}/bin/bt-agent -c NoInputNoOutput
|
||||
'';
|
||||
ExecStop = pkgs.writeShellScript "exec-stop" ''
|
||||
kill -s SIGINT $MAINPID
|
||||
'';
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.bluealsa-aplay = {
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
];
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.bluez-alsa}/bin/bluealsa-aplay --profile-a2dp --pcm=default:CARD=bluetooth 00:00:00:00:00:00";
|
||||
Restart = "on-failure";
|
||||
SupplementaryGroups = [ "audio" ];
|
||||
bluealsa-aplay = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
DynamicUser = true;
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.bluez-alsa}/bin/bluealsa-aplay --profile-a2dp --pcm=default:CARD=bluetooth 00:00:00:00:00:00";
|
||||
Restart = "on-failure";
|
||||
SupplementaryGroups = [ "audio" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.bluealsa-a2dp = {
|
||||
wantedBy = [
|
||||
"multi-user.target"
|
||||
];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.bluez-alsa}/bin/bluealsa -p a2dp-sink";
|
||||
Restart = "on-failure";
|
||||
bluealsa-a2dp = {
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.bluez-alsa}/bin/bluealsa -p a2dp-sink";
|
||||
Restart = "on-failure";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,50 +30,52 @@ in
|
|||
|
||||
jalr.libvirt.enable = true;
|
||||
|
||||
systemd.services.libvirt-guests.serviceConfig.ExecStop = [
|
||||
""
|
||||
"${shutdownAndroidVm} ${vmName}"
|
||||
"${pkgs.libvirt}/libexec/libvirt-guests.sh stop"
|
||||
];
|
||||
systemd.services = {
|
||||
libvirt-guests.serviceConfig.ExecStop = [
|
||||
""
|
||||
"${shutdownAndroidVm} ${vmName}"
|
||||
"${pkgs.libvirt}/libexec/libvirt-guests.sh stop"
|
||||
];
|
||||
|
||||
systemd.services."whatsapp@" = {
|
||||
description = "Start Android VM, wait for WhatsApp and shut down VM.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
environment.VM = "%i";
|
||||
script = ''
|
||||
export PATH=${pkgs.lib.makeBinPath [pkgs.libvirt pkgs.gnused pkgs.android-tools pkgs.coreutils]}
|
||||
"whatsapp@" = {
|
||||
description = "Start Android VM, wait for WhatsApp and shut down VM.";
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
environment.VM = "%i";
|
||||
script = ''
|
||||
export PATH=${pkgs.lib.makeBinPath [pkgs.libvirt pkgs.gnused pkgs.android-tools pkgs.coreutils]}
|
||||
|
||||
domstate="$(virsh domstate "$VM")"
|
||||
domstate="$(virsh domstate "$VM")"
|
||||
|
||||
if [ "$domstate" != "running" ]; then
|
||||
virsh start "$VM"
|
||||
fi
|
||||
|
||||
echo "Wait until IP of Android VM is known"
|
||||
while :; do
|
||||
host="$(virsh -q domifaddr --domain "$VM" | sed -n -r 's#.*ipv4\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/[0-9]+$#\1#p')"
|
||||
if [ "$host" ]; then
|
||||
break
|
||||
if [ "$domstate" != "running" ]; then
|
||||
virsh start "$VM"
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
port=5555
|
||||
adb connect "$host:$port"
|
||||
echo "Wait until IP of Android VM is known"
|
||||
while :; do
|
||||
host="$(virsh -q domifaddr --domain "$VM" | sed -n -r 's#.*ipv4\s*([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/[0-9]+$#\1#p')"
|
||||
if [ "$host" ]; then
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Waiting for WhatsApp"
|
||||
while ! adb -s "$host:$port" shell -- pgrep com.whatsapp > /dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
port=5555
|
||||
adb connect "$host:$port"
|
||||
|
||||
echo "Sleeping..."
|
||||
sleep 5m
|
||||
echo "Waiting for WhatsApp"
|
||||
while ! adb -s "$host:$port" shell -- pgrep com.whatsapp > /dev/null; do
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "Shutting down Android"
|
||||
adb -s "$host:$port" shell -- reboot -p
|
||||
'';
|
||||
echo "Sleeping..."
|
||||
sleep 5m
|
||||
|
||||
echo "Shutting down Android"
|
||||
adb -s "$host:$port" shell -- reboot -p
|
||||
'';
|
||||
};
|
||||
};
|
||||
systemd.timers."whatsapp-${vmName}" = {
|
||||
description = "Start Android VM to run WhatsApp";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
{
|
||||
boot.initrd.postDeviceCommands =
|
||||
let
|
||||
device = config.disko.devices.disk.virt.content.partitions.linux.device;
|
||||
inherit (config.disko.devices.disk.virt.content.partitions.linux) device;
|
||||
in
|
||||
lib.mkAfter ''
|
||||
mkdir /mnt
|
||||
|
|
@ -14,16 +14,17 @@
|
|||
btrfs subvolume snapshot /mnt/root-blank /mnt/root
|
||||
'';
|
||||
|
||||
services.openssh = {
|
||||
hostKeys = lib.mkForce [{
|
||||
path = "/persist/etc/ssh/ssh_host_ed25519_key";
|
||||
type = "ed25519";
|
||||
}];
|
||||
services = {
|
||||
openssh = {
|
||||
hostKeys = lib.mkForce [{
|
||||
path = "/persist/etc/ssh/ssh_host_ed25519_key";
|
||||
type = "ed25519";
|
||||
}];
|
||||
};
|
||||
forgejo.stateDir = "/persist/var/lib/forgejo";
|
||||
postgresql.dataDir = "/persist/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}";
|
||||
};
|
||||
|
||||
services.forgejo.stateDir = "/persist/var/lib/forgejo";
|
||||
services.postgresql.dataDir = "/persist/var/lib/postgresql/${config.services.postgresql.package.psqlSchema}";
|
||||
|
||||
fileSystems."/persist".neededForBoot = true;
|
||||
environment.persistence."/persist" = {
|
||||
hideMounts = true;
|
||||
|
|
|
|||
|
|
@ -10,44 +10,44 @@ in
|
|||
owner = config.systemd.services.hedgedoc.serviceConfig.User;
|
||||
sopsFile = ../secrets.yaml;
|
||||
};
|
||||
services.hedgedoc = {
|
||||
enable = true;
|
||||
settings =
|
||||
let
|
||||
day = 24 * 60 * 60 * 1000;
|
||||
in
|
||||
{
|
||||
domain = domain;
|
||||
protocolUseSSL = true;
|
||||
csp.enable = true;
|
||||
port = ports.hedgedoc.tcp;
|
||||
db = {
|
||||
dialect = "postgres";
|
||||
host = "/run/postgresql";
|
||||
user = "hedgedoc";
|
||||
database = "hedgedoc";
|
||||
services = {
|
||||
hedgedoc = {
|
||||
enable = true;
|
||||
settings =
|
||||
let
|
||||
day = 24 * 60 * 60 * 1000;
|
||||
in
|
||||
{
|
||||
inherit domain;
|
||||
protocolUseSSL = true;
|
||||
csp.enable = true;
|
||||
port = ports.hedgedoc.tcp;
|
||||
db = {
|
||||
dialect = "postgres";
|
||||
host = "/run/postgresql";
|
||||
user = "hedgedoc";
|
||||
database = "hedgedoc";
|
||||
};
|
||||
allowEmailRegister = false;
|
||||
sessionSecret = config.sops.secrets.hedgedoc-session-secret.path;
|
||||
sessionLife = 90 * day;
|
||||
};
|
||||
allowEmailRegister = false;
|
||||
sessionSecret = config.sops.secrets.hedgedoc-session-secret.path;
|
||||
sessionLife = 90 * day;
|
||||
};
|
||||
postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "hedgedoc" ];
|
||||
ensureUsers = [{
|
||||
name = "hedgedoc";
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
};
|
||||
nginx.virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://${cfg.settings.host}:${toString cfg.settings.port}";
|
||||
};
|
||||
};
|
||||
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureDatabases = [ "hedgedoc" ];
|
||||
ensureUsers = [{
|
||||
name = "hedgedoc";
|
||||
ensureDBOwnership = true;
|
||||
}];
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts."${domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/" = {
|
||||
proxyPass = "http://${cfg.settings.host}:${toString cfg.settings.port}";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,15 +6,13 @@ let
|
|||
publicKey = "GCmQs7upvDYFueEfqD2yJkkOZg3K7YaGluWWzdjsyTo=";
|
||||
in
|
||||
{
|
||||
sops.secrets = (
|
||||
lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "wireguard_key_${name}" {
|
||||
sopsFile = ../secrets.yaml;
|
||||
})
|
||||
[
|
||||
"hetzner-ha"
|
||||
]
|
||||
)
|
||||
sops.secrets = lib.listToAttrs (map
|
||||
(name: lib.nameValuePair "wireguard_key_${name}" {
|
||||
sopsFile = ../secrets.yaml;
|
||||
})
|
||||
[
|
||||
"hetzner-ha"
|
||||
]
|
||||
);
|
||||
|
||||
#boot.kernel.sysctl = {
|
||||
|
|
@ -22,24 +20,27 @@ in
|
|||
# "net.ipv4.conf.hetzner-ha.proxy_arp" = 1;
|
||||
# "net.ipv4.conf.enp1s0.proxy_arp" = 1;
|
||||
#};
|
||||
networking.interfaces.hetzner-ha.proxyARP = true;
|
||||
networking.interfaces.enp1s0.proxyARP = true;
|
||||
|
||||
networking.wireguard.interfaces = {
|
||||
hetzner-ha = {
|
||||
ips = [ ];
|
||||
privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path;
|
||||
listenPort = listenPort;
|
||||
networking = {
|
||||
interfaces = {
|
||||
hetzner-ha.proxyARP = true;
|
||||
enp1s0.proxyARP = true;
|
||||
};
|
||||
firewall.allowedUDPPorts = [ listenPort ];
|
||||
wireguard.interfaces = {
|
||||
hetzner-ha = {
|
||||
ips = [ ];
|
||||
privateKeyFile = config.sops.secrets.wireguard_key_hetzner-ha.path;
|
||||
inherit listenPort;
|
||||
|
||||
peers = [{
|
||||
publicKey = publicKey;
|
||||
persistentKeepalive = 25;
|
||||
allowedIPs = [
|
||||
"159.69.103.126/32"
|
||||
];
|
||||
}];
|
||||
peers = [{
|
||||
inherit publicKey;
|
||||
persistentKeepalive = 25;
|
||||
allowedIPs = [
|
||||
"159.69.103.126/32"
|
||||
];
|
||||
}];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedUDPPorts = [ listenPort ];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,14 @@
|
|||
{
|
||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" "sr_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
boot = {
|
||||
initrd = {
|
||||
availableKernelModules = [ "xhci_pci" "virtio_pci" "virtio_scsi" "usbhid" "sr_mod" ];
|
||||
kernelModules = [ ];
|
||||
};
|
||||
kernelModules = [ ];
|
||||
extraModulePackages = [ ];
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
|
|
|
|||
|
|
@ -23,67 +23,15 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
services.pretix = {
|
||||
enable = true;
|
||||
settings = {
|
||||
pretix = {
|
||||
instance_name = "Digitaler Dienst GmbH";
|
||||
url = "https://${domain}";
|
||||
registration = false;
|
||||
password_reset = true;
|
||||
};
|
||||
locale = {
|
||||
default = "de";
|
||||
timezone = "Europe/Berlin";
|
||||
};
|
||||
mail = {
|
||||
from = "no-reply@tickets.weinturm-open-air.de";
|
||||
};
|
||||
redis.location = "unix:///run/redis-pretix/redis.sock?db=0";
|
||||
celery.backend = "redis+socket:///run/redis-pretix/redis.sock?virtual_host=2";
|
||||
celery.broker = "redis+socket:///run/redis-pretix/redis.sock?virtual_host=1";
|
||||
};
|
||||
nginx = {
|
||||
enable = true;
|
||||
inherit domain;
|
||||
};
|
||||
gunicorn = {
|
||||
extraArgs = [
|
||||
"--workers=${toString gunicornWorkers}"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Add user to `redis-pretix` group
|
||||
# to grant access to /run/redis-pretix/redis.sock
|
||||
users.users.pretix.extraGroups = [ "redis-pretix" ];
|
||||
|
||||
services.pretix-banktool = {
|
||||
enable = true;
|
||||
days = 14;
|
||||
secretsFile = config.sops.secrets.pretix-banktool-cfg.path;
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
|
||||
services.nginx = lib.mkIf cfg.nginx.enable {
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
virtualHosts = {
|
||||
"${cfg.nginx.domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
kTLS = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
|
||||
more_set_headers Referrer-Policy same-origin;
|
||||
more_set_headers X-Content-Type-Options nosniff;
|
||||
'';
|
||||
serverAliases = extraDomains;
|
||||
};
|
||||
};
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = lib.mkForce "helfer@weinturm-open-air.de";
|
||||
};
|
||||
|
||||
jalr.mailserver = {
|
||||
|
|
@ -101,8 +49,62 @@ in
|
|||
spam.enable = false;
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = lib.mkForce "helfer@weinturm-open-air.de";
|
||||
services = {
|
||||
pretix = {
|
||||
enable = true;
|
||||
settings = {
|
||||
pretix = {
|
||||
instance_name = "Digitaler Dienst GmbH";
|
||||
url = "https://${domain}";
|
||||
registration = false;
|
||||
password_reset = true;
|
||||
};
|
||||
locale = {
|
||||
default = "de";
|
||||
timezone = "Europe/Berlin";
|
||||
};
|
||||
mail = {
|
||||
from = "no-reply@tickets.weinturm-open-air.de";
|
||||
};
|
||||
redis.location = "unix:///run/redis-pretix/redis.sock?db=0";
|
||||
celery.backend = "redis+socket:///run/redis-pretix/redis.sock?virtual_host=2";
|
||||
celery.broker = "redis+socket:///run/redis-pretix/redis.sock?virtual_host=1";
|
||||
};
|
||||
nginx = {
|
||||
enable = true;
|
||||
inherit domain;
|
||||
};
|
||||
gunicorn = {
|
||||
extraArgs = [
|
||||
"--workers=${toString gunicornWorkers}"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
pretix-banktool = {
|
||||
enable = true;
|
||||
days = 14;
|
||||
secretsFile = config.sops.secrets.pretix-banktool-cfg.path;
|
||||
};
|
||||
|
||||
nginx = lib.mkIf cfg.nginx.enable {
|
||||
recommendedGzipSettings = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedProxySettings = true;
|
||||
recommendedTlsSettings = true;
|
||||
virtualHosts = {
|
||||
"${cfg.nginx.domain}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
kTLS = true;
|
||||
extraConfig = ''
|
||||
add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload' always;
|
||||
more_set_headers Referrer-Policy same-origin;
|
||||
more_set_headers X-Content-Type-Options nosniff;
|
||||
'';
|
||||
serverAliases = extraDomains;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,9 +9,11 @@ in
|
|||
};
|
||||
config = lib.mkIf cfg.bluetooth.enable {
|
||||
hardware.bluetooth.enable = true;
|
||||
services.blueman.enable = true;
|
||||
services.ofono.enable = true;
|
||||
services.upower.enable = true;
|
||||
services = {
|
||||
blueman.enable = true;
|
||||
ofono.enable = true;
|
||||
upower.enable = true;
|
||||
};
|
||||
hardware.bluetooth.settings.General.Experimental = true; # to show battery state
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,20 +45,19 @@ in
|
|||
});
|
||||
};
|
||||
};
|
||||
config = lib.mkIf cfg.enable
|
||||
(
|
||||
let
|
||||
makeUsbDevPath = usbDevice: "/dev/disk/" + usbDevice;
|
||||
makeMountPath = usbDevice: "/key/" + (builtins.hashString "md5" usbDevice);
|
||||
usbFsType = "vfat";
|
||||
config = lib.mkIf cfg.enable (
|
||||
let
|
||||
makeUsbDevPath = usbDevice: "/dev/disk/" + usbDevice;
|
||||
makeMountPath = usbDevice: "/key/" + (builtins.hashString "md5" usbDevice);
|
||||
usbFsType = "vfat";
|
||||
|
||||
mapAttrsNameValue = f: set:
|
||||
lib.listToAttrs (map f (lib.attrsToList set));
|
||||
in
|
||||
{
|
||||
boot.initrd.kernelModules = [ "uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1" ];
|
||||
|
||||
boot.initrd.systemd.services =
|
||||
mapAttrsNameValue = f: set:
|
||||
lib.listToAttrs (map f (lib.attrsToList set));
|
||||
in
|
||||
{
|
||||
boot.initrd = {
|
||||
kernelModules = [ "uas" "usbcore" "usb_storage" "vfat" "nls_cp437" "nls_iso8859_1" ];
|
||||
systemd.services =
|
||||
let
|
||||
makeService = name: { keyPath, usbDevice, waitForDevice }:
|
||||
let
|
||||
|
|
@ -89,7 +88,12 @@ in
|
|||
|
||||
if [ -e ${lib.escapeShellArg usbDevPath} ]; then
|
||||
mkdir -m0500 -p ${lib.escapeShellArg usbMountPath}
|
||||
mount -n -t ${lib.escapeShellArg usbFsType} -o ro,fmask=0137,dmask=0027 ${lib.escapeShellArg usbDevPath} ${lib.escapeShellArg usbMountPath}
|
||||
mount \
|
||||
-n \
|
||||
-t ${lib.escapeShellArg usbFsType} \
|
||||
-o ro,fmask=0137,dmask=0027 \
|
||||
${lib.escapeShellArg usbDevPath} \
|
||||
${lib.escapeShellArg usbMountPath}
|
||||
fi
|
||||
'';
|
||||
};
|
||||
|
|
@ -101,7 +105,7 @@ in
|
|||
})
|
||||
cfg.devices;
|
||||
|
||||
boot.initrd.luks.devices = builtins.mapAttrs
|
||||
luks.devices = builtins.mapAttrs
|
||||
(name: { keyPath, usbDevice, ... }:
|
||||
let
|
||||
usbMountPath = makeMountPath usbDevice;
|
||||
|
|
@ -111,6 +115,7 @@ in
|
|||
keyFileTimeout = 1;
|
||||
})
|
||||
cfg.devices;
|
||||
}
|
||||
);
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,26 +5,26 @@ let
|
|||
listToString = lib.concatStringsSep ",";
|
||||
|
||||
# List of attribute sets with single key-value pair
|
||||
plainAliases = (lib.flatten
|
||||
plainAliases = lib.flatten
|
||||
(map
|
||||
({ address, aliases, ... }:
|
||||
map
|
||||
(alias: { "${alias}" = address; })
|
||||
(aliases ++ lib.singleton address))
|
||||
cfg.users));
|
||||
cfg.users);
|
||||
|
||||
# Attribute set with every alias mapped to a list of receivers
|
||||
mergedAliases = (lib.attrsets.foldAttrs
|
||||
mergedAliases = lib.attrsets.foldAttrs
|
||||
(val: col: lib.singleton val ++ col)
|
||||
[ ]
|
||||
plainAliases);
|
||||
plainAliases;
|
||||
|
||||
# Contents of the aliases file
|
||||
aliasesString = (lib.concatStringsSep
|
||||
aliasesString = lib.concatStringsSep
|
||||
"\n"
|
||||
(lib.mapAttrsToList
|
||||
(alias: addresses: "${alias} ${listToString addresses}")
|
||||
mergedAliases));
|
||||
mergedAliases);
|
||||
|
||||
valiases = pkgs.writeText "valiases" aliasesString;
|
||||
|
||||
|
|
@ -38,7 +38,7 @@ lib.mkIf cfg.enable {
|
|||
services.postfix = {
|
||||
enable = true;
|
||||
|
||||
relayPort = cfg.relayPort;
|
||||
inherit (cfg) relayPort;
|
||||
|
||||
enableSubmission = false; # plain/STARTTLS (latter is forced in submissionOptions)
|
||||
enableSubmissions = true; # submission with implicit TLS (TCP/465)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ let
|
|||
# nix shell nixpkgs#rspamd -c \
|
||||
# rspamadm dkim_keygen -s default -d example.com -b 4096 -k /dev/shm/dkim.key > dkim.txt
|
||||
|
||||
dkimEnabledDomains = (lib.filter (d: d.enableDKIM) cfg.domains);
|
||||
dkimEnabledDomains = lib.filter (d: d.enableDKIM) cfg.domains;
|
||||
dkimSignatureDir = pkgs.stdenvNoCC.mkDerivation {
|
||||
name = "dkim-signatures";
|
||||
dontUnpack = true;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ in
|
|||
type = port;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = (pkgs.formats.json { }).type;
|
||||
inherit ((pkgs.formats.json { })) type;
|
||||
};
|
||||
};
|
||||
mautrix-whatsapp = {
|
||||
|
|
@ -75,7 +75,7 @@ in
|
|||
type = port;
|
||||
};
|
||||
settings = mkOption {
|
||||
type = (pkgs.formats.json { }).type;
|
||||
inherit ((pkgs.formats.json { })) type;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ lib.mkIf cfg.mautrix-signal.enable {
|
|||
};
|
||||
appservice = rec {
|
||||
hostname = "127.0.0.1";
|
||||
port = cfg.mautrix-signal.port;
|
||||
inherit (cfg.mautrix-signal) port;
|
||||
address = "http://${hostname}:${toString port}";
|
||||
provisioning.shared_secret = "disable";
|
||||
database = "sqlite:///${dataDir}/mautrix-signal.db";
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ lib.mkIf cfg.mautrix-whatsapp.enable {
|
|||
};
|
||||
appservice = rec {
|
||||
hostname = "127.0.0.1";
|
||||
port = cfg.mautrix-whatsapp.port;
|
||||
inherit (cfg.mautrix-whatsapp) port;
|
||||
address = "http://${hostname}:${toString port}";
|
||||
provisioning.shared_secret = "disable";
|
||||
database = {
|
||||
|
|
|
|||
|
|
@ -4,84 +4,107 @@ let
|
|||
cfg = config.jalr.matrix;
|
||||
in
|
||||
lib.mkIf cfg.enable {
|
||||
services.matrix-synapse = {
|
||||
enable = true;
|
||||
services = {
|
||||
matrix-synapse = {
|
||||
enable = true;
|
||||
|
||||
settings = {
|
||||
server_name = cfg.domain;
|
||||
public_baseurl = "https://${cfg.fqdn}";
|
||||
settings = {
|
||||
server_name = cfg.domain;
|
||||
public_baseurl = "https://${cfg.fqdn}";
|
||||
|
||||
database.name = "sqlite3";
|
||||
database.name = "sqlite3";
|
||||
|
||||
listeners = lib.singleton {
|
||||
port = cfg.synapse.port;
|
||||
bind_addresses = [ "127.0.0.1" "::1" ];
|
||||
type = "http";
|
||||
tls = false;
|
||||
x_forwarded = true;
|
||||
resources = lib.singleton {
|
||||
names = [ "client" "federation" "metrics" ];
|
||||
compress = false;
|
||||
listeners = lib.singleton {
|
||||
inherit (cfg.synapse) port;
|
||||
bind_addresses = [ "127.0.0.1" "::1" ];
|
||||
type = "http";
|
||||
tls = false;
|
||||
x_forwarded = true;
|
||||
resources = lib.singleton {
|
||||
names = [ "client" "federation" "metrics" ];
|
||||
compress = false;
|
||||
};
|
||||
};
|
||||
|
||||
turn_uris = [
|
||||
"turns:${cfg.turn.host}:5349?transport=udp"
|
||||
"turns:${cfg.turn.host}:5349?transport=tcp"
|
||||
"turn:${cfg.turn.host}:3478?transport=udp"
|
||||
"turn:${cfg.turn.host}:3478?transport=tcp"
|
||||
];
|
||||
turn_user_lifetime = "1h";
|
||||
|
||||
enable_metrics = true;
|
||||
|
||||
# adapted from https://github.com/NixOS/nixpkgs/blob/7e10bf4327491a6ebccbe1aaa8e6c6c0aca4663a/nixos/modules/services/misc/matrix-synapse-log_config.yaml
|
||||
# - set root.level to WARNING instead of INFO
|
||||
log_config = pkgs.writeText "log_config.yaml" (builtins.toJSON {
|
||||
version = 1;
|
||||
|
||||
formatters.journal_fmt.format = "%(name)s: [%(request)s] %(message)s";
|
||||
|
||||
filters.context = {
|
||||
"()" = "synapse.util.logcontext.LoggingContextFilter";
|
||||
request = "";
|
||||
};
|
||||
|
||||
handlers.journal = {
|
||||
class = "systemd.journal.JournalHandler";
|
||||
formatter = "journal_fmt";
|
||||
filters = [ "context" ];
|
||||
SYSLOG_IDENTIFIER = "synapse";
|
||||
};
|
||||
|
||||
root = {
|
||||
level = "WARNING";
|
||||
handlers = [ "journal" ];
|
||||
};
|
||||
|
||||
disable_existing_loggers = false;
|
||||
});
|
||||
|
||||
max_upload_size = "50M";
|
||||
|
||||
# I’m okay with using matrix.org as trusted key server
|
||||
suppress_key_server_warning = true;
|
||||
|
||||
# For mautrix-whatsapp backfilling
|
||||
experimental_features.msc2716_enabled = true;
|
||||
};
|
||||
|
||||
turn_uris = [
|
||||
"turns:${cfg.turn.host}:5349?transport=udp"
|
||||
"turns:${cfg.turn.host}:5349?transport=tcp"
|
||||
"turn:${cfg.turn.host}:3478?transport=udp"
|
||||
"turn:${cfg.turn.host}:3478?transport=tcp"
|
||||
extraConfigFiles = [
|
||||
cfg.turn.sharedSecretFile
|
||||
];
|
||||
turn_user_lifetime = "1h";
|
||||
|
||||
enable_metrics = true;
|
||||
|
||||
# adapted from https://github.com/NixOS/nixpkgs/blob/7e10bf4327491a6ebccbe1aaa8e6c6c0aca4663a/nixos/modules/services/misc/matrix-synapse-log_config.yaml
|
||||
# - set root.level to WARNING instead of INFO
|
||||
log_config = pkgs.writeText "log_config.yaml" (builtins.toJSON {
|
||||
version = 1;
|
||||
|
||||
formatters.journal_fmt.format = "%(name)s: [%(request)s] %(message)s";
|
||||
|
||||
filters.context = {
|
||||
"()" = "synapse.util.logcontext.LoggingContextFilter";
|
||||
request = "";
|
||||
};
|
||||
|
||||
handlers.journal = {
|
||||
class = "systemd.journal.JournalHandler";
|
||||
formatter = "journal_fmt";
|
||||
filters = [ "context" ];
|
||||
SYSLOG_IDENTIFIER = "synapse";
|
||||
};
|
||||
|
||||
root = {
|
||||
level = "WARNING";
|
||||
handlers = [ "journal" ];
|
||||
};
|
||||
|
||||
disable_existing_loggers = false;
|
||||
});
|
||||
|
||||
max_upload_size = "50M";
|
||||
|
||||
# I’m okay with using matrix.org as trusted key server
|
||||
suppress_key_server_warning = true;
|
||||
|
||||
# For mautrix-whatsapp backfilling
|
||||
experimental_features.msc2716_enabled = true;
|
||||
};
|
||||
|
||||
extraConfigFiles = [
|
||||
cfg.turn.sharedSecretFile
|
||||
];
|
||||
matrix-synapse.settings.app_service_config_files = lib.attrsets.mapAttrsToList
|
||||
(
|
||||
name: value:
|
||||
"/run/matrix-synapse/app_service_config/${name}.yaml"
|
||||
)
|
||||
cfg.synapse.app_service_config;
|
||||
|
||||
nginx.virtualHosts = {
|
||||
"${cfg.fqdn}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/_matrix" =
|
||||
let
|
||||
listenerCfg = lib.elemAt config.services.matrix-synapse.settings.listeners 0;
|
||||
in
|
||||
{
|
||||
proxyPass = "http://${lib.elemAt listenerCfg.bind_addresses 0}:${toString listenerCfg.port}";
|
||||
|
||||
extraConfig = ''
|
||||
client_max_body_size ${config.services.matrix-synapse.settings.max_upload_size};
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
services.matrix-synapse.settings.app_service_config_files = lib.attrsets.mapAttrsToList
|
||||
(
|
||||
name: value:
|
||||
"/run/matrix-synapse/app_service_config/${name}.yaml"
|
||||
)
|
||||
cfg.synapse.app_service_config;
|
||||
systemd.services.matrix-synapse = {
|
||||
restartTriggers = lib.attrsets.mapAttrsToList
|
||||
(
|
||||
|
|
@ -109,24 +132,4 @@ lib.mkIf cfg.enable {
|
|||
cfg.synapse.app_service_config;
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts = {
|
||||
"${cfg.fqdn}" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
|
||||
locations."/_matrix" =
|
||||
let
|
||||
listenerCfg = (lib.elemAt config.services.matrix-synapse.settings.listeners 0);
|
||||
in
|
||||
{
|
||||
proxyPass = "http://${lib.elemAt listenerCfg.bind_addresses 0}:${toString listenerCfg.port}";
|
||||
|
||||
extraConfig = ''
|
||||
client_max_body_size ${config.services.matrix-synapse.settings.max_upload_size};
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
(final: prev: {
|
||||
master = import inputs.nixpkgsMaster {
|
||||
inherit system;
|
||||
config = prev.config;
|
||||
inherit (prev) config;
|
||||
};
|
||||
})
|
||||
];
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ in
|
|||
extraArgs = [ "-f" ];
|
||||
postCreateHook =
|
||||
let
|
||||
device = cfg.devices.disk.virt.content.partitions.linux.device;
|
||||
inherit (cfg.devices.disk.virt.content.partitions.linux) device;
|
||||
in
|
||||
''
|
||||
mountpoint="$(mktemp -d)"
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ in
|
|||
];
|
||||
|
||||
sops.secrets.sturzbach-htpasswd = {
|
||||
sopsFile = cfg.sopsFile;
|
||||
inherit (cfg) sopsFile;
|
||||
owner = "nginx";
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
{ config, lib, pkgs, ... }:
|
||||
|
||||
lib.mkIf (config.jalr.gui.enable && config.jalr.gui.desktop == "sway") {
|
||||
programs.sway = {
|
||||
enable = true;
|
||||
xwayland.enable = true;
|
||||
wrapperFeatures.gtk = true;
|
||||
programs = {
|
||||
wshowkeys.enable = true;
|
||||
dconf.enable = true;
|
||||
sway = {
|
||||
enable = true;
|
||||
xwayland.enable = true;
|
||||
wrapperFeatures.gtk = true;
|
||||
};
|
||||
};
|
||||
|
||||
hardware.graphics.enable = true;
|
||||
|
|
@ -19,6 +23,7 @@ lib.mkIf (config.jalr.gui.enable && config.jalr.gui.desktop == "sway") {
|
|||
}];
|
||||
|
||||
xdg = {
|
||||
icons.enable = true;
|
||||
portal = {
|
||||
enable = true;
|
||||
extraPortals = with pkgs; [
|
||||
|
|
@ -27,13 +32,8 @@ lib.mkIf (config.jalr.gui.enable && config.jalr.gui.desktop == "sway") {
|
|||
];
|
||||
xdgOpenUsePortal = true;
|
||||
};
|
||||
icons.enable = true;
|
||||
};
|
||||
|
||||
programs.wshowkeys.enable = true;
|
||||
|
||||
programs.dconf.enable = true;
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
adwaita-icon-theme
|
||||
];
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{ lib, ... }:
|
||||
|
||||
{
|
||||
nixpkgs.config.allowUnfreePredicate = (pkg: lib.elem (lib.getName pkg) [
|
||||
nixpkgs.config.allowUnfreePredicate = pkg: lib.elem (lib.getName pkg) [
|
||||
"unifi-controller"
|
||||
"mongodb"
|
||||
]);
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
{ ... }@inputs:
|
||||
inputs:
|
||||
|
||||
final: prev:
|
||||
let
|
||||
|
|
|
|||
|
|
@ -84,73 +84,73 @@ in
|
|||
|
||||
config = lib.mkIf cfg.enable {
|
||||
environment.etc."myintercom-doorbell/settings.json".text = builtins.toJSON {
|
||||
host = cfg.host;
|
||||
username = cfg.username;
|
||||
passwordFile = cfg.passwordFile;
|
||||
inherit (cfg) host;
|
||||
inherit (cfg) username;
|
||||
inherit (cfg) passwordFile;
|
||||
audiosocket = {
|
||||
address = cfg.audiosocket.address;
|
||||
port = cfg.audiosocket.port;
|
||||
uuid = cfg.audiosocket.uuid;
|
||||
inherit (cfg.audiosocket) address;
|
||||
inherit (cfg.audiosocket) port;
|
||||
inherit (cfg.audiosocket) uuid;
|
||||
};
|
||||
callerId = cfg.callerId;
|
||||
dialTime = cfg.dialTime;
|
||||
inherit (cfg) callerId;
|
||||
inherit (cfg) dialTime;
|
||||
};
|
||||
|
||||
systemd.services.myintercom-doorbell-poll = {
|
||||
enable = cfg.enable;
|
||||
description = "Polls myintercom doorbell ring button status.";
|
||||
after = [ "asterisk.service" "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "asterisk";
|
||||
# @TODO: Use unstable only until 23.11 is released
|
||||
ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-poll";
|
||||
systemd.services = {
|
||||
myintercom-doorbell-poll = {
|
||||
inherit (cfg) enable;
|
||||
description = "Polls myintercom doorbell ring button status.";
|
||||
after = [ "asterisk.service" "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "asterisk";
|
||||
# @TODO: Use unstable only until 23.11 is released
|
||||
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" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
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}"
|
||||
"HOST=${cfg.host}"
|
||||
"USERNAME=${cfg.username}"
|
||||
"PASSWORD_FILE=%d/password"
|
||||
];
|
||||
ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-audiosocket";
|
||||
myintercom-doorbell-audiosocket = {
|
||||
inherit (cfg) enable;
|
||||
description = "myintercom doorbell AudioSocket for Asterisk";
|
||||
requires = [ "asterisk.service" ];
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
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}"
|
||||
"HOST=${cfg.host}"
|
||||
"USERNAME=${cfg.username}"
|
||||
"PASSWORD_FILE=%d/password"
|
||||
];
|
||||
ExecStart = "${pkgs.myintercom-doorbell}/bin/myintercom-doorbell-audiosocket";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.services.myintercom-doorbell-cam-proxy = {
|
||||
enable = cfg.cam.enable;
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Proxies the videostream of myintercom doorbell.";
|
||||
script = ''
|
||||
sed "s:__PASSWORD__:$(cat "$PASSWORD_FILE"):" "${mediamtxConfig}" | ${pkgs.master.mediamtx}/bin/mediamtx /dev/stdin
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
DynamicUser = true;
|
||||
LoadCredential = "password:${cfg.passwordFile}";
|
||||
Environment = [
|
||||
"PASSWORD_FILE=%d/password"
|
||||
];
|
||||
myintercom-doorbell-cam-proxy = {
|
||||
inherit (cfg.cam) enable;
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Proxies the videostream of myintercom doorbell.";
|
||||
script = ''
|
||||
sed "s:__PASSWORD__:$(cat "$PASSWORD_FILE"):" "${mediamtxConfig}" | ${pkgs.master.mediamtx}/bin/mediamtx /dev/stdin
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
DynamicUser = true;
|
||||
LoadCredential = "password:${cfg.passwordFile}";
|
||||
Environment = [
|
||||
"PASSWORD_FILE=%d/password"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
stdenv.mkDerivation rec {
|
||||
pname = "wofi-bluetooth";
|
||||
version = rofi-bluetooth.version;
|
||||
src = rofi-bluetooth.src;
|
||||
inherit (rofi-bluetooth) version;
|
||||
inherit (rofi-bluetooth) src;
|
||||
patches = [
|
||||
./wofi-bluetooth.patch
|
||||
];
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ in
|
|||
{
|
||||
|
||||
programs.alacritty = {
|
||||
enable = nixosConfig.jalr.gui.enable;
|
||||
inherit (nixosConfig.jalr.gui) enable;
|
||||
};
|
||||
|
||||
xdg.configFile = lib.attrsets.mapAttrs'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ nixosConfig, lib, pkgs, config, ... }:
|
||||
|
||||
let
|
||||
xdg = config.xdg;
|
||||
inherit (config) xdg;
|
||||
in
|
||||
{
|
||||
config = lib.mkIf nixosConfig.jalr.aws.enable {
|
||||
|
|
@ -17,7 +17,7 @@ in
|
|||
xdg.configFile."aws/config".text = lib.generators.toINI { } (
|
||||
lib.mapAttrs'
|
||||
(name: value:
|
||||
lib.attrsets.nameValuePair ("profile ${name}") (value)
|
||||
lib.attrsets.nameValuePair "profile ${name}" value
|
||||
)
|
||||
nixosConfig.jalr.aws.accounts
|
||||
//
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@
|
|||
} // (with config.lib.htop; leftMeters ([
|
||||
(bar "LeftCPUs")
|
||||
(bar "Memory")
|
||||
] ++ lib.lists.optional nixosConfig.zramSwap.enable (bar "Zram") ++ [
|
||||
] ++ lib.lists.optional (!(nixosConfig.swapDevices == [ ])) (bar "Swap") ++ [
|
||||
] ++ lib.lists.optional nixosConfig.zramSwap.enable (bar "Zram") ++ lib.lists.optional (nixosConfig.swapDevices != [ ]) (bar "Swap") ++ [
|
||||
(bar "DiskIO")
|
||||
])) // (with config.lib.htop; rightMeters [
|
||||
(bar "RightCPUs")
|
||||
|
|
|
|||
|
|
@ -40,18 +40,16 @@ let
|
|||
target = "myclirc";
|
||||
}
|
||||
{
|
||||
exec = (
|
||||
exec =
|
||||
if nixosConfig.jalr.gui.enable
|
||||
then [ "/usr/bin/env" "gsettings" "set" "org.gnome.desktop.interface" "color-scheme" "prefer-%scheme%" ]
|
||||
else null
|
||||
);
|
||||
else null;
|
||||
}
|
||||
{
|
||||
exec = (
|
||||
exec =
|
||||
if nixosConfig.jalr.gui.enable
|
||||
then [ "/usr/bin/env" "gsettings" "set" "org.gnome.desktop.interface" "gtk-theme" "Adwaita-%scheme%" ]
|
||||
else null
|
||||
);
|
||||
else null;
|
||||
}
|
||||
];
|
||||
dynamic-colors = pkgs.writers.writePython3Bin "dynamic-colors" { } ''
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ nixosConfig, pkgs, ... }:
|
||||
{
|
||||
programs.firefox = {
|
||||
enable = nixosConfig.jalr.gui.enable;
|
||||
inherit (nixosConfig.jalr.gui) enable;
|
||||
package = pkgs.firefox-esr;
|
||||
policies = {
|
||||
AllowedDomainsForApps = "";
|
||||
|
|
@ -155,113 +155,115 @@
|
|||
}
|
||||
];
|
||||
*/
|
||||
SearchEngines.Default = "DuckDuckGo";
|
||||
SearchEngines.Remove = [
|
||||
"Google"
|
||||
"Wikipedia (en)"
|
||||
];
|
||||
SearchEngines.Add = [
|
||||
{
|
||||
Name = "Startpage";
|
||||
URLTemplate = "https://www.startpage.com/sp/search";
|
||||
Method = "POST";
|
||||
PostData = "qadf=none&query={searchTerms}";
|
||||
IconURL = "https://www.startpage.com/sp/cdn/favicons/mobile/android-icon-192x192.png";
|
||||
Alias = "sp";
|
||||
}
|
||||
{
|
||||
Name = "DuckDuckGo";
|
||||
URLTemplate = "https://duckduckgo.com/?q={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://duckduckgo.com/favicon.ico";
|
||||
Alias = "ddg";
|
||||
}
|
||||
SearchEngines = {
|
||||
Default = "DuckDuckGo";
|
||||
Remove = [
|
||||
"Google"
|
||||
"Wikipedia (en)"
|
||||
];
|
||||
Add = [
|
||||
{
|
||||
Name = "Startpage";
|
||||
URLTemplate = "https://www.startpage.com/sp/search";
|
||||
Method = "POST";
|
||||
PostData = "qadf=none&query={searchTerms}";
|
||||
IconURL = "https://www.startpage.com/sp/cdn/favicons/mobile/android-icon-192x192.png";
|
||||
Alias = "sp";
|
||||
}
|
||||
{
|
||||
Name = "DuckDuckGo";
|
||||
URLTemplate = "https://duckduckgo.com/?q={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://duckduckgo.com/favicon.ico";
|
||||
Alias = "ddg";
|
||||
}
|
||||
|
||||
# Wikipedia
|
||||
{
|
||||
Name = "Wikipedia en";
|
||||
URLTemplate = "https://en.wikipedia.org/wiki/Special:Search?search={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://en.wikipedia.org/static/images/icons/wikipedia.png";
|
||||
Alias = "wen";
|
||||
}
|
||||
{
|
||||
Name = "Wikipedia de";
|
||||
URLTemplate = "https://de.wikipedia.org/w/index.php?search={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.wikipedia.de/img/wikipedia.png";
|
||||
Alias = "wde";
|
||||
}
|
||||
{
|
||||
Name = "Nix Packages";
|
||||
URLTemplate = "https://search.nixos.org/packages?query={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://nixos.org/favicon.png";
|
||||
Alias = "pkg";
|
||||
}
|
||||
{
|
||||
Name = "NixOS Options";
|
||||
URLTemplate = "https://search.nixos.org/options?query={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://nixos.org/favicon.png";
|
||||
Alias = "opt";
|
||||
}
|
||||
{
|
||||
Name = "Docker images";
|
||||
URLTemplate = "https://hub.docker.com/search/?q={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://hub.docker.com/favicon.ico";
|
||||
Alias = "docker";
|
||||
}
|
||||
{
|
||||
Name = "GitHub";
|
||||
URLTemplate = "https://github.com/search?q={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://github.githubassets.com/favicons/favicon.svg";
|
||||
Alias = "gh";
|
||||
}
|
||||
# Wikipedia
|
||||
{
|
||||
Name = "Wikipedia en";
|
||||
URLTemplate = "https://en.wikipedia.org/wiki/Special:Search?search={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://en.wikipedia.org/static/images/icons/wikipedia.png";
|
||||
Alias = "wen";
|
||||
}
|
||||
{
|
||||
Name = "Wikipedia de";
|
||||
URLTemplate = "https://de.wikipedia.org/w/index.php?search={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.wikipedia.de/img/wikipedia.png";
|
||||
Alias = "wde";
|
||||
}
|
||||
{
|
||||
Name = "Nix Packages";
|
||||
URLTemplate = "https://search.nixos.org/packages?query={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://nixos.org/favicon.png";
|
||||
Alias = "pkg";
|
||||
}
|
||||
{
|
||||
Name = "NixOS Options";
|
||||
URLTemplate = "https://search.nixos.org/options?query={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://nixos.org/favicon.png";
|
||||
Alias = "opt";
|
||||
}
|
||||
{
|
||||
Name = "Docker images";
|
||||
URLTemplate = "https://hub.docker.com/search/?q={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://hub.docker.com/favicon.ico";
|
||||
Alias = "docker";
|
||||
}
|
||||
{
|
||||
Name = "GitHub";
|
||||
URLTemplate = "https://github.com/search?q={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://github.githubassets.com/favicons/favicon.svg";
|
||||
Alias = "gh";
|
||||
}
|
||||
|
||||
# Shopping
|
||||
{
|
||||
Name = "Amazon de";
|
||||
URLTemplate = "https://www.amazon.de/s?k={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.amazon.de/favicon.ico";
|
||||
Alias = "amde";
|
||||
}
|
||||
{
|
||||
Name = "Ebay de";
|
||||
URLTemplate = "https://www.ebay.de/sch/i.html?_nkw={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://pages.ebay.com/favicon.ico";
|
||||
Alias = "ebde";
|
||||
}
|
||||
# Shopping
|
||||
{
|
||||
Name = "Amazon de";
|
||||
URLTemplate = "https://www.amazon.de/s?k={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.amazon.de/favicon.ico";
|
||||
Alias = "amde";
|
||||
}
|
||||
{
|
||||
Name = "Ebay de";
|
||||
URLTemplate = "https://www.ebay.de/sch/i.html?_nkw={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://pages.ebay.com/favicon.ico";
|
||||
Alias = "ebde";
|
||||
}
|
||||
|
||||
# Dictionary
|
||||
{
|
||||
Name = "dict.cc";
|
||||
URLTemplate = "https://www.dict.cc/?s={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www4.dict.cc/img/favicons/favicon4.png";
|
||||
Alias = "dcc";
|
||||
}
|
||||
{
|
||||
Name = "Duden";
|
||||
URLTemplate = "https://www.duden.de/suchen/dudenonline/{searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.duden.de/sites/default/res/apple-touch-icon/180x180.png";
|
||||
Alias = "duden";
|
||||
}
|
||||
# Dictionary
|
||||
{
|
||||
Name = "dict.cc";
|
||||
URLTemplate = "https://www.dict.cc/?s={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www4.dict.cc/img/favicons/favicon4.png";
|
||||
Alias = "dcc";
|
||||
}
|
||||
{
|
||||
Name = "Duden";
|
||||
URLTemplate = "https://www.duden.de/suchen/dudenonline/{searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.duden.de/sites/default/res/apple-touch-icon/180x180.png";
|
||||
Alias = "duden";
|
||||
}
|
||||
|
||||
# Map
|
||||
{
|
||||
Name = "OpenStreetMap";
|
||||
URLTemplate = "https://www.openstreetmap.org/search?query={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.openstreetmap.org/assets/favicon-194x194-79d3fb0152c735866e64b1d7535d504483cd13c2fad0131a6142bd9629d30de2.png";
|
||||
Alias = "osm";
|
||||
}
|
||||
];
|
||||
# Map
|
||||
{
|
||||
Name = "OpenStreetMap";
|
||||
URLTemplate = "https://www.openstreetmap.org/search?query={searchTerms}";
|
||||
Method = "GET";
|
||||
IconURL = "https://www.openstreetmap.org/assets/favicon-194x194-79d3fb0152c735866e64b1d7535d504483cd13c2fad0131a6142bd9629d30de2.png";
|
||||
Alias = "osm";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
profiles.default = {
|
||||
id = 0;
|
||||
|
|
|
|||
|
|
@ -169,36 +169,38 @@
|
|||
};
|
||||
};
|
||||
|
||||
xdg.configFile."fish/completions/mycli.fish".text = ''
|
||||
complete -e -c mycli
|
||||
complete -c mycli -f
|
||||
complete -c mycli -f -s h -l host -d "Host address of the database."
|
||||
complete -c mycli -f -s P -l port -d "Port number to use for connection."
|
||||
complete -c mycli -f -s u -l user -d "User name to connect to the database."
|
||||
complete -c mycli -f -s S -l socket -d "The socket file to use for connection."
|
||||
complete -c mycli -f -s p -l pass \
|
||||
-l password -d "Password to connect to the database."
|
||||
complete -c mycli -f -s V -l version -d "Output mycli's version."
|
||||
complete -c mycli -f -s v -l verbose -d "Verbose output."
|
||||
complete -c mycli -f -s d -l dsn -d "Use DSN configured into the [alias_dsn] section of myclirc file."
|
||||
complete -c mycli -f -l list-dsn -d "list of DSN configured into the [alias_dsn] section of myclirc file."
|
||||
xdg.configFile = {
|
||||
"fish/completions/mycli.fish".text = ''
|
||||
complete -e -c mycli
|
||||
complete -c mycli -f
|
||||
complete -c mycli -f -s h -l host -d "Host address of the database."
|
||||
complete -c mycli -f -s P -l port -d "Port number to use for connection."
|
||||
complete -c mycli -f -s u -l user -d "User name to connect to the database."
|
||||
complete -c mycli -f -s S -l socket -d "The socket file to use for connection."
|
||||
complete -c mycli -f -s p -l pass \
|
||||
-l password -d "Password to connect to the database."
|
||||
complete -c mycli -f -s V -l version -d "Output mycli's version."
|
||||
complete -c mycli -f -s v -l verbose -d "Verbose output."
|
||||
complete -c mycli -f -s d -l dsn -d "Use DSN configured into the [alias_dsn] section of myclirc file."
|
||||
complete -c mycli -f -l list-dsn -d "list of DSN configured into the [alias_dsn] section of myclirc file."
|
||||
|
||||
complete -c mycli -f -s t -l table -d "Display batch output in table format."
|
||||
complete -c mycli -f -l csv -d "Display batch output in CSV format."
|
||||
complete -c mycli -f -l warn \
|
||||
-l no-warn -d "Warn before running a destructive query."
|
||||
complete -c mycli -f -s e -l execute -d "Execute command and quit."
|
||||
complete -c mycli -f -s t -l table -d "Display batch output in table format."
|
||||
complete -c mycli -f -l csv -d "Display batch output in CSV format."
|
||||
complete -c mycli -f -l warn \
|
||||
-l no-warn -d "Warn before running a destructive query."
|
||||
complete -c mycli -f -s e -l execute -d "Execute command and quit."
|
||||
|
||||
|
||||
complete -c mycli -f -s h -l host -r -a '(__fish_print_hostnames)'
|
||||
complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)'
|
||||
'';
|
||||
complete -c mycli -f -s h -l host -r -a '(__fish_print_hostnames)'
|
||||
complete -c mycli -f -s d -l dsn -r -a '(mycli --list-dsn)'
|
||||
'';
|
||||
|
||||
xdg.configFile."fish/completions/myssh.fish".text = ''
|
||||
complete -c myssh -f -a '(myssh --list)'
|
||||
'';
|
||||
"fish/completions/myssh.fish".text = ''
|
||||
complete -c myssh -f -a '(myssh --list)'
|
||||
'';
|
||||
|
||||
xdg.configFile."fish/completions/just.fish".source = pkgs.runCommand "just-fish-completions" { } ''
|
||||
${pkgs.just}/bin/just --completions fish > $out
|
||||
'';
|
||||
"fish/completions/just.fish".source = pkgs.runCommand "just-fish-completions" { } ''
|
||||
${pkgs.just}/bin/just --completions fish > $out
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,6 @@ let
|
|||
pkgs.gnuradio3_8Packages;
|
||||
};
|
||||
in
|
||||
(lib.mkIf nixosConfig.jalr.gui.enable {
|
||||
lib.mkIf nixosConfig.jalr.gui.enable {
|
||||
home.packages = [ gnuradioEnv ];
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,111 +139,112 @@ in
|
|||
]);
|
||||
};
|
||||
|
||||
xdg.configFile."nvim/lua/init.lua".text = builtins.concatStringsSep "\n" (
|
||||
[
|
||||
''
|
||||
-- init.lua
|
||||
-- this configuration applies to servers and workstations
|
||||
''
|
||||
] ++ lib.optional nixosConfig.jalr.workstation.enable (
|
||||
''
|
||||
-- this configuration applies to workstations only
|
||||
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
|
||||
local lsp = require('lspconfig')
|
||||
'' +
|
||||
builtins.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList
|
||||
(
|
||||
lang: cfg: "lsp.${lang}.setup\n" + lib.generators.toLua { } cfg
|
||||
)
|
||||
{
|
||||
# C and C++
|
||||
ccls = {
|
||||
cmd = [ "${pkgs.ccls}/bin/ccls" ];
|
||||
};
|
||||
xdg.configFile = {
|
||||
"nvim/ftplugin/gitcommit.vim".text = ''
|
||||
setlocal spell
|
||||
setlocal colorcolumn=73
|
||||
'';
|
||||
"nvim/ftplugin/markdown.vim".text = ''
|
||||
setlocal spell
|
||||
setlocal colorcolumn=81
|
||||
'';
|
||||
"nvim/ftplugin/sshconfig.vim".text = ''
|
||||
setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
|
||||
'';
|
||||
"nvim/lua/init.lua".text = builtins.concatStringsSep "\n" (
|
||||
[
|
||||
''
|
||||
-- init.lua
|
||||
-- this configuration applies to servers and workstations
|
||||
''
|
||||
] ++ lib.optional nixosConfig.jalr.workstation.enable (
|
||||
''
|
||||
-- this configuration applies to workstations only
|
||||
-- https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md
|
||||
local lsp = require('lspconfig')
|
||||
'' +
|
||||
builtins.concatStringsSep "\n" (
|
||||
lib.mapAttrsToList
|
||||
(
|
||||
lang: cfg: "lsp.${lang}.setup\n" + lib.generators.toLua { } cfg
|
||||
)
|
||||
{
|
||||
# C and C++
|
||||
ccls = {
|
||||
cmd = [ "${pkgs.ccls}/bin/ccls" ];
|
||||
};
|
||||
|
||||
# Nix
|
||||
nixd = {
|
||||
cmd = [ "${pkgs.nixd}/bin/nixd" ];
|
||||
};
|
||||
# Nix
|
||||
nixd = {
|
||||
cmd = [ "${pkgs.nixd}/bin/nixd" ];
|
||||
};
|
||||
|
||||
# PHP
|
||||
phpactor = {
|
||||
cmd = [ "${pkgs.phpactor}/bin/phpactor" "language-server" ];
|
||||
};
|
||||
# PHP
|
||||
phpactor = {
|
||||
cmd = [ "${pkgs.phpactor}/bin/phpactor" "language-server" ];
|
||||
};
|
||||
|
||||
# Python
|
||||
pylsp = {
|
||||
cmd = [ "${pkgs.python3Packages.python-lsp-server}/bin/pylsp" ];
|
||||
settings = {
|
||||
# https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md
|
||||
pylsp = {
|
||||
plugins = {
|
||||
flake8 = {
|
||||
enabled = true;
|
||||
executable = "${pkgs.python3Packages.flake8}/bin/flake8";
|
||||
# Python
|
||||
pylsp = {
|
||||
cmd = [ "${pkgs.python3Packages.python-lsp-server}/bin/pylsp" ];
|
||||
settings = {
|
||||
# https://github.com/python-lsp/python-lsp-server/blob/develop/CONFIGURATION.md
|
||||
pylsp = {
|
||||
plugins = {
|
||||
flake8 = {
|
||||
enabled = true;
|
||||
executable = "${pkgs.python3Packages.flake8}/bin/flake8";
|
||||
};
|
||||
jedi_completion = { enabled = true; };
|
||||
jedi_definition = { enabled = true; };
|
||||
jedi_hover = { enabled = true; };
|
||||
jedi_references = { enabled = true; };
|
||||
jedi_signature_help = { enabled = true; };
|
||||
jedi_symbols = { enabled = true; };
|
||||
mccabe = { enabled = true; };
|
||||
lsp_signature-nvim = { enabled = true; };
|
||||
preload = { enabled = true; };
|
||||
pycodestyle = { enabled = true; };
|
||||
pyflakes = { enabled = true; };
|
||||
rope_completion = { enabled = true; };
|
||||
yapf = { enabled = true; };
|
||||
};
|
||||
jedi_completion = { enabled = true; };
|
||||
jedi_definition = { enabled = true; };
|
||||
jedi_hover = { enabled = true; };
|
||||
jedi_references = { enabled = true; };
|
||||
jedi_signature_help = { enabled = true; };
|
||||
jedi_symbols = { enabled = true; };
|
||||
mccabe = { enabled = true; };
|
||||
lsp_signature-nvim = { enabled = true; };
|
||||
preload = { enabled = true; };
|
||||
pycodestyle = { enabled = true; };
|
||||
pyflakes = { enabled = true; };
|
||||
rope_completion = { enabled = true; };
|
||||
yapf = { enabled = true; };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Ruby
|
||||
solargraph = {
|
||||
cmd = [ "${pkgs.solargraph}/bin/solargraph" "stdio" ];
|
||||
};
|
||||
# Ruby
|
||||
solargraph = {
|
||||
cmd = [ "${pkgs.solargraph}/bin/solargraph" "stdio" ];
|
||||
};
|
||||
|
||||
# Rust
|
||||
rust_analyzer = {
|
||||
cmd = [ "${pkgs.rust-analyzer}/bin/rust-analyzer" ];
|
||||
};
|
||||
# Rust
|
||||
rust_analyzer = {
|
||||
cmd = [ "${pkgs.rust-analyzer}/bin/rust-analyzer" ];
|
||||
};
|
||||
|
||||
# Bash
|
||||
bashls = {
|
||||
cmd = [ "${pkgs.nodePackages.bash-language-server}/bin/bash-language-server" "start" ];
|
||||
};
|
||||
# Bash
|
||||
bashls = {
|
||||
cmd = [ "${pkgs.nodePackages.bash-language-server}/bin/bash-language-server" "start" ];
|
||||
};
|
||||
|
||||
# Terraform
|
||||
terraformls = {
|
||||
cmd = [ "${pkgs.terraform-ls}/bin/terraform-ls" "serve" ];
|
||||
};
|
||||
# Terraform
|
||||
terraformls = {
|
||||
cmd = [ "${pkgs.terraform-ls}/bin/terraform-ls" "serve" ];
|
||||
};
|
||||
|
||||
# YAML
|
||||
yamlls = {
|
||||
cmd = [ "${pkgs.nodePackages.yaml-language-server}/bin/yaml-language-server" "--stdio" ];
|
||||
settings = {
|
||||
yaml = {
|
||||
keyOrdering = false;
|
||||
# YAML
|
||||
yamlls = {
|
||||
cmd = [ "${pkgs.nodePackages.yaml-language-server}/bin/yaml-language-server" "--stdio" ];
|
||||
settings = {
|
||||
yaml = {
|
||||
keyOrdering = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
xdg.configFile."nvim/ftplugin/gitcommit.vim".text = ''
|
||||
setlocal spell
|
||||
setlocal colorcolumn=73
|
||||
'';
|
||||
xdg.configFile."nvim/ftplugin/markdown.vim".text = ''
|
||||
setlocal spell
|
||||
setlocal colorcolumn=81
|
||||
'';
|
||||
xdg.configFile."nvim/ftplugin/sshconfig.vim".text = ''
|
||||
setlocal tabstop=4 shiftwidth=4 softtabstop=4 expandtab
|
||||
'';
|
||||
);
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
{
|
||||
programs.obs-studio = {
|
||||
enable = nixosConfig.jalr.gui.enable;
|
||||
inherit (nixosConfig.jalr.gui) enable;
|
||||
plugins = with pkgs; [
|
||||
obs-studio-plugins.wlrobs
|
||||
];
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ let
|
|||
#gsettings set $gnome_schema gtk-theme 'Dracula'
|
||||
${pkgs.glib}/bin/gsettings "$@"
|
||||
'';
|
||||
matchHostname = (hostname: lib.optionalAttrs (nixosConfig.networking.hostName == hostname));
|
||||
matchHostname = hostname: lib.optionalAttrs (nixosConfig.networking.hostName == hostname);
|
||||
resumeTimeTrackingNotification = pkgs.writeShellScript "resume-time-tracking-notification" ''
|
||||
export PATH=${pkgs.lib.makeBinPath [pkgs.timewarrior pkgs.libnotify]}
|
||||
task="$1"
|
||||
|
|
@ -97,19 +97,6 @@ in
|
|||
end
|
||||
'';
|
||||
|
||||
xdg.configFile."sway/light-theme".text = with solarized; ''
|
||||
client.focused ${base01.hex} ${blue.hex} ${base3.hex} ${blue.hex} ${blue.hex}
|
||||
client.focused_inactive ${base2.hex} ${base2.hex} ${base01.hex} ${base0.hex} ${base2.hex}
|
||||
client.unfocused ${base2.hex} ${base3.hex} ${base01.hex} ${base2.hex} ${base2.hex}
|
||||
client.urgent ${red.hex} ${red.hex} ${base3.hex} ${red.hex} ${red.hex}
|
||||
'';
|
||||
xdg.configFile."sway/dark-theme".text = with solarized; ''
|
||||
client.focused ${base1.hex} ${blue.hex} ${base03.hex} ${blue.hex} ${blue.hex}
|
||||
client.focused_inactive ${base02.hex} ${base02.hex} ${base1.hex} ${base03.hex} ${base02.hex}
|
||||
client.unfocused ${base02.hex} ${base03.hex} ${base1.hex} ${base02.hex} ${base02.hex}
|
||||
client.urgent ${red.hex} ${red.hex} ${base03.hex} ${red.hex} ${red.hex}
|
||||
'';
|
||||
|
||||
wayland.windowManager.sway = {
|
||||
enable = true;
|
||||
|
||||
|
|
@ -379,26 +366,40 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
xdg.configFile."swaynag/config".text =
|
||||
let
|
||||
# adding it to the header doesn’t work since the defaults overwrite it
|
||||
commonConfig = /* ini */ ''
|
||||
background=${lib.substring 1 6 solarized.base3.hex}
|
||||
border-bottom=${lib.substring 1 6 solarized.base2.hex}
|
||||
border=${lib.substring 1 6 solarized.base2.hex}
|
||||
button-background=${lib.substring 1 6 solarized.base3.hex}
|
||||
button-text=${lib.substring 1 6 solarized.base00.hex}
|
||||
'';
|
||||
in
|
||||
/* ini */ ''
|
||||
font=Monospace 12
|
||||
|
||||
[warning]
|
||||
text=${lib.substring 1 6 solarized.yellow.hex}
|
||||
${commonConfig}
|
||||
|
||||
[error]
|
||||
text=${lib.substring 1 6 solarized.red.hex}
|
||||
${commonConfig}
|
||||
xdg.configFile = {
|
||||
"sway/light-theme".text = with solarized; ''
|
||||
client.focused ${base01.hex} ${blue.hex} ${base3.hex} ${blue.hex} ${blue.hex}
|
||||
client.focused_inactive ${base2.hex} ${base2.hex} ${base01.hex} ${base0.hex} ${base2.hex}
|
||||
client.unfocused ${base2.hex} ${base3.hex} ${base01.hex} ${base2.hex} ${base2.hex}
|
||||
client.urgent ${red.hex} ${red.hex} ${base3.hex} ${red.hex} ${red.hex}
|
||||
'';
|
||||
"sway/dark-theme".text = with solarized; ''
|
||||
client.focused ${base1.hex} ${blue.hex} ${base03.hex} ${blue.hex} ${blue.hex}
|
||||
client.focused_inactive ${base02.hex} ${base02.hex} ${base1.hex} ${base03.hex} ${base02.hex}
|
||||
client.unfocused ${base02.hex} ${base03.hex} ${base1.hex} ${base02.hex} ${base02.hex}
|
||||
client.urgent ${red.hex} ${red.hex} ${base03.hex} ${red.hex} ${red.hex}
|
||||
'';
|
||||
"swaynag/config".text =
|
||||
let
|
||||
# adding it to the header doesn’t work since the defaults overwrite it
|
||||
commonConfig = /* ini */ ''
|
||||
background=${lib.substring 1 6 solarized.base3.hex}
|
||||
border-bottom=${lib.substring 1 6 solarized.base2.hex}
|
||||
border=${lib.substring 1 6 solarized.base2.hex}
|
||||
button-background=${lib.substring 1 6 solarized.base3.hex}
|
||||
button-text=${lib.substring 1 6 solarized.base00.hex}
|
||||
'';
|
||||
in
|
||||
/* ini */ ''
|
||||
font=Monospace 12
|
||||
|
||||
[warning]
|
||||
text=${lib.substring 1 6 solarized.yellow.hex}
|
||||
${commonConfig}
|
||||
|
||||
[error]
|
||||
text=${lib.substring 1 6 solarized.red.hex}
|
||||
${commonConfig}
|
||||
'';
|
||||
};
|
||||
})
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ let
|
|||
thinsp = " ";
|
||||
|
||||
solarized = import ../solarized.nix;
|
||||
solarizedColors = (as: lib.strings.concatLines (lib.attrsets.mapAttrsToList (name: value: let color = solarized."${value}".hex; in "@define-color ${name} ${color};") as));
|
||||
solarizedColors = as: lib.strings.concatLines (lib.attrsets.mapAttrsToList (name: value: let color = solarized."${value}".hex; in "@define-color ${name} ${color};") as);
|
||||
in
|
||||
{
|
||||
# home-manager’s waybar module performs additional checks that are overly strict
|
||||
|
|
@ -227,198 +227,200 @@ in
|
|||
};
|
||||
};
|
||||
|
||||
xdg.configFile."waybar/theme-light.css".text = solarizedColors {
|
||||
base00 = "base3";
|
||||
base01 = "base2";
|
||||
base02 = "base1";
|
||||
base03 = "base0";
|
||||
base04 = "base00";
|
||||
base05 = "base01";
|
||||
base06 = "base02";
|
||||
base07 = "base03";
|
||||
base08 = "red";
|
||||
base09 = "orange";
|
||||
base0A = "yellow";
|
||||
base0B = "green";
|
||||
base0C = "cyan";
|
||||
base0D = "blue";
|
||||
base0E = "violet";
|
||||
base0F = "magenta";
|
||||
};
|
||||
xdg.configFile."waybar/theme-dark.css".text = solarizedColors {
|
||||
base00 = "base03";
|
||||
base01 = "base02";
|
||||
base02 = "base01";
|
||||
base03 = "base00";
|
||||
base04 = "base0";
|
||||
base05 = "base1";
|
||||
base06 = "base2";
|
||||
base07 = "base3";
|
||||
base08 = "red";
|
||||
base09 = "orange";
|
||||
base0A = "yellow";
|
||||
base0B = "green";
|
||||
base0C = "cyan";
|
||||
base0D = "blue";
|
||||
base0E = "violet";
|
||||
base0F = "magenta";
|
||||
};
|
||||
xdg.configFile."waybar/style.css".text = ''
|
||||
@import "theme.css";
|
||||
xdg.configFile = {
|
||||
"waybar/theme-light.css".text = solarizedColors {
|
||||
base00 = "base3";
|
||||
base01 = "base2";
|
||||
base02 = "base1";
|
||||
base03 = "base0";
|
||||
base04 = "base00";
|
||||
base05 = "base01";
|
||||
base06 = "base02";
|
||||
base07 = "base03";
|
||||
base08 = "red";
|
||||
base09 = "orange";
|
||||
base0A = "yellow";
|
||||
base0B = "green";
|
||||
base0C = "cyan";
|
||||
base0D = "blue";
|
||||
base0E = "violet";
|
||||
base0F = "magenta";
|
||||
};
|
||||
"waybar/theme-dark.css".text = solarizedColors {
|
||||
base00 = "base03";
|
||||
base01 = "base02";
|
||||
base02 = "base01";
|
||||
base03 = "base00";
|
||||
base04 = "base0";
|
||||
base05 = "base1";
|
||||
base06 = "base2";
|
||||
base07 = "base3";
|
||||
base08 = "red";
|
||||
base09 = "orange";
|
||||
base0A = "yellow";
|
||||
base0B = "green";
|
||||
base0C = "cyan";
|
||||
base0D = "blue";
|
||||
base0E = "violet";
|
||||
base0F = "magenta";
|
||||
};
|
||||
"waybar/style.css".text = ''
|
||||
@import "theme.css";
|
||||
|
||||
* {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
font-family: "Iosevka Nerd Font";
|
||||
font-size: 14px;
|
||||
min-height: 0;
|
||||
transition-property: none;
|
||||
}
|
||||
* {
|
||||
border-radius: 0;
|
||||
border: none;
|
||||
font-family: "Iosevka Nerd Font";
|
||||
font-size: 14px;
|
||||
min-height: 0;
|
||||
transition-property: none;
|
||||
}
|
||||
|
||||
window#waybar {
|
||||
background-color: @base00;
|
||||
color: @base04;
|
||||
}
|
||||
window#waybar {
|
||||
background-color: @base00;
|
||||
color: @base04;
|
||||
}
|
||||
|
||||
#workspaces button {
|
||||
padding: 0 5px;
|
||||
background-color: @base00;
|
||||
color: inherit;
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
#workspaces button {
|
||||
padding: 0 5px;
|
||||
background-color: @base00;
|
||||
color: inherit;
|
||||
border-bottom: 2px solid transparent;
|
||||
}
|
||||
|
||||
#workspaces button:hover {
|
||||
background: @base01;
|
||||
box-shadow: inherit;
|
||||
text-shadow: inherit;
|
||||
}
|
||||
#workspaces button:hover {
|
||||
background: @base01;
|
||||
box-shadow: inherit;
|
||||
text-shadow: inherit;
|
||||
}
|
||||
|
||||
#workspaces button.focused {
|
||||
border-bottom: 2px solid @base0B;
|
||||
}
|
||||
#workspaces button.focused {
|
||||
border-bottom: 2px solid @base0B;
|
||||
}
|
||||
|
||||
#workspaces button.urgent {
|
||||
background-color: @base08;
|
||||
}
|
||||
#workspaces button.urgent {
|
||||
background-color: @base08;
|
||||
}
|
||||
|
||||
#mode {
|
||||
background-color: @base01;
|
||||
font-style: italic;
|
||||
}
|
||||
#mode {
|
||||
background-color: @base01;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* all modules on the right */
|
||||
#waybar > box > box:nth-child(3) > widget > label {
|
||||
padding: 0 10px;
|
||||
}
|
||||
/* all modules on the right */
|
||||
#waybar > box > box:nth-child(3) > widget > label {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
#battery.charging {
|
||||
color: @base01;
|
||||
background-color: @base0B;
|
||||
}
|
||||
#battery.charging {
|
||||
color: @base01;
|
||||
background-color: @base0B;
|
||||
}
|
||||
|
||||
@keyframes blink {
|
||||
to {
|
||||
@keyframes blink {
|
||||
to {
|
||||
background-color: @base07;
|
||||
color: @base03;
|
||||
}
|
||||
}
|
||||
|
||||
#battery.critical:not(.charging),
|
||||
#temperature.critical {
|
||||
background-color: @base08;
|
||||
animation-name: blink;
|
||||
animation-duration: 0.5s;
|
||||
/* FIXME use nearest neighbor interpolation if possible */
|
||||
animation-timing-function: cubic-bezier(1, 0, 0, 1);
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#cpu {
|
||||
background-color: @base0C;
|
||||
color: @base01
|
||||
}
|
||||
|
||||
#memory {
|
||||
background-color: @base0A;
|
||||
color: @base01
|
||||
}
|
||||
|
||||
#backlight {
|
||||
background-color: @base07;
|
||||
color: @base03;
|
||||
}
|
||||
}
|
||||
|
||||
#battery.critical:not(.charging),
|
||||
#temperature.critical {
|
||||
background-color: @base08;
|
||||
animation-name: blink;
|
||||
animation-duration: 0.5s;
|
||||
/* FIXME use nearest neighbor interpolation if possible */
|
||||
animation-timing-function: cubic-bezier(1, 0, 0, 1);
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
#network {
|
||||
background-color: @base0E;
|
||||
color: @base01
|
||||
}
|
||||
|
||||
#cpu {
|
||||
background-color: @base0C;
|
||||
color: @base01
|
||||
}
|
||||
#network.disconnected {
|
||||
background-color: @base08;
|
||||
}
|
||||
|
||||
#memory {
|
||||
background-color: @base0A;
|
||||
color: @base01
|
||||
}
|
||||
#pulseaudio {
|
||||
background-color: @base07;
|
||||
color: @base03;
|
||||
}
|
||||
|
||||
#backlight {
|
||||
background-color: @base07;
|
||||
color: @base03;
|
||||
}
|
||||
#pulseaudio.muted {
|
||||
background-color: @base00;
|
||||
color: @base04;
|
||||
}
|
||||
|
||||
#network {
|
||||
background-color: @base0E;
|
||||
color: @base01
|
||||
}
|
||||
#temperature {
|
||||
background-color: @base0F;
|
||||
color: @base01;
|
||||
}
|
||||
|
||||
#network.disconnected {
|
||||
background-color: @base08;
|
||||
}
|
||||
#idle_inhibitor.activated {
|
||||
background-color: @base07;
|
||||
color: @base00;
|
||||
}
|
||||
|
||||
#pulseaudio {
|
||||
background-color: @base07;
|
||||
color: @base03;
|
||||
}
|
||||
#custom-redshift {
|
||||
color: @base01;
|
||||
}
|
||||
|
||||
#pulseaudio.muted {
|
||||
background-color: @base00;
|
||||
color: @base04;
|
||||
}
|
||||
#custom-redshift.active {
|
||||
background-color: @base08;
|
||||
}
|
||||
|
||||
#temperature {
|
||||
background-color: @base0F;
|
||||
color: @base01;
|
||||
}
|
||||
#custom-redshift.inactive {
|
||||
background-color: @base0D;
|
||||
}
|
||||
|
||||
#idle_inhibitor.activated {
|
||||
background-color: @base07;
|
||||
color: @base00;
|
||||
}
|
||||
#tray {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
#custom-redshift {
|
||||
color: @base01;
|
||||
}
|
||||
#custom-notification_inhibitor.active {
|
||||
background-color: @base07;
|
||||
color: @base00;
|
||||
}
|
||||
|
||||
#custom-redshift.active {
|
||||
background-color: @base08;
|
||||
}
|
||||
#custom-screencast {
|
||||
background-color: @base08;
|
||||
color: @base00;
|
||||
animation-name: blink;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#custom-redshift.inactive {
|
||||
background-color: @base0D;
|
||||
}
|
||||
#custom-pomodoro.resumed {
|
||||
color: @base01;
|
||||
background-color: @base0B;
|
||||
}
|
||||
|
||||
#tray {
|
||||
padding: 0 5px;
|
||||
}
|
||||
|
||||
#custom-notification_inhibitor.active {
|
||||
background-color: @base07;
|
||||
color: @base00;
|
||||
}
|
||||
|
||||
#custom-screencast {
|
||||
background-color: @base08;
|
||||
color: @base00;
|
||||
animation-name: blink;
|
||||
animation-duration: 1s;
|
||||
animation-timing-function: ease-in-out;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
#custom-pomodoro.resumed {
|
||||
color: @base01;
|
||||
background-color: @base0B;
|
||||
}
|
||||
|
||||
#custom-dnd.active {
|
||||
color: @base01;
|
||||
background-color: @base0B;
|
||||
}
|
||||
'';
|
||||
#custom-dnd.active {
|
||||
color: @base01;
|
||||
background-color: @base0B;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.user.services.waybar = {
|
||||
Unit = {
|
||||
|
|
|
|||
|
|
@ -4,86 +4,88 @@ let
|
|||
solarized = import ../solarized.nix;
|
||||
in
|
||||
{
|
||||
xdg.configFile."wofi/color-light".text = lib.strings.concatLines (map (c: solarized."${c}".hex) [
|
||||
"base3"
|
||||
"base2"
|
||||
"base1"
|
||||
"base0"
|
||||
"base00"
|
||||
"base01"
|
||||
"base02"
|
||||
"base03"
|
||||
"red"
|
||||
"orange"
|
||||
"yellow"
|
||||
"green"
|
||||
"cyan"
|
||||
"blue"
|
||||
"violet"
|
||||
"magenta"
|
||||
]);
|
||||
xdg.configFile."wofi/color-dark".text = lib.strings.concatLines (map (c: solarized."${c}".hex) [
|
||||
"base03"
|
||||
"base02"
|
||||
"base01"
|
||||
"base00"
|
||||
"base0"
|
||||
"base1"
|
||||
"base2"
|
||||
"base3"
|
||||
"red"
|
||||
"orange"
|
||||
"yellow"
|
||||
"green"
|
||||
"cyan"
|
||||
"blue"
|
||||
"violet"
|
||||
"magenta"
|
||||
]);
|
||||
xdg.configFile."wofi/style.css".text = ''
|
||||
window {
|
||||
margin: 0px;
|
||||
border: 3px solid --wofi-color1;
|
||||
border-radius: 8px;
|
||||
background-color: rgba(--wofi-rgb-color0,0.8);
|
||||
}
|
||||
xdg.configFile = {
|
||||
"wofi/color-light".text = lib.strings.concatLines (map (c: solarized."${c}".hex) [
|
||||
"base3"
|
||||
"base2"
|
||||
"base1"
|
||||
"base0"
|
||||
"base00"
|
||||
"base01"
|
||||
"base02"
|
||||
"base03"
|
||||
"red"
|
||||
"orange"
|
||||
"yellow"
|
||||
"green"
|
||||
"cyan"
|
||||
"blue"
|
||||
"violet"
|
||||
"magenta"
|
||||
]);
|
||||
"wofi/color-dark".text = lib.strings.concatLines (map (c: solarized."${c}".hex) [
|
||||
"base03"
|
||||
"base02"
|
||||
"base01"
|
||||
"base00"
|
||||
"base0"
|
||||
"base1"
|
||||
"base2"
|
||||
"base3"
|
||||
"red"
|
||||
"orange"
|
||||
"yellow"
|
||||
"green"
|
||||
"cyan"
|
||||
"blue"
|
||||
"violet"
|
||||
"magenta"
|
||||
]);
|
||||
"wofi/style.css".text = ''
|
||||
window {
|
||||
margin: 0px;
|
||||
border: 3px solid --wofi-color1;
|
||||
border-radius: 8px;
|
||||
background-color: rgba(--wofi-rgb-color0,0.8);
|
||||
}
|
||||
|
||||
#input {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: --wofi-color4;
|
||||
background-color: rgba(--wofi-rgb-color1,0.8);
|
||||
}
|
||||
#input {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: --wofi-color4;
|
||||
background-color: rgba(--wofi-rgb-color1,0.8);
|
||||
}
|
||||
|
||||
#inner-box {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
#inner-box {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#outer-box {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
#outer-box {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
background: none;
|
||||
}
|
||||
|
||||
#scroll {
|
||||
margin: 0px;
|
||||
border: none;
|
||||
}
|
||||
#scroll {
|
||||
margin: 0px;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#text {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: --wofi-color4;
|
||||
}
|
||||
#text {
|
||||
margin: 5px;
|
||||
border: none;
|
||||
color: --wofi-color4;
|
||||
}
|
||||
|
||||
#entry:selected {
|
||||
background-color: rgba(--wofi-rgb-color1,0.8);
|
||||
}
|
||||
#entry:selected {
|
||||
background-color: rgba(--wofi-rgb-color1,0.8);
|
||||
}
|
||||
|
||||
#entry:selected #text{
|
||||
color: --wofi-color11;
|
||||
}
|
||||
'';
|
||||
#entry:selected #text{
|
||||
color: --wofi-color11;
|
||||
}
|
||||
'';
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ nixosConfig, pkgs, ... }:
|
||||
{
|
||||
programs.thunderbird = {
|
||||
enable = nixosConfig.jalr.gui.enable;
|
||||
inherit (nixosConfig.jalr.gui) enable;
|
||||
package = pkgs.thunderbird-esr;
|
||||
profiles."default" = {
|
||||
isDefault = true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue