Compare commits

...

39 commits

Author SHA1 Message Date
Bruno BELANYI 5cae5632d3 flake: bump inputs
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-12-21 17:06:37 -05:00
Bruno BELANYI b7b6705391 home: wm: i3: make 'arandr' float
All checks were successful
ci/woodpecker/push/check Pipeline was successful
Another work-around due to a wrapper in nixpkgs.
2024-12-18 20:48:09 -05:00
Bruno BELANYI ead8101b8d home: wm: i3: match 'blueman' float explicitly
This is more of a work-around due to the wrapper in nixpkgs' packaging
of that application, so might as well make that explicit and narrow.
2024-12-18 20:48:09 -05:00
Bruno BELANYI c75a307c58 home: wm: i3: fix 'pavucontrol' float
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-12-18 20:39:15 -05:00
Bruno BELANYI f4f1aad1c0 pkgs: fix shell formatting
All checks were successful
ci/woodpecker/push/check Pipeline was successful
Ran `shfmt --write --indent 4 --simplify --case-indent`, in accordance
with my editor settings.
2024-12-18 20:35:34 -05:00
Bruno BELANYI 322fbc970b home: vim: lsp: rely on 'bashls' formatting
All checks were successful
ci/woodpecker/push/check Pipeline was successful
I finally figured out why I was getting the wrong indentation, turns out
it was an issue in `lsp-format.nvim`. With that fixed/worked around, I
can now rely completely on `bash-language-server` for formatting.

I'll also rely on `shfmt` automatically detecting the type of file, as
(Neo)Vim cannot be made to reliably set `ft=bash` for Bash scripts and
`ft=sh` for POSIX shell.

Finally, I removed spaces after redirections, I've now come around to
liking the default (no spaces) better.
2024-12-18 20:20:28 -05:00
Bruno BELANYI 92e5fbe7df overlays: add 'lsp-format-nvim-indentation'
To fix the issue I reported upstream [1].

[1]: https://github.com/lukas-reineke/lsp-format.nvim/issues/94
2024-12-18 20:13:03 -05:00
Bruno BELANYI 747b344b76 pkgs: remove 'cgt-calc'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
It's been merged upstream.
2024-12-15 18:39:27 -05:00
Bruno BELANYI dec5dabf02 modules: services: postgres: upgrade version
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-12-16 00:20:18 +01:00
Bruno BELANYI b2d2ff1798 nixos: services: postgres: fix renamed option 2024-12-16 00:19:31 +01:00
Bruno BELANYI c5a375d165 nixos: services: paperless: use automatic DB setup
That way I don't have to worry about the `postgresql.service` dependency
anymore :-).
2024-12-11 01:40:14 +01:00
Bruno BELANYI cb5eb68d35 flake: bump inputs
And fix deprecated NUR overlay attribute.
2024-12-11 01:40:10 +01:00
Bruno BELANYI 19120bca29 nixos: hardware: graphics: use 'initrd' option
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-12-08 16:08:48 -05:00
Bruno BELANYI 35c547a090 home: tmux: enable focus events
All checks were successful
ci/woodpecker/push/check Pipeline was successful
Since `tmux-sensible` was disabled by default, we should enable this
explicitly now.
2024-12-08 10:44:26 -05:00
Bruno BELANYI ad1cfbd6f0 flake: bump inputs
Allow-list the build inputs for `sonarr` until the package is fixed
upstream [1].

[1]: https://github.com/NixOS/nixpkgs/issues/360592
2024-12-08 10:44:26 -05:00
Bruno BELANYI baa853477d nixos: hardware: sound: remove ALSA
`sound.enable` was removed from the latest release, and is unnecessary
with PulseAudio.
2024-12-08 10:44:26 -05:00
Bruno BELANYI 3ac85b8762 home: packages: add 'tree' 2024-12-08 10:44:26 -05:00
Bruno BELANYI c74acda957 nixos: system: packages: remove 'wget' 2024-12-08 10:44:26 -05:00
Bruno BELANYI 98c90d77c5 home: tmux: add sloppy window switching bindings
Another set of bindings which were setup by `tmux-sensible`, that I want
to enable explicitly to avoid issues when it is disabled by default.
2024-12-08 10:44:26 -05:00
Bruno BELANYI b38658405a home: tmux: add binding to refresh configuration
Don't rely on `tmux-sensible` to set it up.
2024-11-28 18:39:09 +00:00
Bruno BELANYI da3c29bbaf home: xdg: add comment about 'tig'
To explain why I didn't modify it as part of my `$XDG_STATE_HOME`
migration in fbd3b70d61.
2024-11-28 12:07:52 +00:00
Bruno BELANYI 8b61af1ac3 home: xdg: remove 'gdb' directory
I have an actual module to configure `gdb`, and it uses
`$XDG_STATE_HOME` anyway...
2024-11-28 12:07:12 +00:00
Bruno BELANYI e8a41187e7 home: xdg: create 'HISTFILE' parent directory
In fbd3b70d61, I forgot to modify the
`.keep` file to be created in `$XDG_STATE_HOME/bash/`.
2024-11-28 12:06:03 +00:00
Bruno BELANYI 83da7ba9c8 home: tmux: explicitly disable mouse support
All checks were successful
ci/woodpecker/push/check Pipeline was successful
It's disabled by default, but make it explicit :-).
2024-11-28 11:24:34 +00:00
Bruno BELANYI f2168378fc home: direnv: lib: also watch '.python-version'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
It's used by `uv` as a kind of configuration file, so watch it as well.
2024-11-27 15:12:10 +00:00
Bruno BELANYI e39fef275c nixos: services: paperless: use 'environmentFile'
All checks were successful
ci/woodpecker/push/check Pipeline was successful
That way I don't have to configure all services to make use of it.

