diff --git a/drivers/all.go b/drivers/all.go index df8a1ffc72ab..785278cf908a 100644 --- a/drivers/all.go +++ b/drivers/all.go @@ -25,6 +25,7 @@ import ( _ "github.com/alist-org/alist/v3/drivers/ftp" _ "github.com/alist-org/alist/v3/drivers/google_drive" _ "github.com/alist-org/alist/v3/drivers/google_photo" + _ "github.com/alist-org/alist/v3/drivers/halalcloud" _ "github.com/alist-org/alist/v3/drivers/ilanzou" _ "github.com/alist-org/alist/v3/drivers/ipfs_api" _ "github.com/alist-org/alist/v3/drivers/lanzou" diff --git a/drivers/halalcloud/driver.go b/drivers/halalcloud/driver.go new file mode 100644 index 000000000000..f03a66d0df3e --- /dev/null +++ b/drivers/halalcloud/driver.go @@ -0,0 +1,563 @@ +package halalcloud + +import ( + "context" + "crypto/sha1" + "fmt" + "github.com/alist-org/alist/v3/internal/driver" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/internal/op" + "github.com/alist-org/alist/v3/pkg/http_range" + "github.com/alist-org/alist/v3/pkg/utils" + bauth "github.com/baidubce/bce-sdk-go/auth" + "github.com/baidubce/bce-sdk-go/bce" + "github.com/baidubce/bce-sdk-go/services/bos" + "github.com/baidubce/bce-sdk-go/services/bos/api" + "github.com/city404/v6-public-rpc-proto/go/v6/common" + pbPublicUser "github.com/city404/v6-public-rpc-proto/go/v6/user" + pubUserFile "github.com/city404/v6-public-rpc-proto/go/v6/userfile" + "github.com/jinzhu/copier" + "github.com/rclone/rclone/lib/readers" + "github.com/zzzhr1990/go-common-entity/userfile" + "google.golang.org/grpc" + "io" + "strconv" + "strings" + "sync" + "time" +) + +type HalalCloud struct { + *HalalCommon + model.Storage + Addition + + uploadThread int + fileStatus int // 文件状态 类型,0小文件(1M)、1中型文件(16M)、2大型文件(32M) +} + +func (d *HalalCloud) Config() driver.Config { + return config +} + +func (d *HalalCloud) GetAddition() driver.Additional { + return &d.Addition +} + +func (d *HalalCloud) Init(ctx context.Context) error { + d.uploadThread, _ = strconv.Atoi(d.UploadThread) + if d.uploadThread < 1 || d.uploadThread > 32 { + d.uploadThread, d.UploadThread = 3, "3" + } + + if d.CustomUploadPartSize == "" { + d.CustomUploadPartSize = "0" + } + + if d.HalalCommon == nil { + d.HalalCommon = &HalalCommon{ + Common: &Common{}, + AuthService: &AuthService{ + appID: AppID, + appVersion: AppVersion, + appSecret: AppSecret, + tr: &TokenResp{ + RefreshToken: d.Addition.RefreshToken, + }, + }, + UserInfo: &UserInfo{}, + refreshTokenFunc: func(token string) error { + d.Addition.RefreshToken = token + op.MustSaveDriverStorage(d) + return nil + }, + } + } + + // 防止重复登录 + if d.Addition.RefreshToken == "" || !d.IsLogin() { + as, err := d.NewAuthServiceWithOauth() + if err != nil { + d.GetStorage().SetStatus(fmt.Sprintf("%+v", err.Error())) + return err + } + d.HalalCommon.AuthService = as + d.SetTokenResp(as.tr) + op.MustSaveDriverStorage(d) + } + var err error + d.HalalCommon.serv, err = d.NewAuthService(d.Addition.RefreshToken) + if err != nil { + return err + } + + return nil +} + +func (d *HalalCloud) Drop(ctx context.Context) error { + return nil +} + +func (d *HalalCloud) List(ctx context.Context, dir model.Obj, args model.ListArgs) ([]model.Obj, error) { + return d.getFiles(ctx, dir) +} + +func (d *HalalCloud) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { + return d.getLink(ctx, file, args) +} + +func (d *HalalCloud) MakeDir(ctx context.Context, parentDir model.Obj, dirName string) (model.Obj, error) { + return d.makeDir(ctx, parentDir, dirName) +} + +func (d *HalalCloud) Move(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { + return d.move(ctx, srcObj, dstDir) +} + +func (d *HalalCloud) Rename(ctx context.Context, srcObj model.Obj, newName string) (model.Obj, error) { + return d.rename(ctx, srcObj, newName) +} + +func (d *HalalCloud) Copy(ctx context.Context, srcObj, dstDir model.Obj) (model.Obj, error) { + return d.copy(ctx, srcObj, dstDir) +} + +func (d *HalalCloud) Remove(ctx context.Context, obj model.Obj) error { + return d.remove(ctx, obj) +} + +func (d *HalalCloud) Put(ctx context.Context, dstDir model.Obj, stream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { + return d.put(ctx, dstDir, stream, up) +} + +func (d *HalalCloud) IsLogin() bool { + if d.AuthService.tr == nil { + return false + } + serv, err := d.NewAuthService(d.Addition.RefreshToken) + if err != nil { + return false + } + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + result, err := pbPublicUser.NewPubUserClient(serv.GetGrpcConnection()).Get(ctx, &pbPublicUser.User{ + Identity: "", + }) + if result == nil || err != nil { + return false + } + d.UserInfo.Identity = result.Identity + d.UserInfo.CreateTs = result.CreateTs + d.UserInfo.Name = result.Name + d.UserInfo.UpdateTs = result.UpdateTs + return true +} + +type HalalCommon struct { + *Common + *AuthService // 登录信息 + *UserInfo // 用户信息 + refreshTokenFunc func(token string) error + serv *AuthService +} + +func (d *HalalCloud) SetTokenResp(tr *TokenResp) { + d.Addition.RefreshToken = tr.RefreshToken +} + +func (d *HalalCloud) getFiles(ctx context.Context, dir model.Obj) ([]model.Obj, error) { + + files := make([]model.Obj, 0) + limit := int64(100) + token := "" + client := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()) + + opDir := d.GetCurrentDir(dir) + //if len(args) > 0 { + // opDir = d.GetCurrentOpDir(dir, args, 0) + //} + //filesList := FilesList{} + //for { + // result, err := client.List(ctx, &pubUserFile.FileListRequest{ + // Parent: &pubUserFile.File{Path: opDir}, + // ListInfo: &common.ScanListRequest{ + // Limit: limit, + // Token: token, + // }, + // }) + // if err != nil { + // return nil, err + // } + // err = copier.Copy(&filesList, result) + // if err != nil { + // return nil, err + // } + // if filesList.Files != nil && len(filesList.Files) > 0 { + // for i := 0; i < len(filesList.Files); i++ { + // files = append(files, filesList.Files[i]) + // } + // } + // + // if result.ListInfo == nil || result.ListInfo.Token == "" { + // break + // } + // token = result.ListInfo.Token + // + //} + + filesList := FilesList{} + + // Create a channel to collect results + results := make(chan *pubUserFile.FileListResponse) + + // Create a WaitGroup to wait for all goroutines to finish + var wg sync.WaitGroup + + for { + wg.Add(1) + go func(token string) { + defer wg.Done() + result, err := client.List(ctx, &pubUserFile.FileListRequest{ + Parent: &pubUserFile.File{Path: opDir}, + ListInfo: &common.ScanListRequest{ + Limit: limit, + Token: token, + }, + }) + if err != nil { + // Handle error + return + } + results <- result + }(token) + + // Wait for all goroutines to finish and close the results channel + go func() { + wg.Wait() + close(results) + }() + + // Collect all results + for result := range results { + err := copier.Copy(&filesList, result) + if err != nil { + return nil, err + } + if filesList.Files != nil && len(filesList.Files) > 0 { + for i := 0; i < len(filesList.Files); i++ { + files = append(files, filesList.Files[i]) + } + } + + if result.ListInfo == nil || result.ListInfo.Token == "" { + return files, nil + } + token = result.ListInfo.Token + } + } + +} + +func (d *HalalCloud) getLink(ctx context.Context, file model.Obj, args model.LinkArgs) (*model.Link, error) { + + id := file.GetID() + + newPath := userfile.NewFormattedPath(d.GetCurrentDir(file)).GetPath() + client := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()) + //if len(id) > 0 { + // newPath = "" + //} + ctx1, cancelFunc := context.WithCancel(context.Background()) + defer cancelFunc() + result, err := client.ParseFileSlice(ctx1, &pubUserFile.File{ + Identity: id, + Parent: file.(*Files).Parent, + Name: file.GetName(), + Path: newPath, + MimeType: file.(*Files).MimeType, + Size: file.(*Files).Size, + Type: file.(*Files).Type, + CreateTs: file.(*Files).CreateTs, + UpdateTs: file.(*Files).UpdateTs, + DeleteTs: file.(*Files).DeleteTs, + ContentIdentity: file.(*Files).ContentIdentity, + }, grpc.MaxCallSendMsgSize(10*1024*1024)) + if err != nil { + return nil, err + } + fileAddrs := []*pubUserFile.SliceDownloadInfo{} + var addressDuration int64 + + nodesNumber := len(result.RawNodes) + nodesIndex := nodesNumber - 1 + startIndex, endIndex := 0, nodesIndex + for nodesIndex >= 0 { + if nodesIndex >= 200 { + endIndex = 200 + } else { + endIndex = nodesNumber + } + for ; endIndex <= nodesNumber; endIndex += 200 { + if endIndex == 0 { + endIndex = 1 + } + sliceAddress, err := client.GetSliceDownloadAddress(ctx, &pubUserFile.SliceDownloadAddressRequest{ + Identity: result.RawNodes[startIndex:endIndex], + Version: 1, + }) + if err != nil { + return nil, err + } + addressDuration = sliceAddress.ExpireAt + fileAddrs = append(fileAddrs, sliceAddress.Addresses...) + startIndex = endIndex + nodesIndex -= 200 + } + + } + + //batchRequest := []string{} + //for _, slice := range result.RawNodes { + // batchRequest = append(batchRequest, slice) + // if len(batchRequest) >= 200 { + // sliceAddress, err := client.GetSliceDownloadAddress(ctx, &pubUserFile.SliceDownloadAddressRequest{ + // Identity: batchRequest, + // Version: 1, + // }) + // if err != nil { + // return nil, err + // } + // fileAddrs = append(fileAddrs, sliceAddress.Addresses...) + // batchRequest = []string{} + // addressDuration = sliceAddress.ExpireAt + // } + //} + //if len(batchRequest) > 0 { + // sliceAddress, err := client.GetSliceDownloadAddress(ctx, &pubUserFile.SliceDownloadAddressRequest{ + // Identity: batchRequest, + // Version: 1, + // }) + // if err != nil { + // return nil, err + // } + // fileAddrs = append(fileAddrs, sliceAddress.Addresses...) + //} + size := result.FileSize + chunks := getChunkSizes(result.Sizes) + var finalClosers utils.Closers + resultRangeReader := func(ctx context.Context, httpRange http_range.Range) (io.ReadCloser, error) { + length := httpRange.Length + if httpRange.Length >= 0 && httpRange.Start+httpRange.Length >= size { + length = -1 + } + if err != nil { + return nil, fmt.Errorf("open download file failed: %w", err) + } + oo := &openObject{ + ctx: ctx, + d: fileAddrs, + chunk: &[]byte{}, + chunks: &chunks, + skip: httpRange.Start, + sha: result.Sha1, + shaTemp: sha1.New(), + } + finalClosers.Add(oo) + + return readers.NewLimitedReadCloser(oo, length), nil + } + + var duration time.Duration + if addressDuration != 0 { + duration = time.Until(time.UnixMilli(addressDuration)) + } else { + duration = time.Until(time.Now().Add(time.Hour)) + } + + resultRangeReadCloser := &model.RangeReadCloser{RangeReader: resultRangeReader, Closers: finalClosers} + return &model.Link{ + RangeReadCloser: resultRangeReadCloser, + Expiration: &duration, + }, nil +} + +func (d *HalalCloud) makeDir(ctx context.Context, dir model.Obj, name string) (model.Obj, error) { + newDir := userfile.NewFormattedPath(d.GetCurrentOpDir(dir, []string{name}, 0)).GetPath() + _, err := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()).Create(ctx, &pubUserFile.File{ + // Parent: &pubUserFile.File{Path: currentDir}, + Path: newDir, + }) + return nil, err +} + +func (d *HalalCloud) move(ctx context.Context, obj model.Obj, dir model.Obj) (model.Obj, error) { + oldDir := userfile.NewFormattedPath(d.GetCurrentDir(obj)).GetPath() + newDir := userfile.NewFormattedPath(d.GetCurrentDir(dir)).GetPath() + _, err := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()).Move(ctx, &pubUserFile.BatchOperationRequest{ + Source: []*pubUserFile.File{ + { + Identity: obj.GetID(), + Path: oldDir, + }, + }, + Dest: &pubUserFile.File{ + Identity: dir.GetID(), + Path: newDir, + }, + }) + return nil, err +} + +func (d *HalalCloud) rename(ctx context.Context, obj model.Obj, name string) (model.Obj, error) { + id := obj.GetID() + newPath := userfile.NewFormattedPath(d.GetCurrentOpDir(obj, []string{name}, 0)).GetPath() + //if len(id) > 0 { + // newPath = "" + //} + _, err := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()).Rename(ctx, &pubUserFile.File{ + Path: newPath, + Identity: id, + Name: name, + }) + return nil, err +} + +func (d *HalalCloud) copy(ctx context.Context, obj model.Obj, dir model.Obj) (model.Obj, error) { + id := obj.GetID() + sourcePath := userfile.NewFormattedPath(d.GetCurrentDir(obj)).GetPath() + if len(id) > 0 { + sourcePath = "" + } + dest := &pubUserFile.File{ + Identity: dir.GetID(), + Path: userfile.NewFormattedPath(d.GetCurrentDir(dir)).GetPath(), + } + _, err := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()).Copy(ctx, &pubUserFile.BatchOperationRequest{ + Source: []*pubUserFile.File{ + { + Path: sourcePath, + Identity: id, + }, + }, + Dest: dest, + }) + return nil, err +} + +func (d *HalalCloud) remove(ctx context.Context, obj model.Obj) error { + id := obj.GetID() + newPath := userfile.NewFormattedPath(d.GetCurrentDir(obj)).GetPath() + //if len(id) > 0 { + // newPath = "" + //} + _, err := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()).Delete(ctx, &pubUserFile.BatchOperationRequest{ + Source: []*pubUserFile.File{ + { + Path: newPath, + Identity: id, + }, + }, + }) + return err +} + +func (d *HalalCloud) put(ctx context.Context, dstDir model.Obj, fileStream model.FileStreamer, up driver.UpdateProgress) (model.Obj, error) { + + tempFile, err := fileStream.CacheFullInTempFile() + if err != nil { + return nil, err + } + + newDir := userfile.NewFormattedPath(d.GetCurrentDir(dstDir)).GetPath() + newDir = strings.TrimSuffix(newDir, "/") + "/" + fileStream.GetName() + result, err := pubUserFile.NewPubUserFileClient(d.HalalCommon.serv.GetGrpcConnection()).CreateUploadToken(ctx, &pubUserFile.File{ + Path: newDir, + }) + if err != nil { + return nil, err + } + clientConfig := bos.BosClientConfiguration{ + Ak: result.AccessKey, + Sk: result.SecretKey, + Endpoint: result.Endpoint, + RedirectDisabled: false, + //SessionToken: result.SessionToken, + } + + // 初始化一个BosClient + bosClient, err := bos.NewClientWithConfig(&clientConfig) + if err != nil { + return nil, fmt.Errorf("failed to create bos client: %w", err) + } + stsCredential, err := bauth.NewSessionBceCredentials( + result.AccessKey, + result.SecretKey, + result.Token) + if err != nil { + return nil, fmt.Errorf("failed to create sts credential: %w", err) + } + bosClient.Config.Credentials = stsCredential + bosClient.MaxParallel = int64(d.uploadThread) + + d.setFileStatus(fileStream.GetSize()) // 设置文件状态 + + bosClient.MultipartSize = d.getSliceSize() + + if fileStream.GetSize() < 1*utils.MB { + partBody, _ := bce.NewBodyFromSizedReader(tempFile, fileStream.GetSize()) + _, err := bosClient.PutObject(result.Bucket, result.Key, partBody, nil) + //_, err = bosClient.PutObjectFromStream(result.GetBucket(), fileStream.GetName(), tempFile, nil) + if err != nil { + return nil, fmt.Errorf("failed to upload file: %v ===> %s/%s", err, clientConfig.Ak, clientConfig.Sk) + } + up(100) + } else { + res, err := bosClient.BasicInitiateMultipartUpload(result.Bucket, result.Key) + // 分块大小按MULTIPART_ALIGN=1MB对齐 + partSize := (bosClient.MultipartSize + + bos.MULTIPART_ALIGN - 1) / bos.MULTIPART_ALIGN * bos.MULTIPART_ALIGN + + // 获取文件大小,并计算分块数目,最大分块数MAX_PART_NUMBER=10000 + fileSize := fileStream.GetSize() + partNum := (fileSize + partSize - 1) / partSize + if partNum > bos.MAX_PART_NUMBER { // 超过最大分块数,需调整分块大小 + partSize = (fileSize + bos.MAX_PART_NUMBER + 1) / bos.MAX_PART_NUMBER + partSize = (partSize + bos.MULTIPART_ALIGN - 1) / bos.MULTIPART_ALIGN * bos.MULTIPART_ALIGN + partNum = (fileSize + partSize - 1) / partSize + } + // 创建保存每个分块上传后的ETag和PartNumber信息的列表 + partEtags := make([]api.UploadInfoType, 0) + + // 逐个分块上传 + for i := int64(1); i <= partNum; i++ { + // 计算偏移offset和本次上传的大小uploadSize + uploadSize := partSize + offset := partSize * (i - 1) + left := fileSize - offset + if left < partSize { + uploadSize = left + } + + // 创建指定大小的文件流 + partBody, _ := bce.NewBodyFromSizedReader(tempFile, uploadSize) + + // 上传当前分块 + etag, _ := bosClient.BasicUploadPart(result.Bucket, result.Key, res.UploadId, int(i), partBody) + + // 保存当前分块上传成功后返回的序号和ETag + partEtags = append(partEtags, api.UploadInfoType{int(i), etag}) + + up(float64(i) / float64(partNum) * 100) + } + + completeArgs := &api.CompleteMultipartUploadArgs{Parts: partEtags} + _, err = bosClient.CompleteMultipartUploadFromStruct( + result.Bucket, result.Key, res.UploadId, completeArgs) + if err != nil { + return nil, err + } + } + return nil, nil +} + +var _ driver.Driver = (*HalalCloud)(nil) diff --git a/drivers/halalcloud/meta.go b/drivers/halalcloud/meta.go new file mode 100644 index 000000000000..89d399a6ddda --- /dev/null +++ b/drivers/halalcloud/meta.go @@ -0,0 +1,35 @@ +package halalcloud + +import ( + "github.com/alist-org/alist/v3/internal/driver" + "github.com/alist-org/alist/v3/internal/op" +) + +type Addition struct { + // Usually one of two + driver.RootID + // define other + RefreshToken string `json:"refresh_token" required:"true" help:"login type is refresh_token,this is required"` + UploadThread string `json:"upload_thread" default:"3" help:"1<=thread<=32"` + CustomUploadPartSize string `json:"custom_upload_part_size" default:"0" help:"0 for auto"` +} + +var config = driver.Config{ + Name: "HalalCloud", + LocalSort: false, + OnlyLocal: true, + OnlyProxy: true, + NoCache: false, + NoUpload: false, + NeedMs: false, + DefaultRoot: "/", + CheckStatus: false, + Alert: "", + NoOverwriteUpload: false, +} + +func init() { + op.RegisterDriver(func() driver.Driver { + return &HalalCloud{} + }) +} diff --git a/drivers/halalcloud/options.go b/drivers/halalcloud/options.go new file mode 100644 index 000000000000..56e5fdc5c096 --- /dev/null +++ b/drivers/halalcloud/options.go @@ -0,0 +1,52 @@ +package halalcloud + +import "google.golang.org/grpc" + +func defaultOptions() halalOptions { + return halalOptions{ + // onRefreshTokenRefreshed: func(string) {}, + grpcOptions: []grpc.DialOption{ + grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(1024 * 1024 * 32)), + // grpc.WithMaxMsgSize(1024 * 1024 * 1024), + }, + } +} + +type HalalOption interface { + apply(*halalOptions) +} + +// halalOptions configure a RPC call. halalOptions are set by the HalalOption +// values passed to Dial. +type halalOptions struct { + onTokenRefreshed func(accessToken string, accessTokenExpiredAt int64, refreshToken string, refreshTokenExpiredAt int64) + grpcOptions []grpc.DialOption +} + +// funcDialOption wraps a function that modifies halalOptions into an +// implementation of the DialOption interface. +type funcDialOption struct { + f func(*halalOptions) +} + +func (fdo *funcDialOption) apply(do *halalOptions) { + fdo.f(do) +} + +func newFuncDialOption(f func(*halalOptions)) *funcDialOption { + return &funcDialOption{ + f: f, + } +} + +func WithRefreshTokenRefreshedCallback(s func(accessToken string, accessTokenExpiredAt int64, refreshToken string, refreshTokenExpiredAt int64)) HalalOption { + return newFuncDialOption(func(o *halalOptions) { + o.onTokenRefreshed = s + }) +} + +func WithGrpcDialOptions(opts ...grpc.DialOption) HalalOption { + return newFuncDialOption(func(o *halalOptions) { + o.grpcOptions = opts + }) +} diff --git a/drivers/halalcloud/types.go b/drivers/halalcloud/types.go new file mode 100644 index 000000000000..9bb7e2c5b03b --- /dev/null +++ b/drivers/halalcloud/types.go @@ -0,0 +1,141 @@ +package halalcloud + +import ( + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/pkg/utils" + "github.com/city404/v6-public-rpc-proto/go/v6/common" + "google.golang.org/grpc" + "time" +) + +type AuthService struct { + appID string + appVersion string + appSecret string + grpcConnection *grpc.ClientConn + dopts halalOptions + tr *TokenResp +} + +type TokenResp struct { + AccessToken string `json:"accessToken,omitempty"` + AccessTokenExpiredAt int64 `json:"accessTokenExpiredAt,omitempty"` + RefreshToken string `json:"refreshToken,omitempty"` + RefreshTokenExpiredAt int64 `json:"refreshTokenExpiredAt,omitempty"` +} + +type UserInfo struct { + Identity string `json:"identity,omitempty"` + UpdateTs int64 `json:"updateTs,omitempty"` + Name string `json:"name,omitempty"` + CreateTs int64 `json:"createTs,omitempty"` +} + +type OrderByInfo struct { + Field string `json:"field,omitempty"` + Asc bool `json:"asc,omitempty"` +} + +type ListInfo struct { + Token string `json:"token,omitempty"` + Limit int64 `json:"limit,omitempty"` + OrderBy []*OrderByInfo `json:"order_by,omitempty"` + Version int32 `json:"version,omitempty"` +} + +type FilesList struct { + Files []*Files `json:"files,omitempty"` + ListInfo *common.ScanListRequest `json:"list_info,omitempty"` +} + +var _ model.Obj = (*Files)(nil) + +type Files struct { + Identity string `json:"identity,omitempty"` + Parent string `json:"parent,omitempty"` + Name string `json:"name,omitempty"` + Path string `json:"path,omitempty"` + MimeType string `json:"mime_type,omitempty"` + Size int64 `json:"size,omitempty"` + Type int64 `json:"type,omitempty"` + CreateTs int64 `json:"create_ts,omitempty"` + UpdateTs int64 `json:"update_ts,omitempty"` + DeleteTs int64 `json:"delete_ts,omitempty"` + Deleted bool `json:"deleted,omitempty"` + Dir bool `json:"dir,omitempty"` + Hidden bool `json:"hidden,omitempty"` + Locked bool `json:"locked,omitempty"` + Shared bool `json:"shared,omitempty"` + Starred bool `json:"starred,omitempty"` + Trashed bool `json:"trashed,omitempty"` + LockedAt int64 `json:"locked_at,omitempty"` + LockedBy string `json:"locked_by,omitempty"` + SharedAt int64 `json:"shared_at,omitempty"` + Flag int64 `json:"flag,omitempty"` + Unique string `json:"unique,omitempty"` + ContentIdentity string `json:"content_identity,omitempty"` + Label int64 `json:"label,omitempty"` + StoreType int64 `json:"store_type,omitempty"` + Version int64 `json:"version,omitempty"` +} + +func (f *Files) GetSize() int64 { + return f.Size +} + +func (f *Files) GetName() string { + return f.Name +} + +func (f *Files) ModTime() time.Time { + return time.UnixMilli(f.UpdateTs) +} + +func (f *Files) CreateTime() time.Time { + return time.UnixMilli(f.UpdateTs) +} + +func (f *Files) IsDir() bool { + return f.Dir +} + +func (f *Files) GetHash() utils.HashInfo { + return utils.HashInfo{} +} + +func (f *Files) GetID() string { + if len(f.Identity) == 0 { + f.Identity = "/" + } + return f.Identity +} + +func (f *Files) GetPath() string { + return f.Path +} + +func fileToObj(f Files) *model.ObjThumb { + return &model.ObjThumb{ + Object: model.Object{ + ID: f.Identity, + Path: f.Path, + Name: f.Name, + Size: f.Size, + Modified: f.ModTime(), + Ctime: f.CreateTime(), + IsFolder: f.IsDir(), + }, + } +} + +type SteamFile struct { + file model.File +} + +func (s *SteamFile) Read(p []byte) (n int, err error) { + return s.file.Read(p) +} + +func (s *SteamFile) Close() error { + return s.file.Close() +} diff --git a/drivers/halalcloud/util.go b/drivers/halalcloud/util.go new file mode 100644 index 000000000000..724836c20d79 --- /dev/null +++ b/drivers/halalcloud/util.go @@ -0,0 +1,493 @@ +package halalcloud + +import ( + "bytes" + "context" + "crypto/md5" + "crypto/tls" + "encoding/hex" + "errors" + "fmt" + "github.com/alist-org/alist/v3/internal/model" + "github.com/alist-org/alist/v3/pkg/utils" + pbPublicUser "github.com/city404/v6-public-rpc-proto/go/v6/user" + pubUserFile "github.com/city404/v6-public-rpc-proto/go/v6/userfile" + "github.com/google/uuid" + "github.com/ipfs/go-cid" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/credentials" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" + "hash" + "io" + "net/http" + "strconv" + "strings" + "sync" + "time" +) + +const ( + AppID = "devDebugger/1.0" + AppVersion = "1.0.0" + AppSecret = "Nkx3Y2xvZ2luLmNu" +) + +const ( + grpcServer = "grpcuserapi.2dland.cn:443" + grpcServerAuth = "grpcuserapi.2dland.cn" +) + +func (d *HalalCloud) NewAuthServiceWithOauth(options ...HalalOption) (*AuthService, error) { + + aService := &AuthService{} + err2 := errors.New("") + + svc := d.HalalCommon.AuthService + for _, opt := range options { + opt.apply(&svc.dopts) + } + + grpcOptions := svc.dopts.grpcOptions + grpcOptions = append(grpcOptions, grpc.WithAuthority(grpcServerAuth), grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + ctxx := svc.signContext(method, ctx) + err := invoker(ctxx, method, req, reply, cc, opts...) // invoking RPC method + return err + })) + + grpcConnection, err := grpc.NewClient(grpcServer, grpcOptions...) + if err != nil { + return nil, err + } + defer grpcConnection.Close() + userClient := pbPublicUser.NewPubUserClient(grpcConnection) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + stateString := uuid.New().String() + // queryValues.Add("callback", oauthToken.Callback) + oauthToken, err := userClient.CreateAuthToken(ctx, &pbPublicUser.LoginRequest{ + ReturnType: 2, + State: stateString, + ReturnUrl: "", + }) + if err != nil { + return nil, err + } + if len(oauthToken.State) < 1 { + oauthToken.State = stateString + } + + if oauthToken.Url != "" { + /* resultChan := make(chan *AuthService, 1) + errorChan := make(chan error, 1) + + go func() { + aService, err := d.GetRefreshToken(svc, &userClient, oauthToken) + if err != nil { + errorChan <- err + } else { + resultChan <- aService + } + }()*/ + return nil, fmt.Errorf(`need verify: Click Here`, oauthToken.Url) + } + + return aService, err2 + +} + +/* + func (d *HalalCloud) GetRefreshToken(svc *AuthService, userClient *pbPublicUser.PubUserClient, oauthToken *pbPublicUser.OauthTokenResponse) (*AuthService, error) { + checkTimer := time.NewTicker(5 * time.Second) + defer checkTimer.Stop() + for { + select { + case <-checkTimer.C: + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + checkLoginResponse, err := (*userClient).VerifyAuthToken(ctx, &pbPublicUser.LoginRequest{ + State: oauthToken.State, + Callback: oauthToken.Callback, + ReturnType: 2, + }) + if err != nil { + return nil, err + } + if checkLoginResponse.Status == 6 { + login := checkLoginResponse.Login + if login == nil { + return nil, fmt.Errorf("login is nil") + } + if login.User != nil && len(login.Token.RefreshToken) > 0 { + // checkLoginResponse = checkLoginResponse + _ = d.refreshTokenFunc(login.Token.RefreshToken) + svc.OnAccessTokenRefreshed(login.Token.AccessToken, login.Token.AccessTokenExpireTs, login.Token.RefreshToken, login.Token.RefreshTokenExpireTs) + newAuthService, err := d.NewAuthService(login.Token.RefreshToken) + if err != nil { + return nil, err + } + return newAuthService, nil + // break + } + } + + // reset timer + checkTimer.Reset(5 * time.Second) + + } + } + } +*/ +func (d *HalalCloud) NewAuthService(refreshToken string, options ...HalalOption) (*AuthService, error) { + svc := d.HalalCommon.AuthService + + if len(refreshToken) < 1 { + refreshToken = d.Addition.RefreshToken + } + + if len(d.tr.AccessToken) > 0 { + accessTokenExpiredAt := d.tr.AccessTokenExpiredAt + current := time.Now().UnixMilli() + if accessTokenExpiredAt < current { + // access token expired + d.tr.AccessToken = "" + d.tr.AccessTokenExpiredAt = 0 + } else { + svc.tr.AccessTokenExpiredAt = accessTokenExpiredAt + svc.tr.AccessToken = d.tr.AccessToken + } + } + + for _, opt := range options { + opt.apply(&svc.dopts) + } + + grpcOptions := svc.dopts.grpcOptions + grpcOptions = append(grpcOptions, grpc.WithAuthority(grpcServerAuth), grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})), grpc.WithUnaryInterceptor(func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { + ctxx := svc.signContext(method, ctx) + err := invoker(ctxx, method, req, reply, cc, opts...) // invoking RPC method + if err != nil { + grpcStatus, ok := status.FromError(err) + // if error is grpc error and error code is unauthenticated and error message contains "invalid accesstoken" and refresh token is not empty + // then refresh access token and retry + if ok && grpcStatus.Code() == codes.Unauthenticated && strings.Contains(grpcStatus.Err().Error(), "invalid accesstoken") && len(refreshToken) > 0 { + // refresh token + refreshResponse, err := pbPublicUser.NewPubUserClient(cc).Refresh(ctx, &pbPublicUser.Token{ + RefreshToken: refreshToken, + }) + if err != nil { + return err + } + if len(refreshResponse.AccessToken) > 0 { + svc.tr.AccessToken = refreshResponse.AccessToken + svc.tr.AccessTokenExpiredAt = refreshResponse.AccessTokenExpireTs + svc.OnAccessTokenRefreshed(refreshResponse.AccessToken, refreshResponse.AccessTokenExpireTs, refreshResponse.RefreshToken, refreshResponse.RefreshTokenExpireTs) + } + // retry + ctxx := svc.signContext(method, ctx) + err = invoker(ctxx, method, req, reply, cc, opts...) // invoking RPC method + if err != nil { + return err + } else { + return nil + } + } + } + // post-processing + return err + })) + grpcConnection, err := grpc.NewClient(grpcServer, grpcOptions...) + + if err != nil { + return nil, err + } + + svc.grpcConnection = grpcConnection + return svc, err +} + +func (s *AuthService) OnAccessTokenRefreshed(accessToken string, accessTokenExpiredAt int64, refreshToken string, refreshTokenExpiredAt int64) { + s.tr.AccessToken = accessToken + s.tr.AccessTokenExpiredAt = accessTokenExpiredAt + s.tr.RefreshToken = refreshToken + s.tr.RefreshTokenExpiredAt = refreshTokenExpiredAt + + if s.dopts.onTokenRefreshed != nil { + s.dopts.onTokenRefreshed(accessToken, accessTokenExpiredAt, refreshToken, refreshTokenExpiredAt) + } + +} + +func (s *AuthService) GetGrpcConnection() *grpc.ClientConn { + return s.grpcConnection +} + +func (s *AuthService) Close() { + s.grpcConnection.Close() +} + +func (s *AuthService) signContext(method string, ctx context.Context) context.Context { + var kvString []string + currentTimeStamp := strconv.FormatInt(time.Now().UnixMilli(), 10) + bufferedString := bytes.NewBufferString(method) + kvString = append(kvString, "timestamp", currentTimeStamp) + bufferedString.WriteString(currentTimeStamp) + kvString = append(kvString, "appid", AppID) + bufferedString.WriteString(AppID) + kvString = append(kvString, "appversion", AppVersion) + bufferedString.WriteString(AppVersion) + if s.tr != nil && len(s.tr.AccessToken) > 0 { + authorization := "Bearer " + s.tr.AccessToken + kvString = append(kvString, "authorization", authorization) + bufferedString.WriteString(authorization) + } + bufferedString.WriteString(AppSecret) + sign := GetMD5Hash(bufferedString.String()) + kvString = append(kvString, "sign", sign) + return metadata.AppendToOutgoingContext(ctx, kvString...) +} + +func (d *HalalCloud) GetCurrentOpDir(dir model.Obj, args []string, index int) string { + currentDir := dir.GetPath() + if len(currentDir) == 0 { + currentDir = "/" + } + opPath := currentDir + "/" + args[index] + if strings.HasPrefix(args[index], "/") { + opPath = args[index] + } + return opPath +} + +func (d *HalalCloud) GetCurrentDir(dir model.Obj) string { + currentDir := dir.GetPath() + if len(currentDir) == 0 { + currentDir = "/" + } + return currentDir +} + +type Common struct { +} + +func tryAndGetRawFiles(addr *pubUserFile.SliceDownloadInfo) ([]byte, error) { + tryTimes := 0 + for { + tryTimes++ + dataBytes, err := getRawFiles(addr) + if err != nil { + if tryTimes > 3 { + return nil, err + } + continue + } + return dataBytes, nil + } +} + +func getRawFiles(addr *pubUserFile.SliceDownloadInfo) ([]byte, error) { + + if addr == nil { + return nil, errors.New("addr is nil") + } + + client := http.Client{ + Timeout: time.Duration(60 * time.Second), // Set timeout to 5 seconds + } + resp, err := client.Get(addr.DownloadAddress) + if err != nil { + + return nil, err + } + defer resp.Body.Close() + body, err := io.ReadAll(resp.Body) + if err != nil { + return nil, err + } + if resp.StatusCode != http.StatusOK { + return nil, fmt.Errorf("bad status: %s, body: %s", resp.Status, body) + } + + if addr.Encrypt > 0 { + cd := uint8(addr.Encrypt) + for idx := 0; idx < len(body); idx++ { + body[idx] = body[idx] ^ cd + } + } + + if addr.StoreType != 10 { + + sourceCid, err := cid.Decode(addr.Identity) + if err != nil { + return nil, err + } + checkCid, err := sourceCid.Prefix().Sum(body) + if err != nil { + return nil, err + } + if !checkCid.Equals(sourceCid) { + return nil, fmt.Errorf("bad cid: %s, body: %s", checkCid.String(), body) + } + } + + return body, nil + +} + +// do others that not defined in Driver interface +// openObject represents a download in progress +type openObject struct { + ctx context.Context + mu sync.Mutex + d []*pubUserFile.SliceDownloadInfo + id int + skip int64 + chunk *[]byte + chunks *[]chunkSize + closed bool + sha string + shaTemp hash.Hash +} + +// get the next chunk +func (oo *openObject) getChunk(ctx context.Context) (err error) { + if oo.id >= len(*oo.chunks) { + return io.EOF + } + var chunk []byte + err = utils.Retry(3, time.Second, func() (err error) { + chunk, err = getRawFiles(oo.d[oo.id]) + return err + }) + if err != nil { + return err + } + oo.id++ + oo.chunk = &chunk + return nil +} + +// Read reads up to len(p) bytes into p. +func (oo *openObject) Read(p []byte) (n int, err error) { + oo.mu.Lock() + defer oo.mu.Unlock() + if oo.closed { + return 0, fmt.Errorf("read on closed file") + } + // Skip data at the start if requested + for oo.skip > 0 { + //size := 1024 * 1024 + _, size, err := oo.ChunkLocation(oo.id) + if err != nil { + return 0, err + } + if oo.skip < int64(size) { + break + } + oo.id++ + oo.skip -= int64(size) + } + if len(*oo.chunk) == 0 { + err = oo.getChunk(oo.ctx) + if err != nil { + return 0, err + } + if oo.skip > 0 { + *oo.chunk = (*oo.chunk)[oo.skip:] + oo.skip = 0 + } + } + n = copy(p, *oo.chunk) + *oo.chunk = (*oo.chunk)[n:] + + oo.shaTemp.Write(*oo.chunk) + + return n, nil +} + +// Close closed the file - MAC errors are reported here +func (oo *openObject) Close() (err error) { + oo.mu.Lock() + defer oo.mu.Unlock() + if oo.closed { + return nil + } + //err = utils.Retry(3, 500*time.Millisecond, func() (err error) { + // return oo.d.Finish() + //}) + // 校验Sha1 + if string(oo.shaTemp.Sum(nil)) != oo.sha { + return fmt.Errorf("failed to finish download: %w", err) + } + + oo.closed = true + return nil +} + +func GetMD5Hash(text string) string { + tHash := md5.Sum([]byte(text)) + return hex.EncodeToString(tHash[:]) +} + +const ( + SmallSliceSize int64 = 1 * utils.MB + MediumSliceSize = 16 * utils.MB + LargeSliceSize = 32 * utils.MB +) + +func (d *HalalCloud) getSliceSize() int64 { + customUploadPartSize, _ := strconv.ParseInt(d.CustomUploadPartSize, 10, 64) + if customUploadPartSize != 0 { + return customUploadPartSize * utils.MB + } + switch d.fileStatus { + case 0: + return SmallSliceSize + case 1: + return MediumSliceSize + case 2: + return LargeSliceSize + default: + return SmallSliceSize + } +} + +func (d *HalalCloud) setFileStatus(fileSize int64) { + if fileSize <= 32*utils.MB { + d.fileStatus = 0 + } else if fileSize <= 512*utils.MB { + d.fileStatus = 1 + } else { + d.fileStatus = 2 + } +} + +// chunkSize describes a size and position of chunk +type chunkSize struct { + position int64 + size int +} + +func getChunkSizes(sliceSize []*pubUserFile.SliceSize) (chunks []chunkSize) { + chunks = make([]chunkSize, 0) + for _, s := range sliceSize { + // 对最后一个做特殊处理 + if s.EndIndex == 0 { + s.EndIndex = s.StartIndex + } + for j := s.StartIndex; j <= s.EndIndex; j++ { + chunks = append(chunks, chunkSize{position: j, size: int(s.Size)}) + } + } + return chunks +} + +func (oo *openObject) ChunkLocation(id int) (position int64, size int, err error) { + if id < 0 || id >= len(*oo.chunks) { + return 0, 0, errors.New("invalid arguments") + } + + return (*oo.chunks)[id].position, (*oo.chunks)[id].size, nil +} diff --git a/go.mod b/go.mod index b18ff9373fb4..a28a424fdc41 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/alist-org/alist/v3 -go 1.21 +go 1.22.4 require ( github.com/SheltonZhu/115driver v1.0.22 @@ -11,11 +11,13 @@ require ( github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible github.com/avast/retry-go v3.0.0+incompatible github.com/aws/aws-sdk-go v1.50.24 + github.com/baidubce/bce-sdk-go v0.9.180 github.com/blevesearch/bleve/v2 v2.3.10 github.com/caarlos0/env/v9 v9.0.0 github.com/charmbracelet/bubbles v0.17.1 github.com/charmbracelet/bubbletea v0.25.0 github.com/charmbracelet/lipgloss v0.9.1 + github.com/city404/v6-public-rpc-proto/go v0.0.0-20240621061101-b074815b04a0 github.com/coreos/go-oidc v2.2.1+incompatible github.com/deckarep/golang-set/v2 v2.6.0 github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8 @@ -31,11 +33,12 @@ require ( github.com/go-resty/resty/v2 v2.11.0 github.com/go-webauthn/webauthn v0.10.0 github.com/golang-jwt/jwt/v4 v4.5.0 - github.com/google/uuid v1.5.0 + github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.5.1 github.com/hirochachacha/go-smb2 v1.1.0 github.com/ipfs/boxo v0.12.0 github.com/ipfs/go-ipfs-api v0.7.0 + github.com/jinzhu/copier v0.4.0 github.com/jlaffaye/ftp v0.2.0 github.com/json-iterator/go v1.1.12 github.com/larksuite/oapi-sdk-go/v3 v3.2.5 @@ -57,11 +60,12 @@ require ( github.com/upyun/go-sdk/v3 v3.0.4 github.com/winfsp/cgofuse v1.5.1-0.20230130140708-f87f5db493b5 github.com/xhofe/tache v0.1.1 - golang.org/x/crypto v0.19.0 + github.com/zzzhr1990/go-common-entity v0.0.0-20221216044934-fd1c571e3a22 + golang.org/x/crypto v0.24.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 golang.org/x/image v0.15.0 - golang.org/x/net v0.21.0 - golang.org/x/oauth2 v0.16.0 + golang.org/x/net v0.26.0 + golang.org/x/oauth2 v0.18.0 golang.org/x/time v0.5.0 google.golang.org/appengine v1.6.8 gopkg.in/ldap.v3 v3.1.0 @@ -71,9 +75,9 @@ require ( gorm.io/gorm v1.25.10 ) +require github.com/BurntSushi/toml v0.3.1 // indirect + require ( - cloud.google.com/go/compute v1.23.0 // indirect - github.com/BurntSushi/toml v0.3.1 // indirect github.com/Max-Sum/base32768 v0.0.0-20230304063302-18e6ce5945fd // indirect github.com/RoaringBitmap/roaring v1.2.3 // indirect github.com/abbot/go-http-auth v0.4.0 // indirect @@ -110,7 +114,7 @@ require ( github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/coreos/go-semver v0.3.1 // indirect github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect github.com/fxamacker/cbor/v2 v2.5.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect @@ -126,14 +130,14 @@ require ( github.com/goccy/go-json v0.10.2 // indirect github.com/golang-jwt/jwt/v5 v5.2.0 // indirect github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 // indirect - github.com/golang/protobuf v1.5.3 // indirect + github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/ipfs/go-cid v0.4.1 // indirect + github.com/ipfs/go-cid v0.4.1 github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/pgx/v5 v5.3.0 // indirect @@ -154,7 +158,7 @@ require ( github.com/lufia/plan9stats v0.0.0-20230326075908-cb1d2100619a // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/mattn/go-sqlite3 v1.14.22 // indirect @@ -180,7 +184,7 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/pelletier/go-toml/v2 v2.1.0 // indirect github.com/pierrec/lz4/v4 v4.1.18 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b // indirect github.com/pquerna/cachecontrol v0.1.0 // indirect github.com/prometheus/client_golang v1.16.0 // indirect @@ -208,15 +212,15 @@ require ( github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/bbolt v1.3.7 // indirect golang.org/x/arch v0.5.0 // indirect - golang.org/x/sync v0.6.0 // indirect - golang.org/x/sys v0.17.0 // indirect - golang.org/x/term v0.17.0 // indirect - golang.org/x/text v0.14.0 // indirect - golang.org/x/tools v0.18.0 // indirect - google.golang.org/api v0.134.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 // indirect - google.golang.org/grpc v1.57.0 // indirect - google.golang.org/protobuf v1.31.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect + google.golang.org/api v0.169.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect + google.golang.org/grpc v1.64.0 + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d // indirect gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect diff --git a/go.sum b/go.sum index de6005d153ef..adfba017a687 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,5 @@ -cloud.google.com/go v0.110.2 h1:sdFPBr6xG9/wkBbfhmUz/JmZC7X6LavQgcrVINrKiVA= -cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= -cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= @@ -40,6 +39,8 @@ github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394 h1:OYA+5W64v3OgClL+I github.com/axgle/mahonia v0.0.0-20180208002826-3358181d7394/go.mod h1:Q8n74mJTIgjX4RBBcHnJ05h//6/k6foqmgE45jTQtxg= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/baidubce/bce-sdk-go v0.9.180 h1:7IRGR/YFTdZiMUs0cGowyGcl5N7exzDofR7vdt+syNE= +github.com/baidubce/bce-sdk-go v0.9.180/go.mod h1:zbYJMQwE4IZuyrJiFO8tO8NbtYiKTFTbwh4eIsqjVdg= github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -106,6 +107,8 @@ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= +github.com/city404/v6-public-rpc-proto/go v0.0.0-20240621061101-b074815b04a0 h1:FJFYghXksa6qVfMR1pcUIShMMhyu0ikoKYVgy70/Ze8= +github.com/city404/v6-public-rpc-proto/go v0.0.0-20240621061101-b074815b04a0/go.mod h1:O1dpz9RYVOC21UgZW4vLkBsUzwyM27mEpyEdd83Ia2o= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/coreos/go-oidc v2.2.1+incompatible h1:mh48q/BqXqgjVHpy2ZY7WnWAbenxRjsz9N1i1YxjHAk= @@ -117,8 +120,9 @@ github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuv github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= @@ -135,6 +139,8 @@ github.com/dlclark/regexp2 v1.10.0 h1:+/GIL799phkJqYW+3YbOd8LCcbHzT0Pbo8zl70MHsq github.com/dlclark/regexp2 v1.10.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564 h1:I6KUy4CI6hHjqnyJLNCEi7YHVMkwwtfSr2k9splgdSM= github.com/dustinxie/ecc v0.0.0-20210511000915-959544187564/go.mod h1:yekO+3ZShy19S+bsmnERmznGy9Rfg6dWWWpiGJjNAz8= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/foxxorcat/mopan-sdk-go v0.1.6 h1:6J37oI4wMZLj8EPgSCcSTTIbnI5D6RCNW/srX8vQd1Y= github.com/foxxorcat/mopan-sdk-go v0.1.6/go.mod h1:UaY6D88yBXWGrcu/PcyLWyL4lzrk5pSxSABPHftOvxs= github.com/foxxorcat/weiyun-sdk-go v0.1.3 h1:I5c5nfGErhq9DBumyjCVCggRA74jhgriMqRRFu5jeeY= @@ -158,6 +164,10 @@ github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SU github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk= github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= @@ -198,26 +208,27 @@ github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4er github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-tpm v0.9.0 h1:sQF6YqWMi+SCXpsmS3fd21oPy/vSddwZry4JnmltHVk= github.com/google/go-tpm v0.9.0/go.mod h1:FkNVkc6C+IsvDI9Jw1OveJmxGZUUaKxtrpOS47QWKfU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc= -github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A= +github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= +github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= -github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM= -github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w= -github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= -github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= +github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= +github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= +github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= @@ -248,6 +259,8 @@ github.com/jackc/pgx/v5 v5.3.0/go.mod h1:t3JDKnCBlYIc0ewLF0Q7B8MXmoIaBOZj/ic7iHo github.com/jackc/puddle/v2 v2.2.0/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jaevor/go-nanoid v1.3.0 h1:nD+iepesZS6pr3uOVf20vR9GdGgJW1HPaR46gtrxzkg= github.com/jaevor/go-nanoid v1.3.0/go.mod h1:SI+jFaPuddYkqkVQoNGHs81navCtH388TcrH0RqFKgY= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= @@ -312,8 +325,8 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= @@ -388,8 +401,9 @@ github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= github.com/pkg/xattr v0.4.9 h1:5883YPCtkSd8LFbs13nXplj9g9tlrwoJRjgpgMu1/fE= github.com/pkg/xattr v0.4.9/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b h1:0LFwY6Q3gMACTjAbMZBjXAqTOzOwFaj2Ld6cjeQ7Rig= github.com/power-devops/perfstat v0.0.0-20221212215047-62379fc7944b/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= @@ -497,10 +511,20 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zzzhr1990/go-common-entity v0.0.0-20221216044934-fd1c571e3a22 h1:X+lHsNTlbatQ1cErXIbtyrh+3MTWxqQFS+sBP/wpFXo= +github.com/zzzhr1990/go-common-entity v0.0.0-20221216044934-fd1c571e3a22/go.mod h1:1zGRDJd8zlG6P8azG96+uywfh6udYWwhOmUivw+xsuM= go.etcd.io/bbolt v1.3.7 h1:j+zJOnnEjF/kyHlDDgGnVL/AIqIJPq8UoB2GSNfkUfQ= go.etcd.io/bbolt v1.3.7/go.mod h1:N9Mkw9X8x5fupy0IKsmuqVtoGDyxsaDlbk4Rd05IAQw= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0 h1:jq9TW8u3so/bN+JPT166wjOI6/vQPF6Xe7nMNIltagk= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.49.0/go.mod h1:p8pYQP+m5XfbZm9fxtSKAbM6oIllS7s2AfxrChvc7iw= +go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo= +go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo= +go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= +go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= +go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= +go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= gocv.io/x/gocv v0.25.0/go.mod h1:Rar2PS6DV+T4FL+PM535EImD/h13hGVaHhnCu1xarBs= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.5.0 h1:jpGode6huXQxcskEIpOCvrU+tzo81b6+oFLUYXWtH/Y= @@ -519,8 +543,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= -golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= -golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= +golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= @@ -544,18 +568,18 @@ golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= -golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/oauth2 v0.16.0 h1:aDkGMBSYxElaoP81NpoUoz2oo2R2wHdZpGToUxfyQrQ= -golang.org/x/oauth2 v0.16.0/go.mod h1:hqZ+0LWXsiVoZpeld6jVt06P3adbS2Uu911W1SsJv2o= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= +golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -583,16 +607,16 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= -golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= -golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= -golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -603,8 +627,8 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -618,25 +642,25 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.134.0 h1:ktL4Goua+UBgoP1eL1/60LwZJqa1sIzkLmvoR3hR6Gw= -google.golang.org/api v0.134.0/go.mod h1:sjRL3UnjTx5UqNQS9EWr9N8p7xbHpy1k0XGRLCf3Spk= +google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= +google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 h1:eSaPbMR4T7WfH9FvABk36NBMacoTUKdWCvV0dx+KfOg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5/go.mod h1:zBEcrKX2ZOcEkHWxBPAIvYUWOKKMIhYcmNiUIu2ji3I= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/pkg/utils/io.go b/pkg/utils/io.go index 7be989c3fd78..e06fb235b8b6 100644 --- a/pkg/utils/io.go +++ b/pkg/utils/io.go @@ -138,7 +138,7 @@ func (mr *MultiReadable) Close() error { func Retry(attempts int, sleep time.Duration, f func() error) (err error) { for i := 0; i < attempts; i++ { - fmt.Println("This is attempt number", i) + //fmt.Println("This is attempt number", i) if i > 0 { log.Println("retrying after error:", err) time.Sleep(sleep)