From 1ad50ebcf8004e176b18ca03b898cd99e4cb9d0c Mon Sep 17 00:00:00 2001 From: Andrew Woodlee Date: Thu, 20 Feb 2025 14:53:44 -0600 Subject: [PATCH] v0.8.1 WIP --- backy.code-workspace | 3 ++- cmd/backup.go | 2 +- cmd/cron.go | 2 +- cmd/exec.go | 2 +- cmd/host.go | 2 +- cmd/list.go | 57 +++++++++++++++++++++++++++++++++------- cmd/root.go | 2 ++ pkg/backy/config.go | 31 ++++++++++++++++++++-- pkg/backy/list.go | 62 ++++++++++++++++++++++++++++++++++++-------- pkg/backy/types.go | 3 ++- pkg/backy/utils.go | 11 +++++++- 11 files changed, 147 insertions(+), 30 deletions(-) diff --git a/backy.code-workspace b/backy.code-workspace index 8493d32..8f55606 100644 --- a/backy.code-workspace +++ b/backy.code-workspace @@ -8,13 +8,14 @@ "settings": { "cSpell.words": [ "Cmds", - "remotefetcher", + "CMDSTDOUT", "knadh", "koanf", "mattn", "maunium", "mautrix", "nikoksr", + "remotefetcher", "Strs" ] } diff --git a/cmd/backup.go b/cmd/backup.go index d39f224..2fcb6ec 100644 --- a/cmd/backup.go +++ b/cmd/backup.go @@ -30,7 +30,7 @@ func init() { } func Backup(cmd *cobra.Command, args []string) { - backyConfOpts := backy.NewOpts(cfgFile, backy.AddCommandLists(cmdLists)) + backyConfOpts := backy.NewOpts(cfgFile, backy.AddCommandLists(cmdLists), backy.SetLogFile(logFile), backy.SetCmdStdOut(cmdStdOut)) backyConfOpts.InitConfig() backyConfOpts.ReadConfig() diff --git a/cmd/cron.go b/cmd/cron.go index 644002e..7d28a73 100644 --- a/cmd/cron.go +++ b/cmd/cron.go @@ -18,7 +18,7 @@ var ( func cron(cmd *cobra.Command, args []string) { parseS3Config() - opts := backy.NewOpts(cfgFile, backy.EnableCron()) + opts := backy.NewOpts(cfgFile, backy.EnableCron(), backy.SetLogFile(logFile), backy.SetCmdStdOut(cmdStdOut)) opts.InitConfig() opts.ReadConfig() diff --git a/cmd/exec.go b/cmd/exec.go index c28a302..1085e3d 100644 --- a/cmd/exec.go +++ b/cmd/exec.go @@ -32,7 +32,7 @@ func execute(cmd *cobra.Command, args []string) { logging.ExitWithMSG("Please provide a command to run. Pass --help to see options.", 1, nil) } - opts := backy.NewOpts(cfgFile, backy.AddCommands(args), backy.SetLogFile(logFile)) + opts := backy.NewOpts(cfgFile, backy.AddCommands(args), backy.SetLogFile(logFile), backy.SetCmdStdOut(cmdStdOut)) opts.InitConfig() opts.ReadConfig() opts.ExecuteCmds() diff --git a/cmd/host.go b/cmd/host.go index fb66a9a..1d9b183 100644 --- a/cmd/host.go +++ b/cmd/host.go @@ -35,7 +35,7 @@ func init() { // 2. stdin (on command line) (TODO) func Host(cmd *cobra.Command, args []string) { - backyConfOpts := backy.NewOpts(cfgFile, backy.SetLogFile(logFile)) + backyConfOpts := backy.NewOpts(cfgFile, backy.SetLogFile(logFile), backy.SetCmdStdOut(cmdStdOut)) backyConfOpts.InitConfig() backyConfOpts.ReadConfig() diff --git a/cmd/list.go b/cmd/list.go index 22a5384..ffb36f1 100644 --- a/cmd/list.go +++ b/cmd/list.go @@ -6,16 +6,29 @@ package cmd import ( "git.andrewnw.xyz/CyberShell/backy/pkg/backy" + "git.andrewnw.xyz/CyberShell/backy/pkg/logging" "github.com/spf13/cobra" ) var ( listCmd = &cobra.Command{ - Use: "list [--list=list1,list2,... | -l list1, list2,...] [ -cmd cmd1 cmd2 cmd3...]", + Use: "list [command]", Short: "Lists commands, lists, or hosts defined in config file.", Long: "Backup lists commands or groups defined in config file.\nUse the --lists or -l flag to list the specified lists. If not flag is not given, all lists will be executed.", - Run: List, + } + + listCmds = &cobra.Command{ + Use: "cmds [cmd1 cmd2 cmd3...]", + Short: "Lists commands, lists, or hosts defined in config file.", + Long: "Backup lists commands or groups defined in config file.\nUse the --lists or -l flag to list the specified lists. If not flag is not given, all lists will be executed.", + Run: ListCmds, + } + listCmdLists = &cobra.Command{ + Use: "lists [list1 list2 ...]", + Short: "Lists commands, lists, or hosts defined in config file.", + Long: "Backup lists commands or groups defined in config file.\nUse the --lists or -l flag to list the specified lists. If not flag is not given, all lists will be executed.", + Run: ListCmdLists, } ) @@ -23,27 +36,51 @@ var listsToList []string var cmdsToList []string func init() { - - listCmd.Flags().StringSliceVarP(&listsToList, "lists", "l", nil, "Accepts comma-separated names of command lists to list.") - listCmd.Flags().StringSliceVarP(&cmdsToList, "cmds", "c", nil, "Accepts comma-separated names of commands to list.") + listCmd.AddCommand(listCmds, listCmdLists) } -func List(cmd *cobra.Command, args []string) { +func ListCmds(cmd *cobra.Command, args []string) { // setup based on whats passed in: // - cmds // - lists // - if none, list all commands - if cmdLists != nil { - + if len(args) > 0 { + cmdsToList = args + } else { + logging.ExitWithMSG("Error: list cmds subcommand needs commands to list", 1, nil) } + parseS3Config() - opts := backy.NewOpts(cfgFile) + opts := backy.NewOpts(cfgFile, backy.SetLogFile(logFile)) opts.InitConfig() opts.ReadConfig() - opts.ListCommand("rm-sn-db") + for _, v := range cmdsToList { + opts.ListCommand(v) + } +} + +func ListCmdLists(cmd *cobra.Command, args []string) { + + parseS3Config() + + if len(args) > 0 { + listsToList = args + } else { + logging.ExitWithMSG("Error: lists subcommand needs lists", 1, nil) + } + + opts := backy.NewOpts(cfgFile, backy.SetLogFile(logFile)) + + opts.InitConfig() + opts.ReadConfig() + + for _, v := range listsToList { + opts.ListCommandList(v) + } + } diff --git a/cmd/root.go b/cmd/root.go index d10339b..80508c3 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -15,6 +15,7 @@ var ( // Used for flags. cfgFile string verbose bool + cmdStdOut bool logFile string s3Endpoint string @@ -35,6 +36,7 @@ func Execute() { func init() { rootCmd.PersistentFlags().StringVar(&logFile, "log-file", "", "log file to write to") + rootCmd.PersistentFlags().BoolVar(&cmdStdOut, "cmdStdOut", false, "Pass to print command output to stdout") rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "f", "", "config file to read from") rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "Sets verbose level") diff --git a/pkg/backy/config.go b/pkg/backy/config.go index 40b09f5..0ac825e 100644 --- a/pkg/backy/config.go +++ b/pkg/backy/config.go @@ -136,7 +136,12 @@ func (opts *ConfigOpts) ReadConfig() *ConfigOpts { opts.loadEnv() if backyKoanf.Bool(getNestedConfig("logging", "cmd-std-out")) { - os.Setenv("BACKY_STDOUT", "enabled") + os.Setenv("BACKY_CMDSTDOUT", "enabled") + } + + // override the default value of cmd-std-out if flag is set + if opts.CmdStdOut { + os.Setenv("BACKY_CMDSTDOUT", "enabled") } CheckConfigValues(backyKoanf, opts.ConfigFilePath) @@ -279,7 +284,6 @@ func loadCommandLists(opts *ConfigOpts, backyKoanf *koanf.Koanf) { listConfigFiles = []string{u.JoinPath("lists.yml").String(), u.JoinPath("lists.yaml").String()} } else { backyConfigFileDir = path.Dir(opts.ConfigFilePath) - // println("backyConfigFileDir", backyConfigFileDir) listConfigFiles = []string{ // "./lists.yml", "./lists.yaml", path.Join(backyConfigFileDir, "lists.yml"), @@ -340,6 +344,7 @@ func loadListConfigFile(filePath string, k *koanf.Koanf, opts *ConfigOpts) bool } unmarshalConfig(k, "cmdLists", &opts.CmdConfigLists, opts.Logger) + keyNotSupported("cmd-lists", "cmdLists", k, opts, true) opts.CmdListFile = filePath return true } @@ -365,6 +370,7 @@ func loadCmdListsFile(backyKoanf *koanf.Koanf, listsConfig *koanf.Koanf, opts *C logging.ExitWithMSG(fmt.Sprintf("error loading config: %v", err), 1, &opts.Logger) } + keyNotSupported("cmd-lists", "cmdLists", listsConfig, opts, true) unmarshalConfig(listsConfig, "cmdLists", &opts.CmdConfigLists, opts.Logger) opts.Logger.Info().Str("using lists config file", opts.CmdListFile).Send() } @@ -559,6 +565,16 @@ func processCmds(opts *ConfigOpts) error { opts.Hosts[*cmd.Host] = &Host{Host: *cmd.Host} cmd.RemoteHost = &Host{Host: *cmd.Host} } + } else { + + if cmd.Dir != nil { + + cmdDir, err := resolveDir(*cmd.Dir) + if err != nil { + return err + } + cmd.Dir = &cmdDir + } } // Parse package commands @@ -685,3 +701,14 @@ func detectOSType(cmd *Command, opts *ConfigOpts) error { } return nil } + +func keyNotSupported(oldKey, newKey string, koanf *koanf.Koanf, opts *ConfigOpts, deprecated bool) { + + if koanf.Exists(oldKey) { + if deprecated { + opts.Logger.Warn().Str("key", oldKey).Msg("key is deprecated. Use " + newKey + " instead.") + } else { + opts.Logger.Fatal().Err(fmt.Errorf("key %s found; it has changed to %s", oldKey, newKey)).Send() + } + } +} diff --git a/pkg/backy/list.go b/pkg/backy/list.go index 0351bc6..82d3293 100644 --- a/pkg/backy/list.go +++ b/pkg/backy/list.go @@ -23,8 +23,7 @@ func (opts *ConfigOpts) ListCommand(cmd string) { var cmdFound bool = false var cmdInfo *Command // check commands in file against cmd - for _, cmdInFile := range opts.executeCmds { - print(cmdInFile) + for cmdInFile := range opts.Cmds { cmdFound = false if cmd == cmdInFile { @@ -37,28 +36,34 @@ func (opts *ConfigOpts) ListCommand(cmd string) { // print the command's information if cmdFound { - print("Command: ") + println("Command: ") print(cmdInfo.Cmd) - if len(cmdInfo.Args) >= 0 { - for _, v := range cmdInfo.Args { - print(" ") // print space between command and args - print(v) // print command arg - } + for _, v := range cmdInfo.Args { + print(" ") // print space between command and args + print(v) // print command arg } - // is is remote or local + // is it remote or local if cmdInfo.Host != nil { - - print("Host: ", cmdInfo.Host) + println() + print("Host: ", *cmdInfo.Host) + println() } else { + println() print("Host: Runs on Local Machine\n\n") } + if cmdInfo.Dir != nil { + println() + print("Directory: ", *cmdInfo.Dir) + println() + } + } else { fmt.Printf("Command %s not found. Check spelling.\n", cmd) @@ -66,3 +71,38 @@ func (opts *ConfigOpts) ListCommand(cmd string) { } } + +func (opts *ConfigOpts) ListCommandList(list string) { + // bool for commands not found + // gets set to false if a command is not found + // set to true if the command is found + var listFound bool = false + var listInfo *CmdList + // check commands in file against cmd + for listInFile, l := range opts.CmdConfigLists { + listFound = false + + if list == listInFile { + listFound = true + listInfo = l + break + } + } + + // print the command's information + if listFound { + + println("List: ", list) + println() + + for _, v := range listInfo.Order { + println() + opts.ListCommand(v) + } + + } else { + + fmt.Printf("List %s not found. Check spelling.\n", list) + + } +} diff --git a/pkg/backy/types.go b/pkg/backy/types.go index 7c14f66..46bf90f 100644 --- a/pkg/backy/types.go +++ b/pkg/backy/types.go @@ -77,7 +77,6 @@ type ( /* Dir specifies a directory in which to run the command. - Ignored if Host is set. */ Dir *string `yaml:"dir,omitempty"` @@ -198,6 +197,8 @@ type ( // Global log level BackyLogLvl *string + CmdStdOut bool + // Holds config file ConfigFilePath string diff --git a/pkg/backy/utils.go b/pkg/backy/utils.go index a5f387f..0500456 100644 --- a/pkg/backy/utils.go +++ b/pkg/backy/utils.go @@ -64,6 +64,13 @@ func SetLogFile(logFile string) BackyOptionFunc { } } +// SetCmdStdOut forces the command output to stdout +func SetCmdStdOut(setStdOut bool) BackyOptionFunc { + return func(bco *ConfigOpts) { + bco.CmdStdOut = setStdOut + } +} + // EnableCron enables the execution of command lists at specified times func EnableCron() BackyOptionFunc { return func(bco *ConfigOpts) { @@ -182,10 +189,12 @@ func IsTerminalActive() bool { } func IsCmdStdOutEnabled() bool { - return os.Getenv("BACKY_STDOUT") == "enabled" + return os.Getenv("BACKY_CMDSTDOUT") == "enabled" } func resolveDir(path string) (string, error) { + path = strings.TrimSpace(path) + if path == "~" { homeDir, err := os.UserHomeDir() if err != nil {