Someday I'll find the will to add the `postgresql.service` dependency
upstream, truly removing the need to configure any service at all.
2024-11-27 12:05:41 +00:00
Bruno BELANYI fe49e47026 flake: bump inputs 2024-11-27 12:02:29 +00:00
Bruno BELANYI 6a5c4a627a nixos: services: pyload: add fail2ban jail
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-11-20 21:06:17 +01:00
Bruno BELANYI 7f0cd6612e nixos: services: paperless: remove MKL work-around
Instead, rely on the upstream service's work-around [1].

This will reduce the amount of package builds I need to do when updating
my server...

[1]: https://github.com/NixOS/nixpkgs/pull/299008

This reverts commit e2ec4d3032.
2024-11-20 21:06:17 +01:00
Bruno BELANYI 2ffbc13513 flake: bump inputs 2024-11-20 21:06:17 +01:00
Bruno BELANYI 60050113bc nixos: services: nginx: modify example
All checks were successful
ci/woodpecker/push/check Pipeline was successful
Now that `websocketLocations` exists, it makes little sense to use
`proxyWebsockets` in an example, so use a different one.
2024-11-19 16:03:38 +00:00
Bruno BELANYI 6a1a35a384 nixos: services: migrate to 'websocketsLocations' 2024-11-19 16:03:38 +00:00
Bruno BELANYI e9d96138d5 nixos: services: nginx: add 'websocketsLocations'
This accounts for the overwhelming majority of my usage of
`extraConfig`.
2024-11-19 16:03:38 +00:00
Bruno BELANYI ae230b5df7 hosts: porthos: services: enable collabora
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-11-19 15:58:48 +01:00
Bruno BELANYI 138d4d2bd9 nixos: services: nextcloud: add collabora
This needs to be configured through the "Nextcloud Office" app,
specifically the WOPI setting is important for security (I put both the
external IP, as well as `::1` and `127.0.0.1`).
2024-11-19 15:58:48 +01:00
Bruno BELANYI ab8a5daefe hosts: porthos: secrets: acme: use OVH API
All checks were successful
ci/woodpecker/push/check Pipeline was successful
I switched registrar, as OVH was ~4x cheaper.

This needs a small change to the module to both refer to OVH instead of
Gandi in the documentation, and make use of the correct API.

I also needed to disable the propagation check, as it looks like OVH is
slower than Gandi, and leads to spurious errors...
2024-11-14 22:19:35 +01:00
Bruno BELANYI 7b42368e2f hosts: nixos: porthos: services: remove tandoor
All checks were successful
ci/woodpecker/push/check Pipeline was successful
I fully transitioned to using Mealie instead.

This reverts commit 493636decb.
2024-11-11 11:45:11 +00:00
Bruno BELANYI 46bd23ff07 flake: bump inputs
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-11-06 10:53:58 +00:00
Bruno BELANYI 62de2772a4 home: vim: do not italicize comments
All checks were successful
ci/woodpecker/push/check Pipeline was successful
2024-11-05 15:54:18 +00:00
36 changed files with 265 additions and 227 deletions

View file

