// backupMetastore will backup the metastore on the host to the passed in path. Database and retention policy backups // will force a backup of the metastore as well as requesting a specific shard backup from the command line func (cmd *Command) backupMetastore() error { metastoreArchivePath, err := cmd.nextPath(filepath.Join(cmd.path, Metafile)) if err != nil { return err } cmd.Logger.Printf("backing up metastore to %s", metastoreArchivePath) req := &snapshotter.Request{ Type: snapshotter.RequestMetastoreBackup, } return cmd.downloadAndVerify(req, metastoreArchivePath, func(file string) error { var data meta.Data binData, err := ioutil.ReadFile(file) if err != nil { return err } if data.UnmarshalBinary(binData) != nil { cmd.Logger.Println("Invalid metadata blob, ensure the metadata service is running (default port 8088)") return errors.New("invalid metadata received") } return nil }) }
// unpackMeta reads the metadata from the backup directory and initializes a raft // cluster and replaces the root metadata. func (cmd *Command) unpackMeta() error { // find the meta file metaFiles, err := filepath.Glob(filepath.Join(cmd.backupFilesPath, backup.Metafile+".*")) if err != nil { return err } if len(metaFiles) == 0 { return fmt.Errorf("no metastore backups in %s", cmd.backupFilesPath) } latest := metaFiles[len(metaFiles)-1] fmt.Fprintf(cmd.Stdout, "Using metastore snapshot: %v\n", latest) // Read the metastore backup f, err := os.Open(latest) if err != nil { return err } var buf bytes.Buffer if _, err := io.Copy(&buf, f); err != nil { return fmt.Errorf("copy: %s", err) } b := buf.Bytes() var i int // Make sure the file is actually a meta store backup file magic := btou64(b[:8]) if magic != snapshotter.BackupMagicHeader { return fmt.Errorf("invalid metadata file") } i += 8 // Size of the meta store bytes length := int(btou64(b[i : i+8])) i += 8 metaBytes := b[i : i+length] i += int(length) // Size of the node.json bytes length = int(btou64(b[i : i+8])) i += 8 nodeBytes := b[i:] // Unpack into metadata. var data meta.Data if err := data.UnmarshalBinary(metaBytes); err != nil { return fmt.Errorf("unmarshal: %s", err) } // Copy meta config and remove peers so it starts in single mode. c := cmd.MetaConfig c.JoinPeers = nil c.LoggingEnabled = false // Create the meta dir if os.MkdirAll(c.Dir, 0700); err != nil { return err } // Write node.json back to meta dir if err := ioutil.WriteFile(filepath.Join(c.Dir, "node.json"), nodeBytes, 0655); err != nil { return err } // Initialize meta store. store := meta.NewService(c) store.RaftListener = newNopListener() // Open the meta store. if err := store.Open(); err != nil { return fmt.Errorf("open store: %s", err) } defer store.Close() // Wait for the store to be ready or error. select { case err := <-store.Err(): return err default: } client := meta.NewClient([]string{store.HTTPAddr()}, false) client.SetLogger(log.New(ioutil.Discard, "", 0)) if err := client.Open(); err != nil { return err } defer client.Close() // Force set the full metadata. if err := client.SetData(&data); err != nil { return fmt.Errorf("set data: %s", err) } return nil }
// unpackMeta reads the metadata from the backup directory and initializes a raft // cluster and replaces the root metadata. func (cmd *Command) unpackMeta() error { // find the meta file metaFiles, err := filepath.Glob(filepath.Join(cmd.backupFilesPath, backup.Metafile+".*")) if err != nil { return err } if len(metaFiles) == 0 { return fmt.Errorf("no metastore backups in %s", cmd.backupFilesPath) } latest := metaFiles[len(metaFiles)-1] fmt.Fprintf(cmd.Stdout, "Using metastore snapshot: %v\n", latest) // Read the metastore backup f, err := os.Open(latest) if err != nil { return err } var buf bytes.Buffer if _, err := io.Copy(&buf, f); err != nil { return fmt.Errorf("copy: %s", err) } // Unpack into metadata. var data meta.Data if err := data.UnmarshalBinary(buf.Bytes()); err != nil { return fmt.Errorf("unmarshal: %s", err) } // Copy meta config and remove peers so it starts in single mode. c := cmd.MetaConfig c.JoinPeers = nil c.LoggingEnabled = false // Initialize meta store. store := meta.NewService(c) store.RaftListener = newNopListener() // Open the meta store. if err := store.Open(); err != nil { return fmt.Errorf("open store: %s", err) } defer store.Close() // Wait for the store to be ready or error. select { case err := <-store.Err(): return err default: } client := meta.NewClient([]string{store.HTTPAddr()}, false) client.SetLogger(log.New(ioutil.Discard, "", 0)) if err := client.Open(); err != nil { return err } defer client.Close() // Force set the full metadata. if err := client.SetData(&data); err != nil { return fmt.Errorf("set data: %s", err) } return nil }