Merge pull request #266 from DarkKirb/switch-back-to-sway
switch back to sway
This commit is contained in:
commit
80744fe532
19 changed files with 1013 additions and 852 deletions
|
@ -21,6 +21,7 @@
|
||||||
services.openssh.enable = true;
|
services.openssh.enable = true;
|
||||||
environment.systemPackages = with pkgs; [
|
environment.systemPackages = with pkgs; [
|
||||||
git
|
git
|
||||||
|
kitty.terminfo
|
||||||
];
|
];
|
||||||
networking.firewall.allowedTCPPorts = [22];
|
networking.firewall.allowedTCPPorts = [22];
|
||||||
networking.firewall.allowedUDPPortRanges = [
|
networking.firewall.allowedUDPPortRanges = [
|
||||||
|
|
|
@ -82,7 +82,6 @@ in {
|
||||||
|
|
||||||
security.pam = {
|
security.pam = {
|
||||||
services.login.u2fAuth = true;
|
services.login.u2fAuth = true;
|
||||||
services.sddm.u2fAuth = true;
|
|
||||||
services.swaylock.u2fAuth = true;
|
services.swaylock.u2fAuth = true;
|
||||||
u2f = {
|
u2f = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -139,7 +138,6 @@ in {
|
||||||
pinentry-qt
|
pinentry-qt
|
||||||
dotool
|
dotool
|
||||||
wl-clipboard
|
wl-clipboard
|
||||||
plasma5Packages.thirdParty.lightly
|
|
||||||
];
|
];
|
||||||
programs.gnupg.agent.pinentryFlavor = "qt";
|
programs.gnupg.agent.pinentryFlavor = "qt";
|
||||||
|
|
||||||
|
@ -156,19 +154,12 @@ in {
|
||||||
libinput.enable = true;
|
libinput.enable = true;
|
||||||
layout = "de";
|
layout = "de";
|
||||||
xkbVariant = "neo";
|
xkbVariant = "neo";
|
||||||
displayManager.sddm.enable = true;
|
|
||||||
desktopManager.plasma5.enable = true;
|
|
||||||
displayManager.defaultSession = "plasmawayland";
|
|
||||||
extraLayouts.zlr = {
|
extraLayouts.zlr = {
|
||||||
description = "lojban layout";
|
description = "lojban layout";
|
||||||
languages = ["jbo"];
|
languages = ["jbo"];
|
||||||
symbolsFile = ../extra/keyboard/symbols;
|
symbolsFile = ../extra/keyboard/symbols;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
i18n.inputMethod = {
|
|
||||||
enabled = "ibus";
|
|
||||||
ibus.engines = with pkgs.ibus-engines; [anthy];
|
|
||||||
};
|
|
||||||
security.polkit.enable = true;
|
security.polkit.enable = true;
|
||||||
services.dbus.enable = true;
|
services.dbus.enable = true;
|
||||||
services.dbus.packages = with pkgs; [dconf];
|
services.dbus.packages = with pkgs; [dconf];
|
||||||
|
|
|
@ -12,7 +12,10 @@
|
||||||
++ (
|
++ (
|
||||||
if desktop
|
if desktop
|
||||||
then [
|
then [
|
||||||
|
../programs/sway.nix
|
||||||
../programs/firefox.nix
|
../programs/firefox.nix
|
||||||
|
../programs/theming.nix
|
||||||
|
../programs/waybar.nix
|
||||||
../programs/ims.nix
|
../programs/ims.nix
|
||||||
../programs/syncthing.nix
|
../programs/syncthing.nix
|
||||||
../programs/plover.nix
|
../programs/plover.nix
|
||||||
|
@ -25,7 +28,6 @@
|
||||||
../programs/zk.nix
|
../programs/zk.nix
|
||||||
../programs/fcitx.nix
|
../programs/fcitx.nix
|
||||||
../programs/gpg.nix
|
../programs/gpg.nix
|
||||||
../programs/kdeconnect.nix
|
|
||||||
../programs/zoom.nix
|
../programs/zoom.nix
|
||||||
]
|
]
|
||||||
else []
|
else []
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
ublock-origin
|
ublock-origin
|
||||||
umatrix
|
umatrix
|
||||||
unpaywall
|
unpaywall
|
||||||
plasma-integration
|
|
||||||
tampermonkey
|
tampermonkey
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
{...}: {
|
|
||||||
services.kdeconnect.enable = true;
|
|
||||||
services.kdeconnect.indicator = true;
|
|
||||||
}
|
|
|
@ -4,15 +4,4 @@
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
home.packages = [pkgs.keepassxc];
|
home.packages = [pkgs.keepassxc];
|
||||||
systemd.user.services.keepassxc = {
|
|
||||||
Unit = {
|
|
||||||
Description = "keepassxc";
|
|
||||||
After = ["graphical-session-pre.target"];
|
|
||||||
PartOf = ["graphical-session.target"];
|
|
||||||
};
|
|
||||||
Install.WantedBy = ["graphical-session.target"];
|
|
||||||
Service = {
|
|
||||||
ExecStart = "${pkgs.keepassxc}/bin/keepassxc";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
5
config/programs/pass-secret-service.nix
Normal file
5
config/programs/pass-secret-service.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
services.pass-secret-service = {
|
||||||
|
enable = true;
|
||||||
|
};
|
||||||
|
}
|
138
config/programs/sway.nix
Normal file
138
config/programs/sway.nix
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
system,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
c = "$";
|
||||||
|
switch_window = pkgs.writeScript "switchWindow" ''
|
||||||
|
set -euo pipefail
|
||||||
|
tree=$(${pkgs.sway}/bin/swaymsg -t get_tree)
|
||||||
|
readarray -t win_ids <<< "$(${pkgs.jq}/bin/jq -r '.. | objects | select(has("app_id")) | .id' <<< "$tree")"
|
||||||
|
readarray -t win_names <<< "$(${pkgs.jq}/bin/jq -r '.. | objects | select(has("app_id")) | .name' <<< "$tree")"
|
||||||
|
readarray -t win_types <<< "$(${pkgs.jq}/bin/jq -r '.. | objects | select(has("app_id")) | .app_id // .window_properties.class' <<< "$tree")"
|
||||||
|
switch () {
|
||||||
|
local k
|
||||||
|
read -r k
|
||||||
|
swaymsg "[con_id=${c}{win_ids[$k]}] focus"
|
||||||
|
}
|
||||||
|
for k in $(seq 0 $((${c}{#win_ids[@]} - 1))); do
|
||||||
|
echo -e "<span weight=\"bold\">${c}{win_types[$k]}</span> - ${c}{win_names[$k]}"
|
||||||
|
done | rofi -dmenu -markup-rows -i -p window -format i | switch
|
||||||
|
'';
|
||||||
|
screenshot_then_switch = pkgs.writeScript "screenshotThenSwitch" ''
|
||||||
|
${pkgs.sway-contrib.grimshot}/bin/grimshot "$@"
|
||||||
|
${pkgs.sway}/bin/swaymsg mode default
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
./wl-clipboard.nix
|
||||||
|
./mako.nix
|
||||||
|
./swayidle.nix
|
||||||
|
./rofi.nix
|
||||||
|
./fcitx.nix
|
||||||
|
./pass-secret-service.nix
|
||||||
|
];
|
||||||
|
wayland.windowManager.sway = {
|
||||||
|
enable = true;
|
||||||
|
config = {
|
||||||
|
modifier = "Mod4";
|
||||||
|
input = {
|
||||||
|
"*" = {
|
||||||
|
xkb_layout = "de,de";
|
||||||
|
xkb_variant = "neo_qwertz,neo";
|
||||||
|
xkb_options = "grp:ctrls_toggle";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
output = {
|
||||||
|
"DP-1" = {
|
||||||
|
mode = "2560x1440@74.971Hz";
|
||||||
|
position = "0 0";
|
||||||
|
subpixel = "rgb";
|
||||||
|
adaptive_sync = "on";
|
||||||
|
};
|
||||||
|
"HDMI-A-1" = {
|
||||||
|
mode = "1920x1080@60Hz";
|
||||||
|
position = "2560 0";
|
||||||
|
subpixel = "rgb";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
keybindings = let
|
||||||
|
inherit (config.wayland.windowManager.sway.config) modifier;
|
||||||
|
in
|
||||||
|
lib.mkOptionDefault {
|
||||||
|
"${modifier}+Return" = "exec ${pkgs.kitty}/bin/kitty";
|
||||||
|
"${modifier}+d" = "exec ${pkgs.rofi}/bin/rofi -show drun";
|
||||||
|
"Print" = "mode screenshot";
|
||||||
|
"XF86AudioRaiseVolume" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ +5%";
|
||||||
|
"XF86AudioLowerVolume" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-volume @DEFAULT_SINK@ -5%";
|
||||||
|
"XF86AudioMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-sink-mute @DEFAULT_SINK@ toggle";
|
||||||
|
"XF86AudioMicMute" = "exec ${pkgs.pulseaudio}/bin/pactl set-source-mute @DEFAULT_SOURCE@ toggle";
|
||||||
|
"XF86MonBrightnessDown" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set 5%-";
|
||||||
|
"XF86MonBrightnessUp" = "exec ${pkgs.brightnessctl}/bin/brightnessctl set +5%";
|
||||||
|
"XF86AudioPlay" = "exec ${pkgs.mpc-cli}/bin/mpc toggle";
|
||||||
|
"XF86AudioNext" = "exec ${pkgs.mpc-cli}/bin/mpc next";
|
||||||
|
"XF86AudioPrev" = "exec ${pkgs.mpc-cli}/bin/mpc prev";
|
||||||
|
"XF86AudioStop" = "exec ${pkgs.mpc-cli}/bin/mpc stop";
|
||||||
|
"Mod1+Tab" = "exec ${switch_window}";
|
||||||
|
};
|
||||||
|
bars = [
|
||||||
|
{
|
||||||
|
command = "${pkgs.waybar}/bin/waybar";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
modes = {
|
||||||
|
screenshot = {
|
||||||
|
Print = "exec ${screenshot_then_switch} copy area";
|
||||||
|
"Shift+Print" = "exec ${screenshot_then_switch} save area $HOME/Pictures/grim-$(date --iso=s | sed 's/:/-/g').png";
|
||||||
|
a = "exec ${screenshot_then_switch} copy active";
|
||||||
|
"Shift+a" = "exec ${screenshot_then_switch} save active $HOME/Pictures/grim-$(date --iso=s | sed 's/:/-/g').png";
|
||||||
|
s = "exec ${screenshot_then_switch} copy screen";
|
||||||
|
"Shift+s" = "exec ${screenshot_then_switch} save screen $HOME/Pictures/grim-$(date --iso=s | sed 's/:/-/g').png";
|
||||||
|
o = "exec ${screenshot_then_switch} copy output";
|
||||||
|
"Shift+o" = "exec ${screenshot_then_switch} save output $HOME/Pictures/grim-$(date --iso=s | sed 's/:/-/g').png";
|
||||||
|
w = "exec ${screenshot_then_switch} copy window";
|
||||||
|
"Shift+w" = "exec ${screenshot_then_switch} save window $HOME/Pictures/grim-$(date --iso=s | sed 's/:/-/g').png";
|
||||||
|
Escape = ''mode "default"'';
|
||||||
|
Return = ''mode "default"'';
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
wrapperFeatures = {
|
||||||
|
base = true;
|
||||||
|
gtk = true;
|
||||||
|
};
|
||||||
|
extraSessionCommands =
|
||||||
|
''
|
||||||
|
export XDG_SESSION_TYPE=wayland
|
||||||
|
export XDG_CURRENT_DESKTOP=sway
|
||||||
|
export QT_WAYLAND_DISABLE_WINDOWDECORATION=1
|
||||||
|
export QT_AUTO_SCREEN_SCALE_FACTOR=0
|
||||||
|
export QT_SCALE_FACTOR=1
|
||||||
|
export GDK_SCALE=1
|
||||||
|
export GDK_DPI_SCALE=1
|
||||||
|
export MOZ_ENABLE_WAYLAND=1
|
||||||
|
export _JAVA_AWT_WM_NONREPARENTING=1
|
||||||
|
export QT_QPA_PLATFORMTHEME=qt5ct
|
||||||
|
export GTK_IM_MODULE=fcitx
|
||||||
|
export QT_IM_MODULE=fcitx
|
||||||
|
export XMODIFIERS=@im=fcitx
|
||||||
|
export GLFW_IM_MODULE=ibus
|
||||||
|
export SDL_IM_MODULE=fcitx
|
||||||
|
''
|
||||||
|
+ (
|
||||||
|
if system == "x86_64-linux"
|
||||||
|
then ''
|
||||||
|
export VK_ICD_FILENAMES=/run/opengl-driver/share/vulkan/icd.d/intel_icd.x86_64.json:/run/opengl-driver/share/vulkan/icd.d/radeon_icd.x86_64.json:/run/opengl-driver-32/share/vulkan/icd.d/radeon_icd.i686.json:/run/opengl-driver-32/share/vulkan/icd.d/intel_icd.i686.json
|
||||||
|
''
|
||||||
|
else ""
|
||||||
|
);
|
||||||
|
extraConfig = ''
|
||||||
|
default_border none
|
||||||
|
gaps outer 8
|
||||||
|
gaps inner 4
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
home.file.".XCompose".source = ../../extra/.XCompose;
|
||||||
|
}
|
52
config/programs/swayidle.nix
Normal file
52
config/programs/swayidle.nix
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
{pkgs, ...}: let
|
||||||
|
lock-script = pkgs.writeScript "suspend" ''
|
||||||
|
${pkgs.swaylock}/bin/swaylock -f -c 000000
|
||||||
|
${pkgs.mpc-cli}/bin/mpc pause
|
||||||
|
'';
|
||||||
|
screen-off-script = pkgs.writeScript "screenOff" ''
|
||||||
|
${pkgs.sway}/bin/swaymsg "output * dpms off"
|
||||||
|
'';
|
||||||
|
suspend-script = pkgs.writeScript "suspend" ''
|
||||||
|
${pkgs.systemd}/bin/systemctl suspend
|
||||||
|
'';
|
||||||
|
resume-script = pkgs.writeScript "resume" ''
|
||||||
|
${pkgs.sway}/bin/swaymsg "output * dpms on"
|
||||||
|
'';
|
||||||
|
unlock-script = pkgs.writeScript "unlock" ''
|
||||||
|
${pkgs.procps}/bin/pkill swaylock
|
||||||
|
${pkgs.mpc-cli}/bin/mpc play
|
||||||
|
'';
|
||||||
|
in {
|
||||||
|
services.swayidle = {
|
||||||
|
enable = true;
|
||||||
|
events = [
|
||||||
|
{
|
||||||
|
event = "before-sleep";
|
||||||
|
command = "${lock-script}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
event = "lock";
|
||||||
|
command = "${lock-script}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
event = "unlock";
|
||||||
|
command = "${unlock-script}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
timeouts = [
|
||||||
|
{
|
||||||
|
timeout = 300;
|
||||||
|
command = "${lock-script}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 305;
|
||||||
|
command = "${screen-off-script}";
|
||||||
|
resumeCommand = "${resume-script}";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
timeout = 900;
|
||||||
|
command = "${suspend-script}";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
}
|
607
config/programs/theming.nix
Normal file
607
config/programs/theming.nix
Normal file
|
@ -0,0 +1,607 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
colorpickle,
|
||||||
|
withNSFW,
|
||||||
|
lib,
|
||||||
|
self,
|
||||||
|
nixpkgs,
|
||||||
|
...
|
||||||
|
}: let
|
||||||
|
theme = import ../../extra/theme.nix;
|
||||||
|
inherit (config.lib.formats.rasi) mkLiteral;
|
||||||
|
|
||||||
|
prepBGs = [
|
||||||
|
["${pkgs.lotte-art}/2021-01-27-ceeza-lottedonut.jxl" "-crop" "2048x1152+0+106"]
|
||||||
|
["${pkgs.lotte-art}/2021-09-15-cloverhare-lotteplush.jxl" "-crop" "1774x997+0+173"]
|
||||||
|
["${pkgs.lotte-art}/2022-11-15-wolfsifi-maff-me-leashed.jxl" "-crop" "1699x956+0+88"]
|
||||||
|
];
|
||||||
|
|
||||||
|
prepBGsNSFW = [
|
||||||
|
["${pkgs.lotte-art}/2021-11-27-theroguez-lottegassyvore1.jxl" "-crop" "1233x694+0+65"]
|
||||||
|
["${pkgs.lotte-art}/2021-12-12-baltnwolf-christmas-diaper.jxl" "-crop" "2599x1462+0+294"]
|
||||||
|
["${pkgs.lotte-art}/2021-12-12-baltnwolf-christmas-diaper-messy.jxl" "-crop" "2599x1462+0+294"]
|
||||||
|
["${pkgs.lotte-art}/2022-04-20-cloverhare-mxbatty-maffsie-train-plush.jxl" "-crop" "3377x1900+0+211"]
|
||||||
|
["${pkgs.lotte-art}/2022-04-20-cloverhare-mxbatty-me-train-maffsie-plush.jxl" "-crop" "3377x1900+0+211"]
|
||||||
|
["${pkgs.lotte-art}/2022-12-27-rexyi-scatych.jxl" "-crop" "2000x1120+0+0"]
|
||||||
|
["${pkgs.lotte-art}/2023-03-09-rexyi-voredisposal-ych.jxl" "-crop" "2000x1120+0+0"]
|
||||||
|
["${pkgs.lotte-art}/2023-04-16-baltnwolf-lottediaperplushies.jxl" "-gravity" "center" "-background" "white" "-extent" "5333x3000"]
|
||||||
|
["${pkgs.lotte-art}/2023-04-16-baltnwolf-lottediaperplushies-messy.jxl" "-gravity" "center" "-background" "white" "-extent" "5333x3000"]
|
||||||
|
];
|
||||||
|
|
||||||
|
fixupImage = instructions:
|
||||||
|
pkgs.stdenv.mkDerivation {
|
||||||
|
name = "bg.jxl";
|
||||||
|
src = pkgs.emptyDirectory;
|
||||||
|
nativeBuildInputs = [pkgs.imagemagick];
|
||||||
|
buildPhase = ''
|
||||||
|
convert ${toString instructions} $out
|
||||||
|
'';
|
||||||
|
installPhase = "true";
|
||||||
|
};
|
||||||
|
|
||||||
|
validBGs = ["${pkgs.lotte-art}/2020-07-24-urbankitsune-bna-ych.jxl" "${pkgs.lotte-art}/2022-05-02-anonfurryartist-giftart.jxl" "${pkgs.lotte-art}/2022-06-21-sammythetanuki-lotteplushpride.jxl"] ++ (map fixupImage prepBGs);
|
||||||
|
validBGsNSFW = ["${pkgs.lotte-art}/2021-10-29-butterskunk-lotte-scat-buffet.jxl" "${pkgs.lotte-art}/2022-08-12-deathtoaster-funpit-scat.jxl" "${pkgs.lotte-art}/2022-08-15-deathtoaster-funpit-mud.jxl"] ++ (map fixupImage prepBGsNSFW) ++ validBGs;
|
||||||
|
|
||||||
|
mod = a: b: a - (a / b * b);
|
||||||
|
choose = l: rand: let len = builtins.length l; in builtins.elemAt l (mod rand len);
|
||||||
|
hexToIntList = {
|
||||||
|
"0" = 0;
|
||||||
|
"1" = 1;
|
||||||
|
"2" = 2;
|
||||||
|
"3" = 3;
|
||||||
|
"4" = 4;
|
||||||
|
"5" = 5;
|
||||||
|
"6" = 6;
|
||||||
|
"7" = 7;
|
||||||
|
"8" = 8;
|
||||||
|
"9" = 9;
|
||||||
|
"a" = 10;
|
||||||
|
"b" = 11;
|
||||||
|
"c" = 12;
|
||||||
|
"d" = 13;
|
||||||
|
"e" = 14;
|
||||||
|
"f" = 15;
|
||||||
|
"A" = 10;
|
||||||
|
"B" = 11;
|
||||||
|
"C" = 12;
|
||||||
|
"D" = 13;
|
||||||
|
"E" = 14;
|
||||||
|
"F" = 15;
|
||||||
|
};
|
||||||
|
hexToInt = s: lib.foldl (state: new: state * 16 + hexToIntList.${new}) 0 (lib.strings.stringToCharacters s);
|
||||||
|
|
||||||
|
seed = hexToInt (self.shortRev or nixpkgs.shortRev);
|
||||||
|
bg =
|
||||||
|
choose (
|
||||||
|
if withNSFW
|
||||||
|
then validBGsNSFW
|
||||||
|
else validBGs
|
||||||
|
)
|
||||||
|
seed;
|
||||||
|
|
||||||
|
color = n:
|
||||||
|
config.environment.graphical.colors.main."${builtins.toString n}";
|
||||||
|
colorD = n:
|
||||||
|
config.environment.graphical.colors.disabled."${builtins.toString n}";
|
||||||
|
colorI = n:
|
||||||
|
config.environment.graphical.colors.inactive."${builtins.toString n}";
|
||||||
|
|
||||||
|
color' = n: mkLiteral (color n);
|
||||||
|
bgPng = pkgs.stdenv.mkDerivation {
|
||||||
|
name = "bg.png";
|
||||||
|
src = pkgs.emptyDirectory;
|
||||||
|
nativeBuildInputs = [pkgs.imagemagick];
|
||||||
|
buildPhase = ''
|
||||||
|
convert ${bg} $out
|
||||||
|
'';
|
||||||
|
installPhase = "true";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
imports = [
|
||||||
|
colorpickle.nixosModules.default
|
||||||
|
];
|
||||||
|
environment.graphical.colorschemes.main = {
|
||||||
|
image = bgPng;
|
||||||
|
params = ["--lighten" "-0.1"];
|
||||||
|
};
|
||||||
|
environment.graphical.colorschemes.disabled = {
|
||||||
|
image = bgPng;
|
||||||
|
params = ["--lighten" "-0.2" "--saturate" "-0.5"];
|
||||||
|
};
|
||||||
|
environment.graphical.colorschemes.inactive = {
|
||||||
|
image = bgPng;
|
||||||
|
params = ["--lighten" "-0.3"];
|
||||||
|
};
|
||||||
|
wayland.windowManager.sway.config.output."*".bg = "${bgPng} fill";
|
||||||
|
dconf.settings."org/gnome/desktop/interface" = {
|
||||||
|
icon-theme = "breeze-dark";
|
||||||
|
cursor-theme = "Vanilla-DMZ";
|
||||||
|
};
|
||||||
|
gtk = {
|
||||||
|
enable = true;
|
||||||
|
gtk2.extraConfig = ''
|
||||||
|
gtk-cursor-theme-name = "Vanilla-DMZ"
|
||||||
|
gtk-cursor-theme-size = 0
|
||||||
|
'';
|
||||||
|
gtk3.extraConfig = {
|
||||||
|
gtk-cursor-theme-name = "Vanilla-DMZ";
|
||||||
|
gtk-cursor-theme-size = 0;
|
||||||
|
};
|
||||||
|
font = {
|
||||||
|
package = pkgs.noto-fonts;
|
||||||
|
name = "Noto Sans";
|
||||||
|
size = 10;
|
||||||
|
};
|
||||||
|
iconTheme = {
|
||||||
|
package = pkgs.libsForQt5.breeze-icons;
|
||||||
|
name = "breeze-dark";
|
||||||
|
};
|
||||||
|
theme = {
|
||||||
|
name = "Catppuccin-Mocha-Compact-Pink-Dark";
|
||||||
|
package = pkgs.catppuccin-gtk.override {
|
||||||
|
accents = ["pink"];
|
||||||
|
size = "compact";
|
||||||
|
tweaks = ["rimless" "black"];
|
||||||
|
variant = "mocha";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
qt = {
|
||||||
|
enable = true;
|
||||||
|
style = {
|
||||||
|
name = "lightly";
|
||||||
|
package = pkgs.plasma5Packages.lightly;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
xdg.configFile."qt5ct/colors/Catppuccin-Custom.conf".text = ''
|
||||||
|
[ColorScheme]
|
||||||
|
active_colors=${color 15}, ${color 0}, #ffa6adc8, #ff9399b2, ${color 1}, #ff6c7086, ${color 15}, ${color 15}, ${color 15}, ${color 0}, ${colorD 0}, #ff7f849c, ${color 8}, ${color 0}, ${color 13}, ${color 5}, ${color 0}, ${color 15}, ${colorI 0}, ${color 5}, #807f849c
|
||||||
|
disabled_colors=${colorD 15}, ${colorD 0}, #ffa6adc8, #ff9399b2, ${colorD 1}, #ff6c7086, ${colorD 15}, ${colorD 15}, ${colorD 15}, ${colorD 0}, ${colorD 0}, #ff7f849c, ${colorD 8}, ${colorD 0}, ${colorD 13}, ${colorD 5}, ${colorD 0}, ${colorD 15}, ${colorI 0}, ${colorD 5}, #807f849c
|
||||||
|
inactive_colors=${colorI 15}, ${colorI 0}, #ffa6adc8, #ff9399b2, ${colorI 1}, #ff6c7086, ${colorI 15}, ${colorI 15}, ${colorI 15}, ${colorI 0}, ${colorD 0}, #ff7f849c, ${colorI 8}, ${colorI 0}, ${colorI 13}, ${colorI 5}, ${colorI 0}, ${colorI 15}, ${colorI 0}, ${colorI 5}, #807f849c
|
||||||
|
'';
|
||||||
|
systemd.user.sessionVariables = {
|
||||||
|
QT_QPA_PLATFORMTHEME = "qt5ct";
|
||||||
|
};
|
||||||
|
nixpkgs.overlays = [
|
||||||
|
(super: self: {
|
||||||
|
python3 = super.python.override {
|
||||||
|
packageOverrides = self: super: {
|
||||||
|
python3Packages = self.python3.pkgs;
|
||||||
|
catppuccin = super.catppuccin.overrideAttrs (super: {
|
||||||
|
patches =
|
||||||
|
super.patches
|
||||||
|
or []
|
||||||
|
++ [
|
||||||
|
(pkgs.writeText "color.patch" ''
|
||||||
|
diff --git a/catppuccin/colour.py b/catppuccin/colour.py
|
||||||
|
index 193eea7..7620cf0 100644
|
||||||
|
--- a/catppuccin/colour.py
|
||||||
|
+++ b/catppuccin/colour.py
|
||||||
|
@@ -43,6 +43,9 @@ class Colour:
|
||||||
|
@classmethod
|
||||||
|
def from_hex(cls, hex_string: str) -> Colour:
|
||||||
|
"""Create a colour from hex string."""
|
||||||
|
+ if hex_string.startswith("#"):
|
||||||
|
+ hex_string = hex_string[1:]
|
||||||
|
+
|
||||||
|
if len(hex_string) not in (6, 8):
|
||||||
|
raise ValueError("Hex string must be 6 or 8 characters long.")
|
||||||
|
diff --git a/catppuccin/flavour.py b/catppuccin/flavour.py
|
||||||
|
index aa7df98..4bf849a 100644
|
||||||
|
--- a/catppuccin/flavour.py
|
||||||
|
+++ b/catppuccin/flavour.py
|
||||||
|
@@ -138,30 +138,30 @@ class Flavour: # pylint: disable=too-many-instance-attributes
|
||||||
|
def mocha() -> "Flavour":
|
||||||
|
"""Mocha flavoured Catppuccin."""
|
||||||
|
return Flavour(
|
||||||
|
- rosewater=Colour(245, 224, 220),
|
||||||
|
- flamingo=Colour(242, 205, 205),
|
||||||
|
- pink=Colour(245, 194, 231),
|
||||||
|
- mauve=Colour(203, 166, 247),
|
||||||
|
- red=Colour(243, 139, 168),
|
||||||
|
- maroon=Colour(235, 160, 172),
|
||||||
|
- peach=Colour(250, 179, 135),
|
||||||
|
- yellow=Colour(249, 226, 175),
|
||||||
|
- green=Colour(166, 227, 161),
|
||||||
|
- teal=Colour(148, 226, 213),
|
||||||
|
- sky=Colour(137, 220, 235),
|
||||||
|
- sapphire=Colour(116, 199, 236),
|
||||||
|
- blue=Colour(137, 180, 250),
|
||||||
|
- lavender=Colour(180, 190, 254),
|
||||||
|
- text=Colour(205, 214, 244),
|
||||||
|
+ rosewater=Colour.from_hex("${color 1}"),
|
||||||
|
+ flamingo=Colour.from_hex("${color 2}"),
|
||||||
|
+ pink=Colour.from_hex("${color 3}"),
|
||||||
|
+ mauve=Colour.from_hex("${color 4}"),
|
||||||
|
+ red=Colour.from_hex("${color 5}"),
|
||||||
|
+ maroon=Colour.from_hex("${color 6}"),
|
||||||
|
+ peach=Colour.from_hex("${color 7}"),
|
||||||
|
+ yellow=Colour.from_hex("${color 8}"),
|
||||||
|
+ green=Colour.from_hex("${color 9}"),
|
||||||
|
+ teal=Colour.from_hex("${color 10}"),
|
||||||
|
+ sky=Colour.from_hex("${color 11}"),
|
||||||
|
+ sapphire=Colour.from_hex("${color 12}"),
|
||||||
|
+ blue=Colour.from_hex("${color 13}"),
|
||||||
|
+ lavender=Colour.from_hex("${color 14}"),
|
||||||
|
+ text=Colour.from_hex("${color 15}"),
|
||||||
|
subtext1=Colour(186, 194, 222),
|
||||||
|
subtext0=Colour(166, 173, 200),
|
||||||
|
overlay2=Colour(147, 153, 178),
|
||||||
|
overlay1=Colour(127, 132, 156),
|
||||||
|
overlay0=Colour(108, 112, 134),
|
||||||
|
- surface2=Colour(88, 91, 112),
|
||||||
|
- surface1=Colour(69, 71, 90),
|
||||||
|
- surface0=Colour(49, 50, 68),
|
||||||
|
- base=Colour(30, 30, 46),
|
||||||
|
- mantle=Colour(24, 24, 37),
|
||||||
|
- crust=Colour(17, 17, 27),
|
||||||
|
+ surface2=Colour.from_hex("${color 2}"),
|
||||||
|
+ surface1=Colour.from_hex("${color 1}"),
|
||||||
|
+ surface0=Colour.from_hex("${color 0}"),
|
||||||
|
+ base=Colour.from_hex("${color 0}"),
|
||||||
|
+ mantle=Colour.from_hex("${color 0}"),
|
||||||
|
+ crust=Colour.from_hex("${color 0}"),
|
||||||
|
)
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
})
|
||||||
|
];
|
||||||
|
|
||||||
|
home.file = {
|
||||||
|
".icons/default/index.theme".text = ''
|
||||||
|
[Icon Theme]
|
||||||
|
Name=Default
|
||||||
|
Comment=Default Cursor Theme
|
||||||
|
Inherits=Vanilla-DMZ
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
programs.kitty.settings = with theme; {
|
||||||
|
background = color 0;
|
||||||
|
foreground = color 15;
|
||||||
|
cursor = color 15;
|
||||||
|
selection_background = "#4f414c";
|
||||||
|
color0 = color 0;
|
||||||
|
color1 = color 9;
|
||||||
|
color2 = color 10;
|
||||||
|
color3 = color 11;
|
||||||
|
color4 = color 12;
|
||||||
|
color5 = color 13;
|
||||||
|
color6 = color 14;
|
||||||
|
color7 = color 7;
|
||||||
|
color8 = color 8;
|
||||||
|
color9 = color 9;
|
||||||
|
color10 = color 10;
|
||||||
|
color11 = color 11;
|
||||||
|
color12 = color 12;
|
||||||
|
color13 = color 13;
|
||||||
|
color14 = color 14;
|
||||||
|
color15 = color 15;
|
||||||
|
};
|
||||||
|
# Taken from https://github.com/jakehamilton/dotfiles/blob/master/waybar/style.css
|
||||||
|
programs.waybar.style = with theme; ''
|
||||||
|
* {
|
||||||
|
border: none;
|
||||||
|
border-radius: 0;
|
||||||
|
font-size: 14px;
|
||||||
|
min-height: 24px;
|
||||||
|
font-family: "NotoSansDisplay Nerd Font", "Noto Sans Mono CJK JP";
|
||||||
|
color: ${color 0};
|
||||||
|
}
|
||||||
|
window#waybar {
|
||||||
|
background: transparent;
|
||||||
|
color: ${color 15};
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
window#waybar.hidden {
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
#window {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 0px 16px 0px 16px;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: none;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
#workspaces {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
background-color: ${color 0};
|
||||||
|
color: ${color 15};
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
#workspaces button {
|
||||||
|
transition: none;
|
||||||
|
background: transparent;
|
||||||
|
font-size: 16px;
|
||||||
|
color: ${color 15};
|
||||||
|
}
|
||||||
|
#workspaces button.focused {
|
||||||
|
background: ${color 13};
|
||||||
|
color: ${color 0};
|
||||||
|
}
|
||||||
|
#workspaces button:hover {
|
||||||
|
background: ${color 10};
|
||||||
|
color: ${color 0};
|
||||||
|
}
|
||||||
|
#mpd {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
background: ${color 2};
|
||||||
|
transition: none;
|
||||||
|
}
|
||||||
|
#mpd.disconnected,
|
||||||
|
#mpd.stopped {
|
||||||
|
background: ${color 4};
|
||||||
|
}
|
||||||
|
#network {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: none;
|
||||||
|
background: ${color 13};
|
||||||
|
}
|
||||||
|
#pulseaudio {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: none;
|
||||||
|
background: ${color 11};
|
||||||
|
}
|
||||||
|
#temperature, #battery {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: none;
|
||||||
|
background: ${color 2};
|
||||||
|
}
|
||||||
|
#cpu, #backlight, #battery.warning {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: none;
|
||||||
|
background: ${color 14};
|
||||||
|
}
|
||||||
|
#memory, #battery.critical {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 24px;
|
||||||
|
transition: none;
|
||||||
|
background: ${color 12};
|
||||||
|
}
|
||||||
|
#clock {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 8px;
|
||||||
|
margin-right: 12px;
|
||||||
|
padding-left: 16px;
|
||||||
|
padding-right: 16px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
border-radius: 26px;
|
||||||
|
transition: none;
|
||||||
|
background: ${color 0};
|
||||||
|
color: ${color 15};
|
||||||
|
}
|
||||||
|
'';
|
||||||
|
|
||||||
|
wayland.windowManager.sway.extraConfig = with theme; ''
|
||||||
|
# target title bg text indicator border
|
||||||
|
client.focused ${color 5} ${color 0} ${color 15} ${color 12} ${color 5}
|
||||||
|
client.focused_inactive ${color 13} ${color 0} ${color 15} ${color 12} ${color 13}
|
||||||
|
client.unfocused ${color 13} ${color 0} ${color 15} ${color 12} ${color 13}
|
||||||
|
client.urgent ${color 14} ${color 0} ${color 14} ${color 8} ${color 14}
|
||||||
|
client.placeholder ${color 8} ${color 0} ${color 15} ${color 8} ${color 8}
|
||||||
|
client.background ${color 0}
|
||||||
|
seat seat0 xcursor_theme breeze-dark 24
|
||||||
|
'';
|
||||||
|
home.packages = with pkgs; [
|
||||||
|
libsForQt5.breeze-icons
|
||||||
|
libsForQt5.qt5ct
|
||||||
|
vanilla-dmz
|
||||||
|
pkgs.plasma5Packages.lightly
|
||||||
|
];
|
||||||
|
|
||||||
|
programs.rofi.theme = with theme; let
|
||||||
|
element = {
|
||||||
|
background-color = mkLiteral "inherit";
|
||||||
|
text-color = mkLiteral "inherit";
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
"*" = {
|
||||||
|
bg-col = color' 0;
|
||||||
|
bg-col-light = color' 0;
|
||||||
|
border-col = color' 0;
|
||||||
|
selected-col = color' 0;
|
||||||
|
blue = color' 1;
|
||||||
|
fg-col = color' 15;
|
||||||
|
fg-col2 = color' 12;
|
||||||
|
grey = color' 8;
|
||||||
|
width = 600;
|
||||||
|
};
|
||||||
|
element-text = element;
|
||||||
|
window = {
|
||||||
|
height = mkLiteral "360px";
|
||||||
|
border = mkLiteral "3px";
|
||||||
|
border-color = mkLiteral "@border-col";
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
};
|
||||||
|
mainbox = {
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
};
|
||||||
|
inputbar = {
|
||||||
|
children = map mkLiteral ["prompt" "entry"];
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
border-radius = mkLiteral "5px";
|
||||||
|
padding = mkLiteral "2px";
|
||||||
|
};
|
||||||
|
prompt = {
|
||||||
|
background-color = mkLiteral "@blue";
|
||||||
|
padding = mkLiteral "6px";
|
||||||
|
text-color = mkLiteral "@bg-col";
|
||||||
|
border-radius = mkLiteral "3px";
|
||||||
|
margin = mkLiteral "20px 0px 0px 20px";
|
||||||
|
};
|
||||||
|
|
||||||
|
textbox-prompt-colon = {
|
||||||
|
expand = mkLiteral "false";
|
||||||
|
str = ":";
|
||||||
|
};
|
||||||
|
|
||||||
|
entry = {
|
||||||
|
padding = mkLiteral "6px";
|
||||||
|
margin = mkLiteral "20px 0px 0px 10px";
|
||||||
|
text-color = mkLiteral "@fg-col";
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
};
|
||||||
|
|
||||||
|
listview = {
|
||||||
|
border = mkLiteral "0px 0px 0px";
|
||||||
|
padding = mkLiteral "6px 0px 0px";
|
||||||
|
margin = mkLiteral "10px 0px 0px 20px";
|
||||||
|
columns = 2;
|
||||||
|
lines = 5;
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
};
|
||||||
|
|
||||||
|
element = {
|
||||||
|
padding = mkLiteral "5px";
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
text-color = mkLiteral "@fg-col";
|
||||||
|
};
|
||||||
|
|
||||||
|
element-icon =
|
||||||
|
element
|
||||||
|
// {
|
||||||
|
size = mkLiteral "25px";
|
||||||
|
};
|
||||||
|
|
||||||
|
"element selected" = {
|
||||||
|
background-color = mkLiteral "@selected-col";
|
||||||
|
text-color = mkLiteral "@fg-col2";
|
||||||
|
};
|
||||||
|
|
||||||
|
mode-switcher =
|
||||||
|
element
|
||||||
|
// {
|
||||||
|
spacing = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
button = {
|
||||||
|
padding = mkLiteral "10px";
|
||||||
|
background-color = mkLiteral "@bg-col-light";
|
||||||
|
text-color = mkLiteral "@grey";
|
||||||
|
vertical-align = mkLiteral "0.5";
|
||||||
|
horizontal-align = mkLiteral "0.5";
|
||||||
|
};
|
||||||
|
|
||||||
|
"button selected" = {
|
||||||
|
background-color = mkLiteral "@bg-col";
|
||||||
|
text-color = mkLiteral "@blue";
|
||||||
|
};
|
||||||
|
|
||||||
|
message = {
|
||||||
|
background-color = mkLiteral "@bg-col-light";
|
||||||
|
margin = mkLiteral "2px";
|
||||||
|
padding = mkLiteral "2px";
|
||||||
|
border-radius = mkLiteral "5px";
|
||||||
|
};
|
||||||
|
|
||||||
|
textbox = {
|
||||||
|
padding = mkLiteral "6px";
|
||||||
|
margin = mkLiteral "20px 0px 0px 20px";
|
||||||
|
text-color = mkLiteral "@blue";
|
||||||
|
background-color = mkLiteral "@bg-col-light";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
programs.neomutt.extraConfig = ''
|
||||||
|
color normal default default # Text is "Text"
|
||||||
|
color index color2 default ~N # New Messages are Green
|
||||||
|
color index color1 default ~F # Flagged messages are Red
|
||||||
|
color index color13 default ~T # Tagged Messages are Red
|
||||||
|
color index color1 default ~D # Messages to delete are Red
|
||||||
|
color attachment color5 default # Attachments are Pink
|
||||||
|
color signature color8 default # Signatures are Surface 2
|
||||||
|
color search color4 default # Highlighted results are Blue
|
||||||
|
color indicator default color8 # currently highlighted message Surface 2=Background Text=Foreground
|
||||||
|
color error color1 default # error messages are Red
|
||||||
|
color status color15 default # status line "Subtext 0"
|
||||||
|
color tree color15 default # thread tree arrows Subtext 0
|
||||||
|
color tilde color15 default # blank line padding Subtext 0
|
||||||
|
color hdrdefault color13 default # default headers Pink
|
||||||
|
color header color13 default "^From:"
|
||||||
|
color header color13 default "^Subject:"
|
||||||
|
color quoted color15 default # Subtext 0
|
||||||
|
color quoted1 color7 default # Subtext 1
|
||||||
|
color quoted2 color8 default # Surface 2
|
||||||
|
color quoted3 color0 default # Surface 1
|
||||||
|
color quoted4 color0 default
|
||||||
|
color quoted5 color0 default
|
||||||
|
color body color2 default [\-\.+_a-zA-Z0-9]+@[\-\.a-zA-Z0-9]+ # email addresses Green
|
||||||
|
color body color2 default (https?|ftp)://[\-\.,/%~_:?&=\#a-zA-Z0-9]+ # URLs Green
|
||||||
|
color body color4 default (^|[[:space:]])\\*[^[:space:]]+\\*([[:space:]]|$) # *bold* text Blue
|
||||||
|
color body color4 default (^|[[:space:]])_[^[:space:]]+_([[:space:]]|$) # _underlined_ text Blue
|
||||||
|
color body color4 default (^|[[:space:]])/[^[:space:]]+/([[:space:]]|$) # /italic/ text Blue
|
||||||
|
color sidebar_flagged color1 default # Mailboxes with flagged mails are Red
|
||||||
|
color sidebar_new color10 default # Mailboxes with new mail are Green
|
||||||
|
'';
|
||||||
|
home.file.".local/share/mc/skins/catppuccin.ini".source = ../../extra/mc-catppuccin.ini;
|
||||||
|
programs.vscode.userSettings = {
|
||||||
|
"catppuccin.colorOverrides".all = {
|
||||||
|
rosewater = color 1;
|
||||||
|
flamingo = color 2;
|
||||||
|
pink = color 3;
|
||||||
|
mauve = color 4;
|
||||||
|
red = color 5;
|
||||||
|
maroon = color 6;
|
||||||
|
peach = color 7;
|
||||||
|
yellow = color 8;
|
||||||
|
green = color 9;
|
||||||
|
teal = color 10;
|
||||||
|
sky = color 11;
|
||||||
|
sapphire = color 12;
|
||||||
|
blue = color 13;
|
||||||
|
lavender = color 14;
|
||||||
|
text = color 15;
|
||||||
|
base = color 0;
|
||||||
|
surface0 = color 0;
|
||||||
|
surface1 = color 1;
|
||||||
|
surface2 = color 2;
|
||||||
|
mantle = color 0;
|
||||||
|
crust = color 0;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
systemd.user.services.transparency = {
|
||||||
|
Unit = {
|
||||||
|
Description = "transparency";
|
||||||
|
After = ["graphical-session-pre.target"];
|
||||||
|
PartOf = ["graphical-session.target"];
|
||||||
|
};
|
||||||
|
Install.WantedBy = ["graphical-session.target"];
|
||||||
|
Service = {
|
||||||
|
ExecStart = "${pkgs.python3.withPackages (ps: with ps; [i3ipc])}/bin/python ${./transparency.py}";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
{pkgs, ...}: {
|
|
||||||
output.plugins = with pkgs.vimPlugins; [indent-blankline-nvim];
|
|
||||||
plugin.setup.ibl = {
|
|
||||||
show_end_of_line = true;
|
|
||||||
char = "▏";
|
|
||||||
char_highlight_list = [
|
|
||||||
"CatppuccinRosewater"
|
|
||||||
"CatppuccinFlamingo"
|
|
||||||
"CatppuccinPink"
|
|
||||||
"CatppuccinMauve"
|
|
||||||
"CatppuccinRed"
|
|
||||||
"CatppuccinMaroon"
|
|
||||||
"CatppuccinPeach"
|
|
||||||
"CatppuccinYellow"
|
|
||||||
"CatppuccinGreen"
|
|
||||||
"CatppuccinTeal"
|
|
||||||
"CatppuccinSky"
|
|
||||||
"CatppuccinSapphire"
|
|
||||||
"CatppuccinBlue"
|
|
||||||
"CatppuccinLavender"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
131
config/programs/waybar.nix
Normal file
131
config/programs/waybar.nix
Normal file
|
@ -0,0 +1,131 @@
|
||||||
|
{pkgs, ...}: {
|
||||||
|
programs.waybar = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
main_bar = {
|
||||||
|
spacing = 4;
|
||||||
|
modules-left = [
|
||||||
|
"sway/workspaces"
|
||||||
|
"sway/mode"
|
||||||
|
];
|
||||||
|
modules-center = [
|
||||||
|
"sway/window"
|
||||||
|
];
|
||||||
|
modules-right = [
|
||||||
|
"mpd"
|
||||||
|
"idle_inhibitor"
|
||||||
|
"pulseaudio"
|
||||||
|
"network"
|
||||||
|
"cpu"
|
||||||
|
"memory"
|
||||||
|
"temperature"
|
||||||
|
"backlight"
|
||||||
|
"battery"
|
||||||
|
"battery#bat2"
|
||||||
|
"clock"
|
||||||
|
"tray"
|
||||||
|
];
|
||||||
|
keyboard-state = {
|
||||||
|
numlock = true;
|
||||||
|
capslock = true;
|
||||||
|
format = "{name} {icon}";
|
||||||
|
};
|
||||||
|
"sway/mode" = {
|
||||||
|
format = "{}";
|
||||||
|
};
|
||||||
|
mpd = {
|
||||||
|
format = "{stateIcon} {artist} - {album} - {title} ({elapsedTime:%M:%S}/{totalTime:%M:%S})";
|
||||||
|
format-disconnected = "ﳌ";
|
||||||
|
format-stopped = "";
|
||||||
|
unknown-tag = "N/A";
|
||||||
|
interval = 2;
|
||||||
|
consume-icons = {
|
||||||
|
on = " ";
|
||||||
|
};
|
||||||
|
random-icons = {
|
||||||
|
off = "<span color=\"#f53c3c\"></span> ";
|
||||||
|
on = " ";
|
||||||
|
};
|
||||||
|
repeat-icons = {
|
||||||
|
on = " ";
|
||||||
|
};
|
||||||
|
single-icons = {
|
||||||
|
on = "1 ";
|
||||||
|
};
|
||||||
|
state-icons = {
|
||||||
|
paused = "";
|
||||||
|
playing = "";
|
||||||
|
};
|
||||||
|
tooltip-format = "MPD (connected)";
|
||||||
|
tooltip-format-disconnected = "MPD (disconnected)";
|
||||||
|
on-click = "${pkgs.mpc-cli}/bin/mpc toggle";
|
||||||
|
on-click-middle = "${pkgs.kitty}/bin/kitty ${pkgs.ncmpcpp}/bin/ncmpcpp";
|
||||||
|
on-click-right = "${pkgs.mpc-cli}/bin/mpc stop";
|
||||||
|
on-scroll-up = "${pkgs.mpc-cli}/bin/mpc seekthrough +00:00:01";
|
||||||
|
on-scroll-down = "${pkgs.mpc-cli}/bin/mpc seekthrough -00:00:01";
|
||||||
|
};
|
||||||
|
idle_inhibitor = {
|
||||||
|
format = "{icon}";
|
||||||
|
format-icons = {
|
||||||
|
activated = "";
|
||||||
|
deactivated = "";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
tray = {
|
||||||
|
spacing = 10;
|
||||||
|
};
|
||||||
|
clock = {
|
||||||
|
tooltip-format = "<big>{:%Y %B}</big>\n<tt><small>{calendar}</small></tt>";
|
||||||
|
format = "{:%H:%M}";
|
||||||
|
};
|
||||||
|
cpu = {
|
||||||
|
format = "{usage}% ";
|
||||||
|
tooltip = false;
|
||||||
|
};
|
||||||
|
memory = {
|
||||||
|
format = "{}% ";
|
||||||
|
};
|
||||||
|
temperature = {
|
||||||
|
critical-threshold = 80;
|
||||||
|
format = "{temperatureC}℃ {icon}";
|
||||||
|
format-icons = ["" "" ""];
|
||||||
|
};
|
||||||
|
backlight = {
|
||||||
|
format = "{percent}% {icon}";
|
||||||
|
format-icons = ["" ""];
|
||||||
|
};
|
||||||
|
battery = {
|
||||||
|
states = {
|
||||||
|
warning = 30;
|
||||||
|
critical = 15;
|
||||||
|
};
|
||||||
|
format = "{capacity}% {icon}";
|
||||||
|
format-charging = "{capacity}% ";
|
||||||
|
format-plugged = "{capacity}% ";
|
||||||
|
format-alt = "{time} {icon}";
|
||||||
|
format-icons = ["" "" "" "" ""];
|
||||||
|
};
|
||||||
|
"battery#bat2" = {
|
||||||
|
bat = "BAT2";
|
||||||
|
};
|
||||||
|
network = {
|
||||||
|
format-wifi = " {essid} {ipaddr}";
|
||||||
|
format-ethernet = " {ipaddr}";
|
||||||
|
};
|
||||||
|
pulseaudio = {
|
||||||
|
format = "{icon} {volume}%";
|
||||||
|
format-icons = {
|
||||||
|
headphone = "";
|
||||||
|
hands-free = "";
|
||||||
|
headset = "";
|
||||||
|
phone = "";
|
||||||
|
portable = "";
|
||||||
|
car = "";
|
||||||
|
default = ["" "" ""];
|
||||||
|
};
|
||||||
|
on-click = "${pkgs.pavucontrol}/bin/pavucontrol";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -7,6 +7,14 @@ desktop: _: {
|
||||||
syntaxHighlighting.enable = true;
|
syntaxHighlighting.enable = true;
|
||||||
enableVteIntegration = desktop;
|
enableVteIntegration = desktop;
|
||||||
autocd = true;
|
autocd = true;
|
||||||
|
loginExtra =
|
||||||
|
if desktop
|
||||||
|
then ''
|
||||||
|
if [[ -z "$DISPLAY" ]] && [[ $(tty) = "/dev/tty1" ]]; then
|
||||||
|
exec sway
|
||||||
|
fi
|
||||||
|
''
|
||||||
|
else "";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,14 +38,14 @@
|
||||||
type = "measure";
|
type = "measure";
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
child = {
|
child = {
|
||||||
compression = "none";
|
compression = "none";
|
||||||
path = "datastore";
|
path = "datastore";
|
||||||
type = "levelds";
|
type = "levelds";
|
||||||
};
|
};
|
||||||
mountpoint = "/";
|
mountpoint = "/";
|
||||||
prefix = "leveldb.datastore";
|
prefix = "leveldb.datastore";
|
||||||
type = "measure";
|
type = "measure";
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
type = "mount";
|
type = "mount";
|
||||||
|
|
49
flake.lock
49
flake.lock
|
@ -78,6 +78,32 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"colorpickle": {
|
||||||
|
"inputs": {
|
||||||
|
"naersk": [
|
||||||
|
"naersk"
|
||||||
|
],
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"utils": [
|
||||||
|
"flake-utils"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1696800008,
|
||||||
|
"narHash": "sha256-dQ2Xf1K5qH18J7h3pzx4ffp6n1nwN+2L8jv6OBXPLzQ=",
|
||||||
|
"owner": "AgathaSorceress",
|
||||||
|
"repo": "colorpickle",
|
||||||
|
"rev": "a1a21aebbc9b9716136ab9cc6f77bf5346f8e7ba",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "AgathaSorceress",
|
||||||
|
"repo": "colorpickle",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"dns": {
|
"dns": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": [
|
"flake-utils": [
|
||||||
|
@ -675,6 +701,27 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"naersk": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1698420672,
|
||||||
|
"narHash": "sha256-/TdeHMPRjjdJub7p7+w55vyABrsJlt5QkznPYy55vKA=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "naersk",
|
||||||
|
"rev": "aeb58d5e8faead8980a807c840232697982d47b9",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "master",
|
||||||
|
"repo": "naersk",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nix": {
|
"nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"lowdown-src": "lowdown-src",
|
"lowdown-src": "lowdown-src",
|
||||||
|
@ -1066,6 +1113,7 @@
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"chir-rs": "chir-rs",
|
"chir-rs": "chir-rs",
|
||||||
|
"colorpickle": "colorpickle",
|
||||||
"dns": "dns",
|
"dns": "dns",
|
||||||
"firefox": "firefox",
|
"firefox": "firefox",
|
||||||
"flake-compat": "flake-compat",
|
"flake-compat": "flake-compat",
|
||||||
|
@ -1075,6 +1123,7 @@
|
||||||
"home-manager": "home-manager",
|
"home-manager": "home-manager",
|
||||||
"lib-aggregate": "lib-aggregate",
|
"lib-aggregate": "lib-aggregate",
|
||||||
"mozilla": "mozilla",
|
"mozilla": "mozilla",
|
||||||
|
"naersk": "naersk",
|
||||||
"nix-gaming": "nix-gaming",
|
"nix-gaming": "nix-gaming",
|
||||||
"nix-neovim": "nix-neovim",
|
"nix-neovim": "nix-neovim",
|
||||||
"nix-packages": "nix-packages",
|
"nix-packages": "nix-packages",
|
||||||
|
|
10
flake.nix
10
flake.nix
|
@ -13,6 +13,12 @@ rec {
|
||||||
inputs.systems.follows = "systems";
|
inputs.systems.follows = "systems";
|
||||||
inputs.treefmt-nix.follows = "treefmt-nix";
|
inputs.treefmt-nix.follows = "treefmt-nix";
|
||||||
};
|
};
|
||||||
|
colorpickle = {
|
||||||
|
url = "github:AgathaSorceress/colorpickle";
|
||||||
|
inputs.naersk.follows = "naersk";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
inputs.utils.follows = "flake-utils";
|
||||||
|
};
|
||||||
dns = {
|
dns = {
|
||||||
url = "github:DarkKirb/dns.nix";
|
url = "github:DarkKirb/dns.nix";
|
||||||
inputs.flake-utils.follows = "flake-utils";
|
inputs.flake-utils.follows = "flake-utils";
|
||||||
|
@ -49,6 +55,10 @@ rec {
|
||||||
inputs.nixpkgs-lib.follows = "nixpkgs";
|
inputs.nixpkgs-lib.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
mozilla.url = "github:mozilla/nixpkgs-mozilla";
|
mozilla.url = "github:mozilla/nixpkgs-mozilla";
|
||||||
|
naersk = {
|
||||||
|
url = "github:nix-community/naersk/master";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
nix-gaming = {
|
nix-gaming = {
|
||||||
url = "github:fufexan/nix-gaming";
|
url = "github:fufexan/nix-gaming";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
|
|
@ -1,768 +0,0 @@
|
||||||
{
|
|
||||||
config,
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}: let
|
|
||||||
cfg = config.services.mastodon;
|
|
||||||
# We only want to create a database if we're actually going to connect to it.
|
|
||||||
databaseActuallyCreateLocally = cfg.database.createLocally && cfg.database.host == "/run/postgresql";
|
|
||||||
|
|
||||||
env =
|
|
||||||
{
|
|
||||||
RAILS_ENV = "production";
|
|
||||||
NODE_ENV = "production";
|
|
||||||
|
|
||||||
LD_PRELOAD = "${pkgs.jemalloc}/lib/libjemalloc.so";
|
|
||||||
|
|
||||||
# mastodon-web concurrency.
|
|
||||||
WEB_CONCURRENCY = toString cfg.webProcesses;
|
|
||||||
MAX_THREADS = toString cfg.webThreads;
|
|
||||||
|
|
||||||
# mastodon-streaming concurrency.
|
|
||||||
STREAMING_CLUSTER_NUM = toString cfg.streamingProcesses;
|
|
||||||
|
|
||||||
DB_USER = cfg.database.user;
|
|
||||||
|
|
||||||
REDIS_HOST = cfg.redis.host;
|
|
||||||
REDIS_PORT = toString cfg.redis.port;
|
|
||||||
DB_HOST = cfg.database.host;
|
|
||||||
DB_PORT = toString cfg.database.port;
|
|
||||||
DB_NAME = cfg.database.name;
|
|
||||||
LOCAL_DOMAIN = cfg.localDomain;
|
|
||||||
SMTP_SERVER = cfg.smtp.host;
|
|
||||||
SMTP_PORT = toString cfg.smtp.port;
|
|
||||||
SMTP_FROM_ADDRESS = cfg.smtp.fromAddress;
|
|
||||||
PAPERCLIP_ROOT_PATH = "/var/lib/mastodon/public-system";
|
|
||||||
PAPERCLIP_ROOT_URL = "/system";
|
|
||||||
ES_ENABLED =
|
|
||||||
if (cfg.elasticsearch.host != null)
|
|
||||||
then "true"
|
|
||||||
else "false";
|
|
||||||
ES_HOST = cfg.elasticsearch.host;
|
|
||||||
ES_PORT = toString cfg.elasticsearch.port;
|
|
||||||
|
|
||||||
TRUSTED_PROXY_IP = cfg.trustedProxy;
|
|
||||||
}
|
|
||||||
// (
|
|
||||||
if cfg.smtp.authenticate
|
|
||||||
then {SMTP_LOGIN = cfg.smtp.user;}
|
|
||||||
else {}
|
|
||||||
)
|
|
||||||
// cfg.extraConfig;
|
|
||||||
|
|
||||||
systemCallsList = ["@cpu-emulation" "@debug" "@keyring" "@ipc" "@mount" "@obsolete" "@privileged" "@setuid"];
|
|
||||||
|
|
||||||
cfgService = {
|
|
||||||
# User and group
|
|
||||||
User = cfg.user;
|
|
||||||
Group = cfg.group;
|
|
||||||
# State directory and mode
|
|
||||||
StateDirectory = "mastodon";
|
|
||||||
StateDirectoryMode = "0750";
|
|
||||||
# Logs directory and mode
|
|
||||||
LogsDirectory = "mastodon";
|
|
||||||
LogsDirectoryMode = "0750";
|
|
||||||
# Proc filesystem
|
|
||||||
ProcSubset = "pid";
|
|
||||||
ProtectProc = "invisible";
|
|
||||||
# Access write directories
|
|
||||||
UMask = "0027";
|
|
||||||
# Capabilities
|
|
||||||
CapabilityBoundingSet = "";
|
|
||||||
# Security
|
|
||||||
NoNewPrivileges = true;
|
|
||||||
# Sandboxing
|
|
||||||
ProtectSystem = "strict";
|
|
||||||
ProtectHome = true;
|
|
||||||
PrivateTmp = true;
|
|
||||||
PrivateDevices = true;
|
|
||||||
PrivateUsers = true;
|
|
||||||
ProtectClock = true;
|
|
||||||
ProtectHostname = true;
|
|
||||||
ProtectKernelLogs = true;
|
|
||||||
ProtectKernelModules = true;
|
|
||||||
ProtectKernelTunables = true;
|
|
||||||
ProtectControlGroups = true;
|
|
||||||
RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6" "AF_NETLINK"];
|
|
||||||
RestrictNamespaces = true;
|
|
||||||
LockPersonality = true;
|
|
||||||
MemoryDenyWriteExecute = false;
|
|
||||||
RestrictRealtime = true;
|
|
||||||
RestrictSUIDSGID = true;
|
|
||||||
RemoveIPC = true;
|
|
||||||
PrivateMounts = true;
|
|
||||||
# System Call Filtering
|
|
||||||
SystemCallArchitectures = "native";
|
|
||||||
};
|
|
||||||
|
|
||||||
envFile = pkgs.writeText "mastodon.env" (lib.concatMapStrings (s: s + "\n") (lib.concatLists (lib.mapAttrsToList
|
|
||||||
(
|
|
||||||
name: value:
|
|
||||||
if value != null
|
|
||||||
then [
|
|
||||||
"${name}=\"${toString value}\""
|
|
||||||
]
|
|
||||||
else []
|
|
||||||
)
|
|
||||||
env)));
|
|
||||||
|
|
||||||
mastodonEnv = pkgs.writeShellScriptBin "mastodon-env" ''
|
|
||||||
set -a
|
|
||||||
export RAILS_ROOT="${cfg.package}"
|
|
||||||
source "${envFile}"
|
|
||||||
source /var/lib/mastodon/.secrets_env
|
|
||||||
eval -- "\$@"
|
|
||||||
'';
|
|
||||||
in {
|
|
||||||
options = {
|
|
||||||
services.mastodon = {
|
|
||||||
enable = lib.mkEnableOption "Mastodon, a federated social network server";
|
|
||||||
|
|
||||||
configureNginx = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Configure nginx as a reverse proxy for mastodon.
|
|
||||||
Note that this makes some assumptions on your setup, and sets settings that will
|
|
||||||
affect other virtualHosts running on your nginx instance, if any.
|
|
||||||
Alternatively you can configure a reverse-proxy of your choice to serve these paths:
|
|
||||||
|
|
||||||
<code>/ -> $(nix-instantiate --eval '<nixpkgs>' -A mastodon.outPath)/public</code>
|
|
||||||
|
|
||||||
<code>/ -> 127.0.0.1:{{ webPort }} </code>(If there was no file in the directory above.)
|
|
||||||
|
|
||||||
<code>/system/ -> /var/lib/mastodon/public-system/</code>
|
|
||||||
|
|
||||||
<code>/api/v1/streaming/ -> 127.0.0.1:{{ streamingPort }}</code>
|
|
||||||
|
|
||||||
Make sure that websockets are forwarded properly. You might want to set up caching
|
|
||||||
of some requests. Take a look at mastodon's provided nginx configuration at
|
|
||||||
<code>https://github.com/mastodon/mastodon/blob/master/dist/nginx.conf</code>.
|
|
||||||
'';
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
user = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
User under which mastodon runs. If it is set to "mastodon",
|
|
||||||
that user will be created, otherwise it should be set to the
|
|
||||||
name of a user created elsewhere. In both cases,
|
|
||||||
<package>mastodon</package> and a package containing only
|
|
||||||
the shell script <code>mastodon-env</code> will be added to
|
|
||||||
the user's package set. To run a command from
|
|
||||||
<package>mastodon</package> such as <code>tootctl</code>
|
|
||||||
with the environment configured by this module use
|
|
||||||
<code>mastodon-env</code>, as in:
|
|
||||||
|
|
||||||
<code>mastodon-env tootctl accounts create newuser --email newuser@example.com</code>
|
|
||||||
'';
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "mastodon";
|
|
||||||
};
|
|
||||||
|
|
||||||
group = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Group under which mastodon runs.
|
|
||||||
'';
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "mastodon";
|
|
||||||
};
|
|
||||||
|
|
||||||
streamingPort = lib.mkOption {
|
|
||||||
description = "TCP port used by the mastodon-streaming service.";
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 55000;
|
|
||||||
};
|
|
||||||
streamingProcesses = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Processes used by the mastodon-streaming service.
|
|
||||||
Defaults to the number of CPU cores minus one.
|
|
||||||
'';
|
|
||||||
type = lib.types.nullOr lib.types.int;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
webPort = lib.mkOption {
|
|
||||||
description = "TCP port used by the mastodon-web service.";
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 55001;
|
|
||||||
};
|
|
||||||
webProcesses = lib.mkOption {
|
|
||||||
description = "Processes used by the mastodon-web service.";
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 2;
|
|
||||||
};
|
|
||||||
webThreads = lib.mkOption {
|
|
||||||
description = "Threads per process used by the mastodon-web service.";
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 5;
|
|
||||||
};
|
|
||||||
|
|
||||||
sidekiqPort = lib.mkOption {
|
|
||||||
description = "TCP port used by the mastodon-sidekiq service.";
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 55002;
|
|
||||||
};
|
|
||||||
sidekiqThreads = lib.mkOption {
|
|
||||||
description = "Worker threads used by the mastodon-sidekiq service.";
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 25;
|
|
||||||
};
|
|
||||||
|
|
||||||
vapidPublicKeyFile = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Path to file containing the public key used for Web Push
|
|
||||||
Voluntary Application Server Identification. A new keypair can
|
|
||||||
be generated by running:
|
|
||||||
|
|
||||||
<code>nix build -f '<nixpkgs>' mastodon; cd result; bin/rake webpush:generate_keys</code>
|
|
||||||
|
|
||||||
If <option>mastodon.vapidPrivateKeyFile</option>does not
|
|
||||||
exist, it and this file will be created with a new keypair.
|
|
||||||
'';
|
|
||||||
default = "/var/lib/mastodon/secrets/vapid-public-key";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
localDomain = lib.mkOption {
|
|
||||||
description = "The domain serving your Mastodon instance.";
|
|
||||||
example = "social.example.org";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
secretKeyBaseFile = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Path to file containing the secret key base.
|
|
||||||
A new secret key base can be generated by running:
|
|
||||||
|
|
||||||
<code>nix build -f '<nixpkgs>' mastodon; cd result; bin/rake secret</code>
|
|
||||||
|
|
||||||
If this file does not exist, it will be created with a new secret key base.
|
|
||||||
'';
|
|
||||||
default = "/var/lib/mastodon/secrets/secret-key-base";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
otpSecretFile = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Path to file containing the OTP secret.
|
|
||||||
A new OTP secret can be generated by running:
|
|
||||||
|
|
||||||
<code>nix build -f '<nixpkgs>' mastodon; cd result; bin/rake secret</code>
|
|
||||||
|
|
||||||
If this file does not exist, it will be created with a new OTP secret.
|
|
||||||
'';
|
|
||||||
default = "/var/lib/mastodon/secrets/otp-secret";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
vapidPrivateKeyFile = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Path to file containing the private key used for Web Push
|
|
||||||
Voluntary Application Server Identification. A new keypair can
|
|
||||||
be generated by running:
|
|
||||||
|
|
||||||
<code>nix build -f '<nixpkgs>' mastodon; cd result; bin/rake webpush:generate_keys</code>
|
|
||||||
|
|
||||||
If this file does not exist, it will be created with a new
|
|
||||||
private key.
|
|
||||||
'';
|
|
||||||
default = "/var/lib/mastodon/secrets/vapid-private-key";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
s3AccessKeyIdFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
s3SecretAccessKeyFile = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
trustedProxy = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
You need to set it to the IP from which your reverse proxy sends requests to Mastodon's web process,
|
|
||||||
otherwise Mastodon will record the reverse proxy's own IP as the IP of all requests, which would be
|
|
||||||
bad because IP addresses are used for important rate limits and security functions.
|
|
||||||
'';
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
enableUnixSocket = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Instead of binding to an IP address like 127.0.0.1, you may bind to a Unix socket. This variable
|
|
||||||
is process-specific, e.g. you need different values for every process, and it works for both web (Puma)
|
|
||||||
processes and streaming API (Node.js) processes.
|
|
||||||
'';
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
redis = {
|
|
||||||
createLocally = lib.mkOption {
|
|
||||||
description = "Configure local Redis server for Mastodon.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
host = lib.mkOption {
|
|
||||||
description = "Redis host.";
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Redis port.";
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 6379;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
database = {
|
|
||||||
createLocally = lib.mkOption {
|
|
||||||
description = "Configure local PostgreSQL database server for Mastodon.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
host = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "/run/postgresql";
|
|
||||||
example = "192.168.23.42";
|
|
||||||
description = "Database host address or unix socket.";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
type = lib.types.int;
|
|
||||||
default = 5432;
|
|
||||||
description = "Database host port.";
|
|
||||||
};
|
|
||||||
|
|
||||||
name = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "mastodon";
|
|
||||||
description = "Database name.";
|
|
||||||
};
|
|
||||||
|
|
||||||
user = lib.mkOption {
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "mastodon";
|
|
||||||
description = "Database user.";
|
|
||||||
};
|
|
||||||
|
|
||||||
passwordFile = lib.mkOption {
|
|
||||||
type = lib.types.nullOr lib.types.path;
|
|
||||||
default = "/var/lib/mastodon/secrets/db-password";
|
|
||||||
example = "/run/keys/mastodon-db-password";
|
|
||||||
description = ''
|
|
||||||
A file containing the password corresponding to
|
|
||||||
<option>database.user</option>.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
smtp = {
|
|
||||||
createLocally = lib.mkOption {
|
|
||||||
description = "Configure local Postfix SMTP server for Mastodon.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
authenticate = lib.mkOption {
|
|
||||||
description = "Authenticate with the SMTP server using username and password.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
host = lib.mkOption {
|
|
||||||
description = "SMTP host used when sending emails to users.";
|
|
||||||
type = lib.types.str;
|
|
||||||
default = "127.0.0.1";
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "SMTP port used when sending emails to users.";
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 25;
|
|
||||||
};
|
|
||||||
|
|
||||||
fromAddress = lib.mkOption {
|
|
||||||
description = ''"From" address used when sending Emails to users.'';
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
user = lib.mkOption {
|
|
||||||
description = "SMTP login name.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
|
|
||||||
passwordFile = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Path to file containing the SMTP password.
|
|
||||||
'';
|
|
||||||
default = "/var/lib/mastodon/secrets/smtp-password";
|
|
||||||
example = "/run/keys/mastodon-smtp-password";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
elasticsearch = {
|
|
||||||
host = lib.mkOption {
|
|
||||||
description = ''
|
|
||||||
Elasticsearch host.
|
|
||||||
If it is not null, Elasticsearch full text search will be enabled.
|
|
||||||
'';
|
|
||||||
type = lib.types.nullOr lib.types.str;
|
|
||||||
default = null;
|
|
||||||
};
|
|
||||||
|
|
||||||
port = lib.mkOption {
|
|
||||||
description = "Elasticsearch port.";
|
|
||||||
type = lib.types.port;
|
|
||||||
default = 9200;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
package = lib.mkOption {
|
|
||||||
type = lib.types.package;
|
|
||||||
default = pkgs.mastodon;
|
|
||||||
defaultText = lib.literalExpression "pkgs.mastodon";
|
|
||||||
description = "Mastodon package to use.";
|
|
||||||
};
|
|
||||||
|
|
||||||
extraConfig = lib.mkOption {
|
|
||||||
type = lib.types.attrs;
|
|
||||||
default = {};
|
|
||||||
description = ''
|
|
||||||
Extra environment variables to pass to all mastodon services.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
|
|
||||||
automaticMigrations = lib.mkOption {
|
|
||||||
type = lib.types.bool;
|
|
||||||
default = true;
|
|
||||||
description = ''
|
|
||||||
Do automatic database migrations.
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
disabledModules = ["services/web-apps/mastodon.nix"];
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
assertions = [
|
|
||||||
{
|
|
||||||
assertion = databaseActuallyCreateLocally -> (cfg.user == cfg.database.user);
|
|
||||||
message = ''For local automatic database provisioning (services.mastodon.database.createLocally == true) with peer authentication (services.mastodon.database.host == "/run/postgresql") to work services.mastodon.user and services.mastodon.database.user must be identical.'';
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
systemd.services.mastodon-init-dirs = {
|
|
||||||
script =
|
|
||||||
''
|
|
||||||
umask 077
|
|
||||||
|
|
||||||
if ! test -f ${cfg.secretKeyBaseFile}; then
|
|
||||||
mkdir -p $(dirname ${cfg.secretKeyBaseFile})
|
|
||||||
bin/rake secret > ${cfg.secretKeyBaseFile}
|
|
||||||
fi
|
|
||||||
if ! test -f ${cfg.otpSecretFile}; then
|
|
||||||
mkdir -p $(dirname ${cfg.otpSecretFile})
|
|
||||||
bin/rake secret > ${cfg.otpSecretFile}
|
|
||||||
fi
|
|
||||||
if ! test -f ${cfg.vapidPrivateKeyFile}; then
|
|
||||||
mkdir -p $(dirname ${cfg.vapidPrivateKeyFile}) $(dirname ${cfg.vapidPublicKeyFile})
|
|
||||||
keypair=$(bin/rake webpush:generate_keys)
|
|
||||||
echo $keypair | grep --only-matching "Private -> [^ ]\+" | sed 's/^Private -> //' > ${cfg.vapidPrivateKeyFile}
|
|
||||||
echo $keypair | grep --only-matching "Public -> [^ ]\+" | sed 's/^Public -> //' > ${cfg.vapidPublicKeyFile}
|
|
||||||
fi
|
|
||||||
|
|
||||||
cat > /var/lib/mastodon/.secrets_env <<EOF
|
|
||||||
SECRET_KEY_BASE="$(cat ${cfg.secretKeyBaseFile})"
|
|
||||||
OTP_SECRET="$(cat ${cfg.otpSecretFile})"
|
|
||||||
VAPID_PRIVATE_KEY="$(cat ${cfg.vapidPrivateKeyFile})"
|
|
||||||
VAPID_PUBLIC_KEY="$(cat ${cfg.vapidPublicKeyFile})"
|
|
||||||
DB_PASS="$(cat ${cfg.database.passwordFile})"
|
|
||||||
AWS_ACCESS_KEY_ID="$(cat ${cfg.s3AccessKeyIdFile})"
|
|
||||||
AWS_SECRET_ACCESS_KEY="$(cat ${cfg.s3SecretAccessKeyFile})"
|
|
||||||
''
|
|
||||||
+ (
|
|
||||||
if cfg.smtp.authenticate
|
|
||||||
then ''
|
|
||||||
SMTP_PASSWORD="$(cat ${cfg.smtp.passwordFile})"
|
|
||||||
''
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
+ ''
|
|
||||||
EOF
|
|
||||||
'';
|
|
||||||
environment = env;
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
Type = "oneshot";
|
|
||||||
WorkingDirectory = cfg.package;
|
|
||||||
# System Call Filtering
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " (systemCallsList ++ ["@resources"])) "@chown" "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
|
|
||||||
after = ["network.target"];
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.mastodon-init-db = lib.mkIf cfg.automaticMigrations {
|
|
||||||
script = ''
|
|
||||||
if [ `psql ${cfg.database.name} -c \
|
|
||||||
"select count(*) from pg_class c \
|
|
||||||
join pg_namespace s on s.oid = c.relnamespace \
|
|
||||||
where s.nspname not in ('pg_catalog', 'pg_toast', 'information_schema') \
|
|
||||||
and s.nspname not like 'pg_temp%';" | sed -n 3p` -eq 0 ]; then
|
|
||||||
SAFETY_ASSURED=1 rails db:schema:load
|
|
||||||
rails db:seed
|
|
||||||
else
|
|
||||||
rails db:migrate
|
|
||||||
fi
|
|
||||||
'';
|
|
||||||
path = [cfg.package pkgs.postgresql];
|
|
||||||
environment = env;
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
Type = "oneshot";
|
|
||||||
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
|
|
||||||
WorkingDirectory = cfg.package;
|
|
||||||
# System Call Filtering
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " (systemCallsList ++ ["@resources"])) "@chown" "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
after =
|
|
||||||
["mastodon-init-dirs.service" "network.target"]
|
|
||||||
++ (
|
|
||||||
if databaseActuallyCreateLocally
|
|
||||||
then ["postgresql.service"]
|
|
||||||
else []
|
|
||||||
);
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.mastodon-streaming = {
|
|
||||||
after =
|
|
||||||
["network.target"]
|
|
||||||
++ (
|
|
||||||
if databaseActuallyCreateLocally
|
|
||||||
then ["postgresql.service"]
|
|
||||||
else []
|
|
||||||
)
|
|
||||||
++ (
|
|
||||||
if cfg.automaticMigrations
|
|
||||||
then ["mastodon-init-db.service"]
|
|
||||||
else ["mastodon-init-dirs.service"]
|
|
||||||
);
|
|
||||||
description = "Mastodon streaming";
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
environment =
|
|
||||||
env
|
|
||||||
// (
|
|
||||||
if cfg.enableUnixSocket
|
|
||||||
then {SOCKET = "/run/mastodon-streaming/streaming.socket";}
|
|
||||||
else {PORT = toString cfg.streamingPort;}
|
|
||||||
);
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
ExecStart = "${cfg.package}/run-streaming.sh";
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = 20;
|
|
||||||
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
|
|
||||||
WorkingDirectory = cfg.package;
|
|
||||||
# Runtime directory and mode
|
|
||||||
RuntimeDirectory = "mastodon-streaming";
|
|
||||||
RuntimeDirectoryMode = "0750";
|
|
||||||
# System Call Filtering
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " (systemCallsList ++ ["@memlock" "@resources"])) "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.mastodon-web = {
|
|
||||||
after =
|
|
||||||
["network.target"]
|
|
||||||
++ (
|
|
||||||
if databaseActuallyCreateLocally
|
|
||||||
then ["postgresql.service"]
|
|
||||||
else []
|
|
||||||
)
|
|
||||||
++ (
|
|
||||||
if cfg.automaticMigrations
|
|
||||||
then ["mastodon-init-db.service"]
|
|
||||||
else ["mastodon-init-dirs.service"]
|
|
||||||
);
|
|
||||||
description = "Mastodon web";
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
environment =
|
|
||||||
env
|
|
||||||
// (
|
|
||||||
if cfg.enableUnixSocket
|
|
||||||
then {SOCKET = "/run/mastodon-web/web.socket";}
|
|
||||||
else {PORT = toString cfg.webPort;}
|
|
||||||
);
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
ExecStart = "${cfg.package}/bin/puma -C config/puma.rb";
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = 20;
|
|
||||||
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
|
|
||||||
WorkingDirectory = cfg.package;
|
|
||||||
# Runtime directory and mode
|
|
||||||
RuntimeDirectory = "mastodon-web";
|
|
||||||
RuntimeDirectoryMode = "0750";
|
|
||||||
# System Call Filtering
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
path = with pkgs; [file imagemagick ffmpeg];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.mastodon-sidekiq = {
|
|
||||||
after =
|
|
||||||
["network.target"]
|
|
||||||
++ (
|
|
||||||
if databaseActuallyCreateLocally
|
|
||||||
then ["postgresql.service"]
|
|
||||||
else []
|
|
||||||
)
|
|
||||||
++ (
|
|
||||||
if cfg.automaticMigrations
|
|
||||||
then ["mastodon-init-db.service"]
|
|
||||||
else ["mastodon-init-dirs.service"]
|
|
||||||
);
|
|
||||||
description = "Mastodon sidekiq";
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
environment =
|
|
||||||
env
|
|
||||||
// {
|
|
||||||
PORT = toString cfg.sidekiqPort;
|
|
||||||
DB_POOL = toString cfg.sidekiqThreads;
|
|
||||||
};
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
ExecStart = "${cfg.package}/bin/sidekiq -c ${toString cfg.sidekiqThreads} -r ${cfg.package}";
|
|
||||||
Restart = "always";
|
|
||||||
RestartSec = 20;
|
|
||||||
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
|
|
||||||
WorkingDirectory = cfg.package;
|
|
||||||
# System Call Filtering
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
path = with pkgs; [file imagemagick ffmpeg];
|
|
||||||
};
|
|
||||||
|
|
||||||
systemd.services.mastodon-clean-media = {
|
|
||||||
description = "Clean mastodon remote media";
|
|
||||||
environment = env;
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
ExecStart = "${cfg.package}/bin/tootctl media remove";
|
|
||||||
Type = "oneshot";
|
|
||||||
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
path = with pkgs; [file imagemagick ffmpeg];
|
|
||||||
};
|
|
||||||
systemd.timers.mastodon-clean-media = {
|
|
||||||
description = "Clean mastodon remote media";
|
|
||||||
requires = ["mastodon-clean-media.service"];
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
timerConfig = {
|
|
||||||
OnUnitActiveSec = 604800;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
systemd.services.mastodon-clean-preview-cards = {
|
|
||||||
description = "Clean mastodon preview cards";
|
|
||||||
environment = env;
|
|
||||||
serviceConfig =
|
|
||||||
{
|
|
||||||
ExecStart = "${cfg.package}/bin/tootctl preview_cards remove";
|
|
||||||
Type = "oneshot";
|
|
||||||
EnvironmentFile = "/var/lib/mastodon/.secrets_env";
|
|
||||||
SystemCallFilter = [("~" + lib.concatStringsSep " " systemCallsList) "@chown" "pipe" "pipe2"];
|
|
||||||
}
|
|
||||||
// cfgService;
|
|
||||||
path = with pkgs; [file imagemagick ffmpeg];
|
|
||||||
};
|
|
||||||
systemd.timers.mastodon-clean-preview-cards = {
|
|
||||||
description = "Clean mastodon preview cards";
|
|
||||||
requires = ["mastodon-clean-preview-cards.service"];
|
|
||||||
wantedBy = ["multi-user.target"];
|
|
||||||
timerConfig = {
|
|
||||||
OnUnitActiveSec = 604800;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.nginx = lib.mkIf cfg.configureNginx {
|
|
||||||
enable = true;
|
|
||||||
recommendedProxySettings = true; # required for redirections to work
|
|
||||||
virtualHosts."${cfg.localDomain}" = {
|
|
||||||
root = "${cfg.package}/public/";
|
|
||||||
forceSSL = true; # mastodon only supports https
|
|
||||||
enableACME = true;
|
|
||||||
|
|
||||||
locations."/system/".alias = "/var/lib/mastodon/public-system/";
|
|
||||||
|
|
||||||
locations."/" = {
|
|
||||||
tryFiles = "$uri @proxy";
|
|
||||||
};
|
|
||||||
|
|
||||||
locations."@proxy" = {
|
|
||||||
proxyPass =
|
|
||||||
if cfg.enableUnixSocket
|
|
||||||
then "http://unix:/run/mastodon-web/web.socket"
|
|
||||||
else "http://127.0.0.1:${toString cfg.webPort}";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
locations."/api/v1/streaming/" = {
|
|
||||||
proxyPass =
|
|
||||||
if cfg.enableUnixSocket
|
|
||||||
then "http://unix:/run/mastodon-streaming/streaming.socket"
|
|
||||||
else "http://127.0.0.1:${toString cfg.streamingPort}/";
|
|
||||||
proxyWebsockets = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
services.postfix = lib.mkIf (cfg.smtp.createLocally && cfg.smtp.host == "127.0.0.1") {
|
|
||||||
enable = true;
|
|
||||||
hostname = lib.mkDefault "${cfg.localDomain}";
|
|
||||||
};
|
|
||||||
services.redis = lib.mkIf (cfg.redis.createLocally && cfg.redis.host == "127.0.0.1") {
|
|
||||||
enable = true;
|
|
||||||
};
|
|
||||||
services.postgresql = lib.mkIf databaseActuallyCreateLocally {
|
|
||||||
enable = true;
|
|
||||||
ensureUsers = [
|
|
||||||
{
|
|
||||||
name = cfg.database.user;
|
|
||||||
ensurePermissions."DATABASE ${cfg.database.name}" = "ALL PRIVILEGES";
|
|
||||||
}
|
|
||||||
];
|
|
||||||
ensureDatabases = [cfg.database.name];
|
|
||||||
};
|
|
||||||
|
|
||||||
users.users = lib.mkMerge [
|
|
||||||
(lib.mkIf (cfg.user == "mastodon") {
|
|
||||||
mastodon = {
|
|
||||||
isSystemUser = true;
|
|
||||||
home = cfg.package;
|
|
||||||
inherit (cfg) group;
|
|
||||||
};
|
|
||||||
})
|
|
||||||
(lib.attrsets.setAttrByPath [cfg.user "packages"] [cfg.package mastodonEnv])
|
|
||||||
];
|
|
||||||
|
|
||||||
users.groups.${cfg.group}.members = lib.optional cfg.configureNginx config.services.nginx.user;
|
|
||||||
};
|
|
||||||
|
|
||||||
meta.maintainers = with lib.maintainers; [happy-river erictapen];
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
{
|
|
||||||
stdenvNoCC,
|
|
||||||
fetchFromGitHub,
|
|
||||||
ibus,
|
|
||||||
ibus-engines,
|
|
||||||
}:
|
|
||||||
stdenvNoCC.mkDerivation rec {
|
|
||||||
pname = "ibus-toki-pona";
|
|
||||||
version = "20220215";
|
|
||||||
src = fetchFromGitHub {
|
|
||||||
owner = "Id405";
|
|
||||||
repo = "sitelen-pona-ucsur-guide";
|
|
||||||
rev = "43da00449a99c0b8aaa6f5099d0dc1f795c7c39f";
|
|
||||||
sha256 = "sha256-CIa0wJnv1G0jpS8l2cjEFey1pdQuJPftiwZ5MZyriJ8=";
|
|
||||||
};
|
|
||||||
buildInputs = [ibus ibus-engines.table];
|
|
||||||
|
|
||||||
buildPhase = ''
|
|
||||||
export HOME=$(pwd)
|
|
||||||
ibus-table-createdb -n tokipona.db -s tokipona.txt
|
|
||||||
'';
|
|
||||||
installPhase = ''
|
|
||||||
install -m444 -Dt $out/share/ibus-table/tables tokipona.db
|
|
||||||
'';
|
|
||||||
meta.isIbusEngine = true;
|
|
||||||
}
|
|
Loading…
Reference in a new issue