Cleanup repository
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
# Rhema Wave User Manual
|
||||
|
||||
## Keybinds
|
||||
These are the basic keybinds for navigating Rhema Wave and operating the program.
|
||||
Should you find a keybind that does something and is not listed here, please email nclack@rhemawavetech.com
|
||||
|
||||
> When you see key combinations such as "SHIFT + UP ARROW", press and hold the first key, in this case SHIFT
|
||||
> then press the second key. Do not hold the second key as right now, there is no way to stop a flood of commands
|
||||
> from being sent to the program, and you could send more than the program can handle, causing things to "continue happening after you've let go of the keys".
|
||||
|
||||
|
||||
### Navigation
|
||||
|
||||
**F1** - The "Welcome" screen. The screen that appears when you first start Rhema Wave and is useful for finding the current version of Rhema Wave you have installed.
|
||||
**F2** - The "Player". This is the main application where your proclamations and audio will be played.
|
||||
**F3** - The "Settings" menu. Use this menu to connect to WiFi, manage Audio Output Devices, and select your active proclamations to be played.
|
||||
|
||||
### Controls
|
||||
|
||||
**SHIFT + UP ARROW** - Volume Up
|
||||
**SHIFT + DOWN ARROW** - Volume Down
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm -rf ~/.local/share/rhemawave/
|
||||
|
||||
echo "Data directory deleted, application reset."
|
||||
@@ -1,796 +0,0 @@
|
||||
# RhemaWave Kiosk Infrastructure — Complete Maintainer Guide
|
||||
|
||||
## Purpose
|
||||
|
||||
This document describes the **complete** infrastructure for building, distributing, and deploying the RhemaWave kiosk application on NixOS. It is written so that a new developer can reconstruct the entire system from scratch on a fresh machine.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. Architecture Overview
|
||||
2. Repositories
|
||||
3. Key Files and Secrets — What Lives Where
|
||||
4. Development Machine Setup (From Scratch)
|
||||
5. The RhemaWave Flake (Application)
|
||||
6. The NixConfig Flake (Kiosk System)
|
||||
7. Binary Cache Setup
|
||||
8. Caddy Server Configuration
|
||||
9. Signing Keys
|
||||
10. Sops-Nix Secrets Management
|
||||
11. GitHub Access
|
||||
12. Building and Publishing a New Release
|
||||
13. Deploying a New Kiosk (nixos-anywhere)
|
||||
14. Auto-Update System
|
||||
15. Testing and Debugging
|
||||
16. Common Errors and Solutions
|
||||
|
||||
---
|
||||
|
||||
## 1. Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────┐
|
||||
│ Developer Machine (P15) │
|
||||
│ │
|
||||
│ RhemaWave repo NixConfig repo│
|
||||
│ (Go application) (NixOS cfg) │
|
||||
│ │ │ │
|
||||
│ nix build nix flake │
|
||||
│ nix store sign update │
|
||||
│ nix copy git push │
|
||||
│ │ │ │
|
||||
└─────────┼───────────────┼───────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌──────────┐
|
||||
│ Web Server │ │ GitHub │
|
||||
│ (Caddy) │ │ (private)│
|
||||
│ │ │ │
|
||||
│ Binary cache: │ │ NixConfig│
|
||||
│ repository. │ │ flake │
|
||||
│ rhemawavetech │ │ │
|
||||
│ .com │ │ RhemaWave│
|
||||
│ │ │ flake │
|
||||
│ Static files: │ │ │
|
||||
│ .narinfo + .nar │ └────┬─────┘
|
||||
└────────┬────────┘ │
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────────────────────┐
|
||||
│ Kiosk Machines │
|
||||
│ │
|
||||
│ systemd timer (every 15min): │
|
||||
│ 1. Fetch NixConfig from │
|
||||
│ GitHub │
|
||||
│ 2. Evaluate flake │
|
||||
│ 3. Download RhemaWave binary │
|
||||
│ from binary cache │
|
||||
│ 4. nixos-rebuild switch │
|
||||
│ │
|
||||
│ Cage compositor → RhemaWave │
|
||||
│ (fullscreen, locked, no TTY │
|
||||
│ switching, auto-restart) │
|
||||
└─────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Repositories
|
||||
|
||||
| Repo | URL | Branch | Contents |
|
||||
|------|-----|--------|----------|
|
||||
| RhemaWave | `github:Rhema-Wave-Technologies/RhemaWave` | `dev` | Go application source, `flake.nix` (package + NixOS module), `nixos/module.nix` |
|
||||
| NixConfig | `github:Rhema-Wave-Technologies/NixConfig` | `main` | NixOS kiosk configuration, disk layout, encrypted secrets, sops config |
|
||||
|
||||
Both repositories are **private**. Access requires a GitHub fine-grained personal access token with read-only Contents permission on both repos.
|
||||
|
||||
---
|
||||
|
||||
## 3. Key Files and Secrets — What Lives Where
|
||||
|
||||
### On the Developer Machine
|
||||
|
||||
| File | Path | Purpose | Backup? |
|
||||
|------|------|---------|---------|
|
||||
| Binary cache private key | `~/Keys/nix/cache/rhemawave/cache-priv-key.pem` | Signs packages for the binary cache | **CRITICAL** — without this, you cannot publish new builds. Back up to encrypted offline storage. |
|
||||
| Binary cache public key | `~/Keys/nix/cache/rhemawave/cache-pub-key.pem` | Distributed to all client machines for verification | Can be regenerated from private key |
|
||||
| Sops age private key | `~/Keys/nix/sops/age-key.txt` | Encrypts/decrypts secrets in NixConfig | **CRITICAL** — without this, you cannot edit secrets. Back up to encrypted offline storage. |
|
||||
| GitHub access token | `~/.config/nix/nix.conf` | Nix uses this to access private GitHub repos | Can be regenerated from GitHub |
|
||||
| Sops age key env var | `~/.bashrc` | `SOPS_AGE_KEY_FILE=~/Keys/nix/sops/age-key.txt` | Convention only |
|
||||
|
||||
### On the Web Server
|
||||
|
||||
| File | Path | Purpose |
|
||||
|------|------|---------|
|
||||
| Binary cache files | `/var/lib/nix-cache/` | Static files served by Caddy |
|
||||
| `nix-cache-info` | `/var/lib/nix-cache/nix-cache-info` | Metadata file for Nix clients |
|
||||
| Caddy config | Caddyfile (location varies) | Serves the cache directory |
|
||||
|
||||
The server does **not** need any signing keys. It is a dumb static file host.
|
||||
|
||||
### On Each Kiosk
|
||||
|
||||
| File | Path | Purpose |
|
||||
|------|------|---------|
|
||||
| SSH host key (private) | `/etc/ssh/ssh_host_ed25519_key` | Used by sops-nix to decrypt secrets |
|
||||
| SSH host key (public) | `/etc/ssh/ssh_host_ed25519_key.pub` | Converted to age key for sops `.sops.yaml` |
|
||||
| Decrypted secrets | `/run/secrets/*` | Runtime-only, never persisted to disk |
|
||||
|
||||
### What to Back Up (Priority Order)
|
||||
|
||||
1. **`~/Keys/nix/cache/rhemawave/cache-priv-key.pem`** — If lost, you must generate a new key pair and update the public key in every kiosk configuration and redeploy.
|
||||
2. **`~/Keys/nix/sops/age-key.txt`** — If lost, you must re-encrypt all secrets with a new key.
|
||||
3. **GitHub token** — Easily regenerated, low priority.
|
||||
|
||||
Store backups on an encrypted USB drive or a password manager's secure notes. Never store these in any Git repository, cloud drive, or unencrypted medium.
|
||||
|
||||
---
|
||||
|
||||
## 4. Development Machine Setup (From Scratch)
|
||||
|
||||
Starting from a fresh NixOS installation on a development machine.
|
||||
|
||||
### 4.1 NixOS Configuration Prerequisites
|
||||
|
||||
In your system `configuration.nix`:
|
||||
|
||||
```nix
|
||||
nix.settings = {
|
||||
experimental-features = [ "nix-command" "flakes" ];
|
||||
trusted-users = [ "root" "yourusername" ];
|
||||
substituters = [
|
||||
"https://cache.nixos.org"
|
||||
"https://repository.rhemawavetech.com"
|
||||
];
|
||||
trusted-public-keys = [
|
||||
"cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY="
|
||||
"repository.rhemawavetech.com-1:hbaEpYz5jE9SeNgkF2jAgjMtjXzruj7lEk6Lvx9ll40="
|
||||
];
|
||||
};
|
||||
nixpkgs.config.allowUnfree = true;
|
||||
```
|
||||
|
||||
Rebuild: `sudo nixos-rebuild switch`
|
||||
|
||||
### 4.2 Add the RhemaWave Flake to Your System Config
|
||||
|
||||
In your system `flake.nix`, add the input and package:
|
||||
|
||||
```nix
|
||||
inputs.rhemawave = {
|
||||
url = "github:Rhema-Wave-Technologies/RhemaWave/dev";
|
||||
inputs.nixpkgs.follows = "nixpkgs";
|
||||
};
|
||||
```
|
||||
|
||||
Add `rhemawave` to the `outputs` function arguments, then add to a module:
|
||||
|
||||
```nix
|
||||
{
|
||||
environment.systemPackages = [
|
||||
rhemawave.packages.x86_64-linux.default
|
||||
];
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 GitHub Access Token
|
||||
|
||||
Generate a fine-grained personal access token at `github.com/settings/tokens`:
|
||||
- Resource owner: `Rhema-Wave-Technologies`
|
||||
- Repository access: Select `NixConfig` and `RhemaWave`
|
||||
- Permissions: Contents → Read-only
|
||||
- Expiration: Set as appropriate
|
||||
|
||||
Configure Nix to use it:
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.config/nix
|
||||
echo "access-tokens = github.com=YOUR_TOKEN_HERE" > ~/.config/nix/nix.conf
|
||||
```
|
||||
|
||||
Also copy to root (needed for `sudo` operations):
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /root/.config/nix
|
||||
sudo cp ~/.config/nix/nix.conf /root/.config/nix/nix.conf
|
||||
```
|
||||
|
||||
### 4.4 Signing Keys
|
||||
|
||||
If you're taking over from an existing maintainer, obtain:
|
||||
- `cache-priv-key.pem` → save to `~/Keys/nix/cache/rhemawave/cache-priv-key.pem`
|
||||
- `age-key.txt` → save to `~/Keys/nix/sops/age-key.txt`
|
||||
|
||||
If starting fresh (new cache):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/Keys/nix/cache/rhemawave
|
||||
nix key generate-secret --key-name repository.rhemawavetech.com-1 > ~/Keys/nix/cache/rhemawave/cache-priv-key.pem
|
||||
nix key convert-secret-to-public < ~/Keys/nix/cache/rhemawave/cache-priv-key.pem > ~/Keys/nix/cache/rhemawave/cache-pub-key.pem
|
||||
```
|
||||
|
||||
If starting fresh (new sops key):
|
||||
|
||||
```bash
|
||||
mkdir -p ~/Keys/nix/sops
|
||||
nix shell nixpkgs#age -c age-keygen -o ~/Keys/nix/sops/age-key.txt
|
||||
```
|
||||
|
||||
Note the public key (starts with `age1...`) — it goes in `.sops.yaml`.
|
||||
|
||||
### 4.5 Sops Environment Variable
|
||||
|
||||
Add to `~/.bashrc`:
|
||||
|
||||
```bash
|
||||
echo 'export SOPS_AGE_KEY_FILE=~/Keys/nix/sops/age-key.txt' >> ~/.bashrc
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
### 4.6 Clone the Repositories
|
||||
|
||||
```bash
|
||||
mkdir -p ~/Work/RhemaWave
|
||||
cd ~/Work/RhemaWave
|
||||
git clone git@github.com:Rhema-Wave-Technologies/RhemaWave.git
|
||||
git clone git@github.com:Rhema-Wave-Technologies/NixConfig.git
|
||||
```
|
||||
|
||||
### 4.7 Verify Everything Works
|
||||
|
||||
```bash
|
||||
# Test GitHub access
|
||||
cd ~/Work/RhemaWave/NixConfig
|
||||
nix flake show github:Rhema-Wave-Technologies/NixConfig
|
||||
|
||||
# Test RhemaWave build
|
||||
cd ~/Work/RhemaWave/RhemaWave
|
||||
nix build .#default
|
||||
|
||||
# Test binary runs
|
||||
./result/bin/rhemawave
|
||||
|
||||
# Test secrets decryption
|
||||
cd ~/Work/RhemaWave/NixConfig
|
||||
SOPS_AGE_KEY_FILE=~/Keys/nix/sops/age-key.txt nix shell nixpkgs#sops -c sops secrets.yaml
|
||||
# Should open in editor with plaintext values
|
||||
# Close without saving
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. The RhemaWave Flake (Application)
|
||||
|
||||
Located at `~/Work/RhemaWave/RhemaWave/flake.nix`.
|
||||
|
||||
### Key Points
|
||||
|
||||
- Uses `buildGoModule` with `vendorHash = null` (vendor directory committed to repo)
|
||||
- CGo is enabled (`env.CGO_ENABLED = "1"`)
|
||||
- SDL2 mixer/ttf/image flags are set in `preBuild` via `pkg-config`
|
||||
- The `share/` directory is copied to `$out/share` in `postInstall`
|
||||
- License is set to `unfree` — consumers must set `allowUnfreePredicate`
|
||||
- Exports `nixosModules.default` (the kiosk module) alongside per-system packages and dev shells
|
||||
|
||||
### Flake Outputs
|
||||
|
||||
| Output | Description |
|
||||
|--------|-------------|
|
||||
| `packages.<system>.default` | The RhemaWave binary |
|
||||
| `devShells.<system>.default` | Development shell with Go + SDL2 deps |
|
||||
| `nixosModules.default` | NixOS module for kiosk configuration (greetd, cage, PipeWire, polkit) |
|
||||
|
||||
### The NixOS Module (`nixos/module.nix`)
|
||||
|
||||
Imported via `import ./nixos/module.nix self` — the `self` argument gives the module access to the flake's packages. The module exposes `services.rhemawave.*` options.
|
||||
|
||||
---
|
||||
|
||||
## 6. The NixConfig Flake (Kiosk System)
|
||||
|
||||
Located at `~/Work/RhemaWave/NixConfig/flake.nix`.
|
||||
|
||||
### Flake Inputs
|
||||
|
||||
```nix
|
||||
nixpkgs → github:NixOS/nixpkgs/nixpkgs-unstable
|
||||
disko → github:nix-community/disko
|
||||
nixos-facter → github:numtide/nixos-facter-modules
|
||||
rhemawave → github:Rhema-Wave-Technologies/RhemaWave/dev
|
||||
sops-nix → github:Mic92/sops-nix
|
||||
```
|
||||
|
||||
All inputs follow `nixpkgs` to ensure a single nixpkgs version.
|
||||
|
||||
### System Configuration Modules
|
||||
|
||||
The NixOS system (`rhemawavekiosk`) loads these modules:
|
||||
1. `disko.nixosModules.disko` — disk partitioning
|
||||
2. `rhemawave.nixosModules.default` — RhemaWave kiosk module
|
||||
3. `sops-nix.nixosModules.sops` — secrets management
|
||||
4. `./configuration.nix` — main system config
|
||||
5. Hardware facter report
|
||||
6. Inline module adding `rhemawave.packages.x86_64-linux.default` to `environment.systemPackages`
|
||||
|
||||
---
|
||||
|
||||
## 7. Binary Cache Setup
|
||||
|
||||
### What It Is
|
||||
|
||||
A Nix binary cache is a static HTTP file server with a specific directory structure. When a NixOS machine needs a package, it checks each configured cache by making HTTP GET requests for `.narinfo` files. If found and the signature is valid, it downloads the pre-built `.nar.xz` archive instead of building from source.
|
||||
|
||||
### Directory Structure
|
||||
|
||||
```
|
||||
/var/lib/nix-cache/
|
||||
├── nix-cache-info # Cache metadata
|
||||
├── fv5iinvsldz9l2s8ikm0mw8ykhriad1g.narinfo # Package metadata + signature
|
||||
├── nar/
|
||||
│ └── 1j7d9cif4xjq7i5rw5dmivxyninh7z1cm7zvdknsp8vjd9rjmzkc.nar.xz # Compressed package
|
||||
└── ... (more .narinfo and .nar.xz files)
|
||||
```
|
||||
|
||||
### nix-cache-info
|
||||
|
||||
```
|
||||
StoreDir: /nix/store
|
||||
WantMassQuery: 1
|
||||
Priority: 40
|
||||
```
|
||||
|
||||
This file must exist at the root. `Priority: 40` means this cache is checked after the official NixOS cache (priority 30).
|
||||
|
||||
### Creating the Cache (One-Time)
|
||||
|
||||
If setting up a new cache server:
|
||||
|
||||
```bash
|
||||
# On the server
|
||||
sudo mkdir -p /var/lib/nix-cache
|
||||
cat > /var/lib/nix-cache/nix-cache-info <<EOF
|
||||
StoreDir: /nix/store
|
||||
WantMassQuery: 1
|
||||
Priority: 40
|
||||
EOF
|
||||
```
|
||||
|
||||
Then configure Caddy (see section 8).
|
||||
|
||||
---
|
||||
|
||||
## 8. Caddy Server Configuration
|
||||
|
||||
The web server at `repository.rhemawavetech.com` runs Caddy with a `file_server` directive pointing at the cache directory.
|
||||
|
||||
### Caddyfile
|
||||
|
||||
```caddyfile
|
||||
repository.rhemawavetech.com {
|
||||
root * /var/lib/nix-cache
|
||||
file_server browse
|
||||
}
|
||||
```
|
||||
|
||||
The `browse` directive is optional (useful for debugging). Caddy handles TLS automatically via Let's Encrypt.
|
||||
|
||||
### Verification
|
||||
|
||||
```bash
|
||||
curl https://repository.rhemawavetech.com/nix-cache-info
|
||||
```
|
||||
|
||||
Should return the three-line metadata file.
|
||||
|
||||
---
|
||||
|
||||
## 9. Signing Keys
|
||||
|
||||
### How Signing Works
|
||||
|
||||
1. The developer builds a package with `nix build`
|
||||
2. The store path is signed with the private key: `nix store sign --key-file ...`
|
||||
3. The signed package is exported to cache format: `nix copy --to file:// ...`
|
||||
4. The `.narinfo` file contains a `Sig:` line with the key name and signature
|
||||
5. Client machines verify the signature against the public key in `trusted-public-keys`
|
||||
|
||||
### Key Name
|
||||
|
||||
The key name `repository.rhemawavetech.com-1` is embedded in both the key files and the `.narinfo` signatures. If you generate new keys, use the same naming convention with an incremented number (e.g., `-2`).
|
||||
|
||||
### Generating New Keys
|
||||
|
||||
```bash
|
||||
nix key generate-secret --key-name repository.rhemawavetech.com-1 > cache-priv-key.pem
|
||||
nix key convert-secret-to-public < cache-priv-key.pem > cache-pub-key.pem
|
||||
```
|
||||
|
||||
### Deriving Public Key from Private Key
|
||||
|
||||
```bash
|
||||
nix key convert-secret-to-public < ~/Keys/nix/cache/rhemawave/cache-priv-key.pem
|
||||
```
|
||||
|
||||
This outputs the public key string. It should match what's in every client's `trusted-public-keys`.
|
||||
|
||||
### Current Public Key
|
||||
|
||||
```
|
||||
repository.rhemawavetech.com-1:hbaEpYz5jE9SeNgkF2jAgjMtjXzruj7lEk6Lvx9ll40=
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Sops-Nix Secrets Management
|
||||
|
||||
### How It Works
|
||||
|
||||
1. Secrets are encrypted in `secrets.yaml` using age public keys
|
||||
2. `.sops.yaml` defines which keys can encrypt/decrypt
|
||||
3. Each kiosk's SSH host key is converted to an age key for decryption
|
||||
4. On activation, sops-nix decrypts secrets and places them at `/run/secrets/<name>`
|
||||
|
||||
### .sops.yaml
|
||||
|
||||
```yaml
|
||||
keys:
|
||||
- &admin age1ptpn9zee8x7vjaaktx9dv65vysdjfmmgtj96wc3l49vd8g8huy6syk8l26
|
||||
- &kiosk-dev age1nmn0r66hl24wrz73q5htt0r90vfse9dvyjwae2evqwrealfgycfsy3apmy
|
||||
creation_rules:
|
||||
- path_regex: secrets\.yaml$
|
||||
key_groups:
|
||||
- age:
|
||||
- *admin
|
||||
- *kiosk-dev
|
||||
```
|
||||
|
||||
### Adding a New Kiosk
|
||||
|
||||
1. Get the kiosk's SSH host public key:
|
||||
```bash
|
||||
ssh root@KIOSK_IP "cat /etc/ssh/ssh_host_ed25519_key.pub"
|
||||
```
|
||||
|
||||
2. Convert to age key:
|
||||
```bash
|
||||
nix shell nixpkgs#ssh-to-age -c ssh-to-age < <(ssh root@KIOSK_IP "cat /etc/ssh/ssh_host_ed25519_key.pub")
|
||||
```
|
||||
|
||||
3. Add the age key to `.sops.yaml` under `keys:` with a descriptive anchor (e.g., `&kiosk-prod-001`)
|
||||
|
||||
4. Add the anchor reference to the creation rule's age list
|
||||
|
||||
5. Re-encrypt secrets with the new key:
|
||||
```bash
|
||||
SOPS_AGE_KEY_FILE=~/Keys/nix/sops/age-key.txt nix shell nixpkgs#sops -c sops updatekeys secrets.yaml
|
||||
```
|
||||
|
||||
6. Commit and push `.sops.yaml` and `secrets.yaml`
|
||||
|
||||
### Editing Secrets
|
||||
|
||||
```bash
|
||||
cd ~/Work/RhemaWave/NixConfig
|
||||
SOPS_AGE_KEY_FILE=~/Keys/nix/sops/age-key.txt nix shell nixpkgs#sops -c sops secrets.yaml
|
||||
```
|
||||
|
||||
The file opens in your editor with plaintext values. Edit, save, close — sops re-encrypts automatically.
|
||||
|
||||
### Secret Format for github-token
|
||||
|
||||
The `github-token` secret must contain the full nix.conf line (because it's included via `!include`):
|
||||
|
||||
```yaml
|
||||
github-token: "access-tokens = github.com=ghp_yourtokenhere"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. GitHub Access
|
||||
|
||||
### Developer Machine
|
||||
|
||||
The token is stored in `~/.config/nix/nix.conf`:
|
||||
|
||||
```
|
||||
access-tokens = github.com=YOUR_TOKEN_HERE
|
||||
```
|
||||
|
||||
Also needs to be in `/root/.config/nix/nix.conf` for `sudo` operations.
|
||||
|
||||
Flake URLs use the `github:` scheme (not `git+https://`), which reads the `access-tokens` setting.
|
||||
|
||||
### Kiosk Machines
|
||||
|
||||
The token is managed via sops-nix and included in `nix.conf` via `!include /run/secrets/github-token`.
|
||||
|
||||
### Token Scope
|
||||
|
||||
Fine-grained personal access token:
|
||||
- Resource owner: `Rhema-Wave-Technologies`
|
||||
- Repositories: `NixConfig`, `RhemaWave`
|
||||
- Permissions: Contents → Read-only
|
||||
|
||||
---
|
||||
|
||||
## 12. Building and Publishing a New Release
|
||||
|
||||
Complete procedure, every command, in order. All commands run on your development machine.
|
||||
|
||||
### Step 1: Commit Application Changes
|
||||
|
||||
```bash
|
||||
cd ~/Work/RhemaWave/RhemaWave
|
||||
|
||||
# If go.mod/go.sum changed:
|
||||
nix shell nixpkgs#go -c go mod vendor
|
||||
git add vendor/
|
||||
|
||||
git add -A
|
||||
git commit -m "your changes"
|
||||
git push origin dev
|
||||
```
|
||||
|
||||
### Step 2: Build
|
||||
|
||||
```bash
|
||||
nix build .#default
|
||||
```
|
||||
|
||||
### Step 3: Sign
|
||||
|
||||
```bash
|
||||
nix store sign --key-file ~/Keys/nix/cache/rhemawave/cache-priv-key.pem $(nix path-info ./result)
|
||||
```
|
||||
|
||||
### Step 4: Export to Cache Format
|
||||
|
||||
```bash
|
||||
rm -rf /tmp/nix-cache
|
||||
nix copy --to file:///tmp/nix-cache ./result --secret-key-files ~/Keys/nix/cache/rhemawave/cache-priv-key.pem
|
||||
```
|
||||
|
||||
### Step 5: Verify Signature
|
||||
|
||||
```bash
|
||||
cat /tmp/nix-cache/*.narinfo | grep Sig
|
||||
```
|
||||
|
||||
Must show `Sig: repository.rhemawavetech.com-1:...`
|
||||
|
||||
### Step 6: Upload to Server
|
||||
|
||||
```bash
|
||||
rsync -av /tmp/nix-cache/ YOUR_USER@your-server:/var/lib/nix-cache/
|
||||
```
|
||||
|
||||
### Step 7: Bump NixConfig
|
||||
|
||||
```bash
|
||||
cd ~/Work/RhemaWave/NixConfig
|
||||
nix flake update rhemawave
|
||||
git add flake.lock
|
||||
git commit -m "bump rhemawave"
|
||||
git push
|
||||
```
|
||||
|
||||
### Step 8: Wait
|
||||
|
||||
Kiosks pick up the update within 15 minutes via the auto-update timer.
|
||||
|
||||
---
|
||||
|
||||
## 13. Deploying a New Kiosk (nixos-anywhere)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Target machine booted from NixOS installer USB
|
||||
- SSH access to the target as root
|
||||
- Target's IP address known
|
||||
|
||||
### Procedure
|
||||
|
||||
From your development machine:
|
||||
|
||||
```bash
|
||||
cd ~/Work/RhemaWave/NixConfig
|
||||
|
||||
# Deploy
|
||||
nix run github:nix-community/nixos-anywhere -- --flake .#rhemawavekiosk root@TARGET_IP
|
||||
```
|
||||
|
||||
This:
|
||||
1. kexec's into the NixOS installer on the target
|
||||
2. Partitions the disk according to `disk-config.nix`
|
||||
3. Installs NixOS with the full kiosk configuration
|
||||
4. Reboots
|
||||
|
||||
**Note:** Uses the local flake (`.#`) so it can access local files and secrets. The `--flake` path must be the NixConfig directory.
|
||||
|
||||
### After Deployment
|
||||
|
||||
1. Get the kiosk's age key (see section 10, "Adding a New Kiosk")
|
||||
2. Add it to `.sops.yaml` and re-encrypt secrets
|
||||
3. Push changes
|
||||
4. The kiosk will pick up the updated secrets on its next auto-update cycle
|
||||
|
||||
### If nixos-rebuild --target-host Fails with Bootloader Errors
|
||||
|
||||
Use the manual three-step deploy instead:
|
||||
|
||||
```bash
|
||||
nix build .#nixosConfigurations.rhemawavekiosk.config.system.build.toplevel
|
||||
nix copy --to ssh://root@TARGET_IP ./result
|
||||
ssh root@TARGET_IP "$(readlink -f ./result)/bin/switch-to-configuration switch"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 14. Auto-Update System
|
||||
|
||||
### How It Works
|
||||
|
||||
Each kiosk runs a systemd timer (`kiosk-auto-update.timer`) that fires every 15 minutes. The associated service runs:
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch --flake github:Rhema-Wave-Technologies/NixConfig#rhemawavekiosk
|
||||
```
|
||||
|
||||
This:
|
||||
1. Fetches the latest NixConfig flake from GitHub (using the encrypted GitHub token)
|
||||
2. Evaluates the configuration (including the pinned RhemaWave version from `flake.lock`)
|
||||
3. Checks the binary cache for pre-built packages
|
||||
4. Downloads any new packages
|
||||
5. Switches to the new configuration
|
||||
|
||||
### What Triggers an Update
|
||||
|
||||
An update is triggered when either:
|
||||
- `flake.lock` changes (new RhemaWave version pinned)
|
||||
- `configuration.nix` or other NixConfig files change
|
||||
- Any flake input is updated
|
||||
|
||||
If nothing has changed, `nixos-rebuild` is a no-op.
|
||||
|
||||
### Monitoring
|
||||
|
||||
```bash
|
||||
# Check timer status
|
||||
ssh root@KIOSK_IP "systemctl status kiosk-auto-update.timer"
|
||||
|
||||
# Check last update result
|
||||
ssh root@KIOSK_IP "systemctl status kiosk-auto-update.service"
|
||||
|
||||
# Full update logs
|
||||
ssh root@KIOSK_IP "journalctl -u kiosk-auto-update -n 100"
|
||||
```
|
||||
|
||||
### Force Immediate Update
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP "systemctl start kiosk-auto-update"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 15. Testing and Debugging
|
||||
|
||||
### SSH into a Running Kiosk
|
||||
|
||||
Even with the kiosk locked down (cage compositor, single TTY), SSH always works:
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP
|
||||
```
|
||||
|
||||
### Check What's Running
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP "systemctl status greetd"
|
||||
ssh root@KIOSK_IP "systemctl status kiosk-auto-update.timer"
|
||||
ssh root@KIOSK_IP "ls -la /run/secrets/"
|
||||
ssh root@KIOSK_IP "cat /run/secrets/wifi-psk" # verify decryption
|
||||
```
|
||||
|
||||
### Check Binary Cache Connectivity
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP "curl -s https://repository.rhemawavetech.com/nix-cache-info"
|
||||
```
|
||||
|
||||
### Check GitHub Connectivity
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP "cat /etc/nix/nix.conf | grep access-tokens"
|
||||
```
|
||||
|
||||
### Restart the Kiosk Application
|
||||
|
||||
If the application crashes or you want to restart it without a full reboot:
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP "systemctl restart greetd"
|
||||
```
|
||||
|
||||
greetd will restart, auto-login the kiosk user, and re-launch rhemawave in cage.
|
||||
|
||||
### View Application Logs
|
||||
|
||||
```bash
|
||||
ssh root@KIOSK_IP "journalctl -u greetd -n 100"
|
||||
```
|
||||
|
||||
### Test a Configuration Change Without Pushing
|
||||
|
||||
Build and deploy directly from your development machine:
|
||||
|
||||
```bash
|
||||
cd ~/Work/RhemaWave/NixConfig
|
||||
nix build .#nixosConfigurations.rhemawavekiosk.config.system.build.toplevel
|
||||
nix copy --to ssh://root@KIOSK_IP ./result
|
||||
ssh root@KIOSK_IP "$(readlink -f ./result)/bin/switch-to-configuration switch"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 16. Common Errors and Solutions
|
||||
|
||||
### `env attribute set cannot contain any attributes passed to derivation`
|
||||
|
||||
**Cause:** `CGO_ENABLED` set as both a top-level attribute and in `env`.
|
||||
**Fix:** Use only `env.CGO_ENABLED = "1";` in the `buildGoModule` block.
|
||||
|
||||
### `vendor/modules.txt` inconsistency
|
||||
|
||||
**Cause:** `go.mod` changed but `vendor/` wasn't updated.
|
||||
**Fix:** Run `nix shell nixpkgs#go -c go mod vendor`, then `git add vendor/` and commit.
|
||||
|
||||
### `unfree license, refusing to evaluate`
|
||||
|
||||
**Cause:** Missing `allowUnfreePredicate` in the nixpkgs config.
|
||||
**Fix:** Add `config.allowUnfreePredicate = pkg: (nixpkgs.lib.getName pkg) == "rhemawave";` to the `pkgs` import.
|
||||
|
||||
### `warning: ignoring the client-specified setting 'secret-key-files'`
|
||||
|
||||
**Cause:** Your user isn't in `trusted-users`.
|
||||
**Fix:** Add your username to `nix.settings.trusted-users` and rebuild your NixOS system.
|
||||
|
||||
### `invalid character in Base64 string`
|
||||
|
||||
**Cause:** The `trusted-public-keys` value is malformed — likely doubled key name or invisible characters.
|
||||
**Fix:** Regenerate the public key: `nix key convert-secret-to-public < cache-priv-key.pem` and paste it fresh into the config.
|
||||
|
||||
### `attribute 'nixosModules' missing`
|
||||
|
||||
**Cause:** The `flake.lock` points to an old RhemaWave commit that doesn't export `nixosModules`.
|
||||
**Fix:** Run `nix flake update rhemawave` in the NixConfig directory.
|
||||
|
||||
### `path '/home/...' is forbidden in pure evaluation mode`
|
||||
|
||||
**Cause:** Using absolute paths (like `builtins.readFile /home/...`) in a flake. Flakes evaluate in pure mode.
|
||||
**Fix:** Use relative paths (`./file.txt`) or manage secrets with sops-nix.
|
||||
|
||||
### `access to absolute path '/home' is forbidden`
|
||||
|
||||
**Cause:** Same as above — `readFile` with an absolute path.
|
||||
**Fix:** Use sops-nix for secrets or deploy with the local flake (`.#`) instead of `github:`.
|
||||
|
||||
### Bootloader errors during remote `nixos-rebuild --target-host`
|
||||
|
||||
**Cause:** GRUB can't detect the disk layout properly over SSH.
|
||||
**Fix:** Use the three-step manual deploy: `nix build` → `nix copy --to ssh://` → `switch-to-configuration switch`.
|
||||
|
||||
### SSH host key changed warning
|
||||
|
||||
**Cause:** After reinstalling a kiosk, its SSH host key changes.
|
||||
**Fix:** `ssh-keygen -R KIOSK_IP` to remove the old key, then reconnect.
|
||||
|
||||
### Auto-update not working on kiosk
|
||||
|
||||
**Check:**
|
||||
1. Timer is active: `systemctl status kiosk-auto-update.timer`
|
||||
2. Service logs: `journalctl -u kiosk-auto-update -n 50`
|
||||
3. GitHub token is decrypted: `cat /etc/nix/nix.conf | grep access-tokens`
|
||||
4. Network connectivity: `curl https://github.com`
|
||||
5. Cache connectivity: `curl https://repository.rhemawavetech.com/nix-cache-info`
|
||||
Reference in New Issue
Block a user