added force shutdown toggle

This commit is contained in:
WeeXnes 2025-02-27 09:20:21 +01:00
parent 9211d4e6ec
commit 8615047c9b
2 changed files with 25 additions and 10 deletions

View file

@ -33,6 +33,7 @@ const shutdownVm = async (vm: any) => {
try { try {
const response = await axios.post('/api/controlVM', { const response = await axios.post('/api/controlVM', {
action: 'shutdown', action: 'shutdown',
force: settings.force_shutdown,
vm: vm vm: vm
}); });
console.log(response.data); console.log(response.data);
@ -53,6 +54,7 @@ const settings = reactive({
ignoreCache: false, ignoreCache: false,
enable_services: false, enable_services: false,
enable_qemu_controls: false, enable_qemu_controls: false,
force_shutdown: false
}); });
const vmInfo = reactive({ const vmInfo = reactive({
@ -274,6 +276,16 @@ onMounted(async () => {
</div> </div>
<h1 v-if="settings.enable_qemu_controls" class="text-4xl font-bold text-center mb-6">QEMU Virtual Machines</h1> <h1 v-if="settings.enable_qemu_controls" class="text-4xl font-bold text-center mb-6">QEMU Virtual Machines</h1>
<div class="form-control flex flex-row gap-2 mb-6">
<label class="label cursor-pointer flex items-center gap-2">
<span class="label-text">Force Shutdown</span>
<input
type="checkbox"
class="checkbox checkbox-primary"
v-model="settings.force_shutdown"
/>
</label>
</div>
<div v-if="settings.enable_qemu_controls" class="grid md:grid-cols-3 gap-6 w-full max-w-5xl mb-8"> <div v-if="settings.enable_qemu_controls" class="grid md:grid-cols-3 gap-6 w-full max-w-5xl mb-8">
<div <div
v-for="vm in vmInfo.vms" v-for="vm in vmInfo.vms"
@ -288,13 +300,20 @@ onMounted(async () => {
<p><strong>Max Memory:</strong> {{ vm.maxMemory }} MB</p> <p><strong>Max Memory:</strong> {{ vm.maxMemory }} MB</p>
<p><strong>Autostart:</strong> {{ vm.autostart ? 'Enabled' : 'Disabled' }}</p> <p><strong>Autostart:</strong> {{ vm.autostart ? 'Enabled' : 'Disabled' }}</p>
</div> </div>
<div class="form-control mt-4 flex flex-row gap-2"> <div class="form-control mt-4 flex flex-row gap-2">
<button @click="startVm(vm)" class="btn btn-primary w-1/2">Start</button> <button @click="startVm(vm)" class="btn btn-primary w-1/2">Start</button>
<button @click="shutdownVm(vm)" class="btn btn-error w-1/2">Shutdown</button> <button
@click="shutdownVm(vm)"
:class="settings.force_shutdown ? 'btn btn-error w-1/2' : 'btn btn-warning w-1/2'"
class="w-1/2">
{{ settings.force_shutdown ? 'Kill' : 'Shutdown' }}
</button>
</div> </div>
</div> </div>
</div> </div>
<h1 v-if="serviceInfo.isLoaded" class="text-4xl font-bold text-center mb-6">Services</h1> <h1 v-if="serviceInfo.isLoaded" class="text-4xl font-bold text-center mb-6">Services</h1>
<div v-if="serviceInfo.isLoaded" class="grid md:grid-cols-3 gap-6 w-full max-w-5xl"> <div v-if="serviceInfo.isLoaded" class="grid md:grid-cols-3 gap-6 w-full max-w-5xl">
<div <div
@ -307,10 +326,6 @@ onMounted(async () => {
<p><strong>Name:</strong> {{ service.name }}</p> <p><strong>Name:</strong> {{ service.name }}</p>
<p><strong>State:</strong> {{ service.state ? "Running" : "Not Running" }}</p> <p><strong>State:</strong> {{ service.state ? "Running" : "Not Running" }}</p>
</div> </div>
<div class="form-control mt-4 flex flex-row gap-2">
<button class="btn btn-primary w-1/2">Start</button>
<button class="btn btn-error w-1/2">Stop</button>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -3,17 +3,17 @@ import Logger from "~/core/logger";
export default defineEventHandler(async (event) => { export default defineEventHandler(async (event) => {
const body = await readBody(event); const body = await readBody(event);
const { action, vm } = body; const { action, force, vm } = body;
try { try {
const command = action === 'start' const command = action === 'start' ? `virsh start ${vm.name}` : (force ? `virsh destroy ${vm.name}` : `virsh shutdown ${vm.name}`);
? `virsh start ${vm.name}`
: `virsh shutdown ${vm.name}`; console.log(command);
await new Promise((resolve, reject) => { await new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => { exec(command, (error, stdout, stderr) => {
if (error || stderr) {; if (error || stderr) {
Logger.error(`Error: ${stderr || error?.message}`); Logger.error(`Error: ${stderr || error?.message}`);
reject(`Error: ${stderr || error?.message}`) reject(`Error: ${stderr || error?.message}`)
} }