Subversion Repositories perlutils

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 rodolico 1
# perlConfigFileUtility
2
 
3
A Perl utility for managing configuration files with template merging, interactive editing, and format conversion capabilities.
4
 
5
## Overview
6
 
7
`perlConfigFileUtility` is designed to simplify configuration file management by:
8
- Merging template structures with existing configuration files
9
- Providing an interactive hierarchical editor for modifying configurations
10
- Converting between YAML and JSON formats
11
- Automatically backing up config files when saving changes
12
 
13
## Background
14
 
15
This utility solves two primary problems:
16
 
17
1. **User-Friendly Editing**: Enables users unfamiliar with JSON/YAML syntax to safely edit configuration files through an interactive interface.
18
 
19
2. **Version Compatibility**: Handles configuration file evolution across software versions. When new key/value pairs are added to the application, the utility merges them with existing config files, ensuring older configurations remain compatible with newer software.
20
 
21
### Implementation Approach
22
 
23
- Default configuration is stored as a Perl data structure in a separate file (loaded via `do` statement in project script)
24
- This template can be shared across multiple applications
25
- The utility loads existing YAML/JSON configs, merges missing values from the template, and presents an interactive editor
26
- Format conversion (YAML ↔ JSON) was added as a natural extension of the merge functionality
27
 
28
## Features
29
 
30
- **Template Merging**: Combine Perl data structure templates with existing YAML/JSON config files
31
- **Interactive Editor**: Navigate and edit nested hashes and arrays with a menu-driven interface
32
- **Dynamic Modifications**: Add new keys to hashes and elements to arrays on the fly
6 rodolico 33
- **Rename Keys**: Rename hash keys while preserving their values in interactive edit mode
2 rodolico 34
- **Delete Operations**: Remove keys from hashes and elements from arrays, including all nested children
6 rodolico 35
- **Config Comparison**: Load and compare multiple config files to identify differences
2 rodolico 36
- **Format Conversion**: Seamlessly convert between YAML and JSON configuration formats
37
- **Safe Updates**: Automatic backup creation before saving changes
38
 
39
## Usage
40
 
41
```bash
42
# Basic usage
6 rodolico 43
perlConfigFileUtility [-t <template_file>] [-c <config_file>] [-o <output_file>] [-e] [-C]
2 rodolico 44
 
45
# Positional arguments (backward compatibility)
46
perlConfigFileUtility <template_file> [config_file]
6 rodolico 47
 
48
# Compare multiple config files
49
perlConfigFileUtility -C -c <file1> -c <file2> [-c <file3> ...]
2 rodolico 50
```
51
 
3 rodolico 52
## Example of template file
53
 
54
The template file is a Perl hash reference that defines the complete configuration structure with default values and inline documentation. Below is a simplified excerpt from the `sneakernet` project's datastructure file (see `../zfs_utils/sneakernet/sneakernet.datastructure` for the full example).
55
 
56
```perl
57
# Default configuration structure for sneakernet
58
# This file is loaded by the sneakernet script to provide default configuration values
59
# Variables from $programDefinition hashref (scriptDirectory, scriptFullPath) will be interpolated at runtime
60
 
61
{
62
   'dryrun' => 0, # if set to 1, will not perform any changes, just log what would be done
63
   'verbosity' => 1, # verbosity level for logging
64
   'debug' => 0, # set to number greater than 0 for debugging program
65
   'status_file' => "<scriptDirectory>/sneakernet_target.status", # file created on source server to track last copied dataset
66
   'log_file' => "<scriptFullPath>.log",
67
   'displayLogsOnTTY' => '', # if set to path of a tty, log messages will be sent there also. Example: /dev/ttyv1
68
   'displayLogsOnConsole' => 1, # If set to non-zero, will send log messages to screen in addition to log file
69
   'source' => { # information about source server
70
      'hostname' => '', # used to see if we are on source
71
      'poolname' => 'pool', # name of the ZFS default parent pool to export
72
      'cleanUpScriptsDir' => '<scriptDirectory>/cleanupScripts', # location on disk where scripts to be sent to target are located
73
      'report' => { # if set, will generate a report via email or by storing on a drive
74
         'email' => '', # if set, will email the report to this address
75
         'subject' => '', # subject of the report email (will be auto-generated if empty)
76
         'targetDrive' => { # if set, will store the report on this drive
77
            'label' => '', # the GPT or msdos label of the report drive, REQUIRED
78
            'fstype' => '', # filesystem type of the report drive, default is msdos
79
            'check_interval' => 15, # how often to check for the disk (seconds), message displayed every interval
80
            'wait_timeout' => 300, # time to wait for the disk to appear in seconds
81
            'mount_point' => '', # where to mount the report drive, default is /mnt/label
82
         }
83
      }
84
   },
85
   # ... additional sections: 'target', 'transport', 'datasets' (see full file)
86
}
87
```
88
 
