From 87d5516eedd717a1f5042abb57b641784d257d74 Mon Sep 17 00:00:00 2001 From: Mike Degatano Date: Wed, 29 Jan 2025 21:15:40 +0000 Subject: [PATCH 1/2] Add enhancments added for cloud backup initiative --- client/client.go | 2 +- cmd/backups.go | 18 +++++++++++++++++- cmd/backups_new.go | 27 ++++++++++++++++----------- cmd/backups_remove.go | 16 +++++++++++++++- cmd/backups_restore.go | 13 ++++++++++++- 5 files changed, 61 insertions(+), 15 deletions(-) diff --git a/client/client.go b/client/client.go index 8497b902..faae1d70 100644 --- a/client/client.go +++ b/client/client.go @@ -14,7 +14,7 @@ var RawJSON = false func GenericJSONErrorHandling(resp *resty.Response, err error) (*resty.Response, error) { if err == nil { switch resp.StatusCode() { - case 200, 400, 403, 503: + case 200, 400, 403, 404, 503: break default: err = fmt.Errorf("Unexpected server response. Status code: %d", resp.StatusCode()) diff --git a/cmd/backups.go b/cmd/backups.go index 91ad0037..937bbe26 100644 --- a/cmd/backups.go +++ b/cmd/backups.go @@ -100,7 +100,7 @@ func backupsLocationsCompletions(cmd *cobra.Command, args []string, toComplete s return nil, cobra.ShellCompDirectiveNoFileComp } var ret []string - ret = append(ret, "\tLocal storage, /backups") + ret = append(ret, ".local\tLocal storage, /backups") data := resp.Result().(*helper.Response) if data.Result == "ok" && data.Data["mounts"] != nil { if mounts, ok := data.Data["mounts"].([]interface{}); ok { @@ -138,3 +138,19 @@ func backupsLocationsCompletions(cmd *cobra.Command, args []string, toComplete s } return ret, cobra.ShellCompDirectiveNoFileComp } + +func backupsAddonsCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + ret, directive := addonsCompletions(cmd, args, toComplete) + ret = append(ret, "ALL\tAll currently installed addons") + return ret, directive +} + +func backupsFoldersCompletions(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) { + if len(args) != 0 { + return nil, cobra.ShellCompDirectiveNoFileComp + } + return []string{"addons", "media", "share", "ssl"}, cobra.ShellCompDirectiveNoFileComp +} diff --git a/cmd/backups_new.go b/cmd/backups_new.go index fe4d2c4e..a9a94512 100644 --- a/cmd/backups_new.go +++ b/cmd/backups_new.go @@ -61,13 +61,16 @@ backup.`, options["compressed"] = false } - location, err := cmd.Flags().GetString("location") - if err == nil && cmd.Flags().Changed("location") { - if location == "" { - options["location"] = nil - } else { - options["location"] = location - } + location, err := cmd.Flags().GetStringArray("location") + log.WithField("location", location).Debug("location") + if len(location) > 0 && err == nil && cmd.Flags().Changed(("location")) { + options["location"] = location + } + + filename, err := cmd.Flags().GetString("filename") + log.WithField("filename", filename).Debug("filename") + if filename != "" && err == nil && cmd.Flags().Changed("filename") { + options["filename"] = filename } ExcludeDB, err := cmd.Flags().GetBool("homeassistant-exclude-database") @@ -93,20 +96,22 @@ func init() { backupsNewCmd.Flags().Bool("uncompressed", false, "Use Uncompressed archives") backupsNewCmd.Flags().StringArrayP("addons", "a", []string{}, "addons to backup, triggers a partial backup") backupsNewCmd.Flags().StringArrayP("folders", "f", []string{}, "folders to backup, triggers a partial backup") - backupsNewCmd.Flags().StringP("location", "l", "", "where to put backup file (backup mount or local)") + backupsNewCmd.Flags().StringArrayP("location", "l", []string{}, "where to put backup file (backup mount or local), use multiple times for multiple locations.") backupsNewCmd.Flags().Bool("homeassistant-exclude-database", false, "Exclude the Home Assistant database file from backup") + backupsNewCmd.Flags().String("filename", "", "name to use for backup file") backupsNewCmd.Flags().Lookup("uncompressed").NoOptDefVal = "false" - backupsNewCmd.Flags().Lookup("location").NoOptDefVal = "" + backupsNewCmd.Flags().Lookup("location").NoOptDefVal = ".local" backupsNewCmd.Flags().Lookup("homeassistant-exclude-database").NoOptDefVal = "false" backupsNewCmd.RegisterFlagCompletionFunc("name", cobra.NoFileCompletions) backupsNewCmd.RegisterFlagCompletionFunc("password", cobra.NoFileCompletions) backupsNewCmd.RegisterFlagCompletionFunc("uncompressed", boolCompletions) - backupsNewCmd.RegisterFlagCompletionFunc("addons", cobra.NoFileCompletions) - backupsNewCmd.RegisterFlagCompletionFunc("folders", cobra.NoFileCompletions) + backupsNewCmd.RegisterFlagCompletionFunc("addons", backupsAddonsCompletions) + backupsNewCmd.RegisterFlagCompletionFunc("folders", backupsFoldersCompletions) backupsNewCmd.RegisterFlagCompletionFunc("location", backupsLocationsCompletions) backupsNewCmd.RegisterFlagCompletionFunc("homeassistant-exclude-database", boolCompletions) + backupsNewCmd.RegisterFlagCompletionFunc("filename", cobra.NoFileCompletions) backupsCmd.AddCommand(backupsNewCmd) } diff --git a/cmd/backups_remove.go b/cmd/backups_remove.go index 66e4ea55..810afb26 100644 --- a/cmd/backups_remove.go +++ b/cmd/backups_remove.go @@ -34,13 +34,24 @@ clean backups from disk.`, } request := helper.GetJSONRequest() + options := make(map[string]interface{}) slug := args[0] - request.SetPathParams(map[string]string{ "slug": slug, }) + location, err := cmd.Flags().GetStringArray("location") + log.WithField("location", location).Debug("location") + if len(location) > 0 && err == nil && cmd.Flags().Changed(("location")) { + options["location"] = location + } + + if len(options) > 0 { + log.WithField("options", options).Debug("Request body") + request.SetBody(options) + } + resp, err := request.Delete(url) resp, err = client.GenericJSONErrorHandling(resp, err) @@ -54,6 +65,9 @@ clean backups from disk.`, } func init() { + backupsRemoveCmd.Flags().StringArrayP("location", "l", []string{}, "location(s) to remove backup from (instead of all), use multiple times for multiple locations.") + backupsRemoveCmd.Flags().Lookup("location").NoOptDefVal = ".local" + backupsRemoveCmd.RegisterFlagCompletionFunc("location", backupsLocationsCompletions) backupsCmd.AddCommand(backupsRemoveCmd) } diff --git a/cmd/backups_restore.go b/cmd/backups_restore.go index 141d9af6..7abeb38d 100644 --- a/cmd/backups_restore.go +++ b/cmd/backups_restore.go @@ -64,6 +64,11 @@ take Home Assistant backup on your system.`, command = "restore/partial" } + location, err := cmd.Flags().GetString("location") + if err == nil && cmd.Flags().Changed("location") { + options["location"] = location + } + url, err := helper.URLHelper(section, command) if err != nil { fmt.Println(err) @@ -96,9 +101,15 @@ func init() { backupsRestoreCmd.Flags().BoolP("homeassistant", "", true, "Restore homeassistant (default true), triggers a partial backup when set to false") backupsRestoreCmd.Flags().StringArrayP("addons", "a", []string{}, "addons to restore, triggers a partial backup") backupsRestoreCmd.Flags().StringArrayP("folders", "f", []string{}, "folders to restore, triggers a partial backup") + backupsRestoreCmd.Flags().StringP("location", "l", "", "where to put backup file (backup mount or local)") + + backupsRestoreCmd.Flags().Lookup("location").NoOptDefVal = ".local" + backupsRestoreCmd.RegisterFlagCompletionFunc("password", cobra.NoFileCompletions) backupsRestoreCmd.RegisterFlagCompletionFunc("homeassistant", boolCompletions) backupsRestoreCmd.RegisterFlagCompletionFunc("addons", cobra.NoFileCompletions) - backupsRestoreCmd.RegisterFlagCompletionFunc("folders", cobra.NoFileCompletions) + backupsRestoreCmd.RegisterFlagCompletionFunc("folders", backupsFoldersCompletions) + backupsRestoreCmd.RegisterFlagCompletionFunc("location", backupsLocationsCompletions) + backupsCmd.AddCommand(backupsRestoreCmd) } From 71ef0cbd6d9c2de334af383fb27d59c8cea5cb9e Mon Sep 17 00:00:00 2001 From: Mike Degatano Date: Thu, 30 Jan 2025 21:15:53 +0000 Subject: [PATCH 2/2] Coderabbit feedback --- cmd/audio_volume.go | 2 +- cmd/backups.go | 4 +++- cmd/backups_new.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/cmd/audio_volume.go b/cmd/audio_volume.go index f5860fff..c3513831 100644 --- a/cmd/audio_volume.go +++ b/cmd/audio_volume.go @@ -1,9 +1,9 @@ package cmd import ( - "strconv" log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "strconv" ) var audioVolumeCmd = &cobra.Command{ diff --git a/cmd/backups.go b/cmd/backups.go index 937bbe26..6377833b 100644 --- a/cmd/backups.go +++ b/cmd/backups.go @@ -10,6 +10,8 @@ import ( "github.com/spf13/cobra" ) +var backupsFolders = []string{"addons", "media", "share", "ssl"} + var backupsCmd = &cobra.Command{ Use: "backups", Aliases: []string{"backup", "back", "backups", "bk", "snapshots", "snapshot", "snap", "shot", "sn"}, @@ -152,5 +154,5 @@ func backupsFoldersCompletions(cmd *cobra.Command, args []string, toComplete str if len(args) != 0 { return nil, cobra.ShellCompDirectiveNoFileComp } - return []string{"addons", "media", "share", "ssl"}, cobra.ShellCompDirectiveNoFileComp + return backupsFolders, cobra.ShellCompDirectiveNoFileComp } diff --git a/cmd/backups_new.go b/cmd/backups_new.go index a9a94512..73f07aa4 100644 --- a/cmd/backups_new.go +++ b/cmd/backups_new.go @@ -63,7 +63,7 @@ backup.`, location, err := cmd.Flags().GetStringArray("location") log.WithField("location", location).Debug("location") - if len(location) > 0 && err == nil && cmd.Flags().Changed(("location")) { + if len(location) > 0 && err == nil && cmd.Flags().Changed("location") { options["location"] = location }