@ -73,11 +73,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1727826117, "lastModified": 1733312601,
"narHash": "sha256-K5ZLCyfO/Zj9mPFldf3iwS6oZStJcU4tSpiXTMYaaL0=", "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=",
"owner": "hercules-ci", "owner": "hercules-ci",
"repo": "flake-parts", "repo": "flake-parts",
"rev": "3d04084d54bedc3d6b8b736c70ef449225c361b1", "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -94,11 +94,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1726560853, "lastModified": 1731533236,
"narHash": "sha256-X6rJYSESBVr3hBoH0WbKE5KvhPU5bloyZ2L4K60/fPQ=", "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide", "owner": "numtide",
"repo": "flake-utils", "repo": "flake-utils",
"rev": "c1dfcf08411b08f6b8615f7d8971a2bfa81d5e8a", "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -136,11 +136,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1729864948, "lastModified": 1734808199,
"narHash": "sha256-CeGSqbN6S8JmzYJX/HqZjr7dMGlvHLLnJJarwB45lPs=", "narHash": "sha256-MxlUcLjE8xLbrI1SJ2B2jftlg4wdutEILa3fgqwA98I=",
"owner": "nix-community", "owner": "nix-community",
"repo": "home-manager", "repo": "home-manager",
"rev": "0c0268a3c80d30b989d0aadbd65f38d4fa27a9a0", "rev": "f342df3ad938f205a913973b832f52c12546aac6",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -152,11 +152,11 @@
}, },
"nixpkgs": { "nixpkgs": {
"locked": { "locked": {
"lastModified": 1729665710, "lastModified": 1734424634,
"narHash": "sha256-AlcmCXJZPIlO5dmFzV3V2XF6x/OpNWUV8Y/FMPGd8Z4=", "narHash": "sha256-cHar1vqHOOyC7f1+tVycPoWTfKIaqkoe1Q6TnKzuti4=",
"owner": "NixOS", "owner": "NixOS",
"repo": "nixpkgs", "repo": "nixpkgs",
"rev": "2768c7d042a37de65bb1b5b3268fc987e534c49d", "rev": "d3c42f187194c26d9f0309a8ecc469d6c878ce33",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -167,12 +167,21 @@
} }
}, },
"nur": { "nur": {
"inputs": {
"flake-parts": [
"flake-parts"
],
"nixpkgs": [
"nixpkgs"
],
"treefmt-nix": "treefmt-nix"
},
"locked": { "locked": {
"lastModified": 1729868220, "lastModified": 1734810357,
"narHash": "sha256-OxHE1U+FIIaQ50nZpt/VxLH0bokiqsEqAshehlHhOFs=", "narHash": "sha256-Oa6d+y1/PVaPrZ/GYwvmTK9kSrc5Qx/8D3DFN2TzpVA=",
"owner": "nix-community", "owner": "nix-community",
"repo": "NUR", "repo": "NUR",
"rev": "70b30d23d33ca2acfb267430b08ddf82ff7116b2", "rev": "e7b7b92a7c97a91f1465ab433bbdf6d00df1db8e",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -194,11 +203,11 @@
] ]
}, },
"locked": { "locked": {
"lastModified": 1729104314, "lastModified": 1734797603,
"narHash": "sha256-pZRZsq5oCdJt3upZIU4aslS9XwFJ+/nVtALHIciX/BI=", "narHash": "sha256-ulZN7ps8nBV31SE+dwkDvKIzvN6hroRY8sYOT0w+E28=",
"owner": "cachix", "owner": "cachix",
"repo": "pre-commit-hooks.nix", "repo": "pre-commit-hooks.nix",
"rev": "3c3e88f0f544d6bb54329832616af7eb971b6be6", "rev": "f0f0dc4920a903c3e08f5bdb9246bb572fcae498",
"type": "github" "type": "github"
}, },
"original": { "original": {
@ -235,6 +244,27 @@
"repo": "default", "repo": "default",
"type": "github" "type": "github"
} }
},
"treefmt-nix": {
"inputs": {
"nixpkgs": [
"nur",
"nixpkgs"
]
},
"locked": {
"lastModified": 1733222881,
"narHash": "sha256-JIPcz1PrpXUCbaccEnrcUS8jjEb/1vJbZz5KkobyFdM=",
"owner": "numtide",
"repo": "treefmt-nix",
"rev": "49717b5af6f80172275d47a418c9719a31a78b53",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "treefmt-nix",
"type": "github"
}
} }
}, },
"root": "root", "root": "root",

View file

@ -55,6 +55,10 @@
owner = "nix-community"; owner = "nix-community";
repo = "NUR"; repo = "NUR";
ref = "master"; ref = "master";
inputs = {
flake-parts.follows = "flake-parts";
nixpkgs.follows = "nixpkgs";
};
}; };
pre-commit-hooks = { pre-commit-hooks = {

View file

@ -25,7 +25,7 @@ let
inherit system; inherit system;
overlays = (lib.attrValues self.overlays) ++ [ overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlay inputs.nur.overlays.default
]; ];
}; };

View file

@ -7,7 +7,7 @@ let
} }
{ {
nixpkgs.overlays = (lib.attrValues self.overlays) ++ [ nixpkgs.overlays = (lib.attrValues self.overlays) ++ [
inputs.nur.overlay inputs.nur.overlays.default
]; ];
} }
# Include generic settings # Include generic settings

View file

