335 lines
16 KiB
Bash
335 lines
16 KiB
Bash
|
|
# Config migration helpers for the Ananke host installer.
|
||
|
|
|
||
|
|
read_ananke_role() {
|
||
|
|
if [[ ! -f "${CONF_DIR}/ananke.yaml" ]]; then
|
||
|
|
echo "coordinator"
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
local role
|
||
|
|
role="$(awk '/^[[:space:]]*role:[[:space:]]*/ {print $2; exit}' "${CONF_DIR}/ananke.yaml" 2>/dev/null || true)"
|
||
|
|
if [[ -z "${role}" ]]; then
|
||
|
|
role="coordinator"
|
||
|
|
fi
|
||
|
|
echo "${role}"
|
||
|
|
}
|
||
|
|
|
||
|
|
migration_yaml_lookup() {
|
||
|
|
local key="$1"
|
||
|
|
awk -F': *' -v k="${key}" '$1 == k {print $2; exit}' "${CONF_DIR}/ananke.yaml" 2>/dev/null || true
|
||
|
|
}
|
||
|
|
|
||
|
|
first_control_plane_name() {
|
||
|
|
awk '
|
||
|
|
/^control_planes:[[:space:]]*$/ {in_list=1; next}
|
||
|
|
in_list && /^[[:space:]]*-[[:space:]]*/ {gsub(/^[[:space:]]*-[[:space:]]*/, "", $0); print $0; exit}
|
||
|
|
in_list && /^[^[:space:]]/ {in_list=0}
|
||
|
|
' "${CONF_DIR}/ananke.yaml" 2>/dev/null || true
|
||
|
|
}
|
||
|
|
|
||
|
|
lookup_node_host() {
|
||
|
|
local node="$1"
|
||
|
|
awk -F': *' -v n="${node}" '$1 == " " n {print $2; exit}' "${CONF_DIR}/ananke.yaml" 2>/dev/null || true
|
||
|
|
}
|
||
|
|
|
||
|
|
migrate_ananke_config() {
|
||
|
|
if [[ ! -f "${CONF_DIR}/ananke.yaml" ]]; then
|
||
|
|
return 0
|
||
|
|
fi
|
||
|
|
|
||
|
|
local changed=0
|
||
|
|
local role_hint
|
||
|
|
role_hint="$(read_ananke_role)"
|
||
|
|
if grep -Eq 'default_budget_seconds:[[:space:]]*300' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei 's/(default_budget_seconds:[[:space:]]*)300/\11380/' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] migrated default_budget_seconds 300 -> 1380 in ${CONF_DIR}/ananke.yaml"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq 'runtime_safety_factor:[[:space:]]*1\.10' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei 's/(runtime_safety_factor:[[:space:]]*)1\.10/\11.25/' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] migrated runtime_safety_factor 1.10 -> 1.25 in ${CONF_DIR}/ananke.yaml"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ssh_node_users:[[:space:]]*$' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& grep -Eq '^ titan-24:[[:space:]]*tethys[[:space:]]*$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei 's/^ titan-24:[[:space:]]*tethys[[:space:]]*$/ titan-24: atlas/' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] migrated ssh_node_users titan-24 override to atlas"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ command_timeout_seconds:[[:space:]]*[0-9]+' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ startup_guard_max_age_seconds:[[:space:]]*[0-9]+' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ command_timeout_seconds:[[:space:]]*[0-9]+/a\ startup_guard_max_age_seconds: 900' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added coordination.startup_guard_max_age_seconds=900"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^[[:space:]]*poweroff_enabled:[[:space:]]*(true|false)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei \
|
||
|
|
-e '/^[[:space:]]*poweroff_enabled:[[:space:]]*(true|false)/d' \
|
||
|
|
-e '/^[[:space:]]*poweroff_delay_seconds:[[:space:]]*[0-9]+/d' \
|
||
|
|
-e '/^[[:space:]]*poweroff_local_host:[[:space:]]*(true|false)/d' \
|
||
|
|
-e '/^[[:space:]]*extra_poweroff_hosts:[[:space:]]*(\[\])?[[:space:]]*$/d' \
|
||
|
|
"${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] removed deprecated host-poweroff shutdown config keys"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ minimum_battery_percent:[[:space:]]*[0-9.]+' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ require_node_inventory_reachability:[[:space:]]*(true|false)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ minimum_battery_percent:[[:space:]]*[0-9.]+/a\ require_node_inventory_reachability: true\n node_inventory_reachability_wait_seconds: 300\n node_inventory_reachability_poll_seconds: 5' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup node inventory reachability gate defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^state:[[:space:]]*$' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ reports_dir:[[:space:]]*/var/lib/ananke/reports' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ dir:[[:space:]]*\/var\/lib\/ananke$/a\ reports_dir: /var/lib/ananke/reports' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added state.reports_dir default"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if ! grep -Eq '^ peer_hosts:' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
if [[ "${role_hint}" == "peer" ]] && grep -Eq '^ forward_shutdown_host:[[:space:]]*[A-Za-z0-9._-]+' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
local peer_host
|
||
|
|
peer_host="$(awk -F': *' '/^ forward_shutdown_host:[[:space:]]*/ {print $2; exit}' "${CONF_DIR}/ananke.yaml" 2>/dev/null || true)"
|
||
|
|
if [[ -n "${peer_host}" ]]; then
|
||
|
|
sed -Ei '/^ forward_shutdown_config:[[:space:]]*.*$/a\ peer_hosts:\n - '"${peer_host}"'' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added coordination.peer_hosts from forward_shutdown_host (${peer_host})"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
elif [[ "${role_hint}" == "coordinator" ]] && grep -Eq '^ titan-24:[[:space:]]*[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ forward_shutdown_config:[[:space:]]*.*$/a\ peer_hosts:\n - titan-24' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added coordination.peer_hosts default (titan-24) for coordinator role"
|
||
|
|
changed=1
|
||
|
|
else
|
||
|
|
sed -Ei '/^ forward_shutdown_config:[[:space:]]*.*$/a\ peer_hosts: []' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added coordination.peer_hosts empty default"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
local default_restore_cp
|
||
|
|
default_restore_cp="$(first_control_plane_name)"
|
||
|
|
if [[ -z "${default_restore_cp}" ]]; then
|
||
|
|
default_restore_cp="titan-0a"
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ api_poll_seconds:[[:space:]]*[0-9]+' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ auto_etcd_restore_on_api_failure:[[:space:]]*(true|false)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ api_poll_seconds:[[:space:]]*[0-9]+/a\ require_time_sync: true\n time_sync_wait_seconds: 240\n time_sync_poll_seconds: 5\n reconcile_access_on_boot: true\n auto_etcd_restore_on_api_failure: true\n etcd_restore_control_plane: '"${default_restore_cp}"'' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup.auto_etcd_restore_on_api_failure + startup.etcd_restore_control_plane defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ api_poll_seconds:[[:space:]]*[0-9]+' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ require_time_sync:[[:space:]]*(true|false)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ api_poll_seconds:[[:space:]]*[0-9]+/a\ require_time_sync: true\n time_sync_wait_seconds: 240\n time_sync_poll_seconds: 5\n reconcile_access_on_boot: true' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup time sync + access reconciliation defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ time_sync_poll_seconds:[[:space:]]*[0-9]+' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ time_sync_mode:[[:space:]]*(strict|quorum)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ time_sync_poll_seconds:[[:space:]]*[0-9]+/a\ time_sync_mode: quorum\n time_sync_quorum: 2' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup time sync quorum defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ etcd_restore_control_plane:[[:space:]]*[A-Za-z0-9._-]+' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ require_storage_ready:[[:space:]]*(true|false)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ etcd_restore_control_plane:[[:space:]]*[A-Za-z0-9._-]+/a\ require_storage_ready: true\n storage_ready_wait_seconds: 420\n storage_ready_poll_seconds: 5\n storage_min_ready_nodes: 2\n storage_critical_pvcs:\n - vault/data-vault-0\n - postgres/postgres-data-postgres-0\n - gitea/gitea-data\n - sso/keycloak-data' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup storage readiness defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ storage_critical_pvcs:[[:space:]]*$' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ require_post_start_probes:[[:space:]]*(true|false)' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ - sso\/keycloak-data$/a\ require_post_start_probes: true\n post_start_probe_wait_seconds: 240\n post_start_probe_poll_seconds: 5\n post_start_probes:\n - https://scm.bstein.dev/api/healthz\n - https://metrics.bstein.dev/api/health\n require_service_checklist: true\n service_checklist_wait_seconds: 420\n service_checklist_poll_seconds: 5\n service_checklist_stability_seconds: 120\n service_checklist:\n - name: gitea-api\n url: https://scm.bstein.dev/api/healthz\n accepted_statuses: [200]\n body_contains: pass\n timeout_seconds: 12\n - name: grafana-api\n url: https://metrics.bstein.dev/api/health\n accepted_statuses: [200]\n body_contains: '\''\"database\":\"ok\"'\''\n timeout_seconds: 12\n vault_unseal_key_file: /var/lib/ananke/vault-unseal.key' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup post-start probe + vault key fallback defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^ - https://sso.bstein.dev/realms/atlas/.well-known/openid-configuration$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ - https:\/\/sso\.bstein\.dev\/realms\/atlas\/\.well-known\/openid-configuration$/d' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] removed sso OIDC probe from startup.post_start_probes (returns 404 in current deployment)"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if ! grep -Eq '^ vault_unseal_key_file:[[:space:]]*/var/lib/ananke/vault-unseal.key' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
if grep -Eq '^startup:[[:space:]]*$' "${CONF_DIR}/ananke.yaml" && grep -Eq '^ post_start_probes:[[:space:]]*$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ - https:\/\/metrics\.bstein\.dev\/api\/health$/a\ vault_unseal_key_file: /var/lib/ananke/vault-unseal.key' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup.vault_unseal_key_file default"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
if ! grep -Eq '^ vault_unseal_breakglass_timeout_seconds:[[:space:]]*[0-9]+' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
if grep -Eq '^ vault_unseal_key_file:[[:space:]]*/var/lib/ananke/vault-unseal.key' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
sed -Ei '/^ vault_unseal_key_file:[[:space:]]*\/var\/lib\/ananke\/vault-unseal.key$/a\ vault_unseal_breakglass_command: ""\n vault_unseal_breakglass_timeout_seconds: 15' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] added startup break-glass fallback defaults"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
install_cluster_inventory_defaults "${role_hint}" && changed=1
|
||
|
|
|
||
|
|
if [[ "${changed}" -eq 1 ]]; then
|
||
|
|
chmod 0640 "${CONF_DIR}/ananke.yaml" || true
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
install_cluster_inventory_defaults() {
|
||
|
|
local role="$1"
|
||
|
|
local changed=0
|
||
|
|
local inventory_block=""
|
||
|
|
local managed_block=""
|
||
|
|
local workers_block
|
||
|
|
workers_block='workers:
|
||
|
|
- titan-04
|
||
|
|
- titan-05
|
||
|
|
- titan-06
|
||
|
|
- titan-07
|
||
|
|
- titan-08
|
||
|
|
- titan-09
|
||
|
|
- titan-10
|
||
|
|
- titan-11
|
||
|
|
- titan-12
|
||
|
|
- titan-13
|
||
|
|
- titan-14
|
||
|
|
- titan-15
|
||
|
|
- titan-17
|
||
|
|
- titan-18
|
||
|
|
- titan-19
|
||
|
|
- titan-20
|
||
|
|
- titan-21
|
||
|
|
- titan-22
|
||
|
|
- titan-24'
|
||
|
|
|
||
|
|
if [[ "${role}" == "coordinator" || "${role}" == "peer" ]]; then
|
||
|
|
inventory_block='ssh_node_hosts:
|
||
|
|
titan-db: 192.168.22.10
|
||
|
|
titan-0a: 192.168.22.11
|
||
|
|
titan-0b: 192.168.22.12
|
||
|
|
titan-0c: 192.168.22.13
|
||
|
|
titan-04: 192.168.22.30
|
||
|
|
titan-05: 192.168.22.31
|
||
|
|
titan-06: 192.168.22.32
|
||
|
|
titan-07: 192.168.22.33
|
||
|
|
titan-08: 192.168.22.34
|
||
|
|
titan-09: 192.168.22.35
|
||
|
|
titan-10: 192.168.22.36
|
||
|
|
titan-11: 192.168.22.37
|
||
|
|
titan-12: 192.168.22.40
|
||
|
|
titan-13: 192.168.22.41
|
||
|
|
titan-14: 192.168.22.42
|
||
|
|
titan-15: 192.168.22.43
|
||
|
|
titan-17: 192.168.22.45
|
||
|
|
titan-18: 192.168.22.46
|
||
|
|
titan-19: 192.168.22.47
|
||
|
|
titan-20: 192.168.22.20
|
||
|
|
titan-21: 192.168.22.21
|
||
|
|
titan-22: 192.168.22.22
|
||
|
|
titan-24: 192.168.22.26'
|
||
|
|
managed_block='ssh_managed_nodes:
|
||
|
|
- titan-db
|
||
|
|
- titan-0a
|
||
|
|
- titan-0b
|
||
|
|
- titan-0c
|
||
|
|
- titan-04
|
||
|
|
- titan-05
|
||
|
|
- titan-06
|
||
|
|
- titan-07
|
||
|
|
- titan-08
|
||
|
|
- titan-09
|
||
|
|
- titan-10
|
||
|
|
- titan-11
|
||
|
|
- titan-12
|
||
|
|
- titan-13
|
||
|
|
- titan-14
|
||
|
|
- titan-15
|
||
|
|
- titan-17
|
||
|
|
- titan-18
|
||
|
|
- titan-19
|
||
|
|
- titan-20
|
||
|
|
- titan-21
|
||
|
|
- titan-22
|
||
|
|
- titan-24'
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -n "${inventory_block}" ]] && grep -Eq '^ssh_node_hosts:[[:space:]]*\{\}[[:space:]]*$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
perl -0pi -e 's#ssh_node_hosts:\s*\{\}\n#'"${inventory_block}"'\n#s' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] hydrated ssh_node_hosts inventory for role=${role}"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if grep -Eq '^workers:[[:space:]]*\[\][[:space:]]*$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
perl -0pi -e 's#workers:\s*\[\]\n#'"${workers_block}"'\n#s' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] hydrated workers inventory for startup/shutdown orchestration"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ -n "${managed_block}" ]]; then
|
||
|
|
if grep -Eq '^ssh_managed_nodes:[[:space:]]*\[\][[:space:]]*$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
perl -0pi -e 's#ssh_managed_nodes:\s*\[\]\n#'"${managed_block}"'\n#s' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] hydrated ssh_managed_nodes inventory for role=${role}"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
if ! grep -Eq '^ - titan-04$' "${CONF_DIR}/ananke.yaml" || ! grep -Eq '^ - titan-21$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
perl -0pi -e 's#ssh_managed_nodes:\n(?: - [^\n]*\n)*#'"${managed_block}"'\n#s' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] refreshed ssh_managed_nodes coverage for role=${role}"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ "${role}" == "peer" ]]; then
|
||
|
|
install_peer_inventory_defaults && changed=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
[[ "${changed}" -eq 1 ]]
|
||
|
|
}
|
||
|
|
|
||
|
|
install_peer_inventory_defaults() {
|
||
|
|
local changed=0
|
||
|
|
if grep -Eq '^ssh_managed_nodes:[[:space:]]*$' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& grep -Eq '^ - titan-db$' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& grep -Eq '^ - titan-24$' "${CONF_DIR}/ananke.yaml" \
|
||
|
|
&& ! grep -Eq '^ - titan-0a$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
perl -0pi -e 's#ssh_managed_nodes:\n - titan-db\n - titan-24\n#ssh_managed_nodes:\n - titan-db\n - titan-0a\n - titan-0b\n - titan-0c\n - titan-04\n - titan-05\n - titan-06\n - titan-07\n - titan-08\n - titan-09\n - titan-10\n - titan-11\n - titan-12\n - titan-13\n - titan-14\n - titan-15\n - titan-17\n - titan-18\n - titan-19\n - titan-20\n - titan-21\n - titan-22\n - titan-24\n#s' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] expanded peer ssh_managed_nodes for bootstrap fallback coverage"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
if ! grep -Eq '^ - services/keycloak$' "${CONF_DIR}/ananke.yaml" || ! grep -Eq '^ - infrastructure/cert-manager$' "${CONF_DIR}/ananke.yaml" || ! grep -Eq '^ - services/oauth2-proxy$' "${CONF_DIR}/ananke.yaml"; then
|
||
|
|
perl -0pi -e 's#local_bootstrap_paths:\n(?: - [^\n]*\n)*#local_bootstrap_paths:\n - infrastructure/core\n - clusters/atlas/flux-system\n - infrastructure/sources/helm\n - infrastructure/metallb\n - infrastructure/traefik\n - infrastructure/cert-manager\n - infrastructure/vault-csi\n - infrastructure/vault-injector\n - services/vault\n - infrastructure/postgres\n - services/gitea\n - services/keycloak\n - services/oauth2-proxy\n#s' "${CONF_DIR}/ananke.yaml"
|
||
|
|
echo "[install] refreshed peer local_bootstrap_paths for full fallback bootstrap parity"
|
||
|
|
changed=1
|
||
|
|
fi
|
||
|
|
[[ "${changed}" -eq 1 ]]
|
||
|
|
}
|
||
|
|
|
||
|
|
sanitize_migrated_ananke_config() {
|
||
|
|
local cfg="${CONF_DIR}/ananke.yaml"
|
||
|
|
[[ -f "${cfg}" ]] || return 0
|
||
|
|
|
||
|
|
local tmp changed=0
|
||
|
|
tmp="$(mktemp)"
|
||
|
|
|
||
|
|
# If a legacy migration bug appended root-level node entries after
|
||
|
|
# ssh_managed_nodes, drop those orphan entries until the next top-level key.
|
||
|
|
awk '
|
||
|
|
BEGIN {in_managed=0}
|
||
|
|
/^ssh_managed_nodes:[[:space:]]*$/ {in_managed=1; print; next}
|
||
|
|
{
|
||
|
|
if (in_managed) {
|
||
|
|
if ($0 ~ /^ - /) {print; next}
|
||
|
|
if ($0 ~ /^- /) {next}
|
||
|
|
if ($0 ~ /^[A-Za-z0-9_]+:[[:space:]]*/) {in_managed=0}
|
||
|
|
}
|
||
|
|
print
|
||
|
|
}
|
||
|
|
' "${cfg}" > "${tmp}"
|
||
|
|
|
||
|
|
if ! cmp -s "${cfg}" "${tmp}"; then
|
||
|
|
mv "${tmp}" "${cfg}"
|
||
|
|
changed=1
|
||
|
|
echo "[install] sanitized malformed ssh_managed_nodes block in ${cfg}"
|
||
|
|
else
|
||
|
|
rm -f "${tmp}"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if grep -Eq '^[[:space:]]*forward_shutdown_config:[[:space:]]*/etc/ananke/hecate.yaml[[:space:]]*$' "${cfg}"; then
|
||
|
|
sed -Ei 's#(^[[:space:]]*forward_shutdown_config:[[:space:]]*)/etc/ananke/hecate.yaml#\1/etc/ananke/ananke.yaml#' "${cfg}"
|
||
|
|
changed=1
|
||
|
|
echo "[install] migrated coordination.forward_shutdown_config to /etc/ananke/ananke.yaml"
|
||
|
|
fi
|
||
|
|
|
||
|
|
if [[ "${changed}" -eq 1 ]]; then
|
||
|
|
chmod 0640 "${cfg}" || true
|
||
|
|
fi
|
||
|
|
}
|