nixfmt
This commit is contained in:
parent
157f7077d0
commit
b4db084e37
|
@ -1,27 +1,35 @@
|
|||
{pkgs}: {
|
||||
{ pkgs }: {
|
||||
syncthing = {
|
||||
declarativeWith = hosts: path: let
|
||||
mkFolder = name: {
|
||||
path = "${path}/${name}";
|
||||
devices = hosts;
|
||||
declarativeWith = hosts: path:
|
||||
let
|
||||
mkFolder = name: {
|
||||
path = "${path}/${name}";
|
||||
devices = hosts;
|
||||
};
|
||||
devices = pkgs.lib.mapAttrs (name: conf:
|
||||
conf // {
|
||||
addresses = [ "tcp6://${name}.vpn.m-0.eu" ];
|
||||
}) {
|
||||
apollo.id =
|
||||
"BOTTTGS-QQUHWAK-IFBT3T2-HGHHUZ7-QHRZXC7-JC42VT7-67ZOJBE-WHDWEQX";
|
||||
zeus.id =
|
||||
"5BUZIS5-ESTYAJO-IQQD7EA-O3VGONJ-E74OHUJ-ZSLF4JK-6HS3UHG-4CQ5OAO";
|
||||
pegasus.id =
|
||||
"BISYPNZ-54VKBKS-LBND4AS-JNWVOW7-BTW2UMV-QHYM5TZ-GE3AK3E-PGSXPQE";
|
||||
hera.id =
|
||||
"TJHVUM6-RTB6V3D-JF4GIB2-TVDF2ST-5MTN6N2-ZDIWGF7-XZUCCFG-EQG5WA6";
|
||||
};
|
||||
in {
|
||||
devices = pkgs.lib.getAttrs hosts devices;
|
||||
folders = {
|
||||
science = mkFolder "science";
|
||||
documents = mkFolder "documents";
|
||||
audio = mkFolder "audio";
|
||||
video = mkFolder "video";
|
||||
images = mkFolder "images";
|
||||
books = mkFolder "books";
|
||||
tmp = mkFolder "tmp";
|
||||
};
|
||||
};
|
||||
devices = pkgs.lib.mapAttrs (name: conf: conf // {addresses = ["tcp6://${name}.vpn.m-0.eu"];}) {
|
||||
apollo.id = "BOTTTGS-QQUHWAK-IFBT3T2-HGHHUZ7-QHRZXC7-JC42VT7-67ZOJBE-WHDWEQX";
|
||||
zeus.id = "5BUZIS5-ESTYAJO-IQQD7EA-O3VGONJ-E74OHUJ-ZSLF4JK-6HS3UHG-4CQ5OAO";
|
||||
pegasus.id = "BISYPNZ-54VKBKS-LBND4AS-JNWVOW7-BTW2UMV-QHYM5TZ-GE3AK3E-PGSXPQE";
|
||||
hera.id = "TJHVUM6-RTB6V3D-JF4GIB2-TVDF2ST-5MTN6N2-ZDIWGF7-XZUCCFG-EQG5WA6";
|
||||
};
|
||||
in {
|
||||
devices = pkgs.lib.getAttrs hosts devices;
|
||||
folders = {
|
||||
science = mkFolder "science";
|
||||
documents = mkFolder "documents";
|
||||
audio = mkFolder "audio";
|
||||
video = mkFolder "video";
|
||||
images = mkFolder "images";
|
||||
books = mkFolder "books";
|
||||
tmp = mkFolder "tmp";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{ config, pkgs, lib, ... }:
|
||||
with lib; {
|
||||
config = {
|
||||
m-0.monitoring = [
|
||||
|
@ -55,8 +50,8 @@ with lib; {
|
|||
monitoring = mkOption {
|
||||
type = types.listOf (types.submodule {
|
||||
options = {
|
||||
name = mkOption {type = types.str;};
|
||||
host = mkOption {type = types.str;};
|
||||
name = mkOption { type = types.str; };
|
||||
host = mkOption { type = types.str; };
|
||||
container = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
|
@ -67,18 +62,13 @@ with lib; {
|
|||
};
|
||||
};
|
||||
});
|
||||
default = [];
|
||||
default = [ ];
|
||||
};
|
||||
headscaleIPs = mkOption {
|
||||
type = types.listOf types.string;
|
||||
default = [
|
||||
"100.64.7.0/24"
|
||||
"fd7a:115c:a1e0:77::/64"
|
||||
];
|
||||
};
|
||||
virtualHosts = mkOption {
|
||||
type = types.attrs;
|
||||
default = [ "100.64.7.0/24" "fd7a:115c:a1e0:77::/64" ];
|
||||
};
|
||||
virtualHosts = mkOption { type = types.attrs; };
|
||||
hosts = mkOption {
|
||||
type = types.attrs;
|
||||
default = let
|
||||
|
@ -99,14 +89,7 @@ with lib; {
|
|||
# (echo '{' && tailscale status -json | jq -r '.Self,.Peer[] | .DNSName[:-17] + " = { A = \"" + .TailscaleIPs[0] + "\"; AAAA = \"" + .TailscaleIPs[1] + "\";};"' && echo '}') > common/tailscale.nix
|
||||
tailscale = import ./tailscale.nix;
|
||||
publicAliases = {
|
||||
hera = [
|
||||
"blog"
|
||||
"cloud"
|
||||
"git"
|
||||
"lists"
|
||||
"matrix"
|
||||
"rpg"
|
||||
];
|
||||
hera = [ "blog" "cloud" "git" "lists" "matrix" "rpg" ];
|
||||
};
|
||||
aliases = {
|
||||
hera = [
|
||||
|
@ -131,9 +114,9 @@ with lib; {
|
|||
"tasks"
|
||||
"taskserver"
|
||||
];
|
||||
fluffy = ["home" "syncthing-fluffy" "5e"];
|
||||
zeus = ["syncthing-zeus"];
|
||||
apollo = ["syncthing-apollo"];
|
||||
fluffy = [ "home" "syncthing-fluffy" "5e" ];
|
||||
zeus = [ "syncthing-zeus" ];
|
||||
apollo = [ "syncthing-apollo" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
inputs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
{ inputs, config, ... }: {
|
||||
imports = [
|
||||
inputs.pre-commit-hooks.flakeModule
|
||||
./nixos/flake-module.nix
|
||||
|
@ -10,22 +6,17 @@
|
|||
./packages/flake-module.nix
|
||||
./overlays/flake-module.nix
|
||||
];
|
||||
systems = ["x86_64-linux"];
|
||||
perSystem = {
|
||||
inputs',
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
systems = [ "x86_64-linux" ];
|
||||
perSystem = { inputs', lib, config, pkgs, ... }: {
|
||||
devShells = {
|
||||
default = pkgs.mkShell {
|
||||
shellHook = config.pre-commit.installationScript;
|
||||
};
|
||||
default =
|
||||
pkgs.mkShell { shellHook = config.pre-commit.installationScript; };
|
||||
};
|
||||
checks = {
|
||||
system-checks = pkgs.recursiveLinkFarm "all-configs" {
|
||||
nixos-configurations = lib.mapAttrs (_: config: config.config.system.build.toplevel) inputs.self.nixosConfigurations;
|
||||
nixos-configurations =
|
||||
lib.mapAttrs (_: config: config.config.system.build.toplevel)
|
||||
inputs.self.nixosConfigurations;
|
||||
home-manager-configurations = inputs.self.homeModes;
|
||||
};
|
||||
};
|
||||
|
@ -42,8 +33,10 @@
|
|||
];
|
||||
hooks = {
|
||||
hlint.enable = true;
|
||||
alejandra.enable = true;
|
||||
nix-linter.enable = false; # Too many false positives for now
|
||||
nixfmt.enable = true;
|
||||
#nil.enable = true;
|
||||
#editorconfig-checker.enable = true;
|
||||
#deadnix.enable = true;
|
||||
statix.enable = true;
|
||||
fourmolu.enable = true;
|
||||
shellcheck.enable = true;
|
||||
|
|
12
flake.nix
12
flake.nix
|
@ -32,13 +32,12 @@
|
|||
nixpkgs-22_11.follows = "";
|
||||
blobs.follows = "";
|
||||
};
|
||||
url = "git+https://gitlab.com/simple-nixos-mailserver/nixos-mailserver.git";
|
||||
url =
|
||||
"git+https://gitlab.com/simple-nixos-mailserver/nixos-mailserver.git";
|
||||
};
|
||||
home-manager = {
|
||||
url = "home-manager/master";
|
||||
inputs = {
|
||||
nixpkgs.follows = "";
|
||||
};
|
||||
inputs = { nixpkgs.follows = ""; };
|
||||
};
|
||||
hexa-nur-packages = {
|
||||
url = "github:mweinelt/nur-packages";
|
||||
|
@ -60,6 +59,7 @@
|
|||
};
|
||||
};
|
||||
|
||||
outputs = inputs @ {nixos-hardware, ...}:
|
||||
inputs.flake-parts.lib.mkFlake {inherit inputs;} (import ./flake-module.nix);
|
||||
outputs = inputs@{ nixos-hardware, ... }:
|
||||
inputs.flake-parts.lib.mkFlake { inherit inputs; }
|
||||
(import ./flake-module.nix);
|
||||
}
|
||||
|
|
|
@ -1,50 +1,36 @@
|
|||
{
|
||||
withSystem,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
flake = withSystem "x86_64-linux" ({
|
||||
self',
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
flattenAttrs = attrs:
|
||||
lib.listToAttrs (lib.flatten (lib.mapAttrsToList
|
||||
(
|
||||
outer_key:
|
||||
lib.mapAttrsToList
|
||||
(inner_key: value: {
|
||||
name = "${outer_key}-${inner_key}";
|
||||
inherit value;
|
||||
})
|
||||
)
|
||||
attrs));
|
||||
machines = import ./machines.nix;
|
||||
buildHomeManager = config: (inputs.home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
modules = [
|
||||
config
|
||||
inputs.emanote.homeManagerModule
|
||||
inputs.nix-index-database.hmModules.nix-index
|
||||
];
|
||||
{ withSystem, lib, inputs, ... }: {
|
||||
flake = withSystem "x86_64-linux" ({ self', pkgs, ... }:
|
||||
let
|
||||
flattenAttrs = attrs:
|
||||
lib.listToAttrs (lib.flatten (lib.mapAttrsToList (outer_key:
|
||||
lib.mapAttrsToList (inner_key: value: {
|
||||
name = "${outer_key}-${inner_key}";
|
||||
inherit value;
|
||||
})) attrs));
|
||||
machines = import ./machines.nix;
|
||||
buildHomeManager = config:
|
||||
(inputs.home-manager.lib.homeManagerConfiguration {
|
||||
inherit pkgs;
|
||||
modules = [
|
||||
config
|
||||
inputs.emanote.homeManagerModule
|
||||
inputs.nix-index-database.hmModules.nix-index
|
||||
];
|
||||
});
|
||||
buildModesForHost = host: modes:
|
||||
(pkgs.recursiveLinkFarm "${host}-modes"
|
||||
(lib.mapAttrs (_: config: (buildHomeManager config).activationPackage)
|
||||
modes)).overrideAttrs (old: {
|
||||
buildCommand = if inputs.self.sourceInfo ? rev then ''
|
||||
${old.buildCommand}
|
||||
echo ${inputs.self.sourceInfo.rev} > $out/config-commit;
|
||||
'' else
|
||||
old.buildCommand;
|
||||
});
|
||||
in {
|
||||
homeConfigurations =
|
||||
lib.mapAttrs (_: buildHomeManager) (flattenAttrs machines);
|
||||
homeModes =
|
||||
lib.mapAttrs buildModesForHost { inherit (machines) zeus apollo; };
|
||||
});
|
||||
buildModesForHost = host: modes:
|
||||
(pkgs.recursiveLinkFarm "${host}-modes"
|
||||
(lib.mapAttrs
|
||||
(_: config: (buildHomeManager config).activationPackage)
|
||||
modes))
|
||||
.overrideAttrs (old: {
|
||||
buildCommand =
|
||||
if inputs.self.sourceInfo ? rev
|
||||
then ''
|
||||
${old.buildCommand}
|
||||
echo ${inputs.self.sourceInfo.rev} > $out/config-commit;
|
||||
''
|
||||
else old.buildCommand;
|
||||
});
|
||||
in {
|
||||
homeConfigurations = lib.mapAttrs (_: buildHomeManager) (flattenAttrs machines);
|
||||
homeModes = lib.mapAttrs buildModesForHost {inherit (machines) zeus apollo;};
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,20 +1,18 @@
|
|||
let
|
||||
restrictedPages =
|
||||
[
|
||||
"reddit.com"
|
||||
"github.com"
|
||||
"*.ccc.de"
|
||||
"haskell.org"
|
||||
"*.haskell.org"
|
||||
"*.nixos.org"
|
||||
"nixos.org"
|
||||
"matrix.org"
|
||||
"element.io"
|
||||
"youtube.*"
|
||||
"*.element.io"
|
||||
"twitter.com"
|
||||
]
|
||||
++ newsPages;
|
||||
restrictedPages = [
|
||||
"reddit.com"
|
||||
"github.com"
|
||||
"*.ccc.de"
|
||||
"haskell.org"
|
||||
"*.haskell.org"
|
||||
"*.nixos.org"
|
||||
"nixos.org"
|
||||
"matrix.org"
|
||||
"element.io"
|
||||
"youtube.*"
|
||||
"*.element.io"
|
||||
"twitter.com"
|
||||
] ++ newsPages;
|
||||
newsPages = [
|
||||
"chaos.social"
|
||||
"zeit.de"
|
||||
|
@ -33,26 +31,19 @@ let
|
|||
];
|
||||
|
||||
makeConfig = hostName: imports: _: {
|
||||
imports = imports ++ [./roles/default.nix];
|
||||
imports = imports ++ [ ./roles/default.nix ];
|
||||
m-0.hostName = hostName;
|
||||
};
|
||||
makeAutostart = name: {config, ...}: {
|
||||
config.xdg.configFile."autostart/${name}.desktop".source = "${config.home.path}/share/applications/${name}.desktop";
|
||||
};
|
||||
orga-basics = [
|
||||
./roles/mail.nix
|
||||
./roles/taskwarrior.nix
|
||||
];
|
||||
default = [
|
||||
./roles/on-my-machine.nix
|
||||
./roles/systemd-exporter.nix
|
||||
];
|
||||
daily-driver = name: extra: let
|
||||
all =
|
||||
extra
|
||||
++ orga-basics
|
||||
++ default
|
||||
++ [
|
||||
makeAutostart = name:
|
||||
{ config, ... }: {
|
||||
config.xdg.configFile."autostart/${name}.desktop".source =
|
||||
"${config.home.path}/share/applications/${name}.desktop";
|
||||
};
|
||||
orga-basics = [ ./roles/mail.nix ./roles/taskwarrior.nix ];
|
||||
default = [ ./roles/on-my-machine.nix ./roles/systemd-exporter.nix ];
|
||||
daily-driver = name: extra:
|
||||
let
|
||||
all = extra ++ orga-basics ++ default ++ [
|
||||
(makeAutostart "kassandra2")
|
||||
(makeAutostart "unlock-ssh")
|
||||
./roles/beets.nix
|
||||
|
@ -83,46 +74,30 @@ let
|
|||
./roles/wallpaper.nix
|
||||
./roles/zettelkasten.nix
|
||||
];
|
||||
blockServer = import ./roles/block-server.nix;
|
||||
in {
|
||||
klausur = makeConfig name (
|
||||
all
|
||||
++ [
|
||||
(blockServer restrictedPages)
|
||||
]
|
||||
);
|
||||
code = makeConfig name (
|
||||
all
|
||||
++ [
|
||||
blockServer = import ./roles/block-server.nix;
|
||||
in {
|
||||
klausur = makeConfig name (all ++ [ (blockServer restrictedPages) ]);
|
||||
code = makeConfig name (all ++ [
|
||||
./roles/mail-client.nix
|
||||
./roles/chat.nix
|
||||
(blockServer newsPages)
|
||||
]
|
||||
);
|
||||
leisure = makeConfig name (
|
||||
all
|
||||
++ [
|
||||
]);
|
||||
leisure = makeConfig name (all ++ [
|
||||
./roles/mail-client.nix
|
||||
./roles/games.nix
|
||||
./roles/chat.nix
|
||||
(blockServer newsPages)
|
||||
]
|
||||
);
|
||||
unrestricted = makeConfig name (
|
||||
all
|
||||
++ [
|
||||
]);
|
||||
unrestricted = makeConfig name (all ++ [
|
||||
./roles/mail-client.nix
|
||||
./roles/games.nix
|
||||
./roles/chat.nix
|
||||
(blockServer [])
|
||||
]
|
||||
);
|
||||
};
|
||||
(blockServer [ ])
|
||||
]);
|
||||
};
|
||||
in {
|
||||
apollo = daily-driver "apollo" [
|
||||
./roles/battery.nix
|
||||
./roles/untrusted-env.nix
|
||||
];
|
||||
apollo =
|
||||
daily-driver "apollo" [ ./roles/battery.nix ./roles/untrusted-env.nix ];
|
||||
zeus = daily-driver "zeus" [
|
||||
(import ./roles/state.nix "klausur")
|
||||
./roles/create-plans.nix
|
||||
|
@ -130,23 +105,14 @@ in {
|
|||
./roles/trusted-env.nix
|
||||
./roles/wine.nix
|
||||
];
|
||||
fluffy.default = makeConfig "fluffy" (
|
||||
default
|
||||
++ [
|
||||
./roles/headless.nix
|
||||
(import ./roles/state.nix "default")
|
||||
]
|
||||
);
|
||||
hera.default = makeConfig "hera" (
|
||||
default
|
||||
++ orga-basics
|
||||
++ [
|
||||
./roles/fetch-banking-timer.nix
|
||||
./roles/weechat
|
||||
./roles/mail-sort.nix
|
||||
./roles/mail2rss.nix
|
||||
./roles/headless-mpd.nix
|
||||
./roles/headless.nix
|
||||
]
|
||||
);
|
||||
fluffy.default = makeConfig "fluffy"
|
||||
(default ++ [ ./roles/headless.nix (import ./roles/state.nix "default") ]);
|
||||
hera.default = makeConfig "hera" (default ++ orga-basics ++ [
|
||||
./roles/fetch-banking-timer.nix
|
||||
./roles/weechat
|
||||
./roles/mail-sort.nix
|
||||
./roles/mail2rss.nix
|
||||
./roles/headless-mpd.nix
|
||||
./roles/headless.nix
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -1,69 +1,63 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
battery-watch =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "battery-watch";
|
||||
bins = [pkgs.acpi];
|
||||
imports = [
|
||||
"DBus.Notify"
|
||||
"Control.Concurrent"
|
||||
"Text.Megaparsec"
|
||||
"Text.Megaparsec.Char"
|
||||
"Text.Megaparsec.Char.Lexer"
|
||||
"Replace.Megaparsec"
|
||||
"Data.Maybe"
|
||||
];
|
||||
} ''
|
||||
moderateLevel = 50 -- percent
|
||||
lowLevel = 20 -- percent
|
||||
criticalLevel = 8 -- percent
|
||||
minute = 60 * 1000 * 1000 -- threadDelay takes microseconds
|
||||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
battery-watch = pkgs.writeHaskellScript {
|
||||
name = "battery-watch";
|
||||
bins = [ pkgs.acpi ];
|
||||
imports = [
|
||||
"DBus.Notify"
|
||||
"Control.Concurrent"
|
||||
"Text.Megaparsec"
|
||||
"Text.Megaparsec.Char"
|
||||
"Text.Megaparsec.Char.Lexer"
|
||||
"Replace.Megaparsec"
|
||||
"Data.Maybe"
|
||||
];
|
||||
} ''
|
||||
moderateLevel = 50 -- percent
|
||||
lowLevel = 20 -- percent
|
||||
criticalLevel = 8 -- percent
|
||||
minute = 60 * 1000 * 1000 -- threadDelay takes microseconds
|
||||
|
||||
main = do
|
||||
client <- connectSession
|
||||
let loop = \lastState handleMay -> do
|
||||
newState <- getState
|
||||
let noteMay = chooseAction lastState newState
|
||||
handle <- if | Just note <- noteMay -> Just <$> maybe (notify client note) (flip (replace client) note) handleMay
|
||||
| otherwise -> pure handleMay
|
||||
threadDelay $ minute `div` 4
|
||||
loop newState handle
|
||||
loop (BatState True 100) Nothing
|
||||
main = do
|
||||
client <- connectSession
|
||||
let loop = \lastState handleMay -> do
|
||||
newState <- getState
|
||||
let noteMay = chooseAction lastState newState
|
||||
handle <- if | Just note <- noteMay -> Just <$> maybe (notify client note) (flip (replace client) note) handleMay
|
||||
| otherwise -> pure handleMay
|
||||
threadDelay $ minute `div` 4
|
||||
loop newState handle
|
||||
loop (BatState True 100) Nothing
|
||||
|
||||
data BatState = BatState { charging :: Bool, level :: Int }
|
||||
data BatState = BatState { charging :: Bool, level :: Int }
|
||||
|
||||
getState = do
|
||||
batteryStateText <- decodeUtf8 <$> (acpi "-a" |> captureTrim)
|
||||
batteryLevelText <- decodeUtf8 <$> (acpi "-b" |> captureTrim)
|
||||
chargerOnline <- maybe (fail "Couldn‘t get charging state") pure $ parseMaybe onlineParser batteryStateText
|
||||
batteryLevel <- maybe (fail "Couldn‘t get battery level") pure $ parseMaybe levelParser batteryLevelText
|
||||
pure $ BatState chargerOnline batteryLevel
|
||||
getState = do
|
||||
batteryStateText <- decodeUtf8 <$> (acpi "-a" |> captureTrim)
|
||||
batteryLevelText <- decodeUtf8 <$> (acpi "-b" |> captureTrim)
|
||||
chargerOnline <- maybe (fail "Couldn‘t get charging state") pure $ parseMaybe onlineParser batteryStateText
|
||||
batteryLevel <- maybe (fail "Couldn‘t get battery level") pure $ parseMaybe levelParser batteryLevelText
|
||||
pure $ BatState chargerOnline batteryLevel
|
||||
|
||||
type Parser = Parsec Text LText
|
||||
type Parser = Parsec Text LText
|
||||
|
||||
onlineParser :: Parser Bool
|
||||
onlineParser = not . null . rights <$> sepCap (string "on-line")
|
||||
onlineParser :: Parser Bool
|
||||
onlineParser = not . null . rights <$> sepCap (string "on-line")
|
||||
|
||||
levelParser :: Parser Int
|
||||
levelParser = (maybe (fail "No Number found") pure . listToMaybe . rights) =<< sepCap (decimal <* "%")
|
||||
levelParser :: Parser Int
|
||||
levelParser = (maybe (fail "No Number found") pure . listToMaybe . rights) =<< sepCap (decimal <* "%")
|
||||
|
||||
chooseAction :: BatState -> BatState -> Maybe Note
|
||||
chooseAction (BatState wasCharging lastLevel) (BatState isCharging currentLevel)
|
||||
| wasCharging && isCharging = Nothing
|
||||
| wasCharging && not isCharging = Just $ myNote{summary = "Charger disconnected." }
|
||||
| not wasCharging && isCharging = Just $ myNote{summary = "Charger connected.", expiry = Milliseconds 5000 }
|
||||
| currentLevel <= criticalLevel = Just $ myNote{summary = "Battery is very low!" }
|
||||
| currentLevel <= lowLevel && currentLevel < lastLevel = Just $ myNote{summary = "Battery is low!"}
|
||||
| ((currentLevel `mod` 5 == 0 && currentLevel <= moderateLevel) || (currentLevel `mod` 10 == 0)) && currentLevel < lastLevel = Just $ myNote{summary = "Battery is discharging."}
|
||||
| otherwise = Nothing
|
||||
where
|
||||
myNote = blankNote { body = Just $ Text [i|#{currentLevel}% remaining.|]}
|
||||
'';
|
||||
chooseAction :: BatState -> BatState -> Maybe Note
|
||||
chooseAction (BatState wasCharging lastLevel) (BatState isCharging currentLevel)
|
||||
| wasCharging && isCharging = Nothing
|
||||
| wasCharging && not isCharging = Just $ myNote{summary = "Charger disconnected." }
|
||||
| not wasCharging && isCharging = Just $ myNote{summary = "Charger connected.", expiry = Milliseconds 5000 }
|
||||
| currentLevel <= criticalLevel = Just $ myNote{summary = "Battery is very low!" }
|
||||
| currentLevel <= lowLevel && currentLevel < lastLevel = Just $ myNote{summary = "Battery is low!"}
|
||||
| ((currentLevel `mod` 5 == 0 && currentLevel <= moderateLevel) || (currentLevel `mod` 10 == 0)) && currentLevel < lastLevel = Just $ myNote{summary = "Battery is discharging."}
|
||||
| otherwise = Nothing
|
||||
where
|
||||
myNote = blankNote { body = Just $ Text [i|#{currentLevel}% remaining.|]}
|
||||
'';
|
||||
in {
|
||||
systemd.user = {
|
||||
services.battery = {
|
||||
|
@ -73,7 +67,7 @@ in {
|
|||
Restart = "always";
|
||||
RestartSec = 60;
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, config, ... }: {
|
||||
xdg.configFile."beets/config.yaml".text = builtins.toJSON {
|
||||
directory = config.services.mpd.musicDirectory;
|
||||
import.move = true;
|
||||
paths = {
|
||||
default = "$genre/%the{$albumartist}/$album/%if{$multidisc,Disc $disc/}$track. $title";
|
||||
default =
|
||||
"$genre/%the{$albumartist}/$album/%if{$multidisc,Disc $disc/}$track. $title";
|
||||
singleton = "$genre/%the{$artist}/singles/$title";
|
||||
comp = "$genre/%the{$artist}/$album%/%if{$multidisc,Disc $disc/}$track. $title";
|
||||
"genre:soundtrack" = "Soundtrack/$album/%if{$multidisc,Disc $disc/}$track. $title";
|
||||
comp =
|
||||
"$genre/%the{$artist}/$album%/%if{$multidisc,Disc $disc/}$track. $title";
|
||||
"genre:soundtrack" =
|
||||
"Soundtrack/$album/%if{$multidisc,Disc $disc/}$track. $title";
|
||||
};
|
||||
plugins = "convert web fromfilename the duplicates missing inline";
|
||||
item_fields.multidisc = "1 if disctotal > 1 else 0";
|
||||
convert = {
|
||||
auto = true;
|
||||
command = "${pkgs.ffmpeg}/bin/ffmpeg -i $source -y -vn -acodec libopus -ab 192k $dest";
|
||||
command =
|
||||
"${pkgs.ffmpeg}/bin/ffmpeg -i $source -y -vn -acodec libopus -ab 192k $dest";
|
||||
extension = "opus";
|
||||
never_convert_lossy_files = true;
|
||||
};
|
||||
|
|
|
@ -1,19 +1,16 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
package = pkgs.rbw.override {
|
||||
withFzf = true;
|
||||
withPass = true;
|
||||
};
|
||||
rbw-totp-fzf = pkgs.runCommand "rbw-totp-fzf" {} ''
|
||||
rbw-totp-fzf = pkgs.runCommand "rbw-totp-fzf" { } ''
|
||||
mkdir -p $out/bin
|
||||
cp ${package}/bin/rbw-fzf $out/bin/rbw-totp-fzf
|
||||
${lib.getExe pkgs.sd} "rbw get" "rbw code" $out/bin/rbw-totp-fzf
|
||||
'';
|
||||
in {
|
||||
home.packages = [rbw-totp-fzf];
|
||||
home.packages = [ rbw-totp-fzf ];
|
||||
programs.rbw = {
|
||||
enable = true;
|
||||
inherit package;
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
list: {
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
list:
|
||||
{ pkgs, lib, ... }: {
|
||||
systemd.user.services.blockserver = {
|
||||
Unit.Description = "Serve a blocklist";
|
||||
Service = let
|
||||
blocklist = pkgs.writeTextDir "blocklist" (lib.concatStringsSep "\r\n" list);
|
||||
startpage = pkgs.writeTextDir "index.html" (builtins.readFile ./startpage.html);
|
||||
blocklist =
|
||||
pkgs.writeTextDir "blocklist" (lib.concatStringsSep "\r\n" list);
|
||||
startpage =
|
||||
pkgs.writeTextDir "index.html" (builtins.readFile ./startpage.html);
|
||||
in {
|
||||
ExecStart = "${pkgs.python3}/bin/python -m http.server --bind :: 8842 -d ${
|
||||
pkgs.symlinkJoin {
|
||||
name = "blockserver-dir";
|
||||
paths = [blocklist startpage];
|
||||
}
|
||||
}";
|
||||
ExecStart =
|
||||
"${pkgs.python3}/bin/python -m http.server --bind :: 8842 -d ${
|
||||
pkgs.symlinkJoin {
|
||||
name = "blockserver-dir";
|
||||
paths = [ blocklist startpage ];
|
||||
}
|
||||
}";
|
||||
Restart = "always";
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages =
|
||||
builtins.attrValues
|
||||
{
|
||||
inherit (pkgs) discord signal-desktop tdesktop element-desktop;
|
||||
weechat = pkgs.writeShellScriptBin "weechat" "ssh -t hera 'TMUX_TMPDIR=/run/user/1000 tmux -L weechat attach'";
|
||||
};
|
||||
xdg.configFile."Element/config.json".text = builtins.toJSON {
|
||||
showLabsSettings = true;
|
||||
{ pkgs, ... }: {
|
||||
home.packages = builtins.attrValues {
|
||||
inherit (pkgs) discord signal-desktop tdesktop element-desktop;
|
||||
weechat = pkgs.writeShellScriptBin "weechat"
|
||||
"ssh -t hera 'TMUX_TMPDIR=/run/user/1000 tmux -L weechat attach'";
|
||||
};
|
||||
xdg.configFile."Element/config.json".text =
|
||||
builtins.toJSON { showLabsSettings = true; };
|
||||
}
|
||||
|
|
|
@ -1,74 +1,65 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
dimensions = "20,130";
|
||||
service = name: {
|
||||
extra,
|
||||
text,
|
||||
wait,
|
||||
}: let
|
||||
config-file = builtins.toFile "conky-${name}.conf" ''
|
||||
conky.config = {
|
||||
background = false,
|
||||
border_width = 0,
|
||||
cpu_avg_samples = 2,
|
||||
double_buffer = true,
|
||||
draw_borders = false,
|
||||
draw_graph_borders = false,
|
||||
draw_outline = false,
|
||||
draw_shades = false,
|
||||
extra_newline = false,
|
||||
font = 'CozetteVector:pixelsize=12',
|
||||
gap_y = 1,
|
||||
minimum_height = 5,
|
||||
minimum_width = 2,
|
||||
max_text_width = 25,
|
||||
net_avg_samples = 2,
|
||||
no_buffers = true,
|
||||
out_to_console = false,
|
||||
out_to_ncurses = false,
|
||||
out_to_stderr = false,
|
||||
out_to_x = true,
|
||||
own_window = true,
|
||||
own_window_class = 'Conky',
|
||||
own_window_type = 'panel',
|
||||
own_window_argb_visual = true,
|
||||
own_window_argb_value = 0,
|
||||
show_graph_range = false,
|
||||
show_graph_scale = false,
|
||||
stippled_borders = 0,
|
||||
color0 = 'd9e0ee',
|
||||
color1 = '9999ff',
|
||||
uppercase = false,
|
||||
use_spacer = 'none',
|
||||
use_xft = true,
|
||||
${extra}
|
||||
}
|
||||
conky.text = [[
|
||||
${text}
|
||||
]]
|
||||
'';
|
||||
in {
|
||||
name = "conky-${name}";
|
||||
value = {
|
||||
Unit = {
|
||||
Description = "Run conky ${name}";
|
||||
};
|
||||
Service = {
|
||||
ExecStart =
|
||||
(pkgs.writeShellScript "conky-${name}" ''
|
||||
service = name:
|
||||
{ extra, text, wait, }:
|
||||
let
|
||||
config-file = builtins.toFile "conky-${name}.conf" ''
|
||||
conky.config = {
|
||||
background = false,
|
||||
border_width = 0,
|
||||
cpu_avg_samples = 2,
|
||||
double_buffer = true,
|
||||
draw_borders = false,
|
||||
draw_graph_borders = false,
|
||||
draw_outline = false,
|
||||
draw_shades = false,
|
||||
extra_newline = false,
|
||||
font = 'CozetteVector:pixelsize=12',
|
||||
gap_y = 1,
|
||||
minimum_height = 5,
|
||||
minimum_width = 2,
|
||||
max_text_width = 25,
|
||||
net_avg_samples = 2,
|
||||
no_buffers = true,
|
||||
out_to_console = false,
|
||||
out_to_ncurses = false,
|
||||
out_to_stderr = false,
|
||||
out_to_x = true,
|
||||
own_window = true,
|
||||
own_window_class = 'Conky',
|
||||
own_window_type = 'panel',
|
||||
own_window_argb_visual = true,
|
||||
own_window_argb_value = 0,
|
||||
show_graph_range = false,
|
||||
show_graph_scale = false,
|
||||
stippled_borders = 0,
|
||||
color0 = 'd9e0ee',
|
||||
color1 = '9999ff',
|
||||
uppercase = false,
|
||||
use_spacer = 'none',
|
||||
use_xft = true,
|
||||
${extra}
|
||||
}
|
||||
conky.text = [[
|
||||
${text}
|
||||
]]
|
||||
'';
|
||||
in {
|
||||
name = "conky-${name}";
|
||||
value = {
|
||||
Unit = { Description = "Run conky ${name}"; };
|
||||
Service = {
|
||||
ExecStart = (pkgs.writeShellScript "conky-${name}" ''
|
||||
${lib.getExe pkgs.conky} -i ${toString wait} -c ${config-file}
|
||||
${lib.getExe pkgs.conky} -c ${config-file}
|
||||
'')
|
||||
.outPath;
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
'').outPath;
|
||||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
};
|
||||
};
|
||||
in {
|
||||
systemd.user.services = lib.mapAttrs' service {
|
||||
status = {
|
||||
|
|
|
@ -1,35 +1,25 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
plans =
|
||||
pkgs.privateValue
|
||||
{
|
||||
"workDay" = "pass";
|
||||
"weekend" = "pass";
|
||||
}
|
||||
"plans";
|
||||
createPlans =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "create-plans";
|
||||
bins = [pkgs.khal pkgs.vdirsyncer];
|
||||
imports = [
|
||||
"Data.Time"
|
||||
];
|
||||
} ''
|
||||
main = do
|
||||
today <- localDay . zonedTimeToLocalTime <$> getZonedTime
|
||||
[0..7] & fmap (`addDays` today) & mapM_ \day -> do
|
||||
planned <- khal ["list", "-a", "Planung", show day, "06:00", "24h", "--notstarted"] |> captureTrim
|
||||
when (LBS.null planned) $ do
|
||||
say $ "Creating events for " <> show day
|
||||
if (dayOfWeek day `elem` [Saturday, Sunday]) then do
|
||||
${plans.weekend}
|
||||
else do
|
||||
${plans.workDay}
|
||||
'';
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
plans = pkgs.privateValue {
|
||||
"workDay" = "pass";
|
||||
"weekend" = "pass";
|
||||
} "plans";
|
||||
createPlans = pkgs.writeHaskellScript {
|
||||
name = "create-plans";
|
||||
bins = [ pkgs.khal pkgs.vdirsyncer ];
|
||||
imports = [ "Data.Time" ];
|
||||
} ''
|
||||
main = do
|
||||
today <- localDay . zonedTimeToLocalTime <$> getZonedTime
|
||||
[0..7] & fmap (`addDays` today) & mapM_ \day -> do
|
||||
planned <- khal ["list", "-a", "Planung", show day, "06:00", "24h", "--notstarted"] |> captureTrim
|
||||
when (LBS.null planned) $ do
|
||||
say $ "Creating events for " <> show day
|
||||
if (dayOfWeek day `elem` [Saturday, Sunday]) then do
|
||||
${plans.weekend}
|
||||
else do
|
||||
${plans.workDay}
|
||||
'';
|
||||
sync = "${lib.getExe pkgs.vdirsyncer} sync nextcloud_calendar/planung";
|
||||
in {
|
||||
systemd.user = {
|
||||
|
@ -37,15 +27,12 @@ in {
|
|||
Unit.Description = "Create planning appointments in calendar";
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
ExecStart =
|
||||
(
|
||||
pkgs.writeShellScript "update-plans" (lib.concatStringsSep "\n" [
|
||||
"set -e"
|
||||
sync
|
||||
(lib.getExe createPlans)
|
||||
])
|
||||
)
|
||||
.outPath;
|
||||
ExecStart = (pkgs.writeShellScript "update-plans"
|
||||
(lib.concatStringsSep "\n" [
|
||||
"set -e"
|
||||
sync
|
||||
(lib.getExe createPlans)
|
||||
])).outPath;
|
||||
Restart = "on-failure";
|
||||
RestartSec = 60;
|
||||
};
|
||||
|
@ -53,7 +40,7 @@ in {
|
|||
timers.create-plans = {
|
||||
Unit.Description = "Create planning appointments in calendar";
|
||||
Timer.OnCalendar = "00:01:00";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, config, lib, ... }: {
|
||||
imports = [
|
||||
./zsh
|
||||
./home-options.nix
|
||||
|
@ -69,7 +64,8 @@
|
|||
git = {
|
||||
aliases = {
|
||||
sync = "!git pull -r && git push";
|
||||
cpr = "!f() { git fetch origin refs/pull/$1/head && git checkout FETCH_HEAD; }; f";
|
||||
cpr =
|
||||
"!f() { git fetch origin refs/pull/$1/head && git checkout FETCH_HEAD; }; f";
|
||||
};
|
||||
|
||||
extraConfig = {
|
||||
|
@ -131,60 +127,33 @@
|
|||
};
|
||||
|
||||
home = {
|
||||
packages =
|
||||
builtins.attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
go
|
||||
gdb
|
||||
mpc_cli
|
||||
ncmpcpp
|
||||
shfmt
|
||||
astyle
|
||||
nodejs
|
||||
tasksh
|
||||
magic-wormhole
|
||||
alejandra
|
||||
nix-top
|
||||
nix-diff
|
||||
matrix-commander
|
||||
upterm
|
||||
lazygit
|
||||
gh
|
||||
ledger
|
||||
aqbanking
|
||||
;
|
||||
inherit (pkgs.haskellPackages) hledger hledger-ui hledger-web;
|
||||
mytmux = pkgs.writeShellScriptBin "mytmux" ''
|
||||
session=$(${pkgs.tmux}/bin/tmux ls | grep -v attached | head -1 | cut -f1 -d:)
|
||||
if [[ -n $session ]]; then
|
||||
exec ${pkgs.tmux}/bin/tmux attach -t $session;
|
||||
else
|
||||
exec ${pkgs.tmux}/bin/tmux;
|
||||
fi
|
||||
'';
|
||||
}
|
||||
++ [
|
||||
(
|
||||
pkgs.writeShellScriptBin "unlock-ssh" ''
|
||||
SSH_ASKPASS="print-ssh-pw" DISPLAY="a" ssh-add < /dev/null
|
||||
''
|
||||
)
|
||||
(
|
||||
pkgs.writeShellScriptBin "print-ssh-pw"
|
||||
"rbw get ${config.m-0.hostName}.m-0.eu ssh-key"
|
||||
)
|
||||
(
|
||||
pkgs.writeShellScriptBin "dingdingding" (builtins.readFile ./signal.sh)
|
||||
)
|
||||
];
|
||||
packages = builtins.attrValues {
|
||||
inherit (pkgs)
|
||||
go gdb mpc_cli ncmpcpp shfmt astyle nodejs tasksh magic-wormhole
|
||||
alejandra nix-top nix-diff matrix-commander upterm lazygit gh ledger
|
||||
aqbanking;
|
||||
inherit (pkgs.haskellPackages) hledger hledger-ui hledger-web;
|
||||
mytmux = pkgs.writeShellScriptBin "mytmux" ''
|
||||
session=$(${pkgs.tmux}/bin/tmux ls | grep -v attached | head -1 | cut -f1 -d:)
|
||||
if [[ -n $session ]]; then
|
||||
exec ${pkgs.tmux}/bin/tmux attach -t $session;
|
||||
else
|
||||
exec ${pkgs.tmux}/bin/tmux;
|
||||
fi
|
||||
'';
|
||||
} ++ [
|
||||
(pkgs.writeShellScriptBin "unlock-ssh" ''
|
||||
SSH_ASKPASS="print-ssh-pw" DISPLAY="a" ssh-add < /dev/null
|
||||
'')
|
||||
(pkgs.writeShellScriptBin "print-ssh-pw"
|
||||
"rbw get ${config.m-0.hostName}.m-0.eu ssh-key")
|
||||
(pkgs.writeShellScriptBin "dingdingding" (builtins.readFile ./signal.sh))
|
||||
];
|
||||
sessionVariables = {
|
||||
PATH = "$HOME/.nix-profile/bin:$PATH";
|
||||
BROWSER = "firefox";
|
||||
SUDO_ASKPASS = toString (
|
||||
pkgs.writeShellScript "print-sudo-pw"
|
||||
"rbw get ${config.m-0.hostName}.m-0.eu ${config.home.username}"
|
||||
);
|
||||
SUDO_ASKPASS = toString (pkgs.writeShellScript "print-sudo-pw"
|
||||
"rbw get ${config.m-0.hostName}.m-0.eu ${config.home.username}");
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -208,17 +177,17 @@
|
|||
mimeApps = {
|
||||
enable = true;
|
||||
defaultApplications = {
|
||||
"application/pdf" = ["org.gnome.Evince.desktop"];
|
||||
"x-scheme-handler/http" = ["firefox.desktop"];
|
||||
"x-scheme-handler/https" = ["firefox.desktop"];
|
||||
"x-scheme-handler/chrome" = ["firefox.desktop"];
|
||||
"text/html" = ["firefox.desktop"];
|
||||
"application/x-extension-htm" = ["firefox.desktop"];
|
||||
"application/x-extension-html" = ["firefox.desktop"];
|
||||
"application/x-extension-shtml" = ["firefox.desktop"];
|
||||
"application/xhtml+xml" = ["firefox.desktop"];
|
||||
"application/x-extension-xhtml" = ["firefox.desktop"];
|
||||
"application/x-extension-xht" = ["firefox.desktop"];
|
||||
"application/pdf" = [ "org.gnome.Evince.desktop" ];
|
||||
"x-scheme-handler/http" = [ "firefox.desktop" ];
|
||||
"x-scheme-handler/https" = [ "firefox.desktop" ];
|
||||
"x-scheme-handler/chrome" = [ "firefox.desktop" ];
|
||||
"text/html" = [ "firefox.desktop" ];
|
||||
"application/x-extension-htm" = [ "firefox.desktop" ];
|
||||
"application/x-extension-html" = [ "firefox.desktop" ];
|
||||
"application/x-extension-shtml" = [ "firefox.desktop" ];
|
||||
"application/xhtml+xml" = [ "firefox.desktop" ];
|
||||
"application/x-extension-xhtml" = [ "firefox.desktop" ];
|
||||
"application/x-extension-xht" = [ "firefox.desktop" ];
|
||||
};
|
||||
};
|
||||
userDirs = {
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
simpleDesktopItem = name: command:
|
||||
pkgs.makeDesktopItem {
|
||||
inherit name;
|
||||
|
@ -19,5 +16,6 @@
|
|||
superSimpleDesktopItem = name: simpleDesktopItem name name;
|
||||
terminalDesktopItem = name: namedTerminalDesktopItem name name;
|
||||
in {
|
||||
home.packages = map superSimpleDesktopItem ["kassandra2"] ++ map terminalDesktopItem ["unlock-ssh"];
|
||||
home.packages = map superSimpleDesktopItem [ "kassandra2" ]
|
||||
++ map terminalDesktopItem [ "unlock-ssh" ];
|
||||
}
|
||||
|
|
|
@ -1,18 +1,12 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, config, ... }: {
|
||||
home = {
|
||||
# This fixes border drawing but makes neo wonky. sessionVariables.NIXOS_OZONE_WL = "1";
|
||||
packages = builtins.attrValues {
|
||||
zoom = pkgs.zoom-us.overrideAttrs (old: {
|
||||
postFixup =
|
||||
old.postFixup
|
||||
+ ''
|
||||
wrapProgram $out/bin/zoom-us --unset XDG_SESSION_TYPE
|
||||
wrapProgram $out/bin/zoom --unset XDG_SESSION_TYPE
|
||||
'';
|
||||
postFixup = old.postFixup + ''
|
||||
wrapProgram $out/bin/zoom-us --unset XDG_SESSION_TYPE
|
||||
wrapProgram $out/bin/zoom --unset XDG_SESSION_TYPE
|
||||
'';
|
||||
});
|
||||
mic-check = pkgs.writeShellScriptBin "mic-check" ''
|
||||
echo "Activating loopback!"
|
||||
|
@ -26,72 +20,37 @@
|
|||
|
||||
inherit (pkgs.gnome) nautilus;
|
||||
inherit (pkgs.xorg) xbacklight;
|
||||
inherit
|
||||
(pkgs)
|
||||
# web
|
||||
|
||||
chromium
|
||||
mumble
|
||||
upower
|
||||
speedtest-cli
|
||||
acpi
|
||||
inherit (pkgs)
|
||||
# web
|
||||
|
||||
chromium mumble upower speedtest-cli acpi
|
||||
# tools & office
|
||||
|
||||
feh
|
||||
gimp
|
||||
imagemagick
|
||||
libreoffice-fresh
|
||||
xournal
|
||||
musescore
|
||||
handbrake
|
||||
evince
|
||||
abcde
|
||||
beets
|
||||
zbar
|
||||
|
||||
feh gimp imagemagick libreoffice-fresh xournal musescore handbrake
|
||||
evince abcde beets zbar
|
||||
# media
|
||||
|
||||
ncpamixer
|
||||
pavucontrol
|
||||
playerctl
|
||||
deluge
|
||||
gmpc
|
||||
vlc
|
||||
yt-dlp
|
||||
spotdl
|
||||
ffmpeg
|
||||
syncplay
|
||||
esphome
|
||||
|
||||
ncpamixer pavucontrol playerctl deluge gmpc vlc yt-dlp spotdl ffmpeg
|
||||
syncplay esphome
|
||||
# To flash devices
|
||||
|
||||
|
||||
esptool
|
||||
# provides esptool.py
|
||||
|
||||
lm_sensors
|
||||
xwayland
|
||||
xdg_utils
|
||||
libnotify
|
||||
shotcut
|
||||
audacity
|
||||
paprefs
|
||||
wl-clipboard
|
||||
dconf2nix
|
||||
chrysalis
|
||||
;
|
||||
inherit
|
||||
(pkgs.gnome)
|
||||
dconf-editor
|
||||
gnome-tweaks
|
||||
adwaita-icon-theme
|
||||
gnome-session
|
||||
;
|
||||
|
||||
lm_sensors xwayland xdg_utils libnotify shotcut audacity paprefs
|
||||
wl-clipboard dconf2nix chrysalis;
|
||||
inherit (pkgs.gnome)
|
||||
dconf-editor gnome-tweaks adwaita-icon-theme gnome-session;
|
||||
};
|
||||
|
||||
file.".zprofile".text = ". $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh";
|
||||
file.".zprofile".text =
|
||||
". $HOME/.nix-profile/etc/profile.d/hm-session-vars.sh";
|
||||
};
|
||||
programs.password-store = {
|
||||
package = pkgs.pass-wayland.withExtensions (exts: [exts.pass-otp]);
|
||||
package = pkgs.pass-wayland.withExtensions (exts: [ exts.pass-otp ]);
|
||||
enable = true;
|
||||
settings.PASSWORD_STORE_DIR = "${config.home.homeDirectory}/git/password-store";
|
||||
settings.PASSWORD_STORE_DIR =
|
||||
"${config.home.homeDirectory}/git/password-store";
|
||||
};
|
||||
gtk = {
|
||||
enable = true;
|
||||
|
@ -108,11 +67,9 @@
|
|||
package = pkgs.catppuccin-gtk.override {
|
||||
variant = "mocha";
|
||||
size = "compact";
|
||||
tweaks = ["rimless"];
|
||||
tweaks = [ "rimless" ];
|
||||
};
|
||||
};
|
||||
gtk3.bookmarks = [
|
||||
"ftp://fluffy.lo.m-0.eu"
|
||||
];
|
||||
gtk3.bookmarks = [ "ftp://fluffy.lo.m-0.eu" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,26 +1,22 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, lib, ... }: {
|
||||
systemd.user = {
|
||||
services.fetch-banking = {
|
||||
Unit.Description = "Fetch banking";
|
||||
Service = {
|
||||
Type = "oneshot";
|
||||
Environment = "PATH=${lib.makeBinPath [pkgs.coreutils pkgs.git pkgs.pass pkgs.gnupg]}";
|
||||
ExecStart = toString (
|
||||
pkgs.writeShellScript "fetch-banking" ''
|
||||
cd ~/git/buchhaltung
|
||||
exec ${pkgs.nix}/bin/nix develop -c ${pkgs.nix}/bin/nix run ".#autoupdate"
|
||||
''
|
||||
);
|
||||
Environment = "PATH=${
|
||||
lib.makeBinPath [ pkgs.coreutils pkgs.git pkgs.pass pkgs.gnupg ]
|
||||
}";
|
||||
ExecStart = toString (pkgs.writeShellScript "fetch-banking" ''
|
||||
cd ~/git/buchhaltung
|
||||
exec ${pkgs.nix}/bin/nix develop -c ${pkgs.nix}/bin/nix run ".#autoupdate"
|
||||
'');
|
||||
};
|
||||
};
|
||||
timers.fetch-banking = {
|
||||
Unit.Description = "Fetch banking";
|
||||
Timer.OnCalendar = "22:00";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = [pkgs.firefox];
|
||||
{ pkgs, ... }: {
|
||||
home.packages = [ pkgs.firefox ];
|
||||
home.sessionVariables = {
|
||||
# So that electron can open firefox links. See
|
||||
# Issue: https://github.com/electron/electron/issues/28436
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
gw2dir = "${config.home.homeDirectory}/.volatile/GW2";
|
||||
wine = pkgs.wineWowPackages.staging;
|
||||
gw2env = ''
|
||||
|
@ -23,7 +20,8 @@
|
|||
export WINEESYNC=1
|
||||
'';
|
||||
dxvk = fetchTarball {
|
||||
url = "https://github.com/doitsujin/dxvk/releases/download/v1.7.2/dxvk-1.7.2.tar.gz";
|
||||
url =
|
||||
"https://github.com/doitsujin/dxvk/releases/download/v1.7.2/dxvk-1.7.2.tar.gz";
|
||||
sha256 = "07q9fsrvjq2ndnhd93000jw89bkaw6hdi2yhl4d6j8n4ak71r8pv";
|
||||
};
|
||||
gw2installdxvk = pkgs.writeShellScriptBin "gw2-install-dxvk" ''
|
||||
|
@ -54,10 +52,8 @@ in {
|
|||
username = "maralorn";
|
||||
token = pkgs.privateValue "" "factorio";
|
||||
};
|
||||
inherit
|
||||
(pkgs) #steam minetest
|
||||
minecraft
|
||||
;
|
||||
inherit (pkgs) # steam minetest
|
||||
minecraft;
|
||||
inherit gw2run gw2setup wine gw2installdxvk;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
_: {
|
||||
programs.git.signing.key = "6C3D12CD88CDF46C5EAF4D12226A2D41EF5378C9";
|
||||
}
|
||||
_: { programs.git.signing.key = "6C3D12CD88CDF46C5EAF4D12226A2D41EF5378C9"; }
|
||||
|
|
|
@ -1,65 +1,51 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
} @ args: let
|
||||
{ pkgs, lib, config, ... }@args:
|
||||
let
|
||||
hotkeys = pkgs.writeShellScriptBin "hotkeys" ''
|
||||
${pkgs.wizards-dialog}/bin/hotkeys ${pkgs.writeText "hotkeys.yaml" (builtins.toJSON (import ./hotkeys.nix args))}
|
||||
${pkgs.wizards-dialog}/bin/hotkeys ${
|
||||
pkgs.writeText "hotkeys.yaml"
|
||||
(builtins.toJSON (import ./hotkeys.nix args))
|
||||
}
|
||||
'';
|
||||
extensions = builtins.attrValues {
|
||||
inherit
|
||||
(pkgs.gnomeExtensions)
|
||||
appindicator
|
||||
window-is-ready-remover
|
||||
nothing-to-say
|
||||
windownavigator
|
||||
user-themes
|
||||
dash-to-panel
|
||||
removable-drive-menu
|
||||
pop-shell
|
||||
notifications-to-file
|
||||
caffeine
|
||||
;
|
||||
inherit (pkgs.gnomeExtensions)
|
||||
appindicator window-is-ready-remover nothing-to-say windownavigator
|
||||
user-themes dash-to-panel removable-drive-menu pop-shell
|
||||
notifications-to-file caffeine;
|
||||
};
|
||||
inherit (lib.hm.gvariant) mkTuple mkUint32;
|
||||
font = "Monospace 9";
|
||||
in {
|
||||
home.packages = extensions ++ [hotkeys];
|
||||
home.packages = extensions ++ [ hotkeys ];
|
||||
services.gpg-agent.pinentryFlavor = "gnome3";
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/notifications" = {
|
||||
show-banners = false;
|
||||
show-in-lock-screen = false;
|
||||
};
|
||||
"org/gnome/shell/keybindings" = {
|
||||
"toggle-overview" = [];
|
||||
};
|
||||
"org/gnome/shell/keybindings" = { "toggle-overview" = [ ]; };
|
||||
"org/gnome/desktop/wm/keybindings" = {
|
||||
switch-input-source = [];
|
||||
switch-input-source-backward = [];
|
||||
switch-applications = [];
|
||||
switch-applications-backward = [];
|
||||
minimize = [];
|
||||
maximize = [];
|
||||
unmaximize = [];
|
||||
cycle-windows = ["<Super>Tab"];
|
||||
cycle-windows-backward = ["<Shift><Super>Tab"];
|
||||
close = ["<Super>q"];
|
||||
move-to-monitor-down = [];
|
||||
move-to-monitor-left = [];
|
||||
move-to-monitor-right = [];
|
||||
move-to-monitor-up = [];
|
||||
toggle-fullscreen = ["<Super>f"];
|
||||
switch-input-source = [ ];
|
||||
switch-input-source-backward = [ ];
|
||||
switch-applications = [ ];
|
||||
switch-applications-backward = [ ];
|
||||
minimize = [ ];
|
||||
maximize = [ ];
|
||||
unmaximize = [ ];
|
||||
cycle-windows = [ "<Super>Tab" ];
|
||||
cycle-windows-backward = [ "<Shift><Super>Tab" ];
|
||||
close = [ "<Super>q" ];
|
||||
move-to-monitor-down = [ ];
|
||||
move-to-monitor-left = [ ];
|
||||
move-to-monitor-right = [ ];
|
||||
move-to-monitor-up = [ ];
|
||||
toggle-fullscreen = [ "<Super>f" ];
|
||||
};
|
||||
|
||||
"org/gnome/mutter" = {
|
||||
dynamic-workspaces = true;
|
||||
};
|
||||
"org/gnome/mutter" = { dynamic-workspaces = true; };
|
||||
|
||||
"org/gnome/mutter/keybindings" = {
|
||||
toggle-tiled-left = [];
|
||||
toggle-tiled-right = [];
|
||||
toggle-tiled-left = [ ];
|
||||
toggle-tiled-right = [ ];
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/color" = {
|
||||
|
@ -73,9 +59,7 @@ in {
|
|||
sleep-inactive-ac-type = "suspend";
|
||||
};
|
||||
|
||||
"org/gnome/desktop/peripherals/mouse" = {
|
||||
speed = 1;
|
||||
};
|
||||
"org/gnome/desktop/peripherals/mouse" = { speed = 1; };
|
||||
|
||||
"org/gnome/desktop/interface" = {
|
||||
document-font-name = font;
|
||||
|
@ -88,9 +72,7 @@ in {
|
|||
locate-pointer = true;
|
||||
};
|
||||
|
||||
"org/gnome/desktop/calendar" = {
|
||||
show-weekdate = true;
|
||||
};
|
||||
"org/gnome/desktop/calendar" = { show-weekdate = true; };
|
||||
|
||||
"org/gnome/desktop/wm/preferences" = {
|
||||
auto-raise = true;
|
||||
|
@ -108,9 +90,7 @@ in {
|
|||
name = "Catppuccin-Mocha-Compact-Blue-Dark";
|
||||
};
|
||||
|
||||
"system/locale" = {
|
||||
region = "en_DK.UTF-8";
|
||||
};
|
||||
"system/locale" = { region = "en_DK.UTF-8"; };
|
||||
|
||||
"org/gnome/desktop/screensaver" = {
|
||||
lock-delay = "0"; # lock screen immediately on screen blank
|
||||
|
@ -129,25 +109,26 @@ in {
|
|||
tile-by-default = true;
|
||||
active-hint = true;
|
||||
hint-color-rgba = "rgba(48, 0, 208,0.5)";
|
||||
tile-enter = ["<Super>t"];
|
||||
tile-move-left-global = ["<Super><Shift>Left"];
|
||||
tile-move-right-global = ["<Super><Shift>Right"];
|
||||
tile-move-up-global = ["<Super><Shift>Up"];
|
||||
tile-move-down-global = ["<Super><Shift>Down"];
|
||||
tile-resize-left = ["n"];
|
||||
tile-resize-right = ["t"];
|
||||
tile-resize-up = ["g"];
|
||||
tile-resize-down = ["r"];
|
||||
pop-workspace-up = [];
|
||||
pop-workspace-down = [];
|
||||
pop-monitor-left = [];
|
||||
pop-monitor-right = [];
|
||||
pop-monitor-up = [];
|
||||
pop-monitor-down = [];
|
||||
tile-enter = [ "<Super>t" ];
|
||||
tile-move-left-global = [ "<Super><Shift>Left" ];
|
||||
tile-move-right-global = [ "<Super><Shift>Right" ];
|
||||
tile-move-up-global = [ "<Super><Shift>Up" ];
|
||||
tile-move-down-global = [ "<Super><Shift>Down" ];
|
||||
tile-resize-left = [ "n" ];
|
||||
tile-resize-right = [ "t" ];
|
||||
tile-resize-up = [ "g" ];
|
||||
tile-resize-down = [ "r" ];
|
||||
pop-workspace-up = [ ];
|
||||
pop-workspace-down = [ ];
|
||||
pop-monitor-left = [ ];
|
||||
pop-monitor-right = [ ];
|
||||
pop-monitor-up = [ ];
|
||||
pop-monitor-down = [ ];
|
||||
};
|
||||
|
||||
"org/gnome/shell/extensions/dash-to-panel" = {
|
||||
panel-element-positions = ''{"0":[{"element":"showAppsButton","visible":false,"position":"stackedTL"},{"element":"dateMenu","visible":false,"position":"stackedTL"},{"element":"activitiesButton","visible":false,"position":"stackedTL"},{"element":"taskbar","visible":false,"position":"stackedTL"},{"element":"leftBox","visible":false,"position":"stackedTL"},{"element":"centerBox","visible":false,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":false,"position":"stackedBR"}]}'';
|
||||
panel-element-positions = ''
|
||||
{"0":[{"element":"showAppsButton","visible":false,"position":"stackedTL"},{"element":"dateMenu","visible":false,"position":"stackedTL"},{"element":"activitiesButton","visible":false,"position":"stackedTL"},{"element":"taskbar","visible":false,"position":"stackedTL"},{"element":"leftBox","visible":false,"position":"stackedTL"},{"element":"centerBox","visible":false,"position":"stackedBR"},{"element":"rightBox","visible":true,"position":"stackedBR"},{"element":"systemMenu","visible":true,"position":"stackedBR"},{"element":"desktopButton","visible":false,"position":"stackedBR"}]}'';
|
||||
panel-positions = ''{"0":"LEFT"}'';
|
||||
panel-anchors = ''{"0":"END"}'';
|
||||
panel-sizes = ''{"0":24}'';
|
||||
|
@ -160,30 +141,34 @@ in {
|
|||
};
|
||||
|
||||
"org/gnome/desktop/input-sources" = {
|
||||
sources = [(mkTuple ["xkb" "de+neo"])]; # use neo
|
||||
sources = [ (mkTuple [ "xkb" "de+neo" ]) ]; # use neo
|
||||
xkb-options = [
|
||||
"altwin:swap_lalt_lwin" # swap alt and win
|
||||
"lv3:menu_switch" # So that gnome-settings does not set it to ralt
|
||||
];
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/terminal" = {
|
||||
binding = "<Super>Return";
|
||||
command = "${config.home.sessionVariables.TERMINAL}";
|
||||
name = "Terminal";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/terminal" =
|
||||
{
|
||||
binding = "<Super>Return";
|
||||
command = "${config.home.sessionVariables.TERMINAL}";
|
||||
name = "Terminal";
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/hotkeys" = {
|
||||
binding = "<Super>space";
|
||||
command = "${config.home.sessionVariables.TERMINAL} ${lib.getExe hotkeys}";
|
||||
name = "Hotkeys";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/hotkeys" =
|
||||
{
|
||||
binding = "<Super>space";
|
||||
command =
|
||||
"${config.home.sessionVariables.TERMINAL} ${lib.getExe hotkeys}";
|
||||
name = "Hotkeys";
|
||||
};
|
||||
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/standby" = {
|
||||
binding = "<Super>F5";
|
||||
command = "systemctl suspend";
|
||||
name = "Standby";
|
||||
};
|
||||
"org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/standby" =
|
||||
{
|
||||
binding = "<Super>F5";
|
||||
command = "systemctl suspend";
|
||||
name = "Standby";
|
||||
};
|
||||
|
||||
"org/gnome/shell/extensions/nothing-to-say" = {
|
||||
icon-visibility = "always";
|
||||
|
@ -195,8 +180,8 @@ in {
|
|||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/hotkeys/"
|
||||
"/org/gnome/settings-daemon/plugins/media-keys/custom-keybindings/standby/"
|
||||
];
|
||||
area-screenshot-clip = ["Print"];
|
||||
screenshot = [];
|
||||
area-screenshot-clip = [ "Print" ];
|
||||
screenshot = [ ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }: {
|
||||
systemd.user.services.hoogle = {
|
||||
Unit.Description = "Hoogle server";
|
||||
Install.WantedBy = ["graphical-session.target"];
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
Service = {
|
||||
ExecStart = "${pkgs.ghcWithPackages}/bin/hoogle server --local --links";
|
||||
Restart = "always";
|
||||
};
|
||||
};
|
||||
home.packages = [pkgs.ghcWithPackages];
|
||||
home.packages = [ pkgs.ghcWithPackages ];
|
||||
}
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
{pkgs, ...}: {
|
||||
services.gpg-agent.pinentryFlavor = "curses";
|
||||
}
|
||||
{ pkgs, ... }: { services.gpg-agent.pinentryFlavor = "curses"; }
|
||||
|
|
|
@ -1,33 +1,21 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
language-servers = {
|
||||
inherit
|
||||
(pkgs.nodePackages)
|
||||
typescript-language-server
|
||||
vscode-json-languageserver-bin
|
||||
vscode-html-languageserver-bin
|
||||
vscode-css-languageserver-bin
|
||||
;
|
||||
inherit (pkgs.nodePackages)
|
||||
typescript-language-server vscode-json-languageserver-bin
|
||||
vscode-html-languageserver-bin vscode-css-languageserver-bin;
|
||||
inherit (pkgs.python3Packages) python-lsp-server;
|
||||
inherit
|
||||
(pkgs)
|
||||
rust-analyzer
|
||||
taplo
|
||||
inherit (pkgs)
|
||||
rust-analyzer taplo
|
||||
# toml
|
||||
|
||||
|
||||
nil
|
||||
# nix
|
||||
|
||||
|
||||
texlab
|
||||
# latex
|
||||
|
||||
lean
|
||||
yaml-language-server
|
||||
ltex-ls
|
||||
;
|
||||
|
||||
lean yaml-language-server ltex-ls;
|
||||
# languagetool support for markdown
|
||||
};
|
||||
in {
|
||||
|
@ -68,29 +56,31 @@ in {
|
|||
"C-f" = ":format";
|
||||
};
|
||||
in {
|
||||
normal =
|
||||
common_keys
|
||||
// {
|
||||
"C-r" = ["extend_to_line_bounds" ":reflow"];
|
||||
};
|
||||
select = {
|
||||
"C-r" = ["extend_to_line_bounds" "join_selections" "keep_primary_selection" "extend_to_line_bounds" ":reflow"];
|
||||
normal = common_keys // {
|
||||
"C-r" = [ "extend_to_line_bounds" ":reflow" ];
|
||||
};
|
||||
select = {
|
||||
"C-r" = [
|
||||
"extend_to_line_bounds"
|
||||
"join_selections"
|
||||
"keep_primary_selection"
|
||||
"extend_to_line_bounds"
|
||||
":reflow"
|
||||
];
|
||||
};
|
||||
insert = common_keys // {
|
||||
up = [ "normal_mode" "move_line_up" ];
|
||||
down = [ "normal_mode" "move_line_down" ];
|
||||
left = [ "normal_mode" "move_char_left" ];
|
||||
right = [ "normal_mode" "move_char_right" ];
|
||||
};
|
||||
insert =
|
||||
common_keys
|
||||
// {
|
||||
up = ["normal_mode" "move_line_up"];
|
||||
down = ["normal_mode" "move_line_down"];
|
||||
left = ["normal_mode" "move_char_left"];
|
||||
right = ["normal_mode" "move_char_right"];
|
||||
};
|
||||
};
|
||||
editor = {
|
||||
whitespace.render = {
|
||||
space = "all";
|
||||
tab = "all";
|
||||
};
|
||||
rulers = [80 100 120];
|
||||
rulers = [ 80 100 120 ];
|
||||
lsp.display-messages = true;
|
||||
indent-guides.render = true;
|
||||
cursorline = true;
|
||||
|
@ -122,7 +112,7 @@ in {
|
|||
{
|
||||
name = "markdown";
|
||||
language-server.command = "ltex-ls";
|
||||
file-types = ["md" "markdown" "txt"];
|
||||
file-types = [ "md" "markdown" "txt" ];
|
||||
config.ltex.additionalRules = {
|
||||
enablePickyRules = true;
|
||||
motherTongue = "de-DE";
|
||||
|
@ -133,7 +123,7 @@ in {
|
|||
name = "nix";
|
||||
formatter = {
|
||||
command = "alejandra";
|
||||
args = ["-q"];
|
||||
args = [ "-q" ];
|
||||
};
|
||||
}
|
||||
];
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{lib, ...}: {
|
||||
{ lib, ... }: {
|
||||
options = {
|
||||
m-0 = {
|
||||
hostName = lib.mkOption {type = lib.types.str;};
|
||||
hostName = lib.mkOption { type = lib.types.str; };
|
||||
colors = lib.mkOption {
|
||||
default = {};
|
||||
default = { };
|
||||
type = lib.types.attrs;
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,22 +1,19 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
fork = cmd: "fork ${cmd}";
|
||||
edit_dir = dir: "sh -c 'cd ${dir}; hx ${dir}'";
|
||||
with-mic-check = cmd: fork "sh -c '${config.home.sessionVariables.TERMINAL} mic-check; ${cmd}'";
|
||||
with-mic-check = cmd:
|
||||
fork "sh -c '${config.home.sessionVariables.TERMINAL} mic-check; ${cmd}'";
|
||||
in [
|
||||
{
|
||||
Orga = [
|
||||
{Kassandra = fork "kassandra2";}
|
||||
{Kalendar = "ikhal";}
|
||||
{Habitica = fork "firefox https://habitica.com";}
|
||||
{Tasks = "tasksh";}
|
||||
{Meditate = "meditate";}
|
||||
{Pythia = "pythia";}
|
||||
{Notes = edit_dir "~/git/notes";}
|
||||
{ Kassandra = fork "kassandra2"; }
|
||||
{ Kalendar = "ikhal"; }
|
||||
{ Habitica = fork "firefox https://habitica.com"; }
|
||||
{ Tasks = "tasksh"; }
|
||||
{ Meditate = "meditate"; }
|
||||
{ Pythia = "pythia"; }
|
||||
{ Notes = edit_dir "~/git/notes"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
|
@ -24,7 +21,8 @@ in [
|
|||
Zotero = fork "zotero";
|
||||
Open = fork "evince ~/git/promotion/out/print.pdf";
|
||||
Build = "sh -c 'cd ~/git/promotion; nix run'";
|
||||
Directory = fork "${config.home.sessionVariables.TERMINAL} -D ~/git/promotion";
|
||||
Directory =
|
||||
fork "${config.home.sessionVariables.TERMINAL} -D ~/git/promotion";
|
||||
Edit = edit_dir "~/git/promotion";
|
||||
};
|
||||
}
|
||||
|
@ -36,47 +34,48 @@ in [
|
|||
};
|
||||
}
|
||||
{
|
||||
SSH = let
|
||||
ssh = host: "ssh ${host}";
|
||||
SSH = let ssh = host: "ssh ${host}";
|
||||
in [
|
||||
{"hera via vpn" = ssh "hera.vpn.m-0.eu";}
|
||||
{"fluffy via vpn" = ssh "fluffy.vpn.m-0.eu";}
|
||||
{remote-builder = ssh "phoibe.cased.de";}
|
||||
{ag = ssh "ag-forward";}
|
||||
{mathe-gateway = ssh "gw";}
|
||||
{backup-server = ssh "borg.cysec.de";}
|
||||
{shells = ssh "shells";}
|
||||
{"bach (ved)" = ssh "bach.vocalensemble-darmstadt.de";}
|
||||
{"nixbuild.net" = "${pkgs.rlwrap}/bin/rlwrap ssh eu.nixbuild.net shell";}
|
||||
{"fluffy via local network" = ssh "fluffy.lo.m-0.eu";}
|
||||
{"hera via public v4" = ssh "hera-v4";}
|
||||
{"TU Tunnel" = "sshuttle --python python3.9 -r gw 130.83.0.0/16";}
|
||||
{ "hera via vpn" = ssh "hera.vpn.m-0.eu"; }
|
||||
{ "fluffy via vpn" = ssh "fluffy.vpn.m-0.eu"; }
|
||||
{ remote-builder = ssh "phoibe.cased.de"; }
|
||||
{ ag = ssh "ag-forward"; }
|
||||
{ mathe-gateway = ssh "gw"; }
|
||||
{ backup-server = ssh "borg.cysec.de"; }
|
||||
{ shells = ssh "shells"; }
|
||||
{ "bach (ved)" = ssh "bach.vocalensemble-darmstadt.de"; }
|
||||
{
|
||||
"nixbuild.net" = "${pkgs.rlwrap}/bin/rlwrap ssh eu.nixbuild.net shell";
|
||||
}
|
||||
{ "fluffy via local network" = ssh "fluffy.lo.m-0.eu"; }
|
||||
{ "hera via public v4" = ssh "hera-v4"; }
|
||||
{ "TU Tunnel" = "sshuttle --python python3.9 -r gw 130.83.0.0/16"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
Sound = let
|
||||
mpdclient = host: "sh -c 'switch-mpd ${host}; ncmpcpp -h ${host}'";
|
||||
in [
|
||||
{"Play/Pause" = "${pkgs.playerctl}/bin/playerctl play-pause";}
|
||||
{"MPD lokal" = mpdclient "::";}
|
||||
{"Lautstärke" = "ncpamixer";}
|
||||
{Pavucontrol = fork "pavucontrol";}
|
||||
{
|
||||
Headset = {
|
||||
Earplugs = {
|
||||
connect = "bluetoothctl connect 00:00:AB:BD:7D:68";
|
||||
disconnect = "bluetoothctl disconnect 00:00:AB:BD:7D:68";
|
||||
Sound =
|
||||
let mpdclient = host: "sh -c 'switch-mpd ${host}; ncmpcpp -h ${host}'";
|
||||
in [
|
||||
{ "Play/Pause" = "${pkgs.playerctl}/bin/playerctl play-pause"; }
|
||||
{ "MPD lokal" = mpdclient "::"; }
|
||||
{ "Lautstärke" = "ncpamixer"; }
|
||||
{ Pavucontrol = fork "pavucontrol"; }
|
||||
{
|
||||
Headset = {
|
||||
Earplugs = {
|
||||
connect = "bluetoothctl connect 00:00:AB:BD:7D:68";
|
||||
disconnect = "bluetoothctl disconnect 00:00:AB:BD:7D:68";
|
||||
};
|
||||
Overears = {
|
||||
connect = "bluetoothctl connect E8:EE:CC:25:66:C3";
|
||||
disconnect = "bluetoothctl disconnect E8:EE:CC:25:66:C3";
|
||||
};
|
||||
};
|
||||
Overears = {
|
||||
connect = "bluetoothctl connect E8:EE:CC:25:66:C3";
|
||||
disconnect = "bluetoothctl disconnect E8:EE:CC:25:66:C3";
|
||||
};
|
||||
};
|
||||
}
|
||||
{"MPD Lounge" = mpdclient "lounge.w17.io";}
|
||||
{"MPD Kitchen" = mpdclient "kitchen.w17.io";}
|
||||
{"MPD Space" = mpdclient "burbon.w17.io";}
|
||||
];
|
||||
}
|
||||
{ "MPD Lounge" = mpdclient "lounge.w17.io"; }
|
||||
{ "MPD Kitchen" = mpdclient "kitchen.w17.io"; }
|
||||
{ "MPD Space" = mpdclient "burbon.w17.io"; }
|
||||
];
|
||||
}
|
||||
{
|
||||
Apps = {
|
||||
|
@ -84,7 +83,8 @@ in [
|
|||
Files = fork "nautilus";
|
||||
Accounting = {
|
||||
Update = "nix run ./git/buchhaltung#update";
|
||||
Display = "hledger -f ~/git/buchhaltung/buchhaltung.journal ui -- --watch --theme=terminal -X€ -t -E";
|
||||
Display =
|
||||
"hledger -f ~/git/buchhaltung/buchhaltung.journal ui -- --watch --theme=terminal -X€ -t -E";
|
||||
};
|
||||
Games = {
|
||||
GW2 = fork "gw2";
|
||||
|
@ -105,14 +105,19 @@ in [
|
|||
}
|
||||
{
|
||||
Passmenu = {
|
||||
Password = "sh -c '(rbw-fzf | wl-copy) && ${lib.getExe pkgs.termdown} -T \"Clearing password in\" -f term 20 && wl-copy -c'";
|
||||
Password = "sh -c '(rbw-fzf | wl-copy) && ${
|
||||
lib.getExe pkgs.termdown
|
||||
} -T \"Clearing password in\" -f term 20 && wl-copy -c'";
|
||||
"OTP" = "sh -c 'rbw-totp-fzf | wl-copy'";
|
||||
};
|
||||
}
|
||||
{"Select Mode" = lib.mapAttrs (name: _: "select-mode ${name}") (import ../machines.nix).${config.m-0.hostName};}
|
||||
{
|
||||
"Select Mode" = lib.mapAttrs (name: _: "select-mode ${name}")
|
||||
(import ../machines.nix).${config.m-0.hostName};
|
||||
}
|
||||
{
|
||||
Communication = [
|
||||
{Matrix = fork "element-desktop";}
|
||||
{ Matrix = fork "element-desktop"; }
|
||||
{
|
||||
Mail = {
|
||||
Open = "neomutt";
|
||||
|
@ -126,15 +131,15 @@ in [
|
|||
Nixos = with-mic-check "mumble mumble://maralorn@lassul.us/nixos";
|
||||
};
|
||||
}
|
||||
{Weechat = "weechat";}
|
||||
{Signal = fork "signal-desktop";}
|
||||
{Zoom = with-mic-check "zoom";}
|
||||
{Telegram = fork "telegram-desktop";}
|
||||
{Discord = with-mic-check "Discord";}
|
||||
{Tmate = "tmate";}
|
||||
{ Weechat = "weechat"; }
|
||||
{ Signal = fork "signal-desktop"; }
|
||||
{ Zoom = with-mic-check "zoom"; }
|
||||
{ Telegram = fork "telegram-desktop"; }
|
||||
{ Discord = with-mic-check "Discord"; }
|
||||
{ Tmate = "tmate"; }
|
||||
];
|
||||
}
|
||||
{"Monitor (btop)" = "btop";}
|
||||
{ "Monitor (btop)" = "btop"; }
|
||||
{
|
||||
"W17" = {
|
||||
Strichliste = "firefox https://strichliste.w17.io/#!/user/56";
|
||||
|
@ -144,5 +149,5 @@ in [
|
|||
Close = "ssh door@burbon.w17.io close";
|
||||
};
|
||||
}
|
||||
{"Clear Notifications" = "sh -c 'rm -r ~/.notifications/*'";}
|
||||
{ "Clear Notifications" = "sh -c 'rm -r ~/.notifications/*'"; }
|
||||
]
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{pkgs, ...}: let
|
||||
dhallFiles = pkgs.runCommand "kassandra-config-src" {} ''
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
dhallFiles = pkgs.runCommand "kassandra-config-src" { } ''
|
||||
mkdir $out
|
||||
${pkgs.kassandra-standalone}/bin/kassandra2 print-types > $out/types.dhall
|
||||
ln -s ${./kassandra}/{config,backend}.dhall $out
|
||||
|
@ -7,15 +8,17 @@
|
|||
'';
|
||||
backend = pkgs.dhallPackages.buildDhallPackage {
|
||||
name = "kassandra-backend-config";
|
||||
code = "${dhallFiles}/backend.dhall : (${dhallFiles}/types.dhall).BackendConfig";
|
||||
code =
|
||||
"${dhallFiles}/backend.dhall : (${dhallFiles}/types.dhall).BackendConfig";
|
||||
source = true;
|
||||
dependencies = [pkgs.dhallPackages.Prelude];
|
||||
dependencies = [ pkgs.dhallPackages.Prelude ];
|
||||
};
|
||||
standalone = pkgs.dhallPackages.buildDhallPackage {
|
||||
name = "kassandra-standalone-config";
|
||||
code = "${dhallFiles}/config.dhall : (${dhallFiles}/types.dhall).StandaloneConfig";
|
||||
code =
|
||||
"${dhallFiles}/config.dhall : (${dhallFiles}/types.dhall).StandaloneConfig";
|
||||
source = true;
|
||||
dependencies = [pkgs.dhallPackages.Prelude];
|
||||
dependencies = [ pkgs.dhallPackages.Prelude ];
|
||||
};
|
||||
dhallResult = pkgs.recursiveLinkFarm "kassandra-config" {
|
||||
"backend.dhall" = "${backend}/source.dhall";
|
||||
|
@ -23,5 +26,5 @@
|
|||
};
|
||||
in {
|
||||
xdg.configFile.kassandra.source = dhallResult.out;
|
||||
home.packages = [pkgs.kassandra-standalone];
|
||||
home.packages = [ pkgs.kassandra-standalone ];
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{pkgs, ...}: let
|
||||
calendars = pkgs.privateValue [] "calendars";
|
||||
{ pkgs, ... }:
|
||||
let calendars = pkgs.privateValue [ ] "calendars";
|
||||
in {
|
||||
home.packages = [pkgs.khal];
|
||||
home.packages = [ pkgs.khal ];
|
||||
xdg.configFile."khal/config".text = ''
|
||||
[locale]
|
||||
dateformat = "%Y-%m-%d"
|
||||
|
@ -10,23 +10,10 @@ in {
|
|||
[default]
|
||||
default_calendar = Standard
|
||||
[calendars]
|
||||
${
|
||||
pkgs.lib.concatMapStringsSep "\n" (
|
||||
{
|
||||
name,
|
||||
readOnly ? false,
|
||||
...
|
||||
}: ''
|
||||
[[${name}]]
|
||||
type = discover
|
||||
path = ~/.calendars/${name}/*
|
||||
readonly = ${
|
||||
if readOnly
|
||||
then "True"
|
||||
else "False"
|
||||
}''
|
||||
)
|
||||
calendars
|
||||
}
|
||||
${pkgs.lib.concatMapStringsSep "\n" ({ name, readOnly ? false, ... }: ''
|
||||
[[${name}]]
|
||||
type = discover
|
||||
path = ~/.calendars/${name}/*
|
||||
readonly = ${if readOnly then "True" else "False"}'') calendars}
|
||||
'';
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = [pkgs.khard];
|
||||
{ pkgs, ... }: {
|
||||
home.packages = [ pkgs.khard ];
|
||||
xdg.configFile."khard/khard.conf".text = ''
|
||||
[addressbooks]
|
||||
[[Kontakte]]
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = [pkgs.neomutt];
|
||||
}
|
||||
{ pkgs, ... }: { home.packages = [ pkgs.neomutt ]; }
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
mail2task = pkgs.writeShellScript "mail2task" ''
|
||||
set -euo pipefail
|
||||
${pkgs.isync}/bin/mbsync hera:Move/todo
|
||||
|
@ -13,9 +9,9 @@
|
|||
${pkgs.notmuch}/bin/notmuch new
|
||||
'';
|
||||
lists = pkgs.privateValue {
|
||||
sortLists = [];
|
||||
stupidLists = [];
|
||||
notifications = [];
|
||||
sortLists = [ ];
|
||||
stupidLists = [ ];
|
||||
notifications = [ ];
|
||||
} "mail/filters";
|
||||
maildir = config.accounts.email.maildirBasePath;
|
||||
# mhdr -h List-ID -d Maildir/hera/Archiv/unsortiert | sort | sed 's/^.*<\(.*\)>$/\1/' | uniq | xargs -I '{}' sh -c "notmuch count List:{} | sed 's/$/: {}/'" | sort
|
||||
|
@ -29,89 +25,83 @@
|
|||
toFolder (lib.concatStringsSep "." (lib.splitString "@" name));
|
||||
toFolder = name:
|
||||
lib.concatStringsSep "/" (lib.reverseList (lib.splitString "." name));
|
||||
simple = filter: target: {inherit filter target;};
|
||||
simple = filter: target: { inherit filter target; };
|
||||
notifications = notify:
|
||||
simple "from:${notify}" "notifications/${mailToFolder notify}";
|
||||
stupidList = list: simple "to:${list}" "list/${mailToFolder list}";
|
||||
simpleSortList = listName:
|
||||
simple "List:${listName}" "list/${toFolder listName}";
|
||||
};
|
||||
myFilters =
|
||||
builtins.map filter.simpleSortList lists.sortLists
|
||||
myFilters = builtins.map filter.simpleSortList lists.sortLists
|
||||
++ builtins.map filter.stupidList lists.stupidLists
|
||||
++ builtins.map filter.notifications lists.notifications;
|
||||
sortMail =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "sort-mail-archive";
|
||||
bins = [pkgs.notmuch pkgs.coreutils pkgs.mblaze pkgs.findutils];
|
||||
imports = [
|
||||
"Text.Megaparsec"
|
||||
"Text.Megaparsec.Char"
|
||||
"Text.Megaparsec.Char.Lexer"
|
||||
"qualified Data.List.NonEmpty as NE"
|
||||
"qualified Data.Text as T"
|
||||
"System.Environment (setEnv)"
|
||||
];
|
||||
} ''
|
||||
reScan = notmuch "new" "--quiet"
|
||||
sortMail = pkgs.writeHaskellScript {
|
||||
name = "sort-mail-archive";
|
||||
bins = [ pkgs.notmuch pkgs.coreutils pkgs.mblaze pkgs.findutils ];
|
||||
imports = [
|
||||
"Text.Megaparsec"
|
||||
"Text.Megaparsec.Char"
|
||||
"Text.Megaparsec.Char.Lexer"
|
||||
"qualified Data.List.NonEmpty as NE"
|
||||
"qualified Data.Text as T"
|
||||
"System.Environment (setEnv)"
|
||||
];
|
||||
} ''
|
||||
reScan = notmuch "new" "--quiet"
|
||||
|
||||
findFilterMail :: (Text,Text) -> IO (Maybe (LByteString, Text, Text))
|
||||
findFilterMail (filter_, target) = do
|
||||
files <- notmuch "search" "--output" "files" (toString filter_) "folder:${unsortedSuffix}" |> capture
|
||||
pure $ if (LBS.length files > 0) then Just (files, filter_, target) else Nothing
|
||||
findFilterMail :: (Text,Text) -> IO (Maybe (LByteString, Text, Text))
|
||||
findFilterMail (filter_, target) = do
|
||||
files <- notmuch "search" "--output" "files" (toString filter_) "folder:${unsortedSuffix}" |> capture
|
||||
pure $ if (LBS.length files > 0) then Just (files, filter_, target) else Nothing
|
||||
|
||||
executeFilterMail :: (LByteString, Text, Text) -> IO ()
|
||||
executeFilterMail (files, filter_, target) = do
|
||||
say [i|Sorting "#{filter_}" into #{target}|]
|
||||
writeOutput files |> mscan
|
||||
mmkdir ([i|${archive}/#{target}|] :: String)
|
||||
writeOutput files |> mrefile ([i|${archive}/#{target}|] :: String)
|
||||
executeFilterMail :: (LByteString, Text, Text) -> IO ()
|
||||
executeFilterMail (files, filter_, target) = do
|
||||
say [i|Sorting "#{filter_}" into #{target}|]
|
||||
writeOutput files |> mscan
|
||||
mmkdir ([i|${archive}/#{target}|] :: String)
|
||||
writeOutput files |> mrefile ([i|${archive}/#{target}|] :: String)
|
||||
|
||||
myFilters :: [(Text,Text)]
|
||||
myFilters = [${
|
||||
lib.concatStringsSep ","
|
||||
(
|
||||
builtins.map ({
|
||||
filter,
|
||||
target,
|
||||
}: ''("${filter}","${target}")'')
|
||||
myFilters
|
||||
)
|
||||
}]
|
||||
myFilters :: [(Text,Text)]
|
||||
myFilters = [${
|
||||
lib.concatStringsSep ","
|
||||
(builtins.map ({ filter, target, }: ''("${filter}","${target}")'')
|
||||
myFilters)
|
||||
}]
|
||||
|
||||
filtersFromTo :: Text -> Maybe (Text,Text)
|
||||
filtersFromTo = filtersFromField "to" [toToName]
|
||||
toToName :: Text -> Maybe Text
|
||||
toToName (T.splitOn "@" -> [name, "maralorn.de"])
|
||||
| not (T.isInfixOf "randy" name) = Just . ("to/" <>) . T.intercalate "_" . T.splitOn "." $ name
|
||||
toToName _ = Nothing
|
||||
filtersFromField :: Text -> [Text-> Maybe Text] -> Text -> Maybe (Text,Text)
|
||||
filtersFromField field filters text = fmap ([i|#{field}:#{text}|],) . viaNonEmpty Relude.head . mapMaybe ($ text) $ filters
|
||||
filtersFromListIDs :: Text -> Maybe (Text,Text)
|
||||
filtersFromListIDs = filtersFromField "List" [githubNameFolderFromId, gitlabNameFolderFromId]
|
||||
githubNameFolderFromId :: Text -> Maybe Text
|
||||
githubNameFolderFromId (reverse . T.splitOn "." -> ("com":"github":org:name)) = Just [i|github/#{org}/#{T.intercalate "_" $ reverse name}|]
|
||||
githubNameFolderFromId _ = Nothing
|
||||
gitlabNameFolderFromId :: Text -> Maybe Text
|
||||
gitlabNameFolderFromId (reverse . T.splitOn "." -> ("de":"ccc":"darmstadt":"git":org:name1:name)) = Just [i|cda-gitlab/#{org}/#{T.intercalate "_" . toList . Relude.tail $ NE.reverse (name1:|name)}|]
|
||||
gitlabNameFolderFromId _ = Nothing
|
||||
filtersFromTo :: Text -> Maybe (Text,Text)
|
||||
filtersFromTo = filtersFromField "to" [toToName]
|
||||
toToName :: Text -> Maybe Text
|
||||
toToName (T.splitOn "@" -> [name, "maralorn.de"])
|
||||
| not (T.isInfixOf "randy" name) = Just . ("to/" <>) . T.intercalate "_" . T.splitOn "." $ name
|
||||
toToName _ = Nothing
|
||||
filtersFromField :: Text -> [Text-> Maybe Text] -> Text -> Maybe (Text,Text)
|
||||
filtersFromField field filters text = fmap ([i|#{field}:#{text}|],) . viaNonEmpty Relude.head . mapMaybe ($ text) $ filters
|
||||
filtersFromListIDs :: Text -> Maybe (Text,Text)
|
||||
filtersFromListIDs = filtersFromField "List" [githubNameFolderFromId, gitlabNameFolderFromId]
|
||||
githubNameFolderFromId :: Text -> Maybe Text
|
||||
githubNameFolderFromId (reverse . T.splitOn "." -> ("com":"github":org:name)) = Just [i|github/#{org}/#{T.intercalate "_" $ reverse name}|]
|
||||
githubNameFolderFromId _ = Nothing
|
||||
gitlabNameFolderFromId :: Text -> Maybe Text
|
||||
gitlabNameFolderFromId (reverse . T.splitOn "." -> ("de":"ccc":"darmstadt":"git":org:name1:name)) = Just [i|cda-gitlab/#{org}/#{T.intercalate "_" . toList . Relude.tail $ NE.reverse (name1:|name)}|]
|
||||
gitlabNameFolderFromId _ = Nothing
|
||||
|
||||
type Parser = Parsec Text Text
|
||||
listId :: Parser Text
|
||||
listId = manyTill anySingle (char '<') *> (toText <$> manyTill anySingle (char '>'))
|
||||
type Parser = Parsec Text Text
|
||||
listId :: Parser Text
|
||||
listId = manyTill anySingle (char '<') *> (toText <$> manyTill anySingle (char '>'))
|
||||
|
||||
main = do
|
||||
setEnv "MBLAZE_PAGER" "cat"
|
||||
setEnv "NOTMUCH_CONFIG" "${config.home.sessionVariables.NOTMUCH_CONFIG or ""}"
|
||||
reScan
|
||||
(listIDs,tos) <- concurrently (mhdr "-h" "List-ID" "-d" "${unsorted}" |> capture) (mhdr "-h" "To" "-d" "${unsorted}" "-A" |> capture)
|
||||
let listFilters = mapMaybe filtersFromListIDs . sortNub . mapMaybe (parseMaybe listId) . lines . decodeUtf8 $ listIDs
|
||||
toFilters = mapMaybe filtersFromTo . sortNub . fmap (\x -> maybe x Relude.id $ parseMaybe listId x) . lines . decodeUtf8 $ tos
|
||||
applicableFilters <- catMaybes <$> forConcurrently (listFilters <> myFilters <> toFilters) findFilterMail
|
||||
for_ applicableFilters executeFilterMail
|
||||
reScan
|
||||
'';
|
||||
main = do
|
||||
setEnv "MBLAZE_PAGER" "cat"
|
||||
setEnv "NOTMUCH_CONFIG" "${
|
||||
config.home.sessionVariables.NOTMUCH_CONFIG or ""
|
||||
}"
|
||||
reScan
|
||||
(listIDs,tos) <- concurrently (mhdr "-h" "List-ID" "-d" "${unsorted}" |> capture) (mhdr "-h" "To" "-d" "${unsorted}" "-A" |> capture)
|
||||
let listFilters = mapMaybe filtersFromListIDs . sortNub . mapMaybe (parseMaybe listId) . lines . decodeUtf8 $ listIDs
|
||||
toFilters = mapMaybe filtersFromTo . sortNub . fmap (\x -> maybe x Relude.id $ parseMaybe listId x) . lines . decodeUtf8 $ tos
|
||||
applicableFilters <- catMaybes <$> forConcurrently (listFilters <> myFilters <> toFilters) findFilterMail
|
||||
for_ applicableFilters executeFilterMail
|
||||
reScan
|
||||
'';
|
||||
in {
|
||||
services.mbsync = {
|
||||
postExec = "${sortMail}/bin/sort-mail-archive";
|
||||
|
@ -120,7 +110,7 @@ in {
|
|||
accounts.email.accounts = {
|
||||
hera.imapnotify = {
|
||||
onNotifyPost = toString mail2task;
|
||||
boxes = ["Move/todo"];
|
||||
boxes = [ "Move/todo" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,21 +1,12 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit
|
||||
(pkgs.privateValue {
|
||||
gpg = "";
|
||||
name = "";
|
||||
mail = "";
|
||||
alternates = [];
|
||||
} "mail/me")
|
||||
gpg
|
||||
name
|
||||
mail
|
||||
alternates
|
||||
;
|
||||
{ lib, config, pkgs, ... }:
|
||||
let
|
||||
inherit (pkgs.privateValue {
|
||||
gpg = "";
|
||||
name = "";
|
||||
mail = "";
|
||||
alternates = [ ];
|
||||
} "mail/me")
|
||||
gpg name mail alternates;
|
||||
quick-mail-sync = pkgs.writeShellScriptBin "quick-mail-sync" ''
|
||||
${pkgs.isync}/bin/mbsync hera:INBOX,Code
|
||||
${pkgs.notmuch}/bin/notmuch new
|
||||
|
@ -32,12 +23,13 @@ in {
|
|||
};
|
||||
systemd.user.timers.mbsync.Timer.RandomizedDelaySec = "10m";
|
||||
|
||||
accounts.email.accounts = lib.recursiveUpdate (pkgs.privateValue {} "mail/accounts") {
|
||||
hera = {
|
||||
passwordCommand = "${pkgs.coreutils}/bin/cat /run/agenix/mail-password";
|
||||
imapnotify.onNotify = lib.getExe quick-mail-sync;
|
||||
accounts.email.accounts =
|
||||
lib.recursiveUpdate (pkgs.privateValue { } "mail/accounts") {
|
||||
hera = {
|
||||
passwordCommand = "${pkgs.coreutils}/bin/cat /run/agenix/mail-password";
|
||||
imapnotify.onNotify = lib.getExe quick-mail-sync;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
systemd.user.services = let
|
||||
hasImapHost = name: account: account.imap != null;
|
||||
|
@ -53,18 +45,17 @@ in {
|
|||
done
|
||||
'');
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
in
|
||||
lib.mapAttrs' mkWatchService (lib.filterAttrs hasImapHost config.accounts.email.accounts)
|
||||
// {
|
||||
mbsync.Service = {
|
||||
Environment = "PATH=${lib.makeBinPath [pkgs.rbw pkgs.coreutils]}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "30s";
|
||||
};
|
||||
in lib.mapAttrs' mkWatchService
|
||||
(lib.filterAttrs hasImapHost config.accounts.email.accounts) // {
|
||||
mbsync.Service = {
|
||||
Environment = "PATH=${lib.makeBinPath [ pkgs.rbw pkgs.coreutils ]}";
|
||||
Restart = "on-failure";
|
||||
RestartSec = "30s";
|
||||
};
|
||||
};
|
||||
|
||||
programs = {
|
||||
msmtp.enable = true;
|
||||
|
@ -78,17 +69,18 @@ in {
|
|||
${pkgs.notmuch}/bin/notmuch tag -spam -- "(not folder:/Junk|Spam|SPAM/) tag:spam"
|
||||
'';
|
||||
new = {
|
||||
tags = [];
|
||||
ignore = [".isyncuidmap.db"];
|
||||
tags = [ ];
|
||||
ignore = [ ".isyncuidmap.db" ];
|
||||
};
|
||||
maildir.synchronizeFlags = true;
|
||||
};
|
||||
};
|
||||
|
||||
home = {
|
||||
packages = [quick-mail-sync];
|
||||
packages = [ quick-mail-sync ];
|
||||
file = let
|
||||
mutt_alternates = "@maralorn.de " + (builtins.concatStringsSep " " alternates);
|
||||
mutt_alternates = "@maralorn.de "
|
||||
+ (builtins.concatStringsSep " " alternates);
|
||||
show-sidebar = pkgs.writeText "show-sidebar" ''
|
||||
set sidebar_visible=yes
|
||||
bind index <up> sidebar-prev
|
||||
|
@ -117,7 +109,9 @@ in {
|
|||
audio/*; ${pkgs.xdg_utils}/bin/xdg-open %s > /dev/null
|
||||
'';
|
||||
# See: https://unix.stackexchange.com/questions/44358/mutt-mark-as-read-and-delete
|
||||
move-message-macro = key: dir: name: ''macro index,pager ${key} ":set confirmappend=no resolve=no\n<clear-flag>N<save-message>=hera/${dir}\n:set confirmappend=yes resolve=yes\n<next-undeleted>" "move message to ${name}"'';
|
||||
move-message-macro = key: dir: name:
|
||||
''
|
||||
macro index,pager ${key} ":set confirmappend=no resolve=no\n<clear-flag>N<save-message>=hera/${dir}\n:set confirmappend=yes resolve=yes\n<next-undeleted>" "move message to ${name}"'';
|
||||
in {
|
||||
".neomuttrc".text = ''
|
||||
set editor = "hx"
|
||||
|
@ -133,7 +127,11 @@ in {
|
|||
${move-message-macro "l" "Move/readlater" "readlater list"}
|
||||
macro attach 'V' "<pipe-entry>iconv -c --to-code=UTF8 > ~/.cache/mutt/mail.html<enter><shell-escape>firefox ~/.cache/mutt/mail.html<enter>"
|
||||
|
||||
macro index,pager <F6> "<shell-escape>${pkgs.zsh}/bin/zsh -c '${pkgs.sieve-connect}/bin/sieve-connect -s ${config.accounts.email.accounts.hera.imap.host or ""} -u ${config.accounts.email.accounts.hera.userName or ""} --passwordfd 3 --edit --remotesieve filter 3<<(cat /run/agenix/mail-password)'\n"
|
||||
macro index,pager <F6> "<shell-escape>${pkgs.zsh}/bin/zsh -c '${pkgs.sieve-connect}/bin/sieve-connect -s ${
|
||||
config.accounts.email.accounts.hera.imap.host or ""
|
||||
} -u ${
|
||||
config.accounts.email.accounts.hera.userName or ""
|
||||
} --passwordfd 3 --edit --remotesieve filter 3<<(cat /run/agenix/mail-password)'\n"
|
||||
macro index,pager A "<pipe-message>${pkgs.khard}/bin/khard add-email<return>" "add sender to to khard"
|
||||
|
||||
set query_format="%4c %t %-70.70a %-70.70n %?e?(%e)?"
|
||||
|
|
|
@ -1,39 +1,33 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
mail2rss =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "mail2rss";
|
||||
bins = [pkgs.notmuch pkgs.mblaze pkgs.isync pkgs.rssfeeds];
|
||||
imports = ["System.Environment (setEnv)"];
|
||||
} ''
|
||||
main = do
|
||||
setEnv "NOTMUCH_CONFIG" "${
|
||||
config.home.sessionVariables.NOTMUCH_CONFIG or ""
|
||||
}"
|
||||
mbsync "-a"
|
||||
notmuch "new" "--quiet"
|
||||
mail2rss "${config.accounts.email.maildirBasePath}" "hera/Move/readlater" &> Truncate "/var/www/rss/mails.xml"
|
||||
files <- notmuch "search" "--output" "files" "folder:hera/Move/readlater" |> capture
|
||||
writeOutput files |> mrefile "${config.accounts.email.maildirBasePath}/hera/Archiv/unsortiert"
|
||||
mbsync "-a"
|
||||
notmuch "new" "--quiet"
|
||||
'';
|
||||
{ lib, pkgs, config, ... }:
|
||||
let
|
||||
mail2rss = pkgs.writeHaskellScript {
|
||||
name = "mail2rss";
|
||||
bins = [ pkgs.notmuch pkgs.mblaze pkgs.isync pkgs.rssfeeds ];
|
||||
imports = [ "System.Environment (setEnv)" ];
|
||||
} ''
|
||||
main = do
|
||||
setEnv "NOTMUCH_CONFIG" "${
|
||||
config.home.sessionVariables.NOTMUCH_CONFIG or ""
|
||||
}"
|
||||
mbsync "-a"
|
||||
notmuch "new" "--quiet"
|
||||
mail2rss "${config.accounts.email.maildirBasePath}" "hera/Move/readlater" &> Truncate "/var/www/rss/mails.xml"
|
||||
files <- notmuch "search" "--output" "files" "folder:hera/Move/readlater" |> capture
|
||||
writeOutput files |> mrefile "${config.accounts.email.maildirBasePath}/hera/Archiv/unsortiert"
|
||||
mbsync "-a"
|
||||
notmuch "new" "--quiet"
|
||||
'';
|
||||
in {
|
||||
systemd.user = {
|
||||
timers.mail2rss = {
|
||||
Timer.OnCalendar = "23:58";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
services = {
|
||||
mail2rss = {
|
||||
Unit.Description = "Mail to rss exporter";
|
||||
Service = {
|
||||
Environment = "PATH=${lib.makeBinPath [pkgs.coreutils]}";
|
||||
Environment = "PATH=${lib.makeBinPath [ pkgs.coreutils ]}";
|
||||
ExecStart = "${mail2rss}/bin/mail2rss";
|
||||
Type = "oneshot";
|
||||
};
|
||||
|
|
|
@ -1,3 +1 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = builtins.attrValues pkgs.mode-scripts;
|
||||
}
|
||||
{ pkgs, ... }: { home.packages = builtins.attrValues pkgs.mode-scripts; }
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
{config, ...}: {
|
||||
xdg.configFile."monitors.xml".source = ./. + "/${config.m-0.hostName}-monitors.xml";
|
||||
{ config, ... }: {
|
||||
xdg.configFile."monitors.xml".source = ./.
|
||||
+ "/${config.m-0.hostName}-monitors.xml";
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = [pkgs.ncmpcpp];
|
||||
{ pkgs, ... }: {
|
||||
home.packages = [ pkgs.ncmpcpp ];
|
||||
home.file.".ncmpcpp/config".text = ''
|
||||
ask_before_clearing_playlists=no
|
||||
mouse_support = yes
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
audio_dir = "${config.home.homeDirectory}/media/audio";
|
||||
playlist_dir = "${audio_dir}/playlists";
|
||||
mprisCfg = config.xdg.configFile."mpDris2/mpDris2.conf";
|
||||
replace_string = "@HOST@";
|
||||
in {
|
||||
home.file."media/audio/playlists" = {
|
||||
source = pkgs.recursiveLinkFarm "mpd-playlists" (lib.mapAttrs' (name: content: lib.nameValuePair "${name}.m3u" (builtins.toFile "${name}.m3u" content)) {
|
||||
"radio-swiss-classic" = "https://stream.srg-ssr.ch/m/rsc_de/aacp_96";
|
||||
"radio-swiss-jazz" = "https://stream.srg-ssr.ch/m/rsj/aacp_96";
|
||||
"br-klassik" = "http://dispatcher.rndfnk.com/br/brklassik/live/mp3/high";
|
||||
"klassik-radio-games" = "https://klassikr.streamabc.net/klr-games-mp3-128-1540253";
|
||||
"klassik-radio-movie" = "https://klassikr.streamabc.net/klr-movie-mp3-128-5213277";
|
||||
"radio-caprice-power-metal" = "http://79.120.77.11:8000/powermetal";
|
||||
"metal-hammer" = "https://metal-hammer.stream.laut.fm/metal-hammer";
|
||||
});
|
||||
source = pkgs.recursiveLinkFarm "mpd-playlists" (lib.mapAttrs'
|
||||
(name: content:
|
||||
lib.nameValuePair "${name}.m3u"
|
||||
(builtins.toFile "${name}.m3u" content)) {
|
||||
"radio-swiss-classic" = "https://stream.srg-ssr.ch/m/rsc_de/aacp_96";
|
||||
"radio-swiss-jazz" = "https://stream.srg-ssr.ch/m/rsj/aacp_96";
|
||||
"br-klassik" =
|
||||
"http://dispatcher.rndfnk.com/br/brklassik/live/mp3/high";
|
||||
"klassik-radio-games" =
|
||||
"https://klassikr.streamabc.net/klr-games-mp3-128-1540253";
|
||||
"klassik-radio-movie" =
|
||||
"https://klassikr.streamabc.net/klr-movie-mp3-128-5213277";
|
||||
"radio-caprice-power-metal" = "http://79.120.77.11:8000/powermetal";
|
||||
"metal-hammer" = "https://metal-hammer.stream.laut.fm/metal-hammer";
|
||||
});
|
||||
recursive = true;
|
||||
};
|
||||
xdg.configFile."mpDris2/mpDris2.conf".enable = false;
|
||||
|
@ -46,7 +48,9 @@ in {
|
|||
home.packages = [
|
||||
(pkgs.writeShellScriptBin "switch-mpd" ''
|
||||
mkdir -p ${config.xdg.configHome}/mpDris2
|
||||
${lib.getExe pkgs.sd} -p ${replace_string} "$1" ${mprisCfg.source} > $HOME/${mprisCfg.target}
|
||||
${
|
||||
lib.getExe pkgs.sd
|
||||
} -p ${replace_string} "$1" ${mprisCfg.source} > $HOME/${mprisCfg.target}
|
||||
${pkgs.systemd}/bin/systemctl --user restart mpdris2.service
|
||||
'')
|
||||
];
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
{pkgs, ...}: let
|
||||
script =
|
||||
(pkgs.recursiveLinkFarm "autosave.lua"
|
||||
{"share/mpv/scripts/autosave.lua" = ./autosave.lua;})
|
||||
// {scriptName = "autosave.lua";};
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
script = (pkgs.recursiveLinkFarm "autosave.lua" {
|
||||
"share/mpv/scripts/autosave.lua" = ./autosave.lua;
|
||||
}) // {
|
||||
scriptName = "autosave.lua";
|
||||
};
|
||||
in {
|
||||
programs.mpv = {
|
||||
enable = true;
|
||||
config = {
|
||||
save-position-on-quit = true;
|
||||
};
|
||||
scripts = [
|
||||
pkgs.mpvScripts.mpris
|
||||
script
|
||||
];
|
||||
config = { save-position-on-quit = true; };
|
||||
scripts = [ pkgs.mpvScripts.mpris script ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,37 +1,36 @@
|
|||
{pkgs, ...}: let
|
||||
night-shutdown =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "night-shutdown";
|
||||
imports = [
|
||||
"Data.Time.LocalTime"
|
||||
"Data.Time.Format"
|
||||
"Data.Time.Clock"
|
||||
"Control.Concurrent"
|
||||
"Data.Functor"
|
||||
];
|
||||
bins = [pkgs.libnotify pkgs.systemd];
|
||||
} ''
|
||||
interval = 5
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
night-shutdown = pkgs.writeHaskellScript {
|
||||
name = "night-shutdown";
|
||||
imports = [
|
||||
"Data.Time.LocalTime"
|
||||
"Data.Time.Format"
|
||||
"Data.Time.Clock"
|
||||
"Control.Concurrent"
|
||||
"Data.Functor"
|
||||
];
|
||||
bins = [ pkgs.libnotify pkgs.systemd ];
|
||||
} ''
|
||||
interval = 5
|
||||
|
||||
main = forever $ do
|
||||
time <- getZonedTime
|
||||
let tod = localTimeOfDay . zonedTimeToLocalTime$ time
|
||||
hour = todHour tod
|
||||
minute = todMin tod
|
||||
evening = hour == 0
|
||||
night = (hour < 6 && hour >= 1)
|
||||
action
|
||||
| evening = notify_send "Shutdown alert!" ([i|Rechner fährt in #{59-minute} Minuten runter.|]::String)
|
||||
| night = systemctl "poweroff"
|
||||
| otherwise = pass
|
||||
action
|
||||
threadDelay $ (interval - (minute `mod` interval)) * 60 * 1000000
|
||||
'';
|
||||
main = forever $ do
|
||||
time <- getZonedTime
|
||||
let tod = localTimeOfDay . zonedTimeToLocalTime$ time
|
||||
hour = todHour tod
|
||||
minute = todMin tod
|
||||
evening = hour == 0
|
||||
night = (hour < 6 && hour >= 1)
|
||||
action
|
||||
| evening = notify_send "Shutdown alert!" ([i|Rechner fährt in #{59-minute} Minuten runter.|]::String)
|
||||
| night = systemctl "poweroff"
|
||||
| otherwise = pass
|
||||
action
|
||||
threadDelay $ (interval - (minute `mod` interval)) * 60 * 1000000
|
||||
'';
|
||||
in {
|
||||
systemd.user.services.night-shutdown = {
|
||||
Unit.Description = "Night Shutdown";
|
||||
Service.ExecStart = "${night-shutdown}/bin/night-shutdown";
|
||||
Install.WantedBy = ["graphical-session.target"];
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
inherit (config.lib) dag;
|
||||
{ config, pkgs, lib, ... }:
|
||||
with lib;
|
||||
let inherit (config.lib) dag;
|
||||
in {
|
||||
home.activation.report-changes = dag.entryAnywhere ''
|
||||
if [[ -n "$oldGenPath" && "$oldGenPath" != "$newGenPath" ]]; then
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, config, lib, ... }: {
|
||||
home = {
|
||||
username = "maralorn";
|
||||
homeDirectory = "/home/maralorn";
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
pythia-path = "${config.home.homeDirectory}/documents/pythia";
|
||||
pythia = pkgs.writeShellScriptBin "pythia" ''
|
||||
today=$(date +%Y-%m-%d)
|
||||
|
@ -104,4 +101,4 @@
|
|||
${hold}
|
||||
exit
|
||||
'';
|
||||
in {home.packages = [pythia meditate];}
|
||||
in { home.packages = [ pythia meditate ]; }
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
configPath = "${config.home.homeDirectory}/git/config";
|
||||
configGit = "${pkgs.git}/bin/git -C ${configPath}";
|
||||
in {
|
||||
|
@ -17,7 +14,7 @@ in {
|
|||
timers.refresh-config = {
|
||||
Unit.Description = "Fetch config updates";
|
||||
Timer.OnCalendar = "*:0/5:0";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{pkgs, ...}: {
|
||||
home.packages = [pkgs.zotero];
|
||||
{ pkgs, ... }: {
|
||||
home.packages = [ pkgs.zotero ];
|
||||
programs.texlive = {
|
||||
enable = true;
|
||||
extraPackages = p: {inherit (p) scheme-full;};
|
||||
extraPackages = p: { inherit (p) scheme-full; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
rbw = config.programs.rbw.package;
|
||||
video_dir = "${config.home.homeDirectory}/.volatile/video-downloads";
|
||||
download-and-watch = pkgs.writeShellScriptBin "download-and-watch" ''
|
||||
|
@ -12,7 +8,9 @@
|
|||
|
||||
link="''${1:-`${lib.getBin pkgs.wl-clipboard}/bin/wl-paste`}"
|
||||
|
||||
filename="`${lib.getExe pkgs.yt-dlp} -j $link | ${lib.getExe pkgs.jq} -r .filename`"
|
||||
filename="`${lib.getExe pkgs.yt-dlp} -j $link | ${
|
||||
lib.getExe pkgs.jq
|
||||
} -r .filename`"
|
||||
if [[ ! -f "$filename" ]]; then
|
||||
echo "Prefetching file …"
|
||||
# --user to use the user daemon
|
||||
|
@ -21,17 +19,19 @@
|
|||
${lib.getBin pkgs.systemd}/bin/systemd-run --user --no-block -G \
|
||||
${lib.getExe pkgs.foot} -D "${video_dir}" \
|
||||
sh -c \
|
||||
"${lib.getExe pkgs.yt-dlp} --embed-subs --embed-metadata --embed-chapters \"$1\" && ${lib.getExe pkgs.libnotify} \"Download complete\" \"$filename\""
|
||||
"${
|
||||
lib.getExe pkgs.yt-dlp
|
||||
} --embed-subs --embed-metadata --embed-chapters \"$1\" && ${
|
||||
lib.getExe pkgs.libnotify
|
||||
} \"Download complete\" \"$filename\""
|
||||
else
|
||||
echo "File already fetched. Playing …"
|
||||
${lib.getExe config.programs.mpv.finalPackage} "$filename"
|
||||
fi
|
||||
'';
|
||||
commands =
|
||||
builtins.mapAttrs (name: {
|
||||
config ? "",
|
||||
user,
|
||||
}: let
|
||||
commands = builtins.mapAttrs (name:
|
||||
{ config ? "", user, }:
|
||||
let
|
||||
configFile = pkgs.writeText "${name}-newsboat-config" ''
|
||||
show-read-feeds no
|
||||
show-read-articles no
|
||||
|
@ -44,22 +44,21 @@
|
|||
miniflux-passwordeval "${lib.getExe rbw} get rss.maralorn.de ${user}"
|
||||
${config}
|
||||
'';
|
||||
in
|
||||
pkgs.writeShellScriptBin name "${lib.getExe pkgs.newsboat} -r -C ${configFile} -c ~/.local/share/newsboat/${name}-cache.db \"$@\"") {
|
||||
news = {
|
||||
user = "maralorn";
|
||||
in pkgs.writeShellScriptBin name ''
|
||||
${
|
||||
lib.getExe pkgs.newsboat
|
||||
} -r -C ${configFile} -c ~/.local/share/newsboat/${name}-cache.db "$@"'') {
|
||||
news = { user = "maralorn"; };
|
||||
software-updates = { user = "maralorn-softwareupdates"; };
|
||||
watchfeeds = {
|
||||
user = "maralorn-watchfeeds";
|
||||
config = ''
|
||||
browser "${lib.getExe download-and-watch} %u"
|
||||
'';
|
||||
};
|
||||
} // {
|
||||
inherit download-and-watch;
|
||||
};
|
||||
software-updates = {
|
||||
user = "maralorn-softwareupdates";
|
||||
};
|
||||
watchfeeds = {
|
||||
user = "maralorn-watchfeeds";
|
||||
config = ''
|
||||
browser "${lib.getExe download-and-watch} %u"
|
||||
'';
|
||||
};
|
||||
}
|
||||
// {inherit download-and-watch;};
|
||||
in {
|
||||
systemd.user = {
|
||||
services.update-software-feeds = {
|
||||
|
@ -75,10 +74,8 @@ in {
|
|||
timers.update-software-feeds = {
|
||||
Unit.Description = "Update software feeds";
|
||||
Timer.OnCalendar = "00:05";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
home = {
|
||||
packages = builtins.attrValues commands;
|
||||
};
|
||||
home = { packages = builtins.attrValues commands; };
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
defaultMode: {
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
defaultMode:
|
||||
{ lib, config, ... }:
|
||||
let
|
||||
# Persistent means that files get snapshoted and kept for a month
|
||||
# Volatile means that files just lay on the disk
|
||||
# Backups are organized independently on this system
|
||||
|
@ -35,8 +33,8 @@ defaultMode: {
|
|||
"git"
|
||||
"media"
|
||||
];
|
||||
persistentStateFiles = [".chpwd-recent-dirs"];
|
||||
volatileStateFiles = [];
|
||||
persistentStateFiles = [ ".chpwd-recent-dirs" ];
|
||||
volatileStateFiles = [ ];
|
||||
volatileStateDirs = [
|
||||
".steam"
|
||||
".local/share/Steam"
|
||||
|
@ -44,21 +42,21 @@ defaultMode: {
|
|||
".cache/nix-output-monitor"
|
||||
];
|
||||
mkLine = type: to: from: "${type} ${to} - - - - ${from}";
|
||||
mkEntry = type: persistence: name: let
|
||||
target = "/disk/${persistence}/maralorn/${name}";
|
||||
in [(mkLine "L+" "${home}/${name}" target) (mkLine type target "")];
|
||||
mkEntry = type: persistence: name:
|
||||
let target = "/disk/${persistence}/maralorn/${name}";
|
||||
in [ (mkLine "L+" "${home}/${name}" target) (mkLine type target "") ];
|
||||
in {
|
||||
systemd.user.tmpfiles.rules =
|
||||
lib.concatLists
|
||||
(
|
||||
map (mkEntry "f" "volatile") volatileStateFiles ++ map (mkEntry "d" "volatile") volatileStateDirs ++ map (mkEntry "f" "persist") persistentStateFiles ++ map (mkEntry "d" "persist") persistentStateDirs
|
||||
)
|
||||
++ [
|
||||
(mkLine "L+" "${home}/.password-store" "git/password-store")
|
||||
(mkLine "L+" "${home}/.volatile" "/disk/volatile/maralorn")
|
||||
(mkLine "L+" "${home}/.persist" "/disk/persist/maralorn")
|
||||
(mkLine "f" "${home}/.mode" defaultMode)
|
||||
(mkLine "f" "${home}/.config/lazygit/state.yml" "startuppopupversion: 5")
|
||||
(mkLine "d" "${home}/.cache/mutt" "")
|
||||
];
|
||||
systemd.user.tmpfiles.rules = lib.concatLists
|
||||
(map (mkEntry "f" "volatile") volatileStateFiles
|
||||
++ map (mkEntry "d" "volatile") volatileStateDirs
|
||||
++ map (mkEntry "f" "persist") persistentStateFiles
|
||||
++ map (mkEntry "d" "persist") persistentStateDirs) ++ [
|
||||
(mkLine "L+" "${home}/.password-store" "git/password-store")
|
||||
(mkLine "L+" "${home}/.volatile" "/disk/volatile/maralorn")
|
||||
(mkLine "L+" "${home}/.persist" "/disk/persist/maralorn")
|
||||
(mkLine "f" "${home}/.mode" defaultMode)
|
||||
(mkLine "f" "${home}/.config/lazygit/state.yml"
|
||||
"startuppopupversion: 5")
|
||||
(mkLine "d" "${home}/.cache/mutt" "")
|
||||
];
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, lib, ... }: {
|
||||
systemd.user.services.status-script = {
|
||||
Unit.Description = "Status Script";
|
||||
Service = {
|
||||
|
@ -10,6 +6,6 @@
|
|||
Restart = "always";
|
||||
RestartSec = "10s";
|
||||
};
|
||||
Install.WantedBy = ["graphical-session.target"];
|
||||
Install.WantedBy = [ "graphical-session.target" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }: {
|
||||
systemd.user = {
|
||||
services.prometheus-systemd-exporter = {
|
||||
Unit.Description = "Prometheus systemd exporter";
|
||||
Service = {
|
||||
ExecStart = "${pkgs.prometheus-systemd-exporter}/bin/systemd_exporter --systemd.collector.user";
|
||||
ExecStart =
|
||||
"${pkgs.prometheus-systemd-exporter}/bin/systemd_exporter --systemd.collector.user";
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,5 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
home.packages = [pkgs.taskwarrior-git];
|
||||
{ lib, pkgs, config, ... }: {
|
||||
home.packages = [ pkgs.taskwarrior-git ];
|
||||
home.file = {
|
||||
"add-git" = {
|
||||
target = ".task/hooks/on-add.git";
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
fix-tasks = pkgs.writeShellScriptBin "fix-tasks" ''
|
||||
sed 's/depends.*open.*\([0-9a-f]\{8\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{4\}-[0-9a-f]\{12\}\).*close[^ ]* /depends:"\1" /' -i ~/.task/*.data
|
||||
sed 's/dep_\[[^ ]* //' -i ~/.task/*.data
|
||||
'';
|
||||
in {
|
||||
home.packages = [fix-tasks];
|
||||
home.packages = [ fix-tasks ];
|
||||
services.taskwarrior-sync = {
|
||||
enable = true;
|
||||
frequency = "*:0/1";
|
||||
|
@ -18,26 +14,25 @@ in {
|
|||
taskwarrior-sync.Service.ExecStartPre =
|
||||
(pkgs.writeShellScript "ensure-taskwarrior-login" ''
|
||||
set -eu
|
||||
if [[ -z "$(${lib.getExe pkgs.taskwarrior} show taskd.credentials | grep maralorn)" ]]; then
|
||||
yes | /bin/sh <(${lib.getExe pkgs.openssh} root@hera nixos-taskserver user export maralorn.de maralorn)
|
||||
if [[ -z "$(${
|
||||
lib.getExe pkgs.taskwarrior
|
||||
} show taskd.credentials | grep maralorn)" ]]; then
|
||||
yes | /bin/sh <(${
|
||||
lib.getExe pkgs.openssh
|
||||
} root@hera nixos-taskserver user export maralorn.de maralorn)
|
||||
fi
|
||||
'')
|
||||
.outPath;
|
||||
'').outPath;
|
||||
watch-tasks = {
|
||||
Unit.Description = "Watch tasks for changes and trigger sync";
|
||||
Service = {
|
||||
ExecStart =
|
||||
(
|
||||
pkgs.writeShellScript "watch-vdir" ''
|
||||
while ${pkgs.coreutils}/bin/sleep 1s; do
|
||||
${pkgs.systemd}/bin/systemctl --user start taskwarrior-sync
|
||||
${pkgs.inotify-tools}/bin/inotifywait -e move,create,delete,modify -r ${config.home.homeDirectory}/.task
|
||||
done
|
||||
''
|
||||
)
|
||||
.outPath;
|
||||
ExecStart = (pkgs.writeShellScript "watch-vdir" ''
|
||||
while ${pkgs.coreutils}/bin/sleep 1s; do
|
||||
${pkgs.systemd}/bin/systemctl --user start taskwarrior-sync
|
||||
${pkgs.inotify-tools}/bin/inotifywait -e move,create,delete,modify -r ${config.home.homeDirectory}/.task
|
||||
done
|
||||
'').outPath;
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
home.file = {
|
||||
|
@ -61,36 +56,33 @@ in {
|
|||
target = ".task/hooks/on-modify.habitica-points";
|
||||
executable = true;
|
||||
source = "${
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "habitica-points";
|
||||
bins = [pkgs.curl pkgs.jq pkgs.libnotify];
|
||||
imports = ["Data.Aeson"];
|
||||
} ''
|
||||
pkgs.writeHaskellScript {
|
||||
name = "habitica-points";
|
||||
bins = [ pkgs.curl pkgs.jq pkgs.libnotify ];
|
||||
imports = [ "Data.Aeson" ];
|
||||
} ''
|
||||
|
||||
data Task = Task { status :: Text } deriving (Generic, FromJSON)
|
||||
data Task = Task { status :: Text } deriving (Generic, FromJSON)
|
||||
|
||||
main = do
|
||||
oldTask <- getLine
|
||||
newTask <- getLine
|
||||
let oldStatus = maybe "unknown" status (decode (encodeUtf8 oldTask))
|
||||
newStatus = maybe "unknown" status (decode (encodeUtf8 newTask))
|
||||
when (oldStatus /= "completed" && newStatus == "completed") $ do
|
||||
result :: String <- curl "-XPOST" "-H" "x-api-user: dbd97aba-8b6b-4649-9dd4-dad284333925" "-H" "x-api-key: ${pkgs.privateValue "" "habitica-token"}" "https://habitica.com/api/v3/tasks/6e95cccd-06e1-466c-b871-643dff31423c/score/up" |> jq "-c" ".data._tmp" |> captureTrim <&> decodeUtf8
|
||||
notify_send "Task Completed!" result
|
||||
putTextLn newTask
|
||||
''
|
||||
}/bin/habitica-points";
|
||||
main = do
|
||||
oldTask <- getLine
|
||||
newTask <- getLine
|
||||
let oldStatus = maybe "unknown" status (decode (encodeUtf8 oldTask))
|
||||
newStatus = maybe "unknown" status (decode (encodeUtf8 newTask))
|
||||
when (oldStatus /= "completed" && newStatus == "completed") $ do
|
||||
result :: String <- curl "-XPOST" "-H" "x-api-user: dbd97aba-8b6b-4649-9dd4-dad284333925" "-H" "x-api-key: ${
|
||||
pkgs.privateValue "" "habitica-token"
|
||||
}" "https://habitica.com/api/v3/tasks/6e95cccd-06e1-466c-b871-643dff31423c/score/up" |> jq "-c" ".data._tmp" |> captureTrim <&> decodeUtf8
|
||||
notify_send "Task Completed!" result
|
||||
putTextLn newTask
|
||||
''
|
||||
}/bin/habitica-points";
|
||||
};
|
||||
};
|
||||
programs.taskwarrior = {
|
||||
enable = true;
|
||||
dataLocation = "${config.home.homeDirectory}/.task";
|
||||
config = {
|
||||
taskd = {
|
||||
server = "taskserver.maralorn.de:53589";
|
||||
};
|
||||
};
|
||||
config = { taskd = { server = "taskserver.maralorn.de:53589"; }; };
|
||||
extraConfig = ''
|
||||
alias.inbox=+PENDING -TAGGED limit:1
|
||||
alias.inboxall=+PENDING -TAGGED
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, config, ... }: {
|
||||
home.sessionVariables.TERMINAL = "${pkgs.foot}/bin/foot";
|
||||
home.packages = [
|
||||
(pkgs.recursiveLinkFarm "fake-gnome-terminal" {
|
||||
|
@ -13,12 +9,10 @@
|
|||
settings = {
|
||||
main = {
|
||||
font = "Symbols Nerd Font Mono:pixelsize=12,CozetteVector:pixelsize=12";
|
||||
include =
|
||||
(pkgs.runCommandLocal "foot-theme" {} ''
|
||||
cat ${pkgs.foot.themes}/share/foot/themes/catppuccin > $out
|
||||
echo -e "background=000000\nalpha=0.9" >> $out
|
||||
'')
|
||||
.outPath;
|
||||
include = (pkgs.runCommandLocal "foot-theme" { } ''
|
||||
cat ${pkgs.foot.themes}/share/foot/themes/catppuccin > $out
|
||||
echo -e "background=000000\nalpha=0.9" >> $out
|
||||
'').outPath;
|
||||
};
|
||||
csd = {
|
||||
preferred = "client";
|
||||
|
@ -26,9 +20,7 @@
|
|||
border-width = "1";
|
||||
color = "ff${config.m-0.colors.accent}";
|
||||
};
|
||||
mouse = {
|
||||
hide-when-typing = "yes";
|
||||
};
|
||||
mouse = { hide-when-typing = "yes"; };
|
||||
tweak.font-monospace-warn = "no";
|
||||
};
|
||||
enable = true;
|
||||
|
|
|
@ -1,16 +1,8 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }: {
|
||||
home.packages = builtins.attrValues {
|
||||
inherit (pkgs.xorg) xev;
|
||||
inherit
|
||||
(pkgs)
|
||||
meld
|
||||
icedtea8_web
|
||||
octave
|
||||
filezilla
|
||||
nix-review
|
||||
gparted
|
||||
grafana-devel
|
||||
;
|
||||
inherit (pkgs)
|
||||
meld icedtea8_web octave filezilla nix-review gparted grafana-devel;
|
||||
};
|
||||
home.file.".editorconfig".text = ''
|
||||
# Top-most EditorConfig file
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
_: {
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/screensaver" = {
|
||||
lock-enabled = false;
|
||||
};
|
||||
"org/gnome/desktop/screensaver" = { lock-enabled = false; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,17 +1,8 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
makeUnlocker = {
|
||||
name,
|
||||
hostName,
|
||||
pubKey,
|
||||
passwordName,
|
||||
}: let
|
||||
knownHosts = pkgs.writeText "KnownBootHosts" "${hostName} ${pubKey}";
|
||||
in
|
||||
pkgs.writeShellScriptBin "unlock-${name}" ''
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
makeUnlocker = { name, hostName, pubKey, passwordName, }:
|
||||
let knownHosts = pkgs.writeText "KnownBootHosts" "${hostName} ${pubKey}";
|
||||
in pkgs.writeShellScriptBin "unlock-${name}" ''
|
||||
echo "Waiting for host to come up";
|
||||
while true; do
|
||||
echo -n .
|
||||
|
@ -22,12 +13,11 @@
|
|||
echo "Ping successful; Entering disk encryption password"
|
||||
${config.programs.rbw.package}/bin/rbw get ${passwordName} | (ssh -4 root@${hostName} -o UserKnownHostsFile=${knownHosts} cryptsetup-askpass && echo "Unlocking of ${name} successful" || echo "Unlocking of ${name} failed")
|
||||
'';
|
||||
unlocker = [
|
||||
{
|
||||
name = "hera";
|
||||
hostName = "hera-v4";
|
||||
pubKey = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCHkqWlFLtmIlTSKahr2PcL++K75YgfsSU6jwVYW5df3JCkowu/M16SIBxABxYSQrKej5uIz/OFCjqSxHJQ8D5wSYBvn2gYr/BbBcz4rfIJmZ55Od2jckaqlj/M8TtkuPPhsQG7S730vXxK5hbMT8iW5WWv8sIKY/WtaRbZOFMX/53WCLEHtnMu5zFJFWf92+mjIHSLyW8ggl1m525RUiaAfCge2vnuzIFq4kUqJxaWzxIvEWIncKWN10K/HMvdI+yOtbSen41uKedwSFhUFs3xHy1mJddYOrlcJQPt5zuuffZ/nTDVXMZoh5QNwg8ZlkkueVChaS1Y5STjb7cem1Mt";
|
||||
passwordName = "hera.m-0.eu disk";
|
||||
}
|
||||
];
|
||||
in {config = {home.packages = map makeUnlocker unlocker;};}
|
||||
unlocker = [{
|
||||
name = "hera";
|
||||
hostName = "hera-v4";
|
||||
pubKey =
|
||||
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCHkqWlFLtmIlTSKahr2PcL++K75YgfsSU6jwVYW5df3JCkowu/M16SIBxABxYSQrKej5uIz/OFCjqSxHJQ8D5wSYBvn2gYr/BbBcz4rfIJmZ55Od2jckaqlj/M8TtkuPPhsQG7S730vXxK5hbMT8iW5WWv8sIKY/WtaRbZOFMX/53WCLEHtnMu5zFJFWf92+mjIHSLyW8ggl1m525RUiaAfCge2vnuzIFq4kUqJxaWzxIvEWIncKWN10K/HMvdI+yOtbSen41uKedwSFhUFs3xHy1mJddYOrlcJQPt5zuuffZ/nTDVXMZoh5QNwg8ZlkkueVChaS1Y5STjb7cem1Mt";
|
||||
passwordName = "hera.m-0.eu disk";
|
||||
}];
|
||||
in { config = { home.packages = map makeUnlocker unlocker; }; }
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
_: {
|
||||
dconf.settings = {
|
||||
"org/gnome/desktop/screensaver" = {
|
||||
lock-enabled = true;
|
||||
};
|
||||
"org/gnome/desktop/screensaver" = { lock-enabled = true; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,115 +1,87 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
addressbooks = pkgs.privateValue [] "addressbooks";
|
||||
calendars = pkgs.privateValue [] "calendars";
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
addressbooks = pkgs.privateValue [ ] "addressbooks";
|
||||
calendars = pkgs.privateValue [ ] "calendars";
|
||||
mkConfig = config:
|
||||
(pkgs.formats.ini {}).generate "vdirsyncer-config" (
|
||||
lib.mapAttrs
|
||||
(
|
||||
_: lib.mapAttrs (_: builtins.toJSON)
|
||||
)
|
||||
config
|
||||
);
|
||||
mkCalendar = {
|
||||
name,
|
||||
url,
|
||||
username,
|
||||
passwordPath,
|
||||
collections ? ["from a" "from b"],
|
||||
readOnly ? false,
|
||||
type ? "caldav",
|
||||
}: let
|
||||
pairName = "${name}_calendar";
|
||||
remoteName = "${pairName}_remote";
|
||||
localName = "${pairName}_local";
|
||||
in {
|
||||
"pair ${pairName}" = {
|
||||
a = localName;
|
||||
b = remoteName;
|
||||
inherit collections;
|
||||
conflict_resolution = "b wins";
|
||||
metadata = ["color"];
|
||||
};
|
||||
"storage ${localName}" = {
|
||||
type = "filesystem";
|
||||
path = "~/.calendars/${name}/";
|
||||
fileext = ".ics";
|
||||
};
|
||||
"storage ${remoteName}" =
|
||||
{
|
||||
(pkgs.formats.ini { }).generate "vdirsyncer-config"
|
||||
(lib.mapAttrs (_: lib.mapAttrs (_: builtins.toJSON)) config);
|
||||
mkCalendar = { name, url, username, passwordPath
|
||||
, collections ? [ "from a" "from b" ], readOnly ? false, type ? "caldav", }:
|
||||
let
|
||||
pairName = "${name}_calendar";
|
||||
remoteName = "${pairName}_remote";
|
||||
localName = "${pairName}_local";
|
||||
in {
|
||||
"pair ${pairName}" = {
|
||||
a = localName;
|
||||
b = remoteName;
|
||||
inherit collections;
|
||||
conflict_resolution = "b wins";
|
||||
metadata = [ "color" ];
|
||||
};
|
||||
"storage ${localName}" = {
|
||||
type = "filesystem";
|
||||
path = "~/.calendars/${name}/";
|
||||
fileext = ".ics";
|
||||
};
|
||||
"storage ${remoteName}" = {
|
||||
inherit type;
|
||||
inherit url;
|
||||
}
|
||||
// (
|
||||
if (type == "caldav")
|
||||
then {
|
||||
inherit username;
|
||||
"password.fetch" = ["command" (lib.getExe config.programs.rbw.package) "get"] ++ passwordPath;
|
||||
read_only = readOnly;
|
||||
}
|
||||
else {}
|
||||
);
|
||||
};
|
||||
mkAddressbook = {
|
||||
name,
|
||||
url,
|
||||
username,
|
||||
passwordPath,
|
||||
collections ? ["from a" "from b"],
|
||||
readOnly ? false,
|
||||
}: let
|
||||
pairName = "${name}_contacts";
|
||||
remoteName = "${pairName}_remote";
|
||||
localName = "${pairName}_local";
|
||||
in {
|
||||
"pair ${pairName}" = {
|
||||
a = localName;
|
||||
b = remoteName;
|
||||
inherit collections;
|
||||
conflict_resolution = "b wins";
|
||||
} // (if (type == "caldav") then {
|
||||
inherit username;
|
||||
"password.fetch" =
|
||||
[ "command" (lib.getExe config.programs.rbw.package) "get" ]
|
||||
++ passwordPath;
|
||||
read_only = readOnly;
|
||||
} else
|
||||
{ });
|
||||
};
|
||||
"storage ${localName}" = {
|
||||
type = "filesystem";
|
||||
path = "~/.contacts/${name}/";
|
||||
fileext = ".vcf";
|
||||
mkAddressbook = { name, url, username, passwordPath
|
||||
, collections ? [ "from a" "from b" ], readOnly ? false, }:
|
||||
let
|
||||
pairName = "${name}_contacts";
|
||||
remoteName = "${pairName}_remote";
|
||||
localName = "${pairName}_local";
|
||||
in {
|
||||
"pair ${pairName}" = {
|
||||
a = localName;
|
||||
b = remoteName;
|
||||
inherit collections;
|
||||
conflict_resolution = "b wins";
|
||||
};
|
||||
"storage ${localName}" = {
|
||||
type = "filesystem";
|
||||
path = "~/.contacts/${name}/";
|
||||
fileext = ".vcf";
|
||||
};
|
||||
"storage ${remoteName}" = {
|
||||
type = "carddav";
|
||||
inherit url username;
|
||||
"password.fetch" =
|
||||
[ "command" (lib.getExe config.programs.rbw.package) "get" ]
|
||||
++ passwordPath;
|
||||
read_only = readOnly;
|
||||
};
|
||||
};
|
||||
"storage ${remoteName}" = {
|
||||
type = "carddav";
|
||||
inherit url username;
|
||||
"password.fetch" = ["command" (lib.getExe config.programs.rbw.package) "get"] ++ passwordPath;
|
||||
read_only = readOnly;
|
||||
};
|
||||
};
|
||||
in {
|
||||
xdg.configFile."vdirsyncer/config".source =
|
||||
mkConfig
|
||||
(
|
||||
pkgs.lib.fold (a: b: a // b)
|
||||
{
|
||||
general.status_path = "~/.vdirsyncer/status";
|
||||
}
|
||||
(map mkCalendar calendars ++ map mkAddressbook addressbooks)
|
||||
);
|
||||
home.packages = [pkgs.vdirsyncer];
|
||||
xdg.configFile."vdirsyncer/config".source = mkConfig
|
||||
(pkgs.lib.fold (a: b: a // b) {
|
||||
general.status_path = "~/.vdirsyncer/status";
|
||||
} (map mkCalendar calendars ++ map mkAddressbook addressbooks));
|
||||
home.packages = [ pkgs.vdirsyncer ];
|
||||
|
||||
systemd.user = {
|
||||
services.watch-vdir = {
|
||||
Unit.Description = "Watch vdir data for changes";
|
||||
Service = {
|
||||
ExecStart = toString (
|
||||
pkgs.writeShellScript "watch-vdir" ''
|
||||
while ${pkgs.coreutils}/bin/sleep 1s; do
|
||||
${pkgs.vdirsyncer}/bin/vdirsyncer sync
|
||||
${pkgs.inotify-tools}/bin/inotifywait -e move,create,delete,modify -r ${config.home.homeDirectory}/.contacts ${config.home.homeDirectory}/.calendars
|
||||
done
|
||||
''
|
||||
);
|
||||
ExecStart = toString (pkgs.writeShellScript "watch-vdir" ''
|
||||
while ${pkgs.coreutils}/bin/sleep 1s; do
|
||||
${pkgs.vdirsyncer}/bin/vdirsyncer sync
|
||||
${pkgs.inotify-tools}/bin/inotifywait -e move,create,delete,modify -r ${config.home.homeDirectory}/.contacts ${config.home.homeDirectory}/.calendars
|
||||
done
|
||||
'');
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
services.vdirsyncer = {
|
||||
Unit.Description = "vdirsyncer sync";
|
||||
|
@ -123,7 +95,7 @@ in {
|
|||
timers.vdirsyncer = {
|
||||
Unit.Description = "vdirsync sync timer";
|
||||
Timer.OnCalendar = "*:0/15";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,32 +1,27 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
modeFile = "${config.home.homeDirectory}/.mode";
|
||||
wallPapers = "${config.home.homeDirectory}/media/images/wallpapers";
|
||||
randomWallpaper =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "random-wallpaper";
|
||||
imports = ["System.Random"];
|
||||
bins = [pkgs.coreutils pkgs.glib];
|
||||
} ''
|
||||
main = do
|
||||
mode <- cat "${modeFile}" |> captureTrim
|
||||
(lines . decodeUtf8 -> files) <- ls ([i|${wallPapers}/#{mode}|] :: String) |> captureTrim
|
||||
((files Unsafe.!!) -> file) <- getStdRandom $ randomR (0, length files - 1)
|
||||
(decodeUtf8 -> current) <- gsettings "get" "org.gnome.desktop.background" "picture-uri" |> captureTrim
|
||||
let new = [i|file:///${wallPapers}/#{mode}/#{file}|] :: String
|
||||
when (new /= current) $ do
|
||||
gsettings "set" "org.gnome.desktop.background" "picture-uri" new
|
||||
gsettings "set" "org.gnome.desktop.screensaver" "picture-uri" new
|
||||
'';
|
||||
randomWallpaper = pkgs.writeHaskellScript {
|
||||
name = "random-wallpaper";
|
||||
imports = [ "System.Random" ];
|
||||
bins = [ pkgs.coreutils pkgs.glib ];
|
||||
} ''
|
||||
main = do
|
||||
mode <- cat "${modeFile}" |> captureTrim
|
||||
(lines . decodeUtf8 -> files) <- ls ([i|${wallPapers}/#{mode}|] :: String) |> captureTrim
|
||||
((files Unsafe.!!) -> file) <- getStdRandom $ randomR (0, length files - 1)
|
||||
(decodeUtf8 -> current) <- gsettings "get" "org.gnome.desktop.background" "picture-uri" |> captureTrim
|
||||
let new = [i|file:///${wallPapers}/#{mode}/#{file}|] :: String
|
||||
when (new /= current) $ do
|
||||
gsettings "set" "org.gnome.desktop.background" "picture-uri" new
|
||||
gsettings "set" "org.gnome.desktop.screensaver" "picture-uri" new
|
||||
'';
|
||||
in {
|
||||
home.packages = [randomWallpaper];
|
||||
home.packages = [ randomWallpaper ];
|
||||
systemd.user = {
|
||||
services.random-wallpaper = {
|
||||
Unit = {Description = "Random Wallpaper";};
|
||||
Unit = { Description = "Random Wallpaper"; };
|
||||
Service = {
|
||||
ExecStart = "${randomWallpaper}/bin/random-wallpaper";
|
||||
Type = "oneshot";
|
||||
|
@ -37,7 +32,7 @@ in {
|
|||
OnCalendar = "*:00/30:00";
|
||||
OnActiveSec = 1;
|
||||
};
|
||||
Install = {WantedBy = ["timers.target"];};
|
||||
Install = { WantedBy = [ "timers.target" ]; };
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,19 +1,13 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}:
|
||||
with lib; let
|
||||
{ lib, pkgs, config, ... }:
|
||||
with lib;
|
||||
let
|
||||
weechat = pkgs.wrapWeechat pkgs.weechat-unwrapped {
|
||||
configure = {availablePlugins, ...}: {
|
||||
plugins = builtins.attrValues (availablePlugins
|
||||
// {
|
||||
python =
|
||||
availablePlugins.python.withPackages
|
||||
(_: [pkgs.weechatScripts.weechat-matrix]);
|
||||
});
|
||||
scripts = [pkgs.weechatScripts.weechat-matrix];
|
||||
configure = { availablePlugins, ... }: {
|
||||
plugins = builtins.attrValues (availablePlugins // {
|
||||
python = availablePlugins.python.withPackages
|
||||
(_: [ pkgs.weechatScripts.weechat-matrix ]);
|
||||
});
|
||||
scripts = [ pkgs.weechatScripts.weechat-matrix ];
|
||||
};
|
||||
};
|
||||
in {
|
||||
|
@ -82,15 +76,13 @@ in {
|
|||
[look]
|
||||
human_buffer_names = on
|
||||
[server]
|
||||
${
|
||||
lib.concatStringsSep "\n" (lib.mapAttrsToList
|
||||
(server: serverConfig: ''
|
||||
${server}.address = "${serverConfig.address}"
|
||||
${server}.autoconnect = on
|
||||
${server}.username = "${serverConfig.user}"
|
||||
${server}.password = "${serverConfig.password}"
|
||||
'') (pkgs.privateValue {} "weechat/matrix"))
|
||||
}
|
||||
${lib.concatStringsSep "\n" (lib.mapAttrsToList
|
||||
(server: serverConfig: ''
|
||||
${server}.address = "${serverConfig.address}"
|
||||
${server}.autoconnect = on
|
||||
${server}.username = "${serverConfig.user}"
|
||||
${server}.password = "${serverConfig.password}"
|
||||
'') (pkgs.privateValue { } "weechat/matrix"))}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
@ -98,7 +90,7 @@ in {
|
|||
systemd.user = {
|
||||
timers.log2rss = {
|
||||
Timer.OnCalendar = "23:58";
|
||||
Install.WantedBy = ["timers.target"];
|
||||
Install.WantedBy = [ "timers.target" ];
|
||||
};
|
||||
services = {
|
||||
log2rss = {
|
||||
|
@ -112,10 +104,11 @@ in {
|
|||
Unit.Description = "Weechat Tmux Session";
|
||||
Service = {
|
||||
Type = "forking";
|
||||
ExecStart = "${pkgs.tmux}/bin/tmux -L weechat -2 new-session -d -s irc -n weechat '${weechat}/bin/weechat'";
|
||||
ExecStart =
|
||||
"${pkgs.tmux}/bin/tmux -L weechat -2 new-session -d -s irc -n weechat '${weechat}/bin/weechat'";
|
||||
Restart = "always";
|
||||
};
|
||||
Install.WantedBy = ["default.target"];
|
||||
Install.WantedBy = [ "default.target" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
wine_dir = "${config.home.homeDirectory}/.volatile/wine_disk";
|
||||
wine = pkgs.wineWowPackages.staging;
|
||||
in {
|
||||
|
@ -14,8 +11,6 @@ in {
|
|||
STAGING_SHARED_MEMORY = 1;
|
||||
WINEESYNC = 1;
|
||||
};
|
||||
packages = builtins.attrValues {
|
||||
inherit wine;
|
||||
};
|
||||
packages = builtins.attrValues { inherit wine; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
{ config, pkgs, ... }: {
|
||||
services.emanote = {
|
||||
enable = true;
|
||||
# host = "127.0.0.1"; # default listen address is 127.0.0.1
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }: {
|
||||
programs.zsh = {
|
||||
enable = true;
|
||||
enableAutosuggestions = true;
|
||||
|
@ -23,14 +23,12 @@
|
|||
'';
|
||||
oh-my-zsh = {
|
||||
enable = true;
|
||||
plugins = ["colored-man-pages"];
|
||||
plugins = [ "colored-man-pages" ];
|
||||
};
|
||||
plugins = [
|
||||
{
|
||||
name = "zsh-nix-shell";
|
||||
file = "nix-shell.plugin.zsh";
|
||||
src = "${pkgs.zsh-nix-shell}/share/zsh-nix-shell";
|
||||
}
|
||||
];
|
||||
plugins = [{
|
||||
name = "zsh-nix-shell";
|
||||
file = "nix-shell.plugin.zsh";
|
||||
src = "${pkgs.zsh-nix-shell}/share/zsh-nix-shell";
|
||||
}];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,26 +1,17 @@
|
|||
{
|
||||
withSystem,
|
||||
lib,
|
||||
inputs,
|
||||
...
|
||||
}: {
|
||||
{ withSystem, lib, inputs, ... }: {
|
||||
flake = {
|
||||
nixosConfigurations = withSystem "x86_64-linux" ({
|
||||
system,
|
||||
self',
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
machines = builtins.attrNames (builtins.readDir ./machines);
|
||||
makeSystem = name:
|
||||
pkgs.nixos {
|
||||
imports = [
|
||||
(import (./. + "/machines/${name}/configuration.nix") inputs)
|
||||
inputs.secrets.nixosModules.default
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
];
|
||||
};
|
||||
in
|
||||
lib.genAttrs machines makeSystem);
|
||||
nixosConfigurations = withSystem "x86_64-linux"
|
||||
({ system, self', pkgs, ... }:
|
||||
let
|
||||
machines = builtins.attrNames (builtins.readDir ./machines);
|
||||
makeSystem = name:
|
||||
pkgs.nixos {
|
||||
imports = [
|
||||
(import (./. + "/machines/${name}/configuration.nix") inputs)
|
||||
inputs.secrets.nixosModules.default
|
||||
inputs.impermanence.nixosModules.impermanence
|
||||
];
|
||||
};
|
||||
in lib.genAttrs machines makeSystem);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
flake-inputs: {
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
inherit (import ../../../common/common.nix {inherit pkgs;}) syncthing;
|
||||
flake-inputs:
|
||||
{ lib, config, pkgs, ... }:
|
||||
let inherit (import ../../../common/common.nix { inherit pkgs; }) syncthing;
|
||||
in {
|
||||
imports = [
|
||||
(flake-inputs.secrets.lib.vpn "apollo")
|
||||
|
@ -41,7 +37,7 @@ in {
|
|||
network.wait-online.enable = false;
|
||||
services = {
|
||||
NetworkManager-wait-online.enable = false;
|
||||
throttled.path = [pkgs.kmod];
|
||||
throttled.path = [ pkgs.kmod ];
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -64,16 +60,15 @@ in {
|
|||
cleanupInterval = "15m";
|
||||
snapshotInterval = "*:00/3:00";
|
||||
};
|
||||
syncthing =
|
||||
{
|
||||
enable = true;
|
||||
group = "users";
|
||||
user = "maralorn";
|
||||
openDefaultPorts = true;
|
||||
cert = config.age.secrets."syncthing/apollo/cert.pem".path;
|
||||
key = config.age.secrets."syncthing/apollo/key.pem".path;
|
||||
}
|
||||
// syncthing.declarativeWith ["hera" "zeus" "pegasus"] "/home/maralorn/media";
|
||||
syncthing = {
|
||||
enable = true;
|
||||
group = "users";
|
||||
user = "maralorn";
|
||||
openDefaultPorts = true;
|
||||
cert = config.age.secrets."syncthing/apollo/cert.pem".path;
|
||||
key = config.age.secrets."syncthing/apollo/key.pem".path;
|
||||
} // syncthing.declarativeWith [ "hera" "zeus" "pegasus" ]
|
||||
"/home/maralorn/media";
|
||||
};
|
||||
system.stateVersion = "19.09";
|
||||
}
|
||||
|
|
|
@ -1,11 +1,5 @@
|
|||
{
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
{ lib, modulesPath, ... }: {
|
||||
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
||||
boot = {
|
||||
loader = {
|
||||
efi = {
|
||||
|
@ -22,18 +16,20 @@
|
|||
};
|
||||
};
|
||||
initrd = {
|
||||
luks.devices."nixos".device = "/dev/disk/by-uuid/78acaebe-952a-43b1-acc8-66c35a60577e";
|
||||
availableKernelModules = ["xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc"];
|
||||
luks.devices."nixos".device =
|
||||
"/dev/disk/by-uuid/78acaebe-952a-43b1-acc8-66c35a60577e";
|
||||
availableKernelModules =
|
||||
[ "xhci_pci" "nvme" "usb_storage" "sd_mod" "rtsx_pci_sdmmc" ];
|
||||
};
|
||||
kernelModules = ["kvm-intel"];
|
||||
supportedFilesystems = ["exfat"];
|
||||
kernelModules = [ "kvm-intel" ];
|
||||
supportedFilesystems = [ "exfat" ];
|
||||
};
|
||||
|
||||
fileSystems = {
|
||||
"/" = {
|
||||
device = "/dev/disk/by-uuid/ce5b0ac6-6eaf-45a6-b6c8-bd4958caf335";
|
||||
fsType = "btrfs";
|
||||
options = ["compress=zstd" "autodefrag" "noatime"];
|
||||
options = [ "compress=zstd" "autodefrag" "noatime" ];
|
||||
};
|
||||
"/boot/EFI" = {
|
||||
device = "/dev/disk/by-uuid/C4A6-3DB5";
|
||||
|
@ -41,11 +37,7 @@
|
|||
};
|
||||
};
|
||||
zramSwap.enable = true;
|
||||
swapDevices = [
|
||||
{
|
||||
device = "/dev/mapper/system-swap";
|
||||
}
|
||||
];
|
||||
swapDevices = [{ device = "/dev/mapper/system-swap"; }];
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
nix.settings.max-jobs = lib.mkDefault 8;
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
flake-inputs: {
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
flake-inputs:
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
wireguard = import ../../../common/wireguard.nix;
|
||||
inherit (config.m-0) hosts;
|
||||
localAddress = "fdc0:1::2";
|
||||
|
@ -20,12 +17,12 @@ in {
|
|||
./hardware-configuration.nix
|
||||
];
|
||||
|
||||
age.identityPaths = ["/disk/persist/etc/ssh/ssh_host_ed25519_key"];
|
||||
age.identityPaths = [ "/disk/persist/etc/ssh/ssh_host_ed25519_key" ];
|
||||
|
||||
fileSystems = let
|
||||
btrfsOptions = {options = ["compress=zstd" "autodefrag" "noatime"];};
|
||||
btrfsOptions = { options = [ "compress=zstd" "autodefrag" "noatime" ]; };
|
||||
in {
|
||||
"/disk" = {neededForBoot = true;} // btrfsOptions;
|
||||
"/disk" = { neededForBoot = true; } // btrfsOptions;
|
||||
"/nix" = btrfsOptions;
|
||||
};
|
||||
|
||||
|
@ -52,11 +49,7 @@ in {
|
|||
];
|
||||
|
||||
environment.persistence."/disk/persist" = {
|
||||
directories = [
|
||||
"/etc/ssh"
|
||||
"/var/lib/nixos"
|
||||
"/var/lib/tailscale"
|
||||
];
|
||||
directories = [ "/etc/ssh" "/var/lib/nixos" "/var/lib/tailscale" ];
|
||||
};
|
||||
|
||||
boot = {
|
||||
|
@ -74,7 +67,8 @@ in {
|
|||
keyFile = "/diskkey.bin";
|
||||
};
|
||||
secrets = {
|
||||
"diskkey.bin" = "/disk/persist/diskkey.bin"; # Key can live on crypted disk, is copied to initrd on install
|
||||
"diskkey.bin" =
|
||||
"/disk/persist/diskkey.bin"; # Key can live on crypted disk, is copied to initrd on install
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -100,12 +94,10 @@ in {
|
|||
];
|
||||
};
|
||||
interfaces.enp1s0 = {
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = localAddress;
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [{
|
||||
address = localAddress;
|
||||
prefixLength = 64;
|
||||
}];
|
||||
useDHCP = true;
|
||||
};
|
||||
#wireguard.interfaces = {
|
||||
|
@ -124,32 +116,26 @@ in {
|
|||
# };
|
||||
#};
|
||||
};
|
||||
programs = {
|
||||
ssh = {
|
||||
startAgent = true;
|
||||
};
|
||||
};
|
||||
programs = { ssh = { startAgent = true; }; };
|
||||
hardware.printers = {
|
||||
ensureDefaultPrinter = "Klio";
|
||||
ensurePrinters = [
|
||||
{
|
||||
name = "Klio";
|
||||
location = "Wohnzimmer";
|
||||
description = "Klio (Brother MFC-L3750CDW)";
|
||||
deviceUri = "ipp://klio.lo.m-0.eu/ipp";
|
||||
model = "everywhere";
|
||||
}
|
||||
];
|
||||
ensurePrinters = [{
|
||||
name = "Klio";
|
||||
location = "Wohnzimmer";
|
||||
description = "Klio (Brother MFC-L3750CDW)";
|
||||
deviceUri = "ipp://klio.lo.m-0.eu/ipp";
|
||||
model = "everywhere";
|
||||
}];
|
||||
};
|
||||
services = {
|
||||
borgbackup.repos.hera = {
|
||||
path = "/backup/hera-borg-repo";
|
||||
authorizedKeys = pkgs.privateValue ["dummy-key"] "backup-ssh-keys";
|
||||
authorizedKeys = pkgs.privateValue [ "dummy-key" ] "backup-ssh-keys";
|
||||
};
|
||||
printing = {
|
||||
enable = true;
|
||||
allowFrom = ["all"];
|
||||
listenAddresses = ["[${localAddress}]:631"];
|
||||
allowFrom = [ "all" ];
|
||||
listenAddresses = [ "[${localAddress}]:631" ];
|
||||
extraConf = "ServerAlias *";
|
||||
defaultShared = true;
|
||||
};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{device, ...}: {
|
||||
{ device, ... }: {
|
||||
disko.devices = {
|
||||
disk.system = {
|
||||
type = "disk";
|
||||
|
@ -33,24 +33,16 @@
|
|||
content = {
|
||||
type = "luks";
|
||||
name = "system";
|
||||
extraOpenArgs = ["--allow-discards"];
|
||||
extraOpenArgs = [ "--allow-discards" ];
|
||||
content = {
|
||||
type = "btrfs";
|
||||
extraArgs = ["-f"]; # Override existing partition
|
||||
extraArgs = [ "-f" ]; # Override existing partition
|
||||
subvolumes = {
|
||||
# Mountpoints inferred from subvolume name
|
||||
"/disk" = {
|
||||
mountOptions = ["compress=zstd"];
|
||||
};
|
||||
"/disk/persist" = {
|
||||
mountOptions = ["compress=zstd"];
|
||||
};
|
||||
"/disk/volatile" = {
|
||||
mountOptions = ["compress=zstd"];
|
||||
};
|
||||
"/nix" = {
|
||||
mountOptions = ["compress=zstd" "noatime"];
|
||||
};
|
||||
"/disk" = { mountOptions = [ "compress=zstd" ]; };
|
||||
"/disk/persist" = { mountOptions = [ "compress=zstd" ]; };
|
||||
"/disk/volatile" = { mountOptions = [ "compress=zstd" ]; };
|
||||
"/nix" = { mountOptions = [ "compress=zstd" "noatime" ]; };
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -59,10 +51,7 @@
|
|||
};
|
||||
nodev."/" = {
|
||||
fsType = "tmpfs";
|
||||
mountOptions = [
|
||||
"defaults"
|
||||
"mode=755"
|
||||
];
|
||||
mountOptions = [ "defaults" "mode=755" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,15 +1,10 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci"];
|
||||
boot.kernelModules = ["kvm-intel"];
|
||||
{ config, lib, pkgs, modulesPath, ... }: {
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "tmpfs";
|
||||
|
@ -31,14 +26,16 @@
|
|||
fsType = "ext4";
|
||||
};
|
||||
|
||||
boot.initrd.luks.devices."crypted-nixos".device = "/dev/disk/by-uuid/020fde09-f651-45a2-9c6a-9b060edf967d";
|
||||
boot.initrd.luks.devices."crypted-nixos".device =
|
||||
"/dev/disk/by-uuid/020fde09-f651-45a2-9c6a-9b060edf967d";
|
||||
|
||||
fileSystems."/nix" = {
|
||||
device = "/dev/disk/by-uuid/9acbc122-e818-49fa-bc2e-de7d9f822d5a";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=nix"];
|
||||
options = [ "subvol=nix" ];
|
||||
};
|
||||
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
hardware.cpu.intel.updateMicrocode =
|
||||
lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{pkgs, ...}: {
|
||||
{ pkgs, ... }: {
|
||||
m-0.server.initSSHKey = "/var/boot-ssh-key";
|
||||
|
||||
boot = {
|
||||
|
@ -7,8 +7,8 @@
|
|||
version = 2;
|
||||
device = "/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_drive-scsi0";
|
||||
};
|
||||
supportedFilesystems = ["exfat"];
|
||||
kernelParams = ["ip=213.136.94.190::213.136.94.1:255.255.255.0:hera"];
|
||||
supportedFilesystems = [ "exfat" ];
|
||||
kernelParams = [ "ip=213.136.94.190::213.136.94.1:255.255.255.0:hera" ];
|
||||
initrd.luks.devices.root = {
|
||||
device = "/dev/disk/by-uuid/536fe284-36f2-425c-b0c5-a737280f9470";
|
||||
preLVM = true;
|
||||
|
|
|
@ -1,21 +1,15 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
adminCreds =
|
||||
pkgs.privateValue
|
||||
{
|
||||
adminpass = "";
|
||||
dbpass = "";
|
||||
adminuser = "";
|
||||
} "nextcloud-admin";
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
adminCreds = pkgs.privateValue {
|
||||
adminpass = "";
|
||||
dbpass = "";
|
||||
adminuser = "";
|
||||
} "nextcloud-admin";
|
||||
inherit (config.m-0) hosts;
|
||||
certPath = "/var/lib/acme";
|
||||
nextcloudServices = hostname: {
|
||||
nextcloud-pg-backup = {
|
||||
script = let
|
||||
name = "nextcloud-psql-${hostname}";
|
||||
script = let name = "nextcloud-psql-${hostname}";
|
||||
in ''
|
||||
${config.services.postgresql.package}/bin/pg_dump nextcloud > /var/lib/db-backup-dumps/${name}
|
||||
'';
|
||||
|
@ -26,8 +20,8 @@
|
|||
};
|
||||
prometheus-nginx-exporter.serviceConfig.RestartSec = 10;
|
||||
nextcloud-setup = {
|
||||
requires = ["postgresql.service" "redis.service"];
|
||||
after = ["postgresql.service" "redis.service"];
|
||||
requires = [ "postgresql.service" "redis.service" ];
|
||||
after = [ "postgresql.service" "redis.service" ];
|
||||
};
|
||||
};
|
||||
nextcloudConf = hostname: {
|
||||
|
@ -45,18 +39,15 @@
|
|||
dbtype = "pgsql";
|
||||
defaultPhoneRegion = "DE";
|
||||
adminuser = "maralorn";
|
||||
adminpassFile = builtins.toFile "nextcloud-adminpass" adminCreds.adminpass;
|
||||
adminpassFile =
|
||||
builtins.toFile "nextcloud-adminpass" adminCreds.adminpass;
|
||||
};
|
||||
autoUpdateApps = {
|
||||
enable = true;
|
||||
startAt = "20:30";
|
||||
};
|
||||
};
|
||||
nextcloud-container = {
|
||||
v6,
|
||||
v4,
|
||||
hostname,
|
||||
}: {
|
||||
nextcloud-container = { v6, v4, hostname, }: {
|
||||
bindMounts = {
|
||||
"${certPath}" = {
|
||||
hostPath = certPath;
|
||||
|
@ -72,17 +63,15 @@
|
|||
privateNetwork = true;
|
||||
hostBridge = "bridge";
|
||||
config = _: {
|
||||
imports = [
|
||||
../../roles
|
||||
];
|
||||
nixpkgs = {inherit pkgs;};
|
||||
imports = [ ../../roles ];
|
||||
nixpkgs = { inherit pkgs; };
|
||||
|
||||
systemd.network.networks."10-wan" = {
|
||||
matchConfig.Name = "eth0";
|
||||
address = ["${v6}/112" "${v4}/24"];
|
||||
address = [ "${v6}/112" "${v4}/24" ];
|
||||
routes = [
|
||||
{routeConfig.Gateway = hosts.hera-intern;}
|
||||
{routeConfig.Gateway = hosts.hera-intern-v4;}
|
||||
{ routeConfig.Gateway = hosts.hera-intern; }
|
||||
{ routeConfig.Gateway = hosts.hera-intern-v4; }
|
||||
];
|
||||
};
|
||||
|
||||
|
@ -92,7 +81,7 @@
|
|||
|
||||
networking = {
|
||||
useHostResolvConf = false;
|
||||
firewall.allowedTCPPorts = [80 443 9100 9113];
|
||||
firewall.allowedTCPPorts = [ 80 443 9100 9113 ];
|
||||
};
|
||||
|
||||
systemd.services = nextcloudServices hostname;
|
||||
|
@ -104,7 +93,7 @@
|
|||
postgresql = {
|
||||
enable = true;
|
||||
package = pkgs.postgresql_14;
|
||||
ensureDatabases = ["nextcloud"];
|
||||
ensureDatabases = [ "nextcloud" ];
|
||||
};
|
||||
};
|
||||
system.stateVersion = "21.05";
|
||||
|
@ -116,7 +105,7 @@ in {
|
|||
services = {
|
||||
redis.servers."".enable = true;
|
||||
nextcloud = nextcloudConf mainHostName;
|
||||
postgresql.ensureDatabases = ["nextcloud"];
|
||||
postgresql.ensureDatabases = [ "nextcloud" ];
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts."cloud.maralorn.de" = {
|
||||
|
@ -172,5 +161,5 @@ in {
|
|||
v4 = hosts.chor-cloud-intern-v4;
|
||||
};
|
||||
};
|
||||
users.users.nextcloud.extraGroups = ["nginx"];
|
||||
users.users.nextcloud.extraGroups = [ "nginx" ];
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
flake-inputs: {
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (import ../../../common/common.nix {inherit pkgs;}) syncthing;
|
||||
backupJobs = pkgs.privateValue {} "borgbackup";
|
||||
backupJobNames = map (name: "borgbackup-job-${name}") (lib.attrNames backupJobs);
|
||||
flake-inputs:
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
inherit (import ../../../common/common.nix { inherit pkgs; }) syncthing;
|
||||
backupJobs = pkgs.privateValue { } "borgbackup";
|
||||
backupJobNames =
|
||||
map (name: "borgbackup-job-${name}") (lib.attrNames backupJobs);
|
||||
in {
|
||||
imports = [
|
||||
(flake-inputs.secrets.lib.vpn "hera")
|
||||
|
@ -54,61 +52,52 @@ in {
|
|||
];
|
||||
})
|
||||
];
|
||||
m-0.monitoring = [
|
||||
{
|
||||
name = "hera";
|
||||
host = "hera-intern:9100";
|
||||
}
|
||||
];
|
||||
m-0.monitoring = [{
|
||||
name = "hera";
|
||||
host = "hera-intern:9100";
|
||||
}];
|
||||
|
||||
systemd.services =
|
||||
{
|
||||
pg_backup = {
|
||||
script =
|
||||
lib.concatMapStringsSep "\n"
|
||||
(name: "${config.services.postgresql.package}/bin/pg_dump ${name} > /var/lib/db-backup-dumps/${name}")
|
||||
config.services.postgresql.ensureDatabases;
|
||||
serviceConfig = {
|
||||
User = "postgres";
|
||||
Type = "oneshot";
|
||||
};
|
||||
systemd.services = {
|
||||
pg_backup = {
|
||||
script = lib.concatMapStringsSep "\n" (name:
|
||||
"${config.services.postgresql.package}/bin/pg_dump ${name} > /var/lib/db-backup-dumps/${name}")
|
||||
config.services.postgresql.ensureDatabases;
|
||||
serviceConfig = {
|
||||
User = "postgres";
|
||||
Type = "oneshot";
|
||||
};
|
||||
bump-config = {
|
||||
script = ''
|
||||
${pkgs.laminar}/bin/laminarc queue bump-config
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
startAt = "Sat 04:00";
|
||||
};
|
||||
night-routines = {
|
||||
script = let
|
||||
start = "${pkgs.systemd}/bin/systemctl start";
|
||||
container = "${pkgs.nixos-container}/bin/nixos-container run";
|
||||
# ${start} mysql-backup -- only needed for firefox-sync
|
||||
in ''
|
||||
set -x
|
||||
set +e
|
||||
${start} pg_backup
|
||||
${container} chor-cloud -- ${start} nextcloud-pg-backup
|
||||
${lib.concatMapStringsSep "\n" (name: "${start} ${name}") backupJobNames}
|
||||
${pkgs.coreutils}/bin/rm -rf /var/lib/db-backup-dumps/*
|
||||
${start} synapse-cleanup
|
||||
${start} nix-gc
|
||||
${start} nix-optimise
|
||||
'';
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
};
|
||||
startAt = "03:00";
|
||||
};
|
||||
}
|
||||
// lib.listToAttrs (map (name: {
|
||||
inherit name;
|
||||
value = {serviceConfig.Type = "oneshot";};
|
||||
})
|
||||
backupJobNames);
|
||||
};
|
||||
bump-config = {
|
||||
script = ''
|
||||
${pkgs.laminar}/bin/laminarc queue bump-config
|
||||
'';
|
||||
serviceConfig = { Type = "oneshot"; };
|
||||
startAt = "Sat 04:00";
|
||||
};
|
||||
night-routines = {
|
||||
script = let
|
||||
start = "${pkgs.systemd}/bin/systemctl start";
|
||||
container = "${pkgs.nixos-container}/bin/nixos-container run";
|
||||
# ${start} mysql-backup -- only needed for firefox-sync
|
||||
in ''
|
||||
set -x
|
||||
set +e
|
||||
${start} pg_backup
|
||||
${container} chor-cloud -- ${start} nextcloud-pg-backup
|
||||
${lib.concatMapStringsSep "\n" (name: "${start} ${name}")
|
||||
backupJobNames}
|
||||
${pkgs.coreutils}/bin/rm -rf /var/lib/db-backup-dumps/*
|
||||
${start} synapse-cleanup
|
||||
${start} nix-gc
|
||||
${start} nix-optimise
|
||||
'';
|
||||
serviceConfig = { Type = "oneshot"; };
|
||||
startAt = "03:00";
|
||||
};
|
||||
} // lib.listToAttrs (map (name: {
|
||||
inherit name;
|
||||
value = { serviceConfig.Type = "oneshot"; };
|
||||
}) backupJobNames);
|
||||
services = {
|
||||
postgresql = {
|
||||
enable = true;
|
||||
|
@ -119,24 +108,22 @@ in {
|
|||
enable = true;
|
||||
fqdn = "${config.m-0.virtualHosts.taskserver}";
|
||||
listenHost = "::";
|
||||
organisations."maralorn.de".users = ["maralorn"];
|
||||
organisations."maralorn.de".users = [ "maralorn" ];
|
||||
};
|
||||
syncthing =
|
||||
{
|
||||
enable = true;
|
||||
group = "nginx";
|
||||
user = "maralorn";
|
||||
openDefaultPorts = true;
|
||||
cert = config.age.secrets."syncthing/hera/cert.pem".path;
|
||||
key = config.age.secrets."syncthing/hera/key.pem".path;
|
||||
}
|
||||
// syncthing.declarativeWith ["apollo" "zeus" "pegasus"] "/media";
|
||||
syncthing = {
|
||||
enable = true;
|
||||
group = "nginx";
|
||||
user = "maralorn";
|
||||
openDefaultPorts = true;
|
||||
cert = config.age.secrets."syncthing/hera/cert.pem".path;
|
||||
key = config.age.secrets."syncthing/hera/key.pem".path;
|
||||
} // syncthing.declarativeWith [ "apollo" "zeus" "pegasus" ] "/media";
|
||||
};
|
||||
systemd.tmpfiles.rules = ["Z /media 0770 maralorn nginx - -"];
|
||||
systemd.tmpfiles.rules = [ "Z /media 0770 maralorn nginx - -" ];
|
||||
nix.sshServe = {
|
||||
protocol = "ssh-ng";
|
||||
enable = true;
|
||||
keys = pkgs.privateValue [] "root-ssh-keys";
|
||||
keys = pkgs.privateValue [ ] "root-ssh-keys";
|
||||
};
|
||||
|
||||
users.users = {
|
||||
|
@ -144,12 +131,14 @@ in {
|
|||
description = "choreutes";
|
||||
isNormalUser = true;
|
||||
uid = 1001;
|
||||
extraGroups = ["wheel" "systemd-journal"];
|
||||
extraGroups = [ "wheel" "systemd-journal" ];
|
||||
passwordFile = config.age.secrets.pam-login-password-choreutes.path;
|
||||
};
|
||||
ved-backup = {
|
||||
isNormalUser = true;
|
||||
openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSldCn4LJcIos8PVI7PJZSM5aQ8FoDPUzMTwSHm6NUl root@bach"];
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDSldCn4LJcIos8PVI7PJZSM5aQ8FoDPUzMTwSHm6NUl root@bach"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -1,20 +1,13 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/profiles/qemu-guest.nix")
|
||||
];
|
||||
{ config, lib, pkgs, modulesPath, ... }: {
|
||||
imports = [ (modulesPath + "/profiles/qemu-guest.nix") ];
|
||||
|
||||
boot.initrd.availableKernelModules = ["ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk"];
|
||||
boot.kernelModules = [];
|
||||
boot.extraModulePackages = [];
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk" ];
|
||||
boot.kernelModules = [ ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "/dev/disk/by-uuid/8e92387a-6785-4b3c-bcdb-a4a423675173";
|
||||
|
@ -26,7 +19,8 @@
|
|||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices = [{device = "/dev/disk/by-uuid/1e651bde-94b5-4fe2-9e6a-7af916d80057";}];
|
||||
swapDevices =
|
||||
[{ device = "/dev/disk/by-uuid/1e651bde-94b5-4fe2-9e6a-7af916d80057"; }];
|
||||
|
||||
nix.settings.max-jobs = lib.mkDefault 4;
|
||||
|
||||
|
|
|
@ -1,21 +1,16 @@
|
|||
flake-inputs: {
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
flake-inputs:
|
||||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
certPath = "/var/lib/acme/hera.m-0.eu";
|
||||
nonMailboxDomains = ["lists.maralorn.de"];
|
||||
nonMailboxDomains = [ "lists.maralorn.de" ];
|
||||
inherit (config.m-0) hosts virtualHosts;
|
||||
rspamd-address = "[::1]:11334";
|
||||
in {
|
||||
imports = [flake-inputs.nixos-mailserver.nixosModules.default];
|
||||
m-0.monitoring = [
|
||||
{
|
||||
name = "postfix on hera";
|
||||
host = "hera-intern:9154";
|
||||
}
|
||||
];
|
||||
imports = [ flake-inputs.nixos-mailserver.nixosModules.default ];
|
||||
m-0.monitoring = [{
|
||||
name = "postfix on hera";
|
||||
host = "hera-intern:9154";
|
||||
}];
|
||||
|
||||
services = {
|
||||
nginx.virtualHosts.${virtualHosts.rspamd}.locations."/" = {
|
||||
|
@ -33,18 +28,16 @@ in {
|
|||
rspamd = {
|
||||
workers = {
|
||||
controller = {
|
||||
bindSockets = [rspamd-address];
|
||||
bindSockets = [ rspamd-address ];
|
||||
extraConfig = ''
|
||||
secure_ip = "::1/128 127.0.0.1/32";
|
||||
'';
|
||||
};
|
||||
normal = {};
|
||||
normal = { };
|
||||
};
|
||||
locals = {
|
||||
"multimap.conf".text = let
|
||||
allow-ip =
|
||||
builtins.toFile "allow-ip.map" ''
|
||||
'';
|
||||
allow-ip = builtins.toFile "allow-ip.map" "";
|
||||
allow-host = builtins.toFile "allow-host.map" ''
|
||||
ccc.de
|
||||
discourse.cloud
|
||||
|
@ -73,12 +66,21 @@ in {
|
|||
};
|
||||
};
|
||||
postfix = {
|
||||
networks = ["[::1]/128" "127.0.0.1/32" "[${config.m-0.prefix}::]/64" "10.0.0.0/24"];
|
||||
networks = [
|
||||
"[::1]/128"
|
||||
"127.0.0.1/32"
|
||||
"[${config.m-0.prefix}::]/64"
|
||||
"10.0.0.0/24"
|
||||
];
|
||||
transport = "email2matrix.maralorn.de smtp:[::1]:2525";
|
||||
config = {
|
||||
# Allow TLSv1 because we need to be able to receive mail from legacy servers.
|
||||
smtpd_tls_protocols = lib.mkForce "TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, !SSLv2, !SSLv3";
|
||||
virtual_mailbox_domains = lib.mkForce (builtins.toFile "vhosts" (lib.concatStringsSep "\n" (builtins.filter (x: !builtins.elem x nonMailboxDomains) config.mailserver.domains)));
|
||||
smtpd_tls_protocols =
|
||||
lib.mkForce "TLSv1.3, TLSv1.2, TLSv1.1, TLSv1, !SSLv2, !SSLv3";
|
||||
virtual_mailbox_domains = lib.mkForce (builtins.toFile "vhosts"
|
||||
(lib.concatStringsSep "\n"
|
||||
(builtins.filter (x: !builtins.elem x nonMailboxDomains)
|
||||
config.mailserver.domains)));
|
||||
smtp_bind_address = hosts.hera-v4;
|
||||
smtp_bind_address6 = hosts.hera;
|
||||
};
|
||||
|
@ -93,9 +95,16 @@ in {
|
|||
enableManageSieve = true;
|
||||
fqdn = "hera.m-0.eu";
|
||||
rewriteMessageId = true;
|
||||
domains = ["m-0.eu" "maralorn.de" "choreutes.de" "mathechor.de" "lists.maralorn.de" "malte-und-clai.re"];
|
||||
forwards = pkgs.privateValue {} "mail/forwards";
|
||||
loginAccounts = pkgs.privateValue {} "mail/users";
|
||||
domains = [
|
||||
"m-0.eu"
|
||||
"maralorn.de"
|
||||
"choreutes.de"
|
||||
"mathechor.de"
|
||||
"lists.maralorn.de"
|
||||
"malte-und-clai.re"
|
||||
];
|
||||
forwards = pkgs.privateValue { } "mail/forwards";
|
||||
loginAccounts = pkgs.privateValue { } "mail/users";
|
||||
hierarchySeparator = "/";
|
||||
certificateScheme = 1;
|
||||
certificateFile = "${certPath}/fullchain.pem";
|
||||
|
|
|
@ -1,8 +1,5 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, ... }:
|
||||
let
|
||||
#wireguard = import ../../../common/wireguard.nix;
|
||||
inherit (config.m-0) hosts;
|
||||
in {
|
||||
|
@ -10,13 +7,10 @@ in {
|
|||
m-0.tailscale-routes = "fd42:ccc:da:64::/64,172.20.64.0/24";
|
||||
systemd.network.networks."10-wan" = {
|
||||
matchConfig.Name = "ens18";
|
||||
address = [
|
||||
"213.136.94.190/24"
|
||||
"${hosts.hera}/128"
|
||||
];
|
||||
address = [ "213.136.94.190/24" "${hosts.hera}/128" ];
|
||||
routes = [
|
||||
{routeConfig.Gateway = "213.136.94.1";}
|
||||
{routeConfig.Gateway = "fe80::1";}
|
||||
{ routeConfig.Gateway = "213.136.94.1"; }
|
||||
{ routeConfig.Gateway = "fe80::1"; }
|
||||
];
|
||||
};
|
||||
networking = {
|
||||
|
@ -54,24 +48,20 @@ in {
|
|||
hostName = "hera";
|
||||
domain = "m-0.eu";
|
||||
interfaces.ens18.proxyARP = true;
|
||||
bridges.bridge.interfaces = [];
|
||||
bridges.bridge.interfaces = [ ];
|
||||
interfaces.bridge = {
|
||||
proxyARP = true;
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = hosts.hera-intern;
|
||||
prefixLength = 112;
|
||||
}
|
||||
];
|
||||
ipv4.addresses = [
|
||||
{
|
||||
address = "10.0.0.1";
|
||||
prefixLength = 24;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [{
|
||||
address = hosts.hera-intern;
|
||||
prefixLength = 112;
|
||||
}];
|
||||
ipv4.addresses = [{
|
||||
address = "10.0.0.1";
|
||||
prefixLength = 24;
|
||||
}];
|
||||
};
|
||||
nameservers = ["213.136.95.10" "2a02:c207::1:53" "2a02:c207::2:53"];
|
||||
firewall.allowedTCPPorts = [8666];
|
||||
nameservers = [ "213.136.95.10" "2a02:c207::1:53" "2a02:c207::2:53" ];
|
||||
firewall.allowedTCPPorts = [ 8666 ];
|
||||
};
|
||||
|
||||
services.ndppd = {
|
||||
|
|
|
@ -1,39 +1,30 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
locations."/".extraConfig = "return 301 https://blog.maralorn.de$request_uri;";
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
locations."/".extraConfig =
|
||||
"return 301 https://blog.maralorn.de$request_uri;";
|
||||
in {
|
||||
networking.firewall.allowedTCPPorts = [80 443];
|
||||
m-0.monitoring = [
|
||||
{
|
||||
name = "hera-nginx";
|
||||
host = "hera-intern:9113";
|
||||
}
|
||||
];
|
||||
security.acme.certs = {
|
||||
"hera.m-0.eu".keyType = "rsa4096";
|
||||
};
|
||||
networking.firewall.allowedTCPPorts = [ 80 443 ];
|
||||
m-0.monitoring = [{
|
||||
name = "hera-nginx";
|
||||
host = "hera-intern:9113";
|
||||
}];
|
||||
security.acme.certs = { "hera.m-0.eu".keyType = "rsa4096"; };
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
virtualHosts =
|
||||
{
|
||||
"hera.m-0.eu" = {
|
||||
default = true;
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
inherit locations;
|
||||
};
|
||||
"maralorn.de" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
inherit locations;
|
||||
};
|
||||
}
|
||||
// pkgs.privateValue {} "extra-sites";
|
||||
virtualHosts = {
|
||||
"hera.m-0.eu" = {
|
||||
default = true;
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
inherit locations;
|
||||
};
|
||||
"maralorn.de" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
inherit locations;
|
||||
};
|
||||
} // pkgs.privateValue { } "extra-sites";
|
||||
};
|
||||
};
|
||||
systemd.services.nginx.serviceConfig.Restart = "always";
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
flake-inputs: {
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (import ../../../common/common.nix {inherit pkgs;}) syncthing;
|
||||
flake-inputs:
|
||||
{ config, pkgs, lib, ... }:
|
||||
let inherit (import ../../../common/common.nix { inherit pkgs; }) syncthing;
|
||||
in {
|
||||
imports = [
|
||||
(flake-inputs.secrets.lib.vpn "zeus")
|
||||
|
@ -17,20 +13,20 @@ in {
|
|||
../../roles/standalone
|
||||
];
|
||||
|
||||
age.identityPaths = ["/disk/persist/etc/ssh/ssh_host_ed25519_key"];
|
||||
age.identityPaths = [ "/disk/persist/etc/ssh/ssh_host_ed25519_key" ];
|
||||
|
||||
nix.distributedBuilds = false;
|
||||
|
||||
fileSystems = let
|
||||
btrfsOptions = {options = ["compress=zstd" "autodefrag" "noatime"];};
|
||||
btrfsOptions = { options = [ "compress=zstd" "autodefrag" "noatime" ]; };
|
||||
in {
|
||||
"/disk" = {neededForBoot = true;} // btrfsOptions;
|
||||
"/disk" = { neededForBoot = true; } // btrfsOptions;
|
||||
"/boot" = btrfsOptions;
|
||||
"/nix" = btrfsOptions;
|
||||
"/home/maralorn/.config/pulse" = {
|
||||
mountPoint = "/home/maralorn/.config/pulse";
|
||||
device = "/disk/persist/maralorn/.config/pulse";
|
||||
options = ["bind"];
|
||||
options = [ "bind" ];
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -40,7 +36,7 @@ in {
|
|||
};
|
||||
|
||||
systemd.services."activate-home-manager" = {
|
||||
path = [pkgs.nix pkgs.dbus];
|
||||
path = [ pkgs.nix pkgs.dbus ];
|
||||
script = ''
|
||||
if [[ -e /home/maralorn/.mode ]]; then
|
||||
MODE="$(cat /home/maralorn/.mode)"
|
||||
|
@ -53,9 +49,9 @@ in {
|
|||
Type = "oneshot";
|
||||
User = "maralorn";
|
||||
};
|
||||
wantedBy = ["multi-user.target"];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
# Try to avoid race conditions, when the user get’s logged in before activation was completed.
|
||||
before = ["display-manager.service"];
|
||||
before = [ "display-manager.service" ];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
|
@ -76,27 +72,23 @@ in {
|
|||
"/var/lib/tailscale"
|
||||
"/root/.ssh"
|
||||
];
|
||||
users.maralorn.directories = [
|
||||
".cache/rbw"
|
||||
".factorio"
|
||||
];
|
||||
users.maralorn.directories = [ ".cache/rbw" ".factorio" ];
|
||||
};
|
||||
|
||||
boot = {
|
||||
loader = {
|
||||
efi = {
|
||||
efiSysMountPoint = "/boot/efi";
|
||||
};
|
||||
efi = { efiSysMountPoint = "/boot/efi"; };
|
||||
grub = {
|
||||
# Enabled by default
|
||||
device = "nodev"; # Don‘t write masterboot under efi
|
||||
efiInstallAsRemovable = true; # Make loader discoverable by filename on efidisk without needing to write efivars to system
|
||||
efiInstallAsRemovable =
|
||||
true; # Make loader discoverable by filename on efidisk without needing to write efivars to system
|
||||
efiSupport = true;
|
||||
enableCryptodisk = true;
|
||||
backgroundColor = "#000000";
|
||||
};
|
||||
};
|
||||
kernelParams = ["amdgpu.cik_support=1"];
|
||||
kernelParams = [ "amdgpu.cik_support=1" ];
|
||||
initrd = {
|
||||
luks.devices."crypted-nixos" = {
|
||||
# device defined in hardware-configuration.nix
|
||||
|
@ -107,7 +99,8 @@ in {
|
|||
"amdgpu" # For earlier and better framebuffer
|
||||
];
|
||||
secrets = {
|
||||
"diskkey.bin" = "/disk/persist/diskkey.bin"; # Key can live on crypted disk, is copied to initrd on install
|
||||
"diskkey.bin" =
|
||||
"/disk/persist/diskkey.bin"; # Key can live on crypted disk, is copied to initrd on install
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -118,12 +111,10 @@ in {
|
|||
networkmanager.enable = false;
|
||||
interfaces.enp34s0 = {
|
||||
useDHCP = true;
|
||||
ipv6.addresses = [
|
||||
{
|
||||
address = "fdc0:1::4";
|
||||
prefixLength = 64;
|
||||
}
|
||||
];
|
||||
ipv6.addresses = [{
|
||||
address = "fdc0:1::4";
|
||||
prefixLength = 64;
|
||||
}];
|
||||
};
|
||||
firewall.allowedTCPPorts = [
|
||||
6600 # mpd
|
||||
|
@ -167,17 +158,16 @@ in {
|
|||
# firewallFilter = "-i m0wire -p tcp -m tcp -m multiport --dports 9100,9558";
|
||||
# openFirewall = lib.mkForce false;
|
||||
#};
|
||||
syncthing =
|
||||
{
|
||||
enable = true;
|
||||
group = "users";
|
||||
user = "maralorn";
|
||||
openDefaultPorts = true;
|
||||
configDir = "/disk/persist/syncthing";
|
||||
cert = config.age.secrets."syncthing/zeus/cert.pem".path;
|
||||
key = config.age.secrets."syncthing/zeus/key.pem".path;
|
||||
}
|
||||
// syncthing.declarativeWith ["hera" "apollo" "pegasus"] "/disk/persist/maralorn/media";
|
||||
syncthing = {
|
||||
enable = true;
|
||||
group = "users";
|
||||
user = "maralorn";
|
||||
openDefaultPorts = true;
|
||||
configDir = "/disk/persist/syncthing";
|
||||
cert = config.age.secrets."syncthing/zeus/cert.pem".path;
|
||||
key = config.age.secrets."syncthing/zeus/key.pem".path;
|
||||
} // syncthing.declarativeWith [ "hera" "apollo" "pegasus" ]
|
||||
"/disk/persist/maralorn/media";
|
||||
#minecraft-server = {
|
||||
# enable = true;
|
||||
# openFirewall = true;
|
||||
|
@ -194,7 +184,7 @@ in {
|
|||
support32Bit = true;
|
||||
tcp = {
|
||||
enable = true;
|
||||
anonymousClients.allowedIpRanges = ["127.0.0.1" "::1"];
|
||||
anonymousClients.allowedIpRanges = [ "127.0.0.1" "::1" ];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
modulesPath,
|
||||
...
|
||||
}: {
|
||||
imports = [
|
||||
(modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
{ config, lib, modulesPath, ... }: {
|
||||
imports = [ (modulesPath + "/installer/scan/not-detected.nix") ];
|
||||
|
||||
boot.initrd.availableKernelModules = ["nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod"];
|
||||
boot.initrd.kernelModules = [];
|
||||
boot.kernelModules = ["kvm-amd"];
|
||||
boot.extraModulePackages = [];
|
||||
boot.initrd.availableKernelModules =
|
||||
[ "nvme" "xhci_pci" "ahci" "usbhid" "usb_storage" "sd_mod" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-amd" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" = {
|
||||
device = "tmpfs";
|
||||
|
@ -26,18 +20,19 @@
|
|||
fsType = "btrfs";
|
||||
};
|
||||
|
||||
boot.initrd.luks.devices."crypted-nixos".device = "/dev/disk/by-uuid/2518e0e0-c263-40bc-b378-419832dc62cc";
|
||||
boot.initrd.luks.devices."crypted-nixos".device =
|
||||
"/dev/disk/by-uuid/2518e0e0-c263-40bc-b378-419832dc62cc";
|
||||
|
||||
fileSystems."/nix" = {
|
||||
device = "/dev/disk/by-uuid/47552982-2abf-45c6-8c5c-d33091ce3f5a";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=nix"];
|
||||
options = [ "subvol=nix" ];
|
||||
};
|
||||
|
||||
fileSystems."/boot" = {
|
||||
device = "/dev/disk/by-uuid/47552982-2abf-45c6-8c5c-d33091ce3f5a";
|
||||
fsType = "btrfs";
|
||||
options = ["subvol=boot"];
|
||||
options = [ "subvol=boot" ];
|
||||
};
|
||||
|
||||
fileSystems."/boot/efi" = {
|
||||
|
@ -45,7 +40,7 @@
|
|||
fsType = "vfat";
|
||||
};
|
||||
|
||||
swapDevices = [];
|
||||
swapDevices = [ ];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
|
@ -58,6 +53,7 @@
|
|||
# networking.interfaces.wlo1.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.amd.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
hardware.cpu.amd.updateMicrocode =
|
||||
lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
nix.settings.max-jobs = lib.mkDefault 12;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,10 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
inherit (config.m-0) virtualHosts;
|
||||
{ config, pkgs, lib, ... }:
|
||||
let inherit (config.m-0) virtualHosts;
|
||||
in {
|
||||
environment.persistence."/disk/persist".directories = ["/var/www/5etools"];
|
||||
environment.persistence."/disk/persist".directories = [ "/var/www/5etools" ];
|
||||
|
||||
services.nginx.virtualHosts.${virtualHosts."5e"}. locations."/" .root = "/var/www/5etools";
|
||||
services.nginx.virtualHosts.${virtualHosts."5e"}.locations."/".root =
|
||||
"/var/www/5etools";
|
||||
|
||||
systemd.services.update-5etools = {
|
||||
script = ''
|
||||
|
@ -16,7 +12,9 @@ in {
|
|||
if [[ -d ".git" ]]; then
|
||||
${lib.getExe pkgs.git} pull
|
||||
else
|
||||
${lib.getExe pkgs.git} clone https://github.com/5etools-mirror-1/5etools-mirror-1.github.io.git .
|
||||
${
|
||||
lib.getExe pkgs.git
|
||||
} clone https://github.com/5etools-mirror-1/5etools-mirror-1.github.io.git .
|
||||
fi
|
||||
'';
|
||||
startAt = "daily";
|
||||
|
|
|
@ -1,11 +1,8 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
openssh.authorizedKeys.keys = pkgs.privateValue [] "ssh-keys";
|
||||
passwordFile = lib.mkIf (config.networking.hostName != "chor-cloud") config.age.secrets.pam-login-password.path;
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
openssh.authorizedKeys.keys = pkgs.privateValue [ ] "ssh-keys";
|
||||
passwordFile = lib.mkIf (config.networking.hostName != "chor-cloud")
|
||||
config.age.secrets.pam-login-password.path;
|
||||
in {
|
||||
users.users = {
|
||||
maralorn = {
|
||||
|
@ -24,6 +21,6 @@ in {
|
|||
];
|
||||
inherit openssh passwordFile;
|
||||
};
|
||||
root = {inherit openssh passwordFile;};
|
||||
root = { inherit openssh passwordFile; };
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{ config, pkgs, lib, ... }: {
|
||||
services = {
|
||||
nginx = {
|
||||
enable = true;
|
||||
|
@ -20,9 +15,7 @@
|
|||
add_header Cache-Control "public";
|
||||
'';
|
||||
};
|
||||
"/" = {
|
||||
tryFiles = "$uri $uri.html $uri/index.html =404";
|
||||
};
|
||||
"/" = { tryFiles = "$uri $uri.html $uri/index.html =404"; };
|
||||
};
|
||||
extraConfig = ''
|
||||
error_page 404 /not-found.html;
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
secretsFile = "/var/lib/luks-secret/key";
|
||||
{ lib, config, ... }:
|
||||
let secretsFile = "/var/lib/luks-secret/key";
|
||||
in {
|
||||
boot = {
|
||||
initrd = {
|
||||
|
|
|
@ -1,20 +1,14 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
fqdn = "${config.networking.hostName}.${config.networking.domain}";
|
||||
key_dir = config.security.acme.certs."${fqdn}".directory;
|
||||
in {
|
||||
users.users.turnserver.extraGroups = ["nginx"]; # For read access to certs;
|
||||
users.users.turnserver.extraGroups = [ "nginx" ]; # For read access to certs;
|
||||
networking.firewall = let
|
||||
range = [
|
||||
{
|
||||
from = config.services.coturn.min-port;
|
||||
to = config.services.coturn.max-port;
|
||||
}
|
||||
];
|
||||
range = [{
|
||||
from = config.services.coturn.min-port;
|
||||
to = config.services.coturn.max-port;
|
||||
}];
|
||||
ports = [
|
||||
config.services.coturn.listening-port
|
||||
config.services.coturn.alt-listening-port
|
||||
|
@ -40,12 +34,10 @@ in {
|
|||
max-port = 52100;
|
||||
pkey = "${key_dir}/key.pem";
|
||||
cert = "${key_dir}/fullchain.pem";
|
||||
static-auth-secret =
|
||||
(pkgs.privateValue {turn_shared_secret = "";}
|
||||
"matrix/server-secrets")
|
||||
.turn_shared_secret;
|
||||
static-auth-secret = (pkgs.privateValue { turn_shared_secret = ""; }
|
||||
"matrix/server-secrets").turn_shared_secret;
|
||||
realm = fqdn;
|
||||
listening-ips = [config.m-0.hosts.hera config.m-0.hosts.hera-v4];
|
||||
listening-ips = [ config.m-0.hosts.hera config.m-0.hosts.hera-v4 ];
|
||||
extraConfig = ''
|
||||
fingerprint
|
||||
|
||||
|
|
|
@ -1,25 +1,21 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, config, lib, ... }:
|
||||
let
|
||||
inherit (config.m-0) hosts;
|
||||
inherit (config.networking) hostName;
|
||||
in {
|
||||
imports = [
|
||||
../../common
|
||||
];
|
||||
imports = [ ../../common ];
|
||||
|
||||
i18n = {
|
||||
defaultLocale = "en_DK.UTF-8";
|
||||
supportedLocales = ["en_DK.UTF-8/UTF-8" "de_DE.UTF-8/UTF-8" "en_US.UTF-8/UTF-8"];
|
||||
supportedLocales =
|
||||
[ "en_DK.UTF-8/UTF-8" "de_DE.UTF-8/UTF-8" "en_US.UTF-8/UTF-8" ];
|
||||
};
|
||||
|
||||
time.timeZone = "Europe/Berlin";
|
||||
|
||||
networking = {
|
||||
resolvconf.dnsExtensionMechanism = false; # this breaks dnssec but is necessary for certain bad-behaved hotspots
|
||||
resolvconf.dnsExtensionMechanism =
|
||||
false; # this breaks dnssec but is necessary for certain bad-behaved hotspots
|
||||
firewall = {
|
||||
enable = true; # It’s the default, but better make sure.
|
||||
allowPing = true;
|
||||
|
@ -27,29 +23,27 @@ in {
|
|||
nftables.enable = true; # Uses firewall variables since 23.05
|
||||
useNetworkd = true;
|
||||
useDHCP = false; # enabled per interface
|
||||
hosts =
|
||||
lib.zipAttrs
|
||||
(
|
||||
lib.mapAttrsToList
|
||||
(host: ip:
|
||||
if builtins.typeOf ip == "set"
|
||||
then {}
|
||||
else {"${ip}" = "${host} ${host}.m-0.eu";})
|
||||
config.m-0.hosts
|
||||
++ lib.mapAttrsToList
|
||||
(host: ips: let
|
||||
hosts = lib.zipAttrs (lib.mapAttrsToList (host: ip:
|
||||
if builtins.typeOf ip == "set" then
|
||||
{ }
|
||||
else {
|
||||
"${ip}" = "${host} ${host}.m-0.eu";
|
||||
}) config.m-0.hosts ++ lib.mapAttrsToList (host: ips:
|
||||
let
|
||||
mkHost = name: "${name} ${name}.maralorn.de";
|
||||
name = "${host} ${host}.vpn.m-0.eu ${lib.concatMapStringsSep " " mkHost config.m-0.hosts.aliases.${host} or []}";
|
||||
name = "${host} ${host}.vpn.m-0.eu ${
|
||||
lib.concatMapStringsSep " " mkHost
|
||||
config.m-0.hosts.aliases.${host} or [ ]
|
||||
}";
|
||||
in {
|
||||
${ips.AAAA} = name;
|
||||
${ips.A} = name;
|
||||
})
|
||||
config.m-0.hosts.tailscale
|
||||
);
|
||||
}) config.m-0.hosts.tailscale);
|
||||
};
|
||||
|
||||
m-0 = {
|
||||
virtualHosts = lib.genAttrs (hosts.aliases.${hostName} or []) (name: "${name}.maralorn.de");
|
||||
virtualHosts = lib.genAttrs (hosts.aliases.${hostName} or [ ])
|
||||
(name: "${name}.maralorn.de");
|
||||
};
|
||||
|
||||
nix = {
|
||||
|
@ -77,68 +71,17 @@ in {
|
|||
|
||||
environment = {
|
||||
systemPackages = builtins.attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
git
|
||||
gnumake
|
||||
mkpasswd
|
||||
file
|
||||
wget
|
||||
curl
|
||||
wireguard-tools
|
||||
gnupg
|
||||
bind
|
||||
liboping
|
||||
psmisc
|
||||
unzip
|
||||
rename
|
||||
whois
|
||||
lsof
|
||||
parted
|
||||
python3
|
||||
binutils
|
||||
ntfsprogs
|
||||
ventoy-bin
|
||||
htop
|
||||
helix
|
||||
btop
|
||||
tree
|
||||
pwgen
|
||||
borgbackup
|
||||
inotifyTools
|
||||
direnv
|
||||
socat
|
||||
nmap
|
||||
ncdu
|
||||
tcpdump
|
||||
tmux
|
||||
tig
|
||||
exa
|
||||
fzf
|
||||
fd
|
||||
sd
|
||||
bat
|
||||
ripgrep
|
||||
ranger
|
||||
pass
|
||||
sshuttle
|
||||
vnstat
|
||||
entr
|
||||
libargon2
|
||||
mblaze
|
||||
niv
|
||||
compsize
|
||||
mediainfo
|
||||
asciinema
|
||||
nix-output-monitor
|
||||
jq
|
||||
home-manager
|
||||
builders-configurator
|
||||
;
|
||||
inherit (pkgs)
|
||||
git gnumake mkpasswd file wget curl wireguard-tools gnupg bind liboping
|
||||
psmisc unzip rename whois lsof parted python3 binutils ntfsprogs
|
||||
ventoy-bin htop helix btop tree pwgen borgbackup inotifyTools direnv
|
||||
socat nmap ncdu tcpdump tmux tig exa fzf fd sd bat ripgrep ranger pass
|
||||
sshuttle vnstat entr libargon2 mblaze niv compsize mediainfo asciinema
|
||||
nix-output-monitor jq home-manager builders-configurator;
|
||||
inherit (pkgs.python3Packages) qrcode;
|
||||
};
|
||||
variables =
|
||||
lib.genAttrs ["CURL_CA_BUNDLE" "GIT_SSL_CAINFO" "SSL_CERT_FILE"]
|
||||
lib.genAttrs [ "CURL_CA_BUNDLE" "GIT_SSL_CAINFO" "SSL_CERT_FILE" ]
|
||||
(_: "${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt");
|
||||
};
|
||||
|
||||
|
@ -159,12 +102,10 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
in
|
||||
{
|
||||
nix-gc.serviceConfig.Type = "oneshot";
|
||||
nix-optimise.serviceConfig.Type = "oneshot";
|
||||
}
|
||||
// builtins.listToAttrs (map makeConfig hosts);
|
||||
in {
|
||||
nix-gc.serviceConfig.Type = "oneshot";
|
||||
nix-optimise.serviceConfig.Type = "oneshot";
|
||||
} // builtins.listToAttrs (map makeConfig hosts);
|
||||
|
||||
oomd.enableRootSlice = true;
|
||||
};
|
||||
|
@ -175,24 +116,23 @@ in {
|
|||
prometheus.exporters = {
|
||||
node = {
|
||||
enable = true;
|
||||
enabledCollectors = ["systemd" "logind"];
|
||||
disabledCollectors = ["timex"];
|
||||
};
|
||||
nginx = {
|
||||
inherit (config.services.nginx) enable;
|
||||
enabledCollectors = [ "systemd" "logind" ];
|
||||
disabledCollectors = [ "timex" ];
|
||||
};
|
||||
nginx = { inherit (config.services.nginx) enable; };
|
||||
};
|
||||
nginx = {
|
||||
virtualHosts =
|
||||
lib.genAttrs
|
||||
(map (name: "${name}.maralorn.de") (builtins.filter (name: !(builtins.elem name hosts.publicAliases.${hostName} or []))
|
||||
(hosts.aliases.${hostName} or []))) (_: {
|
||||
extraConfig = ''
|
||||
satisfy any;
|
||||
${lib.concatMapStringsSep "\n" (ip_range: "allow ${ip_range};") config.m-0.headscaleIPs}
|
||||
deny all;
|
||||
'';
|
||||
});
|
||||
virtualHosts = lib.genAttrs (map (name: "${name}.maralorn.de")
|
||||
(builtins.filter
|
||||
(name: !(builtins.elem name hosts.publicAliases.${hostName} or [ ]))
|
||||
(hosts.aliases.${hostName} or [ ]))) (_: {
|
||||
extraConfig = ''
|
||||
satisfy any;
|
||||
${lib.concatMapStringsSep "\n" (ip_range: "allow ${ip_range};")
|
||||
config.m-0.headscaleIPs}
|
||||
deny all;
|
||||
'';
|
||||
});
|
||||
statusPage = true;
|
||||
recommendedOptimisation = true;
|
||||
recommendedGzipSettings = true;
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
{
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: {
|
||||
{ lib, pkgs, ... }: {
|
||||
programs = {
|
||||
adb.enable = true;
|
||||
seahorse.enable = lib.mkForce false;
|
||||
dconf.enable = true;
|
||||
};
|
||||
services = {
|
||||
udev.packages = [pkgs.chrysalis];
|
||||
udev.packages = [ pkgs.chrysalis ];
|
||||
pipewire.enable = lib.mkForce false;
|
||||
printing = {
|
||||
enable = true;
|
||||
|
@ -36,7 +32,7 @@
|
|||
core-utilities.enable = lib.mkForce false;
|
||||
};
|
||||
};
|
||||
environment.gnome.excludePackages = [pkgs.orca pkgs.gnome-tour];
|
||||
environment.gnome.excludePackages = [ pkgs.orca pkgs.gnome-tour ];
|
||||
sound.enable = true;
|
||||
hardware = {
|
||||
pulseaudio = {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{pkgs, ...}: let
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
default_mailbox = {
|
||||
MailboxName = "<missing>";
|
||||
MatrixRoomId = "<missing>";
|
||||
|
@ -9,8 +10,7 @@
|
|||
IgnoreBody = false;
|
||||
SkipMarkdown = false;
|
||||
};
|
||||
email2matrix-config =
|
||||
pkgs.writeText "email2matrix-config.json"
|
||||
email2matrix-config = pkgs.writeText "email2matrix-config.json"
|
||||
(builtins.toJSON {
|
||||
Smtp = {
|
||||
ListenInterface = "[::1]:2525";
|
||||
|
@ -19,29 +19,27 @@
|
|||
};
|
||||
Matrix = {
|
||||
Mappings = [
|
||||
(default_mailbox
|
||||
// {
|
||||
MailboxName = "notify";
|
||||
MatrixRoomId = "!kTKVQjRwxjaoMQmcve:maralorn.de";
|
||||
})
|
||||
(default_mailbox
|
||||
// {
|
||||
MailboxName = "subjects";
|
||||
MatrixRoomId = "!kTKVQjRwxjaoMQmcve:maralorn.de";
|
||||
IgnoreBody = true;
|
||||
})
|
||||
(default_mailbox
|
||||
// {
|
||||
MailboxName = "weather";
|
||||
MatrixRoomId = "!ELeFcSrHXgMqOmwnxg:maralorn.de";
|
||||
})
|
||||
(default_mailbox // {
|
||||
MailboxName = "notify";
|
||||
MatrixRoomId = "!kTKVQjRwxjaoMQmcve:maralorn.de";
|
||||
})
|
||||
(default_mailbox // {
|
||||
MailboxName = "subjects";
|
||||
MatrixRoomId = "!kTKVQjRwxjaoMQmcve:maralorn.de";
|
||||
IgnoreBody = true;
|
||||
})
|
||||
(default_mailbox // {
|
||||
MailboxName = "weather";
|
||||
MatrixRoomId = "!ELeFcSrHXgMqOmwnxg:maralorn.de";
|
||||
})
|
||||
];
|
||||
};
|
||||
Misc = {Debug = true;};
|
||||
Misc = { Debug = true; };
|
||||
});
|
||||
in {
|
||||
systemd.services.email2matrix = {
|
||||
script = "${pkgs.email2matrix}/bin/devture-email2matrix --config ${email2matrix-config}";
|
||||
wantedBy = ["multi-user.target"];
|
||||
script =
|
||||
"${pkgs.email2matrix}/bin/devture-email2matrix --config ${email2matrix-config}";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,4 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, lib, config, ... }: {
|
||||
services.mysql = {
|
||||
enable = true;
|
||||
package = pkgs.mariadb;
|
||||
|
@ -11,7 +6,7 @@
|
|||
|
||||
services.mysqlBackup = {
|
||||
enable = true;
|
||||
databases = ["firefox_syncserver"];
|
||||
databases = [ "firefox_syncserver" ];
|
||||
calendar = "";
|
||||
singleTransaction = true;
|
||||
};
|
||||
|
|
|
@ -1,66 +1,60 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: {
|
||||
{ config, pkgs, lib, ... }: {
|
||||
fonts = {
|
||||
fontconfig = {
|
||||
enable = true;
|
||||
cache32Bit = true;
|
||||
defaultFonts = let
|
||||
unicode-fallback = ["Noto Sans Symbols" "Noto Sans Symbols2"];
|
||||
in {
|
||||
monospace = ["Symbols Nerd Font Mono" "CozetteVector" "Noto Sans Mono"] ++ unicode-fallback;
|
||||
sansSerif = ["B612" "Noto Sans"] ++ unicode-fallback;
|
||||
serif = ["Libertinus Serif" "Noto Serif"] ++ unicode-fallback;
|
||||
};
|
||||
defaultFonts =
|
||||
let unicode-fallback = [ "Noto Sans Symbols" "Noto Sans Symbols2" ];
|
||||
in {
|
||||
monospace =
|
||||
[ "Symbols Nerd Font Mono" "CozetteVector" "Noto Sans Mono" ]
|
||||
++ unicode-fallback;
|
||||
sansSerif = [ "B612" "Noto Sans" ] ++ unicode-fallback;
|
||||
serif = [ "Libertinus Serif" "Noto Serif" ] ++ unicode-fallback;
|
||||
};
|
||||
};
|
||||
fonts = builtins.attrValues {
|
||||
inherit
|
||||
(pkgs)
|
||||
inherit (pkgs)
|
||||
libertinus
|
||||
# nice text font
|
||||
|
||||
|
||||
material-icons
|
||||
# icons in my app
|
||||
|
||||
|
||||
tamzen
|
||||
# 12px
|
||||
|
||||
|
||||
cozette
|
||||
# 13px
|
||||
|
||||
|
||||
# too wide: dina-font
|
||||
|
||||
|
||||
# can‘t find font in there: efont-unicode
|
||||
|
||||
|
||||
# too wide: envypn-font
|
||||
|
||||
|
||||
spleen
|
||||
# Great if you need 8 px font, also nice on 12px.
|
||||
|
||||
gohufont
|
||||
tewi-font
|
||||
|
||||
gohufont tewi-font
|
||||
# Too wide tracking: curie
|
||||
|
||||
|
||||
scientifica
|
||||
# Quite cool on: 11px
|
||||
|
||||
|
||||
# biwidth: too small
|
||||
|
||||
|
||||
# Too wide tracking: creep
|
||||
|
||||
|
||||
# For all my terminal needs.
|
||||
|
||||
|
||||
b612
|
||||
# sans font, very good for displays
|
||||
|
||||
|
||||
noto-fonts
|
||||
# for unicode fallback
|
||||
|
||||
nerdfonts
|
||||
;
|
||||
|
||||
nerdfonts;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -69,11 +63,7 @@
|
|||
environment.etc = let
|
||||
# fonts with src attributes
|
||||
font_sources = map (v: v.src) (lib.filter (v: v ? src) config.fonts.fonts);
|
||||
in
|
||||
builtins.listToAttrs (lib.imap0
|
||||
(n: source:
|
||||
lib.nameValuePair "src-cache/fonts/${toString n}" {
|
||||
inherit source;
|
||||
})
|
||||
font_sources);
|
||||
in builtins.listToAttrs (lib.imap0 (n: source:
|
||||
lib.nameValuePair "src-cache/fonts/${toString n}" { inherit source; })
|
||||
font_sources);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
{pkgs, ...}: let
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
name = "foundryvtt";
|
||||
stateDir = "/var/lib/${name}";
|
||||
dataDir = "${stateDir}/data";
|
||||
|
@ -13,11 +14,12 @@
|
|||
minifyStaticFiles = true;
|
||||
updateChannel = "release";
|
||||
};
|
||||
declarativeConfigFile = builtins.toFile "foundry-options.json" (builtins.toJSON config);
|
||||
declarativeConfigFile =
|
||||
builtins.toFile "foundry-options.json" (builtins.toJSON config);
|
||||
in {
|
||||
config = {
|
||||
systemd.services."${name}" = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Foundryvtt server";
|
||||
preStart = ''
|
||||
mkdir -p ${dataDir}
|
||||
|
@ -38,7 +40,8 @@ in {
|
|||
DynamicUser = true;
|
||||
Restart = "always";
|
||||
Environment = "HOME=${stateDir}";
|
||||
ExecStart = "${pkgs.nodejs}/bin/node ${stateDir}/app/resources/app/main.js --dataPath=\"${dataDir}\"";
|
||||
ExecStart = ''
|
||||
${pkgs.nodejs}/bin/node ${stateDir}/app/resources/app/main.js --dataPath="${dataDir}"'';
|
||||
};
|
||||
};
|
||||
services = {
|
||||
|
@ -60,10 +63,14 @@ in {
|
|||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
if ($query_string ~ "pw=([A-Za-z]*)") {
|
||||
add_header Set-Cookie "password=$1; path=/; Max-Age=${toString (365 * 24 * 60 * 60)}; Secure";
|
||||
add_header Set-Cookie "password=$1; path=/; Max-Age=${
|
||||
toString (365 * 24 * 60 * 60)
|
||||
}; Secure";
|
||||
return 303 /;
|
||||
}
|
||||
if ($http_cookie !~ "password=${pkgs.privateValue "" "foundry-pw"}") {
|
||||
if ($http_cookie !~ "password=${
|
||||
pkgs.privateValue "" "foundry-pw"
|
||||
}") {
|
||||
return 303 /logout;
|
||||
}
|
||||
'';
|
||||
|
|
|
@ -1,44 +1,36 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
gitoliteCfg = config.services.gitolite;
|
||||
post-update =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
name = "post-update";
|
||||
bins = [pkgs.git pkgs.laminar];
|
||||
imports = [
|
||||
"System.Directory (withCurrentDirectory)"
|
||||
];
|
||||
} ''
|
||||
checkout :: String -> IO FilePath
|
||||
checkout path = do
|
||||
(decodeUtf8 -> repoDir) <- mktemp "-d" |> captureTrim
|
||||
git "clone" path repoDir
|
||||
pure repoDir
|
||||
post-update = pkgs.writeHaskellScript {
|
||||
name = "post-update";
|
||||
bins = [ pkgs.git pkgs.laminar ];
|
||||
imports = [ "System.Directory (withCurrentDirectory)" ];
|
||||
} ''
|
||||
checkout :: String -> IO FilePath
|
||||
checkout path = do
|
||||
(decodeUtf8 -> repoDir) <- mktemp "-d" |> captureTrim
|
||||
git "clone" path repoDir
|
||||
pure repoDir
|
||||
|
||||
main = do
|
||||
jobMay <- lookupEnv "GL_OPTION_CI_JOB"
|
||||
whenJust jobMay $ \job -> do
|
||||
args <- toString . Text.intercalate " " . fmap toText <$> getArgs
|
||||
setEnv "LAMINAR_REASON" [i|Build triggered by push to branch #{args}|]
|
||||
jobName <- decodeUtf8 <$> (laminarc ["queue", job, [i|BRANCH=#{args}|]] |> captureTrim)
|
||||
say [i|Queued job #{jobName}.\nSee https://ci.maralorn.de/jobs/#{Text.replace ":" "/" jobName}|]
|
||||
mirrorMay <- lookupEnv "GL_OPTION_MIRROR"
|
||||
whenJust mirrorMay $ \mirror -> do
|
||||
say [i|Force pushing all branches to #{mirror}|]
|
||||
git "push" "--all" "-f" mirror
|
||||
deployMay <- lookupEnv "GL_OPTION_WEB_DEPLOY"
|
||||
whenJust deployMay $ \deploy -> do
|
||||
(maybe [] (\x -> ["-A", x]) -> target) <- lookupEnv "GL_OPTION_WEB_DEPLOY_NIX_TARGET"
|
||||
(decodeUtf8 -> path) <- pwd |> captureTrim
|
||||
say [i|Building default.nix #{show target} to /var/www/#{deploy}|]
|
||||
bracket (checkout path) (rm "-rf") $ \repoDir -> withCurrentDirectory repoDir $ nix_build "-o" ([i|/var/www/#{deploy}|] :: String) target
|
||||
say "Done"
|
||||
'';
|
||||
main = do
|
||||
jobMay <- lookupEnv "GL_OPTION_CI_JOB"
|
||||
whenJust jobMay $ \job -> do
|
||||
args <- toString . Text.intercalate " " . fmap toText <$> getArgs
|
||||
setEnv "LAMINAR_REASON" [i|Build triggered by push to branch #{args}|]
|
||||
jobName <- decodeUtf8 <$> (laminarc ["queue", job, [i|BRANCH=#{args}|]] |> captureTrim)
|
||||
say [i|Queued job #{jobName}.\nSee https://ci.maralorn.de/jobs/#{Text.replace ":" "/" jobName}|]
|
||||
mirrorMay <- lookupEnv "GL_OPTION_MIRROR"
|
||||
whenJust mirrorMay $ \mirror -> do
|
||||
say [i|Force pushing all branches to #{mirror}|]
|
||||
git "push" "--all" "-f" mirror
|
||||
deployMay <- lookupEnv "GL_OPTION_WEB_DEPLOY"
|
||||
whenJust deployMay $ \deploy -> do
|
||||
(maybe [] (\x -> ["-A", x]) -> target) <- lookupEnv "GL_OPTION_WEB_DEPLOY_NIX_TARGET"
|
||||
(decodeUtf8 -> path) <- pwd |> captureTrim
|
||||
say [i|Building default.nix #{show target} to /var/www/#{deploy}|]
|
||||
bracket (checkout path) (rm "-rf") $ \repoDir -> withCurrentDirectory repoDir $ nix_build "-o" ([i|/var/www/#{deploy}|] :: String) target
|
||||
say "Done"
|
||||
'';
|
||||
cgitrc = ''
|
||||
enable-git-config=1
|
||||
remove-suffix=1
|
||||
|
@ -93,12 +85,10 @@
|
|||
scan-path=/var/lib/gitolite/repositories
|
||||
'';
|
||||
in {
|
||||
systemd.tmpfiles.rules =
|
||||
lib.mkAfter
|
||||
[
|
||||
"z ${gitoliteCfg.dataDir}/.ssh/id_ed25519 0600 ${gitoliteCfg.user} ${gitoliteCfg.group} - -"
|
||||
"v /var/cache/cgit 0700 cgit ${gitoliteCfg.group} - -"
|
||||
];
|
||||
systemd.tmpfiles.rules = lib.mkAfter [
|
||||
"z ${gitoliteCfg.dataDir}/.ssh/id_ed25519 0600 ${gitoliteCfg.user} ${gitoliteCfg.group} - -"
|
||||
"v /var/cache/cgit 0700 cgit ${gitoliteCfg.group} - -"
|
||||
];
|
||||
users.users.cgit = {
|
||||
isSystemUser = true;
|
||||
inherit (gitoliteCfg) group;
|
||||
|
@ -122,8 +112,8 @@ in {
|
|||
gitolite = {
|
||||
enable = true;
|
||||
user = "git";
|
||||
adminPubkey = builtins.elemAt (pkgs.privateValue [""] "ssh-keys") 0;
|
||||
commonHooks = ["${post-update}/bin/post-update"];
|
||||
adminPubkey = builtins.elemAt (pkgs.privateValue [ "" ] "ssh-keys") 0;
|
||||
commonHooks = [ "${post-update}/bin/post-update" ];
|
||||
extraGitoliteRc = ''
|
||||
$RC{UMASK} = 0027;
|
||||
$RC{GIT_CONFIG_KEYS} = 'gitweb\..*';
|
||||
|
@ -141,9 +131,7 @@ in {
|
|||
enableACME = true;
|
||||
|
||||
locations = {
|
||||
"~* ^.+\.(css|png|ico)$" = {
|
||||
root = "${pkgs.cgit}/cgit";
|
||||
};
|
||||
"~* ^.+.(css|png|ico)$" = { root = "${pkgs.cgit}/cgit"; };
|
||||
|
||||
"/" = {
|
||||
extraConfig = ''
|
||||
|
|
|
@ -1,46 +1,39 @@
|
|||
{
|
||||
pkgs,
|
||||
config,
|
||||
...
|
||||
}: {
|
||||
{ pkgs, config, ... }: {
|
||||
#imports = [ modules/go-neb.nix ];
|
||||
|
||||
services.go-neb = {
|
||||
enable = true;
|
||||
baseUrl = "http://localhost";
|
||||
config = {
|
||||
clients = [
|
||||
{
|
||||
UserId = "@marabot:maralorn.de";
|
||||
AccessToken = pkgs.privateValue "" "matrix/marabot-token";
|
||||
HomeServerUrl = "https://matrix.maralorn.de";
|
||||
Sync = true;
|
||||
AutoJoinRooms = true;
|
||||
DisplayName = "marabot";
|
||||
}
|
||||
];
|
||||
realms = [];
|
||||
sessions = [];
|
||||
services = [
|
||||
{
|
||||
ID = "alertmanager_service";
|
||||
Type = "alertmanager";
|
||||
UserId = "@marabot:maralorn.de";
|
||||
Config = {
|
||||
webhook_url = "http://localhost:4050/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2UK";
|
||||
rooms = {
|
||||
"!negVsngnYOmXYCLKiO:maralorn.de" = {
|
||||
text_template = ''
|
||||
{{range .Alerts -}} [{{ .Status }}] {{index .Annotations "description"}} ({{index .Labels "alertname" }}){{ end -}}'';
|
||||
html_template = ''
|
||||
{{range .Alerts -}}{{ $severity := index .Labels "severity" }}{{ if eq .Status "firing" }}{{ if eq $severity "critical"}}<font color='red'><b>[FIRING - CRITICAL]</b></font>{{ else if eq $severity "warning"}}<font color='orange'><b>[FIRING - WARNING]</b></font>{{ else }}<font color='yellow'><b>[FIRING - {{ $severity }}]</b></font>{{ end }}{{ else }}<font color='green'><b>[RESOLVED]</b></font>{{ end }} {{ index .Annotations "description"}} {{ $url := index .Labels "url" }}{{ if eq $url "" }}{{ else }}<a href="{{ $url }}">more infos</a> {{ end }}({{ index .Labels "alertname"}}, <a href="https://stats.maralorn.de/d/health-status">dashboard</a>, <a href="{{ .SilenceURL }}">silence</a>)<br/>{{end -}}
|
||||
'';
|
||||
msg_type = "m.text"; # Must be either `m.text` or `m.notice`
|
||||
};
|
||||
clients = [{
|
||||
UserId = "@marabot:maralorn.de";
|
||||
AccessToken = pkgs.privateValue "" "matrix/marabot-token";
|
||||
HomeServerUrl = "https://matrix.maralorn.de";
|
||||
Sync = true;
|
||||
AutoJoinRooms = true;
|
||||
DisplayName = "marabot";
|
||||
}];
|
||||
realms = [ ];
|
||||
sessions = [ ];
|
||||
services = [{
|
||||
ID = "alertmanager_service";
|
||||
Type = "alertmanager";
|
||||
UserId = "@marabot:maralorn.de";
|
||||
Config = {
|
||||
webhook_url =
|
||||
"http://localhost:4050/services/hooks/YWxlcnRtYW5hZ2VyX3NlcnZpY2UK";
|
||||
rooms = {
|
||||
"!negVsngnYOmXYCLKiO:maralorn.de" = {
|
||||
text_template = ''
|
||||
{{range .Alerts -}} [{{ .Status }}] {{index .Annotations "description"}} ({{index .Labels "alertname" }}){{ end -}}'';
|
||||
html_template = ''
|
||||
{{range .Alerts -}}{{ $severity := index .Labels "severity" }}{{ if eq .Status "firing" }}{{ if eq $severity "critical"}}<font color='red'><b>[FIRING - CRITICAL]</b></font>{{ else if eq $severity "warning"}}<font color='orange'><b>[FIRING - WARNING]</b></font>{{ else }}<font color='yellow'><b>[FIRING - {{ $severity }}]</b></font>{{ end }}{{ else }}<font color='green'><b>[RESOLVED]</b></font>{{ end }} {{ index .Annotations "description"}} {{ $url := index .Labels "url" }}{{ if eq $url "" }}{{ else }}<a href="{{ $url }}">more infos</a> {{ end }}({{ index .Labels "alertname"}}, <a href="https://stats.maralorn.de/d/health-status">dashboard</a>, <a href="{{ .SilenceURL }}">silence</a>)<br/>{{end -}}
|
||||
'';
|
||||
msg_type = "m.text"; # Must be either `m.text` or `m.notice`
|
||||
};
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
}];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,38 +1,32 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, ... }:
|
||||
let
|
||||
src = pkgs.fetchurl {
|
||||
url = "https://github.com/zgoat/goatcounter/releases/download/v2.0.4/goatcounter-v2.0.4-linux-amd64.gz";
|
||||
url =
|
||||
"https://github.com/zgoat/goatcounter/releases/download/v2.0.4/goatcounter-v2.0.4-linux-amd64.gz";
|
||||
sha256 = "1h7hv5lk2gm3klbfbgwfa7xn31az9zmlryd8bqqq38lp5r56cpb4";
|
||||
};
|
||||
goatcounter-bin = pkgs.runCommand "goatcounter-bin" {} ''
|
||||
goatcounter-bin = pkgs.runCommand "goatcounter-bin" { } ''
|
||||
mkdir -p $out/bin
|
||||
gunzip -c ${src} > $out/bin/goatcounter
|
||||
chmod +x $out/bin/goatcounter
|
||||
'';
|
||||
goatcounter-token = pkgs.privateValue "" "goatcounter-token";
|
||||
in {
|
||||
environment.systemPackages = [goatcounter-bin];
|
||||
environment.systemPackages = [ goatcounter-bin ];
|
||||
users = {
|
||||
users.goatcounter = {
|
||||
isSystemUser = true;
|
||||
group = "goatcounter";
|
||||
};
|
||||
groups.goatcounter = {};
|
||||
groups.goatcounter = { };
|
||||
};
|
||||
services.postgresql = {
|
||||
enable = true;
|
||||
ensureUsers = [
|
||||
{
|
||||
name = "goatcounter";
|
||||
ensurePermissions = {
|
||||
"DATABASE goatcounter" = "ALL PRIVILEGES";
|
||||
};
|
||||
}
|
||||
];
|
||||
ensureDatabases = ["goatcounter"];
|
||||
ensureUsers = [{
|
||||
name = "goatcounter";
|
||||
ensurePermissions = { "DATABASE goatcounter" = "ALL PRIVILEGES"; };
|
||||
}];
|
||||
ensureDatabases = [ "goatcounter" ];
|
||||
};
|
||||
services.nginx = {
|
||||
appendHttpConfig = lib.mkAfter ''
|
||||
|
@ -49,20 +43,21 @@ in {
|
|||
};
|
||||
systemd.services = {
|
||||
goatcounter = {
|
||||
requires = ["postgresql.service"];
|
||||
after = ["postgresql.service"];
|
||||
requires = [ "postgresql.service" ];
|
||||
after = [ "postgresql.service" ];
|
||||
serviceConfig = {
|
||||
User = "goatcounter";
|
||||
ExecStart = "${goatcounter-bin}/bin/goatcounter serve -db 'postgresql://host=/run/postgresql dbname=goatcounter' -listen *:8081 -tls http -automigrate";
|
||||
ExecStart =
|
||||
"${goatcounter-bin}/bin/goatcounter serve -db 'postgresql://host=/run/postgresql dbname=goatcounter' -listen *:8081 -tls http -automigrate";
|
||||
WatchdogSignal = "SIGTERM";
|
||||
WatchdogSec = "20m";
|
||||
Restart = "always";
|
||||
};
|
||||
wantedBy = ["multi-user.target"];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
};
|
||||
goatcounter-feeder = {
|
||||
requires = ["goatcounter.service"];
|
||||
after = ["goatcounter.service"];
|
||||
requires = [ "goatcounter.service" ];
|
||||
after = [ "goatcounter.service" ];
|
||||
serviceConfig = {
|
||||
User = "nginx";
|
||||
Type = "oneshot";
|
||||
|
@ -82,7 +77,7 @@ in {
|
|||
systemd.timers = {
|
||||
goatcounter-feeder = {
|
||||
timerConfig.OnCalendar = "minutely";
|
||||
wantedBy = ["timers.target"];
|
||||
wantedBy = [ "timers.target" ];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,20 +1,15 @@
|
|||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
inherit (config.m-0) hosts;
|
||||
domain = "headscale.maralorn.de";
|
||||
zone = "maralorn.de";
|
||||
derp_port = 3479;
|
||||
in {
|
||||
m-0.monitoring = [
|
||||
{
|
||||
name = "hera-headscale";
|
||||
host = "[::1]:9098";
|
||||
}
|
||||
];
|
||||
networking.firewall.allowedUDPPorts = [derp_port];
|
||||
m-0.monitoring = [{
|
||||
name = "hera-headscale";
|
||||
host = "[::1]:9098";
|
||||
}];
|
||||
networking.firewall.allowedUDPPorts = [ derp_port ];
|
||||
services = {
|
||||
headscale = {
|
||||
enable = true;
|
||||
|
@ -30,28 +25,20 @@ in {
|
|||
region_code = "hera";
|
||||
region_name = "Hera";
|
||||
};
|
||||
urls = [];
|
||||
urls = [ ];
|
||||
};
|
||||
dns_config = {
|
||||
base_domain = "m-0.eu";
|
||||
nameservers = [
|
||||
config.m-0.hosts.tailscale.hera.AAAA
|
||||
"9.9.9.9"
|
||||
];
|
||||
domains = [zone];
|
||||
extra_records = lib.concatLists (lib.concatLists (lib.mapAttrsToList (
|
||||
host: ips: (
|
||||
map (alias:
|
||||
lib.mapAttrsToList
|
||||
(type: value: {
|
||||
name = "${alias}.${zone}";
|
||||
inherit type value;
|
||||
})
|
||||
(lib.filterAttrs (_: addr: addr != "") ips))
|
||||
(hosts.aliases.${host} or [])
|
||||
)
|
||||
)
|
||||
hosts.tailscale));
|
||||
nameservers = [ config.m-0.hosts.tailscale.hera.AAAA "9.9.9.9" ];
|
||||
domains = [ zone ];
|
||||
extra_records = lib.concatLists (lib.concatLists (lib.mapAttrsToList
|
||||
(host: ips:
|
||||
(map (alias:
|
||||
lib.mapAttrsToList (type: value: {
|
||||
name = "${alias}.${zone}";
|
||||
inherit type value;
|
||||
}) (lib.filterAttrs (_: addr: addr != "") ips))
|
||||
(hosts.aliases.${host} or [ ]))) hosts.tailscale));
|
||||
};
|
||||
logtail.enabled = false;
|
||||
metrics_listen_addr = "[::1]:9098";
|
||||
|
@ -63,11 +50,12 @@ in {
|
|||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString config.services.headscale.port}";
|
||||
proxyPass =
|
||||
"http://localhost:${toString config.services.headscale.port}";
|
||||
proxyWebsockets = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
environment.systemPackages = [config.services.headscale.package];
|
||||
environment.systemPackages = [ config.services.headscale.package ];
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,4 +1,5 @@
|
|||
{pkgs, ...}: let
|
||||
{ pkgs, ... }:
|
||||
let
|
||||
nur = pkgs.flake-inputs'.hexa-nur-packages.packages;
|
||||
|
||||
mkLovelaceModule = name: {
|
||||
|
|
|
@ -1,13 +1,19 @@
|
|||
lib: let
|
||||
inherit (builtins) foldl';
|
||||
lib:
|
||||
let inherit (builtins) foldl';
|
||||
in rec {
|
||||
case = default: attrs: ''
|
||||
{% if ${lib.concatStringsSep "\n{% elseif " (lib.mapAttrsToList (condition: result: "${condition} %}\n ${result}") attrs)}
|
||||
{% if ${
|
||||
lib.concatStringsSep ''
|
||||
|
||||
{% elseif '' (lib.mapAttrsToList (condition: result: ''
|
||||
${condition} %}
|
||||
${result}'') attrs)
|
||||
}
|
||||
{% else %}
|
||||
${default}
|
||||
{% endif %}
|
||||
'';
|
||||
if' = condition: ifTrue: ifFalse: case ifFalse {"${condition}" = ifTrue;};
|
||||
if' = condition: ifTrue: ifFalse: case ifFalse { "${condition}" = ifTrue; };
|
||||
or = lhs: rhs: "(${lhs} or ${rhs})";
|
||||
and = lhs: rhs: "(${lhs} and ${rhs})";
|
||||
isState = entity: state: "is_state('${entity}','${state}')";
|
||||
|
|
|
@ -8,12 +8,7 @@ rec {
|
|||
fromServiceAction = action: {
|
||||
action = "call-service";
|
||||
inherit (action) service;
|
||||
service_data =
|
||||
action.data
|
||||
or {}
|
||||
// {
|
||||
inherit (action) entity_id;
|
||||
};
|
||||
service_data = action.data or { } // { inherit (action) entity_id; };
|
||||
};
|
||||
in {
|
||||
setMode = mode: option: fromServiceAction (actions.setMode mode option);
|
||||
|
@ -22,7 +17,7 @@ rec {
|
|||
actions = {
|
||||
notify = message: {
|
||||
service = "notify.matrix";
|
||||
data = {inherit message;};
|
||||
data = { inherit message; };
|
||||
};
|
||||
cycleMode = mode: {
|
||||
service = "input_select.select_next";
|
||||
|
@ -30,17 +25,18 @@ rec {
|
|||
};
|
||||
setMode = mode: option: {
|
||||
service = "input_select.select_option";
|
||||
data = {inherit option;};
|
||||
data = { inherit option; };
|
||||
entity_id = util.modeSelectEntity mode;
|
||||
};
|
||||
};
|
||||
util = rec {
|
||||
mkIcon = name: "mdi:${name}";
|
||||
mkMode = name: options: {inherit name options;};
|
||||
mkMode = name: options: { inherit name options; };
|
||||
modeSelectEntity = mode: "input_select.${modeSelectName mode}";
|
||||
modeSelectName = mode: "mode_${mode.name}";
|
||||
modeBinarySensorName = mode: option: "${modeSelectName mode}_is_${option}";
|
||||
modeBinarySensorEntity = mode: option: "binary_sensor.${modeBinarySensorName mode option}";
|
||||
modeBinarySensorEntity = mode: option:
|
||||
"binary_sensor.${modeBinarySensorName mode option}";
|
||||
};
|
||||
triggers = rec {
|
||||
stateTrigger = entity_id: {
|
||||
|
@ -57,42 +53,45 @@ rec {
|
|||
};
|
||||
};
|
||||
modules = rec {
|
||||
mkHAConfig = attrs: {
|
||||
services.home-assistant.config = attrs;
|
||||
};
|
||||
mkModeSwitcher = mode: let
|
||||
options = builtins.attrNames mode.options;
|
||||
in
|
||||
attrs: _:
|
||||
mkHAConfig {
|
||||
input_select."${util.modeSelectName mode}" =
|
||||
{
|
||||
inherit options;
|
||||
name = mode.title;
|
||||
}
|
||||
// attrs;
|
||||
template = builtins.map (templates.binarySensorForMode mode) options;
|
||||
};
|
||||
mkHAConfig = attrs: { services.home-assistant.config = attrs; };
|
||||
mkModeSwitcher = mode:
|
||||
let options = builtins.attrNames mode.options;
|
||||
in attrs: _:
|
||||
mkHAConfig {
|
||||
input_select."${util.modeSelectName mode}" = {
|
||||
inherit options;
|
||||
name = mode.title;
|
||||
} // attrs;
|
||||
template = builtins.map (templates.binarySensorForMode mode) options;
|
||||
};
|
||||
};
|
||||
cards = {
|
||||
modeSwitcher = mode: let
|
||||
mkEntity = optionName: option: {
|
||||
entity = util.modeBinarySensorEntity mode optionName;
|
||||
name = option.title;
|
||||
inherit (option) icon;
|
||||
tap_action = tap_actions.setMode mode optionName;
|
||||
modeSwitcher = mode:
|
||||
let
|
||||
mkEntity = optionName: option: {
|
||||
entity = util.modeBinarySensorEntity mode optionName;
|
||||
name = option.title;
|
||||
inherit (option) icon;
|
||||
tap_action = tap_actions.setMode mode optionName;
|
||||
};
|
||||
in {
|
||||
type = "glance";
|
||||
inherit (mode) title;
|
||||
columns = builtins.length (builtins.attrNames mode.options);
|
||||
show_state = false;
|
||||
entities = lib.mapAttrsToList mkEntity mode.options;
|
||||
};
|
||||
in {
|
||||
type = "glance";
|
||||
inherit (mode) title;
|
||||
columns = builtins.length (builtins.attrNames mode.options);
|
||||
show_state = false;
|
||||
entities = lib.mapAttrsToList mkEntity mode.options;
|
||||
};
|
||||
};
|
||||
templates = rec {
|
||||
binarySensor = state: attrs: {binary_sensor = [({inherit state;} // attrs)];};
|
||||
binarySensorFromCondition = condition: binarySensor (jinja.if' condition "1" "0");
|
||||
binarySensorForMode = mode: option: binarySensorFromCondition (jinja.isState (util.modeSelectEntity mode) option) {name = util.modeBinarySensorName mode option;};
|
||||
binarySensor = state: attrs: {
|
||||
binary_sensor = [ ({ inherit state; } // attrs) ];
|
||||
};
|
||||
binarySensorFromCondition = condition:
|
||||
binarySensor (jinja.if' condition "1" "0");
|
||||
binarySensorForMode = mode: option:
|
||||
binarySensorFromCondition
|
||||
(jinja.isState (util.modeSelectEntity mode) option) {
|
||||
name = util.modeBinarySensorName mode option;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
flake-inputs: {config, ...}: {
|
||||
imports = [flake-inputs.home-manager.nixosModules.home-manager];
|
||||
flake-inputs:
|
||||
{ config, ... }: {
|
||||
imports = [ flake-inputs.home-manager.nixosModules.home-manager ];
|
||||
home-manager = {
|
||||
backupFileExtension = "home-manager-backup";
|
||||
useGlobalPkgs = true;
|
||||
useUserPackages = true;
|
||||
users.maralorn = (import ../../home-manager/machines.nix).${config.networking.hostName}.default;
|
||||
users.maralorn = (import
|
||||
../../home-manager/machines.nix).${config.networking.hostName}.default;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,24 +1,26 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
inherit (lib) types mkOption;
|
||||
stateDir = "/var/lib/laminar";
|
||||
cfgDir = "${stateDir}/cfg";
|
||||
cfg = config.services.laminar;
|
||||
mkTimeoutConf = run_name: {"${lib.removeSuffix ".run" run_name}.conf" = builtins.toFile "timeout.conf" "TIMEOUT=10800";};
|
||||
addTimeouts = cfg_files: cfg_files // {jobs = lib.foldr lib.mergeAttrs cfg_files.jobs (map mkTimeoutConf (builtins.filter (lib.hasSuffix ".run") (lib.attrNames cfg_files.jobs)));};
|
||||
mkTimeoutConf = run_name: {
|
||||
"${lib.removeSuffix ".run" run_name}.conf" =
|
||||
builtins.toFile "timeout.conf" "TIMEOUT=10800";
|
||||
};
|
||||
addTimeouts = cfg_files:
|
||||
cfg_files // {
|
||||
jobs = lib.foldr lib.mergeAttrs cfg_files.jobs (map mkTimeoutConf
|
||||
(builtins.filter (lib.hasSuffix ".run")
|
||||
(lib.attrNames cfg_files.jobs)));
|
||||
};
|
||||
in {
|
||||
options = {
|
||||
services.laminar = {
|
||||
cfgFiles = mkOption {
|
||||
type = let
|
||||
valueType = with types; oneOf [path (attrsOf valueType)];
|
||||
in
|
||||
valueType;
|
||||
default = {};
|
||||
type = let valueType = with types; oneOf [ path (attrsOf valueType) ];
|
||||
in valueType;
|
||||
default = { };
|
||||
description = ''
|
||||
Every entry will be copied to /var/lib/laminar/cfg/<name>
|
||||
|
||||
|
@ -27,7 +29,7 @@ in {
|
|||
};
|
||||
};
|
||||
};
|
||||
imports = [./test-config.nix ./projects.nix];
|
||||
imports = [ ./test-config.nix ./projects.nix ];
|
||||
config = {
|
||||
services.laminar.cfgFiles = {
|
||||
env = builtins.toFile "laminar-env" ''
|
||||
|
@ -50,16 +52,16 @@ in {
|
|||
};
|
||||
};
|
||||
users = {
|
||||
groups.laminar = {};
|
||||
groups.laminar = { };
|
||||
users.laminar = {
|
||||
group = "laminar";
|
||||
home = stateDir;
|
||||
isSystemUser = true;
|
||||
};
|
||||
};
|
||||
environment.systemPackages = [pkgs.laminar];
|
||||
environment.systemPackages = [ pkgs.laminar ];
|
||||
systemd.services.laminar = {
|
||||
wantedBy = ["multi-user.target"];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
description = "Laminar continuous integration service";
|
||||
serviceConfig = {
|
||||
WorkingDirectory = stateDir;
|
||||
|
@ -69,8 +71,10 @@ in {
|
|||
Restart = "always";
|
||||
LimitNOFILE = "1024000";
|
||||
};
|
||||
after = ["network.target"];
|
||||
preStart = "ln -sfT ${pkgs.recursiveLinkFarm "laminar-config-dir" (addTimeouts cfg.cfgFiles)} ${cfgDir}";
|
||||
after = [ "network.target" ];
|
||||
preStart = "ln -sfT ${
|
||||
pkgs.recursiveLinkFarm "laminar-config-dir" (addTimeouts cfg.cfgFiles)
|
||||
} ${cfgDir}";
|
||||
};
|
||||
services = {
|
||||
nginx = {
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
path = [pkgs.git pkgs.nix pkgs.gnutar pkgs.gzip pkgs.openssh pkgs.laminar];
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
path = [ pkgs.git pkgs.nix pkgs.gnutar pkgs.gzip pkgs.openssh pkgs.laminar ];
|
||||
mkJob = name:
|
||||
pkgs.writeShellScript "${name}.run" ''
|
||||
set -e
|
||||
|
|
|
@ -1,70 +1,50 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
bins = lib.attrValues {inherit (pkgs) git nix gnutar xz gzip openssh laminar builders-configurator;};
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
bins = lib.attrValues {
|
||||
inherit (pkgs) git nix gnutar xz gzip openssh laminar builders-configurator;
|
||||
};
|
||||
standardPath = lib.makeBinPath bins;
|
||||
systems = builtins.attrNames (builtins.readDir ../../machines);
|
||||
homes = lib.attrNames (import ../../../home-manager/machines.nix);
|
||||
deployCommand = "${
|
||||
pkgs.writeShellScript "deploy-system-config"
|
||||
"${pkgs.systemd}/bin/systemctl start --no-block update-config"
|
||||
}";
|
||||
deployCommand = "${pkgs.writeShellScript "deploy-system-config"
|
||||
"${pkgs.systemd}/bin/systemctl start --no-block update-config"}";
|
||||
in {
|
||||
services.laminar.cfgFiles.jobs = {
|
||||
"test-config.run" = let
|
||||
test-config =
|
||||
pkgs.writeHaskell "test-config"
|
||||
{
|
||||
libraries = builtins.attrValues pkgs.myHaskellScriptPackages;
|
||||
ghcEnv = {
|
||||
HOMES = lib.concatStringsSep " " homes;
|
||||
SYSTEMS = lib.concatStringsSep " " systems;
|
||||
DEPLOY = deployCommand;
|
||||
PATH = "${standardPath}:$PATH";
|
||||
};
|
||||
ghcArgs = ["-threaded"];
|
||||
}
|
||||
(builtins.readFile ./test-config.hs);
|
||||
in
|
||||
pkgs.writeShellScript "test-config" ''
|
||||
FLAGS="" PATH=${standardPath}:$PATH ${test-config}
|
||||
'';
|
||||
test-config = pkgs.writeHaskell "test-config" {
|
||||
libraries = builtins.attrValues pkgs.myHaskellScriptPackages;
|
||||
ghcEnv = {
|
||||
HOMES = lib.concatStringsSep " " homes;
|
||||
SYSTEMS = lib.concatStringsSep " " systems;
|
||||
DEPLOY = deployCommand;
|
||||
PATH = "${standardPath}:$PATH";
|
||||
};
|
||||
ghcArgs = [ "-threaded" ];
|
||||
} (builtins.readFile ./test-config.hs);
|
||||
in pkgs.writeShellScript "test-config" ''
|
||||
FLAGS="" PATH=${standardPath}:$PATH ${test-config}
|
||||
'';
|
||||
"bump-config.run" = let
|
||||
bump-config =
|
||||
pkgs.writeHaskell "bump-config"
|
||||
{
|
||||
libraries = builtins.attrValues pkgs.myHaskellScriptPackages;
|
||||
ghcEnv.PATH = "${standardPath}:$PATH";
|
||||
ghcArgs = ["-threaded"];
|
||||
}
|
||||
(builtins.readFile ./bump-config.hs);
|
||||
in
|
||||
pkgs.writeShellScript "bump-config" ''
|
||||
PATH=${standardPath}:$PATH ${bump-config}
|
||||
'';
|
||||
bump-config = pkgs.writeHaskell "bump-config" {
|
||||
libraries = builtins.attrValues pkgs.myHaskellScriptPackages;
|
||||
ghcEnv.PATH = "${standardPath}:$PATH";
|
||||
ghcArgs = [ "-threaded" ];
|
||||
} (builtins.readFile ./bump-config.hs);
|
||||
in pkgs.writeShellScript "bump-config" ''
|
||||
PATH=${standardPath}:$PATH ${bump-config}
|
||||
'';
|
||||
};
|
||||
security.sudo.extraRules = let
|
||||
allowedCommands = [deployCommand];
|
||||
in [
|
||||
{
|
||||
commands =
|
||||
map
|
||||
(
|
||||
command: {
|
||||
inherit command;
|
||||
options = ["NOPASSWD"];
|
||||
}
|
||||
)
|
||||
allowedCommands;
|
||||
users = ["laminar"];
|
||||
}
|
||||
];
|
||||
security.sudo.extraRules = let allowedCommands = [ deployCommand ];
|
||||
in [{
|
||||
commands = map (command: {
|
||||
inherit command;
|
||||
options = [ "NOPASSWD" ];
|
||||
}) allowedCommands;
|
||||
users = [ "laminar" ];
|
||||
}];
|
||||
systemd.services = {
|
||||
update-config = {
|
||||
path = [pkgs.git pkgs.openssh pkgs.nix];
|
||||
path = [ pkgs.git pkgs.openssh pkgs.nix ];
|
||||
restartIfChanged = false;
|
||||
unitConfig.X-StopOnRemoval = false;
|
||||
serviceConfig = {
|
||||
|
@ -74,41 +54,40 @@ in {
|
|||
script = let
|
||||
user = "maralorn";
|
||||
name = "update-config-after-build-if-forward";
|
||||
haskell_script =
|
||||
pkgs.writeHaskellScript
|
||||
{
|
||||
inherit name;
|
||||
imports = [
|
||||
"Control.Exception qualified as Exception"
|
||||
"Data.ByteString.Char8 qualified as BSC"
|
||||
];
|
||||
bins = [pkgs.nix-diff pkgs.jq];
|
||||
} ''
|
||||
exitOnError = \msg action -> try action >>= \case
|
||||
Left (_ :: Exception.IOException) -> say msg >> exitSuccess
|
||||
Right value -> pure value
|
||||
haskell_script = pkgs.writeHaskellScript {
|
||||
inherit name;
|
||||
imports = [
|
||||
"Control.Exception qualified as Exception"
|
||||
"Data.ByteString.Char8 qualified as BSC"
|
||||
];
|
||||
bins = [ pkgs.nix-diff pkgs.jq ];
|
||||
} ''
|
||||
exitOnError = \msg action -> try action >>= \case
|
||||
Left (_ :: Exception.IOException) -> say msg >> exitSuccess
|
||||
Right value -> pure value
|
||||
|
||||
git arg = exe "/run/wrappers/bin/sudo" "-u" "${user}" "${lib.getExe pkgs.git}" arg |> captureTrim
|
||||
git arg = exe "/run/wrappers/bin/sudo" "-u" "${user}" "${
|
||||
lib.getExe pkgs.git
|
||||
}" arg |> captureTrim
|
||||
|
||||
main = do
|
||||
cd "/etc/nixos"
|
||||
void $ git ["pull", "--ff-only"]
|
||||
new_system <- readlink "-f" "/var/cache/gc-links/test-config/nixos-configurations/hera" |> captureTrim
|
||||
old_system <- readlink "-f" "/run/current-system" |> captureTrim
|
||||
when (new_system == old_system) do say "No changes."; exitSuccess
|
||||
let switch = do
|
||||
nix_env "-p" "/nix/var/nix/profiles/system" "--set" (decodeUtf8 new_system :: String)
|
||||
exe ([i|#{new_system}/bin/switch-to-configuration|] :: String) "switch"
|
||||
exitSuccess
|
||||
diff_is_small <- (== "[]") <$> (nix_diff "--json" [new_system, "/run/current-system"] |> jq ".inputsDiff.inputDerivationDiffs" |> captureTrim)
|
||||
when diff_is_small switch
|
||||
current_commit <- BSC.strip <$> (exitOnError "Current system is from a dirty commit." do readFileBS "/run/current-system/config-commit")
|
||||
new_commit <- BSC.strip <$> readFileBS [i|#{new_system}/config-commit|]
|
||||
is_direct_forward <- ("" ==) <$> exitOnError "Unknown commit." (git ["log", "-n1", "--oneline", [i|^#{new_commit}|], decodeUtf8 current_commit])
|
||||
when is_direct_forward switch
|
||||
'';
|
||||
in
|
||||
lib.getExe haskell_script;
|
||||
main = do
|
||||
cd "/etc/nixos"
|
||||
void $ git ["pull", "--ff-only"]
|
||||
new_system <- readlink "-f" "/var/cache/gc-links/test-config/nixos-configurations/hera" |> captureTrim
|
||||
old_system <- readlink "-f" "/run/current-system" |> captureTrim
|
||||
when (new_system == old_system) do say "No changes."; exitSuccess
|
||||
let switch = do
|
||||
nix_env "-p" "/nix/var/nix/profiles/system" "--set" (decodeUtf8 new_system :: String)
|
||||
exe ([i|#{new_system}/bin/switch-to-configuration|] :: String) "switch"
|
||||
exitSuccess
|
||||
diff_is_small <- (== "[]") <$> (nix_diff "--json" [new_system, "/run/current-system"] |> jq ".inputsDiff.inputDerivationDiffs" |> captureTrim)
|
||||
when diff_is_small switch
|
||||
current_commit <- BSC.strip <$> (exitOnError "Current system is from a dirty commit." do readFileBS "/run/current-system/config-commit")
|
||||
new_commit <- BSC.strip <$> readFileBS [i|#{new_system}/config-commit|]
|
||||
is_direct_forward <- ("" ==) <$> exitOnError "Unknown commit." (git ["log", "-n1", "--oneline", [i|^#{new_commit}|], decodeUtf8 current_commit])
|
||||
when is_direct_forward switch
|
||||
'';
|
||||
in lib.getExe haskell_script;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,71 +1,59 @@
|
|||
{
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
...
|
||||
}: let
|
||||
{ pkgs, lib, config, ... }:
|
||||
let
|
||||
hostname = "lists.maralorn.de";
|
||||
lists = pkgs.privateValue {} "mail/lists";
|
||||
me = pkgs.privateValue {mail = "";} "mail/me";
|
||||
lists = pkgs.privateValue { } "mail/lists";
|
||||
me = pkgs.privateValue { mail = ""; } "mail/me";
|
||||
admin = me.mail;
|
||||
in {
|
||||
systemd.services.mailman.postStart = lib.concatStringsSep "\n" (
|
||||
map
|
||||
(
|
||||
x: ''
|
||||
${(pkgs.mailmanPackages.buildEnvs {}).mailmanEnv}/bin/mailman syncmembers -W -G - "${x}" << EOF
|
||||
${lib.concatStringsSep "\n" lists."${x}"}
|
||||
EOF
|
||||
''
|
||||
)
|
||||
(builtins.attrNames lists)
|
||||
);
|
||||
systemd.services.mailman.postStart = lib.concatStringsSep "\n" (map (x: ''
|
||||
${
|
||||
(pkgs.mailmanPackages.buildEnvs { }).mailmanEnv
|
||||
}/bin/mailman syncmembers -W -G - "${x}" << EOF
|
||||
${lib.concatStringsSep "\n" lists."${x}"}
|
||||
EOF
|
||||
'') (builtins.attrNames lists));
|
||||
services = {
|
||||
mailman = {
|
||||
enable = true;
|
||||
webHosts = [hostname];
|
||||
webHosts = [ hostname ];
|
||||
serve.enable = true;
|
||||
enablePostfix = true;
|
||||
siteOwner = admin;
|
||||
webSettings = {
|
||||
ACCOUNT_ADAPTER = "django_mailman3.views.user_adapter.DisableSignupAdapter";
|
||||
ACCOUNT_ADAPTER =
|
||||
"django_mailman3.views.user_adapter.DisableSignupAdapter";
|
||||
};
|
||||
hyperkitty.enable = true; # Annoyingly mailman crashes when it can‘t find
|
||||
# a hyperkitty. This is stupid, but I have no patience to find a fix for
|
||||
# this.
|
||||
settings = {
|
||||
mailman.default_language = "de";
|
||||
"paths.fhs".template_dir =
|
||||
lib.mkForce
|
||||
(
|
||||
pkgs.recursiveLinkFarm "mailman-templates" {
|
||||
site.de = {
|
||||
"list:user:notice:goodbye.txt" = builtins.toFile "goodbye" ''
|
||||
Du erhältst nun keine E-Mails mehr über diese Mailingliste.
|
||||
"paths.fhs".template_dir = lib.mkForce
|
||||
(pkgs.recursiveLinkFarm "mailman-templates" {
|
||||
site.de = {
|
||||
"list:user:notice:goodbye.txt" = builtins.toFile "goodbye" ''
|
||||
Du erhältst nun keine E-Mails mehr über diese Mailingliste.
|
||||
|
||||
Bei Fragen oder wenn Du doch E-Mails von dieser Liste bekommen möchtest wende Dich an ${admin}.
|
||||
'';
|
||||
"list:member:generic:footer.txt" = builtins.toFile "footer" ''
|
||||
---
|
||||
Du erhältst diese E-Mail über die Mailingliste "$display_name".
|
||||
Bei Fragen oder wenn Du diese E-Mails nicht mehr bekommen möchtest wende Dich an ${admin}.
|
||||
'';
|
||||
Bei Fragen oder wenn Du doch E-Mails von dieser Liste bekommen möchtest wende Dich an ${admin}.
|
||||
'';
|
||||
"list:member:generic:footer.txt" = builtins.toFile "footer" ''
|
||||
---
|
||||
Du erhältst diese E-Mail über die Mailingliste "$display_name".
|
||||
Bei Fragen oder wenn Du diese E-Mails nicht mehr bekommen möchtest wende Dich an ${admin}.
|
||||
'';
|
||||
|
||||
"list:user:notice:welcome.txt" = builtins.toFile "welcome" ''
|
||||
Herzlich Willkommen auf der Mailingliste "$display_name".
|
||||
"list:user:notice:welcome.txt" = builtins.toFile "welcome" ''
|
||||
Herzlich Willkommen auf der Mailingliste "$display_name".
|
||||
|
||||
Bei Fragen und wenn Du keine E-Mails von dieser Liste mehr bekommen möchtest wende Dich an ${admin}.
|
||||
'';
|
||||
};
|
||||
}
|
||||
)
|
||||
.outPath;
|
||||
Bei Fragen und wenn Du keine E-Mails von dieser Liste mehr bekommen möchtest wende Dich an ${admin}.
|
||||
'';
|
||||
};
|
||||
}).outPath;
|
||||
};
|
||||
};
|
||||
postfix = {
|
||||
relayDomains = ["hash:/var/lib/mailman/data/postfix_domains"];
|
||||
config = let
|
||||
lmtp = ["hash:/var/lib/mailman/data/postfix_lmtp"];
|
||||
relayDomains = [ "hash:/var/lib/mailman/data/postfix_domains" ];
|
||||
config = let lmtp = [ "hash:/var/lib/mailman/data/postfix_lmtp" ];
|
||||
in {
|
||||
transport_maps = lmtp;
|
||||
local_recipient_maps = lmtp;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue