XCP-ng
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login
    1. Home
    2. RaHu
    3. Topics
    R
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 2
    • Posts 9
    • Groups 0

    Topics

    • R

      Delete VM Snapshot over REST

      Watching Ignoring Scheduled Pinned Locked Moved Solved REST API
      7
      0 Votes
      7 Posts
      174 Views
      R
      @Danp Thanks! Finally I was able to get my script working. Also some contribution to "GROK" who assisted quite well! It allows a VM to Snapshot itself, before running automated maintenance over cron. And it allows minimalistic retention of the snapshots created this way. Happy to share it with the community: #!/bin/bash : <<'END' Snapshot Management Script for Xen Orchestra Usage: ./snapshot-vm.sh [OPTIONS] Options: -v Enable verbose output (detailed logging) -s Silent mode (suppress all non-error output) -r <number> Set retention limit (delete oldest snapshots beyond this number) -n No-snapshot mode (skip snapshot creation, only manage retention) Examples: ./snapshot-vm.sh # Create a snapshot, no retention ./snapshot-vm.sh -v -r 3 # Create a snapshot, keep latest 3, verbose ./snapshot-vm.sh -r 5 -n # Skip snapshot, keep latest 5 ./snapshot-vm.sh -v -s -r 2 # Create a snapshot, keep latest 2, verbose but silent Configuration: Edit XO_URL, TOKEN, and SNAPSHOT_PREFIX at the top of the script. END # Configuration variables XO_URL="http://your-xen-orchestra-server" TOKEN="your-authentication-token" VM_UUID=$(dmidecode -s system-uuid | tr '[:upper:]' '[:lower:]') SNAPSHOT_PREFIX="AutoMaintenance" # Prefix for snapshot names # Default retention (no deletion if not specified) RETENTION=-1 # Flags VERBOSE=0 SILENT=0 NOSNAPSHOT=0 # Parse command-line options while getopts "vsr:n" opt; do case $opt in v) VERBOSE=1;; s) SILENT=1;; r) RETENTION="$OPTARG";; n) NOSNAPSHOT=1;; esac done # Function to print messages based on mode print_msg() { if [ $SILENT -eq 0 ]; then if [ $VERBOSE -eq 1 ]; then echo "$1" else echo -e "$1" fi fi } # Check if we got the UUID if [ -z "$VM_UUID" ]; then echo "Error: Could not retrieve system UUID" exit 1 fi # Function to check if jq is installed check_jq() { if ! command -v jq &> /dev/null; then echo "Error: jq is required but not installed" exit 1 fi } # Function to get VM name get_vm_name() { local vm_info=$(curl -s -X GET \ -b "authenticationToken=$TOKEN" \ -H "Accept: application/json" \ "$XO_URL/rest/v0/vms/$VM_UUID") vm_name=$(echo "$vm_info" | jq -r '.name_label // "Unknown"') } # Function to trigger snapshot trigger_snapshot() { local SNAPSHOT_NAME="${SNAPSHOT_PREFIX}-$(date +%Y%m%d-%H%M%S)" if [ $VERBOSE -eq 1 ]; then local curl_cmd="curl -s -X POST \ -b \"authenticationToken=$TOKEN\" \ -H \"Content-Type: application/json\" \ -H \"Accept: application/json\" \ -d '{\"name_label\": \"$SNAPSHOT_NAME\"}' \ \"$XO_URL/rest/v0/vms/$VM_UUID/actions/snapshot\"" print_msg "Executing snapshot trigger command:" print_msg "$curl_cmd" print_msg "-----" fi response=$(curl -s -X POST \ -b "authenticationToken=$TOKEN" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d "{\"name_label\": \"$SNAPSHOT_NAME\"}" \ "$XO_URL/rest/v0/vms/$VM_UUID/actions/snapshot") if [ $VERBOSE -eq 1 ]; then print_msg "Snapshot trigger response: $response" print_msg "-----" fi if [[ "$response" =~ /rest/v0/tasks/([a-z0-9]+) ]]; then task_id="${BASH_REMATCH[1]}" if [ $VERBOSE -eq 1 ]; then print_msg "Snapshot triggered (Task ID: $task_id)" fi return 0 elif [[ "$response" =~ ^[a-z0-9]+$ ]]; then task_id="$response" if [ $VERBOSE -eq 1 ]; then print_msg "Snapshot triggered (Task ID: $task_id)" fi return 0 else print_msg "Error: Failed to get task ID. Response: $response" exit 1 fi } # Function to monitor task status monitor_task() { local task_id=$1 local max_attempts=30 local attempt=1 if [ $VERBOSE -eq 1 ]; then print_msg "Monitoring task $task_id..." fi while [ $attempt -le $max_attempts ]; do status_response=$(curl -s -X GET \ -b "authenticationToken=$TOKEN" \ -H "Accept: application/json" \ "$XO_URL/rest/v0/tasks/$task_id") if [ $VERBOSE -eq 1 ]; then print_msg "Attempt $attempt - Raw response: $status_response" fi if [ -n "$status_response" ] && echo "$status_response" | jq -e . >/dev/null 2>&1; then status=$(echo "$status_response" | jq -r '.status') if [ $VERBOSE -eq 1 ]; then print_msg "Status: $status" else print_msg "Taking Snapshot of VM: $vm_name... Status: $status" fi case "$status" in "pending"|"running") if [ $VERBOSE -eq 1 ]; then print_msg "Task still in progress" fi sleep 5 ((attempt++)) ;; "success") if [ $VERBOSE -eq 1 ]; then print_msg "Snapshot completed successfully" else print_msg "Taking Snapshot of VM: $vm_name... Status: Completed" fi return 0 ;; "failure") error=$(echo "$status_response" | jq -r '.result.message // "Unknown error"') print_msg "Task failed: $error" exit 1 ;; *) if [ $VERBOSE -eq 1 ]; then print_msg "Unknown status: $status" fi sleep 5 ((attempt++)) ;; esac else if [ $VERBOSE -eq 1 ]; then print_msg "Invalid or empty response" fi sleep 5 ((attempt++)) fi done print_msg "Timeout waiting for task completion" exit 1 } # Function to manage snapshot retention manage_retention() { if [ $RETENTION -lt 0 ]; then print_msg "Retention not specified, skipping cleanup" return 0 fi # Get VM data with snapshot UUIDs vm_data=$(curl -s -X GET \ -b "authenticationToken=$TOKEN" \ -H "Accept: application/json" \ "$XO_URL/rest/v0/vms/$VM_UUID") if [ $VERBOSE -eq 1 ]; then print_msg "Raw VM data response: $vm_data" print_msg "-----" fi if ! echo "$vm_data" | jq -e . >/dev/null 2>&1; then print_msg "Error: Invalid JSON response from VM endpoint" print_msg "Response: $vm_data" exit 1 fi # Extract snapshot UUIDs snapshot_uuids=$(echo "$vm_data" | jq -r '.snapshots[]') # Fetch details for each snapshot, verify existence, and filter by prefix auto_snapshots="" for uuid in $snapshot_uuids; do # Check existence with a HEAD request to avoid full body download http_status=$(curl -s -o /dev/null -w "%{http_code}" -I \ -b "authenticationToken=$TOKEN" \ "$XO_URL/rest/v0/vm-snapshots/$uuid") if [ "$http_status" -eq 404 ]; then if [ $VERBOSE -eq 1 ]; then print_msg "Snapshot $uuid does not exist (HTTP 404), skipping" print_msg "-----" fi continue elif [ "$http_status" -ne 200 ]; then if [ $VERBOSE -eq 1 ]; then print_msg "Unexpected HTTP status $http_status for snapshot $uuid, skipping" print_msg "-----" fi continue fi # Fetch full snapshot data if it exists snapshot_data=$(curl -s -X GET \ -b "authenticationToken=$TOKEN" \ -H "Accept: application/json" \ "$XO_URL/rest/v0/vm-snapshots/$uuid") if [ $VERBOSE -eq 1 ]; then print_msg "Snapshot $uuid data: $snapshot_data" print_msg "-----" fi # Verify it’s a valid JSON response if ! echo "$snapshot_data" | jq -e . >/dev/null 2>&1; then print_msg "Error: Invalid JSON response for snapshot $uuid" print_msg "Response: $snapshot_data" continue fi # Filter for snapshots with the specified prefix if echo "$snapshot_data" | jq -e ".name_label | startswith(\"$SNAPSHOT_PREFIX\")" >/dev/null 2>&1; then snapshot_line=$(echo "$snapshot_data" | jq -r '[.id, .name_label, .snapshot_time] | join("\t")') auto_snapshots="$auto_snapshots$snapshot_line\n" fi done # Sort by snapshot_time auto_snapshots=$(echo -e "$auto_snapshots" | sort -k3 -n | grep -v '^$') if [ $VERBOSE -eq 1 ]; then print_msg "Filtered and sorted $SNAPSHOT_PREFIX snapshots:" print_msg "$auto_snapshots" print_msg "-----" fi # Count current snapshots snapshot_count=$(echo "$auto_snapshots" | wc -l) print_msg "Current $SNAPSHOT_PREFIX snapshot count: $snapshot_count" # If over retention limit, delete oldest if [ $snapshot_count -gt $RETENTION ]; then excess=$((snapshot_count - RETENTION)) print_msg "Excess snapshots to delete: $excess" # Get IDs of oldest snapshots to delete delete_ids=$(echo "$auto_snapshots" | head -n $excess | cut -f1) for id in $delete_ids; do if [ $VERBOSE -eq 1 ]; then print_msg "Deleting snapshot $id" print_msg "Delete command: curl -s -X DELETE -b \"authenticationToken=$TOKEN\" \"$XO_URL/rest/v0/vm-snapshots/$id\"" fi delete_response=$(curl -s -X DELETE \ -b "authenticationToken=$TOKEN" \ "$XO_URL/rest/v0/vm-snapshots/$id") if [ $VERBOSE -eq 1 ]; then print_msg "Delete response: $delete_response" print_msg "-----" fi # Treat empty response, {"status": "success"}, or "OK" as success if [ -z "$delete_response" ] || echo "$delete_response" | jq -e '.status == "success"' >/dev/null 2>&1 || [ "$delete_response" = "OK" ]; then print_msg "Successfully deleted snapshot $id" else print_msg "Warning: Failed to delete snapshot $id. Response: $delete_response" fi done else if [ $VERBOSE -eq 1 ]; then print_msg "No excess snapshots to delete" fi fi } # Main execution check_jq get_vm_name if [ $VERBOSE -eq 1 ]; then print_msg "Using VM UUID: $VM_UUID" fi if [ $NOSNAPSHOT -eq 0 ]; then trigger_snapshot monitor_task "$task_id" else if [ $VERBOSE -eq 1 ]; then print_msg "Skipping snapshot creation due to --nosnapshot flag" fi fi manage_retention exit 0 Cheers!
    • R

      Netbox plugin: VM's IP not in Netbox

      Watching Ignoring Scheduled Pinned Locked Moved Xen Orchestra
      6
      0 Votes
      6 Posts
      1k Views
      pdoniasP
      Hi @RaHu! No, at the moment, we don't synchronize hosts' information. I'm not even sure where that information could go as there isn't such a thing as a host object in Netbox, AFAIK.