diff --git a/flake.lock b/flake.lock index 6dbaea0..b5b3f78 100644 --- a/flake.lock +++ b/flake.lock @@ -641,16 +641,17 @@ "kernel-src": { "flake": false, "locked": { - "lastModified": 1678442395, - "narHash": "sha256-5q9ZqD+TQmLjKQI/sQetHHOgFRmwoNustb1I0M0f3ok=", + "lastModified": 1676631659, + "narHash": "sha256-TjAF7BPSDy5iHSk8byp+vsKop0V+rqrmr+TXLqXLB2M=", "owner": "radxa", "repo": "kernel", - "rev": "75f35d0549b7588cc561ed63b4246130c38a9c69", + "rev": "a9583fb47e9b96c552f458a376207141602c0025", "type": "github" }, "original": { "owner": "radxa", "repo": "kernel", + "rev": "a9583fb47e9b96c552f458a376207141602c0025", "type": "github" } }, @@ -1124,11 +1125,11 @@ "treefmt-nix": "treefmt-nix" }, "locked": { - "lastModified": 1678619682, - "narHash": "sha256-Om3Pe5Rss96jVh8Ncq72eFyu/ev8UO3iZZC8R0n2iAs=", + "lastModified": 1679242046, + "narHash": "sha256-CeGpTKnPQ++m11CV7Iisppwx+8fNwJSW8Q1ML6NxSJY=", "owner": "aciceri", "repo": "rock5b-nixos", - "rev": "ba79eb513a6db741b9c9d3b717ea5f7a36ff4812", + "rev": "e1099dd4a6be8018a5cc489fb2ee1d50e4e285a0", "type": "github" }, "original": { diff --git a/hmModules/firefox/default.nix b/hmModules/firefox/default.nix index e21696f..b2ff4b2 100644 --- a/hmModules/firefox/default.nix +++ b/hmModules/firefox/default.nix @@ -28,7 +28,7 @@ # fx_cast # TODO make PR to rycee NUR repo ]; settings = { - "browser.startup.homepage" = "https://searx.be"; + "browser.startup.homepage" = "https://google.com"; "browser.search.region" = "IT"; "browser.search.isUS" = false; "distribution.searchplugins.defaultLocale" = "it-IT"; @@ -39,7 +39,7 @@ "browser.shell.checkDefaultBrowser" = false; }; search.force = true; - search.default = "Searx"; + search.default = "Google"; search.engines = { "Searx" = { urls = [ diff --git a/hmModules/git-workspace/default.nix b/hmModules/git-workspace/default.nix new file mode 100644 index 0000000..9d29ce6 --- /dev/null +++ b/hmModules/git-workspace/default.nix @@ -0,0 +1,45 @@ +{age, ...}: { + imports = [ + ./git-workspace-program.nix + ./git-workspace-service.nix + ]; + + programs.git-workspace.enable = true; + services.git-workspace = { + enable = true; + frequency = "04:00:00"; + environmentFile = age.secrets.git-workspace-tokens.path; + workspaces = { + aciceri = { + provider = [ + { + provider = "github"; + name = "aciceri"; + path = "/home/ccr/projects"; + skips_forks = false; + } + ]; + }; + mlabs = { + provider = [ + { + provider = "github"; + name = "mlabs-haskell"; + path = "/home/ccr/projects"; + skip_forks = false; + } + ]; + }; + ethereansos = { + provider = [ + { + provider = "github"; + name = "EthereansOS"; + path = "/home/ccr/projects"; + skip_forks = false; + } + ]; + }; + }; + }; +} diff --git a/hmModules/git-workspace/git-workspace-program.nix b/hmModules/git-workspace/git-workspace-program.nix new file mode 100644 index 0000000..717d768 --- /dev/null +++ b/hmModules/git-workspace/git-workspace-program.nix @@ -0,0 +1,20 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.programs.git-workspace; +in { + options.programs.git-workspace = { + enable = lib.mkEnableOption "git-workspace"; + package = lib.mkOption { + type = lib.types.package; + default = pkgs.git-workspace; + description = "The git-workspace to use"; + }; + }; + config = lib.mkIf cfg.enable { + home.packages = [pkgs.git-workspace]; + }; +} diff --git a/hmModules/git-workspace/git-workspace-service.nix b/hmModules/git-workspace/git-workspace-service.nix new file mode 100644 index 0000000..0142c2c --- /dev/null +++ b/hmModules/git-workspace/git-workspace-service.nix @@ -0,0 +1,96 @@ +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.services.git-workspace; + tomlFormat = pkgs.formats.toml {}; +in { + options.services.git-workspace = { + enable = lib.mkEnableOption "git-workspace systemd timer"; + package = lib.mkOption { + type = lib.types.package; + default = + if config.programs.git-workspace.enable + then config.programs.git-workspace.package + else pkgs.git-workspace; + description = "The git-workspace to use"; + }; + frequency = lib.mkOption { + type = lib.types.str; + default = ""; + description = ""; + }; + environmentFile = lib.mkOption { + type = lib.types.path; + default = ""; + description = ""; + example = ""; + }; + workspaces = lib.mkOption { + type = lib.types.attrsOf tomlFormat.type; + default = {}; + description = "Workspaces verbatims"; + # example = { + # workspace-foo = { + # provider = [ + # { + # provider = "github"; + # name = ""; + # path = "..."; + # skip_forks = false; + # } + # ]; + # }; + # }; + }; + }; + config = lib.mkIf cfg.enable { + xdg.configFile = + lib.mapAttrs' (workspaceName: workspace: { + name = "git-workspace/${workspaceName}/workspace.toml"; + value.source = + (tomlFormat.generate "${workspaceName}-workspace.toml" workspace).outPath; + }) + cfg.workspaces; + systemd.user.services = + lib.mapAttrs' (workspaceName: workspace: rec { + name = "git-workspace-${workspaceName}-update"; + value = { + Unit.Description = "Runs `git-workspace update` for ${workspaceName}"; + Service = { + EnvironmentFile = cfg.environmentFile; + ExecStart = let + script = pkgs.writeShellApplication { + name = "${name}-launcher"; + text = '' + ${cfg.package}/bin/git-workspace \ + --workspace ${config.xdg.configHome}/git-workspace/${workspaceName} \ + update + ''; + runtimeInputs = with pkgs; [busybox openssh git]; + }; + in "${script}/bin/${name}-launcher"; + }; + }; + }) + cfg.workspaces; + systemd.user.timers = + lib.mapAttrs' (workspaceName: workspace: { + name = "git-workspace-${workspaceName}-update"; + value = { + Unit = { + Description = "Automatically runs `git-workspace update` for ${workspaceName}"; + }; + Timer = { + Unit = "git-workspace-${workspaceName}-update.unit"; + OnCalendar = cfg.frequency; + Persistent = true; + }; + Install.WantedBy = ["timers.target"]; + }; + }) + cfg.workspaces; + }; +} diff --git a/hmModules/git/default.nix b/hmModules/git/default.nix index 80d5640..2c84c64 100644 --- a/hmModules/git/default.nix +++ b/hmModules/git/default.nix @@ -14,13 +14,21 @@ in { pull.rebase = false; rebase.autostash = true; github.user = "aciceri"; + + user.signingKey = "/home/ccr/.ssh/id_rsa"; + gpg.format = "ssh"; + commit.gpgsign = true; }; userName = config.name; userEmail = config.email; - signing = { - signByDefault = true; - key = config.email; + # signing = { + # signByDefault = true; + # key = config.email; + # }; + + extraConfig.url = { + "ssh://git@github.com/" = {insteadOf = "https://github.com/";}; }; delta = { diff --git a/hmModules/kitty/default.nix b/hmModules/kitty/default.nix new file mode 100644 index 0000000..59407ae --- /dev/null +++ b/hmModules/kitty/default.nix @@ -0,0 +1,13 @@ +{ + programs.kitty = { + enable = true; + font = { + name = "Fira Code"; + size = 12; + }; + settings = { + disable_ligatures = "cursor"; + confirm_os_window_close = 0; + }; + }; +} diff --git a/hmModules/spotify/default.nix b/hmModules/spotify/default.nix new file mode 100644 index 0000000..ec376f4 --- /dev/null +++ b/hmModules/spotify/default.nix @@ -0,0 +1,27 @@ +{pkgs, ...}: let + spotify-adblock = pkgs.rustPlatform.buildRustPackage { + pname = "spotify-adblock"; + version = "1.0.2"; + src = pkgs.fetchFromGitHub { + owner = "abba23"; + repo = "spotify-adblock"; + rev = "v1.0.2"; + sha256 = "YGD3ymBZ2yT3vrcPRS9YXcljGNczJ1vCvAXz/k16r9Y="; + }; + + cargoSha256 = "bYqkCooBfGeHZHl2/9Om+0qbudyOCzpvwMhy8QCsPRE="; + }; + + spotify-adblocked = pkgs.callPackage ./spotify-adblocked.nix { + inherit spotify-adblock; + }; + # spotify-adblocked = pkgs.spotify.overrideAttrs (_: { + # preInstallPhase = '' + # ln -s ${spotify-adblock}/lib/libspotifyadblock.so $out/lib/spotify/ + # # wrapProgram $out/bin/spotify \ + # # --set LD_PRELOAD ${spotify-adblock}/lib/libspotifyadblock.so + # ''; + # }); +in { + home.packages = [spotify-adblocked]; +} diff --git a/hmModules/spotify/spotify-adblocked.nix b/hmModules/spotify/spotify-adblocked.nix new file mode 100644 index 0000000..acd0d6b --- /dev/null +++ b/hmModules/spotify/spotify-adblocked.nix @@ -0,0 +1,212 @@ +{ + fetchurl, + lib, + stdenv, + squashfsTools, + xorg, + alsa-lib, + makeWrapper, + wrapGAppsHook, + openssl, + freetype, + glib, + pango, + cairo, + atk, + gdk-pixbuf, + gtk3, + cups, + nspr, + nss, + libpng, + libnotify, + libgcrypt, + systemd, + fontconfig, + dbus, + expat, + ffmpeg, + curlWithGnuTls, + zlib, + gnome, + at-spi2-atk, + at-spi2-core, + libpulseaudio, + libdrm, + mesa, + libxkbcommon, + # High-DPI support: Spotify's --force-device-scale-factor argument + # not added if `null`, otherwise, should be a number. + deviceScaleFactor ? null, + spotify-adblock, +}: let + # TO UPDATE: just execute the ./update.sh script (won't do anything if there is no update) + # "rev" decides what is actually being downloaded + # If an update breaks things, one of those might have valuable info: + # https://aur.archlinux.org/packages/spotify/ + # https://community.spotify.com/t5/Desktop-Linux + version = "1.1.84.716.gc5f8b819"; + # To get the latest stable revision: + # curl -H 'X-Ubuntu-Series: 16' 'https://api.snapcraft.io/api/v1/snaps/details/spotify?channel=stable' | jq '.download_url,.version,.last_updated' + # To get general information: + # curl -H 'Snap-Device-Series: 16' 'https://api.snapcraft.io/v2/snaps/info/spotify' | jq '.' + # More examples of api usage: + # https://github.com/canonical-websites/snapcraft.io/blob/master/webapp/publisher/snaps/views.py + rev = "60"; + + deps = [ + alsa-lib + at-spi2-atk + at-spi2-core + atk + cairo + cups + curlWithGnuTls + dbus + expat + ffmpeg + fontconfig + freetype + gdk-pixbuf + glib + gtk3 + libdrm + libgcrypt + libnotify + libpng + libpulseaudio + libxkbcommon + mesa + nss + pango + stdenv.cc.cc + systemd + xorg.libICE + xorg.libSM + xorg.libX11 + xorg.libxcb + xorg.libXcomposite + xorg.libXcursor + xorg.libXdamage + xorg.libXext + xorg.libXfixes + xorg.libXi + xorg.libXrandr + xorg.libXrender + xorg.libXScrnSaver + xorg.libxshmfence + xorg.libXtst + zlib + ]; +in + stdenv.mkDerivation { + pname = "spotify"; + inherit version; + + # fetch from snapcraft instead of the debian repository most repos fetch from. + # That is a bit more cumbersome. But the debian repository only keeps the last + # two versions, while snapcraft should provide versions indefinately: + # https://forum.snapcraft.io/t/how-can-a-developer-remove-her-his-app-from-snap-store/512 + + # This is the next-best thing, since we're not allowed to re-distribute + # spotify ourselves: + # https://community.spotify.com/t5/Desktop-Linux/Redistribute-Spotify-on-Linux-Distributions/td-p/1695334 + src = fetchurl { + url = "https://api.snapcraft.io/api/v1/snaps/download/pOBIoZ2LrCB3rDohMxoYGnbN14EHOgD7_${rev}.snap"; + sha512 = "1209b956822d8bb661daa2c88616bed403ec26dc22c6b866cecff59235c56112284c2f99aa06352fc0df6fcd15225a6ad60afd3b4ff4d7b948ab83e70ab31a71"; + }; + + nativeBuildInputs = [makeWrapper wrapGAppsHook squashfsTools]; + + dontStrip = true; + dontPatchELF = true; + + unpackPhase = '' + runHook preUnpack + unsquashfs "$src" '/usr/share/spotify' '/usr/bin/spotify' '/meta/snap.yaml' + cd squashfs-root + if ! grep -q 'grade: stable' meta/snap.yaml; then + # Unfortunately this check is not reliable: At the moment (2018-07-26) the + # latest version in the "edge" channel is also marked as stable. + echo "The snap package is marked as unstable:" + grep 'grade: ' meta/snap.yaml + echo "You probably chose the wrong revision." + exit 1 + fi + if ! grep -q '${version}' meta/snap.yaml; then + echo "Package version differs from version found in snap metadata:" + grep 'version: ' meta/snap.yaml + echo "While the nix package specifies: ${version}." + echo "You probably chose the wrong revision or forgot to update the nix version." + exit 1 + fi + runHook postUnpack + ''; + + # Prevent double wrapping + dontWrapGApps = true; + + installPhase = '' + runHook preInstall + + libdir=$out/lib/spotify + mkdir -p $libdir + mv ./usr/* $out/ + + cp meta/snap.yaml $out + + # Work around Spotify referring to a specific minor version of + # OpenSSL. + + ln -s ${lib.getLib openssl}/lib/libssl.so $libdir/libssl.so.1.0.0 + ln -s ${lib.getLib openssl}/lib/libcrypto.so $libdir/libcrypto.so.1.0.0 + ln -s ${nspr.out}/lib/libnspr4.so $libdir/libnspr4.so + ln -s ${nspr.out}/lib/libplc4.so $libdir/libplc4.so + + ln -s ${ffmpeg.lib}/lib/libavcodec.so* $libdir + ln -s ${ffmpeg.lib}/lib/libavformat.so* $libdir + + ln -s ${spotify-adblock}/lib/libspotifyadblock.so $libdir + + rpath="$out/share/spotify:$libdir" + + patchelf \ + --interpreter "$(cat $NIX_CC/nix-support/dynamic-linker)" \ + --set-rpath $rpath $out/share/spotify/spotify + + librarypath="${lib.makeLibraryPath deps}:$libdir" + wrapProgram $out/share/spotify/spotify \ + ''${gappsWrapperArgs[@]} \ + ${lib.optionalString (deviceScaleFactor != null) '' + --add-flags "--force-device-scale-factor=${toString deviceScaleFactor}" \ + ''} \ + --prefix LD_LIBRARY_PATH : "$librarypath" \ + --prefix PATH : "${gnome.zenity}/bin" + + # fix Icon line in the desktop file (#48062) + sed -i "s:^Icon=.*:Icon=spotify-client:" "$out/share/spotify/spotify.desktop" + + # Desktop file + mkdir -p "$out/share/applications/" + cp "$out/share/spotify/spotify.desktop" "$out/share/applications/" + + # Icons + for i in 16 22 24 32 48 64 128 256 512; do + ixi="$i"x"$i" + mkdir -p "$out/share/icons/hicolor/$ixi/apps" + ln -s "$out/share/spotify/icons/spotify-linux-$i.png" \ + "$out/share/icons/hicolor/$ixi/apps/spotify-client.png" + done + + runHook postInstall + ''; + + meta = with lib; { + homepage = "https://www.spotify.com/"; + description = "Play music from the Spotify music service"; + sourceProvenance = with sourceTypes; [binaryNativeCode]; + license = licenses.unfree; + maintainers = with maintainers; [eelco ftrvxmtrx sheenobu mudri timokau ma27]; + platforms = ["x86_64-linux"]; + }; + } diff --git a/hmModules/sway/default.nix b/hmModules/sway/default.nix index c42b9e8..dc46f1d 100644 --- a/hmModules/sway/default.nix +++ b/hmModules/sway/default.nix @@ -10,6 +10,7 @@ ./gammastep.nix ../foot ../alacritty + ../kitty ]; config = { home.packages = with pkgs; [wl-clipboard]; diff --git a/hosts/default.nix b/hosts/default.nix index 3df46cd..8b32ccc 100644 --- a/hosts/default.nix +++ b/hosts/default.nix @@ -21,8 +21,23 @@ }; secrets = lib.mkOption { description = "List of secrets names in the `secrets` folder"; - type = lib.types.listOf lib.types.str; - default = []; + type = lib.types.attrsOf (lib.types.submodule ({name, ...}: { + options = { + owner = lib.mkOption { + type = lib.types.str; + default = "root"; + }; + group = lib.mkOption { + type = lib.types.str; + default = "root"; + }; + file = lib.mkOption { + type = lib.types.path; + default = "${self.outPath}/secrets/${name}.age"; + }; + }; + })); + default = {}; }; enableHomeManager = lib.mkOption { description = "Enable home-manager module"; @@ -80,20 +95,38 @@ ] ++ (lib.optionals (config.secrets != []) [ inputs.agenix.nixosModules.default - ({lib, ...}: { - age.secrets = + ({lib, ...}: let + allSecrets = lib.mapAttrs' (name: value: { + name = lib.removeSuffix ".age" name; + inherit value; + }) (import "${self.outPath}/secrets"); + filteredSecrets = lib.filterAttrs - (name: _: builtins.elem name config.secrets) - (lib.mapAttrs' (name: _: { - name = lib.removeSuffix ".age" (builtins.baseNameOf name); - value.file = "${self.outPath}/${name}"; - }) (import "${self.outPath}/secrets")); + (name: _: builtins.hasAttr name config.secrets) + allSecrets; + in { + age.secrets = + lib.mapAttrs' (name: _: { + name = builtins.baseNameOf name; + value = { + inherit (config.secrets.${name}) owner group file; + }; + }) + filteredSecrets; }) ]) - ++ (lib.optionals config.enableHomeManager [ + ++ (lib.optionals config.enableHomeManager (let + user = config.extraHmModulesUser; + extraHmModules = config.extraHmModules; + in [ inputs.homeManager.nixosModule - {home-manager.users."${config.extraHmModulesUser}".imports = config.extraHmModules;} - ]) + ({config, ...}: { + home-manager.users."${user}" = { + imports = extraHmModules; + _module.args.age = config.age or {}; + }; + }) + ])) ++ config.extraModules; specialArgs = { fleetModules = builtins.map (moduleName: "${self.outPath}/modules/${moduleName}"); @@ -117,7 +150,6 @@ extraHmModules = [ inputs.ccrEmacs.hmModules.default ]; - secrets = ["cachix"]; }; rock5b = { system = "aarch64-linux"; @@ -134,6 +166,15 @@ ]; }; hs = {}; + devbox = { + extraModules = [inputs.disko.nixosModules.disko]; + extraHmModules = [ + inputs.ccrEmacs.hmModules.default + ]; + secrets = { + "git-workspace-tokens".owner = "ccr"; + }; + }; }; flake.nixosConfigurations = diff --git a/hosts/devbox/default.nix b/hosts/devbox/default.nix new file mode 100644 index 0000000..36590ba --- /dev/null +++ b/hosts/devbox/default.nix @@ -0,0 +1,68 @@ +{ + modulesPath, + fleetModules, + lib, + pkgs, + ... +}: { + imports = + [ + (modulesPath + "/installer/scan/not-detected.nix") + (modulesPath + "/profiles/qemu-guest.nix") + ] + ++ fleetModules [ + "common" + "ssh" + "ccr" + "nix" + ]; + + ccr = { + enable = true; + autologin = true; + modules = [ + "emacs" + "git" + "gpg" + "helix" + "password-store" + "shell" + "xdg" + "git-workspace" + ]; + packages = with pkgs; [ + comma + ]; + extraGroups = [ + "wheel" + "fuse" + "video" + "networkmanager" + ]; + }; + + fonts = { + fonts = with pkgs; [powerline-fonts dejavu_fonts fira-code fira-code-symbols emacs-all-the-icons-fonts nerdfonts joypixels etBook]; + fontconfig.defaultFonts = { + monospace = ["DejaVu Sans Mono for Powerline"]; + sansSerif = ["DejaVu Sans"]; + serif = ["DejaVu Serif"]; + }; + }; + + nixpkgs.config.joypixels.acceptLicense = true; + + environment.systemPackages = with pkgs; [waypipe firefox]; + + programs.mosh.enable = true; + + disko.devices = import ./disko.nix { + inherit lib; + }; + + boot.loader.grub = { + devices = ["/dev/sda"]; + efiSupport = true; + efiInstallAsRemovable = true; + }; +} diff --git a/hosts/devbox/disko.nix b/hosts/devbox/disko.nix new file mode 100644 index 0000000..bdf06b4 --- /dev/null +++ b/hosts/devbox/disko.nix @@ -0,0 +1,79 @@ +# Example to create a bios compatible gpt partition +{ + lib, + disks ? ["/dev/sda"], + ... +}: { + disk = lib.genAttrs disks (dev: { + device = dev; + type = "disk"; + content = { + type = "table"; + format = "gpt"; + partitions = [ + { + name = "boot"; + type = "partition"; + start = "0"; + end = "1M"; + part-type = "primary"; + flags = ["bios_grub"]; + } + { + type = "partition"; + name = "ESP"; + start = "1MiB"; + end = "100MiB"; + bootable = true; + content = { + type = "mdraid"; + name = "boot"; + }; + } + { + name = "root"; + type = "partition"; + start = "100MiB"; + end = "100%"; + part-type = "primary"; + bootable = true; + content = { + type = "lvm_pv"; + vg = "pool"; + }; + } + ]; + }; + }); + mdadm = { + boot = { + type = "mdadm"; + level = 1; + metadata = "1.0"; + content = { + type = "filesystem"; + format = "vfat"; + mountpoint = "/boot"; + }; + }; + }; + lvm_vg = { + pool = { + type = "lvm_vg"; + lvs = { + root = { + type = "lvm_lv"; + size = "100%FREE"; + content = { + type = "filesystem"; + format = "ext4"; + mountpoint = "/"; + mountOptions = [ + "defaults" + ]; + }; + }; + }; + }; + }; +} diff --git a/hosts/rock5b/default.nix b/hosts/rock5b/default.nix index a88e78b..fbee320 100644 --- a/hosts/rock5b/default.nix +++ b/hosts/rock5b/default.nix @@ -14,17 +14,33 @@ "common" "ssh" "ccr" + "cgit" ]); ccr.enable = true; - # programs.sway.enable = true; - services.rock5b-fan-control.enable = true; - # nixpkgs.config.permittedInsecurePackages = [ - # "libav-11.12" - # ]; + services.nginx.enable = true; + services.nginx.virtualHosts."localhost" = { + cgit = { + enable = true; + virtual-root = "/"; + include = [ + (builtins.toFile "cgitrc-extra-1" '' + repo.url=test-repo.git + repo.path=/srv/git/test-repo. + repo.desc=the master foo repository + repo.owner=fooman@example.com + css=/custom.css + '') + (builtins.toFile "cgitrc-extra-2" '' + # Allow http transport git clone + enable-http-clone=1 + '') + ]; + }; + }; fileSystems."/mnt/film" = { device = "//ccr.ydns.eu/film"; @@ -58,6 +74,18 @@ extraGroups = ["video" "input"]; }; + networking.firewall.allowedTCPPorts = [ + 8080 # kodi control + 80 + ]; + + programs.bash.loginShellInit = '' + [[ "$(tty)" == '/dev/tty1' ]] && \ + [[ "$(whoami)" == 'kodi' ]] && \ + ${pkgs.kodi-rock5b}/bin/kodi-standalone + + ''; + # Waiting for https://github.com/NixOS/nixpkgs/issues/140304 services.getty = let script = pkgs.writeText "login-program.sh" '' diff --git a/hosts/thinkpad/default.nix b/hosts/thinkpad/default.nix index e007a24..b4755e8 100644 --- a/hosts/thinkpad/default.nix +++ b/hosts/thinkpad/default.nix @@ -60,6 +60,7 @@ "zathura" "chrome" "obs-studio" + "spotify" ]; packages = with pkgs; [ comma diff --git a/modules/cgit/custom.css b/modules/cgit/custom.css new file mode 100644 index 0000000..b3f4f42 --- /dev/null +++ b/modules/cgit/custom.css @@ -0,0 +1,86 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ + +@import url("cgit.css"); + +* { line-height: 1.25em; } + +div#cgit { + max-width: 117ch; + margin: auto; + font-family: monospace; + -moz-tab-size: 4; + tab-size: 4; +} + +div#cgit table#header td.sub { + border-top: none; +} +div#cgit table#header td.sub.right { + padding-right: 1em; +} +div#cgit table.tabs { + border-bottom: none; +} +div#cgit div.content { + border-bottom: none; +} +div#cgit table.list th a { + color: inherit; +} +div#cgit table.list tr:nth-child(even) { + background: inherit; +} +div#cgit table.list tr:hover { + background: inherit; +} +div#cgit table.list tr.nohover-highlight:hover:nth-child(even) { + background: inherit; +} + +div#cgit table.blob td.linenumbers a:target { + color: goldenrod; + text-decoration: underline; + outline: none; +} + +div#cgit div#summary { + max-width: 80ch; +} + +/* for hilex(1) */ +div#cgit pre .Ke { color: dimgray; } +div#cgit pre .Ma { color: green; } +div#cgit pre .Co { color: navy; } +div#cgit pre .St { color: teal; } +div#cgit pre .Fo { color: teal; font-weight: bold; } +div#cgit pre .Su { color: olive; } + +/* for htagml(1) */ +div#cgit pre a.tag { color: inherit; text-decoration: underline; } +div#cgit pre a.tag:target { color: goldenrod; outline: none; } + +/* for mandoc(1) */ +table.head, table.foot { width: 100%; } +td.head-rtitle, td.foot-os { text-align: right; } +td.head-vol { text-align: center; } +div.Pp { margin: 1ex 0ex; } +div.Nd, div.Bf, div.Op { display: inline; } +span.Pa, span.Ad { font-style: italic; } +span.Ms { font-weight: bold; } +dl.Bl-diag > dt { font-weight: bold; } +code.Nm, code.Fl, code.Cm, code.Ic, code.In, code.Fd, code.Fn, +code.Cd { font-weight: bold; font-family: inherit; } + +h1.Sh { font-size: 1.5em; } +table.Nm td:first-child { padding-right: 1ch; } +code.Fl { white-space: nowrap; } +span.RsT { font-style: italic; } +dl.Bl-tag:not(.Bl-compact) > dt { margin-top: 1em; } +ul.Bl-bullet:not(.Bl-compact) > li { margin-top: 1em; } +div.Bd-indent { margin-left: 4ch; } +table.Bl-column { width: 100%; } +table.foot { margin-top: 1em; } + +div#cgit a.permalink { color: inherit; } diff --git a/modules/cgit/default.nix b/modules/cgit/default.nix new file mode 100644 index 0000000..00ce56d --- /dev/null +++ b/modules/cgit/default.nix @@ -0,0 +1,133 @@ +{ + config, + lib, + pkgs, + ... +}: +with lib; let + globalConfig = config; + settingsFormat = { + type = with lib.types; let + value = + oneOf [int str] + // { + description = "INI-like atom (int or string)"; + }; + values = + coercedTo value lib.singleton (listOf value) + // { + description = value.description + " or a list of them for duplicate keys"; + }; + in + attrsOf values; + generate = name: values: + pkgs.writeText name (lib.generators.toKeyValue {listsAsDuplicateKeys = true;} values); + }; +in { + options.services.nginx.virtualHosts = mkOption { + type = types.attrsOf (types.submodule ({config, ...}: let + cfg = config.cgit; + + # These are the global options for this submodule, but for nicer UX they + # are inlined into the freeform settings. Hence they MUST NOT INTERSECT + # with any settings from cgitrc! + options = { + enable = mkEnableOption "cgit"; + + location = mkOption { + default = "/"; + type = types.str; + description = '' + Location to serve cgit on. + ''; + }; + }; + + # Remove the global options for serialization into cgitrc + settings = removeAttrs cfg (attrNames options); + in { + options.cgit = mkOption { + type = types.submodule { + freeformType = settingsFormat.type; + inherit options; + config = { + css = mkDefault "/cgit.css"; + logo = mkDefault "/cgit.png"; + favicon = mkDefault "/favicon.ico"; + }; + }; + default = {}; + example = literalExample '' + { + enable = true; + virtual-root = "/"; + source-filter = "''${pkgs.cgit-pink}/lib/cgit/filters/syntax-highlighting.py"; + about-filter = "''${pkgs.cgit-pink}/lib/cgit/filters/about-formatting.sh"; + cache-size = 1000; + scan-path = "/srv/git"; + include = [ + (builtins.toFile "cgitrc-extra-1" ''' + # Anything that has to be in a particular order + ''') + (builtins.toFile "cgitrc-extra-2" ''' + # Anything that has to be in a particular order + ''') + ]; + } + ''; + description = '' + Verbatim contents of the cgit runtime configuration file. Documentation + (with cgitrc example file) is available in "man cgitrc". Or online: + http://git.zx2c4.com/cgit/tree/cgitrc.5.txt + ''; + }; + + config = let + location = removeSuffix "/" cfg.location; + in + mkIf cfg.enable { + locations."${location}/" = { + root = "${pkgs.cgit-pink}/cgit/"; + tryFiles = "$uri @cgit"; + }; + locations."~ ^${location}/(cgit.(css|png)|favicon.ico|robots.txt)$" = { + alias = "${pkgs.cgit-pink}/cgit/$1"; + }; + locations."~ ^${location}/custom.css$" = { + alias = ./custom.css; + }; + locations."@cgit" = { + extraConfig = + '' + include ${pkgs.nginx}/conf/fastcgi_params; + fastcgi_param CGIT_CONFIG ${settingsFormat.generate "cgitrc" settings}; + fastcgi_param SCRIPT_FILENAME ${pkgs.cgit-pink}/cgit/cgit.cgi; + fastcgi_param QUERY_STRING $args; + fastcgi_param HTTP_HOST $server_name; + fastcgi_pass unix:${globalConfig.services.fcgiwrap.socketAddress}; + '' + + ( + if cfg.location == "/" + then '' + fastcgi_param PATH_INFO $uri; + '' + else '' + fastcgi_split_path_info ^(${location}/)(/?.+)$; + fastcgi_param PATH_INFO $fastcgi_path_info; + '' + ); + }; + }; + })); + }; + + config = let + vhosts = config.services.nginx.virtualHosts; + in + mkIf (any (name: vhosts.${name}.cgit.enable) (attrNames vhosts)) { + # make the cgitrc manpage available + environment.systemPackages = [pkgs.cgit-pink]; + + services.fcgiwrap.enable = true; + }; +} diff --git a/secrets/autistici-password.age b/secrets/autistici-password.age index fe2962c..1de9cea 100644 --- a/secrets/autistici-password.age +++ b/secrets/autistici-password.age @@ -1,19 +1,17 @@ age-encryption.org/v1 -> ssh-rsa QHr3/A -htmJ7Ita9rp1TshaeTq14G7Z8vUmsHG8cvcbiT+X7acGx/W79zUjM0r1KiBwyD75 -SqLMhlLylaPCf7wjoL800UZ/nlQsXCCOgETKFbJH7jJIJhsYIzWOWwVScXjRNRqY -xp1Y+TTnyao0gzTv2uFJy2w2cg2VM+f+UXOeoQ6gUGxFHvwsuRDorXu2n/JHXh/R -kiNZGBi9tx93F3jAsHM6Sudq7j1HsJwQZO6vaHwuqxankHX5CpXXo8bHY1pE+smG -yO92qJ4cxSB/A9T2PXr20EDmj1Nr4pbk12Tn69GZasSKAlyUo0SDUW6BVFHwDf8E -L3K6XKyGuUcZsd5Hh26deT7kAYwUbD5Edlyhgc8Rp9/rX2qEG5i196/tLL0ngI4G -xoHwHhnVUC0IULOizzPbxtnat1cCIhcSbncKv6wnBnlXHDivJV8Vg0YGnzmYy0j8 -TbVN76OsNrU8zXXTGjLO6Gp+AEPIk5Z72Snpoq5Io4H+IoNuX0hYGbMrPQg0Urnn -gM2/EN2ivCKfMMNWI6sq0FJy4IsGNsVLM98VmAh9pfWXGFjz3So9cYMwYCqG0vbP -HQQKqsmxbdJljxGix7Z5SpIl6bDuS66hJpEA6wlvGcUmXzy+kFnlTNmmFwovfotX -wIPYTJZGtXh0WNsIuVnPYSZ6MahBswKzHcI+az48PvM --> u!n2o-grease -+fY6SvlSCYFsB0/7dxDJtw7zKufZ9LZUZ7tqVaJkdjSl9y/2fDGVQHFKFXBGhHKu -wcIB ---- hBiR9gBibjABVhE5I42l1zepYvWZq3qsqXk9Y8qlTno -蹿\Ѓ- -(>2A^ l[CPW@ϛdj \ No newline at end of file +mkKvIOoT0dIym2TcQCRk+QALX+gUo2HqahYwMbuJbfbUAyoB3rG9ccgwoVr7R+Iu +KJazZredX8SBnA8X2V6J9GIT4xkShAM5JZ4g8BLclKFqPXmSXzNh26Kxli7upt15 +h5hmGejDJ3jdPU7UTfxv0g8EnXbvEBdP5C0B4nKex11d0ZBceCZmsXDTj+c9Y6f6 +gf7tveLqLk1bj0gyKA3KHpUz+yj2dN5AFyME55bcISqoNMmXIX9Iu1JygF9LG8CL +EC6/dcSGe5FPjTFeJmmvjq8+adJ1oGsmH1UUwkDSMbpAWVMGwqZbiwIjcvsfx95i +KGYlNOcuLXxh9eWpXqQBGt3u5dAN3tHq8xU3D0pDefRU/bnIImYOpW1p2P12O7L6 +ntmFhOehI5dj4awLV9agKEst7GsiqFkODFELV+rOA+4pJnkKwY/GEdyJF4SmpBPE +bFwOlPaw5DH4JWrEZBF0CCidPHME6eXXkPPfsRyjLq8cS2e+iVie+bokfC5VrMpV +3g1PVYKi1dhZ+lFKaL8fcMx/AHXAfPsCFFJAO7idfhNqEh3RhOPTwQu6tbffA+gT +qTsK830hTkMDIkk3u6U/eBDLJ6QUsmsl7S/8lzpnC22XIIRckgPQPZo7Lj0TlCUf +RRCXX7bxvrv941wlgiLEvHzIJhy2IkyNx2fVrizj/8Q +-> 0\@ek*.D-grease Kr #fh S|97g@0K N?M2 +JzOV6h/q +--- u1h801vplfmXhMJ8qkpD+XTyI9TwY1XjQcGMJqTl6YU +b- o}1 FoBi%w Dw&J \ No newline at end of file diff --git a/secrets/cachix.age b/secrets/cachix.age index e09ae5d..ae7a5d3 100644 Binary files a/secrets/cachix.age and b/secrets/cachix.age differ diff --git a/secrets/default.nix b/secrets/default.nix index 1e637d2..3d09736 100644 --- a/secrets/default.nix +++ b/secrets/default.nix @@ -1,9 +1,11 @@ let - keys = { - agenix = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5cEUx25pnZiH3eBrE2xNbJ92gJiKSznDUNRzcEL4ti6FlJm+75p4q0hgdqHwStR8+uCWBL6viVFCGutOVMFE5MX1Oc3A8fJdR6H9Rrwvk/1UQzqzc9tWxw1qPLKz+fnPDomjOvNofghCWQRwX3Xf1HnIqvRwELpNbR9i+/cHkDGzLJxkstbt4gol8ywMPkw02QdKk8s5MEd1vawxc+7Chs0JPW57RDqDYFErYys52JLeAViCBB9bofF+KT42LuRXKSjWlvCV9kR5TL49vUeBgzMQWMh++WQdN4m9lpqFqYyc75I49/E0HGf8LChDSS+hvRnb5MbtnVGjEA4WDHyldmJCvUNob5CUo4FjoSPRi+S/J3Ads8D4JVwaJOJEVqmMKEhiQ0Hzk4hwe3eV/VumlZj4U/QjaCrqqi4TW/iP0gNRfzcfiM+G/z5R7w1NMUpTX7oilyKjMQmGnXB857D3SSptS7dwh5OiKhVmrQMRCduooUsj236abqLU28K//RnxhOgh8kDGgoUHApnTiMZNKhgLiR42lKrubNcW1tAAqoNyFLMwwXeMLjh0iP1b5y8ntfNPNIcGb7vcwpS24z/aIjW7rQ4J7x5EBphHGhys6ne+irdhOM8c7kFr+c8+Q2oU0YAtFuMYztAFOHm1e20X00Zvys2nuee+hT9F1NungAQ=="; + users.ccr = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQC5cEUx25pnZiH3eBrE2xNbJ92gJiKSznDUNRzcEL4ti6FlJm+75p4q0hgdqHwStR8+uCWBL6viVFCGutOVMFE5MX1Oc3A8fJdR6H9Rrwvk/1UQzqzc9tWxw1qPLKz+fnPDomjOvNofghCWQRwX3Xf1HnIqvRwELpNbR9i+/cHkDGzLJxkstbt4gol8ywMPkw02QdKk8s5MEd1vawxc+7Chs0JPW57RDqDYFErYys52JLeAViCBB9bofF+KT42LuRXKSjWlvCV9kR5TL49vUeBgzMQWMh++WQdN4m9lpqFqYyc75I49/E0HGf8LChDSS+hvRnb5MbtnVGjEA4WDHyldmJCvUNob5CUo4FjoSPRi+S/J3Ads8D4JVwaJOJEVqmMKEhiQ0Hzk4hwe3eV/VumlZj4U/QjaCrqqi4TW/iP0gNRfzcfiM+G/z5R7w1NMUpTX7oilyKjMQmGnXB857D3SSptS7dwh5OiKhVmrQMRCduooUsj236abqLU28K//RnxhOgh8kDGgoUHApnTiMZNKhgLiR42lKrubNcW1tAAqoNyFLMwwXeMLjh0iP1b5y8ntfNPNIcGb7vcwpS24z/aIjW7rQ4J7x5EBphHGhys6ne+irdhOM8c7kFr+c8+Q2oU0YAtFuMYztAFOHm1e20X00Zvys2nuee+hT9F1NungAQ=="; + hosts = { + test = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHc46mGCuaKLwNzK/abuedYQLw9h/Cp5MhVb7IHTGh0E root@test"; }; in { - "secrets/cachix.age".publicKeys = [keys.agenix]; - "secrets/autistici-password.age".publicKeys = [keys.agenix]; - "secrets/magit-forge-github-token.age".publicKeys = [keys.agenix]; + "cachix.age".publicKeys = [users.ccr]; + "autistici-password.age".publicKeys = [users.ccr]; + "magit-forge-github-token.age".publicKeys = [users.ccr]; + "git-workspace-tokens.age".publicKeys = [users.ccr hosts.test]; } diff --git a/secrets/git-workspace-token.age b/secrets/git-workspace-token.age new file mode 100644 index 0000000..c3fdd71 --- /dev/null +++ b/secrets/git-workspace-token.age @@ -0,0 +1,20 @@ +age-encryption.org/v1 +-> ssh-rsa QHr3/A +keGOWcWTGA2ddugZLX3ZXs4V7vsEMYv3SNSFlgvqjiJx0dzUQCCrp5FE2v+uXwjp +MQegxCuveBiHK4ea5eogCt9ZTAzkvbV8J3NAxYqyGs/sOjbArluqUkRzJ+mV1L5f +m9iu5s1eyViesiRT7mt9dI7JvZGfbxbroZcXBDDjxqcbrOyzqhnRhSH4FhYXMITa +63fIeqgXNpdy6XnwFS8q0nQoECboKdWHPRvRJlJ86ysBhI3QwZRwjG+v14XpsE4e +6meFszkX0A+gg//qOe02TTSoMNexupdVj4mSrola5HFkiOfLAJIS+51L+g3Rs7ZN +scvjnxlv7nF/4K/s0ksFs8gpDjWzY0VVdhbY3ZBJQCanF/LBtol/5WttCRHXS+/R +be+Ak/j8NpZJcHgCJkXinA9y0fsEKb2YngX4klnemGQ12an15cfV8B4V1GON1Brz +Bro7Z3cvxaHhXWI3VlsbFXlffJgEz+rF434z9u7mYlCjkt0wJAHMZkBqn/Ecu7wE +6b4qrmI3VdsDCNp4fMVLvgfdAyzl5kfzqDPJRKBhXYyO51dK6wKy3j4hT5v4ahyK +2TpRwVebmrmE2jIEU+X0QX4mw76f5oZ0AArUO1XZT2oiT7bW0MFWiqT526xok7sa +ZPZZTEMeuNNn7GQscknt3mTYfrwSPwCNH5YcTXUsINc +-> ssh-ed25519 zco92w YYlPbyyNNzbqwHrvB4K/S6pSXF19FgBMLa7YPwLURlA +1lAiYKEGBuPeNEpE75tcrsf6mzTj0UB+rH15L2LfeN8 +-> s)xdR|-grease M +uVmULVxzGAPmPwQyi+DMLt9YXIhj5nLW6ox/cDQiJ0r9P1KecouXQPU +--- MU/ggSTGHLbNDds2mBqI99xf68ab3vI5C3r8wZFhNMM +]F=w01SS7ftR9_zV +KaWy?8a F!nC(k&'Q~X \ No newline at end of file diff --git a/secrets/git-workspace-tokens.age b/secrets/git-workspace-tokens.age new file mode 100644 index 0000000..d54383a Binary files /dev/null and b/secrets/git-workspace-tokens.age differ diff --git a/secrets/magit-forge-github-token.age b/secrets/magit-forge-github-token.age index 8ae2842..eafea43 100644 --- a/secrets/magit-forge-github-token.age +++ b/secrets/magit-forge-github-token.age @@ -1,18 +1,19 @@ age-encryption.org/v1 -> ssh-rsa QHr3/A -minytBGD5mhGlZVBUiHlTCKgR/IQBa5CLqr49w39AM8fjjJtj19UryLyoA1Jouef -GKRU+uR16Lj9MjdqJhcGi7Ox7/L+Si/eh5M5y08G0M8bod6VTyezbjWjbKTeoY68 -72Iz20s254jP75jhlyekL/rTQJR9aeQiDsVXBr02wu8ICC+eESfTiq8Srwwaq3Gr -H/rfHO2/vqrA+NYSI9I+1fCYp+8YLSIAMmDI4jjrC/d3RQhDkiqhn2uvslV5UiqH -yBcfIEz7CSNdJp5KfF/Qw2BgepkMibYj+iKZ9zfYZJQyQy8FCEXfx+BwwjdEPadk -0lOmatm1UmR8BAl0LCof7VxwsEbTeQHuz/FX/kfadlxNSUYF0bkVBNWHsLG1YP6Y -JBzFiBA5Wy8qEUHIeKmVP70moVohURiTliV8mN1dL490ns+kgpBPjQm+ThJGXyCE -ibx6j8AmGxMXoykBIFYxi3HvSJm5CKhUahBCHLlTdcUoGqDMz6ZS0Ys6ojW6iMEu -VfI1ZeHScnFKmR7Y237i5ZRYl4wUD7tjBSHl+7T1UsHUyg6Vymop6tiR+TYp0Jwp -j+1V4irQ5PVbULWW5IYEDzyeggiUUarWXJQiIhZvR+w5IQGK0OpigWqlzZz/OJ9N -8VyiKhr1/Q7Lbxvt3aF/gudZG9HeDVAnXTLSxF/HfWs --> k04\pIXA-grease !~)DrR 8gGWs" % -bWx1d5LHHOqqMjp9oLbsWfuSmojeftp2Cm9gfvf78lbLFfamqVRJDZiqwCOBF8Zx -haDVCJPzlTbXJ7dJ3A ---- Oj+guFcy4YP1C3mhTRK7WIogGKH1PH06Ppc+MqT6dV0 -cp ̓lIFCamT 5lɓ! `Ykg4p5fpR0|] \ No newline at end of file +qcb2b07+fqMtxbC9ij/OV7HeQqQ7NGTVx2qN6UPqkbcSx4FU9RoHVdRvyhj4gOcz +R1lC2li0gsoijTnSlpJNdJALk/BBFKMNtMDhI4zeEivVhRuPg2cXpf4q41eL+FK+ +UIovBdx+xTOaSvWtz4QzWMaGaREUTLlg7IS+OjVh9p6LgXpn5I5L4vQ8P4n8JGRb +cNsXIVKJ5KMOzoj+UZCJ4ltfd4kUPmETSXMCtu2qEIsV9hF6T1yeImGXZW2tgNHC +WobMSm7Au0l5w2NQDwgEQnEE9BAFhsxZpM1nSC80vh5q9EHwvRkAOZT2l7MAp+7l +yKhbF4yN5dM7Xf4SqXY89YeSU2uZ52AwPam54+MRyeLfc2qS9zjGaFo1+7SFjA5W +dHbFBEXOjAJinVNgNGs9r4ot1CAZFym3nUhvbET8Cqirl9w71vObw6KqwWM04xTH +IXhUo2xbCObuPTkohoUg/P/EFyBrg6PBnUDW4lCx6Wi20SEoQo4KnimQHYZnSC7Q +UOk+Y/dwF+rRJcJ4BkbKJuieFlmHYIlNMbmpDz4ufsOSl9sL5Sop+28uLDee5llh +zcNe+S7mpHdHVjqc5S9CXsReqVxzqnv6igaOcAm704W6WeytJx7u3kwu3vaoDTY4 +5m9Oag936EuBHdsyyR+f7X3OsCsF46/iP0OEDEePkdo +-> e