From 4107d267b184409a882390287177cec467dd2e2c Mon Sep 17 00:00:00 2001 From: Florent Gluck <florent.gluck@hesge.ch> Date: Thu, 4 Aug 2022 13:00:57 +0200 Subject: [PATCH] Added 2 commands: vmlistexportdir List VMs that can have a directory exported (regex matching). vmexportdir Export one or more VMs' directory into one or more tar archives. Create one archive per VM (regex matching). --- README.md | 7 +++ src/client_cli/cmdVM/helper.go | 16 ++--- src/client_cli/cmdVM/vmAttach.go | 5 +- src/client_cli/cmdVM/vmCred2pdf.go | 11 +--- src/client_cli/cmdVM/vmDel.go | 5 +- src/client_cli/cmdVM/vmDelAccess.go | 2 +- src/client_cli/cmdVM/vmEdit.go | 2 +- src/client_cli/cmdVM/vmExportDir.go | 78 ++++++++++++++++++++++++ src/client_cli/cmdVM/vmList.go | 9 ++- src/client_cli/cmdVM/vmListAttach.go | 3 +- src/client_cli/cmdVM/vmListDel.go | 3 +- src/client_cli/cmdVM/vmListEdit.go | 3 +- src/client_cli/cmdVM/vmListEditAccess.go | 3 +- src/client_cli/cmdVM/vmListExportDir.go | 22 +++++++ src/client_cli/cmdVM/vmListStart.go | 3 +- src/client_cli/cmdVM/vmListStop.go | 3 +- src/client_cli/cmdVM/vmSetAccess.go | 2 +- src/client_cli/cmdVM/vmStart.go | 5 +- src/client_cli/cmdVM/vmStop.go | 5 +- src/client_cli/nexus-client.go | 2 + 20 files changed, 152 insertions(+), 37 deletions(-) create mode 100644 src/client_cli/cmdVM/vmExportDir.go create mode 100644 src/client_cli/cmdVM/vmListExportDir.go diff --git a/README.md b/README.md index de96a67..3334368 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,7 @@ List of supported Commands: vmlistedit List VMs that can be edited (regex matching). vmlisteditaccess List VMs that can have their VM access edited (regex matching). vmlistdel List VMs that can be deleted (regex matching). + vmlistexportdir List VMs that can have a directory exported (regex matching). vmcred2pdf Create a PDF with the credentials required to attach to running VMs (regex matching). vmstart Start one or more VMs (regex matching). vmstop Stop one or more VMs (regex matching). @@ -56,6 +57,7 @@ List of supported Commands: vmdel Delete one or more VMs (regex matching). vmsetaccess Set a user's VM access in one or more VMs (regex matching). vmdelaccess Delete a user's VM access in one or more VMs (regex matching). + vmexportdir Export one or more VMs' directory into one or more tar archives. Create one archive per VM (regex matching). tpllist List available templates (regex matching). tplcreate Create a template, either from an existing VM or from a .qcow file. tpldel Delete one or more templates (regex matching). @@ -273,6 +275,11 @@ Generate `exam_vms.pdf` with the credentials required to connect to all running nexus-client vmcred2pdf "exam prog sys" output.pdf ``` +Extract and download the `/home` directory of all VMs matching "exam prog sys" (each directory is saved in a `.tar` archive named after the VM's ID): +``` +nexus-client vmlistexportdir "exam prog sys" /home +``` + List all available templates: ``` nexus-client tpllist . diff --git a/src/client_cli/cmdVM/helper.go b/src/client_cli/cmdVM/helper.go index c62a414..7d3121e 100644 --- a/src/client_cli/cmdVM/helper.go +++ b/src/client_cli/cmdVM/helper.go @@ -52,17 +52,13 @@ func (vm *VM)String() string { return string(output) } -func printUsage(c cmd.Command, action string, showLongOutputFlag bool) { +func printRegexUsage(c cmd.Command) { u.PrintlnErr(c.GetDesc()) - longOutputFlag := "" - if showLongOutputFlag { - longOutputFlag = " [-l]" - } - u.PrintlnErr("Usage: ",c.GetName(),longOutputFlag+" [ID ...] [regex ...]") - if showLongOutputFlag { - u.PrintlnErr("Use \"-l\" to specify detailed VMs output.") - } - u.PrintlnErr("Only VMs matching the specified IDs or regexes will be "+action+".") + u.PrintlnErr("Usage: ",c.GetName()," [ID ...] [regex ...]") +} + +func printRegexUsageDetails() { + u.PrintlnErr("The action only applies to VMs matching the specified IDs or regexes.") const usage string = `Any number of IDs or regexes can be specified. The regex only matches the VM's name and is case-insensitive. Regex examples: diff --git a/src/client_cli/cmdVM/vmAttach.go b/src/client_cli/cmdVM/vmAttach.go index c46abdc..ff3ee6b 100644 --- a/src/client_cli/cmdVM/vmAttach.go +++ b/src/client_cli/cmdVM/vmAttach.go @@ -27,7 +27,8 @@ func (cmd *Attach)GetDesc() string { } func (cmd *Attach)PrintUsage() { - printUsage(cmd, "attached to", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *Attach)Run(args []string) int { @@ -52,7 +53,7 @@ func (cmd *Attach)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to attach to!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmCred2pdf.go b/src/client_cli/cmdVM/vmCred2pdf.go index 6cb6ba0..f1cefa4 100644 --- a/src/client_cli/cmdVM/vmCred2pdf.go +++ b/src/client_cli/cmdVM/vmCred2pdf.go @@ -21,14 +21,7 @@ func (cmd *Cred2pdf)GetDesc() string { func (cmd *Cred2pdf)PrintUsage() { u.PrintlnErr(cmd.GetDesc()) u.PrintlnErr("Usage: ",cmd.GetName()," [ID ...] [regex ...] pdfile") - u.PrintlnErr("Only VMs that can be attached to and matching the specified IDs or regexes will be listed.") - const usage string = `Any number of IDs or regexes can be specified. -The regex only matches the VM's name and is case-insensitive. -Regex examples: -"" -> matches any VMs -"." -> matches any VMs -"bla" -> matches any VMs containing "bla" in their name` - u.PrintlnErr(usage) + printRegexUsageDetails() } func (cmd *Cred2pdf)Run(args []string) int { @@ -47,7 +40,7 @@ func (cmd *Cred2pdf)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to retrieve credentials from!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmDel.go b/src/client_cli/cmdVM/vmDel.go index f1b893f..71a27f7 100644 --- a/src/client_cli/cmdVM/vmDel.go +++ b/src/client_cli/cmdVM/vmDel.go @@ -18,7 +18,8 @@ func (cmd *Del)GetDesc() string { } func (cmd *Del)PrintUsage() { - printUsage(cmd, "deleted", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *Del)Run(args []string) int { @@ -38,7 +39,7 @@ func (cmd *Del)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to delete!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmDelAccess.go b/src/client_cli/cmdVM/vmDelAccess.go index 0116315..3c80b2e 100644 --- a/src/client_cli/cmdVM/vmDelAccess.go +++ b/src/client_cli/cmdVM/vmDelAccess.go @@ -59,7 +59,7 @@ func (cmd *DelAccess)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to delete user's VM access!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmEdit.go b/src/client_cli/cmdVM/vmEdit.go index 007fd46..dc81d3c 100644 --- a/src/client_cli/cmdVM/vmEdit.go +++ b/src/client_cli/cmdVM/vmEdit.go @@ -72,7 +72,7 @@ func (cmd *Edit)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to edit!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmExportDir.go b/src/client_cli/cmdVM/vmExportDir.go new file mode 100644 index 0000000..b9c5694 --- /dev/null +++ b/src/client_cli/cmdVM/vmExportDir.go @@ -0,0 +1,78 @@ +package cmdVM + +import ( + u "nexus-client/utils" + g "nexus-client/globals" +) + +type ExportDir struct { + Name string +} + +type vmExportDirParams struct { + Dir string +} + +func (cmd *ExportDir)GetName() string { + return cmd.Name +} + +func (cmd *ExportDir)GetDesc() string { + return "Export one or more VMs' directory into one or more tar archives. Create one archive per VM (regex matching)." +} + +func (cmd *ExportDir)PrintUsage() { + u.PrintlnErr(cmd.GetDesc()) + u.PrintlnErr("Usage: ",cmd.GetName()," [ID ...] [regex ...] dir") + u.PrintlnErr("\"dir\" is the directory in the VM to export into a tar archive named after the VM ID.") + printRegexUsageDetails() +} + +func (cmd *ExportDir)Run(args []string) int { + client := g.GetInstance().Client + host := g.GetInstance().Host + + argc := len(args) + if argc < 2 { + cmd.PrintUsage() + return 1 + } + + dir := args[argc-1] + + vms, err := getFilteredVMs("/vms/exportdir", args[:argc-1]) + if err != nil { + u.PrintlnErr("Error: "+err.Error()) + return 1 + } + + if len(vms) == 0 { + u.PrintlnErr("No match.") + return 1 + } + + params := &vmExportDirParams { Dir: dir } + + statusCode := 0 + + client.SetAllowGetMethodPayload(true) + + for _, vm := range(vms) { + uuid := vm.ID.String() + outputFile := uuid+".tar" + resp, err := client.R().SetOutput(outputFile).SetBody(params).Get(host+"/vms/"+uuid+"/exportdir") + if err != nil { + u.PrintlnErr("Failed exporting "+dir+" from VM \""+vm.Name+"\" | "+uuid+" : "+err.Error()) + statusCode = 1 + } else { + if resp.IsSuccess() { + u.Println("Successfully exported "+dir+" from VM \""+vm.Name+"\" ("+uuid+") into "+outputFile) + } else { + u.PrintlnErr("Failed exporting "+dir+" from VM \""+vm.Name+"\" | "+uuid+" : "+resp.Status()+": "+resp.String()) + statusCode = 1 + } + } + } + + return statusCode +} diff --git a/src/client_cli/cmdVM/vmList.go b/src/client_cli/cmdVM/vmList.go index ba904a0..d8b1fe1 100644 --- a/src/client_cli/cmdVM/vmList.go +++ b/src/client_cli/cmdVM/vmList.go @@ -1,5 +1,9 @@ package cmdVM +import ( + u "nexus-client/utils" +) + type List struct { Name string } @@ -13,7 +17,10 @@ func (cmd *List)GetDesc() string { } func (cmd *List)PrintUsage() { - printUsage(cmd, "listed", true) + u.PrintlnErr(cmd.GetDesc()) + u.PrintlnErr("Usage: ",cmd.GetName(), " [-l] [ID ...] [regex ...]") + u.PrintlnErr("Use \"-l\" to specify detailed VMs output.") + printRegexUsageDetails() } func (cmd *List)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmListAttach.go b/src/client_cli/cmdVM/vmListAttach.go index 5953aab..bc5a3ad 100644 --- a/src/client_cli/cmdVM/vmListAttach.go +++ b/src/client_cli/cmdVM/vmListAttach.go @@ -13,7 +13,8 @@ func (cmd *ListAttach)GetDesc() string { } func (cmd *ListAttach)PrintUsage() { - printUsage(cmd, "listed", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *ListAttach)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmListDel.go b/src/client_cli/cmdVM/vmListDel.go index 9506db8..0e22640 100644 --- a/src/client_cli/cmdVM/vmListDel.go +++ b/src/client_cli/cmdVM/vmListDel.go @@ -13,7 +13,8 @@ func (cmd *ListDel)GetDesc() string { } func (cmd *ListDel)PrintUsage() { - printUsage(cmd, "listed", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *ListDel)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmListEdit.go b/src/client_cli/cmdVM/vmListEdit.go index 73d4096..7d45a9b 100644 --- a/src/client_cli/cmdVM/vmListEdit.go +++ b/src/client_cli/cmdVM/vmListEdit.go @@ -13,7 +13,8 @@ func (cmd *ListEdit)GetDesc() string { } func (cmd *ListEdit)PrintUsage() { - printUsage(cmd, "listed", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *ListEdit)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmListEditAccess.go b/src/client_cli/cmdVM/vmListEditAccess.go index 78d9a59..7de1add 100644 --- a/src/client_cli/cmdVM/vmListEditAccess.go +++ b/src/client_cli/cmdVM/vmListEditAccess.go @@ -13,7 +13,8 @@ func (cmd *ListEditAccess)GetDesc() string { } func (cmd *ListEditAccess)PrintUsage() { - printUsage(cmd, "listed", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *ListEditAccess)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmListExportDir.go b/src/client_cli/cmdVM/vmListExportDir.go new file mode 100644 index 0000000..d6e5653 --- /dev/null +++ b/src/client_cli/cmdVM/vmListExportDir.go @@ -0,0 +1,22 @@ +package cmdVM + +type ListExportDir struct{ + Name string +} + +func (cmd *ListExportDir)GetName() string { + return cmd.Name +} + +func (cmd *ListExportDir)GetDesc() string { + return "List VMs that can have a directory exported (regex matching)." +} + +func (cmd *ListExportDir)PrintUsage() { + printRegexUsage(cmd) + printRegexUsageDetails() +} + +func (cmd *ListExportDir)Run(args []string) int { + return printFilteredVMs(cmd, args, "/vms/exportdir") +} diff --git a/src/client_cli/cmdVM/vmListStart.go b/src/client_cli/cmdVM/vmListStart.go index 16038ba..2a04678 100644 --- a/src/client_cli/cmdVM/vmListStart.go +++ b/src/client_cli/cmdVM/vmListStart.go @@ -13,7 +13,8 @@ func (cmd *ListStart)GetDesc() string { } func (cmd *ListStart)PrintUsage() { - printUsage(cmd, "listed", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *ListStart)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmListStop.go b/src/client_cli/cmdVM/vmListStop.go index 76846b4..9eb6d26 100644 --- a/src/client_cli/cmdVM/vmListStop.go +++ b/src/client_cli/cmdVM/vmListStop.go @@ -13,7 +13,8 @@ func (cmd *ListStop)GetDesc() string { } func (cmd *ListStop)PrintUsage() { - printUsage(cmd, "listed", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *ListStop)Run(args []string) int { diff --git a/src/client_cli/cmdVM/vmSetAccess.go b/src/client_cli/cmdVM/vmSetAccess.go index 08159be..50cd240 100644 --- a/src/client_cli/cmdVM/vmSetAccess.go +++ b/src/client_cli/cmdVM/vmSetAccess.go @@ -56,7 +56,7 @@ func (cmd *SetAccess)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to set user's VM access!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmStart.go b/src/client_cli/cmdVM/vmStart.go index 3ed02d2..33c7340 100644 --- a/src/client_cli/cmdVM/vmStart.go +++ b/src/client_cli/cmdVM/vmStart.go @@ -18,7 +18,8 @@ func (cmd *Start)GetDesc() string { } func (cmd *Start)PrintUsage() { - printUsage(cmd, "started", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *Start)Run(args []string) int { @@ -38,7 +39,7 @@ func (cmd *Start)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to start!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/cmdVM/vmStop.go b/src/client_cli/cmdVM/vmStop.go index 73180e1..079221d 100644 --- a/src/client_cli/cmdVM/vmStop.go +++ b/src/client_cli/cmdVM/vmStop.go @@ -18,7 +18,8 @@ func (cmd *Stop)GetDesc() string { } func (cmd *Stop)PrintUsage() { - printUsage(cmd, "stopped", false) + printRegexUsage(cmd) + printRegexUsageDetails() } func (cmd *Stop)Run(args []string) int { @@ -38,7 +39,7 @@ func (cmd *Stop)Run(args []string) int { } if len(vms) == 0 { - u.PrintlnErr("No VMs to stop!") + u.PrintlnErr("No match.") return 1 } diff --git a/src/client_cli/nexus-client.go b/src/client_cli/nexus-client.go index d78d84d..dd72494 100644 --- a/src/client_cli/nexus-client.go +++ b/src/client_cli/nexus-client.go @@ -31,6 +31,7 @@ var cmdList = []cmd.Command { &cmdVM.ListEdit{"vmlistedit"}, &cmdVM.ListEditAccess{"vmlisteditaccess"}, &cmdVM.ListDel{"vmlistdel"}, + &cmdVM.ListExportDir{"vmlistexportdir"}, &cmdVM.Cred2pdf{"vmcred2pdf"}, @@ -42,6 +43,7 @@ var cmdList = []cmd.Command { &cmdVM.Del{"vmdel"}, &cmdVM.SetAccess{"vmsetaccess"}, &cmdVM.DelAccess{"vmdelaccess"}, + &cmdVM.ExportDir{"vmexportdir"}, &cmdTemplate.List{"tpllist"}, &cmdTemplate.Create{"tplcreate"}, -- GitLab