Files
sibsutis/procxmos/manip.sh
T
Павел Родионов b558aaa76d proxmos
2025-11-28 18:58:15 +07:00

179 lines
5.6 KiB
Bash
Executable File
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 2min)
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 keybased 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