// Restore restores the database to a previous state. func (s *Store) Restore(rc io.ReadCloser) error { if err := os.Remove(s.dbPath); err != nil && !os.IsNotExist(err) { return err } b, err := ioutil.ReadAll(rc) if err != nil { return err } if err := ioutil.WriteFile(s.dbPath, b, 0660); err != nil { return err } db, err := sql.OpenWithConfiguration(s.dbPath, s.dbConf) if err != nil { return err } s.db = db return nil }
// Open opens the store. If enableSingle is set, and there are no existing peers, // then this node becomes the first node, and therefore leader, of the cluster. func (s *Store) Open(enableSingle bool) error { if err := os.MkdirAll(s.raftDir, 0755); err != nil { return err } // Create the database. Unless it's a memory-based database, tt must be deleted if !s.dbConf.Memory { // as it will be rebuilt from (possibly) a snapshot and committed log entries. if err := os.Remove(s.dbPath); err != nil && !os.IsNotExist(err) { return err } } db, err := sql.OpenWithConfiguration(s.dbPath, s.dbConf) if err != nil { return err } s.db = db s.logger.Println("SQLite database opened at", s.dbConf.FQDSN(s.dbPath)) // Setup Raft configuration. config := raft.DefaultConfig() // Check for any existing peers. peers, err := readPeersJSON(filepath.Join(s.raftDir, "peers.json")) if err != nil { return err } // Allow the node to entry single-mode, potentially electing itself, if // explicitly enabled and there is only 1 node in the cluster already. if enableSingle && len(peers) <= 1 { s.logger.Println("enabling single-node mode") config.EnableSingleNode = true config.DisableBootstrapAfterElect = false } // Setup Raft communication. ln, err := net.Listen("tcp", s.raftBind) if err != nil { return err } s.ln = newnetworkLayer(ln) transport := raft.NewNetworkTransport(s.ln, 3, 10*time.Second, os.Stderr) // Create peer storage. peerStore := raft.NewJSONPeers(s.raftDir, transport) // Create the snapshot store. This allows Raft to truncate the log. snapshots, err := raft.NewFileSnapshotStore(s.raftDir, retainSnapshotCount, os.Stderr) if err != nil { return fmt.Errorf("file snapshot store: %s", err) } // Create the log store and stable store. logStore, err := raftboltdb.NewBoltStore(filepath.Join(s.raftDir, "raft.db")) if err != nil { return fmt.Errorf("new bolt store: %s", err) } // Instantiate the Raft system. ra, err := raft.NewRaft(config, s, logStore, logStore, snapshots, peerStore, transport) if err != nil { return fmt.Errorf("new raft: %s", err) } s.raft = ra return nil }