@ -1,8 +1,9 @@
age-encryption.org/v1 age-encryption.org/v1
-> ssh-ed25519 cKojmg bQFr9oAnbo1rI/MpUV8wQz/Xj7iZY4ZU+Swf0nSIQFw -> ssh-ed25519 cKojmg Ec0xt1uJTva8MxUdoTVX5m3uWaIiRlodf345FEM7Uzs
zama2XJ0gdvUlD2GHMhmZqHSxHe+dKSfXnHoWDcSw7Y aJIneWFJPB5HVeoUGp57agXih9YeZ6xMEbyQ+zJtWQY
-> ssh-ed25519 jPowng gitUwSKTNKWLSxnwa185O7x/u0ul93g8wPESdZaKRk8 -> ssh-ed25519 jPowng B5XotRgv7s/FUegGhceBj7EoukewNUOIFl4TFRQf1EQ
uvBIfAUkZp5sg6rfeEGvL5ZDV8m2uSEotW02kjPN3Hw PgGCBd/Pqwp7ayqi7okHBGF1SfFpwT4KlHJ/np6p2uQ
--- SZxe5f/CUZBvPQa2Sz/UBY3L68rMkIGGRuZPk7YE+Vg --- AeLgwGz6k3OABb53cXNaCU/sgI4FlU1s6p8PhAaFOlg
¾r ú&…¥‹{~v?¨}=Ä 1ÌÉCÔ¹ð¤ŽULfI1¸Hm»Ûòb}m” ÁÅ¡ìg•ß0¦¢–¤`X<16>G>\>¹8rŽz+ŠY ™¼`—Ê¢.JBUÏ!z¸Z50ú*õ¡ÙŸ¤×ÖÇ®I<C2AE>ôÔ]¹Ïå I
}+ ¿SQM[²]Œ±k MÒAàtŒÃmMë/£µLsü|Þ…m©CÀñiYC}ƒŽ‡çxŽ€ ĵ<18>¿oÒÛ°…g„®„ÒêÁ³Â¿Ÿt©nƒºãcz[»{
jçå&ÁõõNæ°Nÿo{õš½‚ -eP¾=L‰™ 6¦.SP:»e¶

View file

@ -95,6 +95,9 @@ in
nextcloud = { nextcloud = {
enable = true; enable = true;
passwordFile = secrets."nextcloud/password".path; passwordFile = secrets."nextcloud/password".path;
collabora = {
enable = true;
};
}; };
nix-cache = { nix-cache = {
enable = true; enable = true;
@ -149,11 +152,6 @@ in
}; };
# Because I still need to play sysadmin # Because I still need to play sysadmin
ssh-server.enable = true; ssh-server.enable = true;
# Recipe manager
tandoor-recipes = {
enable = true;
secretKeyFile = secrets."tandoor-recipes/secret-key".path;
};
# Torrent client and webui # Torrent client and webui
transmission = { transmission = {
enable = true; enable = true;

View file

@ -53,4 +53,5 @@ layout_uv() {
PATH_add "$VIRTUAL_ENV/bin" PATH_add "$VIRTUAL_ENV/bin"
watch_file pyproject.toml watch_file pyproject.toml
watch_file uv.lock watch_file uv.lock
watch_file .python-version
} }

View file

@ -26,6 +26,7 @@ in
fd fd
file file
ripgrep ripgrep
tree
] ++ cfg.additionalPackages); ] ++ cfg.additionalPackages);
nixpkgs.config = { nixpkgs.config = {

View file

@ -47,6 +47,8 @@ in
clock24 = true; # I'm one of those heathens clock24 = true; # I'm one of those heathens
escapeTime = 0; # Let vim do its thing instead escapeTime = 0; # Let vim do its thing instead
historyLimit = 100000; # Bigger buffer historyLimit = 100000; # Bigger buffer
mouse = false; # I dislike mouse support
focusEvents = true; # Report focus events
terminal = "tmux-256color"; # I want accurate termcap info terminal = "tmux-256color"; # I want accurate termcap info
plugins = with pkgs.tmuxPlugins; [ plugins = with pkgs.tmuxPlugins; [
@ -80,6 +82,13 @@ in
]; ];
extraConfig = '' extraConfig = ''
# Refresh configuration
bind-key -N "Source tmux.conf" R source-file ${config.xdg.configHome}/tmux/tmux.conf \; display-message "Sourced tmux.conf!"
# Accept sloppy Ctrl key when switching windows, on top of default mapping
bind-key -N "Select the previous window" C-p previous-window
bind-key -N "Select the next window" C-n next-window
# Better vim mode # Better vim mode
bind-key -T copy-mode-vi 'v' send -X begin-selection bind-key -T copy-mode-vi 'v' send -X begin-selection
${ ${

View file

@ -102,7 +102,11 @@ gruvbox.setup({
DiffText = { fg = colors.yellow, bg = colors.bg0 }, DiffText = { fg = colors.yellow, bg = colors.bg0 },
-- Directories "pop" better in blue -- Directories "pop" better in blue
Directory = { link = "GruvboxBlueBold" }, Directory = { link = "GruvboxBlueBold" },
} },
italic = {
-- Comments should not be italic, for e.g: box drawing
comments = false,
},
}) })
EOF EOF
" Use my preferred colorscheme " Use my preferred colorscheme

View file

@ -74,6 +74,16 @@ if utils.is_executable("bash-language-server") then
filetypes = { "bash", "sh", "zsh" }, filetypes = { "bash", "sh", "zsh" },
capabilities = capabilities, capabilities = capabilities,
on_attach = lsp.on_attach, on_attach = lsp.on_attach,
settings = {
bashIde = {
shfmt = {
-- Simplify the code
simplifyCode = true,
-- Indent switch cases
caseIndent = true,
},
},
},
}) })
end end

View file

@ -46,29 +46,3 @@ null_ls.register({
condition = utils.is_executable_condition("isort"), condition = utils.is_executable_condition("isort"),
}), }),
}) })
-- Shell (non-POSIX)
null_ls.register({
null_ls.builtins.formatting.shfmt.with({
-- Indent with 4 spaces, simplify the code, indent switch cases,
-- add space after redirection, use bash dialect
extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "bash" },
-- Restrict to bash and zsh
filetypes = { "bash", "zsh" },
-- Only used if available
condition = utils.is_executable_condition("shfmt"),
}),
})
-- Shell (POSIX)
null_ls.register({
null_ls.builtins.formatting.shfmt.with({
-- Indent with 4 spaces, simplify the code, indent switch cases,
-- add space after redirection, use POSIX
extra_args = { "-i", "4", "-s", "-ci", "-sr", "-ln", "posix" },
-- Restrict to POSIX sh
filetypes = { "sh" },
-- Only used if available
condition = utils.is_executable_condition("shfmt"),
}),
})

View file

