From 93ddc9cb616d1fcabd8f1b7cab338d1da8701fd4 Mon Sep 17 00:00:00 2001
From: Collin Williams <96917990+bluedragon1221@users.noreply.github.com>
Date: Sun, 22 Feb 2026 15:22:54 -0600
Subject: stuff
---
modules/services/favicon.svg | 1 -
modules/services/nixos/cgit.nix | 135 -----------
modules/services/nixos/cgit/cgit.css | 385 ++++++++++++++++++++++++++++++++
modules/services/nixos/cgit/default.nix | 139 ++++++++++++
modules/services/nixos/cgit/favicon.svg | 1 +
modules/services/nixos/default.nix | 2 +-
modules/services/nixos/goaccess.nix | 2 +-
7 files changed, 527 insertions(+), 138 deletions(-)
delete mode 100644 modules/services/favicon.svg
delete mode 100644 modules/services/nixos/cgit.nix
create mode 100644 modules/services/nixos/cgit/cgit.css
create mode 100644 modules/services/nixos/cgit/default.nix
create mode 100644 modules/services/nixos/cgit/favicon.svg
(limited to 'modules/services')
diff --git a/modules/services/favicon.svg b/modules/services/favicon.svg
deleted file mode 100644
index 52c5f79..0000000
--- a/modules/services/favicon.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/modules/services/nixos/cgit.nix b/modules/services/nixos/cgit.nix
deleted file mode 100644
index e1726bc..0000000
--- a/modules/services/nixos/cgit.nix
+++ /dev/null
@@ -1,135 +0,0 @@
-{
- pkgs,
- config,
- lib,
- ...
-}: let
- cfg = config.collinux.services.cgit;
-in {
- config = lib.mkIf cfg.enable {
- environment.shells = ["${pkgs.git}/bin/git-shell"];
- users.groups."git" = {};
- users.users."git" = {
- isSystemUser = true;
- group = "git";
- shell = "${pkgs.git}/bin/git-shell";
-
- home = "/var/lib/cgit";
- createHome = true;
- homeMode = "755";
-
- openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC3SjzIs3YI8PWJaNrAuaEeRcTcvIVHOKyCh2VwHTHEF"];
- };
- hjem.users."git".files = {
- "git-shell-commands/set-description" = {
- executable = true;
- text = ''
- #!/usr/bin/env bash
- set -euo pipefail
- repo="$1"
- desc="$2"
- base="/var/lib/cgit"
- repo_path="$base/$repo"
-
- test -d "$repo_path" || { echo "Repository does not exist"; exit 1; }
-
- # Prevent path traversal
- real=$(realpath "$repo_path")
- if [[ "$real" != "$base/"* ]]; then
- echo "Invalid path"
- exit 1
- fi
-
- echo "$desc" | head -n 1 > "$repo_path/description"
-
- echo "Description updated for '$repo'"
- '';
- };
- "git-shell-commands/create-repo" = {
- executable = true;
- text = ''
- #!/usr/bin/env bash
- set -euo pipefail
- repo="$1"
- base="/var/lib/cgit"
- repo_path="$base/$repo"
-
- test -d "$repo_path" && { echo "Repository already exists."; exit 1; }
-
- git init --bare "$repo_path"
- echo "Repository '$repo' created"
- '';
- };
- };
-
- services.openssh.extraConfig = lib.mkAfter ''
- Match User git
- AllowTcpForwarding no
- X11Forwarding no
- PermitTunnel no
- PubkeyAuthentication yes
- AuthenticationMethods publickey
- '';
-
- environment.etc."cgitrc".text = ''
- logo=/favicon.svg
- favicon=/favicon.svg
-
- repo.sort=age
- enable-http-clone=1
- diff-style=ssdiff
-
- root-title=Ganymede Public Git Server
- root-desc=
-
- readme=:README.md
- about-filter=${pkgs.cgit}/lib/cgit/filters/html-converters/md2html
-
- virtual-root=/
- scan-path=/var/lib/cgit
- '';
-
- services.fcgiwrap.instances."cgit" = {
- process = {
- user = "git";
- group = "git";
- };
-
- socket = {
- user = "caddy";
- group = "caddy";
- type = "unix";
- address = "/run/fcgiwrap-cgit.sock";
- };
- };
-
- networking.extraHosts = "127.0.0.1 git.ganymede";
- services.caddy.virtualHosts."git.ganymede".extraConfig = let
- custom_cgit = pkgs.stdenv.mkDerivation {
- name = "custom-cgit-assets";
- src = pkgs.cgit;
- installPhase = ''
- mkdir -p $out
- cp -pPR ./cgit/* $out/
-
- rm -f $out/cgit.png $out/favicon.ico
- cp -f ${../favicon.svg} $out/favicon.svg
- '';
- };
- in ''
- tls internal
-
- @assets path /cgit.css /cgit.js /favicon.svg /robots.txt
- handle @assets {
- root * ${custom_cgit}
- file_server
- }
-
- reverse_proxy unix//run/fcgiwrap-cgit.sock {
- transport fastcgi {
- env SCRIPT_FILENAME ${custom_cgit}/cgit.cgi
- }
- }
- '';
- };
-}
diff --git a/modules/services/nixos/cgit/cgit.css b/modules/services/nixos/cgit/cgit.css
new file mode 100644
index 0000000..6d55e02
--- /dev/null
+++ b/modules/services/nixos/cgit/cgit.css
@@ -0,0 +1,385 @@
+html {
+ height: 100vh;
+ width: 100vw;
+}
+
+body {
+ /* Ensure the parent allows the child to center */
+ margin: 0;
+ padding: 0;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+div#cgit {
+ padding: 4px;
+ margin: 0 auto;
+
+ width: 95%;
+ max-width: 1200px;
+
+ font-family: sans-serif;
+ font-size: 10pt;
+ color: #333;
+ background: white;
+
+ /* Global element styles within cgit */
+ a {
+ color: blue;
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+ img {
+ border: none;
+ }
+
+ input#switch-btn {
+ margin: 2px 0px 0px 0px;
+ }
+
+ .oid {
+ font-family: monospace;
+ font-size: 90%;
+ }
+
+ /* Utility Classes */
+ .left { text-align: left; }
+ .right { text-align: right; }
+
+ /* Header Table */
+ table#header {
+ width: 100%;
+ margin-bottom: 1em;
+ border-collapse: collapse;
+
+ td {
+ &.logo {
+ width: 96px;
+ vertical-align: top;
+ }
+
+ &.main {
+ font-size: 250%;
+ padding-left: 10px;
+ white-space: nowrap;
+ a { color: #000; }
+ }
+
+ &.form {
+ text-align: right;
+ vertical-align: bottom;
+ padding-right: 1em;
+ padding-bottom: 2px;
+ white-space: nowrap;
+
+ form, input, select {
+ font-size: 90%;
+ }
+ }
+
+ &.sub {
+ color: #777;
+ border-top: solid 1px #ccc;
+ padding-left: 10px;
+ }
+ }
+ }
+
+ /* Tabs Table */
+ table.tabs {
+ border-bottom: solid 3px #ccc;
+ border-collapse: collapse;
+ margin-top: 2em;
+ margin-bottom: 0px;
+ width: 100%;
+
+ td {
+ padding: 0px 1em;
+ vertical-align: bottom;
+
+ a {
+ padding: 2px 0.75em;
+ color: #777;
+ font-size: 110%;
+
+ &.active {
+ color: #000;
+ background-color: #ccc;
+ }
+ }
+
+ &.form {
+ text-align: right;
+ form {
+ padding-bottom: 2px;
+ font-size: 90%;
+ white-space: nowrap;
+ }
+ input, select { font-size: 90%; }
+ }
+ }
+ }
+
+ /* Content Sections */
+ div.path {
+ margin: 0px;
+ padding: 5px 2em 2px 2em;
+ color: #000;
+ background-color: #eee;
+ }
+
+ div.content {
+ margin: 0px;
+ padding: 2em;
+ border-bottom: solid 3px #ccc;
+ }
+
+ /* List Tables (Repo index, log, etc) */
+ table.list {
+ width: 100%;
+ border: none;
+ border-collapse: collapse;
+
+ tr {
+ background: white;
+
+ &.logheader { background: #eee; }
+ &:nth-child(even) { background: #f7f7f7; }
+ &:nth-child(odd) { background: white; }
+ &:hover { background: #eee; }
+
+ &.nohover {
+ background: white;
+ &:hover { background: white; }
+ }
+
+ &.nohover-highlight:hover {
+ &:nth-child(even) { background: #f7f7f7; }
+ &:nth-child(odd) { background: white; }
+ }
+ }
+
+ th {
+ font-weight: bold;
+ padding: 0.1em 0.5em 0.05em 0.5em;
+ vertical-align: baseline;
+ }
+
+ td {
+ border: none;
+ padding: 0.1em 0.5em 0.1em 0.5em;
+
+ a {
+ color: black;
+ &:hover { color: #00f; }
+ &.ls-dir { font-weight: bold; color: #00f; }
+ }
+
+ &.commitgraph {
+ font-family: monospace;
+ white-space: pre;
+ .column1 { color: #a00; }
+ .column2 { color: #0a0; }
+ .column3 { color: #aa0; }
+ .column4 { color: #00a; }
+ .column5 { color: #a0a; }
+ .column6 { color: #0aa; }
+ }
+
+ &.logsubject { font-family: monospace; font-weight: bold; }
+ &.logmsg { font-family: monospace; white-space: pre; padding: 0 0.5em; }
+ &.reposection { font-style: italic; color: #888; }
+ &.sublevel-repo { padding-left: 1.5em; }
+ }
+ }
+
+ /* File Blob / Blame Views */
+ table.blob, table.ssdiff, table.blame {
+ td.linenumbers, td.lineno {
+ a {
+ color: gray;
+ text-align: right;
+ text-decoration: none;
+ &:hover { color: black; }
+ }
+ }
+ }
+
+ table.blob {
+ margin-top: 0.5em;
+ border-top: solid 1px black;
+
+ td.hashes, td.lines {
+ margin: 0; padding: 0 0 0 0.5em;
+ vertical-align: top;
+ color: black;
+ }
+
+ td.linenumbers {
+ margin: 0; padding: 0 0.5em 0 0.5em;
+ vertical-align: top;
+ text-align: right;
+ border-right: 1px solid gray;
+ }
+
+ pre { padding: 0; margin: 0; }
+ }
+
+ table.blame {
+ td.hashes, td.lines, td.linenumbers { padding: 0; }
+ td.hashes div.alt, td.lines div.alt { padding: 0 0.5em; }
+ td.linenumbers div.alt { padding: 0 0.5em 0 0; }
+
+ div.alt {
+ &:nth-child(even) { background: #eee; }
+ &:nth-child(odd) { background: white; }
+ }
+
+ td.lines > div {
+ position: relative;
+ & > pre {
+ padding: 0 0 0 0.5em;
+ position: absolute;
+ top: 0;
+ }
+ }
+ }
+
+ /* Diffstat and Panels */
+ table.diffstat {
+ border-collapse: collapse;
+ border: solid 1px #aaa;
+ background-color: #eee;
+
+ th {
+ font-weight: normal;
+ text-align: left;
+ text-decoration: underline;
+ padding: 0.1em 1em 0.1em 0.1em;
+ }
+
+ td {
+ padding: 0.2em 0.2em 0.1em 0.1em;
+ border: none;
+
+ &.mode { white-space: nowrap; }
+ span.modechange { padding-left: 1em; color: red; }
+ &.add a { color: green; }
+ &.del a { color: red; }
+ &.upd a { color: blue; }
+
+ &.graph {
+ width: 500px;
+ vertical-align: middle;
+ table { border: none; }
+ td {
+ padding: 0px;
+ border: 0px;
+ height: 7pt;
+ &.add { background-color: #5c5; }
+ &.rem { background-color: #c55; }
+ }
+ }
+ }
+ }
+
+ /* Side-by-side Diff (ssdiff) */
+ table.ssdiff {
+ width: 100%;
+ td {
+ font-size: 75%;
+ font-family: monospace;
+ white-space: pre;
+ padding: 1px 4px;
+ border-left: solid 1px #aaa;
+ border-right: solid 1px #aaa;
+
+ &.add { color: black; background: #cfc; min-width: 50%; }
+ &.add_dark { color: black; background: #aca; min-width: 50%; }
+ &.del { color: black; background: #fcc; min-width: 50%; }
+ &.del_dark { color: black; background: #caa; min-width: 50%; }
+ &.changed { color: black; background: #ffc; min-width: 50%; }
+ &.changed_dark { color: black; background: #cca; min-width: 50%; }
+ &.lineno { color: black; background: #eee; text-align: right; width: 3em; }
+ &.hunk { color: black; background: #ccf; border-top: solid 1px #aaa; border-bottom: solid 1px #aaa; }
+ &.head {
+ border-top: solid 1px #aaa; border-bottom: solid 1px #aaa;
+ div.head { font-weight: bold; color: black; }
+ }
+ &.foot { border-top: solid 1px #aaa; border-left: none; border-right: none; border-bottom: none; }
+ &.space { border: none; div { min-height: 3em; } }
+ }
+ span.add { background: #cfc; font-weight: bold; }
+ span.del { background: #fcc; font-weight: bold; }
+ }
+
+ /* Footer & Pager */
+ ul.pager {
+ list-style-type: none;
+ text-align: center;
+ margin: 1em 0 0 0;
+ padding: 0;
+ li { display: inline-block; margin: 0.25em 0.5em; }
+ a { color: #777; }
+ .current { font-weight: bold; }
+ }
+
+ div.footer {
+ margin-top: 0.5em;
+ text-align: center;
+ font-size: 80%;
+ color: #ccc;
+ a {
+ color: #ccc;
+ text-decoration: none;
+ &:hover { text-decoration: underline; }
+ }
+ }
+
+ /* Decorators (Branches/Tags) */
+ a.branch-deco, a.tag-deco, a.tag-annotated-deco, a.remote-deco, a.deco {
+ color: #000;
+ margin: 0px 0.5em;
+ padding: 0px 0.25em;
+ border: solid 1px;
+ }
+ a.branch-deco { background-color: #88ff88; border-color: #007700; }
+ a.tag-deco { background-color: #ffff88; border-color: #777700; }
+ a.tag-annotated-deco { background-color: #ffcc88; border-color: #777700; }
+ a.remote-deco { background-color: #ccccff; border-color: #000077; }
+ a.deco { background-color: #ff8888; border-color: #770000; }
+
+ div.commit-subject {
+ font-weight: bold;
+ font-size: 125%;
+ margin: 1.5em 0em 0.5em 0em;
+ padding: 0em;
+
+ a.branch-deco, a.tag-deco, a.tag-annotated-deco, a.remote-deco, a.deco {
+ margin-left: 1em;
+ font-size: 75%;
+ }
+ }
+
+ /* Misc specific IDs */
+ td#sidebar input.txt { width: 100%; margin: 2px 0 0 0; }
+ div#summary { vertical-align: top; margin-bottom: 1em; }
+ div.error { color: red; font-weight: bold; margin: 1em 2em; }
+
+ /* Age Spans */
+ span {
+ &.age-mins, &.age-hours { color: #080; }
+ &.age-mins { font-weight: bold; }
+ &.age-days { color: #040; }
+ &.age-weeks { color: #444; }
+ &.age-months { color: #888; }
+ &.age-years { color: #bbb; }
+ &.insertions { color: #080; }
+ &.deletions { color: #800; }
+ }
+}
diff --git a/modules/services/nixos/cgit/default.nix b/modules/services/nixos/cgit/default.nix
new file mode 100644
index 0000000..0f81958
--- /dev/null
+++ b/modules/services/nixos/cgit/default.nix
@@ -0,0 +1,139 @@
+{
+ pkgs,
+ config,
+ lib,
+ ...
+}: let
+ cfg = config.collinux.services.cgit;
+in {
+ config = lib.mkIf cfg.enable {
+ environment.shells = ["${pkgs.git}/bin/git-shell"];
+ users.groups."git" = {};
+ users.users."git" = {
+ isSystemUser = true;
+ group = "git";
+ shell = "${pkgs.git}/bin/git-shell";
+
+ home = "/var/lib/cgit";
+ createHome = true;
+ homeMode = "755";
+
+ openssh.authorizedKeys.keys = ["ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIC3SjzIs3YI8PWJaNrAuaEeRcTcvIVHOKyCh2VwHTHEF"];
+ };
+ hjem.users."git".files = {
+ "git-shell-commands/set-description" = {
+ executable = true;
+ text = ''
+ #!/usr/bin/env bash
+ set -euo pipefail
+ repo="$1"
+ desc="$2"
+ base="/var/lib/cgit"
+ repo_path="$base/$repo"
+
+ test -d "$repo_path" || { echo "Repository does not exist"; exit 1; }
+
+ # Prevent path traversal
+ real=$(realpath "$repo_path")
+ if [[ "$real" != "$base/"* ]]; then
+ echo "Invalid path"
+ exit 1
+ fi
+
+ echo "$desc" | head -n 1 > "$repo_path/description"
+
+ echo "Description updated for '$repo'"
+ '';
+ };
+ "git-shell-commands/create-repo" = {
+ executable = true;
+ text = ''
+ #!/usr/bin/env bash
+ set -euo pipefail
+ repo="$1"
+ base="/var/lib/cgit"
+ repo_path="$base/$repo"
+
+ test -d "$repo_path" && { echo "Repository already exists."; exit 1; }
+
+ git init --bare "$repo_path"
+ echo "Repository '$repo' created"
+ '';
+ };
+ };
+
+ services.openssh.extraConfig = lib.mkAfter ''
+ Match User git
+ AllowTcpForwarding no
+ X11Forwarding no
+ PermitTunnel no
+ PubkeyAuthentication yes
+ AuthenticationMethods publickey
+ '';
+
+ environment.etc."cgitrc".text = ''
+ logo=/favicon.svg
+ favicon=/favicon.svg
+
+ repo.sort=age
+ enable-http-clone=1
+ enable-commit-graph=1
+ side-by-side-diffs=1
+
+ root-title=git@ganymede
+ root-desc=Git repos associated with Ganymede
+
+ readme=:README.md
+ about-filter=${pkgs.cgit}/lib/cgit/filters/html-converters/md2html
+ source-filter=${pkgs.cgit}/lib/cgit/filters/syntax-highlighting.py
+ footer=
+
+ virtual-root=/
+ scan-path=/var/lib/cgit
+ '';
+
+ services.fcgiwrap.instances."cgit" = {
+ process = {
+ user = "git";
+ group = "git";
+ };
+
+ socket = {
+ user = "caddy";
+ group = "caddy";
+ type = "unix";
+ address = "/run/fcgiwrap-cgit.sock";
+ };
+ };
+
+ networking.extraHosts = "127.0.0.1 git.ganymede";
+ services.caddy.virtualHosts."git.ganymede".extraConfig = let
+ custom_cgit = pkgs.stdenv.mkDerivation {
+ name = "custom-cgit-assets";
+ src = pkgs.cgit;
+ installPhase = ''
+ mkdir -p $out
+ cp -pPR ./cgit/* $out/
+
+ rm -f $out/cgit.png $out/favicon.ico $out/cgit.css
+ cp -f ${./favicon.svg} $out/favicon.svg
+ cp -f ${./cgit.css} $out/cgit.css
+ '';
+ };
+ in ''
+ tls internal
+
+ @assets path /cgit.css /cgit.js /favicon.svg /robots.txt
+ handle @assets {
+ root * ${custom_cgit}
+ file_server
+ }
+
+ reverse_proxy unix//run/fcgiwrap-cgit.sock {
+ transport fastcgi {
+ env SCRIPT_FILENAME ${custom_cgit}/cgit.cgi
+ }
+ }
+ '';
+ };
+}
diff --git a/modules/services/nixos/cgit/favicon.svg b/modules/services/nixos/cgit/favicon.svg
new file mode 100644
index 0000000..52c5f79
--- /dev/null
+++ b/modules/services/nixos/cgit/favicon.svg
@@ -0,0 +1 @@
+
diff --git a/modules/services/nixos/default.nix b/modules/services/nixos/default.nix
index 738213f..2883629 100644
--- a/modules/services/nixos/default.nix
+++ b/modules/services/nixos/default.nix
@@ -2,7 +2,7 @@
imports = [
./mopidy.nix
./forgejo.nix
- ./cgit.nix
+ ./cgit
./openssh.nix
# ./jellyfin.nix
./caddy.nix
diff --git a/modules/services/nixos/goaccess.nix b/modules/services/nixos/goaccess.nix
index 896874a..47dbbfa 100644
--- a/modules/services/nixos/goaccess.nix
+++ b/modules/services/nixos/goaccess.nix
@@ -27,7 +27,7 @@
external-assets = "true";
all-static-files = "false";
- html-report-title = "Ganymede Stats";
+ html-report-title = "stats@ganymede";
hl-header = "true";
agent-list = "false";
with-output-resolver = "false";
--
cgit v1.3.1