From d9fadb7712e85837dc0ef01d73ff9c442bcf5b92 Mon Sep 17 00:00:00 2001 From: Muzaffer AKYIL Date: Sat, 3 Sep 2022 16:54:25 +0300 Subject: [PATCH 1/4] add start/resume for stopped/paused vm options and delay options feature --- .gitignore | 3 +- src/Corsinvest.ProxmoxVE.Pepper/Program.cs | 50 ++++++++++++++++++++-- 2 files changed, 48 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 8cc5134..94f1b08 100644 --- a/.gitignore +++ b/.gitignore @@ -351,4 +351,5 @@ MigrationBackup/ # Ionide (cross platform F# VS Code tools) working folder .ionide/ -TestParm.parm \ No newline at end of file +TestParm.parm +.idea/.idea.Corsinvest.ProxmoxVE.Pepper/.idea/ diff --git a/src/Corsinvest.ProxmoxVE.Pepper/Program.cs b/src/Corsinvest.ProxmoxVE.Pepper/Program.cs index 961eb3b..0fcfc73 100644 --- a/src/Corsinvest.ProxmoxVE.Pepper/Program.cs +++ b/src/Corsinvest.ProxmoxVE.Pepper/Program.cs @@ -13,6 +13,7 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using Corsinvest.ProxmoxVE.Api.Extension; using Corsinvest.ProxmoxVE.Api.Extension.Utils; +using Corsinvest.ProxmoxVE.Api.Shared.Models.Vm; using Corsinvest.ProxmoxVE.Api.Shell.Helpers; namespace Corsinvest.ProxmoxVE.Pepper @@ -35,6 +36,16 @@ namespace Corsinvest.ProxmoxVE.Pepper var optViewerOptions = app.AddOption("--viewer-options", "Send options directly SPICE Viewer (quote value)."); + var optStartOrResume = app.AddOption("--start-or-resume", "Run stopped or paused VM"); + optStartOrResume.IsRequired = false; + optStartOrResume.SetDefaultValue("false"); + + var optWaitForStartup = app.AddOption("--wait-for-startup", "Wait for startup VM"); + optWaitForStartup.IsRequired = false; + optWaitForStartup.SetDefaultValue(5); + + var startOrResume = optStartOrResume.GetValue() == "true"; + app.SetHandler(async (InvocationContext ctx) => { var loggerFactory = ConsoleHelper.CreateLoggerFactory(app.GetLogLevelFromDebug()); @@ -44,7 +55,37 @@ namespace Corsinvest.ProxmoxVE.Pepper if (string.IsNullOrWhiteSpace(proxy)) { proxy = client.Host; } var vm = await client.GetVm(optVmId.GetValue()); - var (success, reasonPhrase, content) = await VmHelper.GetQemuSpiceFileVV(client, vm.Node,vm.VmId, proxy); + + if (startOrResume && (vm.IsStopped || vm.IsPaused)) + { + if (app.DebugIsActive()) + { + await Console.Out.WriteLineAsync( + $"VM is {(vm.IsStopped ? "stopped" : "paused")}. {(vm.IsStopped ? "Running" : "Resuming")} now!"); + } + + await VmHelper.ChangeStatusVm(client, vm.Node, vm.VmType, vm.VmId, + vm.IsStopped ? VmStatus.Start : VmStatus.Resume); + + for (var i = 1; i < int.Parse(optWaitForStartup.GetValue()); i++) + { + if (app.DebugIsActive()) + { + await Console.Out.WriteAsync($"\r{10 - i}"); + } + + await Task.Delay(1000); + } + + if (app.DebugIsActive()) + { + await Console.Out.WriteLineAsync(); + await Console.Out.WriteLineAsync("VM is running."); + } + } + + var (success, reasonPhrase, content) = + await VmHelper.GetQemuSpiceFileVV(client, vm.Node, vm.VmId, proxy); if (success) { //proxy force @@ -59,6 +100,7 @@ namespace Corsinvest.ProxmoxVE.Pepper break; } } + content = string.Join("\n", lines); if (app.DebugIsActive()) @@ -97,8 +139,8 @@ namespace Corsinvest.ProxmoxVE.Pepper if (app.DebugIsActive()) { - Console.Out.WriteLine($"Run FileName: {process.StartInfo.FileName}"); - Console.Out.WriteLine($"Run Arguments: {process.StartInfo.Arguments}"); + await Console.Out.WriteLineAsync($"Run FileName: {process.StartInfo.FileName}"); + await Console.Out.WriteLineAsync($"Run Arguments: {process.StartInfo.Arguments}"); } if (!app.DryRunIsActive()) @@ -111,7 +153,7 @@ namespace Corsinvest.ProxmoxVE.Pepper } else { - Console.Out.WriteLine($"Error: {reasonPhrase}"); + await Console.Out.WriteLineAsync($"Error: {reasonPhrase}"); ctx.ExitCode = 1; } }); From 78263ce4c132962e985f822a21c8c733dd8ff636 Mon Sep 17 00:00:00 2001 From: Muzaffer AKYIL Date: Sat, 3 Sep 2022 16:59:39 +0300 Subject: [PATCH 2/4] doc updated --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 70c7149..535079c 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,8 @@ Options: http(s)://[host]:[port] then replace proxy option in file .vv. E.g. for reverse proxy. --viewer (REQUIRED) Executable SPICE client remote viewer. --viewer-options Send options directly SPICE Viewer (quote value). + --start-or-resume Run stopped or paused VM [default: false] + --wait-for-startup Wait for startup VM [default: 5] --version Show version information -?, -h, --help Show help and usage information @@ -69,6 +71,7 @@ this software aims to simplify run SPICE client from Proxmox VE using command li * Execute out side Proxmox VE * Not require Web login * Support multiple host for HA in --host parameter es. host[:port],host1[:port],host2[:port] +* Start or Resume VM on connection * Check-Update and Upgrade application * Use Api token --api-token parameter * Send options directly to viewer From b2797a3ebe9c8194fad56e9e6effac48cacce9e1 Mon Sep 17 00:00:00 2001 From: Daniele Corsini Date: Tue, 13 Sep 2022 16:02:39 +0200 Subject: [PATCH 3/4] doc updated --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 535079c..851974c 100644 --- a/README.md +++ b/README.md @@ -21,20 +21,20 @@ Usage: cv4pve-pepper [command] [options] Options: - --host (REQUIRED) The host name host[:port],host1[:port],host2[:port] - --api-token Api token format 'USER@REALM!TOKENID=UUID'. Require Proxmox VE 6.2 or later - --username User name @ - --password The password. Specify 'file:path_file' to store password in file. - --vmid The id or name VM/CT - --proxy SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs - 'spiceproxy', so it is up to the client to choose one. By default, we return the node to connect. If specify - http(s)://[host]:[port] then replace proxy option in file .vv. E.g. for reverse proxy. - --viewer (REQUIRED) Executable SPICE client remote viewer. - --viewer-options Send options directly SPICE Viewer (quote value). - --start-or-resume Run stopped or paused VM [default: false] - --wait-for-startup Wait for startup VM [default: 5] - --version Show version information - -?, -h, --help Show help and usage information + --host (REQUIRED) The host name host[:port],host1[:port],host2[:port] + --api-token Api token format 'USER@REALM!TOKENID=UUID'. Require Proxmox VE 6.2 or later + --username User name @ + --password The password. Specify 'file:path_file' to store password in file. + --vmid The id or name VM/CT + --proxy SPICE proxy server. This can be used by the client to specify the proxy server. All nodes in a cluster runs + 'spiceproxy', so it is up to the client to choose one. By default, we return the node to connect. If specify + http(s)://[host]:[port] then replace proxy option in file .vv. E.g. for reverse proxy. + --viewer (REQUIRED) Executable SPICE client remote viewer. + --viewer-options Send options directly SPICE Viewer (quote value). + --start-or-resume Run stopped or paused VM + --wait-for-startup Wait sec. for startup VM [default: 5] + --version Show version information + -?, -h, --help Show help and usage information Commands: app-check-update Check update application From 6eaa9a20af1efc51f9d027d604f7f795949031b9 Mon Sep 17 00:00:00 2001 From: Daniele Corsini Date: Tue, 13 Sep 2022 16:04:18 +0200 Subject: [PATCH 4/4] @victorioustr add start/resume for stopped/paused vm options and delay options feature --- src/Corsinvest.ProxmoxVE.Pepper/Program.cs | 53 ++++++++-------------- 1 file changed, 18 insertions(+), 35 deletions(-) diff --git a/src/Corsinvest.ProxmoxVE.Pepper/Program.cs b/src/Corsinvest.ProxmoxVE.Pepper/Program.cs index 0fcfc73..95f3d2a 100644 --- a/src/Corsinvest.ProxmoxVE.Pepper/Program.cs +++ b/src/Corsinvest.ProxmoxVE.Pepper/Program.cs @@ -1,4 +1,4 @@ -/* +/* * SPDX-FileCopyrightText: Copyright Corsinvest Srl * SPDX-License-Identifier: GPL-3.0-only */ @@ -36,15 +36,10 @@ namespace Corsinvest.ProxmoxVE.Pepper var optViewerOptions = app.AddOption("--viewer-options", "Send options directly SPICE Viewer (quote value)."); - var optStartOrResume = app.AddOption("--start-or-resume", "Run stopped or paused VM"); - optStartOrResume.IsRequired = false; - optStartOrResume.SetDefaultValue("false"); + var optStartOrResume = app.AddOption("--start-or-resume", "Run stopped or paused VM"); - var optWaitForStartup = app.AddOption("--wait-for-startup", "Wait for startup VM"); - optWaitForStartup.IsRequired = false; + var optWaitForStartup = app.AddOption("--wait-for-startup", "Wait sec. for startup VM"); optWaitForStartup.SetDefaultValue(5); - - var startOrResume = optStartOrResume.GetValue() == "true"; app.SetHandler(async (InvocationContext ctx) => { @@ -56,36 +51,25 @@ namespace Corsinvest.ProxmoxVE.Pepper var vm = await client.GetVm(optVmId.GetValue()); - if (startOrResume && (vm.IsStopped || vm.IsPaused)) + if (optStartOrResume.GetValue() && (vm.IsStopped || vm.IsPaused)) { - if (app.DebugIsActive()) - { - await Console.Out.WriteLineAsync( - $"VM is {(vm.IsStopped ? "stopped" : "paused")}. {(vm.IsStopped ? "Running" : "Resuming")} now!"); - } - - await VmHelper.ChangeStatusVm(client, vm.Node, vm.VmType, vm.VmId, - vm.IsStopped ? VmStatus.Start : VmStatus.Resume); - - for (var i = 1; i < int.Parse(optWaitForStartup.GetValue()); i++) - { - if (app.DebugIsActive()) - { - await Console.Out.WriteAsync($"\r{10 - i}"); - } - - await Task.Delay(1000); - } + var status = vm.IsStopped ? VmStatus.Start : VmStatus.Resume; if (app.DebugIsActive()) { - await Console.Out.WriteLineAsync(); - await Console.Out.WriteLineAsync("VM is running."); + await Console.Out.WriteLineAsync($"VM is {(vm.IsStopped ? "stopped" : "paused")}. {status} now!"); } + + //start VM + var result = await VmHelper.ChangeStatusVm(client, vm.Node, vm.VmType, vm.VmId, status); + await client.WaitForTaskToFinish(result, timeout: optWaitForStartup.GetValue() * 1000); + + //check VM is running + vm = await client.GetVm(optVmId.GetValue()); + if (app.DebugIsActive()) { await Console.Out.WriteLineAsync($"VM is {vm.Status}."); } } - var (success, reasonPhrase, content) = - await VmHelper.GetQemuSpiceFileVV(client, vm.Node, vm.VmId, proxy); + var (success, reasonPhrase, content) = await VmHelper.GetQemuSpiceFileVV(client, vm.Node, vm.VmId, proxy); if (success) { //proxy force @@ -100,13 +84,12 @@ namespace Corsinvest.ProxmoxVE.Pepper break; } } - content = string.Join("\n", lines); if (app.DebugIsActive()) { - Console.Out.WriteLine($"Replace Proxy: {proxy}"); - Console.Out.WriteLine(content); + await Console.Out.WriteLineAsync($"Replace Proxy: {proxy}"); + await Console.Out.WriteLineAsync(content); } } @@ -161,4 +144,4 @@ namespace Corsinvest.ProxmoxVE.Pepper return await app.ExecuteApp(args); } } -} \ No newline at end of file +}