github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/pkg/cli/reset.go (about) 1 package cli 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "strings" 8 9 "github.com/apprenda/kismatic/pkg/install" 10 "github.com/apprenda/kismatic/pkg/util" 11 "github.com/spf13/cobra" 12 ) 13 14 type resetOpts struct { 15 planFilename string 16 generatedAssetsDir string 17 verbose bool 18 outputFormat string 19 limit []string 20 force bool 21 removeAssets bool 22 } 23 24 // NewCmdReset resets nodes 25 func NewCmdReset(in io.Reader, out io.Writer) *cobra.Command { 26 opts := &resetOpts{} 27 cmd := &cobra.Command{ 28 Use: "reset", 29 Short: "reset any changes made to the hosts by 'apply'", 30 RunE: func(cmd *cobra.Command, args []string) error { 31 if len(args) != 0 { 32 return fmt.Errorf("Unexpected args: %v", args) 33 } 34 if opts.force == false { 35 ans, err := util.PromptForString(in, out, "Are you sure you want to reset the cluster? All data will be lost", "N", []string{"N", "y"}) 36 if err != nil { 37 return fmt.Errorf("error getting user response: %v", err) 38 } 39 if strings.ToLower(ans) != "y" { 40 os.Exit(0) 41 } 42 } 43 return doReset(out, opts) 44 }, 45 } 46 47 cmd.Flags().StringSliceVar(&opts.limit, "limit", []string{}, "comma-separated list of hostnames to limit the execution to a subset of nodes") 48 cmd.Flags().StringVar(&opts.generatedAssetsDir, "generated-assets-dir", "generated", "path to the directory where assets generated during the installation process will be stored") 49 cmd.Flags().BoolVar(&opts.verbose, "verbose", false, "enable verbose logging from the installation") 50 cmd.Flags().StringVarP(&opts.outputFormat, "output", "o", "simple", "installation output format (options \"simple\"|\"raw\")") 51 cmd.Flags().BoolVar(&opts.force, "force", false, `do not prompt`) 52 cmd.Flags().BoolVar(&opts.removeAssets, "remove-assets", false, "remove generated-assets-dir") 53 54 addPlanFileFlag(cmd.PersistentFlags(), &opts.planFilename) 55 56 return cmd 57 } 58 59 func doReset(out io.Writer, opts *resetOpts) error { 60 planner := &install.FilePlanner{File: opts.planFilename} 61 if !planner.PlanExists() { 62 return planFileNotFoundErr{filename: opts.planFilename} 63 } 64 plan, err := planner.Read() 65 if err != nil { 66 return fmt.Errorf("failed to read plan file: %v", err) 67 } 68 executorOpts := install.ExecutorOptions{ 69 GeneratedAssetsDirectory: opts.generatedAssetsDir, 70 OutputFormat: opts.outputFormat, 71 Verbose: opts.verbose, 72 } 73 executor, err := install.NewExecutor(out, os.Stderr, executorOpts) 74 if err != nil { 75 return err 76 } 77 if err := executor.Reset(plan, opts.limit...); err != nil { 78 return fmt.Errorf("error running reset: %v", err) 79 } 80 81 if opts.removeAssets { 82 util.PrintHeader(out, "Removing Assets Directory", '=') 83 if _, err := os.Stat(opts.generatedAssetsDir); os.IsNotExist(err) { 84 util.PrettyPrintSkipped(out, "Removed %q", opts.generatedAssetsDir) 85 } else { 86 err := os.RemoveAll(opts.generatedAssetsDir) 87 if err != nil { 88 return fmt.Errorf("error deleting assets directory: %v", err) 89 } 90 util.PrettyPrintOk(out, "Remove %q directory", opts.generatedAssetsDir) 91 } 92 } 93 94 return nil 95 }