89
### How it works
90
 
91
The template file serves dual purposes:
92
 
93
1. **Default Values**: The Perl script loads it at runtime using `$config = do 'scriptname.datastructure'`, which returns the hash reference with all defaults.
94
 
95
2. **Configuration Schema**: The inline comments document each setting's purpose, forming a self-documenting configuration schema that can be exported to YAML format (e.g., `scriptname.conf.yaml`).
96
 
97
When the datastructure changes, this tool can non-destructively merge the updated template with existing configuration files, preserving user customizations while adding new keys and documentation. The interactive edit mode (`-e`) provides safe, menu-driven configuration management.
98
 
2 rodolico 99
## Options
100
 
101
| Option | Description |
102
|--------|-------------|
103
| `-t, --template <file>` | Template file (Perl hashref) |
6 rodolico 104
| `-c, --config <file>` | Config file (YAML or JSON) - can specify multiple for comparison |
2 rodolico 105
| `-o, --output <file>` | Output file (default: STDOUT) |
106
| `-e, --edit` | Interactive edit mode |
6 rodolico 107
| `-C, --compare` | Compare multiple config files and show differences |
2 rodolico 108
| `-v, --version` | Show version information |
109
| `-h, --help` | Show help message |
110
 
4 rodolico 111
## Examples
112
 
113
### Merge Template with Existing Config
114
```bash
115
perlConfigFileUtility -t template.pl -c config.yaml -o output.yaml
116
```
117
 
118
### Interactive Editing
119
```bash
120
perlConfigFileUtility -c config.yaml -e
121
```
6 rodolico 122
Navigate through nested structures, modify values, add new keys/elements, rename keys, or delete existing ones.
4 rodolico 123
 
6 rodolico 124
### Compare Multiple Config Files
125
```bash
126
# Compare two config files
127
perlConfigFileUtility -C -c production.yaml -c staging.yaml
128
 
129
# Compare three or more files
130
perlConfigFileUtility -C -c prod.yaml -c staging.yaml -c dev.yaml
131
 
132
# Save comparison report to file
133
perlConfigFileUtility -C -c config1.yaml -c config2.yaml -o comparison.txt
134
```
135
Shows all differences including missing keys and differing values.
136
 
4 rodolico 137
### Format Conversion
138
```bash
139
# YAML to JSON
140
perlConfigFileUtility -c config.yaml -o config.json
141
 
142
# JSON to YAML
143
perlConfigFileUtility -c config.json -o config.yaml
144
```
145
 
146
### Update Config with New Template Keys
147
```bash
148
# Merge new template keys into existing config, preserving user values
149
perlConfigFileUtility -t myapp.datastructure -c myapp.conf.yaml -o myapp.conf.yaml
150
```
151
 
152
### Start Fresh from Template
153
```bash
154
# Export template as YAML config
155
perlConfigFileUtility -t myapp.datastructure -o myapp.conf.yaml
156
```
157
 
158
## Interactive Editor Commands
159
 
160
When in edit mode (`-e`), the following commands are available:
161
 
162
- **Number (1-N)**: Select and edit the numbered item
163
- **0 or Enter**: Go back to previous level
164
- **a**: Add new key (in hash) or element (in array)
6 rodolico 165
- **r**: Rename a key (in hash only)
4 rodolico 166
- **d**: Delete a key (from hash) or element (from array)
167
- **q**: Quit and optionally save changes
168
 
169
When editing:
170
- **Scalars**: Enter new value or press Enter to keep current
171
- **Hashes**: Navigate into nested structure
172
- **Arrays**: Navigate into nested structure or edit elements
173
 
2 rodolico 174
## Requirements
175
 
4 rodolico 176
### Perl Modules
2 rodolico 177
 
4 rodolico 178
**Required:**
179
- Perl 5.x or higher
180
- `File::Slurp` - File reading utilities
181
- `Data::Dumper` - Data structure serialization
182
- `Getopt::Long` - Command-line option parsing
183
 
184
**At least one YAML library:**
185
- `YAML::XS` (recommended, fastest)
186
- `YAML::Tiny`
187
- `YAML`
188
 
189
**At least one JSON library:**
190
- `JSON::XS` (recommended, fastest)
191
- `JSON::PP`
192
- `JSON`
193
 
194
### Installation
195
 
196
**Using CPAN:**
197
```bash
198
cpan File::Slurp YAML::XS JSON::XS
199
```
200
 
201
**Using cpanm:**
202
```bash
203
cpanm File::Slurp YAML::XS JSON::XS
204
```
205
 
206
**Debian/Ubuntu:**
207
```bash
208
sudo apt-get install libfile-slurp-perl libyaml-perl libjson-xs-perl
209
```
210
 
211
**RedHat/CentOS:**
212
```bash
213
sudo yum install perl-File-Slurp perl-YAML perl-JSON-XS
214
```
215
 
