smallest change
This commit is contained in:
parent
4cca1dc327
commit
9c83ba6849
77 changed files with 36828 additions and 1516 deletions
209
modules/nixos/hardware/audio/auto-connect-tt.lua
Normal file
209
modules/nixos/hardware/audio/auto-connect-tt.lua
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
-- As explained on (and stolen from): https://bennett.dev/auto-link-pipewire-ports-wireplumber/
|
||||
--
|
||||
-- This script keeps my stereo-null-sink connected to whatever output I'm currently using.
|
||||
-- I do this so Pulseaudio (and Wine) always sees a stereo output plus I can swap the output
|
||||
-- without needing to reconnect everything.
|
||||
|
||||
-- Link two ports together
|
||||
function link_port(output_port, input_port)
|
||||
if not input_port or not output_port then
|
||||
return nil
|
||||
end
|
||||
|
||||
print("out", dump(output_port.properties))
|
||||
print("in", dump(input_port.properties))
|
||||
|
||||
local link_args = {
|
||||
["link.input.node"] = input_port.properties["node.id"],
|
||||
["link.input.port"] = input_port.properties["object.id"],
|
||||
|
||||
["link.output.node"] = output_port.properties["node.id"],
|
||||
["link.output.port"] = output_port.properties["object.id"],
|
||||
|
||||
-- -- The node never got created if it didn't have this field set to something
|
||||
-- ["object.id"] = nil,
|
||||
--
|
||||
-- -- I was running into issues when I didn't have this set
|
||||
-- ["object.linger"] = 1,
|
||||
--
|
||||
-- ["node.description"] = "Link created by auto_connect_ports",
|
||||
}
|
||||
|
||||
print(dump(link_args))
|
||||
|
||||
local link = Link("link-factory", link_args)
|
||||
link:activate(1)
|
||||
|
||||
print("link created", dump(link.properties))
|
||||
|
||||
return link
|
||||
end
|
||||
|
||||
-- Automatically link ports together by their specific audio channels.
|
||||
--
|
||||
-- ┌──────────────────┐ ┌───────────────────┐
|
||||
-- │ │ │ │
|
||||
-- │ FL ├────────►│ AUX0 │
|
||||
-- │ OUTPUT │ │ │
|
||||
-- │ FR ├────────►│ AUX1 INPUT │
|
||||
-- │ │ │ │
|
||||
-- └──────────────────┘ │ AUX2 │
|
||||
-- │ │
|
||||
-- └───────────────────┘
|
||||
--
|
||||
-- -- Call this method inside a script in global scope
|
||||
--
|
||||
-- auto_connect_ports {
|
||||
--
|
||||
-- -- A constraint for all the required ports of the output device
|
||||
-- output = Constraint { "node.name"}
|
||||
--
|
||||
-- -- A constraint for all the required ports of the input device
|
||||
-- input = Constraint { .. }
|
||||
--
|
||||
-- -- A mapping of output audio channels to input audio channels
|
||||
--
|
||||
-- connections = {
|
||||
-- ["FL"] = "AUX0"
|
||||
-- ["FR"] = "AUX1"
|
||||
-- }
|
||||
--
|
||||
-- }
|
||||
|
||||
function dump(o)
|
||||
if type(o) == "table" then
|
||||
local s = "{ "
|
||||
for k, v in pairs(o) do
|
||||
if type(k) ~= "number" then
|
||||
k = '"' .. k .. '"'
|
||||
end
|
||||
s = s .. "[" .. k .. "] = " .. dump(v) .. ","
|
||||
end
|
||||
return s .. "} "
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
function auto_connect_ports(args)
|
||||
local output_om = ObjectManager({
|
||||
Interest({
|
||||
type = "port",
|
||||
args["output"],
|
||||
Constraint({ "port.direction", "equals", "out" }),
|
||||
}),
|
||||
})
|
||||
|
||||
print("output_om", dump(output_om))
|
||||
|
||||
local links = {}
|
||||
|
||||
local input_om = ObjectManager({
|
||||
Interest({
|
||||
type = "port",
|
||||
args["input"],
|
||||
Constraint({ "port.direction", "equals", "in" }),
|
||||
}),
|
||||
})
|
||||
|
||||
print("input_om", dump(input_om))
|
||||
|
||||
local all_links = ObjectManager({
|
||||
Interest({
|
||||
type = "link",
|
||||
}),
|
||||
})
|
||||
|
||||
print("all_links", dump(all_links))
|
||||
|
||||
local unless = nil
|
||||
|
||||
if args["unless"] then
|
||||
unless = ObjectManager({
|
||||
Interest({
|
||||
type = "port",
|
||||
args["unless"],
|
||||
Constraint({ "port.direction", "equals", "in" }),
|
||||
}),
|
||||
})
|
||||
end
|
||||
|
||||
function _connect()
|
||||
print("connecting...")
|
||||
local delete_links = unless and unless:get_n_objects() > 0
|
||||
|
||||
if delete_links then
|
||||
for _i, link in pairs(links) do
|
||||
link:request_destroy()
|
||||
end
|
||||
|
||||
links = {}
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
for output_name, input_names in pairs(args.connect) do
|
||||
local input_names = input_names[1] == nil and { input_names } or input_names
|
||||
|
||||
-- for output in output_om:iterate() do
|
||||
-- print(dump(output.properties))
|
||||
-- end
|
||||
|
||||
if delete_links then
|
||||
else
|
||||
-- Iterate through all the output ports with the correct channel name
|
||||
for output in output_om:iterate({ Constraint({ "audio.channel", "equals", output_name }) }) do
|
||||
for _i, input_name in pairs(input_names) do
|
||||
-- Iterate through all the input ports with the correct channel name
|
||||
-- print("inp name", input_name)
|
||||
-- print("output", dump(output.properties))
|
||||
-- for input in input_om:iterate() do
|
||||
-- print("hi")
|
||||
-- -- print(dump(input.properties))
|
||||
-- end
|
||||
for input in input_om:iterate({ Constraint({ "audio.channel", "equals", input_name }) }) do
|
||||
-- print("here2")
|
||||
-- Link all the nodes
|
||||
local link = link_port(output, input)
|
||||
-- print("linked")
|
||||
|
||||
if link then
|
||||
table.insert(links, link)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
output_om:connect("object-added", _connect)
|
||||
input_om:connect("object-added", _connect)
|
||||
all_links:connect("object-added", _connect)
|
||||
|
||||
output_om:activate()
|
||||
input_om:activate()
|
||||
all_links:activate()
|
||||
|
||||
if unless then
|
||||
unless:connect("object-added", _connect)
|
||||
unless:connect("object-removed", _connect)
|
||||
unless:activate()
|
||||
end
|
||||
|
||||
print("dun")
|
||||
end
|
||||
|
||||
-- Auto connect the stereo null sink to bluetooth headphones
|
||||
auto_connect_ports({
|
||||
input = Constraint({
|
||||
"port.alias",
|
||||
"matches",
|
||||
"Scarlett Solo USB:playback_*",
|
||||
}),
|
||||
output = Constraint({ "port.alias", "matches", "ALC1220 Analog:capture_*" }),
|
||||
connect = {
|
||||
["FL"] = { "FL" },
|
||||
["FR"] = { "FR" },
|
||||
},
|
||||
})
|
||||
|
|
@ -13,7 +13,6 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Enable sound with pipewire.
|
||||
hardware.pulseaudio.enable = false;
|
||||
security.rtkit.enable = true;
|
||||
services.pipewire = {
|
||||
|
|
@ -21,19 +20,102 @@ in {
|
|||
alsa.enable = true;
|
||||
alsa.support32Bit = true;
|
||||
pulse.enable = true;
|
||||
# If you want to use JACK applications, uncomment this
|
||||
wireplumber.enable = true;
|
||||
jack.enable = true;
|
||||
|
||||
extraConfig.pipewire.adjust-sample-rate = {
|
||||
"context.properties" = {
|
||||
"default.clock.rate" = 44100;
|
||||
"default.allowed-rates" = [44100];
|
||||
};
|
||||
};
|
||||
# extraConfig.pipewire.adjust-sample-rate = {
|
||||
# "context.properties" = {
|
||||
# "default.clock.rate" = 41000;
|
||||
# "default.clock.allowed-rates" = [44100];
|
||||
# };
|
||||
# };
|
||||
|
||||
# use the example session manager (no others are packaged yet so this is enabled by default,
|
||||
# no need to redefine it in your config for now)
|
||||
wireplumber.enable = true;
|
||||
# wireplumber.extraConfig = {
|
||||
# "custom" = {
|
||||
# "monitor.alsa.rules" = [
|
||||
# {
|
||||
# matches = [
|
||||
# {
|
||||
# "node.name" = "alsa_output.usb-Focusrite_Scarlett_Solo_USB_Y76P5M4160A866-00.HiFi__Line1__sink";
|
||||
# }
|
||||
# ];
|
||||
# actions = {
|
||||
# update-props = {
|
||||
# "audio.format" = "S32LE";
|
||||
# "audio.rate" = 192000;
|
||||
# "api.alsa.period-size" = 1024;
|
||||
# };
|
||||
# };
|
||||
# }
|
||||
# {
|
||||
# matches = [
|
||||
# {
|
||||
# "node.name" = "alsa_input.pci-0000_0d_00.4.analog-stereo";
|
||||
# }
|
||||
# ];
|
||||
# actions = {
|
||||
# update-props = {
|
||||
# "audio.format" = "S32LE";
|
||||
# "audio.rate" = 192000;
|
||||
# "api.alsa.period-size" = 1024;
|
||||
# };
|
||||
# };
|
||||
# }
|
||||
# {
|
||||
# matches = [
|
||||
# {
|
||||
# "node.name" = "~alsa_output.*";
|
||||
# }
|
||||
# ];
|
||||
# actions = {
|
||||
# update-props = {
|
||||
# "api.alsa.period-size" = 1024;
|
||||
# "api.alsa.headroom" = 8192;
|
||||
# };
|
||||
# };
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
#
|
||||
# "99-connect-tt" = {
|
||||
# "wireplumber.components" = [
|
||||
# {
|
||||
# name = "auto-connect-tt.lua";
|
||||
# type = "script/lua";
|
||||
# provides = "custom.connect-tt";
|
||||
# }
|
||||
# ];
|
||||
#
|
||||
# "wireplumber.profiles" = {
|
||||
# main = {
|
||||
# "custom.connect-tt" = "required";
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
# wireplumber.extraScripts = {
|
||||
# "auto-connect-tt.lua" = builtins.readFile ./auto-connect-tt.lua;
|
||||
# };
|
||||
# };
|
||||
#
|
||||
# # PulseAudio compatibility layer configuration for 44.1kHz
|
||||
# services.pipewire.extraConfig.pipewire-pulse."92-steam-config" = {
|
||||
# context.modules = [
|
||||
# {
|
||||
# name = "libpipewire-module-protocol-pulse";
|
||||
# args = {
|
||||
# pulse.min.req = "32/44100";
|
||||
# pulse.default.req = "32/44100";
|
||||
# pulse.min.quantum = "32/44100";
|
||||
# pulse.max.quantum = "8192/44100";
|
||||
# };
|
||||
# }
|
||||
# ];
|
||||
# };
|
||||
#
|
||||
# environment.sessionVariables = {
|
||||
# PIPEWIRE_LATENCY = "1024/44100";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
28
modules/nixos/hardware/audio/dump-links.lua
Normal file
28
modules/nixos/hardware/audio/dump-links.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-- Dump all Wireplumber links
|
||||
|
||||
function dump(o)
|
||||
if type(o) == "table" then
|
||||
local s = "{ "
|
||||
for k, v in pairs(o) do
|
||||
if type(k) ~= "number" then
|
||||
k = '"' .. k .. '"'
|
||||
end
|
||||
s = s .. "[" .. k .. "] = " .. dump(v) .. ",\n"
|
||||
end
|
||||
return s .. "} "
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
local link_om = ObjectManager({
|
||||
Interest({
|
||||
type = "link",
|
||||
}),
|
||||
})
|
||||
|
||||
link_om:connect("object-added", function(om, link)
|
||||
print(dump(link.properties) .. "\n\n")
|
||||
end)
|
||||
|
||||
link_om:activate()
|
||||
28
modules/nixos/hardware/audio/dump-ports.lua
Normal file
28
modules/nixos/hardware/audio/dump-ports.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
-- Dump all Wireplumber ports
|
||||
|
||||
function dump(o)
|
||||
if type(o) == "table" then
|
||||
local s = "{ "
|
||||
for k, v in pairs(o) do
|
||||
if type(k) ~= "number" then
|
||||
k = '"' .. k .. '"'
|
||||
end
|
||||
s = s .. "[" .. k .. "] = " .. dump(v) .. ",\n"
|
||||
end
|
||||
return s .. "} "
|
||||
else
|
||||
return tostring(o)
|
||||
end
|
||||
end
|
||||
|
||||
local port_om = ObjectManager({
|
||||
Interest({
|
||||
type = "port",
|
||||
}),
|
||||
})
|
||||
|
||||
port_om:connect("object-added", function(om, port)
|
||||
print(dump(port.properties) .. "\n\n")
|
||||
end)
|
||||
|
||||
port_om:activate()
|
||||
104
modules/nixos/hardware/custom-opts/default.nix
Normal file
104
modules/nixos/hardware/custom-opts/default.nix
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
# yoinked from https://gitlab.com/funaali/dotfiles/-/blob/3c74966cc4501c548aac0ee83cf5982510dd615c/modules/nixos/custom-opts.nix#L50, thanks!
|
||||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.custom; let
|
||||
cfg = config.hardware.march;
|
||||
in {
|
||||
options.hardware.march = with types; {
|
||||
arch = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "GCC -march=";
|
||||
};
|
||||
|
||||
system = mkOption {
|
||||
type = types.str;
|
||||
default = "x86_64-linux";
|
||||
};
|
||||
|
||||
enableNativeOptimizations = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable -march=<arch> optimizations for all packages";
|
||||
};
|
||||
|
||||
enableNativeOptimizationsByDefault = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [];
|
||||
description = ''
|
||||
Architectures for which native optimizations are enabled by default.
|
||||
'';
|
||||
};
|
||||
|
||||
TCPBBRCongestionControl = mkEnableOption "TCP BBR congestion control";
|
||||
|
||||
cpu.vcores = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
description = "Teh number of virtual CPU cores. Used to calculate heuristics.";
|
||||
};
|
||||
|
||||
memory.total = mkOption {
|
||||
type = types.int;
|
||||
default = 0;
|
||||
description = "Total amount of RAM in the system (gigabytes). Used to calculate heuristics.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkMerge [
|
||||
# Enable nix to build for the system arch and its inferiors.
|
||||
(mkIf (cfg.arch != null) {
|
||||
# taken from https://github.com/NixOS/nixpkgs/blob/nixos-unstable/nixos/modules/config/nix.nix
|
||||
nix.settings.system-features = map (x: "gccarch-${x}") ((systems.architectures.inferiors.${cfg.arch} or []) ++ [cfg.arch]) ++ ["big-parallel"];
|
||||
})
|
||||
|
||||
# Set nix cores and max jobs based on cores and installed memory.
|
||||
(mkIf (cfg.cpu.vcores + cfg.memory.total > 0) (
|
||||
let
|
||||
minMemoryPerCore = 2;
|
||||
jobsOvercommitFactor = 4;
|
||||
cores = min 16 (min (cfg.cpu.vcores / 2) (cfg.memory.total / minMemoryPerCore));
|
||||
max-jobs = jobsOvercommitFactor * cfg.memory.total / (cores * minMemoryPerCore);
|
||||
in {
|
||||
nix.settings = {
|
||||
inherit cores max-jobs;
|
||||
};
|
||||
}
|
||||
))
|
||||
|
||||
# Native arch optimizations
|
||||
(mkIf (cfg.enableNativeOptimizations || elem cfg.arch cfg.enableNativeOptimizationsByDefault) {
|
||||
assertions = [
|
||||
{
|
||||
message = "custom.arch can't be null when custom.enableNativeOptimizations is true!";
|
||||
assertion = cfg.enableNativeOptimizations -> cfg.arch != null;
|
||||
}
|
||||
];
|
||||
|
||||
nixpkgs.hostPlatform = mkOverride 1 {
|
||||
system = cfg.system;
|
||||
gcc.arch = cfg.arch;
|
||||
gcc.tune = cfg.arch;
|
||||
};
|
||||
})
|
||||
|
||||
# Enable TCP BBR congestion control
|
||||
(mkIf cfg.TCPBBRCongestionControl {
|
||||
boot.kernelModules = ["tcp_bbr"];
|
||||
boot.kernel.sysctl = {
|
||||
"net.core.default_qdisc" = "cake";
|
||||
"net.ipv4.tcp_congestion_control" = "bbr";
|
||||
};
|
||||
})
|
||||
|
||||
# Settings if total memory is defined
|
||||
(mkIf (cfg.memory.total > 0) {
|
||||
services.earlyoom.freeMemThreshold = min 1 (max 5 (200 / cfg.memory.total));
|
||||
})
|
||||
];
|
||||
}
|
||||
|
|
@ -48,7 +48,7 @@ in {
|
|||
kmod
|
||||
systemd
|
||||
ripgrep
|
||||
mullvad
|
||||
nixos-stable.mullvad
|
||||
killall
|
||||
sd
|
||||
];
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ in {
|
|||
# https://github.com/NVIDIA/open-gpu-kernel-modules#compatible-gpus
|
||||
# Only available from driver 515.43.04+
|
||||
# Currently alpha-quality/buggy, so false is currently the recommended setting.
|
||||
open = false;
|
||||
open = true;
|
||||
|
||||
# Enable the Nvidia settings menu,
|
||||
# accessible via `nvidia-settings`.
|
||||
nvidiaSettings = true;
|
||||
nvidiaSettings = false;
|
||||
|
||||
# Optionally, you may need to select the appropriate driver version for your specific GPU.
|
||||
package = config.boot.kernelPackages.nvidiaPackages.beta;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,20 @@ in {
|
|||
|
||||
services.xserver.displayManager.gdm.enable = true;
|
||||
|
||||
programs.uwsm.enable = true;
|
||||
programs.uwsm = {
|
||||
enable = true;
|
||||
# waylandCompositors = {
|
||||
# "mwc" = {
|
||||
# prettyName = "MWC";
|
||||
# binPath = "/run/current-system/sw/bin/mwc";
|
||||
# comment = "previously owl";
|
||||
# };
|
||||
# };
|
||||
};
|
||||
|
||||
# environment.systemPackages = [
|
||||
# pkgs.custom.mwc
|
||||
# ];
|
||||
|
||||
programs.hyprland = {
|
||||
withUWSM = true;
|
||||
|
|
|
|||
87
modules/nixos/services/mail/default.nix
Normal file
87
modules/nixos/services/mail/default.nix
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.custom; let
|
||||
cfg = config.services.mail;
|
||||
|
||||
sec = config.age.secrets;
|
||||
in {
|
||||
options.services.mail = with types; {
|
||||
enable = mkBoolOpt false "Enable Simple Nixos Mailserver";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
age.secrets = {
|
||||
webmaster-pw = {
|
||||
file = ./sec/webmaster-pw.age;
|
||||
};
|
||||
zoeycomputer-pw = {
|
||||
file = ./sec/zoey-zoeycomputer-pw.age;
|
||||
};
|
||||
zmio-pw = {
|
||||
file = ./sec/zmio-pw.age;
|
||||
};
|
||||
zach-pw.file = ./sec/zach-pw.age;
|
||||
emily-pw.file = ./sec/emily-piccat.age;
|
||||
};
|
||||
|
||||
mailserver = {
|
||||
enable = true;
|
||||
fqdn = "mail.zoeys.email";
|
||||
domains = ["zoeys.email" "zoeys.cloud" "zoeys.computer" "zackmyers.io" "zacharymyers.com" "pictureofcat.com"];
|
||||
|
||||
loginAccounts = {
|
||||
"zoey@zoeys.email" = {
|
||||
hashedPasswordFile = sec.webmaster-pw.path;
|
||||
aliases = ["zoey@zoeys.cloud" "postmaster@zoeys.email" "abuse@zoeys.email"];
|
||||
};
|
||||
"hi@zoeys.computer" = {
|
||||
hashedPasswordFile = sec.zoeycomputer-pw.path;
|
||||
aliases = ["spam@zoeys.computer"];
|
||||
};
|
||||
"me@zackmyers.io" = {
|
||||
hashedPasswordFile = sec.zmio-pw.path;
|
||||
aliases = ["zach@zacharymyers.com" "zack@zacharymyers.com"];
|
||||
};
|
||||
"gf@zackmyers.io" = {
|
||||
hashedPasswordFile = sec.emily-pw.path;
|
||||
aliases = ["emily@pictureofcat.com"];
|
||||
};
|
||||
};
|
||||
|
||||
certificateScheme = "acme-nginx";
|
||||
virusScanning = true;
|
||||
};
|
||||
|
||||
# services.nginx = {
|
||||
# virtualHosts = {
|
||||
# "cal.zoeys.cloud" = {
|
||||
# forceSSL = true;
|
||||
# enableACME = true;
|
||||
# locations."/" = {
|
||||
# proxyPass = "http://localhost:5232/";
|
||||
# extraConfig = ''
|
||||
# proxy_set_header X-Script-Name /;
|
||||
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
# proxy_pass_header Authorization;
|
||||
# '';
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
# };
|
||||
|
||||
services.roundcube = {
|
||||
enable = true;
|
||||
hostName = "zoeys.email";
|
||||
extraConfig = ''
|
||||
$config['smtp_server'] = "tls://${config.mailserver.fqdn}";
|
||||
$config['smtp_user'] = "%u";
|
||||
$config['smtp_pass'] = "%p";
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
7
modules/nixos/services/mail/sec/emily-piccat.age
Normal file
7
modules/nixos/services/mail/sec/emily-piccat.age
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 CtmR6w GByJvx+LFQ6yzgAl/liuJjfzjkwZMHC+R+aKNfKNAmY
|
||||
S5csNYDpwtHvIWe5W0lEiKbVnR2FcOtRU5WQW2cALAA
|
||||
-> ssh-ed25519 +be3hg 68FeHprHjQxUbxJj0ERz6HOM338g12EU/BmLCDjtz3Y
|
||||
ydJ94RUuxLwuk0BedBk816wLMWjgOQd3/Eb7msud3mA
|
||||
--- pM8bV+881Kh2Rpizrmaa/JzzvNXtKRTRU1KyFw9qtaQ
|
||||
:Ã쀬ÿxÕþ,ʅ梞ÔYk0+1‚ÂZÏOIq@ÛY”¼Ô¡Ö±2T³Jũޤ*Íýù!%¹…cüýcšò<C5A1>Yq<RÕF ²ù±^Ú+éf Ý
|
||||
8
modules/nixos/services/mail/sec/webmaster-pw.age
Normal file
8
modules/nixos/services/mail/sec/webmaster-pw.age
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 CtmR6w s2FYa/CFw32d95iUrKgwFbvMtNe+17vDYLzCRJaBumA
|
||||
YgQyjn/bkEN6bH7VSlrN4xT/epITxj8NnPsalOz4ndU
|
||||
-> ssh-ed25519 +be3hg BkNhJbmWJHREV54OnrDzA7ep8h2ZzVtzh+Ns6Es1jQ4
|
||||
eepXxHwYgVZN56nuCisQuy+PHRjz+/NrJfVdqaAAMRE
|
||||
--- wyDX4yv5LbYhCvxIiK+wzndFlBs5AdV/FgNC+MRHAO8
|
||||
<EFBFBD>wVX=ó|¹éì
@ß3ŒÜr‘”tÅÇ™sWl&ón»
|
||||
¿Ù¿4“‹T&ÁÅJ"‚<Ë;רGYò-Dp@1Á<31>Î@ò»º_š9µÎ‡³ÌUû×™™ )•üb"
|
||||
BIN
modules/nixos/services/mail/sec/zach-pw.age
Normal file
BIN
modules/nixos/services/mail/sec/zach-pw.age
Normal file
Binary file not shown.
BIN
modules/nixos/services/mail/sec/zmio-pw.age
Normal file
BIN
modules/nixos/services/mail/sec/zmio-pw.age
Normal file
Binary file not shown.
BIN
modules/nixos/services/mail/sec/zoey-zoeycomputer-pw.age
Normal file
BIN
modules/nixos/services/mail/sec/zoey-zoeycomputer-pw.age
Normal file
Binary file not shown.
168
modules/nixos/services/polaris2/default.nix
Normal file
168
modules/nixos/services/polaris2/default.nix
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
{
|
||||
config,
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
cfg = config.services.polaris2;
|
||||
settingsFormat = pkgs.formats.toml {};
|
||||
in {
|
||||
options = {
|
||||
services.polaris2 = {
|
||||
enable = lib.mkEnableOption "Polaris Music Server";
|
||||
|
||||
package = lib.mkPackageOption pkgs "polaris" {};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "polaris";
|
||||
description = "User account under which Polaris runs.";
|
||||
};
|
||||
|
||||
group = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
default = "polaris";
|
||||
description = "Group under which Polaris is run.";
|
||||
};
|
||||
|
||||
extraGroups = lib.mkOption {
|
||||
type = lib.types.listOf lib.types.str;
|
||||
default = [];
|
||||
description = "Polaris' auxiliary groups.";
|
||||
example = lib.literalExpression ''["media" "music"]'';
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 5050;
|
||||
description = ''
|
||||
The port which the Polaris REST api and web UI should listen to.
|
||||
Note: polaris is hardcoded to listen to the hostname "0.0.0.0".
|
||||
'';
|
||||
};
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = settingsFormat.type;
|
||||
default = {};
|
||||
description = ''
|
||||
Contents for the TOML Polaris config, applied each start.
|
||||
Although poorly documented, an example may be found here:
|
||||
[CONFIGURATION.md](https://github.com/agersant/polaris/blob/46aed8096ee9d8702b5a98e6f3b1ff5db2bfc32a/docs/CONFIGURATION.md#format)
|
||||
[test-config.toml](https://github.com/agersant/polaris/blob/46aed8096ee9d8702b5a98e6f3b1ff5db2bfc32a/test-data/config.toml)
|
||||
'';
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
settings.reindex_every_n_seconds = 7*24*60*60; # weekly, default is 1800
|
||||
settings.album_art_pattern =
|
||||
"(cover|front|folder)\.(jpeg|jpg|png|bmp|gif)";
|
||||
mount_dirs = [
|
||||
{
|
||||
name = "NAS";
|
||||
source = "/mnt/nas/music";
|
||||
}
|
||||
{
|
||||
name = "Local";
|
||||
source = "/home/my_user/Music";
|
||||
}
|
||||
];
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Open the configured port in the firewall.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
systemd.services.polaris = {
|
||||
description = "Polaris Music Server";
|
||||
after = ["network.target"];
|
||||
wantedBy = ["multi-user.target"];
|
||||
|
||||
serviceConfig = rec {
|
||||
User = cfg.user;
|
||||
Group = cfg.group;
|
||||
DynamicUser = true;
|
||||
SupplementaryGroups = cfg.extraGroups;
|
||||
StateDirectory = "polaris";
|
||||
CacheDirectory = "polaris";
|
||||
ExecStart = lib.escapeShellArgs (
|
||||
[
|
||||
"${cfg.package}/bin/polaris"
|
||||
"--foreground"
|
||||
"--port"
|
||||
cfg.port
|
||||
"--database"
|
||||
"/var/lib/${StateDirectory}/db.sqlite"
|
||||
"--data"
|
||||
"/var/lib/${StateDirectory}/data"
|
||||
"--cache"
|
||||
"/var/cache/${CacheDirectory}"
|
||||
]
|
||||
++ lib.optionals (cfg.settings != {}) [
|
||||
"--config"
|
||||
(settingsFormat.generate "polaris-config.toml" cfg.settings)
|
||||
]
|
||||
);
|
||||
Restart = "on-failure";
|
||||
|
||||
# Security options:
|
||||
|
||||
#NoNewPrivileges = true; # implied by DynamicUser
|
||||
#RemoveIPC = true; # implied by DynamicUser
|
||||
|
||||
AmbientCapabilities = "";
|
||||
CapabilityBoundingSet = "";
|
||||
|
||||
DeviceAllow = "";
|
||||
|
||||
LockPersonality = true;
|
||||
|
||||
#PrivateTmp = true; # implied by DynamicUser
|
||||
PrivateDevices = true;
|
||||
PrivateUsers = true;
|
||||
|
||||
ProtectClock = true;
|
||||
ProtectControlGroups = true;
|
||||
ProtectHostname = true;
|
||||
ProtectKernelLogs = true;
|
||||
ProtectKernelModules = true;
|
||||
ProtectKernelTunables = true;
|
||||
|
||||
RestrictNamespaces = true;
|
||||
RestrictAddressFamilies = [
|
||||
"AF_INET"
|
||||
"AF_INET6"
|
||||
"AF_UNIX"
|
||||
];
|
||||
RestrictRealtime = true;
|
||||
#RestrictSUIDSGID = true; # implied by DynamicUser
|
||||
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallErrorNumber = "EPERM";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@cpu-emulation"
|
||||
"~@debug"
|
||||
"~@keyring"
|
||||
"~@memlock"
|
||||
"~@obsolete"
|
||||
"~@privileged"
|
||||
"~@setuid"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall = lib.mkIf cfg.openFirewall {
|
||||
allowedTCPPorts = [cfg.port];
|
||||
};
|
||||
};
|
||||
|
||||
meta.maintainers = with lib.maintainers; [pbsds];
|
||||
}
|
||||
|
|
@ -15,7 +15,29 @@ in {
|
|||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.mullvad-vpn.enable = cfg.mullvad;
|
||||
services.mullvad-vpn = {
|
||||
enable = cfg.mullvad;
|
||||
package = nixos-stable.mullvad;
|
||||
};
|
||||
#
|
||||
# # Create a specific network namespace for VPN traffic
|
||||
# systemd.services.mullvad-daemon = {
|
||||
# serviceConfig = {
|
||||
# NetworkNamespacePath = "/run/netns/mullvad";
|
||||
# };
|
||||
# };
|
||||
#
|
||||
# # Configure transmission to use Mullvad's SOCKS5 proxy
|
||||
# # Configure transmission to use the Mullvad network namespace
|
||||
# systemd.services.transmission = mkIf config.services.transmission.enable {
|
||||
# serviceConfig = {
|
||||
# NetworkNamespacePath = "/run/netns/mullvad";
|
||||
# };
|
||||
# # Make sure Mullvad is running before transmission starts
|
||||
# requires = ["mullvad-daemon.service"];
|
||||
# after = ["mullvad-daemon.service"];
|
||||
# };
|
||||
|
||||
services.openvpn = {
|
||||
servers = {
|
||||
work = {
|
||||
|
|
@ -27,14 +49,21 @@ in {
|
|||
|
||||
systemd.services.openvpn-work.wantedBy = lib.mkForce [];
|
||||
|
||||
systemd.services."mullvad-daemon".postStart = let
|
||||
mullvad = config.services.mullvad-vpn.package;
|
||||
in
|
||||
mkIf cfg.mullvad ''
|
||||
while ! ${mullvad}/bin/mullvad status >/dev/null; do sleep 1; done
|
||||
${mullvad}/bin/mullvad auto-connect set on
|
||||
${mullvad}/bin/mullvad tunnel set ipv6 on
|
||||
${mullvad}/bin/mullvad connect
|
||||
'';
|
||||
# # Add necessary networking tools
|
||||
# environment.systemPackages = with pkgs; [
|
||||
# iproute2 # for ip netns commands
|
||||
# ];
|
||||
#
|
||||
# # Setup network namespace
|
||||
# systemd.services.setup-mullvad-netns = {
|
||||
# description = "Setup Mullvad Network Namespace";
|
||||
# before = ["mullvad-daemon.service"];
|
||||
# serviceConfig = {
|
||||
# Type = "oneshot";
|
||||
# RemainAfterExit = true;
|
||||
# ExecStart = "${pkgs.iproute2}/bin/ip netns add mullvad";
|
||||
# ExecStop = "${pkgs.iproute2}/bin/ip netns delete mullvad";
|
||||
# };
|
||||
# };
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,22 @@ in {
|
|||
recommendedOptimisation = true;
|
||||
recommendedTlsSettings = true;
|
||||
sslDhparam = config.security.dhparams.params.nginx.path;
|
||||
virtualHosts = {
|
||||
"node.nyc.zackmyers.io" = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
};
|
||||
};
|
||||
appendHttpConfig = ''
|
||||
limit_req_zone $binary_remote_addr zone=iso_ratelimit:10m rate=1r/m;
|
||||
limit_conn_zone $binary_remote_addr zone=iso_connlimit:10m;
|
||||
|
||||
access_log /var/log/nginx/blocked.log combined if=$ratelimited;
|
||||
|
||||
map $request_uri $ratelimited {
|
||||
default 0;
|
||||
~\.iso$ $limit_req_status;
|
||||
}
|
||||
'';
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "zach@zacharymyers.com";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
60
modules/nixos/services/wg/default.nix
Normal file
60
modules/nixos/services/wg/default.nix
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.custom; let
|
||||
cfg = config.services.wg;
|
||||
in {
|
||||
options.services.wg = with types; {
|
||||
enable = mkBoolOpt false "Enable wg service(s)";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
networking.nat.enable = false;
|
||||
networking.nat.externalInterface = "enp5s0";
|
||||
networking.nat.internalInterfaces = ["wg0"];
|
||||
networking.firewall = {
|
||||
allowedUDPPorts = [51820];
|
||||
|
||||
extraCommands = ''
|
||||
# Allow WireGuard peer to access only Jellyfin
|
||||
${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -s 10.100.0.2 -d 192.168.1.83 -j ACCEPT
|
||||
${pkgs.iptables}/bin/iptables -A FORWARD -i wg0 -s 10.100.0.3 -d 192.168.1.83 -j ACCEPT
|
||||
'';
|
||||
|
||||
extraStopCommands = ''
|
||||
# Clean up rules when stopping
|
||||
${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -s 10.100.0.2 -d 192.168.1.83 -j ACCEPT
|
||||
${pkgs.iptables}/bin/iptables -D FORWARD -i wg0 -s 10.100.0.3 -d 192.168.1.83 -j ACCEPT
|
||||
'';
|
||||
};
|
||||
|
||||
networking.wireguard.interfaces = {
|
||||
wg0 = {
|
||||
ips = ["10.100.0.1/24"];
|
||||
|
||||
listenPort = 51820;
|
||||
|
||||
privateKeyFile = "/home/zoey/wg-keys/private";
|
||||
|
||||
peers = [
|
||||
# List of allowed peers.
|
||||
{
|
||||
# Feel free to give a meaning full name
|
||||
# Public key of the peer (not a file path).
|
||||
publicKey = "oxcliwRzjiYda7x90lv71R/PnnPxIWSVIjSjiv2DyBQ=";
|
||||
# List of IPs assigned to this peer within the tunnel subnet. Used to configure routing.
|
||||
allowedIPs = ["10.100.0.2/32" "192.168.1.83/32"];
|
||||
}
|
||||
{
|
||||
publicKey = "+lWaMyRJOmijb3pSe8iufFO3lw2VW62uCn/ckJyAUxk=";
|
||||
allowedIPs = ["10.100.0.3/32" "192.168.1.83/32"];
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -27,7 +27,7 @@ in {
|
|||
root = "${inputs.resume.packages.${pkgs.system}.default}";
|
||||
};
|
||||
extraConfig = ''
|
||||
index resume.pdf;
|
||||
index ZacharyMyersResume.pdf;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ in {
|
|||
mkdir -p -m 0755 /nix/var/nix/profiles/per-user/root
|
||||
mkdir -p -m 0700 "$HOME/.nix-defexpr"
|
||||
. ${pkgs.nix}/etc/profile.d/nix-daemon.sh
|
||||
${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixos-24.05 nixpkgs # 3
|
||||
${pkgs.nix}/bin/nix-channel --add https://nixos.org/channels/nixos-24.11 nixpkgs # 3
|
||||
${pkgs.nix}/bin/nix-channel --update nixpkgs
|
||||
${pkgs.nix}/bin/nix-env -i ${concatStringsSep " " (with pkgs; [nix cacert git openssh])}
|
||||
'';
|
||||
|
|
|
|||
7
modules/nixos/sites/gitlab/sec/gitlab-runner.age
Normal file
7
modules/nixos/sites/gitlab/sec/gitlab-runner.age
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
age-encryption.org/v1
|
||||
-> ssh-ed25519 CtmR6w UnmasP/1wPHR+LhLwOPU8n8xmYxzSxnz3zvnIxhKngY
|
||||
bHwSyrccC/4a4X1nCSVR+Vl+Oi7Y1Sd5IzZjXVmkG5s
|
||||
-> ssh-ed25519 RMNffg 5EgurJJqitwKtwze+WrcNmfFolK29aW0nqLyRFShamY
|
||||
YsNxchVifSo+rBnhKsGYkVCxkHGmRH0FwnpLVjHYMH8
|
||||
--- 0RY2Pmkw1TKwh8hCJ55R/6IYHWZAXrKra+y82GsJWNk
|
||||
…®<>MÑPpÿVš9Ýc¥ÅP<Õ¨´8m<5<>{ˆÊ8ïCê^+[S”-²ªÞ^%,ò—˜0KÛ΀çºFDOµNbY†ts@¬ó™5§ÓE&Us¸‘P7È5å]ÇmPd˜h<CB9C>„ä¿ÎŽCz
|
||||
35
modules/nixos/sites/immich/default.nix
Normal file
35
modules/nixos/sites/immich/default.nix
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.custom; let
|
||||
cfg = config.sites.immich;
|
||||
in {
|
||||
options.sites.immich = with types; {
|
||||
enable = mkBoolOpt false "Enable Immich Photo backup";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.immich.enable = true;
|
||||
services.immich.port = 2283;
|
||||
|
||||
services.nginx.virtualHosts."i.zoeys.photos" = {
|
||||
enableACME = true;
|
||||
forceSSL = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://[::1]:${toString config.services.immich.port}";
|
||||
proxyWebsockets = true;
|
||||
recommendedProxySettings = true;
|
||||
extraConfig = ''
|
||||
client_max_body_size 50000M;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
send_timeout 600s;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -16,6 +16,22 @@ in {
|
|||
services.jellyfin = {
|
||||
enable = true;
|
||||
openFirewall = true;
|
||||
user = "zoey";
|
||||
group = "users";
|
||||
};
|
||||
|
||||
virtualisation.oci-containers = {
|
||||
containers.jellyfin-vue = {
|
||||
image = "ghcr.io/jellyfin/jellyfin-vue:unstable";
|
||||
environment = {
|
||||
"PUBLIC_JELLYFIN_API" = "http://localhost:8096";
|
||||
};
|
||||
ports = [
|
||||
"8065:80"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = [8065];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
22
modules/nixos/sites/mealie/default.nix
Normal file
22
modules/nixos/sites/mealie/default.nix
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.custom; let
|
||||
cfg = config.sites.mealie;
|
||||
in {
|
||||
options.sites.mealie = with types; {
|
||||
enable = mkBoolOpt false "Enable mealie";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.mealie = {
|
||||
enable = true;
|
||||
port = 9090;
|
||||
listenAddress = "127.0.0.1";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -38,6 +38,7 @@ in {
|
|||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
client_max_body_size 1G;
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -39,6 +39,18 @@ in {
|
|||
locations."/".extraConfig = ''
|
||||
autoindex on;
|
||||
'';
|
||||
|
||||
locations."~* \.iso$".extraConfig = ''
|
||||
limit_req zone=iso_ratelimit burst=20 nodelay;
|
||||
limit_conn iso_connlimit 5;
|
||||
limit_rate_after 10m;
|
||||
limit_rate 500k;
|
||||
|
||||
if ($http_user_agent ~* "Transmission") {
|
||||
access_log /var/log/nginx/blocked_transmission.log combined;
|
||||
return 403;
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
|
|||
131
modules/nixos/sites/polaris/default.nix
Normal file
131
modules/nixos/sites/polaris/default.nix
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
{
|
||||
lib,
|
||||
config,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
with lib;
|
||||
with lib.custom; let
|
||||
cfg = config.sites.polaris;
|
||||
|
||||
polaris-web = pkgs.buildNpmPackage rec {
|
||||
pname = "polaris-web";
|
||||
version = "76";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "agersant";
|
||||
repo = "polaris-web";
|
||||
rev = "build-${version}";
|
||||
hash = "sha256-mGsgW6lRqCt+K2RrF2s4zhvYzH94K+GEXGUCn5ngBTY=";
|
||||
};
|
||||
|
||||
npmDepsHash = "sha256-MVqC6mMdiqtJzAB8J8xdxO5xCwiibBasA3BvN6EiBSM=";
|
||||
|
||||
env.CYPRESS_INSTALL_BINARY = "0";
|
||||
|
||||
npmBuildScript = "build";
|
||||
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
mkdir -p $out/share
|
||||
cp -a dist $out/share/polaris-web
|
||||
|
||||
runHook postInstall
|
||||
'';
|
||||
};
|
||||
|
||||
polaris = pkgs.rustPlatform.buildRustPackage rec {
|
||||
pname = "polaris";
|
||||
version = "0.15.0";
|
||||
|
||||
src = pkgs.fetchFromGitHub {
|
||||
owner = "agersant";
|
||||
repo = "polaris";
|
||||
tag = version;
|
||||
hash = "sha256-uwYNyco4IY6lF+QSVEOVVhZCJ4nRkj8gsgRA0UydLHU=";
|
||||
|
||||
# The polaris version upstream in Cargo.lock is "0.0.0".
|
||||
# We're unable to simply patch it in the patch phase due to
|
||||
# rustPlatform.buildRustPackage fetching dependencies before applying patches.
|
||||
# If we patch it after fetching dependencies we get an error when
|
||||
# validating consistency between the final build and the prefetched deps.
|
||||
postFetch = ''
|
||||
# 'substituteInPlace' does not support multiline replacements?
|
||||
sed -i $out/Cargo.lock -z \
|
||||
-e 's/\[\[package\]\]\nname = "polaris"\nversion = "0.0.0"/[[package]]\nname = "polaris"\nversion = "'"${version}"'"/g'
|
||||
'';
|
||||
};
|
||||
|
||||
useFetchCargoVendor = true;
|
||||
cargoHash = "sha256-EUUxKLLdXgNp7GWTWAkzdNHKogu4Voo8wjeFFzM9iEg=";
|
||||
|
||||
# Compile-time environment variables for where to find assets needed at runtime
|
||||
env = {
|
||||
POLARIS_WEB_DIR = "${polaris-web}/share/polaris-web";
|
||||
};
|
||||
|
||||
preCheck = ''
|
||||
# 'Err' value: Os { code: 24, kind: Uncategorized, message: "Too many open files" }
|
||||
ulimit -n 4096
|
||||
# to debug bumps
|
||||
export RUST_BACKTRACE=1
|
||||
'';
|
||||
|
||||
checkFlags = [
|
||||
# requires network
|
||||
"--skip=server::test::settings::put_settings_golden_path"
|
||||
];
|
||||
|
||||
__darwinAllowLocalNetworking = true;
|
||||
|
||||
doCheck = false;
|
||||
|
||||
meta = with lib; {
|
||||
description = "Self-host your music collection, and access it from any computer and mobile device";
|
||||
longDescription = ''
|
||||
Polaris is a FOSS music streaming application, designed to let you enjoy your music collection
|
||||
from any computer or mobile device. Polaris works by streaming your music directly from your
|
||||
own computer, without uploading it to a third-party. There are no kind of premium version.
|
||||
The only requirement is that your computer stays on while it streams your music!
|
||||
'';
|
||||
homepage = "https://github.com/agersant/polaris";
|
||||
license = licenses.mit;
|
||||
maintainers = with maintainers; [pbsds];
|
||||
platforms = platforms.unix;
|
||||
mainProgram = "polaris";
|
||||
};
|
||||
};
|
||||
in {
|
||||
options.sites.polaris = with types; {
|
||||
enable = mkBoolOpt false "Enable Music (Polaris)";
|
||||
|
||||
domain = mkStringOpt "music.zoeys.cloud" "The domain of the music instance";
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.polaris2 = {
|
||||
enable = true;
|
||||
package = polaris;
|
||||
# group = "users";
|
||||
# user = "zoey";
|
||||
openFirewall = true;
|
||||
settings = {
|
||||
mount_dirs = [
|
||||
{
|
||||
name = "local";
|
||||
source = "/home/zoey/Music/";
|
||||
}
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
services.nginx.virtualHosts.${cfg.domain} = {
|
||||
forceSSL = true;
|
||||
enableACME = true;
|
||||
locations."/" = {
|
||||
proxyPass = "http://localhost:${toString config.services.polaris.port}";
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
|
@ -31,53 +31,7 @@ in {
|
|||
dejavu_fonts
|
||||
iosevka
|
||||
cantarell-fonts
|
||||
# (let
|
||||
# bolder = writeText "bolder.py" ''
|
||||
# #!/usr/bin/env python
|
||||
# # Script shamelessly stolen from: https://github.com/shytikov/pragmasevka
|
||||
#
|
||||
# import sys
|
||||
# import fontforge
|
||||
#
|
||||
# if len(sys.argv) < 2:
|
||||
# print("Please provide path prefix of the font to update!")
|
||||
# exit()
|
||||
#
|
||||
# prefix = sys.argv[1]
|
||||
#
|
||||
# glyphs = [
|
||||
# "exclam", "ampersand", "parenleft", "parenright", "asterisk", "plus",
|
||||
# "comma", "hyphen", "period", "slash", "colon", "semicolon", "less",
|
||||
# "equal", "greater", "question", "bracketleft", "backslash", "bracketright",
|
||||
# "asciicircum", "braceleft", "bar", "braceright", "asciitilde",
|
||||
# ]
|
||||
#
|
||||
# pairs = [
|
||||
# ['regular', 'semibold'],
|
||||
# ['regularItalic', 'semiboldItalic'],
|
||||
# ['bold', 'black'],
|
||||
# ['boldItalic', 'blackItalic'],
|
||||
# ]
|
||||
#
|
||||
# for [recipient, donor] in pairs:
|
||||
# font = f"{prefix}{recipient}.ttf"
|
||||
# donor_font = f"{prefix}{donor}.ttf"
|
||||
#
|
||||
# target = fontforge.open(font)
|
||||
# # Finding all punctuation
|
||||
# target.selection.select(*glyphs)
|
||||
# # and deleting it to make space
|
||||
# for i in target.selection.byGlyphs:
|
||||
# target.removeGlyph(i)
|
||||
#
|
||||
# source = fontforge.open(donor_font)
|
||||
# source.selection.select(*glyphs)
|
||||
# source.copy()
|
||||
# target.paste()
|
||||
#
|
||||
# target.generate(font)
|
||||
# '';
|
||||
# in (iosevka.override
|
||||
# (iosevka.override
|
||||
# {
|
||||
# set = "Custom";
|
||||
# privateBuildPlan = ''
|
||||
|
|
@ -90,34 +44,20 @@ in {
|
|||
#
|
||||
# [buildPlans.IosevkaCustom.variants]
|
||||
# inherits = "ss08"
|
||||
#
|
||||
# [buildPlans.IosevkaCustom.widths.Normal]
|
||||
# shape = 500
|
||||
# menu = 5
|
||||
# css = "normal"
|
||||
# '';
|
||||
# }))
|
||||
# .overrideAttrs (oldAttrs: {
|
||||
# buildInputs =
|
||||
# (oldAttrs.buildInputs or [])
|
||||
# ++ [
|
||||
# pkgs.python3
|
||||
# pkgs.python3Packages.fontforge
|
||||
# ];
|
||||
#
|
||||
# postInstall = ''
|
||||
# ${oldAttrs.postInstall or ""}
|
||||
#
|
||||
# echo $out
|
||||
#
|
||||
# cd $out/share/fonts/truetype
|
||||
#
|
||||
# PREFIX="IosevkaCustom-normal"
|
||||
#
|
||||
# python3 ${bolder} $PREFIX
|
||||
# '';
|
||||
# }))
|
||||
# })
|
||||
noto-fonts
|
||||
noto-fonts-cjk-sans
|
||||
noto-fonts-emoji
|
||||
jetbrains-mono
|
||||
nerd-fonts.iosevka
|
||||
nerd-fonts.zed-mono
|
||||
adwaita-fonts
|
||||
# (nerdfonts.override {fonts = ["ZedMono" "Iosevka"];})
|
||||
];
|
||||
|
||||
|
|
@ -127,11 +67,11 @@ in {
|
|||
fontconfig = {
|
||||
defaultFonts = {
|
||||
monospace = [
|
||||
"Pragmata Pro Mono"
|
||||
# "Iosevka"
|
||||
# "Pragmata Pro Mono"
|
||||
"Iosevka"
|
||||
"Noto Color Emoji"
|
||||
];
|
||||
sansSerif = ["Cantarell" "Noto Color Emoji"];
|
||||
sansSerif = ["Adwaita Sans" "Noto Color Emoji"];
|
||||
serif = ["Noto Serif" "Noto Color Emoji"];
|
||||
emoji = ["Noto Color Emoji"];
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue