del test. add wayland
This commit is contained in:
@@ -1,178 +0,0 @@
|
|||||||
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:-120} # 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
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
set -euo pipefail
|
|
||||||
set -x # optional: keep for debugging
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
# Determine the directory that contains this script (handles symlinks)
|
|
||||||
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
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
|
|
||||||
echo "ADDR = ${ADDR}"
|
|
||||||
echo "USERNAME = ${USERNAME}"
|
|
||||||
echo "PASSWORD = ${PASSWORD}"
|
|
||||||
|
|
||||||
# ---- 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 "-------------------"
|
|
||||||
|
|
||||||
if [[ -n "$TICKET" && -n "$CSRF" ]]; then
|
|
||||||
vmlist=$(curl -s -k -b "PVEAuthCookie=${TICKET}" \
|
|
||||||
-H "CSRFPreventionToken: ${CSRF}" \
|
|
||||||
"https://${ADDR}:8006/api2/json/cluster/resources?type=vm")
|
|
||||||
echo "=== VM LIST RAW ==="
|
|
||||||
echo "$vmlist"
|
|
||||||
echo "===================="
|
|
||||||
if command -v jq >/dev/null 2>&1; then
|
|
||||||
echo "=== VM LIST FORMATTED ==="
|
|
||||||
echo "$vmlist" | jq .
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Login failed – no ticket/CSRF token."
|
|
||||||
fi
|
|
||||||
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
set -euo pipefail
|
|
||||||
set -x # optional: keep for debugging
|
|
||||||
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
# Determine the directory that contains this script (handles symlinks)
|
|
||||||
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
|
|
||||||
# ------------------------------------------------------------------
|
|
||||||
|
|
||||||
echo "ADDR = ${ADDR}"
|
|
||||||
echo "USERNAME = ${USERNAME}"
|
|
||||||
echo "PASSWORD = ${PASSWORD}"
|
|
||||||
|
|
||||||
# ---- 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 "-------------------"
|
|
||||||
|
|
||||||
if [[ -n "$TICKET" && -n "$CSRF" ]]; then
|
|
||||||
vmlist=$(curl -s -k -b "PVEAuthCookie=${TICKET}" \
|
|
||||||
-H "CSRFPreventionToken: ${CSRF}" \
|
|
||||||
"https://${ADDR}:8006/api2/json/cluster/resources?type=vm")
|
|
||||||
echo "=== VM LIST RAW ==="
|
|
||||||
echo "$vmlist"
|
|
||||||
echo "===================="
|
|
||||||
if command -v jq >/dev/null 2>&1; then
|
|
||||||
echo "=== VM LIST FORMATTED ==="
|
|
||||||
echo "$vmlist" | jq .
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Login failed – no ticket/CSRF token."
|
|
||||||
fi
|
|
||||||
|
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wayland-client.h>
|
||||||
|
|
||||||
|
// 1. Обработчик глобальных объектов (Global Registry)
|
||||||
|
static void global_registry_handler(void *data, struct wl_registry *registry,
|
||||||
|
uint32_t id, const char *interface, uint32_t version) {
|
||||||
|
|
||||||
|
// Выводим имя интерфейса, чтобы показать, какие сервисы доступны
|
||||||
|
printf("Обнаружен глобальный объект: id: %u, интерфейс: %s, версия: %u\n",
|
||||||
|
id, interface, version);
|
||||||
|
|
||||||
|
// В реальном приложении здесь происходит привязка к нужным интерфейсам
|
||||||
|
// (например, wl_compositor, xdg_wm_base) для создания окон.
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Обработчик удаления глобальных объектов
|
||||||
|
static void global_registry_remover(void *data, struct wl_registry *registry, uint32_t id) {
|
||||||
|
printf("Объект удален: id: %u\n", id);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Структура для слушателей реестра
|
||||||
|
static const struct wl_registry_listener registry_listener = {
|
||||||
|
.global = global_registry_handler,
|
||||||
|
.global_remove = global_registry_remover,
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
// 4. Установка соединения с Wayland-дисплеем
|
||||||
|
struct wl_display *display = wl_display_connect(NULL);
|
||||||
|
if (display == NULL) {
|
||||||
|
fprintf(stderr, "Не удалось подключиться к Wayland-дисплею.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Успешное подключение к Wayland-дисплею.\n");
|
||||||
|
|
||||||
|
// 5. Получение реестра глобальных объектов
|
||||||
|
struct wl_registry *registry = wl_display_get_registry(display);
|
||||||
|
if (registry == NULL) {
|
||||||
|
fprintf(stderr, "Не удалось получить реестр.\n");
|
||||||
|
wl_display_disconnect(display);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. Добавление слушателя к реестру
|
||||||
|
wl_registry_add_listener(registry, ®istry_listener, NULL);
|
||||||
|
|
||||||
|
// 7. Ожидание ответа от композитора (обработка всех глобальных объектов)
|
||||||
|
// Wayland работает асинхронно, wl_display_dispatch_pending() обрабатывает
|
||||||
|
// все сообщения, включая список глобальных объектов, который присылает композитор.
|
||||||
|
wl_display_dispatch(display);
|
||||||
|
wl_display_roundtrip(display); // Убеждаемся, что все сообщения обработаны
|
||||||
|
|
||||||
|
// 8. Очистка ресурсов
|
||||||
|
wl_registry_destroy(registry);
|
||||||
|
wl_display_disconnect(display);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
Executable
BIN
Binary file not shown.
Reference in New Issue
Block a user