Skip to content

Commit a2a209c

Browse files
authored
Merge pull request #398 from YangSen-qn/nfs
support sequential read file
2 parents 9957276 + 70b3685 commit a2a209c

File tree

16 files changed

+144
-30
lines changed

16 files changed

+144
-30
lines changed

cmd/upload.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package cmd
22

33
import (
44
"github.com/qiniu/go-sdk/v7/storage"
5+
"github.com/spf13/cobra"
6+
57
"github.com/qiniu/qshell/v2/docs"
68
"github.com/qiniu/qshell/v2/iqshell"
79
"github.com/qiniu/qshell/v2/iqshell/common/config"
810
"github.com/qiniu/qshell/v2/iqshell/common/data"
911
"github.com/qiniu/qshell/v2/iqshell/storage/object/upload/operations"
10-
"github.com/spf13/cobra"
1112
)
1213

1314
var uploadCmdBuilder = func(cfg *iqshell.Config) *cobra.Command {
@@ -71,6 +72,7 @@ var upload2CmdBuilder = func(cfg *iqshell.Config) *cobra.Command {
7172
cmd.Flags().StringVarP(&info.OverwriteExportFilePath, "overwrite-list", "w", "", "upload success (overwrite) file list")
7273
cmd.Flags().IntVar(&info.Info.WorkerCount, "thread-count", 1, "multiple thread count")
7374
cmd.Flags().IntVar(&info.UploadConfig.WorkerCount, "worker-count", 3, "the number of concurrently uploaded parts of a single file in resumable upload")
75+
cmd.Flags().BoolVar(&info.UploadConfig.SequentialReadFile, "sequential-read-file", false, "File reading is sequential and does not involve skipping; when enabled, the uploading fragment data will be loaded into the memory. This option may increase file upload speed for mounted network filesystems.")
7476

7577
cmd.Flags().BoolVarP(&info.ResumableAPIV2, "resumable-api-v2", "", false, "use resumable upload v2 APIs to upload")
7678
cmd.Flags().Int64Var(&info.ResumableAPIV2PartSize, "resumable-api-v2-part-size", data.BLOCK_SIZE, "the part size when use resumable upload v2 APIs to upload")
@@ -203,6 +205,7 @@ var resumeUploadCmdBuilder = func(cfg *iqshell.Config) *cobra.Command {
203205
cmd.Flags().StringVarP(&info.MimeType, "mimetype", "t", "", "file mime type")
204206
cmd.Flags().BoolVarP(&info.Overwrite, "overwrite", "", false, "overwrite the file of same key in bucket")
205207
cmd.Flags().BoolVarP(&info.UseResumeV2, "resumable-api-v2", "", false, "use resumable upload v2 APIs to upload")
208+
cmd.Flags().BoolVar(&info.SequentialReadFile, "sequential-read-file", false, "File reading is sequential and does not involve skipping; when enabled, the uploading fragment data will be loaded into the memory. This option may increase file upload speed for mounted network filesystems.")
206209

207210
cmd.Flags().Int64VarP(&info.ChunkSize, "resumable-api-v2-part-size", "", data.BLOCK_SIZE, "the part size when use resumable upload v2 APIs to upload, default 4M")
208211
cmd.Flags().Int64VarP(&info.ChunkSize, "v2-part-size", "", data.BLOCK_SIZE, "the part size when use resumable upload v2 APIs to upload, same to --resumable-api-v2-part-size")

cmd_test/aa_pre_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ package cmd
44

55
import (
66
"fmt"
7+
"testing"
8+
79
"github.com/qiniu/qshell/v2/cmd_test/test"
810
"github.com/qiniu/qshell/v2/iqshell/common/data"
9-
"testing"
1011
)
1112

1213
func TestCmd(t *testing.T) {

cmd_test/user.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,11 @@
33
package cmd
44

55
import (
6-
"github.com/qiniu/qshell/v2/cmd"
7-
"github.com/qiniu/qshell/v2/cmd_test/test"
86
"os"
97
"testing"
8+
9+
"github.com/qiniu/qshell/v2/cmd"
10+
"github.com/qiniu/qshell/v2/cmd_test/test"
1011
)
1112

1213
var accessKey = test.AccessKey

docs/qupload.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ $ qshell qupload --doc
8484
- resumable_api_v2:使用分片 V2 进行上传,默认为 `false` 使用分片 V1 。【可选】
8585
- resumable_api_v2_part_size:使用分片 V2 进行上传时定制分片大小,默认 4194304(4M) 。【可选】
8686
- put_threshold:上传阈值,上传文件大小超过此值会使用分片上传,不超过使用表单上传;单位:B,默认为 8388608(8M) 。【可选】
87+
- sequential_read_file: 文件读为顺序读,不涉及跳读;开启后,上传中的分片数据会被加载至内存。此选项可能会增加挂载网络文件系统的文件上传速度。默认是:false。 【可选】
8788
- record_root:上传记录信息保存路径,包括日志文件和上传进度文件;默认为 `qshell` 上传目录;【可选】
8889
- 通过 `-L` 指定工作目录时,`record_root` 则为此工作目录/qdownload/$jobId,
8990
- 未通过 `-L` 指定工作目录时为 `用户目录/.qshell/users/$CurrentUserName/qdownload/$jobId`

docs/qupload2.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Flags:
4242
--rescan-local rescan local dir to upload newly add files
4343
--resumable-api-v2 use resumable upload v2 APIs to upload
4444
--resumable-api-v2-part-size int the part size when use resumable upload v2 APIs to upload (default 4194304)
45+
--sequential-read-file File reading is sequential and does not involve skipping; when enabled, the uploading fragment data will be loaded into the memory. This option may increase file upload speed for mounted network filesystems.
4546
--skip-file-prefixes string skip files with these file prefixes
4647
--skip-fixed-strings string skip files with the fixed string in the name
4748
--skip-path-prefixes string skip files with these relative path prefixes

docs/rput.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ $ qshell rput --doc
3838
- -T/--callbackHost:上传回调HOST, 必须和 CallbackUrls 一起指定。 【可选】
3939
- --resumable-api-v2:使用分片上传 API V2 进行上传,默认为 `false`, 使用 V1 上传。【可选】
4040
- --resumable-api-v2-part-size:使用分片上传 API V2 进行上传时的分片大小,默认为 4M 。【可选】
41+
- --sequential-read-file: 文件读为顺序读,不涉及跳读;开启后,上传中的分片数据会被加载至内存。此选项可能会增加挂载网络文件系统的文件上传速度。默认是:false。【可选】
4142

4243
# 示例
4344
1 上传本地文件 `/Users/jemy/Documents/qiniu.mp4` 到空间 `if-pbl` 里面。

iqshell/common/account/actions.go

Lines changed: 45 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@ import (
77
"strings"
88

99
"github.com/qiniu/go-sdk/v7/auth/qbox"
10+
"github.com/syndtr/goleveldb/leveldb"
11+
"github.com/syndtr/goleveldb/leveldb/opt"
12+
1013
"github.com/qiniu/qshell/v2/iqshell/common/config"
1114
"github.com/qiniu/qshell/v2/iqshell/common/data"
1215
"github.com/qiniu/qshell/v2/iqshell/common/log"
13-
"github.com/syndtr/goleveldb/leveldb"
14-
"github.com/syndtr/goleveldb/leveldb/opt"
1516
)
1617

1718
// 保存账户信息到账户文件中
@@ -96,9 +97,9 @@ func SaveToDB(acc Account, accountOver bool) (err *data.CodeError) {
9697
}
9798

9899
func getAccount(pt string) (account Account, err *data.CodeError) {
99-
accountFh, openErr := os.Open(pt)
100+
accountFh, openErr := os.OpenFile(info.AccountPath, os.O_RDWR, 0600)
100101
if openErr != nil {
101-
err = data.NewEmptyError().AppendDescF("Open account file error, %s, please use `account` to set Id and SecretKey first", openErr)
102+
err = data.NewEmptyError().AppendDescF("Get account error, %s, please use `account` to set Id and SecretKey first", openErr)
102103
return
103104
}
104105
defer accountFh.Close()
@@ -115,12 +116,48 @@ func getAccount(pt string) (account Account, err *data.CodeError) {
115116
}
116117

117118
acc, dErr := decrypt(string(accountBytes))
118-
if dErr != nil {
119-
err = data.NewEmptyError().AppendDescF("Decrypt account bytes: %v", dErr)
119+
if dErr == nil {
120+
account = acc
120121
return
121122
}
122-
account = acc
123-
return
123+
124+
oldError := data.NewEmptyError().AppendDescF("Decrypt account bytes: %s, you can delete account file(%s) and use `account` command to reset the account", dErr, pt)
125+
if len(acc.Name) == 0 {
126+
return account, oldError
127+
}
128+
129+
accounts, lErr := LookUp(acc.Name)
130+
if lErr != nil || len(accounts) == 0 {
131+
return account, oldError
132+
}
133+
134+
account = accounts[0]
135+
136+
// 尝试替换错误缓存,失败也没关系
137+
jsonStr, mErr := account.value()
138+
if mErr != nil {
139+
log.WarningF("get account, get json error:%s", mErr)
140+
return account, nil
141+
}
142+
143+
_, sErr := accountFh.Seek(0, io.SeekStart)
144+
if sErr != nil {
145+
log.WarningF("get account, file seek error:%s", sErr)
146+
return account, nil
147+
}
148+
149+
tErr := accountFh.Truncate(0)
150+
if tErr != nil {
151+
log.WarningF("get account, file truncate error:%s", tErr)
152+
return account, nil
153+
}
154+
155+
_, wErr := accountFh.WriteString(jsonStr)
156+
if wErr != nil {
157+
log.WarningF("get account, file write error:%s", wErr)
158+
}
159+
160+
return account, nil
124161
}
125162

126163
// qshell 会记录当前的user信息,当切换账户后, 老的账户信息会记录下来

iqshell/common/account/crypt.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ package account
22

33
import (
44
"encoding/base64"
5-
"github.com/qiniu/qshell/v2/iqshell/common/data"
65
"strings"
76

7+
"github.com/qiniu/qshell/v2/iqshell/common/data"
8+
89
"github.com/qiniu/qshell/v2/iqshell/common/utils"
910
)
1011

@@ -15,6 +16,15 @@ func splits(joinStr string) []string {
1516
// 对保存在account.json中的文件字符串进行揭秘操作, 返回Account
1617
func decrypt(joinStr string) (acc Account, err *data.CodeError) {
1718
ss := splits(joinStr)
19+
if len(ss) > 0 {
20+
acc.Name = ss[0]
21+
}
22+
23+
if len(ss) != 3 {
24+
err = data.NewEmptyError().AppendDescF("account json style format error")
25+
return
26+
}
27+
1828
name, accessKey, encryptedKey := ss[0], ss[1], ss[2]
1929
if name == "" || accessKey == "" || encryptedKey == "" {
2030
err = data.NewEmptyError().AppendDescF("name, accessKey and encryptedKey should not be empty")

iqshell/common/utils/crypto.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"crypto/cipher"
77
"crypto/md5"
88
"encoding/hex"
9+
910
"github.com/qiniu/qshell/v2/iqshell/common/data"
1011
)
1112

@@ -42,6 +43,9 @@ func AesDecrypt(crypted, key []byte) ([]byte, *data.CodeError) {
4243

4344
blockMode.CryptBlocks(origData, crypted)
4445
origData = PKCS5UnPadding(origData)
46+
if len(origData) == 0 {
47+
return nil, data.NewEmptyError().AppendDesc("data format error")
48+
}
4549
return origData, nil
4650
}
4751

@@ -56,5 +60,9 @@ func PKCS5Padding(ciphertext []byte, blockSize int) []byte {
5660
func PKCS5UnPadding(origData []byte) []byte {
5761
length := len(origData)
5862
unpadding := int(origData[length-1])
63+
if unpadding >= length {
64+
return nil
65+
}
66+
5967
return origData[:(length - unpadding)]
6068
}

iqshell/common/workspace/load.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package workspace
22

33
import (
4+
"path/filepath"
5+
46
"github.com/qiniu/go-sdk/v7/auth"
57
"github.com/qiniu/go-sdk/v7/storage"
8+
69
"github.com/qiniu/qshell/v2/iqshell/common/data"
7-
"path/filepath"
810

911
"github.com/qiniu/qshell/v2/iqshell/common/account"
1012
"github.com/qiniu/qshell/v2/iqshell/common/config"
@@ -151,6 +153,7 @@ func loadUserInfo() {
151153
}
152154
} else {
153155
userDir = filepath.Join(workspaceDir, usersDirName, defaultUserDirName)
156+
log.WarningF("load user error:%s", err)
154157
}
155158

156159
log.DebugF("user dir:%s", userDir)

0 commit comments

Comments
 (0)