Skip to content

Commit dece49e

Browse files
authored
feat: implement migration tool for legacy configuration to homelab.yaml (#42)
1 parent eece54f commit dece49e

2 files changed

Lines changed: 955 additions & 0 deletions

File tree

Lines changed: 382 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,382 @@
1+
# Migration Guide: Legacy Configuration to homelab.yaml
2+
3+
**Purpose**: Guide for migrating from legacy multi-file configuration (`services.yaml` + `machines.yml` + `volumes.yaml` + `.env`) to the unified `homelab.yaml` format.
4+
5+
## Overview
6+
7+
The migration tool automatically converts your existing configuration files to the new unified `homelab.yaml` format, preserving all essential service definitions and deployment settings while simplifying the overall configuration structure.
8+
9+
## What Gets Migrated
10+
11+
### Input Files (Legacy Format)
12+
- **`config/services.yaml`** - Service definitions, container configs, and deployment settings
13+
- **`machines.yml`** - Multi-node infrastructure definitions (managers/workers)
14+
- **`config/volumes.yaml`** - Storage and volume configurations
15+
- **`.env`** - Environment variables and secrets
16+
17+
### Output File (New Format)
18+
- **`homelab.yaml`** - Unified configuration with all settings
19+
20+
## Migration Process
21+
22+
### Basic Migration
23+
24+
```bash
25+
# Dry run to preview changes
26+
./scripts/migrate_to_homelab_yaml.sh --dry-run
27+
28+
# Migrate to default homelab.yaml
29+
./scripts/migrate_to_homelab_yaml.sh
30+
31+
# Migrate for Docker Swarm deployment
32+
./scripts/migrate_to_homelab_yaml.sh --deployment docker_swarm
33+
```
34+
35+
### Migration Options
36+
37+
| Option | Description | Example |
38+
|--------|-------------|---------|
39+
| `--dry-run` | Preview migration without creating files | `--dry-run` |
40+
| `--deployment TYPE` | Target deployment type | `--deployment docker_swarm` |
41+
| `--output FILE` | Custom output file | `--output my-config.yaml` |
42+
| `--force` | Overwrite existing output file | `--force` |
43+
| `--validate` | Validate output after migration | `--validate` |
44+
| `--services FILE` | Custom services file | `--services custom-services.yaml` |
45+
| `--machines FILE` | Custom machines file | `--machines custom-machines.yml` |
46+
47+
### Advanced Migration
48+
49+
```bash
50+
# Custom input files with validation
51+
./scripts/migrate_to_homelab_yaml.sh \
52+
--services config/my-services.yaml \
53+
--machines my-machines.yml \
54+
--output production-homelab.yaml \
55+
--deployment docker_swarm \
56+
--validate \
57+
--force
58+
59+
# Preview complex migration
60+
./scripts/migrate_to_homelab_yaml.sh \
61+
--dry-run \
62+
--deployment docker_compose \
63+
--services config/services.yaml
64+
```
65+
66+
## Migration Mapping
67+
68+
### Services Configuration
69+
70+
#### Legacy Format (`services.yaml`)
71+
```yaml
72+
services:
73+
actual:
74+
name: Actual Budget
75+
port: 5006
76+
compose:
77+
image: actualbudget/actual-server:latest
78+
ports: ["5006:5006"]
79+
environment:
80+
- DEBUG=actual:config
81+
volumes:
82+
- /media/external/budget:/data
83+
nginx:
84+
upstream: actual_server:5006
85+
enabled: true
86+
```
87+
88+
#### New Format (`homelab.yaml`)
89+
```yaml
90+
services:
91+
actual:
92+
image: actualbudget/actual-server:latest
93+
port: 5006
94+
storage: true
95+
environment:
96+
DEBUG: "actual:config"
97+
overrides:
98+
docker_compose:
99+
volumes:
100+
- "/media/external/budget:/data"
101+
```
102+
103+
### Machine Configuration
104+
105+
#### Legacy Format (`machines.yml`)
106+
```yaml
107+
managers:
108+
- hostname: "manager1.local"
109+
ip: "192.168.1.100"
110+
user: "ubuntu"
111+
role: "manager"
112+
labels:
113+
environment: "production"
114+
115+
workers:
116+
- hostname: "worker1.local"
117+
ip: "192.168.1.101"
118+
user: "ubuntu"
119+
role: "worker"
120+
```
121+
122+
#### New Format (`homelab.yaml`)
123+
```yaml
124+
machines:
125+
manager1:
126+
host: 192.168.1.100
127+
user: ubuntu
128+
role: manager
129+
labels:
130+
- "environment=production"
131+
132+
worker1:
133+
host: 192.168.1.101
134+
user: ubuntu
135+
role: worker
136+
```
137+
138+
### Environment Variables
139+
140+
#### Legacy Format (`.env`)
141+
```bash
142+
BASE_DOMAIN=homelab.local
143+
PROJECT_ROOT=/opt/homelab
144+
DB_PASSWORD=secret123
145+
```
146+
147+
#### New Format (`homelab.yaml`)
148+
```yaml
149+
environment:
150+
BASE_DOMAIN: homelab.local
151+
PROJECT_ROOT: /opt/homelab
152+
DB_PASSWORD: secret123
153+
```
154+
155+
## Migration Behavior
156+
157+
### Service Processing
158+
1. **Image Extraction**: Pulls from `compose.image` or `container.image`
159+
2. **Port Detection**: Uses `port` field or extracts from `compose.ports`
160+
3. **Storage Detection**: Sets `storage: true` if volumes are present
161+
4. **Environment Variables**: Converts arrays and objects to unified format
162+
5. **Complex Configurations**: Moves to `overrides` section
163+
164+
### Machine Processing
165+
1. **Name Generation**: Creates machine names from hostnames (removes domain)
166+
2. **Role Assignment**: Preserves manager/worker roles for Docker Swarm
167+
3. **Label Conversion**: Converts key-value objects to "key=value" array format
168+
4. **Default Creation**: Creates `driver: localhost` if no machines file exists
169+
170+
### Environment Processing
171+
1. **Variable Export**: Loads all environment variables for template expansion
172+
2. **Readonly Handling**: Skips `UID` and `GID` to avoid conflicts
173+
3. **Quote Removal**: Strips quotes from values
174+
4. **Comment Filtering**: Ignores commented and empty lines
175+
176+
## Migration Results
177+
178+
### Successful Migration Output
179+
```bash
180+
[INFO] Starting migration from legacy configuration to homelab.yaml
181+
[INFO] Target deployment type: docker_compose
182+
[INFO] Processing machines configuration from machines.yml
183+
[INFO] Processing environment variables from .env
184+
[INFO] Processing services configuration from config/services.yaml
185+
[INFO] Processing service: actual
186+
[INFO] Processing service: homepage
187+
[SUCCESS] Migration completed successfully
188+
[INFO] Generated: homelab.yaml
189+
190+
Next steps:
191+
1. Review the generated homelab.yaml
192+
2. Validate: ./scripts/simple_homelab_validator.sh homelab.yaml
193+
3. Test deployment with new configuration
194+
4. Backup and remove legacy files when satisfied
195+
```
196+
197+
### Common Issues and Solutions
198+
199+
#### Issue: yq Parsing Errors
200+
**Symptoms**: Multiple parsing errors during migration
201+
**Cause**: Complex YAML structures or malformed configuration
202+
**Solution**: Check original YAML files for syntax errors
203+
204+
```bash
205+
# Validate original files
206+
yq . config/services.yaml
207+
yq . machines.yml
208+
yq . config/volumes.yaml
209+
```
210+
211+
#### Issue: Missing Services
212+
**Symptoms**: Some services not included in output
213+
**Cause**: Services marked as `enabled: false`
214+
**Solution**: Enable services or manually add them
215+
216+
```yaml
217+
# In services.yaml, ensure:
218+
services:
219+
myservice:
220+
enabled: true # Make sure this is true
221+
```
222+
223+
#### Issue: Complex Configurations Lost
224+
**Symptoms**: Advanced Docker configurations missing
225+
**Cause**: Migration simplified complex setups
226+
**Solution**: Review `overrides` section and add missing configurations
227+
228+
```yaml
229+
# Add missing configurations to overrides
230+
services:
231+
myservice:
232+
overrides:
233+
docker_compose:
234+
depends_on: ["database"]
235+
networks: ["custom"]
236+
restart: unless-stopped
237+
```
238+
239+
#### Issue: Machine Names Incorrect
240+
**Symptoms**: Generated machine names don't match expectations
241+
**Cause**: Automatic name generation from hostnames
242+
**Solution**: Manually adjust machine names in output
243+
244+
```yaml
245+
# Change from:
246+
machines:
247+
manager1local: # Auto-generated
248+
host: 192.168.1.100
249+
250+
# To:
251+
machines:
252+
manager-01: # Manually adjusted
253+
host: 192.168.1.100
254+
```
255+
256+
## Post-Migration Tasks
257+
258+
### 1. Validation
259+
```bash
260+
# Validate generated configuration
261+
./scripts/simple_homelab_validator.sh homelab.yaml
262+
263+
# Or with full schema validation (if available)
264+
./scripts/validate_homelab_schema.sh homelab.yaml
265+
```
266+
267+
### 2. Review and Adjust
268+
- **Service Names**: Ensure they match your preferences
269+
- **Machine Names**: Adjust to your naming convention
270+
- **Port Mappings**: Verify all ports are correctly extracted
271+
- **Storage Paths**: Check that volume mappings are preserved
272+
- **Environment Variables**: Confirm all secrets are included
273+
274+
### 3. Test Deployment
275+
```bash
276+
# Test with new configuration (future implementation)
277+
./selfhosted.sh deploy --config homelab.yaml --dry-run
278+
```
279+
280+
### 4. Backup Legacy Files
281+
```bash
282+
# Create backup directory
283+
mkdir -p backups/legacy-config-$(date +%Y%m%d)
284+
285+
# Backup original files
286+
cp config/services.yaml backups/legacy-config-$(date +%Y%m%d)/
287+
cp machines.yml backups/legacy-config-$(date +%Y%m%d)/ 2>/dev/null || true
288+
cp config/volumes.yaml backups/legacy-config-$(date +%Y%m%d)/
289+
cp .env backups/legacy-config-$(date +%Y%m%d)/ 2>/dev/null || true
290+
```
291+
292+
## Migration Examples
293+
294+
### Example 1: Basic Single-Machine Setup
295+
```bash
296+
# Legacy: services.yaml only
297+
./scripts/migrate_to_homelab_yaml.sh --dry-run
298+
299+
# Result: Simple homelab.yaml with driver machine
300+
```
301+
302+
### Example 2: Multi-Node Docker Compose
303+
```bash
304+
# Legacy: services.yaml + machines.yml
305+
./scripts/migrate_to_homelab_yaml.sh \
306+
--deployment docker_compose \
307+
--validate
308+
```
309+
310+
### Example 3: Docker Swarm Cluster
311+
```bash
312+
# Legacy: Full configuration with swarm settings
313+
./scripts/migrate_to_homelab_yaml.sh \
314+
--deployment docker_swarm \
315+
--output swarm-homelab.yaml \
316+
--validate
317+
```
318+
319+
## Troubleshooting
320+
321+
### Debug Migration Issues
322+
```bash
323+
# Run with verbose debugging
324+
bash -x ./scripts/migrate_to_homelab_yaml.sh --dry-run 2>&1 | less
325+
326+
# Check specific file issues
327+
yq '.services.problematic_service' config/services.yaml
328+
```
329+
330+
### Manual Migration Steps
331+
If automatic migration fails, you can manually create sections:
332+
333+
1. **Start with basic structure**:
334+
```yaml
335+
version: "2.0"
336+
deployment: docker_compose
337+
environment: {}
338+
machines: {}
339+
services: {}
340+
```
341+
342+
2. **Copy services one by one** from legacy configuration
343+
3. **Validate each addition** using the validation script
344+
4. **Test incrementally** to identify issues
345+
346+
### Getting Help
347+
- **Validation Errors**: Use the validation tools to identify specific issues
348+
- **Complex Configurations**: Review the homelab.yaml reference documentation
349+
- **Migration Bugs**: Check that input files have valid YAML syntax
350+
351+
## Best Practices
352+
353+
### Before Migration
354+
1. **Backup Everything**: Ensure you have backups of all configuration files
355+
2. **Test Environment**: Run migration in a test environment first
356+
3. **Document Customizations**: Note any custom configurations that need manual handling
357+
358+
### During Migration
359+
1. **Use Dry Run**: Always preview changes before applying
360+
2. **Validate Output**: Use validation tools to check generated configuration
361+
3. **Review Carefully**: Examine the generated file for accuracy
362+
363+
### After Migration
364+
1. **Test Thoroughly**: Verify all services work with new configuration
365+
2. **Monitor Deployment**: Watch for any issues in the first deployment
366+
3. **Keep Backups**: Retain legacy files until confident in new setup
367+
368+
## Migration Checklist
369+
370+
- [ ] Backup all legacy configuration files
371+
- [ ] Run migration with `--dry-run` to preview changes
372+
- [ ] Review generated `homelab.yaml` for accuracy
373+
- [ ] Validate configuration using validation tools
374+
- [ ] Test deployment in staging environment
375+
- [ ] Migrate production environment
376+
- [ ] Verify all services are working correctly
377+
- [ ] Archive legacy configuration files
378+
- [ ] Update documentation and procedures
379+
380+
---
381+
382+
**Note**: The migration tool handles most common configurations automatically, but complex setups may require manual adjustments. Always review the generated configuration before deploying to production.

0 commit comments

Comments
 (0)