From 274e08f50faffe1b8e4a760811b0a12450eae719 Mon Sep 17 00:00:00 2001 From: Linnnus Date: Tue, 20 Feb 2024 19:00:53 +0100 Subject: Merge 'reorg' into 'main' This patch moves in the reorganizational work done on the reorg branch, mainly: * Move host-specific modules into hosts// * Break up HM config See the reorg branch for the individual commits. --- flake.nix | 15 +-- home/default.nix | 2 - home/iterm2/default.nix | 26 ------ home/neovim/completion.nix | 1 - home/neovim/default.nix | 3 +- home/neovim/editing-plugins.nix | 26 ++++++ home/neovim/lsp.nix | 109 ---------------------- home/neovim/plugins.nix | 90 ------------------ home/noweb/default.nix | 12 --- hosts/ahmed/cloudflare-proxy/default.nix | 88 +++++++++++++++++ hosts/ahmed/configuration.nix | 43 +++------ hosts/ahmed/disable-screen/default.nix | 61 ++++++++++++ hosts/ahmed/duksebot/default.nix | 61 ++++++++++++ hosts/ahmed/forsvarsarper/default.nix | 58 ++++++++++++ hosts/ahmed/forsvarsarper/script.py | 28 ++++++ hosts/ahmed/git.linus.onl/about.html | 5 + hosts/ahmed/git.linus.onl/default.nix | 84 +++++++++++++++++ hosts/ahmed/hellohtml.linus.onl/default.nix | 51 ++++++++++ hosts/ahmed/home/default.nix | 9 ++ hosts/ahmed/linus.onl/default.nix | 93 ++++++++++++++++++ hosts/ahmed/nofitications.linus.onl/default.nix | 24 +++++ hosts/ahmed/ssh.nix | 19 ---- hosts/ahmed/ssh/default.nix | 19 ++++ hosts/muhammed/configuration.nix | 4 + hosts/muhammed/home/default.nix | 10 ++ hosts/muhammed/home/iterm2/default.nix | 26 ++++++ hosts/muhammed/home/neovim/conjure.nix | 71 ++++++++++++++ hosts/muhammed/home/neovim/default.nix | 8 ++ hosts/muhammed/home/neovim/lsp.nix | 107 +++++++++++++++++++++ hosts/muhammed/home/noweb/default.nix | 12 +++ modules/darwin/default.nix | 3 +- modules/nixos/cloudflare-proxy/default.nix | 109 ---------------------- modules/nixos/default.nix | 19 +--- modules/nixos/disable-screen/default.nix | 61 ------------ modules/nixos/duksebot/default.nix | 72 -------------- modules/nixos/forsvarsarper/default.nix | 65 ------------- modules/nixos/forsvarsarper/script.py | 28 ------ modules/nixos/git.linus.onl/about.html | 5 - modules/nixos/git.linus.onl/default.nix | 95 ------------------- modules/nixos/graphics/default.nix | 37 -------- modules/nixos/hellohtml.linus.onl/default.nix | 60 ------------ modules/nixos/linus.onl/default.nix | 100 -------------------- modules/nixos/nofitications.linus.onl/default.nix | 34 ------- 43 files changed, 866 insertions(+), 987 deletions(-) delete mode 100644 home/iterm2/default.nix create mode 100644 home/neovim/editing-plugins.nix delete mode 100644 home/neovim/lsp.nix delete mode 100644 home/neovim/plugins.nix delete mode 100644 home/noweb/default.nix create mode 100644 hosts/ahmed/cloudflare-proxy/default.nix create mode 100644 hosts/ahmed/disable-screen/default.nix create mode 100644 hosts/ahmed/duksebot/default.nix create mode 100644 hosts/ahmed/forsvarsarper/default.nix create mode 100644 hosts/ahmed/forsvarsarper/script.py create mode 100644 hosts/ahmed/git.linus.onl/about.html create mode 100644 hosts/ahmed/git.linus.onl/default.nix create mode 100644 hosts/ahmed/hellohtml.linus.onl/default.nix create mode 100644 hosts/ahmed/home/default.nix create mode 100644 hosts/ahmed/linus.onl/default.nix create mode 100644 hosts/ahmed/nofitications.linus.onl/default.nix delete mode 100644 hosts/ahmed/ssh.nix create mode 100644 hosts/ahmed/ssh/default.nix create mode 100644 hosts/muhammed/home/default.nix create mode 100644 hosts/muhammed/home/iterm2/default.nix create mode 100644 hosts/muhammed/home/neovim/conjure.nix create mode 100644 hosts/muhammed/home/neovim/default.nix create mode 100644 hosts/muhammed/home/neovim/lsp.nix create mode 100644 hosts/muhammed/home/noweb/default.nix delete mode 100644 modules/nixos/cloudflare-proxy/default.nix delete mode 100644 modules/nixos/disable-screen/default.nix delete mode 100644 modules/nixos/duksebot/default.nix delete mode 100644 modules/nixos/forsvarsarper/default.nix delete mode 100644 modules/nixos/forsvarsarper/script.py delete mode 100644 modules/nixos/git.linus.onl/about.html delete mode 100644 modules/nixos/git.linus.onl/default.nix delete mode 100644 modules/nixos/graphics/default.nix delete mode 100644 modules/nixos/hellohtml.linus.onl/default.nix delete mode 100644 modules/nixos/linus.onl/default.nix delete mode 100644 modules/nixos/nofitications.linus.onl/default.nix diff --git a/flake.nix b/flake.nix index 588bf98..f9142a0 100644 --- a/flake.nix +++ b/flake.nix @@ -44,13 +44,6 @@ metadata = nixpkgs.lib.importTOML ./metadata.toml; }; - darwinModules = - builtins.attrValues (import ./modules/darwin).general - ++ builtins.attrValues (import ./modules/darwin).personal; - nixosModules = - builtins.attrValues (import ./modules/nixos).general - ++ builtins.attrValues (import ./modules/nixos).personal; - # This is a function that generates an attribute by calling a function # you pass to it, with each system as an argument. `systems` lists all # supported systems. @@ -75,7 +68,7 @@ ./hosts/common.nix ./home ] - ++ darwinModules; + ++ builtins.attrValues (import ./modules/darwin); }; }; @@ -92,7 +85,7 @@ ./hosts/common.nix ./home ] - ++ nixosModules; + ++ builtins.attrValues (import ./modules/nixos); }; }; @@ -111,8 +104,8 @@ overlays = import ./overlays; # We export the generally applicable modules. - darwinModules = (import ./modules/darwin).geneal; - nixosModules = (import ./modules/nixos).general; + darwinModules = import ./modules/darwin; homeModules = import ./modules/home-manager; + nixosModules = import ./modules/nixos; }; } diff --git a/home/default.nix b/home/default.nix index 93c3720..d02e7b3 100644 --- a/home/default.nix +++ b/home/default.nix @@ -22,8 +22,6 @@ ./git ./dev-utils ./networking-utils - ./iterm2 - ./noweb ] ++ builtins.attrValues flakeOutputs.homeModules; diff --git a/home/iterm2/default.nix b/home/iterm2/default.nix deleted file mode 100644 index d868e57..0000000 --- a/home/iterm2/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -# This file configures iterm2. Note that the actual definition of iTerm2 for -# home-manager is in `modules/home-manager/iterm2`. *That* file declares -# `options.programs.iterm2.enable`. -{ - pkgs, - lib, - ... -}: let - inherit (lib) mkIf; - inherit (pkgs.stdenv) isDarwin; -in { - config = mkIf isDarwin { - home.packages = with pkgs; [imgcat]; - - programs.iterm2 = { - enable = true; - # config = { - # # Use the minimal tab style. - # # See: https://github.com/gnachman/iTerm2/blob/bd40fba0611fa94684dadf2478625f2a93eb6e47/sources/iTermPreferences.h#L29 - # TabStyleWithAutomaticOption = 5; - # }; - - shellIntegration.enableZshIntegration = true; - }; - }; -} diff --git a/home/neovim/completion.nix b/home/neovim/completion.nix index 904491d..3776674 100644 --- a/home/neovim/completion.nix +++ b/home/neovim/completion.nix @@ -43,6 +43,5 @@ cmp-calc cmp-buffer cmp-path - cmp-conjure ]; } diff --git a/home/neovim/default.nix b/home/neovim/default.nix index 1739047..56f6171 100644 --- a/home/neovim/default.nix +++ b/home/neovim/default.nix @@ -1,10 +1,9 @@ # This file contains the HM configuration options for Neovim. {...}: { imports = [ - ./lsp.nix ./filetype.nix ./completion.nix - ./plugins.nix + ./editing-plugins.nix ]; programs.neovim = { diff --git a/home/neovim/editing-plugins.nix b/home/neovim/editing-plugins.nix new file mode 100644 index 0000000..23c7d63 --- /dev/null +++ b/home/neovim/editing-plugins.nix @@ -0,0 +1,26 @@ +# This module sets up and configures various miscellaneous plugins. +# TODO: I fear this file will become the utils.lua of my Neovim configuration. Remove it! +{pkgs, ...}: { + programs.neovim.plugins = [ + { + plugin = pkgs.vimPlugins.vim-localvimrc; + type = "viml"; + config = '' + let g:localvimrc_persistent = 1 + let g:localvimrc_name = [ "local.vim", "editors/local.vim" ] + ''; + } + { + plugin = pkgs.vimPlugins.vim-sneak; + type = "viml"; + config = '' + let g:sneak#s_next = 1 + let g:sneak#use_ic_scs = 1 + map f Sneak_f + map F Sneak_F + map t Sneak_t + map T Sneak_T + ''; + } + ]; +} diff --git a/home/neovim/lsp.nix b/home/neovim/lsp.nix deleted file mode 100644 index 0c2e290..0000000 --- a/home/neovim/lsp.nix +++ /dev/null @@ -1,109 +0,0 @@ -# This module sets up LSP server configurations for Neovim. It is waaay -# overcomplicated as it kind of turned into an experiment in generating Lua -# code from a Nix attrset. -{pkgs, ...}: { - programs.neovim.plugins = [ - { - plugin = pkgs.vimPlugins.nvim-lspconfig; - type = "lua"; - config = '' - local lspconfig = require("lspconfig") - local util = require("lspconfig.util") - - -- Mappings. - -- See `:help vim.diagnostic.*` for documentation on any of the below functions - local opts = { noremap=true, silent=true } - vim.keymap.set('n', 'e', vim.diagnostic.open_float, opts) - vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) - vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) - vim.keymap.set('n', 'q', vim.diagnostic.setloclist, opts) - - -- Use an on_attach function to only map the following keys - -- after the language server attaches to the current buffer - local on_attach = function(client, bufnr) - -- Enable completion triggered by - vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') - - -- Mappings. - -- See `:help vim.lsp.*` for documentation on any of the below functions - local bufopts = { noremap=true, silent=true, buffer=bufnr } - vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) - vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) - vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts) - vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) - vim.keymap.set('n', '', vim.lsp.buf.signature_help, bufopts) - vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, bufopts) - vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, bufopts) - vim.keymap.set('n', 'wl', function() - print(vim.inspect(vim.lsp.buf.list_workspace_folders())) - end, bufopts) - vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, bufopts) - vim.keymap.set('n', 'rn', vim.lsp.buf.rename, bufopts) - vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) - vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) - vim.keymap.set('n', 'f', function() vim.lsp.buf.format { async = true } end, bufopts) - vim.keymap.set('n', 's', function() vim.cmd[[ClangdSwitchSourceHeader]] end, bufopts) - end - - -- Use a loop to conveniently call 'setup' on multiple servers and - -- map buffer local keybindings when the language server attaches - local servers = { - pyright = { cmd = { "${pkgs.pyright}/bin/pyright-langserver", "--stdio" } }, - nixd = { cmd = { "${pkgs.nixd}/bin/nixd" } }, - denols = { - init_options = { - enable = true, - unstable = true, - lint = true, - }, - cmd = { "${pkgs.unstable.deno}/bin/deno", "lsp", "--unstable" }, - root_dir = function(startpath) - if util.find_package_json_ancestor(startpath) then - -- This is a Node project; let tsserver handle this one. - return nil - else - -- Otherwise, we try to find the root or - -- default to the current directory. - return util.root_pattern("deno.json", "deno.jsonc", ".git")(startpath) - or util.path.dirname(startpath) - end - end, - }, - clangd = { - cmd = { "${pkgs.clang-tools}/bin/clangd" }, - }, - nimls = { - cmd = { "${pkgs.nimlsp}/bin/nimlsp" }, - }, - }; - for server, config in pairs(servers) do - -- set common options - config.on_attach = on_attach; - config.debounce_text_changes = 150; - - lspconfig[server].setup(config) - end - ''; - } - ]; -} -# I spent like an hour writing this, only to find it was a pretty bad idea. -# -# nixToLua = s: -# if builtins.isAttrs s then -# let -# renderAttr = name: value: "[ [==========[" + name + "]==========] ] = " + (nixToLua value); -# attrsList = map (name: renderAttr name s.${name}) (lib.attrNames s); -# attrsListStr = lib.concatStringsSep ", " attrsList; -# in -# "{ ${attrsListStr} }" -# else if builtins.isList s then -# "{ " + (lib.concatStringsSep ", " (map nixToLua s)) + " }" -# else if builtins.isString s then -# # Oh boy I sure hope `s` doesn't contain "]==========]". -# "[==========[" + s + "]==========]" -# else if builtins.isInt s || builtins.isFloat s then -# toString s -# else -# throw "Cannot convert ${builtins.typeOf s} to Lua value!"; - diff --git a/home/neovim/plugins.nix b/home/neovim/plugins.nix deleted file mode 100644 index 54f6d9d..0000000 --- a/home/neovim/plugins.nix +++ /dev/null @@ -1,90 +0,0 @@ -# This module sets up and configures various miscellaneous plugins. -# TODO: I fear this file will become the utils.lua of my Neovim configuration. Remove it! -{pkgs, ...}: { - programs.neovim.plugins = [ - { - plugin = pkgs.vimPlugins.vim-localvimrc; - type = "viml"; - config = '' - let g:localvimrc_persistent = 1 - let g:localvimrc_name = [ "local.vim", "editors/local.vim" ] - ''; - } - { - plugin = pkgs.vimPlugins.vim-sneak; - type = "viml"; - config = '' - let g:sneak#s_next = 1 - let g:sneak#use_ic_scs = 1 - map f Sneak_f - map F Sneak_F - map t Sneak_t - map T Sneak_T - ''; - } - { - # Add interactive repl-like environment. - # See also the addition of cmp-conjure in `completion.nix`. - # See also the addition of clojure in `dev-utils/default.nix`. - plugin = pkgs.vimPlugins.conjure; - type = "lua"; - config = '' - local start_clj_repl = "StartCljRepl"; - local start_lein_repl = "StartLeinRepl"; - - -- Create a command to launch nRepl for Clojure support. - -- See: https://github.com/Olical/conjure/wiki/Quick-start:-Clojure - vim.api.nvim_create_user_command(start_clj_repl, function() - local id = vim.fn.jobstart({ - "${pkgs.clojure}/bin/clj", - "-Sdeps", - '{:deps {nrepl/nrepl {:mvn/version "1.0.0"} cider/cider-nrepl {:mvn/version "0.40.0"}}}', - "--main", - "nrepl.cmdline", - "--middleware", - '["cider.nrepl/cider-middleware"]', - "--interactive", - }) - print("Started nRepl job #" .. id) - end, { - desc = "Starts an nRepl session in the current directory using clj.", - }) - - vim.api.nvim_create_user_command(start_lein_repl, function() - local id = vim.fn.jobstart({ - "${pkgs.leiningen}/bin/lein", - "repl", - }) - print("Started nRepl job #" .. id) - end, { - desc = "Starts an nRepl session in the current directory using Lein.", - }) - - -- Launch nRepl when any clojure file is started. - -- vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, { - -- pattern = "*.clj", - -- command = start_clj_repl, - -- }); - - -- Use Guile to evaluate scheme buffers. - local start_guile_repl = "StartGuileRepl"; - local sock_path = "/tmp/guile-repl.sock" - vim.g["conjure#filetype#scheme"] = "conjure.client.guile.socket" - vim.g["conjure#client#guile#socket#pipename"] = sock_path - vim.api.nvim_create_user_command(start_guile_repl, function() - local id = vim.fn.jobstart({ - "${pkgs.guile}/bin/guile", - "--listen=" .. sock_path, - }) - print("Started Guile job #" .. id) - end, { - desc = "Starts an Guile repl session listening on " .. sock_path, - }) - - -- Jump to bottom of log when new evaluation happens - -- See: https://github.com/Olical/conjure/blob/58c46d1f4999679659a5918284b574c266a7ac83/doc/conjure.txt#L872 - vim.cmd [[autocmd User ConjureEval if expand("%:t") =~ "^conjure-log-" | exec "normal G" | endif]] - ''; - } - ]; -} diff --git a/home/noweb/default.nix b/home/noweb/default.nix deleted file mode 100644 index ef67862..0000000 --- a/home/noweb/default.nix +++ /dev/null @@ -1,12 +0,0 @@ -{pkgs, ...}: { - home.packages = with pkgs; [ - noweb - texliveFull - yalafi-shell - ]; - - # Prepend nowebs STY files to the search path. I chose to do it globally, - # rather than using `makeWrapper` because I sometimes want to manually invoke - # `pdflatex` and the like on the output of `noweave`. - home.sessionVariables.TEXINPUTS = "${pkgs.noweb.tex}/tex/latex/noweb/:$TEXINPUTS"; -} diff --git a/hosts/ahmed/cloudflare-proxy/default.nix b/hosts/ahmed/cloudflare-proxy/default.nix new file mode 100644 index 0000000..45ccaa6 --- /dev/null +++ b/hosts/ahmed/cloudflare-proxy/default.nix @@ -0,0 +1,88 @@ +# This module adds some extra configuration useful when running behid a Cloudflare Proxy. +# Mainly, it blocks all incomming conncections on relevant ports that aren't +# coming from an official CloudFlare domain. +{ + config, + lib, + pkgs, + metadata, + ... +}: let + # TODO: What happens when these get out of date??? Huh??? You little pissbaby + fileToList = x: lib.strings.splitString "\n" (builtins.readFile x); + cfipv4 = fileToList (pkgs.fetchurl { + url = "https://www.cloudflare.com/ips-v4"; + hash = "sha256-8Cxtg7wBqwroV3Fg4DbXAMdFU1m84FTfiE5dfZ5Onns="; + }); + cfipv6 = fileToList (pkgs.fetchurl { + url = "https://www.cloudflare.com/ips-v6"; + hash = "sha256-np054+g7rQDE3sr9U8Y/piAp89ldto3pN9K+KCNMoKk="; + }); + + IPv4Whitelist = [metadata.hosts.muhammed.ipAddress]; + IPv6Whitelist = []; +in { + config = { + # Teach NGINX how to extract the proxied IP from proxied requests. + # + # See: https://nixos.wiki/wiki/Nginx#Using_realIP_when_behind_CloudFlare_or_other_CDN + services.nginx.commonHttpConfig = let + realIpsFromList = lib.strings.concatMapStringsSep "\n" (x: "set_real_ip_from ${x};"); + in '' + ${realIpsFromList cfipv4} + ${realIpsFromList cfipv6} + real_ip_header CF-Connecting-IP; + ''; + + # Block non-Cloudflare IP addresses. + networking.firewall = let + chain = "cloudflare-whitelist"; + in { + extraCommands = let + allow-interface = lib.strings.concatMapStringsSep "\n" (i: ''ip46tables --append ${chain} --in-interface ${i} --jump RETURN''); + allow-ip = cmd: lib.strings.concatMapStringsSep "\n" (r: ''${cmd} --append ${chain} --source ${r} --jump RETURN''); + in '' + # Flush the old firewall rules. This behavior mirrors the default firewall service. + # See: https://github.com/NixOS/nixpkgs/blob/ac911bf685eecc17c2df5b21bdf32678b9f88c92/nixos/modules/services/networking/firewall-iptables.nix#L59-L66 + ip46tables --delete INPUT --protocol tcp --destination-port 80 --syn --jump ${chain} 2>/dev/null || true + ip46tables --delete INPUT --protocol tcp --destination-port 443 --syn --jump ${chain} 2>/dev/null || true + ip46tables --flush ${chain} || true + ip46tables --delete-chain ${chain} || true + + # Create a chain that only allows whitelisted IPs through. + ip46tables --new-chain ${chain} + + # Allow trusted interfaces through. + ${allow-interface config.networking.firewall.trustedInterfaces} + + # Allow local whitelisted IPs through + ${allow-ip "iptables" IPv4Whitelist} + ${allow-ip "ip6tables" IPv6Whitelist} + + # Allow Cloudflare's IP ranges through. + ${allow-ip "iptables" cfipv4} + ${allow-ip "ip6tables" cfipv6} + + # Everything else is dropped. + # + # TODO: I would like to use `nixos-fw-log-refuse` here, but I keep + # running into weird issues when reloading the firewall. + # Something about the table not being deleted properly. + ip46tables --append ${chain} --jump DROP + + # Inject our chain as the first check in INPUT (before nixos-fw). + # We want to capture any new incomming TCP connections. + ip46tables --insert INPUT 1 --protocol tcp --destination-port 80 --syn --jump ${chain} + ip46tables --insert INPUT 1 --protocol tcp --destination-port 443 --syn --jump ${chain} + ''; + extraStopCommands = '' + # Clean up added rulesets (${chain}). This mirrors the behavior of the + # default firewall at the time of writing. + # + # See: https://github.com/NixOS/nixpkgs/blob/ac911bf685eecc17c2df5b21bdf32678b9f88c92/nixos/modules/services/networking/firewall-iptables.nix#L218-L219 + ip46tables --delete INPUT --protocol tcp --destination-port 80 --syn --jump ${chain} 2>/dev/null || true + ip46tables --delete INPUT --protocol tcp --destination-port 443 --syn --jump ${chain} 2>/dev/null || true + ''; + }; + }; +} diff --git a/hosts/ahmed/configuration.nix b/hosts/ahmed/configuration.nix index e0eb202..27c35eb 100644 --- a/hosts/ahmed/configuration.nix +++ b/hosts/ahmed/configuration.nix @@ -3,12 +3,21 @@ { config, pkgs, - metadata, ... }: { imports = [ ./hardware-configuration.nix - ./ssh.nix + + ./cloudflare-proxy + ./disable-screen + ./duksebot + ./forsvarsarper + ./git.linus.onl + ./hellohtml.linus.onl + ./linus.onl + ./nofitications.linus.onl + ./ssh + ./home ]; # Create the main user. @@ -47,31 +56,11 @@ }; services.cloudflare-dyndns.domains = ["minecraft.linus.onl"]; - # Set up dukse server. Det er satme hårdt at være overduksepåmindelsesansvarlig. - services.duksebot.enable = true; - # Virtual hosts. + # Each module for a HTTP service will register a virtual host. services.nginx.enable = true; - modules."linus.onl" = { - enable = true; - useACME = true; - }; - modules."notifications.linus.onl" = { - enable = true; - useACME = true; - }; - modules."git.linus.onl" = { - enable = true; - useACME = true; - }; - modules."hellohtml.linus.onl" = { - enable = true; - useACME = true; - }; - - services.forsvarsarper.enable = true; - # Configure ACME for various HTTPS services. + # Configure ACME. This is used by various HTTP services through the NGINX virtual hosts. security.acme = { acceptTerms = true; defaults.email = "linusvejlo+${config.networking.hostName}-acme@gmail.com"; @@ -94,12 +83,6 @@ # Listen for HTTP connections. networking.firewall.allowedTCPPorts = [80 443]; - # We are running behind CF proxy. - modules.cloudflare-proxy = { - enable = true; - firewall.IPv4Whitelist = [metadata.hosts.muhammed.ipAddress]; - }; - # This value determines the NixOS release from which the default # settings for stateful data, like file locations and database versions # on your system were taken. It's perfectly fine and recommended to leave diff --git a/hosts/ahmed/disable-screen/default.nix b/hosts/ahmed/disable-screen/default.nix new file mode 100644 index 0000000..638437a --- /dev/null +++ b/hosts/ahmed/disable-screen/default.nix @@ -0,0 +1,61 @@ +# This file defines some configuration options which disable the screen. This +# is only relevant because this host is an old laptop running as a server. +{ + lib, + config, + ... +}: let + inherit (lib) mkEnableOption mkOption mkIf types; + + cfg = config.services.disable-screen; +in { + options.services.disable-screen = { + enable = mkEnableOption "disable screen"; + + device-path = mkOption { + description = "Path to the device in the `/sys` file system."; + type = types.str; + example = "/sys/class/backlight/intel_backlight"; + }; + + device-unit = mkOption { + description = "The systemd device unit that corresponds to the device speciefied in `device-path`."; + type = types.str; + example = "sys-devices-pci...-intel_backligt.device"; + }; + }; + + config = mkIf cfg.enable { + # Disable sleep on lid close. + services.logind = let + lidSwitchAction = "ignore"; + in { + lidSwitchExternalPower = lidSwitchAction; + lidSwitchDocked = lidSwitchAction; + lidSwitch = lidSwitchAction; + }; + + # Don't store screen brightness between boots. We always want to turn off the + # screen. + # + # See: https://wiki.archlinux.org/title/backlight#Save_and_restore_functionality + # See: https://github.com/NixOS/nixpkgs/blob/990398921f677615c0732d704857484b84c6c888/nixos/modules/system/boot/systemd.nix#L97-L101 + systemd.suppressedSystemUnits = ["systemd-backlight@.service"]; + + # FIXME: Figure out how to enable screen when on-device debugging is necessary. + # Create a new service which turns off the display on boot. + # + # See: https://nixos.wiki/wiki/Backlight#.2Fsys.2Fclass.2Fbacklight.2F... + # See: https://superuser.com/questions/851846/how-to-write-a-systemd-service-that-depends-on-a-device-being-present + systemd.services.disable-screen = { + requires = [cfg.device-unit]; + after = [cfg.device-unit]; + wantedBy = [cfg.device-unit]; + + serviceConfig.Type = "oneshot"; + script = '' + tee ${cfg.device-path}/brightness <<<0 + ''; + }; + }; +} diff --git a/hosts/ahmed/duksebot/default.nix b/hosts/ahmed/duksebot/default.nix new file mode 100644 index 0000000..f15b0ff --- /dev/null +++ b/hosts/ahmed/duksebot/default.nix @@ -0,0 +1,61 @@ +# This module defines systemd unit which runs a script that sends Discrord +# messages. I use it to notify my classmates about who's on cleaning duty. You +# are probably not interested in this. + +{ + config, + pkgs, + ... +}: let + # What script to run. + package = pkgs.duksebot; +in { + config = { + # Create a user to run the server under. + users.users.duksebot = { + description = "Runs daily dukse reminder"; + group = "duksebot"; + isSystemUser = true; + home = "/srv/duksebot"; + createHome = true; + }; + users.groups.duksebot = {}; + + age.secrets.duksebot-env = { + file = ../../../secrets/duksebot.env.age; + owner = config.users.users.duksebot.name; + group = config.users.users.duksebot.group; + mode = "0440"; + }; + + # Create a service which simply runs script. This will be invoked by our timer. + systemd.services.duksebot = { + serviceConfig = { + # We only want to run this once every time the timer triggers it. + Type = "oneshot"; + # Run as the user we created above. + User = "duksebot"; + Group = "duksebot"; + WorkingDirectory = config.users.users.duksebot.home; + }; + script = '' + # Load the secret environment variables. + export $(grep -v '^#' ${config.age.secrets.duksebot-env.path} | xargs) + # Kick off. + exec "${package}"/bin/duksebot + ''; + }; + + # Create a timer to activate our oneshot service. + systemd.timers.duksebot = { + wantedBy = ["timers.target"]; + partOf = ["duksebot.service"]; + after = ["network-online.target"]; + wants = ["network-online.target"]; + timerConfig = { + OnCalendar = "*-*-* 7:00:00"; + Unit = "duksebot.service"; + }; + }; + }; +} diff --git a/hosts/ahmed/forsvarsarper/default.nix b/hosts/ahmed/forsvarsarper/default.nix new file mode 100644 index 0000000..c1c6163 --- /dev/null +++ b/hosts/ahmed/forsvarsarper/default.nix @@ -0,0 +1,58 @@ +# This module defines an on-demand minecraft server service which turns off the +# server when it's not being used. +{ + config, + pkgs, + ... +}:{ + config = { + # Create a user to run the server under. + users.users.forsvarsarper = { + description = "Runs daily scan for tests"; + group = "forsvarsarper"; + isSystemUser = true; + home = "/srv/forsvarsarper"; + createHome = true; + }; + users.groups.forsvarsarper = {}; + + age.secrets.forsvarsarper-env = { + file = ../../../secrets/forsvarsarper.env.age; + owner = config.users.users.forsvarsarper.name; + group = config.users.users.forsvarsarper.group; + mode = "0440"; + }; + + # Create a service which simply runs script. This will be invoked by our timer. + systemd.services.forsvarsarper = { + serviceConfig = { + # We only want to run this once every time the timer triggers it. + Type = "oneshot"; + # Run as the user we created above. + User = "forsvarsarper"; + Group = "forsvarsarper"; + WorkingDirectory = config.users.users.forsvarsarper.home; + }; + script = let + python3' = pkgs.python3.withPackages (ps: [ps.requests]); + in '' + # Load the secret environment variables. + export $(grep -v '^#' ${config.age.secrets.forsvarsarper-env.path} | xargs) + # Kick off. + exec ${python3'}/bin/python3 ${./script.py} + ''; + }; + + # Create a timer to activate our oneshot service. + systemd.timers.forsvarsarper = { + wantedBy = ["timers.target"]; + partOf = ["forsvarsarper.service"]; + after = ["network-online.target"]; + wants = ["network-online.target"]; + timerConfig = { + OnCalendar = "*-*-* 8:00:00"; + Unit = "forsvarsarper.service"; + }; + }; + }; +} diff --git a/hosts/ahmed/forsvarsarper/script.py b/hosts/ahmed/forsvarsarper/script.py new file mode 100644 index 0000000..7f12508 --- /dev/null +++ b/hosts/ahmed/forsvarsarper/script.py @@ -0,0 +1,28 @@ +import requests +import os + +URL = "https://karriere.forsvaret.dk/varnepligt/varnepligten/cybervarnepligt/" +TARGET_PHRASE = "Der er på nuværende tidspunkt ikke planlagt nogen afprøvninger." + +try: + response = requests.get(URL); + print(f"Forespørgsel til {URL} gav status {response.status_code}") +except: + message = "nejj den er ødelagt" +else: + if TARGET_PHRASE in response.text: + message = "der er stadig ikke planlagt nogle afprøvninger" + else: + message = "noget har ændret sig på siden!!" + print(response.text) + +token = os.getenv("TOKEN") +data = { + "title": "forsvaret status", + "message": message, + "url": URL, +} +response = requests.post(f"https://notifications.linus.onl/api/send-notification/{token}", json=data) +print(f"Forespørgsel til at sende notifikation gav status {response.status_code}") +response.raise_for_status() + diff --git a/hosts/ahmed/git.linus.onl/about.html b/hosts/ahmed/git.linus.onl/about.html new file mode 100644 index 0000000..2d18ca4 --- /dev/null +++ b/hosts/ahmed/git.linus.onl/about.html @@ -0,0 +1,5 @@ +