216
**FreeBSD:**
217
```bash
218
sudo pkg install p5-File-Slurp p5-YAML p5-JSON-XS
219
```
220
 
221
### Source Code
222
 
223
This script is part of the Subversion repository and may be downloaded, checked out, or exported from:
224
 
225
```bash
226
# Checkout the entire repository
227
svn checkout http://svn.dailydata.net/svn/perlutils/trunk perlutils
228
 
229
# Export without version control metadata
230
svn export http://svn.dailydata.net/svn/perlutils/trunk perlutils
231
 
232
# Download just this script
233
svn export http://svn.dailydata.net/svn/perlutils/trunk/perlConfigFileUtility
234
```
235
 
236
## Use Cases
237
 
238
### 1. User-Friendly Configuration Editing
239
 
240
Enable non-technical users to modify complex configuration files without risking syntax errors:
241
```bash
242
perlConfigFileUtility -c /etc/myapp/config.yaml -e
243
```
244
 
245
### 2. Configuration Version Management
246
 
247
When software is updated with new configuration options, merge them into existing configs:
248
```bash
249
# v2.0 adds new keys to template
250
perlConfigFileUtility -t myapp-v2.datastructure -c myapp-v1.conf.yaml -o myapp-v2.conf.yaml
251
```
252
User customizations are preserved while new defaults are added.
253
 
254
### 3. Configuration Format Migration
255
 
256
Convert existing configs between formats:
257
```bash
258
# Organization switches from JSON to YAML
259
for file in configs/*.json; do
260
  perlConfigFileUtility -c "$file" -o "${file%.json}.yaml"
261
done
262
```
263
 
264
### 4. Configuration Deployment
265
 
266
Generate initial configuration files from templates:
267
```bash
268
perlConfigFileUtility -t defaults.pl -o /etc/newapp/config.yaml
269
```
270
 
6 rodolico 271
### 5. Configuration Comparison and Auditing
272
 
273
Compare config files across environments to identify discrepancies:
274
```bash
275
# Compare production vs staging configurations
276
perlConfigFileUtility -C -c /etc/app/prod.yaml -c /etc/app/staging.yaml
277
 
278
# Audit multiple server configs
279
perlConfigFileUtility -C -c server1.yaml -c server2.yaml -c server3.yaml -o audit-report.txt
280
```
281
Identifies missing keys, type mismatches, and value differences for troubleshooting and compliance.
282
 
4 rodolico 283
## Technical Details
284
 
285
### Template Files
286
 
287
Template files are Perl data structures (hashrefs) that define the configuration schema:
288
 
289
```perl
290
{
291
   'setting1' => 'default_value',
292
   'section' => {
293
      'nested_setting' => 123,
294
      'array_setting' => ['item1', 'item2']
295
   }
296
}
297
```
298
 
299
Inline comments in templates serve as documentation and are preserved when exported to YAML.
300
 
301
### Merge Behavior
302
 
303
- **Missing keys**: Added from template
304
- **Existing keys**: Preserved from config (user values not overwritten)
305
- **Nested hashes**: Recursively merged
306
- **Arrays**: Extended if template is longer; existing elements preserved
307
- **Type mismatches**: Config value takes precedence
308
 
309
### Backup Strategy
310
 
311
When saving changes, the original file is renamed with `.bak` extension:
312
```
313
config.yaml → config.yaml.bak  (old version)
314
config.yaml → (new version)
315
```
316
 
317
## Troubleshooting
318
 
319
**No YAML/JSON library error:**
320
Install at least one YAML and one JSON library using your system package manager or CPAN.
321
 
322
**Template must be a hashref error:**
323
Ensure template file contains a single hashref structure (starts with `{` and ends with `}`).
324
 
325
**Config must be a hashref error:**
326
The utility only works with hash-based configurations, not arrays or scalars at the root level.
327
 
328
**Permission denied errors:**
329
Ensure you have write permissions for the output directory when saving files.
330
 
2 rodolico 331
## License
332
 
333
Simplified BSD License (FreeBSD License)  
334
Copyright (c) 2026, Daily Data Inc.
335
 
336
## Author
337
 
338
R. W. Rodolico <rodo@dailydata.net>
339
 
340
## Version
341
 
6 rodolico 342
1.2.0 (January 2026)
2 rodolico 343
 
344
### Version History
345
 
6 rodolico 346
- **1.2.0** (2026-01-18): 
347
  - Added config file comparison mode to identify differences across multiple files
348
  - Added ability to rename hash keys in interactive edit mode
349
  - Refactored long functions for improved code readability and maintainability
2 rodolico 350
- **1.1.0** (2026-01-15): Added ability to delete keys from hashes and elements from arrays
351
- **1.0** (2026-01-13): Initial release with merge, edit, and format conversion capabilities