Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5f6459d5be | ||
|
|
1d2a3a8306 | ||
|
|
045dedef67 | ||
|
|
60989a3905 | ||
|
|
e789924547 |
@@ -0,0 +1,5 @@
|
|||||||
|
## v0.13.0 - 2026-08-15
|
||||||
|
### Changed
|
||||||
|
* List subcommands print out everything with no arguments
|
||||||
|
### Fixed
|
||||||
|
* Error hooks no longer return after one is executed
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
## v0.13.1 - 2026-08-15
|
||||||
|
### Changed
|
||||||
|
* Print help for exec command if no args given
|
||||||
@@ -6,6 +6,16 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
|
|||||||
and is generated by [Changie](https://github.com/miniscruff/changie).
|
and is generated by [Changie](https://github.com/miniscruff/changie).
|
||||||
|
|
||||||
|
|
||||||
|
## v0.13.1 - 2026-08-15
|
||||||
|
### Changed
|
||||||
|
* Print help for exec command if no args given
|
||||||
|
|
||||||
|
## v0.13.0 - 2026-08-15
|
||||||
|
### Changed
|
||||||
|
* List subcommands print out everything with no arguments
|
||||||
|
### Fixed
|
||||||
|
* Error hooks no longer return after one is executed
|
||||||
|
|
||||||
## v0.12.1 - 2026-03-23
|
## v0.12.1 - 2026-03-23
|
||||||
### Added
|
### Added
|
||||||
* Command output respects `command.[name].output.toLog` when standard output is enabled
|
* Command output respects `command.[name].output.toLog` when standard output is enabled
|
||||||
|
|||||||
+3
-1
@@ -5,6 +5,8 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
||||||
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
||||||
|
|
||||||
@@ -29,7 +31,7 @@ func execute(cmd *cobra.Command, args []string) {
|
|||||||
parseS3Config()
|
parseS3Config()
|
||||||
|
|
||||||
if len(args) < 1 {
|
if len(args) < 1 {
|
||||||
logging.ExitWithMSG("Please provide a command to run. Pass --help to see options.", 1, nil)
|
logging.ExitWithMSG(fmt.Sprintf("Please provide a command to run.\n\n%s", cmd.Long), 1, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := backy.NewConfigOptions(configFile,
|
opts := backy.NewConfigOptions(configFile,
|
||||||
|
|||||||
+1
-1
@@ -9,7 +9,7 @@ import (
|
|||||||
var (
|
var (
|
||||||
hostExecCommand = &cobra.Command{
|
hostExecCommand = &cobra.Command{
|
||||||
Use: "host [--command=command1 --command=command2 ... | -c command1 -c command2 ...] [--hosts=host1 --hosts=hosts2 ... | -m host1 -m host2 ...] ",
|
Use: "host [--command=command1 --command=command2 ... | -c command1 -c command2 ...] [--hosts=host1 --hosts=hosts2 ... | -m host1 -m host2 ...] ",
|
||||||
Short: "Runs command defined in config file on the hosts in order specified.",
|
Short: "Specify command(s) defined in config file on the host in order specified.",
|
||||||
Long: "Host executes specified commands on the hosts defined in config file.\nUse the --commands or -c flag to choose the commands.",
|
Long: "Host executes specified commands on the hosts defined in config file.\nUse the --commands or -c flag to choose the commands.",
|
||||||
Run: Host,
|
Run: Host,
|
||||||
}
|
}
|
||||||
|
|||||||
+40
-26
@@ -5,8 +5,10 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
"git.andrewnw.xyz/CyberShell/backy/pkg/backy"
|
||||||
"git.andrewnw.xyz/CyberShell/backy/pkg/logging"
|
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
@@ -15,28 +17,26 @@ var (
|
|||||||
listCmd = &cobra.Command{
|
listCmd = &cobra.Command{
|
||||||
Use: "list [command]",
|
Use: "list [command]",
|
||||||
Short: "List commands, lists, or hosts defined in config file.",
|
Short: "List commands, lists, or hosts defined in config file.",
|
||||||
Long: "List commands, lists, or hosts defined in config file",
|
Long: "List commands, lists, or hosts defined in config file. The subcommands take zero or more arguments to print specific commands or lists",
|
||||||
}
|
}
|
||||||
|
|
||||||
listCmds = &cobra.Command{
|
listCmds = &cobra.Command{
|
||||||
Use: "cmds [cmd1 cmd2 cmd3...]",
|
Use: "cmds [cmd1 cmd2 cmd3...]",
|
||||||
Short: "List commands defined in config file.",
|
Short: "Prints commands defined in config file.",
|
||||||
Long: "List commands defined in config file",
|
Long: "Prints commands defined in config file. Pass no arguments to print all commands",
|
||||||
Run: ListCommands,
|
Run: ListCommands,
|
||||||
}
|
}
|
||||||
listCmdLists = &cobra.Command{
|
listCmdLists = &cobra.Command{
|
||||||
Use: "lists [list1 list2 ...]",
|
Use: "lists [list1 list2 ...]",
|
||||||
Short: "List lists defined in config file.",
|
Short: "Prints lists defined in config file.",
|
||||||
Long: "List lists defined in config file",
|
Long: "Prints lists defined in config file. Pass no arguments to print all lists",
|
||||||
Run: ListCommandLists,
|
Run: ListCommandLists,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var listsToList []string
|
|
||||||
var cmdsToList []string
|
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
listCmd.AddCommand(listCmds, listCmdLists)
|
listCmd.AddCommand(listCmds, listCmdLists)
|
||||||
|
parseS3Config()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,13 +46,6 @@ func ListCommands(cmd *cobra.Command, args []string) {
|
|||||||
// - cmds
|
// - cmds
|
||||||
// - lists
|
// - lists
|
||||||
// - if none, list all commands
|
// - if none, list all commands
|
||||||
if len(args) > 0 {
|
|
||||||
cmdsToList = args
|
|
||||||
} else {
|
|
||||||
logging.ExitWithMSG("Error: list cmds subcommand needs commands to list", 1, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
parseS3Config()
|
|
||||||
|
|
||||||
opts := backy.NewConfigOptions(configFile,
|
opts := backy.NewConfigOptions(configFile,
|
||||||
backy.SetLogFile(logFile),
|
backy.SetLogFile(logFile),
|
||||||
@@ -61,21 +54,28 @@ func ListCommands(cmd *cobra.Command, args []string) {
|
|||||||
opts.InitConfig()
|
opts.InitConfig()
|
||||||
opts.ParseConfigurationFile()
|
opts.ParseConfigurationFile()
|
||||||
|
|
||||||
for _, v := range cmdsToList {
|
if len(args) > 0 {
|
||||||
|
for _, v := range args {
|
||||||
opts.ListCommand(v)
|
opts.ListCommand(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opts.Cmds) == 0 {
|
||||||
|
fmt.Println("No commands defined in config file")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for c := range opts.Cmds {
|
||||||
|
println()
|
||||||
|
println()
|
||||||
|
println("---------------------------------------------------------------------------------")
|
||||||
|
opts.ListCommand(c)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ListCommandLists(cmd *cobra.Command, args []string) {
|
func ListCommandLists(cmd *cobra.Command, args []string) {
|
||||||
|
|
||||||
parseS3Config()
|
|
||||||
|
|
||||||
if len(args) > 0 {
|
|
||||||
listsToList = args
|
|
||||||
} else {
|
|
||||||
logging.ExitWithMSG("Error: lists subcommand needs lists", 1, nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := backy.NewConfigOptions(configFile,
|
opts := backy.NewConfigOptions(configFile,
|
||||||
backy.SetLogFile(logFile),
|
backy.SetLogFile(logFile),
|
||||||
backy.SetHostsConfigFile(hostsConfigFile))
|
backy.SetHostsConfigFile(hostsConfigFile))
|
||||||
@@ -83,8 +83,22 @@ func ListCommandLists(cmd *cobra.Command, args []string) {
|
|||||||
opts.InitConfig()
|
opts.InitConfig()
|
||||||
opts.ParseConfigurationFile()
|
opts.ParseConfigurationFile()
|
||||||
|
|
||||||
for _, v := range listsToList {
|
if len(args) > 0 {
|
||||||
|
for _, v := range args {
|
||||||
opts.ListCommandList(v)
|
opts.ListCommandList(v)
|
||||||
}
|
}
|
||||||
|
os.Exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(opts.CmdConfigLists) == 0 {
|
||||||
|
fmt.Println("No command lists defined in config file")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
for c := range opts.CmdConfigLists {
|
||||||
|
println()
|
||||||
|
println()
|
||||||
|
println("---------------------------------------------------------------------------------")
|
||||||
|
opts.ListCommandList(c)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ import (
|
|||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
const versionStr = "0.12.1"
|
const versionStr = "0.13.1"
|
||||||
|
|
||||||
var (
|
var (
|
||||||
versionCmd = &cobra.Command{
|
versionCmd = &cobra.Command{
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ Usage:
|
|||||||
backy exec [command]
|
backy exec [command]
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
host Runs command defined in config file on the hosts in order specified.
|
host Specify command(s) defined in config file on the host in order specified.
|
||||||
hosts Runs command defined in config file on the hosts in order specified.
|
hosts Runs command defined in config file on the hosts in order specified.
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
@@ -153,14 +153,14 @@ Global Flags:
|
|||||||
## list
|
## list
|
||||||
|
|
||||||
```
|
```
|
||||||
List commands, lists, or hosts defined in config file
|
List commands, lists, or hosts defined in config file. The subcommands take zero or more arguments to print specific commands or lists
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
backy list [command]
|
backy list [command]
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
cmds List commands defined in config file.
|
cmds Prints commands defined in config file.
|
||||||
lists List lists defined in config file.
|
lists Prints lists defined in config file.
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
-h, --help help for list
|
-h, --help help for list
|
||||||
@@ -178,7 +178,7 @@ Use "backy list [command] --help" for more information about a command.
|
|||||||
## list cmds
|
## list cmds
|
||||||
|
|
||||||
```
|
```
|
||||||
List commands defined in config file
|
Prints commands defined in config file. Pass no arguments to print all commands
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
backy list cmds [cmd1 cmd2 cmd3...] [flags]
|
backy list cmds [cmd1 cmd2 cmd3...] [flags]
|
||||||
@@ -197,7 +197,7 @@ Global Flags:
|
|||||||
## list lists
|
## list lists
|
||||||
|
|
||||||
```
|
```
|
||||||
List lists defined in config file
|
Prints lists defined in config file. Pass no arguments to print all lists
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
backy list lists [list1 list2 ...] [flags]
|
backy list lists [list1 list2 ...] [flags]
|
||||||
|
|||||||
@@ -2,14 +2,23 @@
|
|||||||
title: Exec
|
title: Exec
|
||||||
---
|
---
|
||||||
|
|
||||||
The `exec` subcommand can do some things that the configuration file can't do yet. The command `exec host` can execute commands on many hosts.
|
~~The `exec` subcommand can do some things that the configuration file can't do yet. The command `exec host` can execute commands on many hosts.~~
|
||||||
|
|
||||||
|
{{% notice info %}}
|
||||||
|
For now only the `exec host` sub-command is implemented. More to come.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
{{% notice warning %}}
|
||||||
|
The config file's `hosts` are overridden by this command. Hooks are not altered. For consistent results, create a local config file with only the hosts you want to use.
|
||||||
|
{{% /notice %}}
|
||||||
|
|
||||||
|
|
||||||
`exec host` takes the following arguments:
|
`exec host` takes the following arguments:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
-c, --commands strings Accepts space-separated names of commands.
|
-c, --command stringArray Accepts space-separated names of commands. Specify multiple times for multiple commands.
|
||||||
-h, --help help for host
|
-h, --help help for host
|
||||||
-m, --hosts strings Accepts space-separated names of hosts.
|
-m, --hosts stringArray Accepts space-separated names of hosts. Specify multiple times for multiple hosts.
|
||||||
```
|
```
|
||||||
|
|
||||||
The commands have to be defined in the config file. The hosts need to at least be in the ssh_config(5) file.
|
The commands have to be defined in the config file. The hosts need to at least be in the ssh_config(5) file.
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ title: List
|
|||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
List commands, lists, or hosts defined in config file
|
List commands, lists, or hosts defined in config file. The subcommands take zero or more arguments to print specific commands or lists
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
```
|
```
|
||||||
@@ -11,8 +11,8 @@ Usage:
|
|||||||
```
|
```
|
||||||
|
|
||||||
Available Commands:
|
Available Commands:
|
||||||
cmds List commands defined in config file.
|
cmds Prints commands defined in config file.
|
||||||
lists List lists defined in config file.
|
lists Prints lists defined in config file.
|
||||||
|
|
||||||
Flags:
|
Flags:
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -944,7 +944,6 @@ func (cmd *Command) ExecuteHooks(hookType string, opts *ConfigOpts) {
|
|||||||
cmdLogger.Info().Msgf("Running error hook command %s", v)
|
cmdLogger.Info().Msgf("Running error hook command %s", v)
|
||||||
// URGENT: Never returns
|
// URGENT: Never returns
|
||||||
_, _ = errCmd.RunCmd(cmdLogger, opts)
|
_, _ = errCmd.RunCmd(cmdLogger, opts)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "success":
|
case "success":
|
||||||
|
|||||||
@@ -101,6 +101,10 @@ func (r *RemoteFileCommandExecutor) copyFile(source, destination string, Perms f
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sshClient == nil {
|
||||||
|
return fmt.Errorf("SSH Client is nil")
|
||||||
|
}
|
||||||
|
|
||||||
client, err := sftp.NewClient(sshClient)
|
client, err := sftp.NewClient(sshClient)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
+45
-7
@@ -36,6 +36,8 @@ func (opts *ConfigOpts) ListCommand(cmd string) {
|
|||||||
// print the command's information
|
// print the command's information
|
||||||
if cmdFound {
|
if cmdFound {
|
||||||
|
|
||||||
|
print("Backy Command: ")
|
||||||
|
println(cmd)
|
||||||
println("Command: ")
|
println("Command: ")
|
||||||
|
|
||||||
print(cmdInfo.Cmd)
|
print(cmdInfo.Cmd)
|
||||||
@@ -45,6 +47,22 @@ func (opts *ConfigOpts) ListCommand(cmd string) {
|
|||||||
print(v) // print command arg
|
print(v) // print command arg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cmdInfo.Type.String() != "" {
|
||||||
|
println()
|
||||||
|
print("Type: ", cmdInfo.Type.String())
|
||||||
|
println()
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmdInfo.Hosts != nil {
|
||||||
|
for n, h := range cmdInfo.Hosts {
|
||||||
|
println()
|
||||||
|
fmt.Printf("Host %d: %s", n, h)
|
||||||
|
println()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
// is it remote or local
|
// is it remote or local
|
||||||
if !IsHostLocal(cmdInfo.Host) {
|
if !IsHostLocal(cmdInfo.Host) {
|
||||||
println()
|
println()
|
||||||
@@ -57,6 +75,30 @@ func (opts *ConfigOpts) ListCommand(cmd string) {
|
|||||||
print("Host: Runs on Local Machine\n\n")
|
print("Host: Runs on Local Machine\n\n")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(cmdInfo.Environment) > 0 {
|
||||||
|
fmt.Print("Environment: ")
|
||||||
|
for _, env := range cmdInfo.Environment {
|
||||||
|
fmt.Printf("%s ", env)
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmdInfo.PackageManager != "" {
|
||||||
|
fmt.Printf("\nPackage Manager: %s\n", cmdInfo.PackageManager)
|
||||||
|
if len(cmdInfo.Packages) > 0 {
|
||||||
|
for _, pkg := range cmdInfo.Packages {
|
||||||
|
fmt.Printf("Package: %v\n", pkg)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmdInfo.Username != "" || cmdInfo.UserID != "" {
|
||||||
|
fmt.Println("\nUser Settings:")
|
||||||
|
fmt.Printf("Username: %s\n", cmdInfo.Username)
|
||||||
|
fmt.Printf("UserID: %s\n", cmdInfo.UserID)
|
||||||
|
}
|
||||||
|
|
||||||
if cmdInfo.Dir != nil {
|
if cmdInfo.Dir != nil {
|
||||||
println()
|
println()
|
||||||
@@ -64,11 +106,6 @@ func (opts *ConfigOpts) ListCommand(cmd string) {
|
|||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
if cmdInfo.Type.String() != "" {
|
|
||||||
print("Type: ", cmdInfo.Type.String())
|
|
||||||
println()
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
fmt.Printf("Command %s not found. Check spelling.\n", cmd)
|
fmt.Printf("Command %s not found. Check spelling.\n", cmd)
|
||||||
@@ -100,9 +137,10 @@ func (opts *ConfigOpts) ListCommandList(list string) {
|
|||||||
println("List: ", list)
|
println("List: ", list)
|
||||||
println()
|
println()
|
||||||
|
|
||||||
for _, v := range listInfo.Order {
|
for n, cmd := range listInfo.Order {
|
||||||
println()
|
println()
|
||||||
opts.ListCommand(v)
|
fmt.Printf("Command %d: \n", n+1)
|
||||||
|
opts.ListCommand(cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package backy
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@@ -75,6 +76,17 @@ func (metricFile *MetricFile) SaveToFile() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func LoadMetricsFromFile(filename string) (*MetricFile, error) {
|
func LoadMetricsFromFile(filename string) (*MetricFile, error) {
|
||||||
|
if err := testFile(filename); err != nil {
|
||||||
|
|
||||||
|
_, createErr := os.Create(filename)
|
||||||
|
if createErr != nil {
|
||||||
|
return nil, fmt.Errorf("error creating file and root cause: %w", err)
|
||||||
|
}
|
||||||
|
metricData := NewMetricsFromFile(filename)
|
||||||
|
data, _ := json.MarshalIndent(metricData, "", " ")
|
||||||
|
os.WriteFile(filename, data, 0600)
|
||||||
|
return metricData, nil
|
||||||
|
}
|
||||||
jsonData, err := os.ReadFile(filename)
|
jsonData, err := os.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
+57
-62
@@ -1,67 +1,62 @@
|
|||||||
package backy
|
package backy
|
||||||
|
|
||||||
// import (
|
import (
|
||||||
// "testing"
|
"testing"
|
||||||
// "time"
|
"time"
|
||||||
// )
|
)
|
||||||
|
|
||||||
// func TestAddingMetricsForCommand(t *testing.T) {
|
func TestAddingMetricsForCommand(t *testing.T) {
|
||||||
|
// Create a new MetricFile
|
||||||
|
metricFile := NewMetricsFromFile("test_metrics.json")
|
||||||
|
metricFile, err := LoadMetricsFromFile(metricFile.Filename)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to load metrics from file: %v", err)
|
||||||
|
}
|
||||||
|
// Add metrics for a command
|
||||||
|
commandName := "test_command"
|
||||||
|
if metricFile.CommandMetrics != nil {
|
||||||
|
if _, exists := metricFile.CommandMetrics[commandName]; !exists {
|
||||||
|
metricFile.CommandMetrics[commandName] = NewMetrics()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Update the metrics for the command
|
||||||
|
executionTime := 1.8 // Example execution time in seconds
|
||||||
|
success := true // Example success status
|
||||||
|
metricFile.CommandMetrics[commandName].Update(success, executionTime, time.Now())
|
||||||
|
// Check if the metrics were updated correctly
|
||||||
|
if metricFile.CommandMetrics[commandName].SuccessfulExecutions > 50 {
|
||||||
|
t.Errorf("Expected 1 successful execution, got %d", metricFile.CommandMetrics[commandName].SuccessfulExecutions)
|
||||||
|
}
|
||||||
|
if metricFile.CommandMetrics[commandName].TotalExecutions > 50 {
|
||||||
|
t.Errorf("Expected 1 total execution, got %d", metricFile.CommandMetrics[commandName].TotalExecutions)
|
||||||
|
}
|
||||||
|
if metricFile.CommandMetrics[commandName].TotalExecutionTime != executionTime {
|
||||||
|
t.Errorf("Expected execution time %f, got %f", executionTime, metricFile.CommandMetrics[commandName].TotalExecutionTime)
|
||||||
|
}
|
||||||
|
err = metricFile.SaveToFile()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to save metrics to file: %v", err)
|
||||||
|
}
|
||||||
|
listName := "test_list"
|
||||||
|
if _, exists := metricFile.ListMetrics[listName]; !exists {
|
||||||
|
metricFile.ListMetrics[listName] = NewMetrics()
|
||||||
|
}
|
||||||
|
// Update the metrics for the list
|
||||||
|
metricFile.ListMetrics[listName].Update(success, executionTime, time.Now())
|
||||||
|
if metricFile.ListMetrics[listName].SuccessfulExecutions > 50 {
|
||||||
|
t.Errorf("Expected 1 successful execution for list, got %d", metricFile.ListMetrics[listName].SuccessfulExecutions)
|
||||||
|
}
|
||||||
|
if metricFile.ListMetrics[listName].TotalExecutions > 50 {
|
||||||
|
t.Errorf("Expected 1 total execution for list, got %d", metricFile.ListMetrics[listName].TotalExecutions)
|
||||||
|
}
|
||||||
|
if metricFile.ListMetrics[listName].TotalExecutionTime > executionTime {
|
||||||
|
t.Errorf("Expected execution time %f for list, got %f", executionTime, metricFile.ListMetrics[listName].TotalExecutionTime)
|
||||||
|
}
|
||||||
|
|
||||||
// // Create a new MetricFile
|
// Save the metrics to a file
|
||||||
// metricFile := NewMetricsFromFile("test_metrics.json")
|
err = metricFile.SaveToFile()
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("Failed to save metrics to file: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
// metricFile, err := LoadMetricsFromFile(metricFile.Filename)
|
}
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf("Failed to load metrics from file: %v", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Add metrics for a command
|
|
||||||
// commandName := "test_command"
|
|
||||||
// if _, exists := metricFile.CommandMetrics[commandName]; !exists {
|
|
||||||
// metricFile.CommandMetrics[commandName] = NewMetrics()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Update the metrics for the command
|
|
||||||
// executionTime := 1.8 // Example execution time in seconds
|
|
||||||
// success := true // Example success status
|
|
||||||
// metricFile.CommandMetrics[commandName].Update(success, executionTime, time.Now())
|
|
||||||
|
|
||||||
// // Check if the metrics were updated correctly
|
|
||||||
// if metricFile.CommandMetrics[commandName].SuccessfulExecutions > 50 {
|
|
||||||
// t.Errorf("Expected 1 successful execution, got %d", metricFile.CommandMetrics[commandName].SuccessfulExecutions)
|
|
||||||
// }
|
|
||||||
// if metricFile.CommandMetrics[commandName].TotalExecutions > 50 {
|
|
||||||
// t.Errorf("Expected 1 total execution, got %d", metricFile.CommandMetrics[commandName].TotalExecutions)
|
|
||||||
// }
|
|
||||||
// // if metricFile.CommandMetrics[commandName].TotalExecutionTime != executionTime {
|
|
||||||
// // t.Errorf("Expected execution time %f, got %f", executionTime, metricFile.CommandMetrics[commandName].TotalExecutionTime)
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// err = metricFile.SaveToFile()
|
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf("Failed to save metrics to file: %v", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// listName := "test_list"
|
|
||||||
// if _, exists := metricFile.ListMetrics[listName]; !exists {
|
|
||||||
// metricFile.ListMetrics[listName] = NewMetrics()
|
|
||||||
// }
|
|
||||||
// // Update the metrics for the list
|
|
||||||
// metricFile.ListMetrics[listName].Update(success, executionTime, time.Now())
|
|
||||||
// if metricFile.ListMetrics[listName].SuccessfulExecutions > 50 {
|
|
||||||
// t.Errorf("Expected 1 successful execution for list, got %d", metricFile.ListMetrics[listName].SuccessfulExecutions)
|
|
||||||
// }
|
|
||||||
// if metricFile.ListMetrics[listName].TotalExecutions > 50 {
|
|
||||||
// t.Errorf("Expected 1 total execution for list, got %d", metricFile.ListMetrics[listName].TotalExecutions)
|
|
||||||
// }
|
|
||||||
// // if metricFile.ListMetrics[listName].TotalExecutionTime > executionTime {
|
|
||||||
// // t.Errorf("Expected execution time %f for list, got %f", executionTime, metricFile.ListMetrics[listName].TotalExecutionTime)
|
|
||||||
// // }
|
|
||||||
|
|
||||||
// // Save the metrics to a file
|
|
||||||
// err = metricFile.SaveToFile()
|
|
||||||
// if err != nil {
|
|
||||||
// t.Errorf("Failed to save metrics to file: %v", err)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// }
|
|
||||||
|
|||||||
+3
-2
@@ -723,7 +723,8 @@ func (command *Command) prepareScriptBuffer() (*bytes.Buffer, error) {
|
|||||||
|
|
||||||
buffer.WriteString(command.Cmd)
|
buffer.WriteString(command.Cmd)
|
||||||
for _, arg := range command.Args {
|
for _, arg := range command.Args {
|
||||||
buffer.WriteString(" " + arg)
|
buffer.WriteString(" ")
|
||||||
|
buffer.WriteString(arg)
|
||||||
}
|
}
|
||||||
buffer.WriteByte('\n')
|
buffer.WriteByte('\n')
|
||||||
return &buffer, nil
|
return &buffer, nil
|
||||||
@@ -847,7 +848,7 @@ func DoesHostHaveHostName(host string) (bool, string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsHostLocal(host string) bool {
|
func IsHostLocal(host string) bool {
|
||||||
host = strings.ToLower(host)
|
host = strings.ToLower(strings.TrimSpace(host))
|
||||||
return host == "127.0.0.1" || host == "localhost" || host == ""
|
return host == "127.0.0.1" || host == "localhost" || host == ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
Command list {{.listName }} failed.
|
Backy Command: {{.CmdName}}.
|
||||||
|
|
||||||
The command run was {{.CmdName}}.
|
The command executed: {{.Command}} {{ if .Args }} {{- range .Args}} {{.}} {{end}} {{end}}
|
||||||
|
|
||||||
The command executed was {{.Command}} {{ if .Args }} {{- range .Args}} {{.}} {{end}} {{end}}
|
{{ if .Err }} Error: {{ .Err }}{{ end }}
|
||||||
|
|
||||||
{{ if .Err }} The error was {{ .Err }}{{ end }}
|
{{ if .Output }} Output: {{- range .Output}} {{.}} {{end}} {{end}}
|
||||||
|
|
||||||
{{ if .Output }} The output was: {{- range .Output}} {{.}} {{end}} {{end}}
|
|
||||||
|
|
||||||
{{ if .CmdsRan }}
|
{{ if .CmdsRan }}
|
||||||
The following commands ran:
|
Commands executed (last one failed):
|
||||||
{{- range .CmdsRan}}
|
{{- range .CmdsRan}}
|
||||||
- {{. -}}
|
- {{. -}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
Command list {{ .listName }} completed successfully.
|
Commands executed:
|
||||||
|
|
||||||
The following commands ran:
|
|
||||||
{{- range .CmdsRan}}
|
{{- range .CmdsRan}}
|
||||||
- {{. -}}
|
- {{. -}}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|||||||
@@ -226,6 +226,11 @@ func CheckConfigValues(config *koanf.Koanf, file string) {
|
|||||||
func collectOutput(buf *bytes.Buffer, commandName string, logger, globalLogger zerolog.Logger, wantOutput bool) []string {
|
func collectOutput(buf *bytes.Buffer, commandName string, logger, globalLogger zerolog.Logger, wantOutput bool) []string {
|
||||||
var outputArr []string
|
var outputArr []string
|
||||||
copyBuf := bytes.NewBuffer(buf.Bytes())
|
copyBuf := bytes.NewBuffer(buf.Bytes())
|
||||||
|
if buf.Len() == 0 {
|
||||||
|
logger.Info().Str("cmd", commandName).Msg("NO OUTPUT!!!!!!!")
|
||||||
|
globalLogger.Info().Str("cmd", commandName).Msg("NO OUTPUT!!!!!!!")
|
||||||
|
return outputArr
|
||||||
|
}
|
||||||
scanner := bufio.NewScanner(copyBuf)
|
scanner := bufio.NewScanner(copyBuf)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.14
|
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.16
|
||||||
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.14
|
[localhost]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDZi/dbBsgthhSj9kf4SIxTZCX+thRmvSgQ+ogC0yyHvoQrIio0Pu2MA66S779LE7Zng3CJ1lxiesffqdiTdcv8mrlnwHlzshNy4trl85NOawdNpwwlY8aiYQkxifXqAXSoHlgG+AlrbLcZ4q0YbeLnwgB3eEywN+eCHuJdetNr1Lq9NkqiGKltBIVYxHofEkUj+jBTJCyPDcp7/CKSYXhcELCaSw8vBkB7+PfsYYy0+TPXspiu/euLZfiagh6ik2fMcfc0k5P4Yn0GRt5Uk4jr85lob7ucO6Q2VPJpfavSjetcqa/oL6peEOJ4/SQzzrbxmh0I/5Tq76lTtrFT+R+tfqn0+n11FkNhS85IulmpdD2kLPGE6yH+vfjYrYD5TdH0qiOltqfXuiJCekRryoU9oWS/VSDi7aEVPryCQWf0IUqj05F/sa4RRtO0k7UOYL8NwJTS8q02sCt+/W+nX03f6XNoG7K57MZlYnREUGS6scqnvktb9bwKBunDZePMwZk=
|
||||||
[localhost]:2222 ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDATufWA1HRnNayIQLjSpA2+P9N6h0WF+jP+abMaINlZkiHFnFVDAoqD5/onVXymskrgQaKEYmBOs+Kv0t+Acvdor2IcvYgFueSm+jkslpSK/uuf1mx0gVJO77S2BIjqyWtUzVv96Iy4Gjt2RsrnalgYNYmi3OyPkG0IUA+3Im+2gztSECCy+nW3R/vaoPLwr4kImpLlrijcSHc4mHOY6BurrcWKNuGrsvTAOKgUZqlya6uDd+yD7fUfsmL1MqBKwZqfP3JAdp/Dd+laNNGcvEM4WhzYFSPfhqblewD0rjbto9MSOSXLyQz5RPmdITj/m5M4lj2ECmcI2gzraDMoj8ZkuJAss50oX6fmVUZestN5jlz7Y7XKEvXuH8qfLHKwaOUTZlcGbfAMz6uSrh8DNT6KzRG4j5nZ9Z5pTn1huz/p6jnJUGuHt2Ez3EK+isM+sHS6TntXavIkebaq7ErcBCO8A1fZFZlhlHoI9o9W62tMY7gbtlGodW8dKxK89+1a88=
|
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.16
|
||||||
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.14
|
[localhost]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBEy0ReNz4EO68wUiQGHmkKOwLQhAUhY9oCyzpyROUWM0FWQId124SKPPcLD3DcYHQpofdG8h11NZ8Dyk1g/mW8M=
|
||||||
[localhost]:2222 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBK9fEYfiGGgu0Eh7X2JT4jR4+utcfpm6Ee+Cer1x/XbMHzCPZg6YmYy6OaCSms/0VJ/QWxD+0HlsO7sqO5oeO60=
|
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.16
|
||||||
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.14
|
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.16
|
||||||
[localhost]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKT5+Cbi/ynOAPzwv0IaOVBtGFYtW33LIvNUuBKYqqyJ
|
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.16
|
||||||
# localhost:2222 SSH-2.0-OpenSSH_9.6p1 Ubuntu-3ubuntu13.14
|
[localhost]:2222 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIArPKqZ3cHWzv0o6RUko8TNpr95olBJAzHRiPIvYD7bH
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ set -euo pipefail
|
|||||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||||
echo "Starting SSH test container (building if needed)..."
|
echo "Starting SSH test container (building if needed)..."
|
||||||
docker compose -f "$DIR/compose.yml" up -d --build
|
docker compose -f "$DIR/compose.yml" up -d --build
|
||||||
|
ssh-keyscan -p 2222 localhost > "$DIR/known_hosts"
|
||||||
echo "Container started on localhost:2222"
|
echo "Container started on localhost:2222"
|
||||||
Reference in New Issue
Block a user