diff --git a/README.md b/README.md index de96a67dddf1937395dabdf83225293e862aa10f..33343685a6c9d5d80793d723ee535bae49056e82 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 c62a4140843ce4ab1e27480405ec2de1635e80ca..7d3121ee4afa7f3f8c067aa04a0aba2917692cfd 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 c46abdc89b680454162e215b5ecc8a18bb225375..ff3ee6b4ac42f9b27cdfb5792142bb62d7feb09d 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 6cb6ba039a3bc0f6c27d4b7f0078377c51a6912c..f1cefa4333045823ea5fc0a6438132e96c9fc246 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 f1b893f286e0236e811d6c7aff9f2c1888733a87..71a27f720ad56bedc66c9c5eff7e417572513d0c 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 01163151ca6715d1c5b2423b6b561f7a07e5c279..3c80b2e0d5d6280b254f30fcb3ee83dedc4b8a2a 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 007fd464b37e47d7b3687a6be6ce58cbd84d94cc..dc81d3c486d708424cbee761c049a7091dc79d8d 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 0000000000000000000000000000000000000000..b9c56947a4fdf79cd90310665616d25c73b60efa --- /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 ba904a02650a2965c79a4174e59e927945ac2055..d8b1fe158b8209ae5f3d72776cc5b8d149dc013c 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 5953aabb341c6da16db2d474ae31aa1b74b25323..bc5a3adf7ec0b13a4df0c2440ef59241ab6923e2 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 9506db80a13827cdc11020d0350b3c33ec9f774d..0e22640a3a7110db041a99bbad8f7ca4c1731950 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 73d4096df3a9dff9abc80486def3d069ff5a135c..7d45a9bc1ace3b13dad8b5f2f65fb9b5628226d7 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 78d9a59d2c4c3bf377a2ca42f77b1b4de8e7a3ee..7de1addf76588ca6c804622d5280a30e5ffa360c 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 0000000000000000000000000000000000000000..d6e56535bf5f408da2260308653f6c0abe1f52ae --- /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 16038bad8f8c6d81bc3e580c44aea461fcf079e0..2a04678561ef9b522e66dc0a2bf98ead5916a19b 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 76846b43bea6c1dbc7549144af01a8008b69606f..9eb6d26f2587ea4cf3d961ddba12e35c6535826a 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 08159bec143fc118a4363cf31f460bf8174525b0..50cd240eed12d45f4f0c238716878227d384406f 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 3ed02d2e82ad7718a293a63755f6e67d670f24b4..33c73407f500f575aaa8c53c860334c818824123 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 73180e1076201fdd0cec97353d9acd110ebf496d..079221df1bc7fc96c0b330f5887b682991ba9356 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 d78d84d8662b46ec85cf0a1061fe423d46b616c8..dd724943c4223d7fad571c68110a99cb6bc991ef 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"},