[#1185] neofs-cli: Add progress bar to object put/get

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-03-09 13:35:52 +03:00 committed by Alex Vanin
parent c3db12d71b
commit ad4583fe85
4 changed files with 55 additions and 2 deletions

View file

@ -464,6 +464,13 @@ type GetObjectPrm struct {
objectAddressPrm objectAddressPrm
rawPrm rawPrm
payloadWriterPrm payloadWriterPrm
headerCallback func(*object.Object)
}
// SetHeaderCallback sets callback which is called on the object after the header is received,
// but before the payload is written.
func (p *GetObjectPrm) SetHeaderCallback(f func(*object.Object)) {
p.headerCallback = f
} }
// GetObjectRes groups resulting values of GetObject operation. // GetObjectRes groups resulting values of GetObject operation.
@ -527,6 +534,9 @@ func GetObject(prm GetObjectPrm) (*GetObjectRes, error) {
_, err = rdr.Close() _, err = rdr.Close()
return nil, fmt.Errorf("read object header: %w", err) return nil, fmt.Errorf("read object header: %w", err)
} }
if prm.headerCallback != nil {
prm.headerCallback(&hdr)
}
sz := hdr.PayloadSize() sz := hdr.PayloadSize()
if sz > maxPayloadBufferSize { if sz > maxPayloadBufferSize {

View file

@ -12,6 +12,7 @@ import (
"strings" "strings"
"time" "time"
"github.com/cheggaaa/pb"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
"github.com/nspcc-dev/neofs-sdk-go/checksum" "github.com/nspcc-dev/neofs-sdk-go/checksum"
@ -123,6 +124,8 @@ const (
const putExpiresOnFlag = "expires-on" const putExpiresOnFlag = "expires-on"
const noProgressFlag = "no-progress"
var putExpiredOn uint64 var putExpiredOn uint64
func initObjectPutCmd() { func initObjectPutCmd() {
@ -141,6 +144,7 @@ func initObjectPutCmd() {
flags.Bool("disable-filename", false, "Do not set well-known filename attribute") flags.Bool("disable-filename", false, "Do not set well-known filename attribute")
flags.Bool("disable-timestamp", false, "Do not set well-known timestamp attribute") flags.Bool("disable-timestamp", false, "Do not set well-known timestamp attribute")
flags.Uint64VarP(&putExpiredOn, putExpiresOnFlag, "e", 0, "Last epoch in the life of the object") flags.Uint64VarP(&putExpiredOn, putExpiresOnFlag, "e", 0, "Last epoch in the life of the object")
flags.Bool(noProgressFlag, false, "Do not show progress bar")
} }
func initObjectDeleteCmd() { func initObjectDeleteCmd() {
@ -169,6 +173,7 @@ func initObjectGetCmd() {
flags.String("file", "", "File to write object payload to. Default: stdout.") flags.String("file", "", "File to write object payload to. Default: stdout.")
flags.String("header", "", "File to write header to. Default: stdout.") flags.String("header", "", "File to write header to. Default: stdout.")
flags.Bool(rawFlag, false, rawFlagDesc) flags.Bool(rawFlag, false, rawFlagDesc)
flags.Bool(noProgressFlag, false, "Do not show progress bar")
} }
func initObjectSearchCmd() { func initObjectSearchCmd() {
@ -446,11 +451,31 @@ func putObject(cmd *cobra.Command, _ []string) {
prepareSessionPrmWithOwner(cmd, sessionObjectCtxAddress, key, ownerID, &prm) prepareSessionPrmWithOwner(cmd, sessionObjectCtxAddress, key, ownerID, &prm)
prepareObjectPrm(cmd, &prm) prepareObjectPrm(cmd, &prm)
prm.SetHeader(obj) prm.SetHeader(obj)
var p *pb.ProgressBar
noProgress, _ := cmd.Flags().GetBool(noProgressFlag)
if noProgress {
prm.SetPayloadReader(f) prm.SetPayloadReader(f)
} else {
fi, err := f.Stat()
if err != nil {
cmd.PrintErrf("Failed to get file size, progress bar is disabled: %v\n", err)
prm.SetPayloadReader(f)
} else {
p = pb.New64(fi.Size())
p.Output = cmd.OutOrStdout()
prm.SetPayloadReader(p.NewProxyReader(f))
p.Start()
}
}
res, err := internalclient.PutObject(prm) res, err := internalclient.PutObject(prm)
exitOnErr(cmd, errf("rpc error: %w", err)) exitOnErr(cmd, errf("rpc error: %w", err))
if p != nil {
p.Finish()
}
cmd.Printf("[%s] Object successfully stored\n", filename) cmd.Printf("[%s] Object successfully stored\n", filename)
cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cid) cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cid)
} }
@ -498,7 +523,21 @@ func getObject(cmd *cobra.Command, _ []string) {
prepareSessionPrm(cmd, objAddr, &prm) prepareSessionPrm(cmd, objAddr, &prm)
prepareObjectPrmRaw(cmd, &prm) prepareObjectPrmRaw(cmd, &prm)
prm.SetAddress(objAddr) prm.SetAddress(objAddr)
var p *pb.ProgressBar
noProgress, _ := cmd.Flags().GetBool(noProgressFlag)
if filename == "" || noProgress {
prm.SetPayloadWriter(out) prm.SetPayloadWriter(out)
} else {
p = pb.New64(0)
p.Output = cmd.OutOrStdout()
prm.SetPayloadWriter(p.NewProxyWriter(out))
prm.SetHeaderCallback(func(o *object.Object) {
p.SetTotal64(int64(o.PayloadSize()))
p.Start()
})
}
res, err := internalclient.GetObject(prm) res, err := internalclient.GetObject(prm)
if err != nil { if err != nil {
@ -510,6 +549,9 @@ func getObject(cmd *cobra.Command, _ []string) {
} }
if filename != "" { if filename != "" {
if p != nil {
p.Finish()
}
cmd.Printf("[%s] Object successfully saved\n", filename) cmd.Printf("[%s] Object successfully saved\n", filename)
} }

1
go.mod
View file

@ -3,6 +3,7 @@ module github.com/nspcc-dev/neofs-node
go 1.16 go 1.16
require ( require (
github.com/cheggaaa/pb v1.0.29
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e
github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568 github.com/flynn-archive/go-shlex v0.0.0-20150515145356-3f9db97f8568
github.com/golang/snappy v0.0.3 // indirect github.com/golang/snappy v0.0.3 // indirect

BIN
go.sum

Binary file not shown.