Welcome! This is where i keep my public repositories.

+
+
+

idk.

+

what do i say here?

diff --git a/hosts/ahmed/git.linus.onl/default.nix b/hosts/ahmed/git.linus.onl/default.nix new file mode 100644 index 0000000..46c74e9 --- /dev/null +++ b/hosts/ahmed/git.linus.onl/default.nix @@ -0,0 +1,84 @@ +{ + config, + pkgs, + metadata, + ... +}: let + git-shell = "${pkgs.gitMinimal}/bin/git-shell"; + + # Enables HTTPS stuff. + useACME = true; + + # Where repositories will be stored. + location = "/srv/git"; +in { + config = { + # Create a user which + # See: https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server + users.users.git = { + description = "Git server user"; + isSystemUser = true; + group = "git"; + + # FIXME: Is serving the home-directory of a user (indirectly through CGit) a bad idea? + home = location; + createHome = false; + + # Restrict this user to Git-related activities. + # See: https://git-scm.com/docs/git-shell + shell = git-shell; + + # List of users who can ssh into this server and write to stuff. We add + # some restrictions on what users can do on the server. This works in + # tandem with the custom shell. + openssh.authorizedKeys.keys = + map (key: "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ${key}") + [ + metadata.hosts.muhammed.sshPubKey + ]; + }; + users.groups.git = {}; + + environment.shells = [git-shell]; + + # Create repo directory. It must be readable to NGINX. + # NOTE: If location != "/srv/git" you may want to change this! + # See: https://git.zx2c4.com/cgit/about/faq#why-doesnt-cgit-findshow-my-repo + system.activationScripts.create-cgit-scan-path = '' + mkdir -p ${location} + chown ${toString config.users.users.git.name} ${location} + chgrp ${toString config.users.groups.git.name} ${location} + chmod 755 ${location} + ''; + + # Public git viewer. + services.cgit."git.linus.onl" = { + enable = true; + scanPath = location; + settings = { + root-title = "Linus' public projects"; + root-desc = "hello yes this is the git server"; + root-readme = toString ./about.html; + }; + extraConfig = '' + readme=:README.md + readme=:README.rst + readme=:README.text + readme=:README.txt + readme=:readme.md + readme=:readme.rst + readme=:readme.text + readme=:readme.txt + ''; + }; + + # Register domain name. + services.cloudflare-dyndns.domains = ["git.linus.onl"]; + + # The CGit service creates the virtual host, but it does not enable ACME. + services.nginx.virtualHosts."git.linus.onl" = { + enableACME = useACME; + forceSSL = useACME; + }; + }; +} diff --git a/hosts/ahmed/hellohtml.linus.onl/default.nix b/hosts/ahmed/hellohtml.linus.onl/default.nix new file mode 100644 index 0000000..2d09788 --- /dev/null +++ b/hosts/ahmed/hellohtml.linus.onl/default.nix @@ -0,0 +1,51 @@ +# This module defines the HelloHTML web server. It extends the NGINX config +# with a virtual server that proxies the local HelloHTML service. + +{ ... }: let + useACME = true; +in { + config = { + # Start service listening on socket /tmp/hellohtml.sock + services.hellohtml = { + enable = true; + }; + + # Register domain name. + services.cloudflare-dyndns.domains = ["hellohtml.linus.onl"]; + + # Use NGINX as reverse proxy. + services.nginx.virtualHosts."hellohtml.linus.onl" = { + enableACME = useACME; + forceSSL = useACME; + locations."/" = rec { + proxyPass = "http://localhost:8538"; + # Disable settings that might mess with the text/event-stream response of the /listen/:id endpoint. + # NOTE: These settings work in tanden with Cloudflare Proxy settings descibed here: + # https://blog.devops.dev/implementing-server-sent-events-with-fastapi-nginx-and-cloudflare-10ede1dffc18 + extraConfig = '' + location /listen/ { + # Have to duplicate this here, as this directive is not inherited. + # See: https://blog.martinfjordvald.com/understanding-the-nginx-configuration-inheritance-model/ + # See: https://serverfault.com/q/1082562 + proxy_pass ${proxyPass}; + # Disable connection header. + # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection + # See: https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives + proxy_set_header Connection \'\'; + # Disable buffering. This is crucial for SSE to ensure that + # messages are sent immediately without waiting for a buffer to + # fill. + proxy_buffering off; + # Disable caching to ensure that all messages are sent and received + # in real-time without being cached by the proxy. + proxy_cache off; + # Set a long timeout for reading from the proxy to prevent the + # connection from timing out. You may need to adjust this value + # based on your specific requirements. + proxy_read_timeout 86400; + } + ''; + }; + }; + }; +} diff --git a/hosts/ahmed/home/default.nix b/hosts/ahmed/home/default.nix new file mode 100644 index 0000000..a031e96 --- /dev/null +++ b/hosts/ahmed/home/default.nix @@ -0,0 +1,9 @@ +# Here we extend the HM user defined in `home/default.nix`. All the global HM +# stuff is defined in there. The only imports here are specific to this host. +{...}: { + home-manager.users.linus = { + imports = [ + # empty for now + ]; + }; +} diff --git a/hosts/ahmed/linus.onl/default.nix b/hosts/ahmed/linus.onl/default.nix new file mode 100644 index 0000000..c31eb73 --- /dev/null +++ b/hosts/ahmed/linus.onl/default.nix @@ -0,0 +1,93 @@ +{ + pkgs, + lib, + ... +}: let + # The domain to serve. Also kinda embedded in the name of the module?? + domain = "linus.onl"; + + # Enable HTTPS stuff. + useACME = true; +in { + config = { + # Create a user to run the build script under. + users.users."${domain}-builder" = { + description = "builds ${domain}"; + group = "${domain}-builder"; + isSystemUser = true; + }; + users.groups."${domain}-builder" = {}; + + # Create the output directory. + system.activationScripts."${domain}-create-www" = lib.stringAfter ["var"] '' + mkdir -p /var/www/${domain} + chown ${domain}-builder /var/www/${domain} + chgrp ${domain}-builder /var/www/${domain} + chmod 0755 /var/www/${domain} + ''; + + # Create a systemd service which rebuild the site regularly. + # + # This can't be done using Nix because the site relies on the git build and + # there are some inherent difficulties with including .git/ in the + # inputSource for derivations. + # + # See: https://github.com/NixOS/nix/issues/6900 + # See: https://github.com/NixOS/nixpkgs/issues/8567 + # + # TODO: Integrate rebuilding with GitHub webhooks to rebuild on push. + systemd.services."${domain}-source" = { + description = "generate https://${domain} source"; + + serviceConfig = { + Type = "oneshot"; + User = "${domain}-builder"; + Group = "${domain}-builder"; + }; + startAt = "*-*-* *:00/5:00"; + + path = with pkgs; [ + git + rsync + coreutils-full + tcl-8_5 + gnumake + ]; + environment.TCLLIBPATH = "$TCLLIBPATH ${pkgs.tcl-cmark}/lib/tclcmark1.0"; + script = '' + set -ex + tmpdir="$(mktemp -d -t linus.onl-source.XXXXXXXXXXXX)" + cd "$tmpdir" + trap 'rm -rf $tmpdir' EXIT + # TODO: Only do minimal possible cloning + git clone https://github.com/linnnus/${domain} . + make _build + rsync --archive --delete _build/ /var/www/${domain} + ''; + + # TODO: Harden service + + # Network must be online for us to check. + after = ["network-online.target"]; + requires = ["network-online.target"]; + + # We must generate some files for NGINX to serve, so this should be run + # before NGINX. + before = ["nginx.service"]; + wantedBy = ["nginx.service"]; + }; + + # Register domain name with ddns. + services.cloudflare-dyndns.domains = [domain]; + + # Register virtual host. + services.nginx = { + virtualHosts."${domain}" = { + # NOTE: 'forceSSL' will cause an infite loop, if the cloudflare proxy does NOT connect over HTTPS. + enableACME = useACME; + forceSSL = useACME; + root = "/var/www/${domain}"; + }; + }; + }; +} diff --git a/hosts/ahmed/nofitications.linus.onl/default.nix b/hosts/ahmed/nofitications.linus.onl/default.nix new file mode 100644 index 0000000..f3ab04f --- /dev/null +++ b/hosts/ahmed/nofitications.linus.onl/default.nix @@ -0,0 +1,24 @@ +{ ... }: let + # Enable HTTPS stuff. + useACME = true; +in { + config = { + # Start the proxied service. + services.push-notification-api = { + enable = true; + }; + + # Register domain name. + services.cloudflare-dyndns.domains = ["notifications.linus.onl"]; + + # Use NGINX as reverse proxy. + services.nginx.virtualHosts."notifications.linus.onl" = { + enableACME = useACME; + forceSSL = useACME; + locations."/" = { + recommendedProxySettings = true; + proxyPass = "http://unix:/run/push-notification-api.sock"; + }; + }; + }; +} diff --git a/hosts/ahmed/ssh.nix b/hosts/ahmed/ssh.nix deleted file mode 100644 index 3c6b7ad..0000000 --- a/hosts/ahmed/ssh.nix +++ /dev/null @@ -1,19 +0,0 @@ -# This file configures openSSH on this host. -{ - lib, - metadata, - ... -}: { - # Who is allowed/expected to connect to this machine? - networking.firewall.allowedTCPPorts = [22]; - services.openssh = { - enable = true; - settings.PasswordAuthentication = false; - }; - - users.users = lib.genAttrs ["root" "linus"] (_: { - openssh.authorizedKeys.keys = [ - metadata.hosts.muhammed.sshPubKey - ]; - }); -} diff --git a/hosts/ahmed/ssh/default.nix b/hosts/ahmed/ssh/default.nix new file mode 100644 index 0000000..3c6b7ad --- /dev/null +++ b/hosts/ahmed/ssh/default.nix @@ -0,0 +1,19 @@ +# This file configures openSSH on this host. +{ + lib, + metadata, + ... +}: { + # Who is allowed/expected to connect to this machine? + networking.firewall.allowedTCPPorts = [22]; + services.openssh = { + enable = true; + settings.PasswordAuthentication = false; + }; + + users.users = lib.genAttrs ["root" "linus"] (_: { + openssh.authorizedKeys.keys = [ + metadata.hosts.muhammed.sshPubKey + ]; + }); +} diff --git a/hosts/muhammed/configuration.nix b/hosts/muhammed/configuration.nix index 9119a55..c629b22 100644 --- a/hosts/muhammed/configuration.nix +++ b/hosts/muhammed/configuration.nix @@ -1,5 +1,9 @@ # This file contains the configuration for my Macbook Pro. {flakeInputs, ...}: { + imports = [ + ./home + ]; + # Specify the location of this configuration file. Very meta. environment.darwinConfig = flakeInputs.self + "/hosts/muhammed/configuration.nix"; diff --git a/hosts/muhammed/home/default.nix b/hosts/muhammed/home/default.nix new file mode 100644 index 0000000..b0b126c --- /dev/null +++ b/hosts/muhammed/home/default.nix @@ -0,0 +1,10 @@ +# Here we extend the HM user defined in `home/default.nix`. All the global HM +# stuff is defined in there. +{...}: { + home-manager.users.linus = { + imports = [ + ./iterm2 + ./noweb + ]; + }; +} diff --git a/hosts/muhammed/home/iterm2/default.nix b/hosts/muhammed/home/iterm2/default.nix new file mode 100644 index 0000000..d868e57 --- /dev/null +++ b/hosts/muhammed/home/iterm2/default.nix @@ -0,0 +1,26 @@ +# This file configures iterm2. Note that the actual definition of iTerm2 for +# home-manager is in `modules/home-manager/iterm2`. *That* file declares +# `options.programs.iterm2.enable`. +{ + pkgs, + lib, + ... +}: let + inherit (lib) mkIf; + inherit (pkgs.stdenv) isDarwin; +in { + config = mkIf isDarwin { + home.packages = with pkgs; [imgcat]; + + programs.iterm2 = { + enable = true; + # config = { + # # Use the minimal tab style. + # # See: https://github.com/gnachman/iTerm2/blob/bd40fba0611fa94684dadf2478625f2a93eb6e47/sources/iTermPreferences.h#L29 + # TabStyleWithAutomaticOption = 5; + # }; + + shellIntegration.enableZshIntegration = true; + }; + }; +} diff --git a/hosts/muhammed/home/neovim/conjure.nix b/hosts/muhammed/home/neovim/conjure.nix new file mode 100644 index 0000000..0acfadd --- /dev/null +++ b/hosts/muhammed/home/neovim/conjure.nix @@ -0,0 +1,71 @@ +{pkgs, ...}: { + programs.neovim.plugins = [ + { + # Add interactive repl-like environment. + # See also the addition of cmp-conjure in `completion.nix`. + # See also the addition of clojure in `dev-utils/default.nix`. + plugin = pkgs.vimPlugins.conjure; + type = "lua"; + config = '' + local start_clj_repl = "StartCljRepl"; + local start_lein_repl = "StartLeinRepl"; + + -- Create a command to launch nRepl for Clojure support. + -- See: https://github.com/Olical/conjure/wiki/Quick-start:-Clojure + vim.api.nvim_create_user_command(start_clj_repl, function() + local id = vim.fn.jobstart({ + "${pkgs.clojure}/bin/clj", + "-Sdeps", + '{:deps {nrepl/nrepl {:mvn/version "1.0.0"} cider/cider-nrepl {:mvn/version "0.40.0"}}}', + "--main", + "nrepl.cmdline", + "--middleware", + '["cider.nrepl/cider-middleware"]', + "--interactive", + }) + print("Started nRepl job #" .. id) + end, { + desc = "Starts an nRepl session in the current directory using clj.", + }) + + vim.api.nvim_create_user_command(start_lein_repl, function() + local id = vim.fn.jobstart({ + "${pkgs.leiningen}/bin/lein", + "repl", + }) + print("Started nRepl job #" .. id) + end, { + desc = "Starts an nRepl session in the current directory using Lein.", + }) + + -- Launch nRepl when any clojure file is started. + -- vim.api.nvim_create_autocmd({"BufEnter", "BufWinEnter"}, { + -- pattern = "*.clj", + -- command = start_clj_repl, + -- }); + + -- Use Guile to evaluate scheme buffers. + local start_guile_repl = "StartGuileRepl"; + local sock_path = "/tmp/guile-repl.sock" + vim.g["conjure#filetype#scheme"] = "conjure.client.guile.socket" + vim.g["conjure#client#guile#socket#pipename"] = sock_path + vim.api.nvim_create_user_command(start_guile_repl, function() + local id = vim.fn.jobstart({ + "${pkgs.guile}/bin/guile", + "--listen=" .. sock_path, + }) + print("Started Guile job #" .. id) + end, { + desc = "Starts an Guile repl session listening on " .. sock_path, + }) + + -- Jump to bottom of log when new evaluation happens + -- See: https://github.com/Olical/conjure/blob/58c46d1f4999679659a5918284b574c266a7ac83/doc/conjure.txt#L872 + vim.cmd [[autocmd User ConjureEval if expand("%:t") =~ "^conjure-log-" | exec "normal G" | endif]] + ''; + } + + # Compe plugin to interact with conjure. + pkgs.vimPlugins.cmp-conjure + ]; +} diff --git a/hosts/muhammed/home/neovim/default.nix b/hosts/muhammed/home/neovim/default.nix new file mode 100644 index 0000000..905896c --- /dev/null +++ b/hosts/muhammed/home/neovim/default.nix @@ -0,0 +1,8 @@ +# Once again we extend the global configuration defined in `home/neovim/` with +# some stuff specific to this host (mainly development stuff). +{...}: { + imports = [ + ./lsp.nix + ./conjure.nix + ]; +} diff --git a/hosts/muhammed/home/neovim/lsp.nix b/hosts/muhammed/home/neovim/lsp.nix new file mode 100644 index 0000000..06745da --- /dev/null +++ b/hosts/muhammed/home/neovim/lsp.nix @@ -0,0 +1,107 @@ +# This module sets up LSP server configurations for Neovim. +{pkgs, ...}: { + programs.neovim.plugins = [ + { + plugin = pkgs.vimPlugins.nvim-lspconfig; + type = "lua"; + config = '' + local lspconfig = require("lspconfig") + local util = require("lspconfig.util") + + -- Mappings. + -- See `:help vim.diagnostic.*` for documentation on any of the below functions + local opts = { noremap=true, silent=true } + vim.keymap.set('n', 'e', vim.diagnostic.open_float, opts) + vim.keymap.set('n', '[d', vim.diagnostic.goto_prev, opts) + vim.keymap.set('n', ']d', vim.diagnostic.goto_next, opts) + vim.keymap.set('n', 'q', vim.diagnostic.setloclist, opts) + + -- Use an on_attach function to only map the following keys + -- after the language server attaches to the current buffer + local on_attach = function(client, bufnr) + -- Enable completion triggered by + vim.api.nvim_buf_set_option(bufnr, 'omnifunc', 'v:lua.vim.lsp.omnifunc') + + -- Mappings. + -- See `:help vim.lsp.*` for documentation on any of the below functions + local bufopts = { noremap=true, silent=true, buffer=bufnr } + vim.keymap.set('n', 'gD', vim.lsp.buf.declaration, bufopts) + vim.keymap.set('n', 'gd', vim.lsp.buf.definition, bufopts) + vim.keymap.set('n', 'K', vim.lsp.buf.hover, bufopts) + vim.keymap.set('n', 'gi', vim.lsp.buf.implementation, bufopts) + vim.keymap.set('n', '', vim.lsp.buf.signature_help, bufopts) + vim.keymap.set('n', 'wa', vim.lsp.buf.add_workspace_folder, bufopts) + vim.keymap.set('n', 'wr', vim.lsp.buf.remove_workspace_folder, bufopts) + vim.keymap.set('n', 'wl', function() + print(vim.inspect(vim.lsp.buf.list_workspace_folders())) + end, bufopts) + vim.keymap.set('n', 'D', vim.lsp.buf.type_definition, bufopts) + vim.keymap.set('n', 'rn', vim.lsp.buf.rename, bufopts) + vim.keymap.set('n', 'ca', vim.lsp.buf.code_action, bufopts) + vim.keymap.set('n', 'gr', vim.lsp.buf.references, bufopts) + vim.keymap.set('n', 'f', function() vim.lsp.buf.format { async = true } end, bufopts) + vim.keymap.set('n', 's', function() vim.cmd[[ClangdSwitchSourceHeader]] end, bufopts) + end + + -- Use a loop to conveniently call 'setup' on multiple servers and + -- map buffer local keybindings when the language server attaches + local servers = { + pyright = { cmd = { "${pkgs.pyright}/bin/pyright-langserver", "--stdio" } }, + nixd = { cmd = { "${pkgs.nixd}/bin/nixd" } }, + denols = { + init_options = { + enable = true, + unstable = true, + lint = true, + }, + cmd = { "${pkgs.unstable.deno}/bin/deno", "lsp", "--unstable" }, + root_dir = function(startpath) + if util.find_package_json_ancestor(startpath) then + -- This is a Node project; let tsserver handle this one. + return nil + else + -- Otherwise, we try to find the root or + -- default to the current directory. + return util.root_pattern("deno.json", "deno.jsonc", ".git")(startpath) + or util.path.dirname(startpath) + end + end, + }, + clangd = { + cmd = { "${pkgs.clang-tools}/bin/clangd" }, + }, + nimls = { + cmd = { "${pkgs.nimlsp}/bin/nimlsp" }, + }, + }; + for server, config in pairs(servers) do + -- set common options + config.on_attach = on_attach; + config.debounce_text_changes = 150; + + lspconfig[server].setup(config) + end + ''; + } + ]; +} +# I spent like an hour writing this, only to find it was a pretty bad idea. +# +# nixToLua = s: +# if builtins.isAttrs s then +# let +# renderAttr = name: value: "[ [==========[" + name + "]==========] ] = " + (nixToLua value); +# attrsList = map (name: renderAttr name s.${name}) (lib.attrNames s); +# attrsListStr = lib.concatStringsSep ", " attrsList; +# in +# "{ ${attrsListStr} }" +# else if builtins.isList s then +# "{ " + (lib.concatStringsSep ", " (map nixToLua s)) + " }" +# else if builtins.isString s then +# # Oh boy I sure hope `s` doesn't contain "]==========]". +# "[==========[" + s + "]==========]" +# else if builtins.isInt s || builtins.isFloat s then +# toString s +# else +# throw "Cannot convert ${builtins.typeOf s} to Lua value!"; + diff --git a/hosts/muhammed/home/noweb/default.nix b/hosts/muhammed/home/noweb/default.nix new file mode 100644 index 0000000..ef67862 --- /dev/null +++ b/hosts/muhammed/home/noweb/default.nix @@ -0,0 +1,12 @@ +{pkgs, ...}: { + home.packages = with pkgs; [ + noweb + texliveFull + yalafi-shell + ]; + + # Prepend nowebs STY files to the search path. I chose to do it globally, + # rather than using `makeWrapper` because I sometimes want to manually invoke + # `pdflatex` and the like on the output of `noweave`. + home.sessionVariables.TEXINPUTS = "${pkgs.noweb.tex}/tex/latex/noweb/:$TEXINPUTS"; +} diff --git a/modules/darwin/default.nix b/modules/darwin/default.nix index 48f0511..832940f 100644 --- a/modules/darwin/default.nix +++ b/modules/darwin/default.nix @@ -1,4 +1,3 @@ { - general.still-awake = import ./still-awake; - personal = {}; + still-awake = import ./still-awake; } diff --git a/modules/nixos/cloudflare-proxy/default.nix b/modules/nixos/cloudflare-proxy/default.nix deleted file mode 100644 index 657722d..0000000 --- a/modules/nixos/cloudflare-proxy/default.nix +++ /dev/null @@ -1,109 +0,0 @@ -# This module adds some extra configuration useful when running behid a Cloudflare Proxy. -# -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib.options) mkEnableOption mkOption; - inherit (lib.modules) mkIf; - inherit (lib.types) listOf nonEmptyStr port; - - # TODO: What happens when these get out of date??? Huh??? You little pissbaby - fileToList = x: lib.strings.splitString "\n" (builtins.readFile x); - cfipv4 = fileToList (pkgs.fetchurl { - url = "https://www.cloudflare.com/ips-v4"; - hash = "sha256-8Cxtg7wBqwroV3Fg4DbXAMdFU1m84FTfiE5dfZ5Onns="; - }); - cfipv6 = fileToList (pkgs.fetchurl { - url = "https://www.cloudflare.com/ips-v6"; - hash = "sha256-np054+g7rQDE3sr9U8Y/piAp89ldto3pN9K+KCNMoKk="; - }); - - cfg = config.modules.cloudflare-proxy; -in { - options.modules.cloudflare-proxy = { - enable = mkEnableOption "Cloudflare proxy IP extraction for NGINX"; - - firewall = { - IPv4Whitelist = mkOption { - description = "List of IPv4 addresses (or ranges) added to the whitelist."; - type = listOf nonEmptyStr; - default = []; - }; - - IPv6Whitelist = mkOption { - description = "List of IPv6 addresses (or ranges) added to the whitelist."; - type = listOf nonEmptyStr; - default = []; - }; - }; - }; - - config = mkIf cfg.enable { - # Teach NGINX how to extract the proxied IP from proxied requests. - # - # See: https://nixos.wiki/wiki/Nginx#Using_realIP_when_behind_CloudFlare_or_other_CDN - services.nginx.commonHttpConfig = let - realIpsFromList = lib.strings.concatMapStringsSep "\n" (x: "set_real_ip_from ${x};"); - in '' - ${realIpsFromList cfipv4} - ${realIpsFromList cfipv6} - real_ip_header CF-Connecting-IP; - ''; - - # Block non-Cloudflare IP addresses. - networking.firewall = let - chain = "cloudflare-whitelist"; - in { - extraCommands = let - allow-interface = lib.strings.concatMapStringsSep "\n" (i: ''ip46tables --append ${chain} --in-interface ${i} --jump RETURN''); - allow-ip = cmd: lib.strings.concatMapStringsSep "\n" (r: ''${cmd} --append ${chain} --source ${r} --jump RETURN''); - in '' - # Flush the old firewall rules. This behavior mirrors the default firewall service. - # See: https://github.com/NixOS/nixpkgs/blob/ac911bf685eecc17c2df5b21bdf32678b9f88c92/nixos/modules/services/networking/firewall-iptables.nix#L59-L66 - # TEMP: Removed 2>/dev/null - ip46tables --delete INPUT --protocol tcp --destination-port 80 --syn --jump ${chain} || true - ip46tables --delete INPUT --protocol tcp --destination-port 443 --syn --jump ${chain} || true - ip46tables --flush ${chain} || true - ip46tables --delete-chain ${chain} || true - - # Create a chain that only allows whitelisted IPs through. - ip46tables --new-chain ${chain} - - # Allow trusted interfaces through. - ${allow-interface config.networking.firewall.trustedInterfaces} - - # Allow local whitelisted IPs through - ${allow-ip "iptables" cfg.firewall.IPv4Whitelist} - ${allow-ip "ip6tables" cfg.firewall.IPv6Whitelist} - - # Allow Cloudflare's IP ranges through. - ${allow-ip "iptables" cfipv4} - ${allow-ip "ip6tables" cfipv6} - - # Everything else is dropped. - # - # TODO: I would like to use `nixos-fw-log-refuse` here, but I keep - # running into weird issues when reloading the firewall. - # Something about the table not being deleted properly. - ip46tables --append ${chain} --jump DROP - - # Inject our chain as the first check in INPUT (before nixos-fw). - # We want to capture any new incomming TCP connections. - ip46tables --insert INPUT 1 --protocol tcp --destination-port 80 --syn --jump ${chain} - ip46tables --insert INPUT 1 --protocol tcp --destination-port 443 --syn --jump ${chain} - ''; - extraStopCommands = '' - # Clean up added rulesets (${chain}). This mirrors the behavior of the - # default firewall at the time of writing. - # - # See: https://github.com/NixOS/nixpkgs/blob/ac911bf685eecc17c2df5b21bdf32678b9f88c92/nixos/modules/services/networking/firewall-iptables.nix#L218-L219 - # TEMP: Removed 2>/dev/null - ip46tables --delete INPUT --protocol tcp --destination-port 80 --syn --jump ${chain} || true - ip46tables --delete INPUT --protocol tcp --destination-port 443 --syn --jump ${chain} || true - ''; - }; - }; -} diff --git a/modules/nixos/default.nix b/modules/nixos/default.nix index 1393627..b813155 100644 --- a/modules/nixos/default.nix +++ b/modules/nixos/default.nix @@ -1,19 +1,4 @@ { - # These components are - general = { - on-demand-minecraft = import ./on-demand-minecraft; - cloudflare-proxy = import ./cloudflare-proxy; - disable-screen = import ./disable-screen; - hellohtml = import ./hellohtml; - }; - - personal = { - duksebot = import ./duksebot; - graphics = import ./graphics; - "linus.onl" = import ./linus.onl; - "notifications.linus.onl" = import ./nofitications.linus.onl; - "git.linus.onl" = import ./git.linus.onl; - "hellohtml.linus.onl" = import ./hellohtml.linus.onl; - forsvarsarper = import ./forsvarsarper; - }; + on-demand-minecraft = import ./on-demand-minecraft; + hellohtml = import ./hellohtml; } diff --git a/modules/nixos/disable-screen/default.nix b/modules/nixos/disable-screen/default.nix deleted file mode 100644 index 638437a..0000000 --- a/modules/nixos/disable-screen/default.nix +++ /dev/null @@ -1,61 +0,0 @@ -# This file defines some configuration options which disable the screen. This -# is only relevant because this host is an old laptop running as a server. -{ - lib, - config, - ... -}: let - inherit (lib) mkEnableOption mkOption mkIf types; - - cfg = config.services.disable-screen; -in { - options.services.disable-screen = { - enable = mkEnableOption "disable screen"; - - device-path = mkOption { - description = "Path to the device in the `/sys` file system."; - type = types.str; - example = "/sys/class/backlight/intel_backlight"; - }; - - device-unit = mkOption { - description = "The systemd device unit that corresponds to the device speciefied in `device-path`."; - type = types.str; - example = "sys-devices-pci...-intel_backligt.device"; - }; - }; - - config = mkIf cfg.enable { - # Disable sleep on lid close. - services.logind = let - lidSwitchAction = "ignore"; - in { - lidSwitchExternalPower = lidSwitchAction; - lidSwitchDocked = lidSwitchAction; - lidSwitch = lidSwitchAction; - }; - - # Don't store screen brightness between boots. We always want to turn off the - # screen. - # - # See: https://wiki.archlinux.org/title/backlight#Save_and_restore_functionality - # See: https://github.com/NixOS/nixpkgs/blob/990398921f677615c0732d704857484b84c6c888/nixos/modules/system/boot/systemd.nix#L97-L101 - systemd.suppressedSystemUnits = ["systemd-backlight@.service"]; - - # FIXME: Figure out how to enable screen when on-device debugging is necessary. - # Create a new service which turns off the display on boot. - # - # See: https://nixos.wiki/wiki/Backlight#.2Fsys.2Fclass.2Fbacklight.2F... - # See: https://superuser.com/questions/851846/how-to-write-a-systemd-service-that-depends-on-a-device-being-present - systemd.services.disable-screen = { - requires = [cfg.device-unit]; - after = [cfg.device-unit]; - wantedBy = [cfg.device-unit]; - - serviceConfig.Type = "oneshot"; - script = '' - tee ${cfg.device-path}/brightness <<<0 - ''; - }; - }; -} diff --git a/modules/nixos/duksebot/default.nix b/modules/nixos/duksebot/default.nix deleted file mode 100644 index 4c10cd8..0000000 --- a/modules/nixos/duksebot/default.nix +++ /dev/null @@ -1,72 +0,0 @@ -# This module defines an on-demand minecraft server service which turns off the -# server when it's not being used. -{ - config, - lib, - pkgs, - modulesPath, - ... -}: let - inherit (lib) mkIf mkOption mkEnableOption types; - - cfg = config.services.duksebot; -in { - options.services.duksebot = { - enable = mkEnableOption "duksebot daily reminder"; - - package = mkOption { - description = "What package to use"; - default = pkgs.duksebot; - type = types.package; - }; - }; - - config = mkIf cfg.enable { - # Create a user to run the server under. - users.users.duksebot = { - description = "Runs daily dukse reminder"; - group = "duksebot"; - isSystemUser = true; - home = "/srv/duksebot"; - createHome = true; - }; - users.groups.duksebot = {}; - - age.secrets.duksebot-env = { - file = ../../../secrets/duksebot.env.age; - owner = config.users.users.duksebot.name; - group = config.users.users.duksebot.group; - mode = "0440"; - }; - - # Create a service which simply runs script. This will be invoked by our timer. - systemd.services.duksebot = { - serviceConfig = { - # We only want to run this once every time the timer triggers it. - Type = "oneshot"; - # Run as the user we created above. - User = "duksebot"; - Group = "duksebot"; - WorkingDirectory = config.users.users.duksebot.home; - }; - script = '' - # Load the secret environment variables. - export $(grep -v '^#' ${config.age.secrets.duksebot-env.path} | xargs) - # Kick off. - exec "${cfg.package}"/bin/duksebot - ''; - }; - - # Create a timer to activate our oneshot service. - systemd.timers.duksebot = { - wantedBy = ["timers.target"]; - partOf = ["duksebot.service"]; - after = ["network-online.target"]; - wants = ["network-online.target"]; - timerConfig = { - OnCalendar = "*-*-* 7:00:00"; - Unit = "duksebot.service"; - }; - }; - }; -} diff --git a/modules/nixos/forsvarsarper/default.nix b/modules/nixos/forsvarsarper/default.nix deleted file mode 100644 index 7052f04..0000000 --- a/modules/nixos/forsvarsarper/default.nix +++ /dev/null @@ -1,65 +0,0 @@ -# This module defines an on-demand minecraft server service which turns off the -# server when it's not being used. -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkIf mkEnableOption; - - cfg = config.services.forsvarsarper; -in { - options.services.forsvarsarper.enable = mkEnableOption "daily scan for tests"; - - config = mkIf cfg.enable { - # Create a user to run the server under. - users.users.forsvarsarper = { - description = "Runs daily scan for tests"; - group = "forsvarsarper"; - isSystemUser = true; - home = "/srv/forsvarsarper"; - createHome = true; - }; - users.groups.forsvarsarper = {}; - - age.secrets.forsvarsarper-env = { - file = ../../../secrets/forsvarsarper.env.age; - owner = config.users.users.forsvarsarper.name; - group = config.users.users.forsvarsarper.group; - mode = "0440"; - }; - - # Create a service which simply runs script. This will be invoked by our timer. - systemd.services.forsvarsarper = { - serviceConfig = { - # We only want to run this once every time the timer triggers it. - Type = "oneshot"; - # Run as the user we created above. - User = "forsvarsarper"; - Group = "forsvarsarper"; - WorkingDirectory = config.users.users.forsvarsarper.home; - }; - script = let - python3' = pkgs.python3.withPackages (ps: [ps.requests]); - in '' - # Load the secret environment variables. - export $(grep -v '^#' ${config.age.secrets.forsvarsarper-env.path} | xargs) - # Kick off. - exec ${python3'}/bin/python3 ${./script.py} - ''; - }; - - # Create a timer to activate our oneshot service. - systemd.timers.forsvarsarper = { - wantedBy = ["timers.target"]; - partOf = ["forsvarsarper.service"]; - after = ["network-online.target"]; - wants = ["network-online.target"]; - timerConfig = { - OnCalendar = "*-*-* 8:00:00"; - Unit = "forsvarsarper.service"; - }; - }; - }; -} diff --git a/modules/nixos/forsvarsarper/script.py b/modules/nixos/forsvarsarper/script.py deleted file mode 100644 index 7f12508..0000000 --- a/modules/nixos/forsvarsarper/script.py +++ /dev/null @@ -1,28 +0,0 @@ -import requests -import os - -URL = "https://karriere.forsvaret.dk/varnepligt/varnepligten/cybervarnepligt/" -TARGET_PHRASE = "Der er på nuværende tidspunkt ikke planlagt nogen afprøvninger." - -try: - response = requests.get(URL); - print(f"Forespørgsel til {URL} gav status {response.status_code}") -except: - message = "nejj den er ødelagt" -else: - if TARGET_PHRASE in response.text: - message = "der er stadig ikke planlagt nogle afprøvninger" - else: - message = "noget har ændret sig på siden!!" - print(response.text) - -token = os.getenv("TOKEN") -data = { - "title": "forsvaret status", - "message": message, - "url": URL, -} -response = requests.post(f"https://notifications.linus.onl/api/send-notification/{token}", json=data) -print(f"Forespørgsel til at sende notifikation gav status {response.status_code}") -response.raise_for_status() - diff --git a/modules/nixos/git.linus.onl/about.html b/modules/nixos/git.linus.onl/about.html deleted file mode 100644 index 2d18ca4..0000000 --- a/modules/nixos/git.linus.onl/about.html +++ /dev/null @@ -1,5 +0,0 @@ -

