github.com/KyaXTeam/consul@v1.4.5/command/snapshot/save/snapshot_save.go (about) 1 package save 2 3 import ( 4 "flag" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/hashicorp/consul/api" 10 "github.com/hashicorp/consul/command/flags" 11 "github.com/hashicorp/consul/snapshot" 12 "github.com/mitchellh/cli" 13 ) 14 15 func New(ui cli.Ui) *cmd { 16 c := &cmd{UI: ui} 17 c.init() 18 return c 19 } 20 21 type cmd struct { 22 UI cli.Ui 23 flags *flag.FlagSet 24 http *flags.HTTPFlags 25 help string 26 } 27 28 func (c *cmd) init() { 29 c.flags = flag.NewFlagSet("", flag.ContinueOnError) 30 c.http = &flags.HTTPFlags{} 31 flags.Merge(c.flags, c.http.ClientFlags()) 32 flags.Merge(c.flags, c.http.ServerFlags()) 33 c.help = flags.Usage(help, c.flags) 34 } 35 36 func (c *cmd) Run(args []string) int { 37 if err := c.flags.Parse(args); err != nil { 38 return 1 39 } 40 41 var file string 42 43 args = c.flags.Args() 44 switch len(args) { 45 case 0: 46 c.UI.Error("Missing FILE argument") 47 return 1 48 case 1: 49 file = args[0] 50 default: 51 c.UI.Error(fmt.Sprintf("Too many arguments (expected 1, got %d)", len(args))) 52 return 1 53 } 54 55 // Create and test the HTTP client 56 client, err := c.http.APIClient() 57 if err != nil { 58 c.UI.Error(fmt.Sprintf("Error connecting to Consul agent: %s", err)) 59 return 1 60 } 61 62 // Take the snapshot. 63 snap, qm, err := client.Snapshot().Save(&api.QueryOptions{ 64 AllowStale: c.http.Stale(), 65 }) 66 if err != nil { 67 c.UI.Error(fmt.Sprintf("Error saving snapshot: %s", err)) 68 return 1 69 } 70 defer snap.Close() 71 72 // Save the file. 73 f, err := os.Create(file) 74 if err != nil { 75 c.UI.Error(fmt.Sprintf("Error creating snapshot file: %s", err)) 76 return 1 77 } 78 if _, err := io.Copy(f, snap); err != nil { 79 f.Close() 80 c.UI.Error(fmt.Sprintf("Error writing snapshot file: %s", err)) 81 return 1 82 } 83 if err := f.Close(); err != nil { 84 c.UI.Error(fmt.Sprintf("Error closing snapshot file after writing: %s", err)) 85 return 1 86 } 87 88 // Read it back to verify. 89 f, err = os.Open(file) 90 if err != nil { 91 c.UI.Error(fmt.Sprintf("Error opening snapshot file for verify: %s", err)) 92 return 1 93 } 94 if _, err := snapshot.Verify(f); err != nil { 95 f.Close() 96 c.UI.Error(fmt.Sprintf("Error verifying snapshot file: %s", err)) 97 return 1 98 } 99 if err := f.Close(); err != nil { 100 c.UI.Error(fmt.Sprintf("Error closing snapshot file after verify: %s", err)) 101 return 1 102 } 103 104 c.UI.Info(fmt.Sprintf("Saved and verified snapshot to index %d", qm.LastIndex)) 105 return 0 106 } 107 108 func (c *cmd) Synopsis() string { 109 return synopsis 110 } 111 112 func (c *cmd) Help() string { 113 return c.help 114 } 115 116 const synopsis = "Saves snapshot of Consul server state" 117 const help = ` 118 Usage: consul snapshot save [options] FILE 119 120 Retrieves an atomic, point-in-time snapshot of the state of the Consul servers 121 which includes key/value entries, service catalog, prepared queries, sessions, 122 and ACLs. 123 124 If ACLs are enabled, a management token must be supplied in order to perform 125 snapshot operations. 126 127 To create a snapshot from the leader server and save it to "backup.snap": 128 129 $ consul snapshot save backup.snap 130 131 To create a potentially stale snapshot from any available server (useful if no 132 leader is available): 133 134 $ consul snapshot save -stale backup.snap 135 136 For a full list of options and examples, please see the Consul documentation. 137 `