Skip to content

Commit

Permalink
Refactor mc cp and make session optional.
Browse files Browse the repository at this point in the history
Now `mc cp --recursive --continue` creates copy session on failure or
resumes if previous failed session is found.

Fixes #2893
  • Loading branch information
balamurugana committed Oct 12, 2019
1 parent aa4a477 commit 16b706d
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 4 deletions.
18 changes: 16 additions & 2 deletions cmd/cp-main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ var (
Name: "attr",
Usage: "add custom metadata for the object",
},
cli.BoolFlag{
Name: "continue, c",
Usage: "create or resume copy session.",
},
}
)

Expand Down Expand Up @@ -127,6 +131,9 @@ EXAMPLES:
13. Copy a text file to an object storage and assign REDUCED_REDUNDANCY storage-class to the uploaded object.
{{.Prompt}} {{.HelpName}} --storage-class REDUCED_REDUNDANCY myobject.txt play/mybucket
14. Copy a text file to an object storage and create or resume copy session.
$ {{.HelpName}} --recursive --continue myobject.txt play/mybucket
`,
}

Expand Down Expand Up @@ -431,7 +438,7 @@ loop:
// For critical errors we should exit. Session
// can be resumed after the user figures out
// the problem.
session.CloseAndDie()
session.copyCloseAndDie(session.Header.CommandBoolFlags["session"])
}
}
}
Expand Down Expand Up @@ -497,14 +504,21 @@ func mainCopy(ctx *cli.Context) error {
}
sse := ctx.String("encrypt")

session := newSessionV8()
sessionID := getHash("cp", ctx.Args())
if ctx.Bool("continue") && isSessionExists(sessionID) {
resumeSession(sessionID)
return nil
}

session := newSessionV8(sessionID)
session.Header.CommandType = "cp"
session.Header.CommandBoolFlags["recursive"] = recursive
session.Header.CommandStringFlags["older-than"] = olderThan
session.Header.CommandStringFlags["newer-than"] = newerThan
session.Header.CommandStringFlags["storage-class"] = storageClass
session.Header.CommandStringFlags["encrypt-key"] = sseKeys
session.Header.CommandStringFlags["encrypt"] = sse
session.Header.CommandBoolFlags["session"] = ctx.Bool("continue")
session.Header.UserMetaData = userMetaMap

var e error
Expand Down
16 changes: 14 additions & 2 deletions cmd/session-v8.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ func loadSessionV8(sid string) (*sessionV8, *probe.Error) {
}

// newSessionV8 provides a new session.
func newSessionV8() *sessionV8 {
func newSessionV8(sessionID string) *sessionV8 {
s := &sessionV8{}
s.Header = &sessionV8Header{}
s.Header.Version = globalSessionConfigVersion
Expand All @@ -177,7 +177,7 @@ func newSessionV8() *sessionV8 {
s.Header.UserMetaData = make(map[string]string)
s.Header.When = UTCNow()
s.mutex = new(sync.Mutex)
s.SessionID = newRandomID(8)
s.SessionID = sessionID

sessionDataFile, err := getSessionDataFile(s.SessionID)
fatalIf(err.Trace(s.SessionID), "Unable to create session data file \""+sessionDataFile+"\".")
Expand Down Expand Up @@ -375,6 +375,18 @@ func (s sessionV8) CloseAndDie() {
console.Fatalln("Session safely terminated. To resume session `mc session resume " + s.SessionID + "`")
}

func (s sessionV8) copyCloseAndDie(sessionFlag bool) {
if sessionFlag {
s.Close()
console.Fatalln("Command terminated safely. Run this command to resume copy again.")
} else {
s.mutex.Lock()
defer s.mutex.Unlock()

s.DataFP.Close() // ignore error.
}
}

// Create a factory function to simplify checking if
// object was last operated on.
func isLastFactory(lastURL string) func(string) bool {
Expand Down
13 changes: 13 additions & 0 deletions cmd/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
package cmd

import (
"crypto/sha256"
"encoding/hex"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -136,3 +138,14 @@ func removeSessionDataFile(sid string) {
}
os.Remove(dataFile)
}

func getHash(prefix string, args []string) string {
hasher := sha256.New()
for _, arg := range args {
if _, err := hasher.Write([]byte(arg)); err != nil {
panic(err)
}
}

return prefix + "-" + hex.EncodeToString(hasher.Sum(nil))
}

0 comments on commit 16b706d

Please sign in to comment.