Compare commits
No commits in common. "f1cb04bd24eb64d3d7072667976e85c66fb3392e" and "57ece79693f3ae2f9672ba0ec708343704773ca0" have entirely different histories.
f1cb04bd24
...
57ece79693
@ -26,34 +26,7 @@ log_info "Installer Root: $INSTALLER_ROOT"
|
|||||||
[[ "$DRY_RUN" == true ]] && log_warn "Dry-Run aktiv"
|
[[ "$DRY_RUN" == true ]] && log_warn "Dry-Run aktiv"
|
||||||
|
|
||||||
run_module "$SCRIPT_DIR/modules/00_preflight.sh" "always"
|
run_module "$SCRIPT_DIR/modules/00_preflight.sh" "always"
|
||||||
run_module "$SCRIPT_DIR/modules/05_network.sh" "always"
|
|
||||||
run_module "$SCRIPT_DIR/modules/10_hardware.sh" "always"
|
run_module "$SCRIPT_DIR/modules/10_hardware.sh" "always"
|
||||||
run_module "$SCRIPT_DIR/modules/15_server_handshake.sh" "always"
|
|
||||||
run_module "$SCRIPT_DIR/modules/20_profile_selection.sh" "always"
|
|
||||||
run_module "$SCRIPT_DIR/modules/25_installation_confirm.sh" "always"
|
|
||||||
|
|
||||||
INSTALLATION_STATE_FILE="/run/tuxflotte/installation/state.env"
|
|
||||||
|
|
||||||
[[ -r "$INSTALLATION_STATE_FILE" ]] ||
|
|
||||||
error_exit "Installationsbestätigung fehlt: $INSTALLATION_STATE_FILE"
|
|
||||||
|
|
||||||
# shellcheck disable=SC1090
|
|
||||||
source "$INSTALLATION_STATE_FILE"
|
|
||||||
|
|
||||||
case "${TUXFLOTTE_INSTALLATION_CONFIRMED:-}" in
|
|
||||||
true)
|
|
||||||
log_info "Commit Point bestätigt. Installationsphase wird fortgesetzt."
|
|
||||||
;;
|
|
||||||
false)
|
|
||||||
log_info "Provisionierung wurde durch den Benutzer kontrolliert beendet."
|
|
||||||
log_info "Es wurden keine destruktiven Installationsaktionen gestartet."
|
|
||||||
exit 0
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
error_exit "Ungültiger Installationsbestätigungszustand."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
run_module "$SCRIPT_DIR/modules/20_storage.sh" "dry-run-safe"
|
run_module "$SCRIPT_DIR/modules/20_storage.sh" "dry-run-safe"
|
||||||
run_module "$SCRIPT_DIR/modules/99_finish.sh" "always"
|
run_module "$SCRIPT_DIR/modules/99_finish.sh" "always"
|
||||||
|
|
||||||
|
|||||||
@ -26,7 +26,7 @@ run_module() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
# shellcheck disable=SC1090
|
# shellcheck disable=SC1090
|
||||||
"$module"
|
source "$module"
|
||||||
|
|
||||||
log_success "Modul abgeschlossen: $(basename "$module")"
|
log_success "Modul abgeschlossen: $(basename "$module")"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,117 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
|
|
||||||
readonly SCRIPT_NAME
|
|
||||||
|
|
||||||
readonly SERVER_RESPONSE_FILE="/run/tuxflotte/server/response.json"
|
|
||||||
readonly RUNTIME_DIR="/run/tuxflotte/assignment"
|
|
||||||
readonly PROFILE_FILE="${RUNTIME_DIR}/profile.json"
|
|
||||||
|
|
||||||
log() {
|
|
||||||
printf '[%s] %s\n' "${SCRIPT_NAME}" "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
fatal() {
|
|
||||||
printf '[%s] FEHLER: %s\n' "${SCRIPT_NAME}" "$*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
require_root() {
|
|
||||||
if [[ "${EUID}" -ne 0 ]]; then
|
|
||||||
fatal "Das Profilauswahlmodul muss als root ausgeführt werden."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare_runtime() {
|
|
||||||
install -d -m 0700 "${RUNTIME_DIR}"
|
|
||||||
rm -f -- "${PROFILE_FILE}"
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_server_response() {
|
|
||||||
[[ -r "${SERVER_RESPONSE_FILE}" ]] ||
|
|
||||||
fatal "Serverantwort nicht gefunden: ${SERVER_RESPONSE_FILE}"
|
|
||||||
|
|
||||||
jq --exit-status . "${SERVER_RESPONSE_FILE}" >/dev/null ||
|
|
||||||
fatal "Serverantwort enthält kein gültiges JSON."
|
|
||||||
|
|
||||||
jq --exit-status '
|
|
||||||
.success == true
|
|
||||||
and (.profiles | type == "array")
|
|
||||||
and (.profiles | length > 0)
|
|
||||||
' "${SERVER_RESPONSE_FILE}" >/dev/null ||
|
|
||||||
fatal "Serverantwort enthält keine auswählbaren Profile."
|
|
||||||
}
|
|
||||||
|
|
||||||
show_profiles() {
|
|
||||||
local index=1
|
|
||||||
local profile
|
|
||||||
|
|
||||||
log "Verfügbare Provisioning-Profile:"
|
|
||||||
|
|
||||||
while IFS= read -r profile; do
|
|
||||||
printf '\n'
|
|
||||||
printf ' %d) %s\n' \
|
|
||||||
"${index}" \
|
|
||||||
"$(jq -r '.label' <<<"${profile}")"
|
|
||||||
|
|
||||||
printf ' Distribution: %s %s\n' \
|
|
||||||
"$(jq -r '.distribution' <<<"${profile}")" \
|
|
||||||
"$(jq -r '.version' <<<"${profile}")"
|
|
||||||
|
|
||||||
printf ' %s\n' \
|
|
||||||
"$(jq -r '.description // ""' <<<"${profile}")"
|
|
||||||
|
|
||||||
((index += 1))
|
|
||||||
done < <(jq -c '.profiles[]' "${SERVER_RESPONSE_FILE}")
|
|
||||||
}
|
|
||||||
|
|
||||||
select_profile() {
|
|
||||||
local profile_count
|
|
||||||
local selection
|
|
||||||
|
|
||||||
profile_count="$(jq '.profiles | length' "${SERVER_RESPONSE_FILE}")"
|
|
||||||
|
|
||||||
while true; do
|
|
||||||
printf '\n'
|
|
||||||
read -r -p "Profil auswählen [1-${profile_count}]: " selection
|
|
||||||
|
|
||||||
if [[ "${selection}" =~ ^[0-9]+$ ]] &&
|
|
||||||
((selection >= 1 && selection <= profile_count)); then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
|
|
||||||
log "Ungültige Auswahl."
|
|
||||||
done
|
|
||||||
|
|
||||||
jq \
|
|
||||||
--argjson index "$((selection - 1))" \
|
|
||||||
'{
|
|
||||||
schema_version: 1,
|
|
||||||
profile: .profiles[$index]
|
|
||||||
}' \
|
|
||||||
"${SERVER_RESPONSE_FILE}" >"${PROFILE_FILE}"
|
|
||||||
|
|
||||||
chmod 0600 "${PROFILE_FILE}"
|
|
||||||
|
|
||||||
jq --exit-status '
|
|
||||||
.schema_version == 1
|
|
||||||
and (.profile | type == "object")
|
|
||||||
and (.profile.id | type == "string")
|
|
||||||
and (.profile.id | length > 0)
|
|
||||||
' "${PROFILE_FILE}" >/dev/null ||
|
|
||||||
fatal "Ausgewähltes Profil konnte nicht gültig gespeichert werden."
|
|
||||||
|
|
||||||
log "Profil $(jq -r '.profile.id' "${PROFILE_FILE}") wurde ausgewählt."
|
|
||||||
log "Profilauswahl wurde unter ${PROFILE_FILE} gespeichert."
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
require_root
|
|
||||||
prepare_runtime
|
|
||||||
validate_server_response
|
|
||||||
show_profiles
|
|
||||||
select_profile
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
@ -1,112 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
set -Eeuo pipefail
|
|
||||||
|
|
||||||
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
|
|
||||||
readonly SCRIPT_NAME
|
|
||||||
|
|
||||||
readonly PROFILE_FILE="/run/tuxflotte/assignment/profile.json"
|
|
||||||
|
|
||||||
readonly RUNTIME_DIR="/run/tuxflotte/installation"
|
|
||||||
readonly STATE_FILE="${RUNTIME_DIR}/state.env"
|
|
||||||
|
|
||||||
log() {
|
|
||||||
printf '[%s] %s\n' "${SCRIPT_NAME}" "$*" >&2
|
|
||||||
}
|
|
||||||
|
|
||||||
fatal() {
|
|
||||||
printf '[%s] FEHLER: %s\n' "${SCRIPT_NAME}" "$*" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
require_root() {
|
|
||||||
if [[ "${EUID}" -ne 0 ]]; then
|
|
||||||
fatal "Das Installationsbestätigungsmodul muss als root ausgeführt werden."
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
prepare_runtime() {
|
|
||||||
install -d \
|
|
||||||
--mode=0700 \
|
|
||||||
--owner=root \
|
|
||||||
--group=root \
|
|
||||||
"${RUNTIME_DIR}"
|
|
||||||
|
|
||||||
rm -f -- "${STATE_FILE}"
|
|
||||||
}
|
|
||||||
|
|
||||||
validate_profile() {
|
|
||||||
[[ -r "${PROFILE_FILE}" ]] ||
|
|
||||||
fatal "Profilauswahl nicht gefunden: ${PROFILE_FILE}"
|
|
||||||
|
|
||||||
jq --exit-status '
|
|
||||||
.schema_version == 1
|
|
||||||
and (.profile | type == "object")
|
|
||||||
and (.profile.id | type == "string")
|
|
||||||
and (.profile.label | type == "string")
|
|
||||||
and (.profile.distribution | type == "string")
|
|
||||||
and (.profile.version | type == "string")
|
|
||||||
' "${PROFILE_FILE}" >/dev/null ||
|
|
||||||
fatal "Profilauswahl enthält kein gültiges Profil."
|
|
||||||
}
|
|
||||||
|
|
||||||
show_installation_plan() {
|
|
||||||
local label
|
|
||||||
local distribution
|
|
||||||
local version
|
|
||||||
local installer_type
|
|
||||||
|
|
||||||
label="$(jq -r '.profile.label' "${PROFILE_FILE}")"
|
|
||||||
distribution="$(jq -r '.profile.distribution' "${PROFILE_FILE}")"
|
|
||||||
version="$(jq -r '.profile.version' "${PROFILE_FILE}")"
|
|
||||||
installer_type="$(jq -r '.profile.installer.type // "unbekannt"' "${PROFILE_FILE}")"
|
|
||||||
|
|
||||||
printf '\n'
|
|
||||||
printf 'Geplanter Installationsvorgang\n'
|
|
||||||
printf '==============================\n\n'
|
|
||||||
printf 'Profil: %s\n' "${label}"
|
|
||||||
printf 'Distribution: %s %s\n' "${distribution}" "${version}"
|
|
||||||
printf 'Installer: %s\n' "${installer_type}"
|
|
||||||
printf '\n'
|
|
||||||
printf 'Die eigentliche Installation kann lokale Datenträger verändern.\n'
|
|
||||||
printf 'Bis zu dieser Bestätigung wurden keine destruktiven Installationsaktionen gestartet.\n'
|
|
||||||
printf '\n'
|
|
||||||
}
|
|
||||||
|
|
||||||
store_confirmation_state() {
|
|
||||||
local confirmed="$1"
|
|
||||||
|
|
||||||
umask 077
|
|
||||||
|
|
||||||
printf 'TUXFLOTTE_INSTALLATION_CONFIRMED=%s\n' \
|
|
||||||
"${confirmed}" >"${STATE_FILE}"
|
|
||||||
|
|
||||||
chmod 0600 "${STATE_FILE}"
|
|
||||||
}
|
|
||||||
|
|
||||||
confirm_installation() {
|
|
||||||
local answer
|
|
||||||
|
|
||||||
read -r -p "Installation jetzt starten? [j/N]: " answer
|
|
||||||
|
|
||||||
case "${answer}" in
|
|
||||||
j|J|ja|JA|Ja)
|
|
||||||
store_confirmation_state true
|
|
||||||
log "Installation wurde durch den Benutzer bestätigt."
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
store_confirmation_state false
|
|
||||||
log "Installation wurde durch den Benutzer abgebrochen."
|
|
||||||
log "Es wurden keine destruktiven Installationsaktionen gestartet."
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
main() {
|
|
||||||
require_root
|
|
||||||
prepare_runtime
|
|
||||||
validate_profile
|
|
||||||
show_installation_plan
|
|
||||||
confirm_installation
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
Loading…
x
Reference in New Issue
Block a user