updated docs
This commit is contained in:
parent
ce8c543e84
commit
73d2f44d74
14 changed files with 940 additions and 913 deletions
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
> Auto-generated documentation for the homelab deployment
|
> Auto-generated documentation for the homelab deployment
|
||||||
>
|
>
|
||||||
> Generated on: tir 29 jul 16:25:52 CEST 2025
|
> Generated on: $(date)
|
||||||
> Source: /home/plasmagoat/homelab
|
> Source: $(pwd)
|
||||||
|
|
||||||
## 📚 Documentation Files
|
## 📚 Documentation Files
|
||||||
|
|
||||||
|
|
@ -20,7 +20,7 @@ This documentation is automatically generated from your colmena flake configurat
|
||||||
## 🚀 Quick Actions
|
## 🚀 Quick Actions
|
||||||
|
|
||||||
### View Current Status
|
### View Current Status
|
||||||
```bash
|
\`\`\`bash
|
||||||
# Service status across fleet (if homelab CLI is available)
|
# Service status across fleet (if homelab CLI is available)
|
||||||
homelab services --global
|
homelab services --global
|
||||||
|
|
||||||
|
|
@ -29,22 +29,22 @@ homelab backups --global
|
||||||
|
|
||||||
# Overall status
|
# Overall status
|
||||||
homelab status
|
homelab status
|
||||||
```
|
\`\`\`
|
||||||
|
|
||||||
### Update Documentation
|
### Update Documentation
|
||||||
```bash
|
\`\`\`bash
|
||||||
# Regenerate all documentation
|
# Regenerate all documentation
|
||||||
homelab-generate-docs ./docs
|
homelab-generate-docs ./docs
|
||||||
|
|
||||||
# Generate in different directory
|
# Generate in different directory
|
||||||
homelab-generate-docs /path/to/output
|
homelab-generate-docs /path/to/output
|
||||||
```
|
\`\`\`
|
||||||
|
|
||||||
## 📋 Quick Stats
|
## 📋 Quick Stats
|
||||||
|
|
||||||
- **Total Nodes**: 2
|
- **Total Nodes**: 2
|
||||||
- **Homelab-Enabled Nodes**: 2
|
- **Homelab-Enabled Nodes**: 2
|
||||||
- **Generated**: tir 29 jul 16:25:55 CEST 2025
|
- **Generated**: tir 29 jul 16:57:16 CEST 2025
|
||||||
|
|
||||||
## 🛠️ Management Tools
|
## 🛠️ Management Tools
|
||||||
|
|
||||||
|
|
@ -60,6 +60,40 @@ homelab-generate-docs /path/to/output
|
||||||
- `colmena apply` - Deploy configuration changes
|
- `colmena apply` - Deploy configuration changes
|
||||||
- `colmena build` - Build configurations without deploying
|
- `colmena build` - Build configurations without deploying
|
||||||
|
|
||||||
|
## 🎯 Integration with CI/CD
|
||||||
|
|
||||||
|
### GitHub Actions Example
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
name: Generate Documentation
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ main ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docs:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- uses: cachix/install-nix-action@v24
|
||||||
|
- name: Generate docs
|
||||||
|
run: nix develop --command homelab-generate-docs ./docs
|
||||||
|
- name: Commit docs
|
||||||
|
run: |
|
||||||
|
git add docs/
|
||||||
|
git commit -m "docs: update homelab documentation" || exit 0
|
||||||
|
git push
|
||||||
|
```
|
||||||
|
|
||||||
|
### Manual Generation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# From your homelab directory
|
||||||
|
nix develop
|
||||||
|
homelab-generate-docs ./docs
|
||||||
|
git add docs/ && git commit -m "Update docs"
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*This documentation reflects the live state of your homelab deployment as evaluated by colmena.*
|
*This documentation reflects the live state of your homelab deployment as evaluated by colmena.*
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
> Current homelab deployment configuration
|
> Current homelab deployment configuration
|
||||||
>
|
>
|
||||||
> Generated on: tir 29 jul 16:25:46 CEST 2025
|
> Generated on: $(date)
|
||||||
> Working directory: /home/plasmagoat/homelab
|
> Working directory: $(pwd)
|
||||||
|
|
||||||
## Deployment Summary
|
## Deployment Summary
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
|
|
||||||
> Auto-generated fleet overview
|
> Auto-generated fleet overview
|
||||||
>
|
>
|
||||||
> Generated on: tir 29 jul 16:25:32 CEST 2025
|
> Generated on: $(date)
|
||||||
> Source: /home/plasmagoat/homelab
|
> Source: $(pwd)
|
||||||
|
|
||||||
## Fleet Statistics
|
## Fleet Statistics
|
||||||
|
|
||||||
|
|
@ -28,12 +28,6 @@
|
||||||
| `photos` | 1 | minio |
|
| `photos` | 1 | minio |
|
||||||
| `sandbox` | 0 | |
|
| `sandbox` | 0 | |
|
||||||
|
|
||||||
### Environment Distribution
|
|
||||||
|
|
||||||
| Environment | Node Count |
|
|
||||||
|-------------|------------|
|
|
||||||
| production | 2 |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Fleet overview generated from colmena evaluation*
|
*Fleet overview generated from colmena evaluation*
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
> Detailed per-node configuration
|
> Detailed per-node configuration
|
||||||
>
|
>
|
||||||
> Generated on: tir 29 jul 16:25:40 CEST 2025
|
> Generated on: $(date)
|
||||||
|
|
||||||
## Node: photos
|
## Node: photos
|
||||||
|
|
||||||
|
|
|
||||||
126
docs/services.md
126
docs/services.md
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
> Available services and their configuration options
|
> Available services and their configuration options
|
||||||
>
|
>
|
||||||
> Generated on: tir 29 jul 16:25:43 CEST 2025
|
> Generated on: $(date)
|
||||||
|
|
||||||
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
||||||
|
|
||||||
|
|
@ -10,6 +10,17 @@ This document catalogs all available homelab services, their configuration optio
|
||||||
|
|
||||||
**Total Available Services:** 4
|
**Total Available Services:** 4
|
||||||
|
|
||||||
|
## Service Integration Matrix
|
||||||
|
|
||||||
|
| Service | Monitoring | Logging | Proxy | Auth Default |
|
||||||
|
|---------|------------|---------|-------|--------------|
|
||||||
|
| `gatus` | ❌ | ❌ | ❌ | 🌐 |
|
||||||
|
| `grafana` | ❌ | ❌ | ❌ | 🌐 |
|
||||||
|
| `minio` | ❌ | ❌ | ❌ | 🌐 |
|
||||||
|
| `prometheus` | ❌ | ❌ | ❌ | 🌐 |
|
||||||
|
|
||||||
|
**Legend:** ✅ = Enabled by default, ❌ = Available but disabled, 🔒 = Auth required, 🌐 = Public access
|
||||||
|
|
||||||
## Service Reference
|
## Service Reference
|
||||||
|
|
||||||
### gatus
|
### gatus
|
||||||
|
|
@ -18,7 +29,15 @@ This document catalogs all available homelab services, their configuration optio
|
||||||
|
|
||||||
**Default Port:** `8080`
|
**Default Port:** `8080`
|
||||||
|
|
||||||
**Current Deployments:** 0 instance(s)
|
**Current Deployments:** 0 instance(s) on:
|
||||||
|
|
||||||
|
#### Default Integration Status
|
||||||
|
|
||||||
|
| Integration | Status | Default Configuration |
|
||||||
|
|-------------|--------|----------------------|
|
||||||
|
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
||||||
|
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
||||||
|
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
||||||
|
|
||||||
#### Core Configuration
|
#### Core Configuration
|
||||||
|
|
||||||
|
|
@ -27,6 +46,11 @@ homelab.services.gatus = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 8080;
|
port = 8080;
|
||||||
description = "Gatus Status Page";
|
description = "Gatus Status Page";
|
||||||
|
|
||||||
|
# Default integrations (adjust as needed)
|
||||||
|
# monitoring.enable = true; # ❌ Disabled by default
|
||||||
|
# logging.enable = true; # ❌ Disabled by default
|
||||||
|
# proxy.enable = true; # ❌ Disabled by default
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -47,17 +71,6 @@ homelab.services.gatus = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Complete Example
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# Full configuration example for gatus
|
|
||||||
homelab.services.gatus = {
|
|
||||||
enable = true;
|
|
||||||
port = 8080;
|
|
||||||
description = "Gatus Status Page";
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### grafana
|
### grafana
|
||||||
|
|
@ -66,7 +79,15 @@ homelab.services.gatus = {
|
||||||
|
|
||||||
**Default Port:** `3000`
|
**Default Port:** `3000`
|
||||||
|
|
||||||
**Current Deployments:** 0 instance(s)
|
**Current Deployments:** 0 instance(s) on:
|
||||||
|
|
||||||
|
#### Default Integration Status
|
||||||
|
|
||||||
|
| Integration | Status | Default Configuration |
|
||||||
|
|-------------|--------|----------------------|
|
||||||
|
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
||||||
|
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
||||||
|
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
||||||
|
|
||||||
#### Core Configuration
|
#### Core Configuration
|
||||||
|
|
||||||
|
|
@ -75,17 +96,11 @@ homelab.services.grafana = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 3000;
|
port = 3000;
|
||||||
description = "Grafana Metrics Dashboard";
|
description = "Grafana Metrics Dashboard";
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
#### Complete Example
|
# Default integrations (adjust as needed)
|
||||||
|
# monitoring.enable = true; # ❌ Disabled by default
|
||||||
```nix
|
# logging.enable = true; # ❌ Disabled by default
|
||||||
# Full configuration example for grafana
|
# proxy.enable = true; # ❌ Disabled by default
|
||||||
homelab.services.grafana = {
|
|
||||||
enable = true;
|
|
||||||
port = 3000;
|
|
||||||
description = "Grafana Metrics Dashboard";
|
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -97,7 +112,15 @@ homelab.services.grafana = {
|
||||||
|
|
||||||
**Default Port:** `9000`
|
**Default Port:** `9000`
|
||||||
|
|
||||||
**Current Deployments:** 1 instance(s)
|
**Current Deployments:** 1 instance(s) on: photos
|
||||||
|
|
||||||
|
#### Default Integration Status
|
||||||
|
|
||||||
|
| Integration | Status | Default Configuration |
|
||||||
|
|-------------|--------|----------------------|
|
||||||
|
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
||||||
|
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
||||||
|
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
||||||
|
|
||||||
#### Core Configuration
|
#### Core Configuration
|
||||||
|
|
||||||
|
|
@ -106,6 +129,11 @@ homelab.services.minio = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 9000;
|
port = 9000;
|
||||||
description = "minio";
|
description = "minio";
|
||||||
|
|
||||||
|
# Default integrations (adjust as needed)
|
||||||
|
# monitoring.enable = true; # ❌ Disabled by default
|
||||||
|
# logging.enable = true; # ❌ Disabled by default
|
||||||
|
# proxy.enable = true; # ❌ Disabled by default
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -123,17 +151,6 @@ homelab.services.minio = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Complete Example
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# Full configuration example for minio
|
|
||||||
homelab.services.minio = {
|
|
||||||
enable = true;
|
|
||||||
port = 9000;
|
|
||||||
description = "minio";
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
### prometheus
|
### prometheus
|
||||||
|
|
@ -142,7 +159,15 @@ homelab.services.minio = {
|
||||||
|
|
||||||
**Default Port:** `9090`
|
**Default Port:** `9090`
|
||||||
|
|
||||||
**Current Deployments:** 0 instance(s)
|
**Current Deployments:** 0 instance(s) on:
|
||||||
|
|
||||||
|
#### Default Integration Status
|
||||||
|
|
||||||
|
| Integration | Status | Default Configuration |
|
||||||
|
|-------------|--------|----------------------|
|
||||||
|
| 📊 Monitoring | ❌ Disabled | Available but requires `monitoring.enable = true` |
|
||||||
|
| 📝 Logging | ❌ Disabled | Available but requires `logging.enable = true` |
|
||||||
|
| 🔀 Proxy | ❌ Disabled | Available but requires `proxy.enable = true` |
|
||||||
|
|
||||||
#### Core Configuration
|
#### Core Configuration
|
||||||
|
|
||||||
|
|
@ -151,6 +176,11 @@ homelab.services.prometheus = {
|
||||||
enable = true;
|
enable = true;
|
||||||
port = 9090;
|
port = 9090;
|
||||||
description = "Prometheus Monitoring Server";
|
description = "Prometheus Monitoring Server";
|
||||||
|
|
||||||
|
# Default integrations (adjust as needed)
|
||||||
|
# monitoring.enable = true; # ❌ Disabled by default
|
||||||
|
# logging.enable = true; # ❌ Disabled by default
|
||||||
|
# proxy.enable = true; # ❌ Disabled by default
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -174,28 +204,17 @@ homelab.services.prometheus = {
|
||||||
};
|
};
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Complete Example
|
|
||||||
|
|
||||||
```nix
|
|
||||||
# Full configuration example for prometheus
|
|
||||||
homelab.services.prometheus = {
|
|
||||||
enable = true;
|
|
||||||
port = 9090;
|
|
||||||
description = "Prometheus Monitoring Server";
|
|
||||||
};
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## Integration Summary
|
## Integration Summary
|
||||||
|
|
||||||
### Available Integration Types
|
### Available Integration Types
|
||||||
|
|
||||||
| Integration | Purpose | Configuration |
|
| Integration | Purpose | Default Behavior | Configuration |
|
||||||
|-------------|---------|---------------|
|
|-------------|---------|------------------|---------------|
|
||||||
| **Monitoring** | Prometheus metrics + health checks | `monitoring.enable = true` |
|
| **📊 Monitoring** | Prometheus metrics + health checks | Service-dependent | `monitoring.enable = true` |
|
||||||
| **Logging** | Centralized log collection | `logging.enable = true` |
|
| **📝 Logging** | Centralized log collection | Service-dependent | `logging.enable = true` |
|
||||||
| **Proxy** | Reverse proxy with SSL + auth | `proxy.enable = true` |
|
| **🔀 Proxy** | Reverse proxy with SSL + auth | Service-dependent | `proxy.enable = true` |
|
||||||
|
|
||||||
### Integration Benefits
|
### Integration Benefits
|
||||||
|
|
||||||
|
|
@ -203,6 +222,7 @@ homelab.services.prometheus = {
|
||||||
- **📊 Unified Monitoring:** All metrics and health checks appear in Prometheus/Grafana
|
- **📊 Unified Monitoring:** All metrics and health checks appear in Prometheus/Grafana
|
||||||
- **📝 Centralized Logging:** All logs are collected and indexed in Loki
|
- **📝 Centralized Logging:** All logs are collected and indexed in Loki
|
||||||
- **🌐 Consistent Access:** All services get consistent subdomain access with SSL
|
- **🌐 Consistent Access:** All services get consistent subdomain access with SSL
|
||||||
|
- **🎯 Smart Defaults:** Each service comes with sensible default configurations
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,5 @@
|
||||||
pkgs: {
|
pkgs: {
|
||||||
# example = pkgs.callPackage ./example { };
|
# example = pkgs.callPackage ./example { };
|
||||||
ente-web = pkgs.callPackage ./ente-web.nix {};
|
ente-web = pkgs.callPackage ./ente-web.nix {};
|
||||||
homelab-docs = pkgs.callPackage ./homelab-docs.nix {};
|
homelab-docs = pkgs.callPackage ./homelab-docs {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,841 +0,0 @@
|
||||||
# homelab-docs.nix - Standalone documentation generator package
|
|
||||||
{
|
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
writeShellScriptBin,
|
|
||||||
jq,
|
|
||||||
nixfmt,
|
|
||||||
}: let
|
|
||||||
# Main documentation generator script
|
|
||||||
docsGenerator = writeShellScriptBin "homelab-generate-docs" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
# Colors
|
|
||||||
BLUE='\033[0;34m'
|
|
||||||
GREEN='\033[0;32m'
|
|
||||||
YELLOW='\033[1;33m'
|
|
||||||
RED='\033[0;31m'
|
|
||||||
NC='\033[0m'
|
|
||||||
|
|
||||||
info() { echo -e "''${BLUE}$1''${NC}"; }
|
|
||||||
success() { echo -e "''${GREEN}$1''${NC}"; }
|
|
||||||
warn() { echo -e "''${YELLOW}$1''${NC}"; }
|
|
||||||
error() { echo -e "''${RED}$1''${NC}"; }
|
|
||||||
|
|
||||||
# Configuration
|
|
||||||
DOCS_DIR="''${1:-./docs}"
|
|
||||||
|
|
||||||
info "📚 Generating homelab documentation..."
|
|
||||||
echo " Output directory: $DOCS_DIR"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Check if we're in a directory with a flake
|
|
||||||
if [[ ! -f flake.nix ]]; then
|
|
||||||
error "No flake.nix found in current directory"
|
|
||||||
echo "Please run this command from your homelab flake directory"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if colmena is available
|
|
||||||
if ! command -v colmena >/dev/null 2>&1; then
|
|
||||||
error "colmena command not found."
|
|
||||||
echo "Please ensure colmena is available in your environment"
|
|
||||||
echo "Add it to your devShell or install it globally"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Create docs directory
|
|
||||||
mkdir -p "$DOCS_DIR"
|
|
||||||
|
|
||||||
# Generate fleet overview
|
|
||||||
info " 🌐 Generating fleet overview..."
|
|
||||||
homelab-docs-fleet > "$DOCS_DIR/fleet-overview.md"
|
|
||||||
|
|
||||||
# Generate node documentation
|
|
||||||
info " 🖥️ Generating node configurations..."
|
|
||||||
homelab-docs-nodes > "$DOCS_DIR/nodes.md"
|
|
||||||
|
|
||||||
# Generate service documentation
|
|
||||||
info " ⚙️ Generating service configurations..."
|
|
||||||
homelab-docs-services > "$DOCS_DIR/services.md"
|
|
||||||
|
|
||||||
# Generate current deployment
|
|
||||||
info " 🏠 Generating current deployment..."
|
|
||||||
homelab-docs-deployment > "$DOCS_DIR/current-deployment.md"
|
|
||||||
|
|
||||||
# Generate README
|
|
||||||
info " 📋 Generating README..."
|
|
||||||
homelab-docs-readme > "$DOCS_DIR/README.md"
|
|
||||||
|
|
||||||
success "✅ Documentation generated successfully!"
|
|
||||||
echo
|
|
||||||
echo "Generated files:"
|
|
||||||
echo " 🌐 fleet-overview.md - Fleet statistics and overview"
|
|
||||||
echo " 🖥️ nodes.md - Per-node configurations"
|
|
||||||
echo " ⚙️ services.md - Service configurations"
|
|
||||||
echo " 🏠 current-deployment.md - Current deployment state"
|
|
||||||
echo " 📋 README.md - Documentation index"
|
|
||||||
echo
|
|
||||||
echo "💡 Tip: Add these files to your repository and set up GitHub Actions"
|
|
||||||
echo " to automatically regenerate documentation on changes!"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Fleet overview generator
|
|
||||||
fleetDocsGenerator = writeShellScriptBin "homelab-docs-fleet" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
cat << EOF
|
|
||||||
# Homelab Fleet Overview
|
|
||||||
|
|
||||||
> Auto-generated fleet overview
|
|
||||||
>
|
|
||||||
> Generated on: $(date)
|
|
||||||
> Source: $(pwd)
|
|
||||||
|
|
||||||
## Fleet Statistics
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Get basic fleet stats
|
|
||||||
echo "### Basic Information"
|
|
||||||
echo
|
|
||||||
|
|
||||||
fleet_stats=$(colmena eval -E '{ nodes, pkgs, lib, ... }: {
|
|
||||||
totalNodes = lib.length (lib.attrNames nodes);
|
|
||||||
nodeNames = lib.attrNames nodes;
|
|
||||||
}')
|
|
||||||
|
|
||||||
total_nodes=$(echo "$fleet_stats" | ${jq}/bin/jq -r '.totalNodes')
|
|
||||||
node_names=$(echo "$fleet_stats" | ${jq}/bin/jq -r '.nodeNames[]' | tr '\n' ' ')
|
|
||||||
|
|
||||||
echo "| Metric | Value |"
|
|
||||||
echo "|--------|-------|"
|
|
||||||
echo "| Total Nodes | $total_nodes |"
|
|
||||||
echo "| Node Names | $node_names |"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Get homelab-enabled nodes
|
|
||||||
echo "### Homelab Configuration"
|
|
||||||
echo
|
|
||||||
|
|
||||||
homelab_info=$(colmena eval -E '{ nodes, pkgs, lib, ... }: {
|
|
||||||
homelabNodes = lib.mapAttrs (name: node: {
|
|
||||||
enabled = node.config.homelab.enable or false;
|
|
||||||
hostname = node.config.homelab.hostname or null;
|
|
||||||
environment = node.config.homelab.environment or null;
|
|
||||||
}) nodes;
|
|
||||||
}')
|
|
||||||
|
|
||||||
echo "| Node | Homelab Enabled | Hostname | Environment |"
|
|
||||||
echo "|------|----------------|----------|-------------|"
|
|
||||||
|
|
||||||
echo "$homelab_info" | ${jq}/bin/jq -r '.homelabNodes | to_entries[] |
|
|
||||||
[.key, (.value.enabled | tostring), (.value.hostname // "N/A"), (.value.environment // "N/A")] |
|
|
||||||
@tsv' | while IFS=$'\t' read -r node enabled hostname environment; do
|
|
||||||
enabled_icon=$(if [[ "$enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
|
||||||
echo "| \`$node\` | $enabled_icon | $hostname | $environment |"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Get service distribution
|
|
||||||
echo "### Service Distribution"
|
|
||||||
echo
|
|
||||||
|
|
||||||
service_info=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
||||||
lib.mapAttrs (name: node:
|
|
||||||
if (node.config.homelab.enable or false) then {
|
|
||||||
serviceCount = lib.length (lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {})));
|
|
||||||
serviceNames = lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {}));
|
|
||||||
} else {
|
|
||||||
serviceCount = 0;
|
|
||||||
serviceNames = [];
|
|
||||||
}
|
|
||||||
) nodes')
|
|
||||||
|
|
||||||
echo "| Node | Service Count | Services |"
|
|
||||||
echo "|------|---------------|----------|"
|
|
||||||
|
|
||||||
echo "$service_info" | ${jq}/bin/jq -r 'to_entries[] |
|
|
||||||
[.key, (.value.serviceCount | tostring), (.value.serviceNames | join(", "))] |
|
|
||||||
@tsv' | while IFS=$'\t' read -r node count services; do
|
|
||||||
echo "| \`$node\` | $count | $services |"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Environment distribution
|
|
||||||
echo "### Environment Distribution"
|
|
||||||
echo
|
|
||||||
|
|
||||||
env_distribution=$(echo "$homelab_info" | ${jq}/bin/jq -r '
|
|
||||||
[.homelabNodes | to_entries[] | select(.value.enabled == true) | .value.environment // "unknown"] |
|
|
||||||
group_by(.) |
|
|
||||||
map({environment: .[0], count: length}) |
|
|
||||||
.[]')
|
|
||||||
|
|
||||||
if [[ -n "$env_distribution" ]]; then
|
|
||||||
echo "| Environment | Node Count |"
|
|
||||||
echo "|-------------|------------|"
|
|
||||||
|
|
||||||
echo "$env_distribution" | ${jq}/bin/jq -r '[.environment, (.count | tostring)] | @tsv' | \
|
|
||||||
while IFS=$'\t' read -r env count; do
|
|
||||||
echo "| $env | $count |"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "No homelab-enabled nodes found."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "---"
|
|
||||||
echo
|
|
||||||
echo "*Fleet overview generated from colmena evaluation*"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Node documentation generator
|
|
||||||
nodeDocsGenerator = writeShellScriptBin "homelab-docs-nodes" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
cat << EOF
|
|
||||||
# Node Configurations
|
|
||||||
|
|
||||||
> Detailed per-node configuration
|
|
||||||
>
|
|
||||||
> Generated on: $(date)
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Get all node information
|
|
||||||
node_info=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
||||||
lib.mapAttrs (name: node: {
|
|
||||||
# Basic system info
|
|
||||||
nixosVersion = node.config.system.nixos.version;
|
|
||||||
hostName = node.config.networking.hostName;
|
|
||||||
system = node.config.nixpkgs.system;
|
|
||||||
|
|
||||||
# Homelab config (safe extraction)
|
|
||||||
homelab = if (node.config.homelab.enable or false) then {
|
|
||||||
enabled = true;
|
|
||||||
hostname = node.config.homelab.hostname or null;
|
|
||||||
domain = node.config.homelab.domain or null;
|
|
||||||
externalDomain = node.config.homelab.externalDomain or null;
|
|
||||||
environment = node.config.homelab.environment or null;
|
|
||||||
location = node.config.homelab.location or null;
|
|
||||||
tags = node.config.homelab.tags or [];
|
|
||||||
} else {
|
|
||||||
enabled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Services (safe extraction)
|
|
||||||
services = if (node.config.homelab.enable or false) then
|
|
||||||
lib.mapAttrs (svcName: svc: {
|
|
||||||
enabled = svc.enable or false;
|
|
||||||
port = svc.port or null;
|
|
||||||
description = svc.description or svcName;
|
|
||||||
tags = svc.tags or [];
|
|
||||||
}) (node.config.homelab.services or {})
|
|
||||||
else {};
|
|
||||||
}) nodes')
|
|
||||||
|
|
||||||
echo "$node_info" | ${jq}/bin/jq -r 'to_entries[] | .key' | while read -r node; do
|
|
||||||
echo "## Node: $node"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Basic system information
|
|
||||||
echo "### System Information"
|
|
||||||
echo
|
|
||||||
|
|
||||||
nixos_version=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].nixosVersion")
|
|
||||||
hostname=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].hostName")
|
|
||||||
system=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].system")
|
|
||||||
|
|
||||||
echo "| Property | Value |"
|
|
||||||
echo "|----------|-------|"
|
|
||||||
echo "| NixOS Version | \`$nixos_version\` |"
|
|
||||||
echo "| Hostname | \`$hostname\` |"
|
|
||||||
echo "| System | \`$system\` |"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Homelab configuration
|
|
||||||
homelab_enabled=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.enabled")
|
|
||||||
|
|
||||||
if [[ "$homelab_enabled" == "true" ]]; then
|
|
||||||
echo "### Homelab Configuration"
|
|
||||||
echo
|
|
||||||
|
|
||||||
hl_hostname=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.hostname // \"N/A\"")
|
|
||||||
hl_domain=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.domain // \"N/A\"")
|
|
||||||
hl_external=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.externalDomain // \"N/A\"")
|
|
||||||
hl_env=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.environment // \"N/A\"")
|
|
||||||
hl_location=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.location // \"N/A\"")
|
|
||||||
hl_tags=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.tags | join(\", \")")
|
|
||||||
|
|
||||||
echo "| Property | Value |"
|
|
||||||
echo "|----------|-------|"
|
|
||||||
echo "| Homelab Hostname | \`$hl_hostname\` |"
|
|
||||||
echo "| Domain | \`$hl_domain\` |"
|
|
||||||
echo "| External Domain | \`$hl_external\` |"
|
|
||||||
echo "| Environment | \`$hl_env\` |"
|
|
||||||
echo "| Location | \`$hl_location\` |"
|
|
||||||
echo "| Tags | $hl_tags |"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Services
|
|
||||||
echo "### Services"
|
|
||||||
echo
|
|
||||||
|
|
||||||
services_data=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].services")
|
|
||||||
service_count=$(echo "$services_data" | ${jq}/bin/jq 'length')
|
|
||||||
|
|
||||||
if [[ "$service_count" -gt 0 ]]; then
|
|
||||||
echo "| Service | Enabled | Port | Description | Tags |"
|
|
||||||
echo "|---------|---------|------|-------------|------|"
|
|
||||||
|
|
||||||
echo "$services_data" | ${jq}/bin/jq -r 'to_entries[] |
|
|
||||||
[.key, (.value.enabled | tostring), (.value.port // "N/A" | tostring), (.value.description // "N/A"), (.value.tags | join(", "))] |
|
|
||||||
@tsv' | while IFS=$'\t' read -r service enabled port description tags; do
|
|
||||||
enabled_icon=$(if [[ "$enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
|
||||||
echo "| \`$service\` | $enabled_icon | $port | $description | $tags |"
|
|
||||||
done
|
|
||||||
else
|
|
||||||
echo "No services configured."
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "### Homelab Configuration"
|
|
||||||
echo
|
|
||||||
echo "❌ Homelab is not enabled on this node."
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "---"
|
|
||||||
echo
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Service documentation generator - refocused on service capabilities
|
|
||||||
serviceDocsGenerator = writeShellScriptBin "homelab-docs-services" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
cat << EOF
|
|
||||||
# Service Catalog
|
|
||||||
|
|
||||||
> Available services and their configuration options
|
|
||||||
>
|
|
||||||
> Generated on: $(date)
|
|
||||||
|
|
||||||
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Get all services and their configurations
|
|
||||||
services_catalog=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
# Collect all services from all nodes to build a complete catalog
|
|
||||||
allServiceConfigs = lib.flatten (lib.mapAttrsToList (nodeName: node:
|
|
||||||
if (node.config.homelab.enable or false) then
|
|
||||||
lib.mapAttrsToList (serviceName: service: {
|
|
||||||
inherit serviceName;
|
|
||||||
config = {
|
|
||||||
# Core service options
|
|
||||||
enable = service.enable or false;
|
|
||||||
port = service.port or null;
|
|
||||||
description = service.description or serviceName;
|
|
||||||
tags = service.tags or [];
|
|
||||||
|
|
||||||
# Integration options
|
|
||||||
monitoring = {
|
|
||||||
enabled = service.monitoring.enable or false;
|
|
||||||
metricsPath = service.monitoring.metrics.path or "/metrics";
|
|
||||||
healthPath = service.monitoring.healthCheck.path or "/health";
|
|
||||||
extraLabels = service.monitoring.extraLabels or {};
|
|
||||||
};
|
|
||||||
|
|
||||||
logging = {
|
|
||||||
enabled = service.logging.enable or false;
|
|
||||||
files = service.logging.files or [];
|
|
||||||
extraLabels = service.logging.extraLabels or {};
|
|
||||||
};
|
|
||||||
|
|
||||||
proxy = {
|
|
||||||
enabled = service.proxy.enable or false;
|
|
||||||
subdomain = service.proxy.subdomain or serviceName;
|
|
||||||
enableAuth = service.proxy.enableAuth or false;
|
|
||||||
additionalSubdomains = service.proxy.additionalSubdomains or [];
|
|
||||||
};
|
|
||||||
|
|
||||||
# Service-specific options (everything else)
|
|
||||||
serviceSpecific = removeAttrs service [
|
|
||||||
"enable" "port" "description" "tags"
|
|
||||||
"monitoring" "logging" "proxy"
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}) (node.config.homelab.services or {})
|
|
||||||
else []
|
|
||||||
) nodes);
|
|
||||||
|
|
||||||
# Group by service name and merge configurations
|
|
||||||
serviceGroups = lib.groupBy (svc: svc.serviceName) allServiceConfigs;
|
|
||||||
|
|
||||||
# Get unique services with merged configuration examples
|
|
||||||
uniqueServices = lib.mapAttrs (serviceName: instances:
|
|
||||||
let
|
|
||||||
# Take the first enabled instance as the canonical example
|
|
||||||
enabledInstances = lib.filter (inst: inst.config.enable) instances;
|
|
||||||
canonicalConfig = if enabledInstances != [] then (lib.head enabledInstances).config else (lib.head instances).config;
|
|
||||||
in {
|
|
||||||
inherit serviceName;
|
|
||||||
config = canonicalConfig;
|
|
||||||
deploymentCount = lib.length (lib.filter (inst: inst.config.enable) instances);
|
|
||||||
availableOn = lib.unique (map (inst: inst.nodeName or "unknown") enabledInstances);
|
|
||||||
}
|
|
||||||
) serviceGroups;
|
|
||||||
|
|
||||||
in {
|
|
||||||
services = uniqueServices;
|
|
||||||
totalUniqueServices = lib.length (lib.attrNames uniqueServices);
|
|
||||||
}')
|
|
||||||
|
|
||||||
total_services=$(echo "$services_catalog" | ${jq}/bin/jq -r '.totalUniqueServices')
|
|
||||||
|
|
||||||
echo "## Overview"
|
|
||||||
echo
|
|
||||||
echo "**Total Available Services:** $total_services"
|
|
||||||
echo
|
|
||||||
echo "## Service Reference"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Process each service
|
|
||||||
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
|
||||||
echo "### $service"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Get service details
|
|
||||||
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
|
||||||
|
|
||||||
description=$(echo "$service_data" | ${jq}/bin/jq -r '.config.description // "No description available"')
|
|
||||||
port=$(echo "$service_data" | ${jq}/bin/jq -r '.config.port // "N/A"')
|
|
||||||
tags=$(echo "$service_data" | ${jq}/bin/jq -r '.config.tags | join(", ")')
|
|
||||||
deployment_count=$(echo "$service_data" | ${jq}/bin/jq -r '.deploymentCount')
|
|
||||||
|
|
||||||
echo "**Description:** $description"
|
|
||||||
echo
|
|
||||||
echo "**Default Port:** \`$port\`"
|
|
||||||
echo
|
|
||||||
if [[ -n "$tags" && "$tags" != "" ]]; then
|
|
||||||
echo "**Tags:** $tags"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
echo "**Current Deployments:** $deployment_count instance(s)"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Core Configuration
|
|
||||||
echo "#### Core Configuration"
|
|
||||||
echo
|
|
||||||
echo "\`\`\`nix"
|
|
||||||
echo "homelab.services.$service = {"
|
|
||||||
echo " enable = true;"
|
|
||||||
if [[ "$port" != "N/A" ]]; then
|
|
||||||
echo " port = $port;"
|
|
||||||
fi
|
|
||||||
echo " description = \"$description\";"
|
|
||||||
if [[ -n "$tags" && "$tags" != "" ]]; then
|
|
||||||
echo " tags = [ $(echo "$tags" | sed 's/, /" "/g' | sed 's/^/"/; s/$/"/') ];"
|
|
||||||
fi
|
|
||||||
echo "};"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Service-specific options
|
|
||||||
service_specific=$(echo "$service_data" | ${jq}/bin/jq -r '.config.serviceSpecific')
|
|
||||||
if [[ "$service_specific" != "{}" && "$service_specific" != "null" ]]; then
|
|
||||||
echo "#### Service-Specific Options"
|
|
||||||
echo
|
|
||||||
echo "Available configuration options for $service:"
|
|
||||||
echo
|
|
||||||
echo "\`\`\`nix"
|
|
||||||
echo "homelab.services.$service = {"
|
|
||||||
echo " # ... core options above ..."
|
|
||||||
echo
|
|
||||||
echo " # Service-specific configuration"
|
|
||||||
echo "$service_specific" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value | tostring);"'
|
|
||||||
echo "};"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Integration Options
|
|
||||||
monitoring_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.enabled')
|
|
||||||
logging_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.enabled')
|
|
||||||
proxy_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enabled')
|
|
||||||
|
|
||||||
if [[ "$monitoring_enabled" == "true" || "$logging_enabled" == "true" || "$proxy_enabled" == "true" ]]; then
|
|
||||||
echo "#### Available Integrations"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Monitoring Integration
|
|
||||||
if [[ "$monitoring_enabled" == "true" ]]; then
|
|
||||||
metrics_path=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.metricsPath')
|
|
||||||
health_path=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.healthPath')
|
|
||||||
extra_labels=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.extraLabels')
|
|
||||||
|
|
||||||
echo "##### 📊 Monitoring"
|
|
||||||
echo
|
|
||||||
echo "- **Metrics Endpoint:** \`$metrics_path\`"
|
|
||||||
echo "- **Health Check:** \`$health_path\`"
|
|
||||||
if [[ "$extra_labels" != "{}" ]]; then
|
|
||||||
echo "- **Default Labels:** $(echo "$extra_labels" | ${jq}/bin/jq -r 'to_entries[] | "\(.key)=\(.value)"' | paste -sd, -)"
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "\`\`\`nix"
|
|
||||||
echo "homelab.services.$service.monitoring = {"
|
|
||||||
echo " enable = true;"
|
|
||||||
echo " metrics.path = \"$metrics_path\";"
|
|
||||||
echo " healthCheck.path = \"$health_path\";"
|
|
||||||
if [[ "$extra_labels" != "{}" ]]; then
|
|
||||||
echo " extraLabels = $extra_labels;"
|
|
||||||
fi
|
|
||||||
echo "};"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Logging Integration
|
|
||||||
if [[ "$logging_enabled" == "true" ]]; then
|
|
||||||
log_files=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.files[]?')
|
|
||||||
log_labels=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.extraLabels')
|
|
||||||
|
|
||||||
echo "##### 📝 Logging"
|
|
||||||
echo
|
|
||||||
if [[ -n "$log_files" ]]; then
|
|
||||||
echo "- **Log Files:**"
|
|
||||||
echo "$log_files" | while read -r file; do
|
|
||||||
echo " - \`$file\`"
|
|
||||||
done
|
|
||||||
fi
|
|
||||||
if [[ "$log_labels" != "{}" ]]; then
|
|
||||||
echo "- **Default Labels:** $(echo "$log_labels" | ${jq}/bin/jq -r 'to_entries[] | "\(.key)=\(.value)"' | paste -sd, -)"
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "\`\`\`nix"
|
|
||||||
echo "homelab.services.$service.logging = {"
|
|
||||||
echo " enable = true;"
|
|
||||||
if [[ -n "$log_files" ]]; then
|
|
||||||
echo " files = ["
|
|
||||||
echo "$log_files" | while read -r file; do
|
|
||||||
echo " \"$file\""
|
|
||||||
done
|
|
||||||
echo " ];"
|
|
||||||
fi
|
|
||||||
if [[ "$log_labels" != "{}" ]]; then
|
|
||||||
echo " extraLabels = $log_labels;"
|
|
||||||
fi
|
|
||||||
echo "};"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Proxy Integration
|
|
||||||
if [[ "$proxy_enabled" == "true" ]]; then
|
|
||||||
subdomain=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.subdomain')
|
|
||||||
enable_auth=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enableAuth')
|
|
||||||
additional_subdomains=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.additionalSubdomains')
|
|
||||||
|
|
||||||
echo "##### 🔀 Reverse Proxy"
|
|
||||||
echo
|
|
||||||
echo "- **Primary Subdomain:** \`$subdomain\`"
|
|
||||||
echo "- **Authentication Required:** $(if [[ "$enable_auth" == "true" ]]; then echo "✅ Yes"; else echo "❌ No"; fi)"
|
|
||||||
if [[ "$additional_subdomains" != "[]" && "$additional_subdomains" != "null" ]]; then
|
|
||||||
echo "- **Additional Subdomains:** Available"
|
|
||||||
fi
|
|
||||||
echo
|
|
||||||
echo "\`\`\`nix"
|
|
||||||
echo "homelab.services.$service.proxy = {"
|
|
||||||
echo " enable = true;"
|
|
||||||
echo " subdomain = \"$subdomain\";"
|
|
||||||
echo " enableAuth = $enable_auth;"
|
|
||||||
if [[ "$additional_subdomains" != "[]" && "$additional_subdomains" != "null" ]]; then
|
|
||||||
echo " additionalSubdomains = ["
|
|
||||||
echo " # Configure additional proxy entries as needed"
|
|
||||||
echo " ];"
|
|
||||||
fi
|
|
||||||
echo "};"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Usage Examples
|
|
||||||
echo "#### Complete Example"
|
|
||||||
echo
|
|
||||||
echo "\`\`\`nix"
|
|
||||||
echo "# Full configuration example for $service"
|
|
||||||
echo "homelab.services.$service = {"
|
|
||||||
echo " enable = true;"
|
|
||||||
if [[ "$port" != "N/A" ]]; then
|
|
||||||
echo " port = $port;"
|
|
||||||
fi
|
|
||||||
echo " description = \"$description\";"
|
|
||||||
|
|
||||||
# Add integration examples
|
|
||||||
if [[ "$monitoring_enabled" == "true" ]]; then
|
|
||||||
echo " "
|
|
||||||
echo " # Monitoring integration"
|
|
||||||
echo " monitoring.enable = true;"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$logging_enabled" == "true" ]]; then
|
|
||||||
echo " "
|
|
||||||
echo " # Logging integration"
|
|
||||||
echo " logging.enable = true;"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "$proxy_enabled" == "true" ]]; then
|
|
||||||
echo " "
|
|
||||||
echo " # Reverse proxy integration"
|
|
||||||
echo " proxy = {"
|
|
||||||
echo " enable = true;"
|
|
||||||
echo " subdomain = \"$subdomain\";"
|
|
||||||
echo " enableAuth = $enable_auth;"
|
|
||||||
echo " };"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "};"
|
|
||||||
echo "\`\`\`"
|
|
||||||
echo
|
|
||||||
echo "---"
|
|
||||||
echo
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "## Integration Summary"
|
|
||||||
echo
|
|
||||||
echo "### Available Integration Types"
|
|
||||||
echo
|
|
||||||
echo "| Integration | Purpose | Configuration |"
|
|
||||||
echo "|-------------|---------|---------------|"
|
|
||||||
echo "| **Monitoring** | Prometheus metrics + health checks | \`monitoring.enable = true\` |"
|
|
||||||
echo "| **Logging** | Centralized log collection | \`logging.enable = true\` |"
|
|
||||||
echo "| **Proxy** | Reverse proxy with SSL + auth | \`proxy.enable = true\` |"
|
|
||||||
echo
|
|
||||||
echo "### Integration Benefits"
|
|
||||||
echo
|
|
||||||
echo "- **🔄 Automatic Discovery:** Enabled integrations are automatically discovered by fleet-wide services"
|
|
||||||
echo "- **📊 Unified Monitoring:** All metrics and health checks appear in Prometheus/Grafana"
|
|
||||||
echo "- **📝 Centralized Logging:** All logs are collected and indexed in Loki"
|
|
||||||
echo "- **🌐 Consistent Access:** All services get consistent subdomain access with SSL"
|
|
||||||
echo
|
|
||||||
echo "---"
|
|
||||||
echo
|
|
||||||
echo "*This service catalog is generated from actual service configurations across your homelab fleet.*"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# Current deployment generator
|
|
||||||
deploymentDocsGenerator = writeShellScriptBin "homelab-docs-deployment" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
cat << EOF
|
|
||||||
# Current Deployment State
|
|
||||||
|
|
||||||
> Current homelab deployment configuration
|
|
||||||
>
|
|
||||||
> Generated on: $(date)
|
|
||||||
> Working directory: $(pwd)
|
|
||||||
|
|
||||||
## Deployment Summary
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Get deployment summary
|
|
||||||
deployment_summary=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
homelabNodes = lib.filterAttrs (name: node: node.config.homelab.enable or false) nodes;
|
|
||||||
allServices = lib.flatten (lib.mapAttrsToList (nodeName: node:
|
|
||||||
lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {}))
|
|
||||||
) homelabNodes);
|
|
||||||
in {
|
|
||||||
totalNodes = lib.length (lib.attrNames nodes);
|
|
||||||
homelabEnabledNodes = lib.length (lib.attrNames homelabNodes);
|
|
||||||
uniqueServices = lib.length (lib.unique allServices);
|
|
||||||
totalServiceInstances = lib.length allServices;
|
|
||||||
nodeNames = lib.attrNames nodes;
|
|
||||||
homelabNodeNames = lib.attrNames homelabNodes;
|
|
||||||
}')
|
|
||||||
|
|
||||||
total_nodes=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.totalNodes')
|
|
||||||
homelab_nodes=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.homelabEnabledNodes')
|
|
||||||
unique_services=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.uniqueServices')
|
|
||||||
service_instances=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.totalServiceInstances')
|
|
||||||
|
|
||||||
echo "| Metric | Count |"
|
|
||||||
echo "|--------|-------|"
|
|
||||||
echo "| Total Nodes | $total_nodes |"
|
|
||||||
echo "| Homelab-Enabled Nodes | $homelab_nodes |"
|
|
||||||
echo "| Unique Services | $unique_services |"
|
|
||||||
echo "| Service Instances | $service_instances |"
|
|
||||||
echo
|
|
||||||
|
|
||||||
echo "## Node Status"
|
|
||||||
echo
|
|
||||||
|
|
||||||
# Get detailed node status
|
|
||||||
node_status=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
||||||
lib.mapAttrs (name: node: {
|
|
||||||
homelabEnabled = node.config.homelab.enable or false;
|
|
||||||
environment = node.config.homelab.environment or "unknown";
|
|
||||||
serviceCount = if (node.config.homelab.enable or false) then
|
|
||||||
lib.length (lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {})))
|
|
||||||
else 0;
|
|
||||||
monitoringEnabled = if (node.config.homelab.enable or false) then
|
|
||||||
node.config.homelab.monitoring.enable or false
|
|
||||||
else false;
|
|
||||||
backupsEnabled = if (node.config.homelab.enable or false) then
|
|
||||||
node.config.homelab.backups.enable or false
|
|
||||||
else false;
|
|
||||||
proxyEnabled = if (node.config.homelab.enable or false) then
|
|
||||||
node.config.homelab.reverseProxy.enable or false
|
|
||||||
else false;
|
|
||||||
}) nodes')
|
|
||||||
|
|
||||||
echo "| Node | Homelab | Environment | Services | Monitoring | Backups | Proxy |"
|
|
||||||
echo "|------|---------|-------------|----------|------------|---------|-------|"
|
|
||||||
|
|
||||||
echo "$node_status" | ${jq}/bin/jq -r 'to_entries[] |
|
|
||||||
[.key, (.value.homelabEnabled | if . then "✅" else "❌" end), .value.environment, (.value.serviceCount | tostring),
|
|
||||||
(.value.monitoringEnabled | if . then "✅" else "❌" end),
|
|
||||||
(.value.backupsEnabled | if . then "✅" else "❌" end),
|
|
||||||
(.value.proxyEnabled | if . then "✅" else "❌" end)] |
|
|
||||||
@tsv' | while IFS=$'\t' read -r node homelab env services monitoring backups proxy; do
|
|
||||||
echo "| \`$node\` | $homelab | $env | $services | $monitoring | $backups | $proxy |"
|
|
||||||
done
|
|
||||||
|
|
||||||
echo
|
|
||||||
echo "---"
|
|
||||||
echo
|
|
||||||
echo "*Deployment state extracted from live colmena configuration*"
|
|
||||||
'';
|
|
||||||
|
|
||||||
# README generator
|
|
||||||
readmeGenerator = writeShellScriptBin "homelab-docs-readme" ''
|
|
||||||
#!/usr/bin/env bash
|
|
||||||
set -euo pipefail
|
|
||||||
|
|
||||||
cat << EOF
|
|
||||||
# Homelab Documentation
|
|
||||||
|
|
||||||
> Auto-generated documentation for the homelab deployment
|
|
||||||
>
|
|
||||||
> Generated on: $(date)
|
|
||||||
> Source: $(pwd)
|
|
||||||
|
|
||||||
## 📚 Documentation Files
|
|
||||||
|
|
||||||
This documentation is automatically generated from your colmena flake configuration.
|
|
||||||
|
|
||||||
### 📊 Overview Documents
|
|
||||||
- **[Fleet Overview](fleet-overview.md)** - High-level fleet statistics and service distribution
|
|
||||||
- **[Current Deployment](current-deployment.md)** - Current deployment state and node status
|
|
||||||
|
|
||||||
### 📖 Detailed Configuration
|
|
||||||
- **[Node Configurations](nodes.md)** - Per-node detailed configuration and services
|
|
||||||
- **[Service Configurations](services.md)** - Service configurations across the fleet
|
|
||||||
|
|
||||||
## 🚀 Quick Actions
|
|
||||||
|
|
||||||
### View Current Status
|
|
||||||
\`\`\`bash
|
|
||||||
# Service status across fleet (if homelab CLI is available)
|
|
||||||
homelab services --global
|
|
||||||
|
|
||||||
# Backup status
|
|
||||||
homelab backups --global
|
|
||||||
|
|
||||||
# Overall status
|
|
||||||
homelab status
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
### Update Documentation
|
|
||||||
\`\`\`bash
|
|
||||||
# Regenerate all documentation
|
|
||||||
homelab-generate-docs ./docs
|
|
||||||
|
|
||||||
# Generate in different directory
|
|
||||||
homelab-generate-docs /path/to/output
|
|
||||||
\`\`\`
|
|
||||||
|
|
||||||
## 📋 Quick Stats
|
|
||||||
|
|
||||||
EOF
|
|
||||||
|
|
||||||
# Add live stats
|
|
||||||
quick_stats=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
|
||||||
let
|
|
||||||
homelabNodes = lib.filterAttrs (name: node: node.config.homelab.enable or false) nodes;
|
|
||||||
in {
|
|
||||||
totalNodes = lib.length (lib.attrNames nodes);
|
|
||||||
homelabNodes = lib.length (lib.attrNames homelabNodes);
|
|
||||||
}')
|
|
||||||
|
|
||||||
total_nodes=$(echo "$quick_stats" | ${jq}/bin/jq -r '.totalNodes')
|
|
||||||
homelab_nodes=$(echo "$quick_stats" | ${jq}/bin/jq -r '.homelabNodes')
|
|
||||||
|
|
||||||
echo "- **Total Nodes**: $total_nodes"
|
|
||||||
echo "- **Homelab-Enabled Nodes**: $homelab_nodes"
|
|
||||||
echo "- **Generated**: $(date)"
|
|
||||||
echo
|
|
||||||
echo "## 🛠️ Management Tools"
|
|
||||||
echo
|
|
||||||
echo "### Documentation Commands"
|
|
||||||
echo "- \`homelab-generate-docs\` - Regenerate this documentation"
|
|
||||||
echo "- \`homelab-docs-fleet\` - Generate fleet overview only"
|
|
||||||
echo "- \`homelab-docs-nodes\` - Generate node configurations only"
|
|
||||||
echo "- \`homelab-docs-services\` - Generate service configurations only"
|
|
||||||
echo "- \`homelab-docs-deployment\` - Generate deployment state only"
|
|
||||||
echo
|
|
||||||
echo "### Colmena Commands"
|
|
||||||
echo "- \`colmena eval\` - Evaluate flake expressions"
|
|
||||||
echo "- \`colmena apply\` - Deploy configuration changes"
|
|
||||||
echo "- \`colmena build\` - Build configurations without deploying"
|
|
||||||
echo
|
|
||||||
echo "---"
|
|
||||||
echo
|
|
||||||
echo "*This documentation reflects the live state of your homelab deployment as evaluated by colmena.*"
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
stdenv.mkDerivation {
|
|
||||||
pname = "homelab-docs";
|
|
||||||
version = "1.0.0";
|
|
||||||
|
|
||||||
dontUnpack = true;
|
|
||||||
dontBuild = true;
|
|
||||||
|
|
||||||
installPhase = ''
|
|
||||||
mkdir -p $out/bin
|
|
||||||
|
|
||||||
# Install all the generators
|
|
||||||
cp ${docsGenerator}/bin/homelab-generate-docs $out/bin/
|
|
||||||
cp ${fleetDocsGenerator}/bin/homelab-docs-fleet $out/bin/
|
|
||||||
cp ${nodeDocsGenerator}/bin/homelab-docs-nodes $out/bin/
|
|
||||||
cp ${serviceDocsGenerator}/bin/homelab-docs-services $out/bin/
|
|
||||||
cp ${deploymentDocsGenerator}/bin/homelab-docs-deployment $out/bin/
|
|
||||||
cp ${readmeGenerator}/bin/homelab-docs-readme $out/bin/
|
|
||||||
|
|
||||||
# Make sure they're executable
|
|
||||||
chmod +x $out/bin/*
|
|
||||||
'';
|
|
||||||
|
|
||||||
meta = with lib; {
|
|
||||||
description = "Documentation generator for homelab colmena deployments";
|
|
||||||
longDescription = ''
|
|
||||||
A collection of tools to generate comprehensive documentation
|
|
||||||
for homelab deployments managed with colmena. Extracts configuration
|
|
||||||
from flakes and generates markdown documentation.
|
|
||||||
'';
|
|
||||||
license = licenses.mit;
|
|
||||||
maintainers = [];
|
|
||||||
platforms = platforms.all;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
50
pkgs/homelab-docs/default.nix
Normal file
50
pkgs/homelab-docs/default.nix
Normal file
|
|
@ -0,0 +1,50 @@
|
||||||
|
# homelab-docs.nix - Main documentation generator package
|
||||||
|
{
|
||||||
|
lib,
|
||||||
|
stdenv,
|
||||||
|
writeShellScriptBin,
|
||||||
|
jq,
|
||||||
|
nixfmt,
|
||||||
|
}: let
|
||||||
|
# Import individual CLI generators
|
||||||
|
docsGenerator = import ./main.nix {inherit writeShellScriptBin;};
|
||||||
|
fleetDocsGenerator = import ./fleet.nix {inherit writeShellScriptBin jq;};
|
||||||
|
nodeDocsGenerator = import ./nodes.nix {inherit writeShellScriptBin jq;};
|
||||||
|
serviceDocsGenerator = import ./services.nix {inherit writeShellScriptBin jq;};
|
||||||
|
deploymentDocsGenerator = import ./deployment.nix {inherit writeShellScriptBin jq;};
|
||||||
|
readmeGenerator = import ./readme.nix {inherit writeShellScriptBin jq;};
|
||||||
|
in
|
||||||
|
stdenv.mkDerivation {
|
||||||
|
pname = "homelab-docs";
|
||||||
|
version = "1.0.0";
|
||||||
|
|
||||||
|
dontUnpack = true;
|
||||||
|
dontBuild = true;
|
||||||
|
|
||||||
|
installPhase = ''
|
||||||
|
mkdir -p $out/bin
|
||||||
|
|
||||||
|
# Install all the generators
|
||||||
|
cp ${docsGenerator}/bin/homelab-generate-docs $out/bin/
|
||||||
|
cp ${fleetDocsGenerator}/bin/homelab-docs-fleet $out/bin/
|
||||||
|
cp ${nodeDocsGenerator}/bin/homelab-docs-nodes $out/bin/
|
||||||
|
cp ${serviceDocsGenerator}/bin/homelab-docs-services $out/bin/
|
||||||
|
cp ${deploymentDocsGenerator}/bin/homelab-docs-deployment $out/bin/
|
||||||
|
cp ${readmeGenerator}/bin/homelab-docs-readme $out/bin/
|
||||||
|
|
||||||
|
# Make sure they're executable
|
||||||
|
chmod +x $out/bin/*
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = with lib; {
|
||||||
|
description = "Documentation generator for homelab colmena deployments";
|
||||||
|
longDescription = ''
|
||||||
|
A collection of tools to generate comprehensive documentation
|
||||||
|
for homelab deployments managed with colmena. Extracts configuration
|
||||||
|
from flakes and generates markdown documentation.
|
||||||
|
'';
|
||||||
|
license = licenses.mit;
|
||||||
|
maintainers = [];
|
||||||
|
platforms = platforms.all;
|
||||||
|
};
|
||||||
|
}
|
||||||
89
pkgs/homelab-docs/deployment.nix
Normal file
89
pkgs/homelab-docs/deployment.nix
Normal file
|
|
@ -0,0 +1,89 @@
|
||||||
|
# homelab-docs-deployment.nix - Deployment documentation generator CLI
|
||||||
|
{
|
||||||
|
writeShellScriptBin,
|
||||||
|
jq,
|
||||||
|
}:
|
||||||
|
writeShellScriptBin "homelab-docs-deployment" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat << 'EOF'
|
||||||
|
# Current Deployment State
|
||||||
|
|
||||||
|
> Current homelab deployment configuration
|
||||||
|
>
|
||||||
|
> Generated on: $(date)
|
||||||
|
> Working directory: $(pwd)
|
||||||
|
|
||||||
|
## Deployment Summary
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Get deployment summary
|
||||||
|
deployment_summary=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
homelabNodes = lib.filterAttrs (name: node: node.config.homelab.enable or false) nodes;
|
||||||
|
allServices = lib.flatten (lib.mapAttrsToList (nodeName: node:
|
||||||
|
lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {}))
|
||||||
|
) homelabNodes);
|
||||||
|
in {
|
||||||
|
totalNodes = lib.length (lib.attrNames nodes);
|
||||||
|
homelabEnabledNodes = lib.length (lib.attrNames homelabNodes);
|
||||||
|
uniqueServices = lib.length (lib.unique allServices);
|
||||||
|
totalServiceInstances = lib.length allServices;
|
||||||
|
nodeNames = lib.attrNames nodes;
|
||||||
|
homelabNodeNames = lib.attrNames homelabNodes;
|
||||||
|
}')
|
||||||
|
|
||||||
|
total_nodes=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.totalNodes')
|
||||||
|
homelab_nodes=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.homelabEnabledNodes')
|
||||||
|
unique_services=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.uniqueServices')
|
||||||
|
service_instances=$(echo "$deployment_summary" | ${jq}/bin/jq -r '.totalServiceInstances')
|
||||||
|
|
||||||
|
echo "| Metric | Count |"
|
||||||
|
echo "|--------|-------|"
|
||||||
|
echo "| Total Nodes | $total_nodes |"
|
||||||
|
echo "| Homelab-Enabled Nodes | $homelab_nodes |"
|
||||||
|
echo "| Unique Services | $unique_services |"
|
||||||
|
echo "| Service Instances | $service_instances |"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "## Node Status"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Get detailed node status
|
||||||
|
node_status=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||||
|
lib.mapAttrs (name: node: {
|
||||||
|
homelabEnabled = node.config.homelab.enable or false;
|
||||||
|
environment = node.config.homelab.environment or "unknown";
|
||||||
|
serviceCount = if (node.config.homelab.enable or false) then
|
||||||
|
lib.length (lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {})))
|
||||||
|
else 0;
|
||||||
|
monitoringEnabled = if (node.config.homelab.enable or false) then
|
||||||
|
node.config.homelab.monitoring.enable or false
|
||||||
|
else false;
|
||||||
|
backupsEnabled = if (node.config.homelab.enable or false) then
|
||||||
|
node.config.homelab.backups.enable or false
|
||||||
|
else false;
|
||||||
|
proxyEnabled = if (node.config.homelab.enable or false) then
|
||||||
|
node.config.homelab.reverseProxy.enable or false
|
||||||
|
else false;
|
||||||
|
}) nodes')
|
||||||
|
|
||||||
|
echo "| Node | Homelab | Environment | Services | Monitoring | Backups | Proxy |"
|
||||||
|
echo "|------|---------|-------------|----------|------------|---------|-------|"
|
||||||
|
|
||||||
|
echo "$node_status" | ${jq}/bin/jq -r 'to_entries[] |
|
||||||
|
[.key, (.value.homelabEnabled | if . then "✅" else "❌" end), .value.environment, (.value.serviceCount | tostring),
|
||||||
|
(.value.monitoringEnabled | if . then "✅" else "❌" end),
|
||||||
|
(.value.backupsEnabled | if . then "✅" else "❌" end),
|
||||||
|
(.value.proxyEnabled | if . then "✅" else "❌" end)] |
|
||||||
|
@tsv' | while IFS=$'\t' read -r node homelab env services monitoring backups proxy; do
|
||||||
|
echo "| \`$node\` | $homelab | $env | $services | $monitoring | $backups | $proxy |"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
echo "*Deployment state extracted from live colmena configuration*"
|
||||||
|
''
|
||||||
91
pkgs/homelab-docs/fleet.nix
Normal file
91
pkgs/homelab-docs/fleet.nix
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
{
|
||||||
|
writeShellScriptBin,
|
||||||
|
jq,
|
||||||
|
}:
|
||||||
|
writeShellScriptBin "homelab-docs-fleet" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat << 'EOF'
|
||||||
|
# Homelab Fleet Overview
|
||||||
|
|
||||||
|
> Auto-generated fleet overview
|
||||||
|
>
|
||||||
|
> Generated on: $(date)
|
||||||
|
> Source: $(pwd)
|
||||||
|
|
||||||
|
## Fleet Statistics
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Get basic fleet stats
|
||||||
|
echo "### Basic Information"
|
||||||
|
echo
|
||||||
|
|
||||||
|
fleet_stats=$(colmena eval -E '{ nodes, pkgs, lib, ... }: {
|
||||||
|
totalNodes = lib.length (lib.attrNames nodes);
|
||||||
|
nodeNames = lib.attrNames nodes;
|
||||||
|
}')
|
||||||
|
|
||||||
|
total_nodes=$(echo "$fleet_stats" | ${jq}/bin/jq -r '.totalNodes')
|
||||||
|
node_names=$(echo "$fleet_stats" | ${jq}/bin/jq -r '.nodeNames[]' | tr '\n' ' ')
|
||||||
|
|
||||||
|
echo "| Metric | Value |"
|
||||||
|
echo "|--------|-------|"
|
||||||
|
echo "| Total Nodes | $total_nodes |"
|
||||||
|
echo "| Node Names | $node_names |"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Get homelab-enabled nodes
|
||||||
|
echo "### Homelab Configuration"
|
||||||
|
echo
|
||||||
|
|
||||||
|
homelab_info=$(colmena eval -E '{ nodes, pkgs, lib, ... }: {
|
||||||
|
homelabNodes = lib.mapAttrs (name: node: {
|
||||||
|
enabled = node.config.homelab.enable or false;
|
||||||
|
hostname = node.config.homelab.hostname or null;
|
||||||
|
environment = node.config.homelab.environment or null;
|
||||||
|
}) nodes;
|
||||||
|
}')
|
||||||
|
|
||||||
|
echo "| Node | Homelab Enabled | Hostname | Environment |"
|
||||||
|
echo "|------|----------------|----------|-------------|"
|
||||||
|
|
||||||
|
echo "$homelab_info" | ${jq}/bin/jq -r '.homelabNodes | to_entries[] |
|
||||||
|
[.key, (.value.enabled | tostring), (.value.hostname // "N/A"), (.value.environment // "N/A")] |
|
||||||
|
@tsv' | while IFS=$'\t' read -r node enabled hostname environment; do
|
||||||
|
enabled_icon=$(if [[ "$enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
||||||
|
echo "| \`$node\` | $enabled_icon | $hostname | $environment |"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Get service distribution
|
||||||
|
echo "### Service Distribution"
|
||||||
|
echo
|
||||||
|
|
||||||
|
service_info=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||||
|
lib.mapAttrs (name: node:
|
||||||
|
if (node.config.homelab.enable or false) then {
|
||||||
|
serviceCount = lib.length (lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {})));
|
||||||
|
serviceNames = lib.attrNames (lib.filterAttrs (n: v: v.enable or false) (node.config.homelab.services or {}));
|
||||||
|
} else {
|
||||||
|
serviceCount = 0;
|
||||||
|
serviceNames = [];
|
||||||
|
}
|
||||||
|
) nodes')
|
||||||
|
|
||||||
|
echo "| Node | Service Count | Services |"
|
||||||
|
echo "|------|---------------|----------|"
|
||||||
|
|
||||||
|
echo "$service_info" | ${jq}/bin/jq -r 'to_entries[] |
|
||||||
|
[.key, (.value.serviceCount | tostring), (.value.serviceNames | join(", "))] |
|
||||||
|
@tsv' | while IFS=$'\t' read -r node count services; do
|
||||||
|
echo "| \`$node\` | $count | $services |"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
echo "*Fleet overview generated from colmena evaluation*"
|
||||||
|
''
|
||||||
73
pkgs/homelab-docs/main.nix
Normal file
73
pkgs/homelab-docs/main.nix
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
{writeShellScriptBin}:
|
||||||
|
writeShellScriptBin "homelab-generate-docs" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Colors
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
RED='\033[0;31m'
|
||||||
|
NC='\033[0m'
|
||||||
|
|
||||||
|
info() { echo -e "''${BLUE}$1''${NC}"; }
|
||||||
|
success() { echo -e "''${GREEN}$1''${NC}"; }
|
||||||
|
warn() { echo -e "''${YELLOW}$1''${NC}"; }
|
||||||
|
error() { echo -e "''${RED}$1''${NC}"; }
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
DOCS_DIR="''${1:-./docs}"
|
||||||
|
|
||||||
|
info "📚 Generating homelab documentation..."
|
||||||
|
echo " Output directory: $DOCS_DIR"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Check if we're in a directory with a flake
|
||||||
|
if [[ ! -f flake.nix ]]; then
|
||||||
|
error "No flake.nix found in current directory"
|
||||||
|
echo "Please run this command from your homelab flake directory"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if colmena is available
|
||||||
|
if ! command -v colmena >/dev/null 2>&1; then
|
||||||
|
error "colmena command not found."
|
||||||
|
echo "Please ensure colmena is available in your environment"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create docs directory
|
||||||
|
mkdir -p "$DOCS_DIR"
|
||||||
|
|
||||||
|
# Generate fleet overview
|
||||||
|
info " 🌐 Generating fleet overview..."
|
||||||
|
homelab-docs-fleet > "$DOCS_DIR/fleet-overview.md"
|
||||||
|
|
||||||
|
# Generate node documentation
|
||||||
|
info " 🖥️ Generating node configurations..."
|
||||||
|
homelab-docs-nodes > "$DOCS_DIR/nodes.md"
|
||||||
|
|
||||||
|
# Generate service documentation
|
||||||
|
info " ⚙️ Generating service configurations..."
|
||||||
|
homelab-docs-services > "$DOCS_DIR/services.md"
|
||||||
|
|
||||||
|
# Generate current deployment
|
||||||
|
info " 🏠 Generating current deployment..."
|
||||||
|
homelab-docs-deployment > "$DOCS_DIR/current-deployment.md"
|
||||||
|
|
||||||
|
# Generate README
|
||||||
|
info " 📋 Generating README..."
|
||||||
|
homelab-docs-readme > "$DOCS_DIR/README.md"
|
||||||
|
|
||||||
|
success "✅ Documentation generated successfully!"
|
||||||
|
echo
|
||||||
|
echo "Generated files:"
|
||||||
|
echo " 🌐 fleet-overview.md - Fleet statistics and overview"
|
||||||
|
echo " 🖥️ nodes.md - Per-node configurations"
|
||||||
|
echo " ⚙️ services.md - Service configurations"
|
||||||
|
echo " 🏠 current-deployment.md - Current deployment state"
|
||||||
|
echo " 📋 README.md - Documentation index"
|
||||||
|
echo
|
||||||
|
echo "💡 Tip: Add these files to your repository and set up GitHub Actions"
|
||||||
|
echo " to automatically regenerate documentation on changes!"
|
||||||
|
''
|
||||||
123
pkgs/homelab-docs/nodes.nix
Normal file
123
pkgs/homelab-docs/nodes.nix
Normal file
|
|
@ -0,0 +1,123 @@
|
||||||
|
{
|
||||||
|
writeShellScriptBin,
|
||||||
|
jq,
|
||||||
|
}:
|
||||||
|
writeShellScriptBin "homelab-docs-nodes" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat << 'EOF'
|
||||||
|
# Node Configurations
|
||||||
|
|
||||||
|
> Detailed per-node configuration
|
||||||
|
>
|
||||||
|
> Generated on: $(date)
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Get all node information
|
||||||
|
node_info=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||||
|
lib.mapAttrs (name: node: {
|
||||||
|
# Basic system info
|
||||||
|
nixosVersion = node.config.system.nixos.version;
|
||||||
|
hostName = node.config.networking.hostName;
|
||||||
|
system = node.config.nixpkgs.system;
|
||||||
|
|
||||||
|
# Homelab config (safe extraction)
|
||||||
|
homelab = if (node.config.homelab.enable or false) then {
|
||||||
|
enabled = true;
|
||||||
|
hostname = node.config.homelab.hostname or null;
|
||||||
|
domain = node.config.homelab.domain or null;
|
||||||
|
externalDomain = node.config.homelab.externalDomain or null;
|
||||||
|
environment = node.config.homelab.environment or null;
|
||||||
|
location = node.config.homelab.location or null;
|
||||||
|
tags = node.config.homelab.tags or [];
|
||||||
|
} else {
|
||||||
|
enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Services (safe extraction)
|
||||||
|
services = if (node.config.homelab.enable or false) then
|
||||||
|
lib.mapAttrs (svcName: svc: {
|
||||||
|
enabled = svc.enable or false;
|
||||||
|
port = svc.port or null;
|
||||||
|
description = svc.description or svcName;
|
||||||
|
tags = svc.tags or [];
|
||||||
|
}) (node.config.homelab.services or {})
|
||||||
|
else {};
|
||||||
|
}) nodes')
|
||||||
|
|
||||||
|
echo "$node_info" | ${jq}/bin/jq -r 'to_entries[] | .key' | while read -r node; do
|
||||||
|
echo "## Node: $node"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Basic system information
|
||||||
|
echo "### System Information"
|
||||||
|
echo
|
||||||
|
|
||||||
|
nixos_version=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].nixosVersion")
|
||||||
|
hostname=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].hostName")
|
||||||
|
system=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].system")
|
||||||
|
|
||||||
|
echo "| Property | Value |"
|
||||||
|
echo "|----------|-------|"
|
||||||
|
echo "| NixOS Version | \`$nixos_version\` |"
|
||||||
|
echo "| Hostname | \`$hostname\` |"
|
||||||
|
echo "| System | \`$system\` |"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Homelab configuration
|
||||||
|
homelab_enabled=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.enabled")
|
||||||
|
|
||||||
|
if [[ "$homelab_enabled" == "true" ]]; then
|
||||||
|
echo "### Homelab Configuration"
|
||||||
|
echo
|
||||||
|
|
||||||
|
hl_hostname=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.hostname // \"N/A\"")
|
||||||
|
hl_domain=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.domain // \"N/A\"")
|
||||||
|
hl_external=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.externalDomain // \"N/A\"")
|
||||||
|
hl_env=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.environment // \"N/A\"")
|
||||||
|
hl_location=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.location // \"N/A\"")
|
||||||
|
hl_tags=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].homelab.tags | join(\", \")")
|
||||||
|
|
||||||
|
echo "| Property | Value |"
|
||||||
|
echo "|----------|-------|"
|
||||||
|
echo "| Homelab Hostname | \`$hl_hostname\` |"
|
||||||
|
echo "| Domain | \`$hl_domain\` |"
|
||||||
|
echo "| External Domain | \`$hl_external\` |"
|
||||||
|
echo "| Environment | \`$hl_env\` |"
|
||||||
|
echo "| Location | \`$hl_location\` |"
|
||||||
|
echo "| Tags | $hl_tags |"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Services
|
||||||
|
echo "### Services"
|
||||||
|
echo
|
||||||
|
|
||||||
|
services_data=$(echo "$node_info" | ${jq}/bin/jq -r ".[\"$node\"].services")
|
||||||
|
service_count=$(echo "$services_data" | ${jq}/bin/jq 'length')
|
||||||
|
|
||||||
|
if [[ "$service_count" -gt 0 ]]; then
|
||||||
|
echo "| Service | Enabled | Port | Description | Tags |"
|
||||||
|
echo "|---------|---------|------|-------------|------|"
|
||||||
|
|
||||||
|
echo "$services_data" | ${jq}/bin/jq -r 'to_entries[] |
|
||||||
|
[.key, (.value.enabled | tostring), (.value.port // "N/A" | tostring), (.value.description // "N/A"), (.value.tags | join(", "))] |
|
||||||
|
@tsv' | while IFS=$'\t' read -r service enabled port description tags; do
|
||||||
|
enabled_icon=$(if [[ "$enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
||||||
|
echo "| \`$service\` | $enabled_icon | $port | $description | $tags |"
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "No services configured."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "### Homelab Configuration"
|
||||||
|
echo
|
||||||
|
echo "❌ Homelab is not enabled on this node."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
''
|
||||||
124
pkgs/homelab-docs/readme.nix
Normal file
124
pkgs/homelab-docs/readme.nix
Normal file
|
|
@ -0,0 +1,124 @@
|
||||||
|
# homelab-docs-readme.nix - README generator CLI
|
||||||
|
{
|
||||||
|
writeShellScriptBin,
|
||||||
|
jq,
|
||||||
|
}:
|
||||||
|
writeShellScriptBin "homelab-docs-readme" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat << 'EOF'
|
||||||
|
# Homelab Documentation
|
||||||
|
|
||||||
|
> Auto-generated documentation for the homelab deployment
|
||||||
|
>
|
||||||
|
> Generated on: $(date)
|
||||||
|
> Source: $(pwd)
|
||||||
|
|
||||||
|
## 📚 Documentation Files
|
||||||
|
|
||||||
|
This documentation is automatically generated from your colmena flake configuration.
|
||||||
|
|
||||||
|
### 📊 Overview Documents
|
||||||
|
- **[Fleet Overview](fleet-overview.md)** - High-level fleet statistics and service distribution
|
||||||
|
- **[Current Deployment](current-deployment.md)** - Current deployment state and node status
|
||||||
|
|
||||||
|
### 📖 Detailed Configuration
|
||||||
|
- **[Node Configurations](nodes.md)** - Per-node detailed configuration and services
|
||||||
|
- **[Service Configurations](services.md)** - Service configurations across the fleet
|
||||||
|
|
||||||
|
## 🚀 Quick Actions
|
||||||
|
|
||||||
|
### View Current Status
|
||||||
|
\`\`\`bash
|
||||||
|
# Service status across fleet (if homelab CLI is available)
|
||||||
|
homelab services --global
|
||||||
|
|
||||||
|
# Backup status
|
||||||
|
homelab backups --global
|
||||||
|
|
||||||
|
# Overall status
|
||||||
|
homelab status
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Update Documentation
|
||||||
|
\`\`\`bash
|
||||||
|
# Regenerate all documentation
|
||||||
|
homelab-generate-docs ./docs
|
||||||
|
|
||||||
|
# Generate in different directory
|
||||||
|
homelab-generate-docs /path/to/output
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## 📋 Quick Stats
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Add live stats
|
||||||
|
quick_stats=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
homelabNodes = lib.filterAttrs (name: node: node.config.homelab.enable or false) nodes;
|
||||||
|
in {
|
||||||
|
totalNodes = lib.length (lib.attrNames nodes);
|
||||||
|
homelabNodes = lib.length (lib.attrNames homelabNodes);
|
||||||
|
}')
|
||||||
|
|
||||||
|
total_nodes=$(echo "$quick_stats" | ${jq}/bin/jq -r '.totalNodes')
|
||||||
|
homelab_nodes=$(echo "$quick_stats" | ${jq}/bin/jq -r '.homelabNodes')
|
||||||
|
|
||||||
|
echo "- **Total Nodes**: $total_nodes"
|
||||||
|
echo "- **Homelab-Enabled Nodes**: $homelab_nodes"
|
||||||
|
echo "- **Generated**: $(date)"
|
||||||
|
echo
|
||||||
|
echo "## 🛠️ Management Tools"
|
||||||
|
echo
|
||||||
|
echo "### Documentation Commands"
|
||||||
|
echo "- \`homelab-generate-docs\` - Regenerate this documentation"
|
||||||
|
echo "- \`homelab-docs-fleet\` - Generate fleet overview only"
|
||||||
|
echo "- \`homelab-docs-nodes\` - Generate node configurations only"
|
||||||
|
echo "- \`homelab-docs-services\` - Generate service configurations only"
|
||||||
|
echo "- \`homelab-docs-deployment\` - Generate deployment state only"
|
||||||
|
echo
|
||||||
|
echo "### Colmena Commands"
|
||||||
|
echo "- \`colmena eval\` - Evaluate flake expressions"
|
||||||
|
echo "- \`colmena apply\` - Deploy configuration changes"
|
||||||
|
echo "- \`colmena build\` - Build configurations without deploying"
|
||||||
|
echo
|
||||||
|
echo "## 🎯 Integration with CI/CD"
|
||||||
|
echo
|
||||||
|
echo "### GitHub Actions Example"
|
||||||
|
echo
|
||||||
|
echo "\`\`\`yaml"
|
||||||
|
echo "name: Generate Documentation"
|
||||||
|
echo "on:"
|
||||||
|
echo " push:"
|
||||||
|
echo " branches: [ main ]"
|
||||||
|
echo ""
|
||||||
|
echo "jobs:"
|
||||||
|
echo " docs:"
|
||||||
|
echo " runs-on: ubuntu-latest"
|
||||||
|
echo " steps:"
|
||||||
|
echo " - uses: actions/checkout@v4"
|
||||||
|
echo " - uses: cachix/install-nix-action@v24"
|
||||||
|
echo " - name: Generate docs"
|
||||||
|
echo " run: nix develop --command homelab-generate-docs ./docs"
|
||||||
|
echo " - name: Commit docs"
|
||||||
|
echo " run: |"
|
||||||
|
echo " git add docs/"
|
||||||
|
echo " git commit -m \"docs: update homelab documentation\" || exit 0"
|
||||||
|
echo " git push"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo
|
||||||
|
echo "### Manual Generation"
|
||||||
|
echo
|
||||||
|
echo "\`\`\`bash"
|
||||||
|
echo "# From your homelab directory"
|
||||||
|
echo "nix develop"
|
||||||
|
echo "homelab-generate-docs ./docs"
|
||||||
|
echo "git add docs/ && git commit -m \"Update docs\""
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
echo "*This documentation reflects the live state of your homelab deployment as evaluated by colmena.*"
|
||||||
|
''
|
||||||
270
pkgs/homelab-docs/services.nix
Normal file
270
pkgs/homelab-docs/services.nix
Normal file
|
|
@ -0,0 +1,270 @@
|
||||||
|
# homelab-docs-services.nix - Service documentation generator CLI
|
||||||
|
{
|
||||||
|
writeShellScriptBin,
|
||||||
|
jq,
|
||||||
|
}:
|
||||||
|
writeShellScriptBin "homelab-docs-services" ''
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cat << 'EOF'
|
||||||
|
# Service Catalog
|
||||||
|
|
||||||
|
> Available services and their configuration options
|
||||||
|
>
|
||||||
|
> Generated on: $(date)
|
||||||
|
|
||||||
|
This document catalogs all available homelab services, their configuration options, and integration capabilities.
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Get all services and their configurations
|
||||||
|
services_catalog=$(colmena eval -E '{ nodes, pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
# Collect all services from all nodes to build a complete catalog
|
||||||
|
allServiceConfigs = lib.flatten (lib.mapAttrsToList (nodeName: node:
|
||||||
|
if (node.config.homelab.enable or false) then
|
||||||
|
lib.mapAttrsToList (serviceName: service: {
|
||||||
|
inherit serviceName;
|
||||||
|
config = {
|
||||||
|
# Core service options
|
||||||
|
enable = service.enable or false;
|
||||||
|
port = service.port or null;
|
||||||
|
description = service.description or serviceName;
|
||||||
|
tags = service.tags or [];
|
||||||
|
|
||||||
|
# Integration options
|
||||||
|
monitoring = {
|
||||||
|
enabled = service.monitoring.enable or false;
|
||||||
|
metricsPath = service.monitoring.metrics.path or "/metrics";
|
||||||
|
healthPath = service.monitoring.healthCheck.path or "/health";
|
||||||
|
extraLabels = service.monitoring.extraLabels or {};
|
||||||
|
};
|
||||||
|
|
||||||
|
logging = {
|
||||||
|
enabled = service.logging.enable or false;
|
||||||
|
files = service.logging.files or [];
|
||||||
|
extraLabels = service.logging.extraLabels or {};
|
||||||
|
};
|
||||||
|
|
||||||
|
proxy = {
|
||||||
|
enabled = service.proxy.enable or false;
|
||||||
|
subdomain = service.proxy.subdomain or serviceName;
|
||||||
|
enableAuth = service.proxy.enableAuth or false;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Service-specific options (everything else)
|
||||||
|
serviceSpecific = removeAttrs service [
|
||||||
|
"enable" "port" "description" "tags"
|
||||||
|
"monitoring" "logging" "proxy"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
deployedOn = nodeName;
|
||||||
|
}) (node.config.homelab.services or {})
|
||||||
|
else []
|
||||||
|
) nodes);
|
||||||
|
|
||||||
|
# Group by service name and merge configurations
|
||||||
|
serviceGroups = lib.groupBy (svc: svc.serviceName) allServiceConfigs;
|
||||||
|
|
||||||
|
# Get unique services with merged configuration examples
|
||||||
|
uniqueServices = lib.mapAttrs (serviceName: instances:
|
||||||
|
let
|
||||||
|
# Take the first enabled instance as the canonical example
|
||||||
|
enabledInstances = lib.filter (inst: inst.config.enable) instances;
|
||||||
|
canonicalConfig = if enabledInstances != [] then (lib.head enabledInstances).config else (lib.head instances).config;
|
||||||
|
in {
|
||||||
|
inherit serviceName;
|
||||||
|
config = canonicalConfig;
|
||||||
|
deploymentCount = lib.length (lib.filter (inst: inst.config.enable) instances);
|
||||||
|
deployedOn = lib.unique (map (inst: inst.deployedOn or "unknown") enabledInstances);
|
||||||
|
}
|
||||||
|
) serviceGroups;
|
||||||
|
|
||||||
|
in {
|
||||||
|
services = uniqueServices;
|
||||||
|
totalUniqueServices = lib.length (lib.attrNames uniqueServices);
|
||||||
|
}')
|
||||||
|
|
||||||
|
total_services=$(echo "$services_catalog" | ${jq}/bin/jq -r '.totalUniqueServices')
|
||||||
|
|
||||||
|
echo "## Overview"
|
||||||
|
echo
|
||||||
|
echo "**Total Available Services:** $total_services"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Create a summary table of services and their default integrations
|
||||||
|
echo "## Service Integration Matrix"
|
||||||
|
echo
|
||||||
|
echo "| Service | Monitoring | Logging | Proxy | Auth Default |"
|
||||||
|
echo "|---------|------------|---------|-------|--------------|"
|
||||||
|
|
||||||
|
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
||||||
|
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
||||||
|
|
||||||
|
monitoring_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.enabled')
|
||||||
|
logging_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.enabled')
|
||||||
|
proxy_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enabled')
|
||||||
|
auth_default=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enableAuth')
|
||||||
|
|
||||||
|
monitoring_icon=$(if [[ "$monitoring_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
||||||
|
logging_icon=$(if [[ "$logging_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
||||||
|
proxy_icon=$(if [[ "$proxy_enabled" == "true" ]]; then echo "✅"; else echo "❌"; fi)
|
||||||
|
auth_icon=$(if [[ "$auth_default" == "true" ]]; then echo "🔒"; else echo "🌐"; fi)
|
||||||
|
|
||||||
|
echo "| \`$service\` | $monitoring_icon | $logging_icon | $proxy_icon | $auth_icon |"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo
|
||||||
|
echo "**Legend:** ✅ = Enabled by default, ❌ = Available but disabled, 🔒 = Auth required, 🌐 = Public access"
|
||||||
|
echo
|
||||||
|
|
||||||
|
echo "## Service Reference"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Process each service
|
||||||
|
echo "$services_catalog" | ${jq}/bin/jq -r '.services | to_entries[] | .key' | sort | while read -r service; do
|
||||||
|
echo "### $service"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Get service details
|
||||||
|
service_data=$(echo "$services_catalog" | ${jq}/bin/jq -r ".services[\"$service\"]")
|
||||||
|
|
||||||
|
description=$(echo "$service_data" | ${jq}/bin/jq -r '.config.description // "No description available"')
|
||||||
|
port=$(echo "$service_data" | ${jq}/bin/jq -r '.config.port // "N/A"')
|
||||||
|
tags=$(echo "$service_data" | ${jq}/bin/jq -r '.config.tags | join(", ")')
|
||||||
|
deployment_count=$(echo "$service_data" | ${jq}/bin/jq -r '.deploymentCount')
|
||||||
|
deployed_on=$(echo "$service_data" | ${jq}/bin/jq -r '.deployedOn | join(", ")')
|
||||||
|
|
||||||
|
echo "**Description:** $description"
|
||||||
|
echo
|
||||||
|
echo "**Default Port:** \`$port\`"
|
||||||
|
echo
|
||||||
|
if [[ -n "$tags" && "$tags" != "" ]]; then
|
||||||
|
echo "**Tags:** $tags"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
echo "**Current Deployments:** $deployment_count instance(s) on: $deployed_on"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Integration Status Overview
|
||||||
|
monitoring_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.enabled')
|
||||||
|
logging_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.enabled')
|
||||||
|
proxy_enabled=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enabled')
|
||||||
|
|
||||||
|
echo "#### Default Integration Status"
|
||||||
|
echo
|
||||||
|
echo "| Integration | Status | Default Configuration |"
|
||||||
|
echo "|-------------|--------|----------------------|"
|
||||||
|
|
||||||
|
# Monitoring status
|
||||||
|
if [[ "$monitoring_enabled" == "true" ]]; then
|
||||||
|
metrics_path=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.metricsPath')
|
||||||
|
health_path=$(echo "$service_data" | ${jq}/bin/jq -r '.config.monitoring.healthPath')
|
||||||
|
echo "| 📊 Monitoring | ✅ **Enabled** | Metrics: \`$metrics_path\`, Health: \`$health_path\` |"
|
||||||
|
else
|
||||||
|
echo "| 📊 Monitoring | ❌ Disabled | Available but requires \`monitoring.enable = true\` |"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Logging status
|
||||||
|
if [[ "$logging_enabled" == "true" ]]; then
|
||||||
|
log_files=$(echo "$service_data" | ${jq}/bin/jq -r '.config.logging.files | length')
|
||||||
|
if [[ "$log_files" -gt 0 ]]; then
|
||||||
|
echo "| 📝 Logging | ✅ **Enabled** | Collecting $log_files log file(s) |"
|
||||||
|
else
|
||||||
|
echo "| 📝 Logging | ✅ **Enabled** | Auto-configured log collection |"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "| 📝 Logging | ❌ Disabled | Available but requires \`logging.enable = true\` |"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Proxy status
|
||||||
|
if [[ "$proxy_enabled" == "true" ]]; then
|
||||||
|
subdomain=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.subdomain')
|
||||||
|
enable_auth=$(echo "$service_data" | ${jq}/bin/jq -r '.config.proxy.enableAuth')
|
||||||
|
auth_status=$(if [[ "$enable_auth" == "true" ]]; then echo "🔒 Auth required"; else echo "🌐 Public access"; fi)
|
||||||
|
echo "| 🔀 Proxy | ✅ **Enabled** | Subdomain: \`$subdomain\`, $auth_status |"
|
||||||
|
else
|
||||||
|
echo "| 🔀 Proxy | ❌ Disabled | Available but requires \`proxy.enable = true\` |"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Core Configuration
|
||||||
|
echo "#### Core Configuration"
|
||||||
|
echo
|
||||||
|
echo "\`\`\`nix"
|
||||||
|
echo "homelab.services.$service = {"
|
||||||
|
echo " enable = true;"
|
||||||
|
if [[ "$port" != "N/A" ]]; then
|
||||||
|
echo " port = $port;"
|
||||||
|
fi
|
||||||
|
echo " description = \"$description\";"
|
||||||
|
if [[ -n "$tags" && "$tags" != "" ]]; then
|
||||||
|
echo " tags = [ $(echo "$tags" | sed 's/, /" "/g' | sed 's/^/"/; s/$/"/') ];"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
echo " # Default integrations (adjust as needed)"
|
||||||
|
if [[ "$monitoring_enabled" == "true" ]]; then
|
||||||
|
echo " monitoring.enable = true; # ✅ Enabled by default"
|
||||||
|
else
|
||||||
|
echo " # monitoring.enable = true; # ❌ Disabled by default"
|
||||||
|
fi
|
||||||
|
if [[ "$logging_enabled" == "true" ]]; then
|
||||||
|
echo " logging.enable = true; # ✅ Enabled by default"
|
||||||
|
else
|
||||||
|
echo " # logging.enable = true; # ❌ Disabled by default"
|
||||||
|
fi
|
||||||
|
if [[ "$proxy_enabled" == "true" ]]; then
|
||||||
|
echo " proxy.enable = true; # ✅ Enabled by default"
|
||||||
|
else
|
||||||
|
echo " # proxy.enable = true; # ❌ Disabled by default"
|
||||||
|
fi
|
||||||
|
echo "};"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Service-specific options
|
||||||
|
service_specific=$(echo "$service_data" | ${jq}/bin/jq -r '.config.serviceSpecific')
|
||||||
|
if [[ "$service_specific" != "{}" && "$service_specific" != "null" ]]; then
|
||||||
|
echo "#### Service-Specific Options"
|
||||||
|
echo
|
||||||
|
echo "Available configuration options for $service:"
|
||||||
|
echo
|
||||||
|
echo "\`\`\`nix"
|
||||||
|
echo "homelab.services.$service = {"
|
||||||
|
echo " # ... core options above ..."
|
||||||
|
echo
|
||||||
|
echo " # Service-specific configuration"
|
||||||
|
echo "$service_specific" | ${jq}/bin/jq -r 'to_entries[] | " \(.key) = \(.value | tostring);"'
|
||||||
|
echo "};"
|
||||||
|
echo "\`\`\`"
|
||||||
|
echo
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "## Integration Summary"
|
||||||
|
echo
|
||||||
|
echo "### Available Integration Types"
|
||||||
|
echo
|
||||||
|
echo "| Integration | Purpose | Default Behavior | Configuration |"
|
||||||
|
echo "|-------------|---------|------------------|---------------|"
|
||||||
|
echo "| **📊 Monitoring** | Prometheus metrics + health checks | Service-dependent | \`monitoring.enable = true\` |"
|
||||||
|
echo "| **📝 Logging** | Centralized log collection | Service-dependent | \`logging.enable = true\` |"
|
||||||
|
echo "| **🔀 Proxy** | Reverse proxy with SSL + auth | Service-dependent | \`proxy.enable = true\` |"
|
||||||
|
echo
|
||||||
|
echo "### Integration Benefits"
|
||||||
|
echo
|
||||||
|
echo "- **🔄 Automatic Discovery:** Enabled integrations are automatically discovered by fleet-wide services"
|
||||||
|
echo "- **📊 Unified Monitoring:** All metrics and health checks appear in Prometheus/Grafana"
|
||||||
|
echo "- **📝 Centralized Logging:** All logs are collected and indexed in Loki"
|
||||||
|
echo "- **🌐 Consistent Access:** All services get consistent subdomain access with SSL"
|
||||||
|
echo "- **🎯 Smart Defaults:** Each service comes with sensible default configurations"
|
||||||
|
echo
|
||||||
|
echo "---"
|
||||||
|
echo
|
||||||
|
echo "*This service catalog is generated from actual service configurations across your homelab fleet.*"
|
||||||
|
''
|
||||||
Loading…
Add table
Add a link
Reference in a new issue