Fix update_allowed_nodes to be properly idempotent
Rewrote AWK state machine to correctly handle: - Multiple allowed_nodes sections (removes all of them) - Comment lines immediately preceding allowed_nodes (discards them) - Empty lines within allowed_nodes section - Indented list items and comments The function now: 1. Buffers comment lines that might precede allowed_nodes 2. When allowed_nodes: is detected, discards buffered comments 3. Skips all content until hitting a non-indented, non-comment line 4. Flushes buffered comments when hitting non-comment content This ensures running the installer multiple times won't create duplicate allowed_nodes sections in config.yaml. Tested with script that verifies duplicate sections are removed correctly.
This commit is contained in:
parent
c10be5cf78
commit
5b7d1726d7
1 changed files with 60 additions and 31 deletions
|
|
@ -75,47 +75,76 @@ update_allowed_nodes() {
|
||||||
# Ensure temp file is cleaned up on exit (success or failure)
|
# Ensure temp file is cleaned up on exit (success or failure)
|
||||||
trap "rm -f '$tmp_config'" RETURN
|
trap "rm -f '$tmp_config'" RETURN
|
||||||
|
|
||||||
# Remove any existing allowed_nodes section (including the YAML key and all list items)
|
# Remove any existing allowed_nodes section using a robust state machine
|
||||||
# This handles multi-line allowed_nodes blocks and associated comment headers
|
# This removes the YAML key, all list items, and any comment lines immediately preceding it
|
||||||
if [[ -f "$config_file" ]]; then
|
if [[ -f "$config_file" ]]; then
|
||||||
awk '
|
awk '
|
||||||
# When we hit allowed_nodes, mark section start and clear pending comments
|
BEGIN {
|
||||||
|
in_section = 0
|
||||||
|
comment_buffer_size = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Detect start of allowed_nodes section
|
||||||
/^allowed_nodes:/ {
|
/^allowed_nodes:/ {
|
||||||
in_section=1
|
# Discard any buffered comment lines (they belong to allowed_nodes)
|
||||||
delete pending_lines
|
comment_buffer_size = 0
|
||||||
pending_count=0
|
in_section = 1
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
|
||||||
# Inside section: skip all content until we hit a non-indented, non-comment line
|
# Inside allowed_nodes section: skip lines until we hit a non-indented, non-comment line
|
||||||
in_section && /^[^ \t#]/ {
|
|
||||||
in_section=0
|
|
||||||
# Fall through to print this line
|
|
||||||
}
|
|
||||||
in_section {
|
in_section {
|
||||||
next
|
# Empty lines within section: skip
|
||||||
}
|
if (/^[ \t]*$/) {
|
||||||
|
next
|
||||||
# Outside section: buffer comment lines (they might belong to allowed_nodes)
|
}
|
||||||
!in_section && /^[ \t]*#/ {
|
# Indented lines (list items): skip
|
||||||
pending_lines[pending_count++] = $0
|
if (/^[ \t]+-/) {
|
||||||
next
|
next
|
||||||
}
|
}
|
||||||
|
# Indented comments: skip
|
||||||
# Outside section: non-comment line - flush pending comments and print
|
if (/^[ \t]+#/) {
|
||||||
!in_section {
|
next
|
||||||
for (i = 0; i < pending_count; i++) {
|
}
|
||||||
print pending_lines[i]
|
# Non-indented, non-comment line: section ends
|
||||||
|
if (/^[^ \t#]/) {
|
||||||
|
in_section = 0
|
||||||
|
# Fall through to normal processing
|
||||||
}
|
}
|
||||||
delete pending_lines
|
|
||||||
pending_count = 0
|
|
||||||
print
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# At end of file, flush any remaining pending comments
|
# Outside section: buffer comment lines (might precede allowed_nodes)
|
||||||
|
!in_section && /^[ \t]*#/ {
|
||||||
|
comment_buffer[comment_buffer_size++] = $0
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# Outside section: non-comment, non-empty line
|
||||||
|
!in_section && !/^[ \t]*$/ {
|
||||||
|
# Flush buffered comments (they don'\''t belong to allowed_nodes)
|
||||||
|
for (i = 0; i < comment_buffer_size; i++) {
|
||||||
|
print comment_buffer[i]
|
||||||
|
}
|
||||||
|
comment_buffer_size = 0
|
||||||
|
print
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# Outside section: empty line
|
||||||
|
!in_section && /^[ \t]*$/ {
|
||||||
|
# Flush buffered comments and print empty line
|
||||||
|
for (i = 0; i < comment_buffer_size; i++) {
|
||||||
|
print comment_buffer[i]
|
||||||
|
}
|
||||||
|
comment_buffer_size = 0
|
||||||
|
print
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
# At end of file, flush any remaining buffered comments
|
||||||
END {
|
END {
|
||||||
for (i = 0; i < pending_count; i++) {
|
for (i = 0; i < comment_buffer_size; i++) {
|
||||||
print pending_lines[i]
|
print comment_buffer[i]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
' "$config_file" > "$tmp_config"
|
' "$config_file" > "$tmp_config"
|
||||||
|
|
@ -138,7 +167,7 @@ update_allowed_nodes() {
|
||||||
done
|
done
|
||||||
} >> "$tmp_config"
|
} >> "$tmp_config"
|
||||||
|
|
||||||
# Replace original file
|
# Replace original file atomically
|
||||||
if ! mv "$tmp_config" "$config_file"; then
|
if ! mv "$tmp_config" "$config_file"; then
|
||||||
echo "ERROR: Failed to update $config_file - check permissions" >&2
|
echo "ERROR: Failed to update $config_file - check permissions" >&2
|
||||||
return 1
|
return 1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue