apply backup
This commit is contained in:
@@ -16,6 +16,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/subcommands"
|
||||
"github.com/schollz/progressbar/v3"
|
||||
)
|
||||
|
||||
type (
|
||||
@@ -51,13 +52,21 @@ func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
||||
fmt.Fprintln(os.Stderr, "error: failed to load datastore:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
cli, err := connect(remoteCred, r)
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error: failed to connect to the remote:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
|
||||
pg := progressbar.New(-1)
|
||||
destroyPg := func() {
|
||||
pg.Finish()
|
||||
pg.Clear()
|
||||
pg.Close()
|
||||
|
||||
}
|
||||
|
||||
pg.Describe(fmt.Sprintf("[%s] Checking status...", g.Name))
|
||||
exists, err := cli.Exists(r.GameID)
|
||||
if err != nil {
|
||||
slog.Error(err.Error())
|
||||
@@ -65,45 +74,61 @@ func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
||||
}
|
||||
|
||||
if !exists {
|
||||
pg.Describe(fmt.Sprintf("[%s] Pushing data...", g.Name))
|
||||
if err := push(g, cli); err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "failed to push:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
pg.Describe(fmt.Sprintf("[%s] Pushing backup...", g.Name))
|
||||
if err := pushBackup(g, cli); err != nil {
|
||||
destroyPg()
|
||||
slog.Warn("failed to push backup files", "err", err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
pg.Describe(fmt.Sprintf("[%s] Fetching metadata...", g.Name))
|
||||
hlocal, err := repository.Hash(r.GameID)
|
||||
if err != nil {
|
||||
destroyPg()
|
||||
slog.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
hremote, err := cli.Hash(r.GameID)
|
||||
if err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "error: failed to get the file hash from the remote:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
vlocal, err := repository.Version(r.GameID)
|
||||
if err != nil {
|
||||
destroyPg()
|
||||
slog.Error(err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
remoteMetadata, err := cli.Metadata(r.GameID)
|
||||
if err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "error: failed to get the game metadata from the remote:", err)
|
||||
continue
|
||||
}
|
||||
|
||||
pg.Describe(fmt.Sprintf("[%s] Pulling backup...", g.Name))
|
||||
if err := pullBackup(g, cli); err != nil {
|
||||
slog.Warn("failed to pull backup files", "err", err)
|
||||
}
|
||||
|
||||
pg.Describe(fmt.Sprintf("[%s] Pushing backup...", g.Name))
|
||||
if err := pushBackup(g, cli); err != nil {
|
||||
slog.Warn("failed to push backup files", "err", err)
|
||||
}
|
||||
|
||||
if hlocal == hremote {
|
||||
destroyPg()
|
||||
if vlocal != remoteMetadata.Version {
|
||||
slog.Debug("version is not the same, but the hash is equal. Updating local database")
|
||||
if err := repository.SetVersion(r.GameID, remoteMetadata.Version); err != nil {
|
||||
@@ -116,29 +141,38 @@ func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
||||
}
|
||||
|
||||
if vlocal > remoteMetadata.Version {
|
||||
pg.Describe(fmt.Sprintf("[%s] Pushing data...", g.Name))
|
||||
if err := push(g, cli); err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "failed to push:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
destroyPg()
|
||||
continue
|
||||
}
|
||||
|
||||
if vlocal < remoteMetadata.Version {
|
||||
destroyPg()
|
||||
if err := pull(r.GameID, cli); err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "failed to push:", err)
|
||||
return subcommands.ExitFailure
|
||||
}
|
||||
if err := repository.SetVersion(r.GameID, remoteMetadata.Version); err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "error: failed to synchronize version number:", err)
|
||||
continue
|
||||
}
|
||||
if err := repository.SetDate(r.GameID, remoteMetadata.Date); err != nil {
|
||||
destroyPg()
|
||||
fmt.Fprintln(os.Stderr, "error: failed to synchronize date:", err)
|
||||
continue
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
destroyPg()
|
||||
|
||||
if vlocal == remoteMetadata.Version {
|
||||
if err := conflict(r.GameID, g, remoteMetadata, cli); err != nil {
|
||||
fmt.Fprintln(os.Stderr, "error: failed to resolve conflict:", err)
|
||||
@@ -148,6 +182,7 @@ func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("done.")
|
||||
return subcommands.ExitSuccess
|
||||
}
|
||||
|
||||
@@ -222,6 +257,39 @@ func pushBackup(m repository.Metadata, cli *client.Client) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func pullBackup(m repository.Metadata, cli *client.Client) error {
|
||||
bs, err := cli.ListArchives(m.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, uuid := range bs {
|
||||
rinfo, err := cli.ArchiveInfo(m.ID, uuid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
linfo, err := repository.Archive(m.ID, uuid)
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
path := filepath.Join(repository.DatastorePath(), m.ID, "hist", uuid)
|
||||
if err := os.MkdirAll(path, 0740); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rinfo.MD5 != linfo.MD5 {
|
||||
if err := cli.PullBackup(m.ID, uuid, filepath.Join(path, "data.tar.gz")); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func pull(gameID string, cli *client.Client) error {
|
||||
archivePath := filepath.Join(repository.DatastorePath(), gameID, "data.tar.gz")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user