@ -127,9 +127,10 @@ in
{ class = "^Blueman-.*$"; } { class = "^Blueman-.*$"; }
{ title = "^htop$"; } { title = "^htop$"; }
{ class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; } { class = "^Thunderbird$"; instance = "Mailnews"; window_role = "filterlist"; }
{ class = "^Pavucontrol.*$"; } { class = "^pavucontrol.*$"; }
{ class = "^Arandr$"; } { class = "^Arandr$"; }
{ class = ".?blueman-manager.*$"; } { class = "^\\.blueman-manager-wrapped$"; }
{ class = "^\\.arandr-wrapped$"; }
]; ];
}; };

View file

@ -30,11 +30,10 @@ in
}; };
# A tidy home is a tidy mind # A tidy home is a tidy mind
dataFile = { dataFile = {
"bash/.keep".text = ""; "tig/.keep".text = ""; # `tig` uses `XDG_DATA_HOME` specifically...
"gdb/.keep".text = "";
"tig/.keep".text = "";
}; };
stateFile = { stateFile = {
"bash/.keep".text = "";
"python/.keep".text = ""; "python/.keep".text = "";
}; };
}; };

View file

@ -33,9 +33,8 @@ in
# AMD GPU # AMD GPU
(lib.mkIf (cfg.gpuFlavor == "amd") { (lib.mkIf (cfg.gpuFlavor == "amd") {
boot.initrd.kernelModules = lib.mkIf cfg.amd.enableKernelModule [ "amdgpu" ];
hardware.amdgpu = { hardware.amdgpu = {
initrd.enable = cfg.amd.enableKernelModule;
# Vulkan # Vulkan
amdvlk = lib.mkIf cfg.amd.amdvlk { amdvlk = lib.mkIf cfg.amd.amdvlk {
enable = true; enable = true;

View file

@ -54,9 +54,6 @@ in
# Pulseaudio setup # Pulseaudio setup
(lib.mkIf cfg.pulse.enable { (lib.mkIf cfg.pulse.enable {
# ALSA
sound.enable = true;
hardware.pulseaudio.enable = true; hardware.pulseaudio.enable = true;
}) })
]); ]);

View file

@ -65,9 +65,7 @@ in
aria-rpc = { aria-rpc = {
port = cfg.rpcPort; port = cfg.rpcPort;
# Proxy websockets for RPC # Proxy websockets for RPC
extraConfig = { websocketsLocations = [ "/" ];
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -30,9 +30,7 @@ in
audiobookshelf = { audiobookshelf = {
inherit (cfg) port; inherit (cfg) port;
# Proxy websockets for RPC # Proxy websockets for RPC
extraConfig = { websocketsLocations = [ "/" ];
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -27,17 +27,13 @@ in
my.services.nginx.virtualHosts = { my.services.nginx.virtualHosts = {
jellyfin = { jellyfin = {
port = 8096; port = 8096;
websocketsLocations = [ "/socket" ];
extraConfig = { extraConfig = {
locations."/" = { locations."/" = {
extraConfig = '' extraConfig = ''
proxy_buffering off; proxy_buffering off;
''; '';
}; };
# Too bad for the repetition...
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
};
}; };
}; };
}; };

View file

@ -0,0 +1,50 @@
# Document editor with Nextcloud
{ config, lib, ... }:
let
cfg = config.my.services.nextcloud.collabora;
in
{
options.my.services.nextcloud.collabora = with lib; {
enable = mkEnableOption "Collabora integration";
port = mkOption {
type = types.port;
default = 9980;
example = 8080;
description = "Internal port for API";
};
};
config = lib.mkIf cfg.enable {
services.collabora-online = {
enable = true;
inherit (cfg) port;
aliasGroups = [
{
host = "https://collabora.${config.networking.domain}";
# Allow using from nextcloud
aliases = [ "https://${config.services.nextcloud.hostName}" ];
}
];
settings = {
# Rely on reverse proxy for SSL
ssl = {
enable = false;
termination = true;
};
};
};
my.services.nginx.virtualHosts = {
collabora = {
inherit (cfg) port;
websocketsLocations = [
"~ ^/cool/(.*)/ws$"
"^~ /cool/adminws"
];
};
};
};
}

View file

@ -4,6 +4,10 @@ let
cfg = config.my.services.nextcloud; cfg = config.my.services.nextcloud;
in in
{ {
imports = [
./collabora.nix
];
options.my.services.nextcloud = with lib; { options.my.services.nextcloud = with lib; {
enable = mkEnableOption "Nextcloud"; enable = mkEnableOption "Nextcloud";
maxSize = mkOption { maxSize = mkOption {

View file

@ -17,6 +17,16 @@ let
''; '';
}; };
websocketsLocations = mkOption {
type = with types; listOf str;
default = [ ];
example = [ "/socket" ];
description = ''
Which locations on this virtual host should be configured for
websockets.
'';
};
port = mkOption { port = mkOption {
type = with types; nullOr port; type = with types; nullOr port;
default = null; default = null;
@ -60,10 +70,13 @@ let
extraConfig = mkOption { extraConfig = mkOption {
type = types.attrs; # FIXME: forward type of virtualHosts type = types.attrs; # FIXME: forward type of virtualHosts
example = { example = {
locations."/socket" = { extraConfig = ''
proxyPass = "http://127.0.0.1:8096/"; add_header X-Clacks-Overhead "GNU Terry Pratchett";
proxyWebsockets = true; '';
};
locations."/".extraConfig = ''
client_max_body_size 1G;
'';
}; };
default = { }; default = { };
description = '' description = ''
@ -86,7 +99,7 @@ in
type = types.str; type = types.str;
example = "/var/lib/acme/creds.env"; example = "/var/lib/acme/creds.env";
description = '' description = ''
Gandi API key file as an 'EnvironmentFile' (see `systemd.exec(5)`) OVH API key file as an 'EnvironmentFile' (see `systemd.exec(5)`)
''; '';
}; };
}; };
@ -108,12 +121,7 @@ in
}; };
jellyfin = { jellyfin = {
port = 8096; port = 8096;
extraConfig = { websocketsLocations = [ "/socket" ];
locations."/socket" = {
proxyPass = "http://127.0.0.1:8096/";
proxyWebsockets = true;
};
};
}; };
}; };
description = '' description = ''
@ -195,6 +203,19 @@ in
} configured. } configured.
''; '';
})) }))
++ (lib.flip lib.mapAttrsToList cfg.virtualHosts (_: { subdomain, ... } @ args:
let
proxyPass = [ "port" "socket" ];
proxyPassUsed = lib.any (v: args.${v} != null) proxyPass;
in
{
assertion = args.websocketsLocations != [ ] -> proxyPassUsed;
message = ''
Subdomain '${subdomain}' can only use 'websocketsLocations' with one of ${
lib.concatStringsSep ", " (builtins.map (v: "'${v}'") proxyPass)
}.
'';
}))
++ ( ++ (
let let
ports = lib.my.mapFilter ports = lib.my.mapFilter
@ -241,6 +262,14 @@ in
virtualHosts = virtualHosts =
let let
domain = config.networking.domain; domain = config.networking.domain;
mkProxyPass = { websocketsLocations, ... }: proxyPass:
let
websockets = lib.genAttrs websocketsLocations (_: {
inherit proxyPass;
proxyWebsockets = true;
});
in
{ "/" = { inherit proxyPass; }; } // websockets;
mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair mkVHost = ({ subdomain, ... } @ args: lib.nameValuePair
"${subdomain}.${domain}" "${subdomain}.${domain}"
(lib.my.recursiveMerge [ (lib.my.recursiveMerge [
@ -251,8 +280,7 @@ in
} }
# Proxy to port # Proxy to port
(lib.optionalAttrs (args.port != null) { (lib.optionalAttrs (args.port != null) {
locations."/".proxyPass = locations = mkProxyPass args "http://127.0.0.1:${toString args.port}";
"http://127.0.0.1:${toString args.port}";
}) })
# Serve filesystem content # Serve filesystem content
(lib.optionalAttrs (args.root != null) { (lib.optionalAttrs (args.root != null) {
@ -260,8 +288,7 @@ in
}) })
# Serve to UNIX socket # Serve to UNIX socket
(lib.optionalAttrs (args.socket != null) { (lib.optionalAttrs (args.socket != null) {
locations."/".proxyPass = locations = mkProxyPass args "http://unix:${args.socket}";
"http://unix:${args.socket}";
}) })
# Redirect to a different domain # Redirect to a different domain
(lib.optionalAttrs (args.redirect != null) { (lib.optionalAttrs (args.redirect != null) {
@ -281,6 +308,7 @@ in
locations."/" = { locations."/" = {
extraConfig = extraConfig =
# FIXME: check that X-User is dropped otherwise
(args.extraConfig.locations."/".extraConfig or "") + '' (args.extraConfig.locations."/".extraConfig or "") + ''
# Use SSO # Use SSO
auth_request /sso-auth; auth_request /sso-auth;
@ -414,7 +442,8 @@ in
{ {
"${domain}" = { "${domain}" = {
extraDomainNames = [ "*.${domain}" ]; extraDomainNames = [ "*.${domain}" ];
dnsProvider = "gandiv5"; dnsProvider = "ovh";
dnsPropagationCheck = false; # OVH is slow
inherit (cfg.acme) credentialsFile; inherit (cfg.acme) credentialsFile;
}; };
}; };

View file

@ -1,4 +1,4 @@
{ config, lib, pkgs, ... }: { config, lib, ... }:
let let
cfg = config.my.services.paperless; cfg = config.my.services.paperless;
in in
@ -61,11 +61,6 @@ in
PAPERLESS_ENABLE_HTTP_REMOTE_USER = true; PAPERLESS_ENABLE_HTTP_REMOTE_USER = true;
PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER"; PAPERLESS_HTTP_REMOTE_USER_HEADER_NAME = "HTTP_X_USER";
# Use PostgreSQL
PAPERLESS_DBHOST = "/run/postgresql";
PAPERLESS_DBUSER = "paperless";
PAPERLESS_DBNAME = "paperless";
# Security settings # Security settings
PAPERLESS_ALLOWED_HOSTS = paperlessDomain; PAPERLESS_ALLOWED_HOSTS = paperlessDomain;
PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}"; PAPERLESS_CORS_ALLOWED_HOSTS = "https://${paperlessDomain}";
@ -80,63 +75,18 @@ in
# Misc # Misc
PAPERLESS_TIME_ZONE = config.time.timeZone; PAPERLESS_TIME_ZONE = config.time.timeZone;
PAPERLESS_ADMIN_USER = cfg.username; PAPERLESS_ADMIN_USER = cfg.username;
# Fix classifier hangs
LD_LIBRARY_PATH = "${lib.getLib pkgs.mkl}/lib";
}; };
# Admin password # Admin password
passwordFile = cfg.passwordFile; passwordFile = cfg.passwordFile;
};
systemd.services = { # Secret key
paperless-scheduler = { environmentFile = cfg.secretKeyFile;
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = { # Automatic PostgreSQL provisioning
EnvironmentFile = cfg.secretKeyFile; database = {
}; createLocally = true;
}; };
paperless-consumer = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-web = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
paperless-task-queue = {
requires = [ "postgresql.service" ];
after = [ "postgresql.service" ];
serviceConfig = {
EnvironmentFile = cfg.secretKeyFile;
};
};
};
# Set-up database
services.postgresql = {
enable = true;
ensureDatabases = [ "paperless" ];
ensureUsers = [
{
name = "paperless";
ensureDBOwnership = true;
}
];
}; };
# Set-up media group # Set-up media group
@ -152,11 +102,7 @@ in
sso = { sso = {
enable = true; enable = true;
}; };
websocketsLocations = [ "/" ];
# Enable websockets on root
extraConfig = {
locations."/".proxyWebsockets = true;
};
}; };
}; };

View file

@ -14,7 +14,7 @@ in
# Let other services enable postgres when they need it # Let other services enable postgres when they need it
(lib.mkIf cfg.enable { (lib.mkIf cfg.enable {
services.postgresql = { services.postgresql = {
package = pkgs.postgresql_13; package = pkgs.postgresql_17;
}; };
}) })
@ -23,15 +23,15 @@ in
environment.systemPackages = environment.systemPackages =
let let
pgCfg = config.services.postgresql; pgCfg = config.services.postgresql;
newPackage' = pkgs.postgresql_13; newPackage' = pkgs.postgresql_17;
oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package; oldPackage = if pgCfg.enableJIT then pgCfg.package.withJIT else pgCfg.package;
oldData = pgCfg.dataDir; oldData = pgCfg.dataDir;
oldBin = "${if pgCfg.extraPlugins == [] then oldPackage else oldPackage.withPackages pgCfg.extraPlugins}/bin"; oldBin = "${if pgCfg.extensions == [] then oldPackage else oldPackage.withPackages pgCfg.extensions}/bin";
newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage'; newPackage = if pgCfg.enableJIT then newPackage'.withJIT else newPackage';
newData = "/var/lib/postgresql/${newPackage.psqlSchema}"; newData = "/var/lib/postgresql/${newPackage.psqlSchema}";
newBin = "${if pgCfg.extraPlugins == [] then newPackage else newPackage.withPackages pgCfg.extraPlugins}/bin"; newBin = "${if pgCfg.extensions == [] then newPackage else newPackage.withPackages pgCfg.extensions}/bin";
in in
[ [
(pkgs.writeScriptBin "upgrade-pg-cluster" '' (pkgs.writeScriptBin "upgrade-pg-cluster" ''

View file

@ -53,6 +53,20 @@ in
}; };
}; };
# FIXME: fail2ban services.fail2ban.jails = {
pyload = ''
enabled = true
filter = pyload
port = http,https
'';
};
environment.etc = {
"fail2ban/filter.d/pyload.conf".text = ''
[Definition]
failregex = ^.*Login failed for user '<F-USER>.*</F-USER>' \[CLIENT: <HOST>\]$
journalmatch = _SYSTEMD_UNIT=pyload.service
'';
};
}; };
} }

