refactor: simplify market datastore backup

This commit is contained in:
Dirk McCormick 2021-07-23 09:33:26 +02:00
parent adba595350
commit 7ef167b04f

View File

@ -2,10 +2,12 @@ package main
import ( import (
"fmt" "fmt"
"io/ioutil"
"os" "os"
"path" "path"
levelds "github.com/ipfs/go-ds-leveldb"
ldbopts "github.com/syndtr/goleveldb/leveldb/opt"
"github.com/filecoin-project/lotus/lib/backupds" "github.com/filecoin-project/lotus/lib/backupds"
"github.com/filecoin-project/lotus/node/repo" "github.com/filecoin-project/lotus/node/repo"
@ -128,16 +130,19 @@ var marketExportDatastoreCmd = &cli.Command{
Action: func(cctx *cli.Context) error { Action: func(cctx *cli.Context) error {
logging.SetLogLevel("badger", "ERROR") // nolint:errcheck logging.SetLogLevel("badger", "ERROR") // nolint:errcheck
// If the backup dir is not specified, just use the OS temp dir
backupDir := cctx.String("backup-dir") backupDir := cctx.String("backup-dir")
if backupDir == "" { if backupDir == "" {
backupDir = os.TempDir() backupDir = os.TempDir()
} }
// Create a new repo at the repo path
r, err := repo.NewFS(cctx.String("repo")) r, err := repo.NewFS(cctx.String("repo"))
if err != nil { if err != nil {
return xerrors.Errorf("opening fs repo: %w", err) return xerrors.Errorf("opening fs repo: %w", err)
} }
// Make sure the repo exists
exists, err := r.Exists() exists, err := r.Exists()
if err != nil { if err != nil {
return err return err
@ -146,39 +151,30 @@ var marketExportDatastoreCmd = &cli.Command{
return xerrors.Errorf("lotus repo doesn't exist") return xerrors.Errorf("lotus repo doesn't exist")
} }
// Lock the repo
lr, err := r.Lock(repo.StorageMiner) lr, err := r.Lock(repo.StorageMiner)
if err != nil { if err != nil {
return err return err
} }
defer lr.Close() //nolint:errcheck defer lr.Close() //nolint:errcheck
// Open the metadata datastore on the repo
namespace := "metadata" namespace := "metadata"
ds, err := lr.Datastore(cctx.Context, datastore.NewKey(namespace).String()) ds, err := lr.Datastore(cctx.Context, datastore.NewKey(namespace).String())
if err != nil { if err != nil {
return err return err
} }
backupRepoDir, err := ioutil.TempDir("", "backup-repo-dir") // Create a tmp datastore that we'll add the exported key / values to
if err != nil { // and then backup
return err backupDs, err := levelds.NewDatastore(backupDir, &levelds.Options{
} Compression: ldbopts.NoCompression,
NoSync: false,
backupRepo, err := repo.NewFS(cctx.String(backupRepoDir)) Strict: ldbopts.StrictAll,
if err != nil { ReadOnly: false,
return xerrors.Errorf("opening backup repo: %w", err) })
}
lockedBackupRepo, err := backupRepo.Lock(repo.StorageMiner)
if err != nil {
return err
}
defer lockedBackupRepo.Close() //nolint:errcheck
backupDs, err := lockedBackupRepo.Datastore(cctx.Context, datastore.NewKey(namespace).String())
if err != nil {
return err
}
// Export the key / values
prefixes := []string{ prefixes := []string{
"/deals/provider", "/deals/provider",
"/retrievals/provider", "/retrievals/provider",
@ -191,16 +187,20 @@ var marketExportDatastoreCmd = &cli.Command{
} }
} }
// Wrap the datastore in a backup datastore
bds, err := backupds.Wrap(backupDs, "") bds, err := backupds.Wrap(backupDs, "")
if err != nil { if err != nil {
return xerrors.Errorf("opening backupds: %w", err) return xerrors.Errorf("opening backupds: %w", err)
} }
fpath := path.Join(backupDir, "datastore.backup") // Create a file for the backup
fpath := path.Join(backupDir, "markets.datastore.backup")
out, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY, 0644) out, err := os.OpenFile(fpath, os.O_CREATE|os.O_WRONLY, 0644)
if err != nil { if err != nil {
return xerrors.Errorf("open %s: %w", fpath, err) return xerrors.Errorf("open %s: %w", fpath, err)
} }
// Write the backup to the file
if err := bds.Backup(out); err != nil { if err := bds.Backup(out); err != nil {
if cerr := out.Close(); cerr != nil { if cerr := out.Close(); cerr != nil {
log.Errorw("error closing backup file while handling backup error", "closeErr", cerr, "backupErr", err) log.Errorw("error closing backup file while handling backup error", "closeErr", cerr, "backupErr", err)