#!/usr/bin/env bash # configure.sh - Interactive first-time configuration wizard # # SPDX-FileCopyrightText: Daniel Pätzold # SPDX-License-Identifier: AGPL-3.0-or-later SCRIPTDIR="$(cd "$(dirname "$0")" && pwd)" CONF_DIST="${SCRIPTDIR}/config.dist/setup_system.conf.dist" CONF_FILE="${SCRIPTDIR}/../config/setup_system.conf" CONF_PRE="${SCRIPTDIR}/../config.d/configure.conf" # Prompt for a single value; returns the old value unchanged if the user presses Enter. prompt_value() { local name="$1" current="$2" new_val printf ' %-28s [%s]: ' "$name" "$current" >&2 read -r new_val printf '%s' "${new_val:-$current}" } # Replace the first matching simple export line in configure.conf. set_conf_var() { local varname="$1" value="$2" sed -i "s|^[[:space:]]*export ${varname}=.*|export ${varname}=\"${value}\"|" "$CONF_PRE" } # Update an existing bare "export VAR=…" line at the top level, or append one. override_conf_var() { local varname="$1" value="$2" if grep -q "^export ${varname}=" "$CONF_PRE"; then sed -i "s|^export ${varname}=.*|export ${varname}=\"${value}\"|" "$CONF_PRE" else printf 'export %s="%s"\n' "$varname" "$value" >> "$CONF_PRE" fi } do_configure() { # Possibilities: # 1 Found CONF_FILE="${SCRIPTDIR}/../config/setup_system.conf": This is a preinstalled company-value filled complete conf file # 2 Found CONF_PRE="${SCRIPTDIR}/../config.d/configure.conf": This a a configure file from a previous configure run # 3 Found none of these: use CONF_DIST="${SCRIPTDIR}/config.dist/setup_system.conf.dist" # -> if 1 or 2 found, ask the user if to use one of them # -> either choice, the CONF_PRE="${SCRIPTDIR}/../config.d/configure.conf" is written from it and used for further setup if [ -f "$CONF_FILE" ] || [ -f "$CONF_PRE" ]; then echo "Some alternatives found for configure source:" if [[ -f "$CONF_PRE" ]]; then echo " Choice (p): Another config run result was found in $CONF_PRE ." echo " Hint: May contain Values that already were setup different for your details" else unset CONF_PRE fi if [[ -f "$CONF_FILE" ]]; then echo " Choice (c): Found companys full config in $CONF_FILE ." echo " This may be a full config, that is valid for your company." else unset CONF_FILE fi # Always possible: Use new dist echo " Choice (d): You may discard all, and use distributed defaults from the maintainers." echo " Hint: Will always start from scratch which guaranties to have a valid config for your current version" while true; do read -r -p " Please make a coice: " CHOICE case "${CHOICE}" in "p") if [[ -f "$CONF_PRE" ]]; then echo "Using the existing config run file." break fi ;; "c") if [[ -f "$CONF_FILE" ]]; then rm "$CONF_PRE" >/dev/null 2>&1 cp "$CONF_FILE" "$CONF_PRE" && break fi ;; "d") rm "$CONF_PRE" >/dev/null 2>&1 cp "$CONF_DIST" "$CONF_PRE" && break ;; esac echo "Invalid choice or error in selection made." done else cp "${CONF_DIST}" "$CONF_PRE" fi echo "" echo "=== System Configuration ===" echo "Press Enter to keep the current value, or type a new one." echo "Configuration will be reread for each value to make sure the settings are applied." echo # If other Repo infos are given, set them first if [[ ! -z $REPO_URL ]]; then echo "REPO_URL is set to $REPO_URL . Will use it for configure.conf." set_conf_var "REPO_URL" "$REPO_URL" fi if [[ ! -z $REPO_BRANCH ]]; then echo "REPO_BRANCH is set to $REPO_BRANCH . Will use it for configure.conf." set_conf_var "REPO_BRANCH" "$REPO_BRANCH" fi # Now there should all starting values be defined in $CONF_PRE file. # We will additionally first read the dists defaults again to make sure, that all relevant settings that may be new to existing configs are predefined # Could be no good idea when sysadmins are only deleting lines instead of unsettings its value, but makes sure there is not missing something for setup source "$CONF_DIST" #Now, read the users setting source "$CONF_PRE" VARS=("TLDOMAIN" "SERVERFQDN_IPA" "DOMAIN" "SERVERFQDN_NC" "IPAVAULTUSE" "IPAVAULTNAME" "DISTCONFIGPATH_SRC" "CLIENTADMINGROUP" ) for ELE in "${VARS[@]}" do while true; do echo "" new_ELE=$(prompt_value "${ELE}" "${!ELE}") set_conf_var "${ELE}" "${new_ELE}" source "$CONF_PRE" REPEAT_TEST=1 case ${ELE} in "SERVERFQDN_NC") echo "=== Testing: Nextcloud server ===" NC_STATUS=$(curl -fsSL "https://${SERVERFQDN_NC}/status.php" 2>/dev/null) if echo "$NC_STATUS" | grep -q '"installed":true'; then NC_VERSION=$(echo "$NC_STATUS" | grep -oP '(?<="versionstring":")[^"]+') echo "Nextcloud confirmed at ${SERVERFQDN_NC} (version ${NC_VERSION})." REPEAT_TEST=0 else echo "" echo "WARNING: '${SERVERFQDN_NC}' does not appear to be a valid Nextcloud server." echo " Could not reach https://${SERVERFQDN_NC}/status.php or response was unexpected." read -rp "Start configuration again (a) or quit (q)? [a/q]: " ans if [[ "${ans,,}" == "q" ]]; then echo "Quitting." exit 1 fi fi ;; "SERVERFQDN_IPA") echo "=== Testing: FreeIPA server ===" IPA_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ "https://${SERVERFQDN_IPA}/ipa/session/json" 2>/dev/null) if [[ "$IPA_CODE" == "200" || "$IPA_CODE" == "401" ]]; then echo "FreeIPA server confirmed at ${SERVERFQDN_IPA}." REPEAT_TEST=0 else echo "" echo "WARNING: '${SERVERFQDN_IPA}' does not appear to be a valid FreeIPA server." echo " https://${SERVERFQDN_IPA}/ipa/session/json returned: ${IPA_CODE:-no response}" read -rp "Start configuration again (a) or quit (q)? [a/q]: " ans if [[ "${ans,,}" == "q" ]]; then echo "Quitting." exit 1 fi fi ;; "DOMAIN") echo "=== Testing: IPA Domain DNS records ===" if ! command -v dig &>/dev/null; then echo "WARNING: 'dig' not found; skipping DNS check." REPEAT_TEST=0 else LDAP_SRV=$(dig +short SRV "_ldap._tcp.${DOMAIN}" 2>/dev/null) KRB_TXT=$(dig +short TXT "_kerberos.${DOMAIN}" 2>/dev/null) KDC_SRV=$(dig +short SRV "_kerberos._udp.${DOMAIN}" 2>/dev/null) if [[ -n "$LDAP_SRV" && -n "$KRB_TXT" ]]; then REALM=$(echo "$KRB_TXT" | tr -d '"') echo "IPA domain confirmed: ${DOMAIN}" echo " Kerberos realm : ${REALM}" [[ -n "$KDC_SRV" ]] && echo " KDC SRV : ${KDC_SRV}" REPEAT_TEST=0 else echo "" [[ -z "$LDAP_SRV" ]] && echo "WARNING: No _ldap._tcp.${DOMAIN} SRV record found." [[ -z "$KRB_TXT" ]] && echo "WARNING: No _kerberos.${DOMAIN} TXT record found." echo " '${DOMAIN}' does not appear to be a valid IPA domain." read -rp "Start configuration again (a) or quit (q)? [a/q]: " ans if [[ "${ans,,}" == "q" ]]; then echo "Quitting." exit 1 fi fi fi ;; *) echo "Not tests available." REPEAT_TEST=0 ;; esac [[ $REPEAT_TEST == 0 ]] && break done done echo "" echo "Configuration written to: ${CONF_PRE}" } while true; do do_configure echo "" echo "=== Select Kickstart Profile ===" KS_DIR="${SCRIPTDIR}/../ks_base_profiles" KS_DEST="${SCRIPTDIR}/../ks.cfg" mapfile -t KS_FILES < <(find "$KS_DIR" -maxdepth 1 -name "*.cfg" | sort) if [[ ${#KS_FILES[@]} -eq 0 ]]; then echo "No kickstart profiles found in ${KS_DIR}." exit 1 fi echo "" for i in "${!KS_FILES[@]}"; do desc=$(awk '/^$/{exit} {print}' "${KS_FILES[$i]}" \ | sed 's/^#[[:space:]]*//' | tr '\n' ' ' | xargs) printf " %d) %-36s %s\n" "$((i+1))" "$(basename "${KS_FILES[$i]}")" "$desc" done echo "" while true; do read -rp "Select profile [1-${#KS_FILES[@]}]: " sel [[ "$sel" =~ ^[0-9]+$ ]] && (( sel >= 1 && sel <= ${#KS_FILES[@]} )) && break echo " Invalid selection, please enter a number between 1 and ${#KS_FILES[@]}." done cp "${KS_FILES[$((sel-1))]}" "$KS_DEST" echo "Copied '$(basename "${KS_FILES[$((sel-1))]}")' to ${KS_DEST}." echo "" echo "=== Configuration complete ===" echo "All values have been configured and verified successfully." echo "The system is now ready for the new installation." echo "Boot from the Fedora USB installer — Anaconda will detect the OEMDRV partition" echo "and run the Kickstart automatically." exit 0 done