#!/bin/bash set -u metadata_file= metadata_temporary= once=0 destination=${XCATDEST:-} request_pid= usage() { printf '%s\n' 'Usage: nextdestiny [ENDPOINT] [--metadata FILE] [--once]' >&2 exit 2 } while (($# > 0)); do case "$1" in --metadata) (($# >= 2)) || usage metadata_file=$2 shift 2 ;; --once) once=1 shift ;; --) shift (($# <= 1)) || usage if (($# == 1)); then destination=$1 fi break ;; -*) usage ;; *) if [[ -z $destination ]]; then destination=$1 fi shift ;; esac done [[ -n $destination ]] || usage temporary_dir=$(mktemp -d "${TMPDIR:-/tmp}/nextdestiny.XXXXXX") || exit 1 request_file=$temporary_dir/request.xml response_file=$temporary_dir/response.xml cleanup() { rm -rf -- "$temporary_dir" [[ -z $metadata_temporary ]] || rm -f -- "$metadata_temporary" } terminate() { local status=$1 trap - HUP INT TERM if [[ -n $request_pid ]]; then kill -TERM "$request_pid" 2>/dev/null || true wait "$request_pid" 2>/dev/null || true fi exit "$status" } trap cleanup EXIT trap 'terminate 129' HUP trap 'terminate 130' INT trap 'terminate 143' TERM printf '%s\n' \ '' \ 'nextdestiny' \ '300' \ '' >"$request_file" request_destiny() { if [[ -f /etc/xcat/cert.pem && -f /etc/xcat/certkey.pem ]]; then openssl s_client -key /etc/xcat/certkey.pem \ -cert /etc/xcat/cert.pem -connect "$destination" -quiet \ 2>/dev/null <"$request_file" >"$response_file" & else openssl s_client -connect "$destination" -quiet \ 2>/dev/null <"$request_file" >"$response_file" & fi request_pid=$! wait "$request_pid" || true request_pid= [[ -s $response_file ]] } if ((once)); then request_destiny \ && { grep -q '' "$response_file" \ || grep -q '' "$response_file"; } \ || exit 1 else request_destiny || true fi extract_element() { local element=$1 sed -n "s:.*<$element>\([^<]*\).*:\1:p" "$response_file" \ | head -n 1 | tr -cd '\40-\176' } destiny=$(extract_element destiny) if [[ -z $destiny ]]; then error=$(extract_element error) [[ -n $error ]] || error='No destiny command received' destiny="error=$error" fi if [[ -n $metadata_file ]]; then metadata_dir=${metadata_file%/*} if [[ $metadata_dir == "$metadata_file" ]]; then metadata_dir=. elif [[ -z $metadata_dir ]]; then metadata_dir=/ fi [[ -d $metadata_dir ]] || exit 1 metadata_temporary=$(mktemp "$metadata_dir/.nextdestiny.XXXXXX") || exit 1 { printf 'XCAT_NODE_NAME=%s\n' "$(extract_element name)" printf 'XCAT_DESTINY=%s\n' "$destiny" printf 'XCAT_IMAGE_SERVER=%s\n' "$(extract_element imgserver)" printf 'XCAT_KERNEL=%s\n' "$(extract_element kernel)" printf 'XCAT_INITRD=%s\n' "$(extract_element initrd)" printf 'XCAT_KERNEL_COMMAND_LINE=%s\n' "$(extract_element kcmdline)" } >"$metadata_temporary" chmod 0600 "$metadata_temporary" mv -f -- "$metadata_temporary" "$metadata_file" fi printf '%s\n' "$destiny"