View file

@ -96,5 +96,15 @@ in
# Sonarr for shows # Sonarr for shows
(mkFullConfig "sonarr") (mkFullConfig "sonarr")
(mkFail2Ban "sonarr") (mkFail2Ban "sonarr")
# HACK: until https://github.com/NixOS/nixpkgs/issues/360592 is resolved
(lib.mkIf cfg.sonarr.enable {
nixpkgs.config.permittedInsecurePackages = [
"aspnetcore-runtime-6.0.36"
"aspnetcore-runtime-wrapped-6.0.36"
"dotnet-sdk-6.0.428"
"dotnet-sdk-wrapped-6.0.428"
];
})
]); ]);
} }

View file

@ -1,5 +1,5 @@
# Common packages # Common packages
{ config, lib, pkgs, ... }: { config, lib, ... }:
let let
cfg = config.my.system.packages; cfg = config.my.system.packages;
in in
@ -13,10 +13,6 @@ in
}; };
config = lib.mkIf cfg.enable { config = lib.mkIf cfg.enable {
environment.systemPackages = with pkgs; [
wget
];
programs = { programs = {
vim = { vim = {
enable = true; enable = true;

View file

@ -0,0 +1,4 @@
self: prev:
{
vimPlugins = prev.vimPlugins.extend (self.callPackage ./generated.nix { });
}

View file

@ -0,0 +1,14 @@
{ fetchpatch, ... }:
_final: prev: {
lsp-format-nvim = prev.lsp-format-nvim.overrideAttrs (oa: {
patches = (oa.patches or [ ]) ++ [
# https://github.com/lukas-reineke/lsp-format.nvim/issues/94
(fetchpatch {
name = "use-effective-indentation";
url = "https://github.com/liskin/lsp-format.nvim/commit/3757ac443bdf5bd166673833794553229ee8d939.patch";
hash = "sha256-Dv+TvXrU/IrrPxz2MSPbLmRxch+qkHbI3AyFMj/ssDk=";
})
];
});
}

View file

@ -66,7 +66,7 @@ query_password() {
printf '%s\n' "$PASSWORD" printf '%s\n' "$PASSWORD"
} }
if [ $# -lt 1 ] || [ $# -gt 2 ]; then if [ $# -lt 1 ] || [ $# -gt 2 ]; then
usage usage
exit 1 exit 1
fi fi

View file

@ -1,47 +0,0 @@
{ lib
, fetchFromGitHub
, python3Packages
, withTeXLive ? true
, texliveSmall
}:
python3Packages.buildPythonApplication rec {
pname = "cgt-calc";
version = "1.13.0";
pyproject = true;
src = fetchFromGitHub {
owner = "KapJI";
repo = "capital-gains-calculator";
rev = "v${version}";
hash = "sha256-y/Y05wG89nccXyxfjqazyPJhd8dOkfwRJre+Rzx97Hw=";
};
build-system = with python3Packages; [
poetry-core
];
dependencies = with python3Packages; [
defusedxml
jinja2
pandas
requests
types-requests
yfinance
];
makeWrapperArgs = lib.optionals withTeXLive [
"--prefix"
"PATH"
":"
"${lib.getBin texliveSmall}/bin"
];
meta = with lib; {
description = "UK capital gains tax calculator";
homepage = "https://github.com/KapJI/capital-gains-calculator";
license = with licenses; [ mit ];
mainProgram = "cgt-calc";
maintainers = with maintainers; [ ambroisie ];
platforms = platforms.unix;
};
}

View file

@ -62,7 +62,7 @@ do_toggle() {
} }
case "$1" in case "$1" in
up|down) up | down)
do_change_volume "$@" do_change_volume "$@"
;; ;;
toggle) toggle)

View file

@ -2,8 +2,6 @@
pkgs.lib.makeScope pkgs.newScope (pkgs: { pkgs.lib.makeScope pkgs.newScope (pkgs: {
bw-pass = pkgs.callPackage ./bw-pass { }; bw-pass = pkgs.callPackage ./bw-pass { };
cgt-calc = pkgs.callPackage ./cgt-calc { };
change-audio = pkgs.callPackage ./change-audio { }; change-audio = pkgs.callPackage ./change-audio { };
change-backlight = pkgs.callPackage ./change-backlight { }; change-backlight = pkgs.callPackage ./change-backlight { };

View file

@ -81,23 +81,23 @@ parse_args() {
shift shift
case "$opt" in case "$opt" in
-h|--help) -h | --help)
usage usage
exit exit
;; ;;
-f|--flake-output) -f | --flake-output)
FLAKE_OUTPUTS+=("$1") FLAKE_OUTPUTS+=("$1")
shift shift
;; ;;
-o|--output) -o | --output)
OUTPUT_FILE="$1" OUTPUT_FILE="$1"
shift shift
;; ;;
-n|--new-rev) -n | --new-rev)
NEW_REV="$(git rev-parse "$1")" NEW_REV="$(git rev-parse "$1")"
shift shift
;; ;;
-p|--previous-rev) -p | --previous-rev)
PREVIOUS_REV="$(git rev-parse "$1")" PREVIOUS_REV="$(git rev-parse "$1")"
shift shift
;; ;;
@ -157,7 +157,7 @@ list_dev_shells() {
} }
diff_output() { diff_output() {
local PREV NEW; local PREV NEW
PREV="$(mktemp --dry-run)" PREV="$(mktemp --dry-run)"
NEW="$(mktemp --dry-run)" NEW="$(mktemp --dry-run)"
@ -169,7 +169,7 @@ diff_output() {
printf 'Closure diff for `%s`:\n```\n' "$1" printf 'Closure diff for `%s`:\n```\n' "$1"
nix store diff-closures "$PREV" "$NEW" | sanitize_output nix store diff-closures "$PREV" "$NEW" | sanitize_output
printf '```\n\n' printf '```\n\n'
} >> "$OUTPUT_FILE" } >>"$OUTPUT_FILE"
} }
parse_args "$@" parse_args "$@"

View file

@ -15,7 +15,7 @@ usage() {
exec 1>&2 exec 1>&2
fi fi
cat << EOF cat <<EOF
Usage: $0 [options] [string] Usage: $0 [options] [string]
Send an arbitrary string to the terminal clipboard using the OSC 52 escape Send an arbitrary string to the terminal clipboard using the OSC 52 escape
sequence as specified in xterm: sequence as specified in xterm:

View file

@ -13,7 +13,7 @@ usage() {
exec 1>&2 exec 1>&2
fi fi
cat << EOF cat <<EOF
Usage: $0 [options] <title> <message> Usage: $0 [options] <title> <message>
Send a notification (title and message) to the host system using the OSC 777 Send a notification (title and message) to the host system using the OSC 777
escape sequence: escape sequence: