diff --git a/third_party/Dell/ubuntu-22.04/iac/README.md b/third_party/Dell/ubuntu-22.04/iac/README.md index 8154d3e8..2e740417 100644 --- a/third_party/Dell/ubuntu-22.04/iac/README.md +++ b/third_party/Dell/ubuntu-22.04/iac/README.md @@ -66,6 +66,12 @@ You may also use any internally hosted ISO that is reachable by iDRAC. chmod +x mount-iso.sh ./mount-iso.sh ``` +### To Unmount ISO +use this command, if you want to unmount ISO. +```bash +./mount-iso.sh -u +``` + --- ## 2. Boot Ubuntu Installer (Terraform + Redfish) diff --git a/third_party/Dell/ubuntu-22.04/iac/deploy-enterprise-inference.sh b/third_party/Dell/ubuntu-22.04/iac/deploy-enterprise-inference.sh index b471aa47..dc01cd5e 100644 --- a/third_party/Dell/ubuntu-22.04/iac/deploy-enterprise-inference.sh +++ b/third_party/Dell/ubuntu-22.04/iac/deploy-enterprise-inference.sh @@ -104,17 +104,21 @@ escape_sed_replacement() { # Hugging Face token checks for selected model numbers check_hf_token_access() { log_info "Validating Hugging Face token..." + local response http_code body response=$(curl -sS -w $'\n%{http_code}' \ -H "Authorization: Bearer ${HF_TOKEN}" \ - "https://huggingface.co/api/whoami-v2") + https://huggingface.co/api/whoami-v2) + http_code="${response##*$'\n'}" body="${response%$'\n'*}" + if [[ "$http_code" != "200" ]]; then log_error "Hugging Face token validation failed (HTTP ${http_code})" echo "$body" exit 1 fi + log_success "Hugging Face token is valid" if [[ -z "${MODELS:-}" ]]; then @@ -124,45 +128,60 @@ check_hf_token_access() { IFS=',' read -r -a model_numbers <<< "${MODELS}" local model_ids=() + for num in "${model_numbers[@]}"; do num="$(echo "$num" | xargs)" if [[ -z "$num" ]]; then continue fi if [[ -z "${MODEL_MAP[$num]:-}" ]]; then - log_warn "Unknown model number '${num}' (no mapping found)" - continue + log_error "Unknown model number '${num}'" + exit 1 fi model_ids+=("${MODEL_MAP[$num]}") done - if [[ ${#model_ids[@]} -eq 0 ]]; then - log_warn "No valid model numbers found; skipping model access checks" - return 0 - fi + log_info "Checking model access..." - log_info "Checking model access for selected numbers..." - local seen_ids=() for model_id in "${model_ids[@]}"; do - if [[ " ${seen_ids[*]} " == *" ${model_id} "* ]]; then - continue - fi - seen_ids+=("${model_id}") log_info "Model: ${model_id}" - local model_code - model_code=$(curl -sS -o /dev/null -w "%{http_code}" \ + + # Step 1: Check metadata + metadata=$(curl -sS \ -H "Authorization: Bearer ${HF_TOKEN}" \ "https://huggingface.co/api/models/${model_id}") - if [[ "$model_code" == "200" ]]; then - log_success "Access confirmed for ${model_id}" - continue + + metadata_code=$(curl -sS -o /dev/null -w "%{http_code}" \ + -H "Authorization: Bearer ${HF_TOKEN}" \ + "https://huggingface.co/api/models/${model_id}") + + if [[ "$metadata_code" != "200" ]]; then + log_error "Model metadata not accessible (HTTP ${metadata_code})" + exit 1 fi - if [[ "$model_code" == "401" || "$model_code" == "403" ]]; then - log_error "Model is gated or token lacks access: ${model_id} (HTTP ${model_code})" + + # Detect gated/private + if echo "$metadata" | grep -q '"gated":true'; then + log_error "Model '${model_id}' is gated. Token must have accepted license." exit 1 fi - log_error "Unable to access model '${model_id}' (HTTP ${model_code})" - exit 1 + + if echo "$metadata" | grep -q '"private":true'; then + log_error "Model '${model_id}' is private and token lacks permission." + exit 1 + fi + + # Step 2: Verify real file download access (CRITICAL CHECK) + download_code=$(curl -s -o /dev/null -w "%{http_code}" \ + -H "Authorization: Bearer ${HF_TOKEN}" \ + "https://huggingface.co/${model_id}/resolve/main/config.json") + + if [[ "$download_code" != "200" ]]; then + log_error "Token does NOT have download access for ${model_id} (HTTP ${download_code})" + exit 1 + fi + + log_success "Access confirmed for ${model_id}" done } diff --git a/third_party/Dell/ubuntu-22.04/iac/mount-iso.sh b/third_party/Dell/ubuntu-22.04/iac/mount-iso.sh index 574ff267..0ba162c7 100644 --- a/third_party/Dell/ubuntu-22.04/iac/mount-iso.sh +++ b/third_party/Dell/ubuntu-22.04/iac/mount-iso.sh @@ -1,136 +1,141 @@ #!/bin/bash # Script to mount/unmount Ubuntu ISO via iDRAC Redfish API -# Usage: -# ./mount-iso.sh - Mount the ISO -# ./mount-iso.sh --unmount - Unmount the ISO -# ./mount-iso.sh -u - Unmount the ISO -# -# Environment variables: -# IDRAC_IP or IDRAC_HOST - iDRAC IP address or hostname (required) -# IDRAC_USER or IDRAC_USERNAME - iDRAC username (required) -# IDRAC_PASS or IDRAC_PASSWORD - iDRAC password (required) set -e -# Parse command line arguments UNMOUNT=false if [ "$1" = "--unmount" ] || [ "$1" = "-u" ]; then UNMOUNT=true fi -# Read from environment variables with fallback options IDRAC_IP="${IDRAC_IP:-${IDRAC_HOST}}" IDRAC_USER="${IDRAC_USER:-${IDRAC_USERNAME}}" IDRAC_PASS="${IDRAC_PASS:-${IDRAC_PASSWORD}}" + DEFAULT_ISO_URL="https://releases.ubuntu.com/22.04/ubuntu-22.04.5-live-server-amd64.iso" ISO_URL="${ISO_URL:-$DEFAULT_ISO_URL}" -# Validate required environment variables -if [ -z "$IDRAC_IP" ]; then - echo "❌ Error: IDRAC_IP or IDRAC_HOST environment variable is required" - echo " Example: export IDRAC_IP=100.67.153.16" - exit 1 -fi +SYSTEM_ID="System.Embedded.1" +VIRTUAL_MEDIA_SLOT="1" + +MAX_RETRIES=3 +SLEEP_INTERVAL=15 -if [ -z "$IDRAC_USER" ]; then - echo "❌ Error: IDRAC_USER or IDRAC_USERNAME environment variable is required" - echo " Example: export IDRAC_USER=root" +# Validate required env vars +if [ -z "$IDRAC_IP" ] || [ -z "$IDRAC_USER" ] || [ -z "$IDRAC_PASS" ]; then + echo "❌ Missing required environment variables (IDRAC_IP, IDRAC_USER, IDRAC_PASS)" exit 1 fi -if [ -z "$IDRAC_PASS" ]; then - echo "❌ Error: IDRAC_PASS or IDRAC_PASSWORD environment variable is required" - echo " Example: export IDRAC_PASS=calvin" +get_virtual_media_field() { + local FIELD=$1 + curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ + "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" \ + 2>/dev/null | python3 -c "import sys, json; print(json.load(sys.stdin).get('${FIELD}', 'None'))" 2>/dev/null || echo "None" +} + +verify_mount() { + echo "Verifying mount..." + + ATTEMPT=1 + while [ $ATTEMPT -le $MAX_RETRIES ]; do + echo " Attempt $ATTEMPT of $MAX_RETRIES..." + sleep $SLEEP_INTERVAL + + IMAGE=$(get_virtual_media_field "Image") + CONNECTED=$(get_virtual_media_field "ConnectedVia") + + if [ "$IMAGE" = "$ISO_URL" ]; then + echo " Image: $IMAGE" + echo " ConnectedVia: $CONNECTED" + echo "" + echo "✅ Ready for installation!" + exit 0 + fi + + ATTEMPT=$((ATTEMPT+1)) + done + + echo "❌ Mount verification failed after ${MAX_RETRIES} attempts." exit 1 -fi +} +verify_unmount() { + echo "Verifying unmount..." -#ISO_URL="https://releases.ubuntu.com/22.04/ubuntu-22.04.5-live-server-amd64.iso" -SYSTEM_ID="System.Embedded.1" -VIRTUAL_MEDIA_SLOT="1" + ATTEMPT=1 + while [ $ATTEMPT -le $MAX_RETRIES ]; do + echo " Attempt $ATTEMPT of $MAX_RETRIES..." + sleep $SLEEP_INTERVAL + + IMAGE=$(get_virtual_media_field "Image") + + if [ "$IMAGE" = "None" ] || [ "$IMAGE" = "null" ]; then + echo " ✅ Confirmed: No media mounted" + exit 0 + fi + + ATTEMPT=$((ATTEMPT+1)) + done + + echo "❌ Unmount verification failed after ${MAX_RETRIES} attempts." + exit 1 +} + +# ---------------- UNMOUNT ---------------- if [ "$UNMOUNT" = true ]; then echo "==========================================" echo "Unmounting Virtual Media via iDRAC Redfish API" echo "==========================================" - echo "" - - # Check current status - echo "Checking current virtual media status..." - CURRENT_IMAGE=$(curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ - "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" \ - 2>/dev/null | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('Image', 'None'))" 2>/dev/null || echo "None") - - if [ "$CURRENT_IMAGE" = "None" ] || [ "$CURRENT_IMAGE" = "null" ] || [ -z "$CURRENT_IMAGE" ]; then + + CURRENT_IMAGE=$(get_virtual_media_field "Image") + + if [ "$CURRENT_IMAGE" = "None" ] || [ "$CURRENT_IMAGE" = "null" ]; then echo "ℹ️ No media is currently mounted" exit 0 fi - + echo "Current mounted image: $CURRENT_IMAGE" - echo "" echo "Unmounting media..." - - RESPONSE=$(curl -sk --max-time 10 --connect-timeout 5 -w "\n%{http_code}" -u "${IDRAC_USER}:${IDRAC_PASS}" \ + + RESPONSE=$(curl -sk -w "\n%{http_code}" -u "${IDRAC_USER}:${IDRAC_PASS}" \ -X POST \ "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}/Actions/VirtualMedia.EjectMedia" \ -H "Content-Type: application/json" \ -d '{}' 2>&1) - + HTTP_CODE=$(echo "$RESPONSE" | tail -n1) - BODY=$(echo "$RESPONSE" | sed '$d') - + if [[ "$HTTP_CODE" =~ ^(200|202|204)$ ]]; then echo "✅ Media unmounted successfully!" - echo "" - echo "Verifying unmount..." - sleep 2 - - VERIFY_IMAGE=$(curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ - "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" \ - 2>/dev/null | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('Image', 'None'))" 2>/dev/null || echo "None") - - if [ "$VERIFY_IMAGE" = "None" ] || [ "$VERIFY_IMAGE" = "null" ]; then - echo " ✅ Confirmed: No media mounted" - exit 0 - else - echo " ⚠️ Media may still be mounted: $VERIFY_IMAGE" - exit 1 - fi + verify_unmount else echo "❌ Failed to unmount media. HTTP Code: $HTTP_CODE" - echo "Response: $BODY" exit 1 fi fi +# ---------------- MOUNT ---------------- + echo "==========================================" echo "Mounting Ubuntu ISO via iDRAC Redfish API" echo "==========================================" -echo "" -# Check if ISO is already mounted -echo "Checking current virtual media status..." -CURRENT_IMAGE=$(curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ - "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" \ - 2>/dev/null | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('Image', 'None'))" 2>/dev/null || echo "None") +CURRENT_IMAGE=$(get_virtual_media_field "Image") if [ "$CURRENT_IMAGE" = "$ISO_URL" ]; then - echo "✅ ISO is already mounted: $ISO_URL" - echo " ConnectedVia: $(curl -sk -u "${IDRAC_USER}:${IDRAC_PASS}" "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" 2>/dev/null | python3 -c "import sys, json; print(json.load(sys.stdin).get('ConnectedVia', 'N/A'))" 2>/dev/null || echo "N/A")" - echo "" - echo "Skipping mount - ISO already in place." + echo "✅ ISO already mounted: $ISO_URL" exit 0 fi -# Eject existing media if any if [ "$CURRENT_IMAGE" != "None" ] && [ "$CURRENT_IMAGE" != "null" ]; then echo "⚠️ Ejecting existing media: $CURRENT_IMAGE" - curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ + curl -sk -u "${IDRAC_USER}:${IDRAC_PASS}" \ -X POST \ "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}/Actions/VirtualMedia.EjectMedia" \ -H "Content-Type: application/json" \ - -d '{}' \ - > /dev/null 2>&1 || echo " (Eject may have failed, continuing anyway...)" + -d '{}' > /dev/null 2>&1 sleep 2 fi @@ -139,15 +144,13 @@ if [[ "$ISO_URL" =~ ^https:// ]]; then elif [[ "$ISO_URL" =~ ^http:// ]]; then TRANSFER_PROTOCOL="HTTP" else - echo "❌ Unsupported ISO URL scheme: $ISO_URL" + echo "❌ Unsupported ISO URL scheme" exit 1 fi -# Mount the ISO echo "Mounting ISO: $ISO_URL" -echo "" -RESPONSE=$(curl -sk --max-time 30 --connect-timeout 10 -w "\n%{http_code}" -u "${IDRAC_USER}:${IDRAC_PASS}" \ +RESPONSE=$(curl -sk -w "\n%{http_code}" -u "${IDRAC_USER}:${IDRAC_PASS}" \ -X POST \ "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}/Actions/VirtualMedia.InsertMedia" \ -H "Content-Type: application/json" \ @@ -158,34 +161,11 @@ RESPONSE=$(curl -sk --max-time 30 --connect-timeout 10 -w "\n%{http_code}" -u "$ }") HTTP_CODE=$(echo "$RESPONSE" | tail -n1) -BODY=$(echo "$RESPONSE" | sed '$d') -if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "202" ] || [ "$HTTP_CODE" = "204" ]; then - echo "✅ ISO mounted successfully!" - echo "" - echo "Verifying mount..." - sleep 3 - - MOUNTED_IMAGE=$(curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ - "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" \ - 2>/dev/null | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('Image', 'None'))" 2>/dev/null || echo "None") - - CONNECTED_VIA=$(curl -sk --max-time 10 --connect-timeout 5 -u "${IDRAC_USER}:${IDRAC_PASS}" \ - "https://${IDRAC_IP}/redfish/v1/Systems/${SYSTEM_ID}/VirtualMedia/${VIRTUAL_MEDIA_SLOT}" \ - 2>/dev/null | python3 -c "import sys, json; data=json.load(sys.stdin); print(data.get('ConnectedVia', 'N/A'))" 2>/dev/null || echo "N/A") - - if [ "$MOUNTED_IMAGE" = "$ISO_URL" ]; then - echo " Image: $MOUNTED_IMAGE" - echo " ConnectedVia: $CONNECTED_VIA" - echo "" - echo "✅ Ready for installation!" - exit 0 - else - echo "⚠️ Mount verification failed. Image: $MOUNTED_IMAGE" - exit 1 - fi +if [[ "$HTTP_CODE" =~ ^(200|202|204)$ ]]; then + echo "✅ ISO mount request accepted!" + verify_mount else echo "❌ Failed to mount ISO. HTTP Code: $HTTP_CODE" - echo "Response: $BODY" exit 1 fi \ No newline at end of file