proxmos
This commit is contained in:
Executable
+178
@@ -0,0 +1,178 @@
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
# Load the .env file that lives beside the script
|
||||
set -a # automatically export assignments
|
||||
source "${SCRIPT_DIR}/.env"
|
||||
set +a
|
||||
|
||||
# ---- login ----
|
||||
login=$(curl -s -k -d "username=${USERNAME}&password=${PASSWORD}" \
|
||||
"https://${ADDR}:8006/api2/json/access/ticket")
|
||||
echo "=== LOGIN RESPONSE ==="
|
||||
echo "$login"
|
||||
echo "======================"
|
||||
|
||||
# Extract ticket & CSRF
|
||||
TICKET=$(echo "$login" | grep -o '"ticket":"[^"]*' | cut -d'"' -f4)
|
||||
CSRF=$(echo "$login" | grep -o '"CSRFPreventionToken":"[^"]*' | cut -d'"' -f4)
|
||||
|
||||
echo "Ticket: $TICKET"
|
||||
echo "CSRF : $CSRF"
|
||||
echo "-------------------"
|
||||
|
||||
# -------------------------------------------------
|
||||
# Helper: wait for a Proxmox task to finish
|
||||
# -------------------------------------------------
|
||||
wait_task() {
|
||||
local upid="$1"
|
||||
local timeout=${2:-40} # seconds (default 2 min)
|
||||
local interval=2
|
||||
local elapsed=0
|
||||
|
||||
while (( elapsed < timeout )); do
|
||||
result=$(curl -s -k \
|
||||
-b "PVEAuthCookie=${TICKET}" \
|
||||
-H "CSRFPreventionToken: ${CSRF}" \
|
||||
"https://${ADDR}:8006/api2/json/nodes/${ADDR}/tasks/${upid}/status")
|
||||
status=$(echo "$result" | jq -r '.data.status')
|
||||
exitstatus=$(echo "$result" | jq -r '.data.exitstatus')
|
||||
|
||||
if [[ "$status" == "stopped" ]]; then
|
||||
if [[ "$exitstatus" == "OK" ]]; then
|
||||
return 0
|
||||
else
|
||||
echo "Task $upid finished with error: $exitstatus" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep "$interval"
|
||||
(( elapsed += interval ))
|
||||
done
|
||||
|
||||
echo "Task $upid timed out after $timeout seconds" >&2
|
||||
return 1
|
||||
}
|
||||
# -------------------------------------------------
|
||||
|
||||
force_stop_vm_ssh() {
|
||||
local vmid=$1
|
||||
local node=$2 # e.g. pve01
|
||||
|
||||
# SSH to the node (assumes key‑based auth or passwordless login)
|
||||
ssh root@"${node}" bash <<EOF
|
||||
# Remove stale lock if it exists
|
||||
lock="/var/lock/qemu-server/lock-${vmid}.conf"
|
||||
if [[ -e "\$lock" ]]; then
|
||||
pid=\$(fuser -n file "\$lock" 2>/dev/null | awk '{print \$1}')
|
||||
[[ -n "\$pid" ]] && kill -9 "\$pid"
|
||||
rm -f "\$lock"
|
||||
fi
|
||||
|
||||
# Stop the VM
|
||||
qm stop "${vmid}"
|
||||
# Wait until it reports stopped
|
||||
while qm status "${vmid}" | grep -q running; do sleep 1; done
|
||||
EOF
|
||||
echo "VM $vmid on node $node is now stopped."
|
||||
}
|
||||
|
||||
while true; do
|
||||
echo "Select an option:"
|
||||
echo "1) get nodes"
|
||||
echo "2) get vm"
|
||||
echo "3) create vm"
|
||||
echo "4) power vm"
|
||||
echo "5) delete vm"
|
||||
echo "6) Exit"
|
||||
printf "Enter choice [1-6]: "
|
||||
|
||||
read choice
|
||||
case $choice in
|
||||
1)
|
||||
# Show only VM IDs and names
|
||||
curl -s -k -b "PVEAuthCookie=${TICKET}" -H "CSRFPreventionToken: ${CSRF}" \
|
||||
"https://${ADDR}:8006/api2/json/cluster/resources?type=vm" |
|
||||
jq '.data[] | {vmid, name, status, node}'
|
||||
|
||||
;;
|
||||
2)
|
||||
curl -s -k -b "PVEAuthCookie=${TICKET}" -H "CSRFPreventionToken: ${CSRF}" \
|
||||
"https://${ADDR}:8006/api2/json/cluster/resources?type=vm" | jq .
|
||||
;;
|
||||
3)
|
||||
echo "PrintID:"
|
||||
read id
|
||||
echo "PintNAME:"
|
||||
read name
|
||||
curl -k -X POST \
|
||||
-b "PVEAuthCookie=${TICKET}" \
|
||||
-H "CSRFPreventionToken: ${CSRF}" \
|
||||
-d "vmid=${id}&name=${name}&memory=2048&net0=virtio,bridge=vmbr0" \
|
||||
https://${ADDR}:8006/api2/json/nodes/${ADDR}/qemu
|
||||
;;
|
||||
4)
|
||||
echo "PrintID:"
|
||||
read id
|
||||
curl -k -X POST \
|
||||
-b "PVEAuthCookie=${TICKET}" \
|
||||
-H "CSRFPreventionToken: ${CSRF}" \
|
||||
https://${ADDR}:8006/api2/json/nodes/${ADDR}/qemu/${id}/status/start
|
||||
;;
|
||||
5)
|
||||
echo "PrintID:"; read id
|
||||
|
||||
# -------------------------------------------------
|
||||
# 1️⃣ Find the node that actually hosts the VM
|
||||
# -------------------------------------------------
|
||||
VM_INFO=$(curl -s -k -b "PVEAuthCookie=${TICKET}" \
|
||||
-H "CSRFPreventionToken: ${CSRF}" \
|
||||
"https://${ADDR}:8006/api2/json/cluster/resources?type=vm")
|
||||
VM_NODE=$(echo "$VM_INFO" | jq -r --arg id "$id" \
|
||||
'.data[] | select(.vmid == ($id|tonumber)) | .node')
|
||||
if [[ -z "$VM_NODE" ]]; then
|
||||
echo "Could not locate VM $id"
|
||||
continue
|
||||
fi
|
||||
echo "VM $id is on node $VM_NODE"
|
||||
|
||||
# -------------------------------------------------
|
||||
# 2️⃣ Stop the VM via API and wait for the task
|
||||
# -------------------------------------------------
|
||||
stop_resp=$(curl -s -k -X POST \
|
||||
-b "PVEAuthCookie=${TICKET}" \
|
||||
-H "CSRFPreventionToken: ${CSRF}" \
|
||||
"https://${ADDR}:8006/api2/json/nodes/${VM_NODE}/qemu/${id}/status/stop")
|
||||
stop_upid=$(echo "$stop_resp" | jq -r '.data')
|
||||
echo "Stop task UPID: $stop_upid"
|
||||
|
||||
if ! wait_task "$stop_upid"; then
|
||||
echo "Failed to stop VM $id – aborting delete."
|
||||
continue
|
||||
fi
|
||||
echo "VM $id is now stopped."
|
||||
|
||||
# -------------------------------------------------
|
||||
# 3️⃣ Destroy the VM via API and wait for the task
|
||||
# -------------------------------------------------
|
||||
destroy_resp=$(curl -s -k -X POST \
|
||||
-b "PVEAuthCookie=${TICKET}" \
|
||||
-H "CSRFPreventionToken: ${CSRF}" \
|
||||
"https://${ADDR}:8006/api2/json/nodes/${VM_NODE}/qemu/${id}/destroy")
|
||||
destroy_upid=$(echo "$destroy_resp" | jq -r '.data')
|
||||
echo "Destroy task UPID: $destroy_upid"
|
||||
|
||||
if wait_task "$destroy_upid"; then
|
||||
echo "VM $id successfully removed."
|
||||
else
|
||||
echo "Failed to destroy VM $id."
|
||||
fi
|
||||
;;
|
||||
6)
|
||||
echo "Goodbye!"; exit 0
|
||||
;;
|
||||
*)
|
||||
echo "Invalid choice, try again."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
Reference in New Issue
Block a user