From 8f93fa1f891d6dda43297f4fc4f50c9baee87394 Mon Sep 17 00:00:00 2001 From: Dan Engelbrecht Date: Sun, 29 May 2022 23:42:34 +0200 Subject: [PATCH] pop command --- commands/cmd_pop.go | 105 +++++++++++++++++++++++++++++++++++++++++++ commands/cmd_push.go | 26 ++++++++++- commands/commands.go | 2 +- 3 files changed, 131 insertions(+), 2 deletions(-) create mode 100644 commands/cmd_pop.go diff --git a/commands/cmd_pop.go b/commands/cmd_pop.go new file mode 100644 index 00000000..3d3466cf --- /dev/null +++ b/commands/cmd_pop.go @@ -0,0 +1,105 @@ +package commands + +import ( + "fmt" + "io/ioutil" + "os" + "strings" + "time" + + "github.com/DanEngelbrecht/golongtail/longtailutils" + "github.com/pkg/errors" + "github.com/sirupsen/logrus" +) + +func pop( + numWorkerCount int, + stackOffset uint32, + retainPermissions bool, + enableFileMapping bool) ([]longtailutils.StoreStat, []longtailutils.TimeStat, error) { + const fname = "get" + log := logrus.WithFields(logrus.Fields{ + "fname": fname, + "stackOffset": stackOffset, + "numWorkerCount": numWorkerCount, + "retainPermissions": retainPermissions, + "enableFileMapping": enableFileMapping, + }) + log.Debug(fname) + + storeStats := []longtailutils.StoreStat{} + timeStats := []longtailutils.TimeStat{} + + setupStartTime := time.Now() + + logFile := ".longtail/log" + targetFolderPath := "." + excludeFilterRegEx := "^\\.longtail(/|$)" + blobStoreURI := ".longtail/store" + + history := "" + _, err := os.Stat(logFile) + if err == nil { + historyBytes, err := ioutil.ReadFile(logFile) + if err != nil { + return storeStats, timeStats, errors.Wrap(err, fname) + } + history = string(historyBytes) + } else if !os.IsNotExist(err) { + return storeStats, timeStats, errors.Wrap(err, fname) + } + + historyLines := make([]string, 0) + if history != "" { + historyLines = strings.Split(string(history), "\n") + } + + if len(historyLines) < int(stackOffset+1) { + err = fmt.Errorf("stack offset out of bounds for `%s`, log contains `%d` entries, need `%d` entries", logFile, len(historyLines), int(stackOffset+1)) + return storeStats, timeStats, errors.Wrap(err, fname) + } + + sourceFilePath := historyLines[len(historyLines)-int(stackOffset+1)] + versionLocalStoreIndexPath := sourceFilePath[:len(sourceFilePath)-3] + "lsi" + + setupTime := time.Since(setupStartTime) + timeStats = append(timeStats, longtailutils.TimeStat{"Setup", setupTime}) + + downSyncStoreStats, downSyncTimeStats, err := downsync( + numWorkerCount, + blobStoreURI, + sourceFilePath, + targetFolderPath, + "", + "", + retainPermissions, + false, + versionLocalStoreIndexPath, + "", + excludeFilterRegEx, + true, + false, + enableFileMapping) + + storeStats = append(storeStats, downSyncStoreStats...) + timeStats = append(timeStats, downSyncTimeStats...) + + return storeStats, timeStats, errors.Wrap(err, fname) +} + +type PopCmd struct { + StackOffset uint32 `name:"offset" help:"Offset into log, zero equals top of stack (latest push)" default:"0"` + RetainPermissionsOption + EnableFileMappingOption +} + +func (r *PopCmd) Run(ctx *Context) error { + storeStats, timeStats, err := pop( + ctx.NumWorkerCount, + r.StackOffset, + r.RetainPermissions, + r.EnableFileMapping) + ctx.StoreStats = append(ctx.StoreStats, storeStats...) + ctx.TimeStats = append(ctx.TimeStats, timeStats...) + return err +} diff --git a/commands/cmd_push.go b/commands/cmd_push.go index f17ad45a..fdcd72ef 100644 --- a/commands/cmd_push.go +++ b/commands/cmd_push.go @@ -5,6 +5,7 @@ import ( "fmt" "io/ioutil" "os" + "strings" "time" "github.com/DanEngelbrecht/golongtail/longtailutils" @@ -40,7 +41,8 @@ func push( storeStats := []longtailutils.StoreStat{} timeStats := []longtailutils.TimeStat{} - excludeFilterRegEx := ".longtail/*." + logFile := ".longtail/log" + excludeFilterRegEx := "^\\.longtail(/|$)" sourceFolderPath := "" targetFilePath := ".longtail/tmp.lvi" blobStoreURI := ".longtail/store" @@ -93,6 +95,28 @@ func push( return storeStats, timeStats, errors.Wrap(err, fname) } + history := "" + _, err = os.Stat(logFile) + if err == nil { + historyBytes, err := ioutil.ReadFile(logFile) + if err != nil { + return storeStats, timeStats, errors.Wrap(err, fname) + } + history = string(historyBytes) + } else if !os.IsNotExist(err) { + return storeStats, timeStats, errors.Wrap(err, fname) + } + + historyLines := make([]string, 0) + if history != "" { + historyLines = strings.Split(string(history), "\n") + } + + historyLines = append(historyLines, hashedVersionFilePath) + history = strings.Join(historyLines, "\n") + + ioutil.WriteFile(logFile, []byte(history), 0666) + storeStats = append(storeStats, upSyncStoreStats...) timeStats = append(timeStats, upSyncTimeStats...) diff --git a/commands/commands.go b/commands/commands.go index 75701874..199b7b60 100644 --- a/commands/commands.go +++ b/commands/commands.go @@ -30,5 +30,5 @@ var Cli struct { Unpack UnpackCmd `cmd:"" name:"unpack" help:"Unpack an archive"` Put PutCmd `cmd:"" name:"put" help:"Upload a folder"` Push PushCmd `cmd:"" name:"push" help:"Makes a snapshot of the current folder and store in .longtail folder"` - // Pop PopCmd `cmd:"" name:"pop" help:"Restores the most current snapshot to the current folder from store in .longtail folder"` + Pop PopCmd `cmd:"" name:"pop" help:"Restores the most current snapshot to the current folder from store in .longtail folder"` }