diff --git a/config/default.nix b/config/default.nix index 6c7ffd3e..79c2c147 100644 --- a/config/default.nix +++ b/config/default.nix @@ -21,6 +21,7 @@ services.openssh.enable = true; environment.systemPackages = with pkgs; [ git + kitty.terminfo ]; networking.firewall.allowedTCPPorts = [22]; networking.firewall.allowedUDPPortRanges = [ diff --git a/config/desktop.nix b/config/desktop.nix index 7f57f632..99c0dac8 100644 --- a/config/desktop.nix +++ b/config/desktop.nix @@ -82,7 +82,6 @@ in { security.pam = { services.login.u2fAuth = true; - services.sddm.u2fAuth = true; services.swaylock.u2fAuth = true; u2f = { enable = true; @@ -139,7 +138,6 @@ in { pinentry-qt dotool wl-clipboard - plasma5Packages.thirdParty.lightly ]; programs.gnupg.agent.pinentryFlavor = "qt"; @@ -156,19 +154,12 @@ in { libinput.enable = true; layout = "de"; xkbVariant = "neo"; - displayManager.sddm.enable = true; - desktopManager.plasma5.enable = true; - displayManager.defaultSession = "plasmawayland"; extraLayouts.zlr = { description = "lojban layout"; languages = ["jbo"]; symbolsFile = ../extra/keyboard/symbols; }; }; - i18n.inputMethod = { - enabled = "ibus"; - ibus.engines = with pkgs.ibus-engines; [anthy]; - }; security.polkit.enable = true; services.dbus.enable = true; services.dbus.packages = with pkgs; [dconf]; diff --git a/config/home-manager/darkkirb.nix b/config/home-manager/darkkirb.nix index 8edb4cd9..4fae06f1 100644 --- a/config/home-manager/darkkirb.nix +++ b/config/home-manager/darkkirb.nix @@ -12,7 +12,10 @@ ++ ( if desktop then [ + ../programs/sway.nix ../programs/firefox.nix + ../programs/theming.nix + ../programs/waybar.nix ../programs/ims.nix ../programs/syncthing.nix ../programs/plover.nix @@ -25,7 +28,6 @@ ../programs/zk.nix ../programs/fcitx.nix ../programs/gpg.nix - ../programs/kdeconnect.nix ../programs/zoom.nix ] else [] diff --git a/config/programs/firefox.nix b/config/programs/firefox.nix index 19d63b18..2bb12c5c 100644 --- a/config/programs/firefox.nix +++ b/config/programs/firefox.nix @@ -46,7 +46,6 @@ ublock-origin umatrix unpaywall - plasma-integration tampermonkey ]; }; diff --git a/config/programs/kdeconnect.nix b/config/programs/kdeconnect.nix deleted file mode 100644 index dd3f085d..00000000 --- a/config/programs/kdeconnect.nix +++ /dev/null @@ -1,4 +0,0 @@ -{...}: { - services.kdeconnect.enable = true; - services.kdeconnect.indicator = true; -} diff --git a/config/programs/keepass.nix b/config/programs/keepass.nix index 000346d9..0f18e96e 100644 --- a/config/programs/keepass.nix +++ b/config/programs/keepass.nix @@ -4,15 +4,4 @@ ... }: { 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"; - }; - }; } diff --git a/config/programs/pass-secret-service.nix b/config/programs/pass-secret-service.nix new file mode 100644 index 00000000..bae7885e --- /dev/null +++ b/config/programs/pass-secret-service.nix @@ -0,0 +1,5 @@ +{ + services.pass-secret-service = { + enable = true; + }; +} diff --git a/config/programs/sway.nix b/config/programs/sway.nix new file mode 100644 index 00000000..f5a9d0f7 --- /dev/null +++ b/config/programs/sway.nix @@ -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 "${c}{win_types[$k]} - ${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; +} diff --git a/config/programs/swayidle.nix b/config/programs/swayidle.nix new file mode 100644 index 00000000..b7a69e8e --- /dev/null +++ b/config/programs/swayidle.nix @@ -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}"; + } + ]; + }; +} diff --git a/config/programs/theming.nix b/config/programs/theming.nix new file mode 100644 index 00000000..21256524 --- /dev/null +++ b/config/programs/theming.nix @@ -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}"; + }; + }; +} diff --git a/config/programs/vim/modules/visual/indent-blankline.nix b/config/programs/vim/modules/visual/indent-blankline.nix deleted file mode 100644 index 828b2fcd..00000000 --- a/config/programs/vim/modules/visual/indent-blankline.nix +++ /dev/null @@ -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" - ]; - }; -} diff --git a/config/programs/waybar.nix b/config/programs/waybar.nix new file mode 100644 index 00000000..f50e1c99 --- /dev/null +++ b/config/programs/waybar.nix @@ -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 = " "; + 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 = "{:%Y %B}\n{calendar}"; + 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"; + }; + }; + }; + }; +} diff --git a/config/programs/zsh.nix b/config/programs/zsh.nix index c667e1f9..d9e97fa7 100644 --- a/config/programs/zsh.nix +++ b/config/programs/zsh.nix @@ -7,6 +7,14 @@ desktop: _: { syntaxHighlighting.enable = true; enableVteIntegration = desktop; autocd = true; + loginExtra = + if desktop + then '' + if [[ -z "$DISPLAY" ]] && [[ $(tty) = "/dev/tty1" ]]; then + exec sway + fi + '' + else ""; }; }; } diff --git a/config/services/kubo.nix b/config/services/kubo.nix index 62b81dfe..efbda1e8 100644 --- a/config/services/kubo.nix +++ b/config/services/kubo.nix @@ -38,14 +38,14 @@ type = "measure"; } { - child = { - compression = "none"; - path = "datastore"; - type = "levelds"; - }; - mountpoint = "/"; - prefix = "leveldb.datastore"; - type = "measure"; + child = { + compression = "none"; + path = "datastore"; + type = "levelds"; + }; + mountpoint = "/"; + prefix = "leveldb.datastore"; + type = "measure"; } ]; type = "mount"; diff --git a/config/services/matrix-media-repo.nix b/config/services/matrix-media-repo.nix index 037dd668..9dc8cbeb 100644 --- a/config/services/matrix-media-repo.nix +++ b/config/services/matrix-media-repo.nix @@ -66,7 +66,7 @@ "fc00::/7" ]; # user agent header was a mistake - userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0, matrix-media-repo (like twitterbot; like telegrambot; like discordbot; like facebook; like whatsapp; like firefox/92; like vkshare) +https://github.com/DarkKirb/nixos-config/pull/264"; + userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0, matrix-media-repo (like twitterbot; like telegrambot; like discordbot; like facebook; like whatsapp; like firefox/92; like vkshare) +https://github.com/DarkKirb/nixos-config/pull/264"; }; downloads = { expireAfterDays = 7; diff --git a/flake.lock b/flake.lock index ba8d6941..802fee25 100644 --- a/flake.lock +++ b/flake.lock @@ -78,6 +78,32 @@ "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": { "inputs": { "flake-utils": [ @@ -675,6 +701,27 @@ "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": { "inputs": { "lowdown-src": "lowdown-src", @@ -1066,6 +1113,7 @@ "root": { "inputs": { "chir-rs": "chir-rs", + "colorpickle": "colorpickle", "dns": "dns", "firefox": "firefox", "flake-compat": "flake-compat", @@ -1075,6 +1123,7 @@ "home-manager": "home-manager", "lib-aggregate": "lib-aggregate", "mozilla": "mozilla", + "naersk": "naersk", "nix-gaming": "nix-gaming", "nix-neovim": "nix-neovim", "nix-packages": "nix-packages", diff --git a/flake.nix b/flake.nix index 42ad8fc7..fa485e4d 100644 --- a/flake.nix +++ b/flake.nix @@ -13,6 +13,12 @@ rec { inputs.systems.follows = "systems"; 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 = { url = "github:DarkKirb/dns.nix"; inputs.flake-utils.follows = "flake-utils"; @@ -49,6 +55,10 @@ rec { inputs.nixpkgs-lib.follows = "nixpkgs"; }; mozilla.url = "github:mozilla/nixpkgs-mozilla"; + naersk = { + url = "github:nix-community/naersk/master"; + inputs.nixpkgs.follows = "nixpkgs"; + }; nix-gaming = { url = "github:fufexan/nix-gaming"; inputs.nixpkgs.follows = "nixpkgs"; diff --git a/modules/mastodon.nix b/modules/mastodon.nix deleted file mode 100644 index 71be9a8b..00000000 --- a/modules/mastodon.nix +++ /dev/null @@ -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: - - / -> $(nix-instantiate --eval '<nixpkgs>' -A mastodon.outPath)/public - - / -> 127.0.0.1:{{ webPort }} (If there was no file in the directory above.) - - /system/ -> /var/lib/mastodon/public-system/ - - /api/v1/streaming/ -> 127.0.0.1:{{ streamingPort }} - - 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 - https://github.com/mastodon/mastodon/blob/master/dist/nginx.conf. - ''; - 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, - mastodon and a package containing only - the shell script mastodon-env will be added to - the user's package set. To run a command from - mastodon such as tootctl - with the environment configured by this module use - mastodon-env, as in: - - mastodon-env tootctl accounts create newuser --email newuser@example.com - ''; - 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: - - nix build -f '<nixpkgs>' mastodon; cd result; bin/rake webpush:generate_keys - - If 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: - - nix build -f '<nixpkgs>' mastodon; cd result; bin/rake secret - - 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: - - nix build -f '<nixpkgs>' mastodon; cd result; bin/rake secret - - 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: - - nix build -f '<nixpkgs>' mastodon; cd result; bin/rake webpush:generate_keys - - 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 - . - ''; - }; - }; - - 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 <