nftable-migration
1#+TITLE: Imperative Configuration
2#+FILETAGS: imperative configuration scripts
3
4Idempotent configuration scripts for systems not managed by NixOS.
5
6* Overview
7
8This directory contains configuration scripts for hosts that cannot or do not use NixOS. Unlike the declarative NixOS configurations in =/systems=, these scripts use an imperative approach but are designed to be idempotent - safe to run multiple times.
9
10** Philosophy
11
12While NixOS provides declarative configuration management, some systems need to use traditional Linux distributions for various reasons:
13- Hardware compatibility requirements
14- Organizational constraints
15- Testing different distributions
16- Transition periods before migrating to NixOS
17
18These scripts bridge the gap by providing repeatable, documented configuration management for non-NixOS systems.
19
20** Key Principles
21
221. *Idempotent* - Scripts can be run multiple times safely
232. *Self-contained* - Each host directory is independent
243. *Documented* - Each host has a README explaining its setup
254. *Versioned* - Configuration is tracked in git like NixOS configs
26
27* Directory Structure
28
29Each host has its own directory containing:
30
31#+begin_example
32imperative/
33├── README.org # This file
34├── nagoya/ # Debian server
35│ ├── README.org # Host-specific documentation
36│ └── apply.sh # Main configuration script
37└── wakasu/ # Fedora desktop
38 ├── README.org # Host-specific documentation
39 └── apply.sh # Main configuration script
40#+end_example
41
42* Current Hosts
43
44** nagoya - Debian Server
45- *OS:* Debian (aarch64)
46- *Type:* Server
47- *Components:* Docker, Kind, Wireguard, Syncthing
48- *VPN IP:* 10.100.0.80/24
49
50See [[file:nagoya/README.org][nagoya/README.org]] for details.
51
52** wakasu - Fedora Desktop
53- *OS:* Fedora
54- *Type:* Desktop
55- *User:* vincent
56- *Components:* Helix, ACPI, Wireguard, Syncthing
57- *VPN IP:* 10.100.0.90/24
58
59See [[file:wakasu/README.org][wakasu/README.org]] for details.
60
61* Usage
62
63** Running Configuration Scripts
64
65From the repository root:
66
67#+begin_src bash
68# Apply configuration for a specific host
69sudo ./imperative/<hostname>/apply.sh
70
71# With environment variables (e.g., for wireguard)
72sudo WG_PRIVATE_KEY="..." ./imperative/<hostname>/apply.sh
73#+end_src
74
75** Adding a New Host
76
771. Create a new directory for the host:
78 #+begin_src bash
79 mkdir imperative/<hostname>
80 #+end_src
81
822. Create an =apply.sh= script following the existing patterns:
83 - Use =set -euo pipefail= for safety
84 - Implement colored logging functions
85 - Make functions idempotent
86 - Use =setup.*= naming convention for functions
87
883. Create a =README.org= documenting:
89 - System information
90 - Components installed
91 - Usage instructions
92 - Environment variables needed
93
944. Make the script executable:
95 #+begin_src bash
96 chmod +x imperative/<hostname>/apply.sh
97 #+end_src
98
995. Update this README to include the new host
100
101** Testing Scripts
102
103Test scripts in a VM or container before running on production systems:
104
105#+begin_src bash
106# Example with Docker
107docker run -it --rm -v $(pwd):/repo debian:latest
108cd /repo
109./imperative/<hostname>/apply.sh
110#+end_src
111
112* Script Conventions
113
114** Error Handling
115
116All scripts use strict error handling:
117#+begin_src bash
118set -euo pipefail
119#+end_src
120
121This ensures:
122- =set -e= - Exit on any error
123- =set -u= - Exit on undefined variable
124- =set -o pipefail= - Catch errors in pipes
125
126** Logging
127
128Use colored logging functions for clarity:
129
130#+begin_src bash
131log_info "Normal operation message"
132log_warn "Warning message"
133log_error "Error message"
134#+end_src
135
136** Function Naming
137
138Use =setup.*= prefix for setup functions:
139
140#+begin_src bash
141setup.docker() { ... }
142setup.wireguard() { ... }
143setup.syncthing() { ... }
144#+end_src
145
146** Environment Variables
147
148- Document all required environment variables in the host's README
149- Provide sensible defaults where possible
150- Fail gracefully or warn when optional variables are missing
151
152** Idempotency
153
154Make operations idempotent by:
155- Checking if software is already installed
156- Using =||= for commands that might fail on re-run
157- Avoiding destructive operations
158- Using configuration management tools when available
159
160* Integration with NixOS Configs
161
162While these scripts are imperative, they share concepts with the NixOS configurations:
163
164- *Wireguard configuration* matches the network topology in =globals.nix=
165- *Syncthing* IDs should be coordinated with NixOS hosts
166- *VPN IP addressing* follows the same scheme (10.100.0.0/24)
167
168* Transitioning to NixOS
169
170When ready to migrate a host to NixOS:
171
1721. Document the current system state using the imperative script as reference
1732. Create a new NixOS configuration in =/systems/<hostname>=
1743. Test the NixOS configuration in a VM
1754. Perform the migration
1765. Archive or remove the imperative configuration
177
178* Maintenance
179
180** Updating Scripts
181
182When updating scripts:
183
1841. Test changes in a VM or non-production system
1852. Update the host's README if behavior changes
1863. Run shellcheck to catch common issues:
187 #+begin_src bash
188 shellcheck imperative/<hostname>/apply.sh
189 #+end_src
190
191** Version Control
192
193All changes to imperative configurations should be:
194- Committed to git
195- Documented in commit messages
196- Tagged if significant milestones are reached
197
198* Comparison: Imperative vs NixOS
199
200| Aspect | Imperative (this directory) | NixOS (=/systems=) |
201|------------------+-----------------------------+---------------------------|
202| *Approach* | Scripts to reach state | Declare desired state |
203| *Idempotency* | Manual (via careful coding) | Automatic |
204| *Rollback* | Manual/difficult | Built-in generations |
205| *Reproducibility* | Best effort | Guaranteed |
206| *Documentation* | README + comments | Code is documentation |
207| *OS Support* | Any Linux distro | NixOS only |
208| *Learning Curve* | Familiar bash scripts | Steeper (Nix language) |
209| *State Management* | Imperative commands | Declarative configuration |
210
211* Resources
212
213** Similar Approaches
214- Ansible playbooks (declarative automation)
215- Chef/Puppet recipes (configuration management)
216- Shell scripts (traditional approach)
217
218** Why Not Use These Tools?
219
220For simple single-host configurations, a well-written bash script:
221- Has no dependencies beyond bash and standard tools
222- Is easy to understand and modify
223- Runs quickly without agent overhead
224- Keeps everything in this repository
225
226For managing many similar hosts, consider tools like Ansible.