Welcome! This is where i keep my public repositories.

-
-
-

idk.

-

what do i say here?

diff --git a/modules/nixos/git.linus.onl/default.nix b/modules/nixos/git.linus.onl/default.nix deleted file mode 100644 index 88e4f6f..0000000 --- a/modules/nixos/git.linus.onl/default.nix +++ /dev/null @@ -1,95 +0,0 @@ -{ - lib, - config, - pkgs, - options, - metadata, - ... -}: let - inherit (lib) mkEnableOption mkOption types mkIf; - - git-shell = "${pkgs.gitMinimal}/bin/git-shell"; - - cfg = config.modules."git.linus.onl"; -in { - options.modules."git.linus.onl" = { - enable = mkEnableOption "git.linus.onl static site"; - - useACME = mkEnableOption "built-in HTTPS stuff"; - - location = mkOption { - description = "Where repositories will be stored."; - type = types.path; - default = "/srv/git"; - }; - }; - - config = mkIf cfg.enable { - # Create a user which - # See: https://git-scm.com/book/en/v2/Git-on-the-Server-Setting-Up-the-Server - users.users.git = { - description = "Git server user"; - isSystemUser = true; - group = "git"; - - # FIXME: Is serving the home-directory of a user (indirectly through CGit) a bad idea? - home = cfg.location; - createHome = false; - - # Restrict this user to Git-related activities. - # See: https://git-scm.com/docs/git-shell - shell = git-shell; - - # List of users who can ssh into this server and write to stuff. We add - # some restrictions on what users can do on the server. This works in - # tandem with the custom shell. - openssh.authorizedKeys.keys = - map (key: "no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ${key}") - [ - metadata.hosts.muhammed.sshPubKey - ]; - }; - users.groups.git = {}; - - environment.shells = [git-shell]; - - # Create repo directory. It must be readable to NGINX. - # See: https://git.zx2c4.com/cgit/about/faq#why-doesnt-cgit-findshow-my-repo - system.activationScripts.create-cgit-scan-path = mkIf (cfg.location == options.modules."git.linus.onl".location.default) '' - mkdir -p ${cfg.location} - chown ${toString config.users.users.git.name} ${cfg.location} - chgrp ${toString config.users.groups.git.name} ${cfg.location} - chmod 755 ${cfg.location} - ''; - - # Public git viewer. - services.cgit."git.linus.onl" = { - enable = true; - scanPath = cfg.location; - settings = { - root-title = "Linus' public projects"; - root-desc = "hello yes this is the git server"; - root-readme = toString ./about.html; - }; - extraConfig = '' - readme=:README.md - readme=:README.rst - readme=:README.text - readme=:README.txt - readme=:readme.md - readme=:readme.rst - readme=:readme.text - readme=:readme.txt - ''; - }; - - # Register domain name. - services.cloudflare-dyndns.domains = ["git.linus.onl"]; - - # The CGit service creates the virtual host, but it does not enable ACME. - services.nginx.virtualHosts."git.linus.onl" = { - enableACME = cfg.useACME; - forceSSL = cfg.useACME; - }; - }; -} diff --git a/modules/nixos/graphics/default.nix b/modules/nixos/graphics/default.nix deleted file mode 100644 index f54d043..0000000 --- a/modules/nixos/graphics/default.nix +++ /dev/null @@ -1,37 +0,0 @@ -# This module configures a basic graphical environment. I use this sometimes for -# ahmed when muhammed is being repaired. -{ - config, - lib, - pkgs, - ... -}: let - inherit (lib) mkEnableOption mkIf; - - cfg = config.modules.graphics; -in { - options.modules.graphics.enable = mkEnableOption "basic graphical environment"; - - config = mkIf cfg.enable { - services.xserver.enable = true; - - # Match console keyboard layout but swap capslock and escape. - # TODO: Create a custom keymap with esc/capslock swap so console can use it. - services.xserver.layout = config.console.keyMap; - services.xserver.xkbOptions = "caps:swapescape"; - - # Enable touchpad support. - services.xserver.libinput.enable = true; - - services.xserver.windowManager.dwm.enable = true; - - # Enable sound. - sound.enable = true; - hardware.pulseaudio.enable = true; - - environment.systemPackages = with pkgs; [ - st # suckless terminal - dwm is pretty sucky without this - dmenu # application launcher - ]; - }; -} diff --git a/modules/nixos/hellohtml.linus.onl/default.nix b/modules/nixos/hellohtml.linus.onl/default.nix deleted file mode 100644 index feb56ba..0000000 --- a/modules/nixos/hellohtml.linus.onl/default.nix +++ /dev/null @@ -1,60 +0,0 @@ -{ - lib, - config, - ... -}: let - inherit (lib) mkEnableOption mkIf; - - cfg = config.modules."hellohtml.linus.onl"; -in { - options.modules."hellohtml.linus.onl" = { - enable = mkEnableOption "hellohtml.linus.onl site"; - - useACME = mkEnableOption "built-in HTTPS stuff"; - }; - - config = mkIf cfg.enable { - # Start service listening on socket /tmp/hellohtml.sock - services.hellohtml = { - enable = true; - }; - - # Register domain name. - services.cloudflare-dyndns.domains = ["hellohtml.linus.onl"]; - - # Use NGINX as reverse proxy. - services.nginx.virtualHosts."hellohtml.linus.onl" = { - enableACME = cfg.useACME; - forceSSL = cfg.useACME; - locations."/" = rec { - proxyPass = "http://localhost:8538"; - # Disable settings that might mess with the text/event-stream response of the /listen/:id endpoint. - # NOTE: These settings work in tanden with Cloudflare Proxy settings descibed here: - # https://blog.devops.dev/implementing-server-sent-events-with-fastapi-nginx-and-cloudflare-10ede1dffc18 - extraConfig = '' - location /listen/ { - # Have to duplicate this here, as this directive is not inherited. - # See: https://blog.martinfjordvald.com/understanding-the-nginx-configuration-inheritance-model/ - # See: https://serverfault.com/q/1082562 - proxy_pass ${proxyPass}; - # Disable connection header. - # See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Connection - # See: https://www.nginx.com/blog/avoiding-top-10-nginx-configuration-mistakes/#no-keepalives - proxy_set_header Connection \'\'; - # Disable buffering. This is crucial for SSE to ensure that - # messages are sent immediately without waiting for a buffer to - # fill. - proxy_buffering off; - # Disable caching to ensure that all messages are sent and received - # in real-time without being cached by the proxy. - proxy_cache off; - # Set a long timeout for reading from the proxy to prevent the - # connection from timing out. You may need to adjust this value - # based on your specific requirements. - proxy_read_timeout 86400; - } - ''; - }; - }; - }; -} diff --git a/modules/nixos/linus.onl/default.nix b/modules/nixos/linus.onl/default.nix deleted file mode 100644 index 52703fe..0000000 --- a/modules/nixos/linus.onl/default.nix +++ /dev/null @@ -1,100 +0,0 @@ -{ - pkgs, - lib, - config, - ... -}: let - inherit (lib) mkEnableOption mkOption types mkIf optional; - - domain = "linus.onl"; - - cfg = config.modules."${domain}"; -in { - options.modules."${domain}" = { - enable = mkEnableOption "${domain} static site"; - - useACME = mkEnableOption "built-in HTTPS stuff"; - }; - - config = mkIf cfg.enable { - # Create a user to run the build script under. - users.users."${domain}-builder" = { - description = "builds ${domain}"; - group = "${domain}-builder"; - isSystemUser = true; - }; - users.groups."${domain}-builder" = {}; - - # Create the output directory. - system.activationScripts."${domain}-create-www" = lib.stringAfter ["var"] '' - mkdir -p /var/www/${domain} - chown ${domain}-builder /var/www/${domain} - chgrp ${domain}-builder /var/www/${domain} - chmod 0755 /var/www/${domain} - ''; - - # Create a systemd service which rebuild the site regularly. - # - # This can't be done using Nix because the site relies on the git build and - # there are some inherent difficulties with including .git/ in the - # inputSource for derivations. - # - # See: https://github.com/NixOS/nix/issues/6900 - # See: https://github.com/NixOS/nixpkgs/issues/8567 - # - # TODO: Integrate rebuilding with GitHub webhooks to rebuild on push. - systemd.services."${domain}-source" = { - description = "generate https://${domain} source"; - - serviceConfig = { - Type = "oneshot"; - User = "${domain}-builder"; - Group = "${domain}-builder"; - }; - startAt = "*-*-* *:00/5:00"; - - path = with pkgs; [ - git - rsync - coreutils-full - tcl-8_5 - gnumake - ]; - environment.TCLLIBPATH = "$TCLLIBPATH ${pkgs.tcl-cmark}/lib/tclcmark1.0"; - script = '' - set -ex - tmpdir="$(mktemp -d -t linus.onl-source.XXXXXXXXXXXX)" - cd "$tmpdir" - trap 'rm -rf $tmpdir' EXIT - # TODO: Only do minimal possible cloning - git clone https://github.com/linnnus/${domain} . - make _build - rsync --archive --delete _build/ /var/www/${domain} - ''; - - # TODO: Harden service - - # Network must be online for us to check. - after = ["network-online.target"]; - requires = ["network-online.target"]; - - # We must generate some files for NGINX to serve, so this should be run - # before NGINX. - before = ["nginx.service"]; - wantedBy = ["nginx.service"]; - }; - - # Register domain name with ddns. - services.cloudflare-dyndns.domains = [domain]; - - # Register virtual host. - services.nginx = { - virtualHosts."${domain}" = { - # NOTE: 'forceSSL' will cause an infite loop, if the cloudflare proxy does NOT connect over HTTPS. - enableACME = cfg.useACME; - forceSSL = cfg.useACME; - root = "/var/www/${domain}"; - }; - }; - }; -} diff --git a/modules/nixos/nofitications.linus.onl/default.nix b/modules/nixos/nofitications.linus.onl/default.nix deleted file mode 100644 index c050ef4..0000000 --- a/modules/nixos/nofitications.linus.onl/default.nix +++ /dev/null @@ -1,34 +0,0 @@ -{ - lib, - config, - ... -}: let - inherit (lib) mkEnableOption mkIf; - - cfg = config.modules."notifications.linus.onl"; -in { - options.modules."notifications.linus.onl" = { - enable = mkEnableOption "notifications.linus.onl static site"; - - useACME = mkEnableOption "built-in HTTPS stuff"; - }; - - config = mkIf cfg.enable { - services.push-notification-api = { - enable = true; - }; - - # Register domain name. - services.cloudflare-dyndns.domains = ["notifications.linus.onl"]; - - # Use NGINX as reverse proxy. - services.nginx.virtualHosts."notifications.linus.onl" = { - enableACME = cfg.useACME; - forceSSL = cfg.useACME; - locations."/" = { - recommendedProxySettings = true; - proxyPass = "http://unix:/run/push-notification-api.sock"; - }; - }; - }; -} -- cgit v1.2.3