diff --git a/scripts/install.sh b/scripts/install.sh index dfe8440..a6e04e7 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -72,6 +72,98 @@ read_hecate_role() { echo "${role}" } +migration_yaml_lookup() { + local key="$1" + awk -F': *' -v k="${key}" '$1 == k {print $2; exit}' "${CONF_DIR}/hecate.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}/hecate.yaml" 2>/dev/null || true +} + +lookup_node_host() { + local node="$1" + awk -F': *' -v n="${node}" '$1 == " " n {print $2; exit}' "${CONF_DIR}/hecate.yaml" 2>/dev/null || true +} + +ensure_hecate_kubeconfig() { + local kubeconfig_path + kubeconfig_path="$(migration_yaml_lookup "kubeconfig")" + if [[ -z "${kubeconfig_path}" ]]; then + kubeconfig_path="/etc/hecate/kubeconfig" + fi + install -d -m 0750 "$(dirname "${kubeconfig_path}")" + + if [[ -s "${kubeconfig_path}" ]] && KUBECONFIG="${kubeconfig_path}" kubectl version --request-timeout=5s >/dev/null 2>&1; then + return 0 + fi + + if [[ -r /etc/rancher/k3s/k3s.yaml ]]; then + install -m 0600 /etc/rancher/k3s/k3s.yaml "${kubeconfig_path}" + echo "[install] refreshed kubeconfig from local /etc/rancher/k3s/k3s.yaml" + if KUBECONFIG="${kubeconfig_path}" kubectl version --request-timeout=5s >/dev/null 2>&1; then + return 0 + fi + fi + + local cp_name cp_host ssh_user ssh_port ssh_cfg ssh_key + cp_name="$(first_control_plane_name)" + if [[ -z "${cp_name}" ]]; then + echo "[install] warning: cannot infer control plane name; kubeconfig bootstrap skipped" + return 0 + fi + cp_host="$(lookup_node_host "${cp_name}")" + if [[ -z "${cp_host}" ]]; then + cp_host="${cp_name}" + fi + ssh_user="$(migration_yaml_lookup "ssh_user")" + ssh_port="$(migration_yaml_lookup "ssh_port")" + ssh_cfg="$(migration_yaml_lookup "ssh_config_file")" + ssh_key="$(migration_yaml_lookup "ssh_identity_file")" + if [[ -z "${ssh_port}" ]]; then + ssh_port="2277" + fi + + local target + target="${cp_host}" + if [[ -n "${ssh_user}" ]]; then + target="${ssh_user}@${cp_host}" + fi + local ssh_args=( + -o BatchMode=yes + -o ConnectTimeout=8 + -o StrictHostKeyChecking=accept-new + ) + if [[ -n "${ssh_cfg}" && -f "${ssh_cfg}" ]]; then + ssh_args+=(-F "${ssh_cfg}") + fi + if [[ -n "${ssh_key}" && -f "${ssh_key}" ]]; then + ssh_args+=(-i "${ssh_key}") + fi + if [[ -n "${ssh_port}" ]]; then + ssh_args+=(-p "${ssh_port}") + fi + + local remote_cfg + if remote_cfg="$(ssh "${ssh_args[@]}" "${target}" "sudo cat /etc/rancher/k3s/k3s.yaml" 2>/dev/null)"; then + printf '%s\n' "${remote_cfg}" > "${kubeconfig_path}" + sed -Ei "s#server:[[:space:]]*https://127\\.0\\.0\\.1:6443#server: https://${cp_host}:6443#g" "${kubeconfig_path}" || true + chmod 0600 "${kubeconfig_path}" + echo "[install] bootstrapped kubeconfig from control plane ${cp_name} (${cp_host})" + if KUBECONFIG="${kubeconfig_path}" kubectl version --request-timeout=5s >/dev/null 2>&1; then + return 0 + fi + else + echo "[install] warning: failed to fetch kubeconfig from ${cp_name} (${cp_host})" + fi + + echo "[install] warning: kubeconfig at ${kubeconfig_path} is still not validated; local startup fallback may fail" +} + migrate_hecate_config() { if [[ ! -f "${CONF_DIR}/hecate.yaml" ]]; then return 0 @@ -353,6 +445,7 @@ else echo "[install] keeping existing config at ${CONF_DIR}/hecate.yaml" fi migrate_hecate_config +ensure_hecate_kubeconfig echo "[install] installing systemd units" install -m 0644 deploy/systemd/hecate.service "${SYSTEMD_DIR}/hecate.service"