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  `