| @@ -0,0 +1,16 @@ | |||||
| package cmd | |||||
| import "github.com/spf13/cobra" | |||||
| var RootCmd = &cobra.Command{ | |||||
| Use: "agent", | |||||
| } | |||||
| func init() { | |||||
| var configPath string | |||||
| RootCmd.Flags().StringVarP(&configPath, "config", "c", "", "path to config file") | |||||
| RootCmd.Run = func(cmd *cobra.Command, args []string) { | |||||
| serve(configPath) | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,245 @@ | |||||
| package cmd | |||||
| import ( | |||||
| "fmt" | |||||
| "net" | |||||
| "os" | |||||
| "time" | |||||
| "gitlink.org.cn/cloudream/storage/agent/internal/http" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| "gitlink.org.cn/cloudream/storage/agent/internal/config" | |||||
| "gitlink.org.cn/cloudream/storage/agent/internal/task" | |||||
| stgglb "gitlink.org.cn/cloudream/storage/common/globals" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/accessstat" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/connectivity" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/distlock" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/downloader" | |||||
| agtrpc "gitlink.org.cn/cloudream/storage/common/pkgs/grpc/agent" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | |||||
| "google.golang.org/grpc" | |||||
| agtmq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/agent" | |||||
| coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | |||||
| grpcsvc "gitlink.org.cn/cloudream/storage/agent/internal/grpc" | |||||
| cmdsvc "gitlink.org.cn/cloudream/storage/agent/internal/mq" | |||||
| ) | |||||
| func serve(configPath string) { | |||||
| err := config.Init(configPath) | |||||
| if err != nil { | |||||
| fmt.Printf("init config failed, err: %s", err.Error()) | |||||
| os.Exit(1) | |||||
| } | |||||
| err = logger.Init(&config.Cfg().Logger) | |||||
| if err != nil { | |||||
| fmt.Printf("init logger failed, err: %s", err.Error()) | |||||
| os.Exit(1) | |||||
| } | |||||
| stgglb.InitLocal(&config.Cfg().Local) | |||||
| stgglb.InitMQPool(&config.Cfg().RabbitMQ) | |||||
| stgglb.InitAgentRPCPool(&agtrpc.PoolConfig{}) | |||||
| hubCfg := downloadHubConfig() | |||||
| stgMgr := mgr.NewManager() | |||||
| for _, stg := range hubCfg.Storages { | |||||
| err := stgMgr.InitStorage(stg) | |||||
| if err != nil { | |||||
| fmt.Printf("init storage %v: %v", stg, err) | |||||
| os.Exit(1) | |||||
| } | |||||
| } | |||||
| sw := exec.NewWorker() | |||||
| httpSvr, err := http.NewServer(config.Cfg().ListenAddr, http.NewService(&sw)) | |||||
| if err != nil { | |||||
| logger.Fatalf("new http server failed, err: %s", err.Error()) | |||||
| } | |||||
| go serveHTTP(httpSvr) | |||||
| // 启动网络连通性检测,并就地检测一次 | |||||
| conCol := connectivity.NewCollector(&config.Cfg().Connectivity, func(collector *connectivity.Collector) { | |||||
| log := logger.WithField("Connectivity", "") | |||||
| coorCli, err := stgglb.CoordinatorMQPool.Acquire() | |||||
| if err != nil { | |||||
| log.Warnf("acquire coordinator mq failed, err: %s", err.Error()) | |||||
| return | |||||
| } | |||||
| defer stgglb.CoordinatorMQPool.Release(coorCli) | |||||
| cons := collector.GetAll() | |||||
| nodeCons := make([]cdssdk.NodeConnectivity, 0, len(cons)) | |||||
| for _, con := range cons { | |||||
| var delay *float32 | |||||
| if con.Delay != nil { | |||||
| v := float32(con.Delay.Microseconds()) / 1000 | |||||
| delay = &v | |||||
| } | |||||
| nodeCons = append(nodeCons, cdssdk.NodeConnectivity{ | |||||
| FromNodeID: *stgglb.Local.NodeID, | |||||
| ToNodeID: con.ToNodeID, | |||||
| Delay: delay, | |||||
| TestTime: con.TestTime, | |||||
| }) | |||||
| } | |||||
| _, err = coorCli.UpdateNodeConnectivities(coormq.ReqUpdateNodeConnectivities(nodeCons)) | |||||
| if err != nil { | |||||
| log.Warnf("update node connectivities: %v", err) | |||||
| } | |||||
| }) | |||||
| conCol.CollectInPlace() | |||||
| acStat := accessstat.NewAccessStat(accessstat.Config{ | |||||
| // TODO 考虑放到配置里 | |||||
| ReportInterval: time.Second * 10, | |||||
| }) | |||||
| go serveAccessStat(acStat) | |||||
| distlock, err := distlock.NewService(&config.Cfg().DistLock) | |||||
| if err != nil { | |||||
| logger.Fatalf("new ipfs failed, err: %s", err.Error()) | |||||
| } | |||||
| dlder := downloader.NewDownloader(config.Cfg().Downloader, &conCol) | |||||
| taskMgr := task.NewManager(distlock, &conCol, &dlder, acStat, stgMgr) | |||||
| // 启动命令服务器 | |||||
| // TODO 需要设计AgentID持久化机制 | |||||
| agtSvr, err := agtmq.NewServer(cmdsvc.NewService(&taskMgr, stgMgr), config.Cfg().ID, &config.Cfg().RabbitMQ) | |||||
| if err != nil { | |||||
| logger.Fatalf("new agent server failed, err: %s", err.Error()) | |||||
| } | |||||
| agtSvr.OnError(func(err error) { | |||||
| logger.Warnf("agent server err: %s", err.Error()) | |||||
| }) | |||||
| go serveAgentServer(agtSvr) | |||||
| //面向客户端收发数据 | |||||
| listenAddr := config.Cfg().GRPC.MakeListenAddress() | |||||
| lis, err := net.Listen("tcp", listenAddr) | |||||
| if err != nil { | |||||
| logger.Fatalf("listen on %s failed, err: %s", listenAddr, err.Error()) | |||||
| } | |||||
| s := grpc.NewServer() | |||||
| agtrpc.RegisterAgentServer(s, grpcsvc.NewService(&sw)) | |||||
| go serveGRPC(s, lis) | |||||
| go serveDistLock(distlock) | |||||
| foever := make(chan struct{}) | |||||
| <-foever | |||||
| } | |||||
| func downloadHubConfig() coormq.GetHubConfigResp { | |||||
| coorCli, err := stgglb.CoordinatorMQPool.Acquire() | |||||
| if err != nil { | |||||
| logger.Errorf("new coordinator client: %v", err) | |||||
| os.Exit(1) | |||||
| } | |||||
| defer stgglb.CoordinatorMQPool.Release(coorCli) | |||||
| cfgResp, err := coorCli.GetHubConfig(coormq.ReqGetHubConfig(cdssdk.NodeID(config.Cfg().ID))) | |||||
| if err != nil { | |||||
| logger.Errorf("getting hub config: %v", err) | |||||
| os.Exit(1) | |||||
| } | |||||
| return *cfgResp | |||||
| } | |||||
| func serveAgentServer(server *agtmq.Server) { | |||||
| logger.Info("start serving command server") | |||||
| err := server.Start() | |||||
| if err != nil { | |||||
| logger.Errorf("command server stopped with error: %s", err.Error()) | |||||
| } | |||||
| logger.Info("command server stopped") | |||||
| // TODO 仅简单结束了程序 | |||||
| os.Exit(1) | |||||
| } | |||||
| func serveGRPC(s *grpc.Server, lis net.Listener) { | |||||
| logger.Info("start serving grpc") | |||||
| err := s.Serve(lis) | |||||
| if err != nil { | |||||
| logger.Errorf("grpc stopped with error: %s", err.Error()) | |||||
| } | |||||
| logger.Info("grpc stopped") | |||||
| // TODO 仅简单结束了程序 | |||||
| os.Exit(1) | |||||
| } | |||||
| func serveHTTP(server *http.Server) { | |||||
| logger.Info("start serving http") | |||||
| err := server.Serve() | |||||
| if err != nil { | |||||
| logger.Errorf("http stopped with error: %s", err.Error()) | |||||
| } | |||||
| logger.Info("http stopped") | |||||
| // TODO 仅简单结束了程序 | |||||
| os.Exit(1) | |||||
| } | |||||
| func serveDistLock(svc *distlock.Service) { | |||||
| logger.Info("start serving distlock") | |||||
| err := svc.Serve() | |||||
| if err != nil { | |||||
| logger.Errorf("distlock stopped with error: %s", err.Error()) | |||||
| } | |||||
| logger.Info("distlock stopped") | |||||
| // TODO 仅简单结束了程序 | |||||
| os.Exit(1) | |||||
| } | |||||
| func serveAccessStat(svc *accessstat.AccessStat) { | |||||
| logger.Info("start serving access stat") | |||||
| ch := svc.Start() | |||||
| loop: | |||||
| for { | |||||
| val, err := ch.Receive() | |||||
| if err != nil { | |||||
| logger.Errorf("access stat stopped with error: %v", err) | |||||
| break | |||||
| } | |||||
| switch val := val.(type) { | |||||
| case error: | |||||
| logger.Errorf("access stat stopped with error: %v", val) | |||||
| break loop | |||||
| } | |||||
| } | |||||
| logger.Info("access stat stopped") | |||||
| // TODO 仅简单结束了程序 | |||||
| os.Exit(1) | |||||
| } | |||||
| @@ -3,6 +3,7 @@ package config | |||||
| import ( | import ( | ||||
| "gitlink.org.cn/cloudream/common/pkgs/distlock" | "gitlink.org.cn/cloudream/common/pkgs/distlock" | ||||
| log "gitlink.org.cn/cloudream/common/pkgs/logger" | log "gitlink.org.cn/cloudream/common/pkgs/logger" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| c "gitlink.org.cn/cloudream/common/utils/config" | c "gitlink.org.cn/cloudream/common/utils/config" | ||||
| stgmodels "gitlink.org.cn/cloudream/storage/common/models" | stgmodels "gitlink.org.cn/cloudream/storage/common/models" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/connectivity" | "gitlink.org.cn/cloudream/storage/common/pkgs/connectivity" | ||||
| @@ -12,7 +13,7 @@ import ( | |||||
| ) | ) | ||||
| type Config struct { | type Config struct { | ||||
| ID int64 `json:"id"` | |||||
| ID cdssdk.NodeID `json:"id"` | |||||
| ListenAddr string `json:"listenAddr"` | ListenAddr string `json:"listenAddr"` | ||||
| Local stgmodels.LocalMachineInfo `json:"local"` | Local stgmodels.LocalMachineInfo `json:"local"` | ||||
| GRPC *grpc.Config `json:"grpc"` | GRPC *grpc.Config `json:"grpc"` | ||||
| @@ -25,8 +26,12 @@ type Config struct { | |||||
| var cfg Config | var cfg Config | ||||
| func Init() error { | |||||
| return c.DefaultLoad("agent", &cfg) | |||||
| func Init(path string) error { | |||||
| if path == "" { | |||||
| return c.DefaultLoad("agent", &cfg) | |||||
| } | |||||
| return c.Load(path, &cfg) | |||||
| } | } | ||||
| func Cfg() *Config { | func Cfg() *Config { | ||||
| @@ -12,9 +12,9 @@ import ( | |||||
| ) | ) | ||||
| func (svc *Service) CheckCache(msg *agtmq.CheckCache) (*agtmq.CheckCacheResp, *mq.CodeMessage) { | func (svc *Service) CheckCache(msg *agtmq.CheckCache) (*agtmq.CheckCacheResp, *mq.CodeMessage) { | ||||
| store := svc.shardStorePool.Get(msg.StorageID) | |||||
| if store == nil { | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("storage %v has no shard store", msg.StorageID)) | |||||
| store, err := svc.stgMgr.GetShardStore(msg.StorageID) | |||||
| if err != nil { | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("get shard store of storage %v: %v", msg.StorageID, err)) | |||||
| } | } | ||||
| infos, err := store.ListAll() | infos, err := store.ListAll() | ||||
| @@ -31,12 +31,12 @@ func (svc *Service) CheckCache(msg *agtmq.CheckCache) (*agtmq.CheckCacheResp, *m | |||||
| } | } | ||||
| func (svc *Service) CacheGC(msg *agtmq.CacheGC) (*agtmq.CacheGCResp, *mq.CodeMessage) { | func (svc *Service) CacheGC(msg *agtmq.CacheGC) (*agtmq.CacheGCResp, *mq.CodeMessage) { | ||||
| store := svc.shardStorePool.Get(msg.StorageID) | |||||
| if store == nil { | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("storage %v has no shard store", msg.StorageID)) | |||||
| store, err := svc.stgMgr.GetShardStore(msg.StorageID) | |||||
| if err != nil { | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("get shard store of storage %v: %v", msg.StorageID, err)) | |||||
| } | } | ||||
| err := store.Purge(msg.Avaiables) | |||||
| err = store.Purge(msg.Avaiables) | |||||
| if err != nil { | if err != nil { | ||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("purging cache: %v", err)) | return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("purging cache: %v", err)) | ||||
| } | } | ||||
| @@ -2,17 +2,17 @@ package mq | |||||
| import ( | import ( | ||||
| "gitlink.org.cn/cloudream/storage/agent/internal/task" | "gitlink.org.cn/cloudream/storage/agent/internal/task" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/pool" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | |||||
| ) | ) | ||||
| type Service struct { | type Service struct { | ||||
| taskManager *task.Manager | |||||
| shardStorePool *pool.ShardStorePool | |||||
| taskManager *task.Manager | |||||
| stgMgr *mgr.Manager | |||||
| } | } | ||||
| func NewService(taskMgr *task.Manager, shardStorePool *pool.ShardStorePool) *Service { | |||||
| func NewService(taskMgr *task.Manager, stgMgr *mgr.Manager) *Service { | |||||
| return &Service{ | return &Service{ | ||||
| taskManager: taskMgr, | |||||
| shardStorePool: shardStorePool, | |||||
| taskManager: taskMgr, | |||||
| stgMgr: stgMgr, | |||||
| } | } | ||||
| } | } | ||||
| @@ -40,9 +40,9 @@ func (t *CacheMovePackage) do(ctx TaskContext) error { | |||||
| log.Debugf("begin with %v", logger.FormatStruct(t)) | log.Debugf("begin with %v", logger.FormatStruct(t)) | ||||
| defer log.Debugf("end") | defer log.Debugf("end") | ||||
| store := ctx.shardStorePool.Get(t.storageID) | |||||
| if store == nil { | |||||
| return fmt.Errorf("storage has no shard store") | |||||
| store, err := ctx.stgMgr.GetShardStore(t.storageID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("get shard store of storage %v: %w", t.storageID, err) | |||||
| } | } | ||||
| mutex, err := reqbuilder.NewBuilder(). | mutex, err := reqbuilder.NewBuilder(). | ||||
| @@ -22,7 +22,7 @@ import ( | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder" | "gitlink.org.cn/cloudream/storage/common/pkgs/distlock/reqbuilder" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ec" | "gitlink.org.cn/cloudream/storage/common/pkgs/ec" | ||||
| coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/utils" | "gitlink.org.cn/cloudream/storage/common/utils" | ||||
| ) | ) | ||||
| @@ -94,9 +94,9 @@ func (t *StorageLoadPackage) do(task *task.Task[TaskContext], ctx TaskContext) e | |||||
| return fmt.Errorf("getting package object details: %w", err) | return fmt.Errorf("getting package object details: %w", err) | ||||
| } | } | ||||
| shardstore := ctx.shardStorePool.Get(t.storageID) | |||||
| if shardstore == nil { | |||||
| return fmt.Errorf("shard store %v not found on this hub", t.storageID) | |||||
| shardstore, err := ctx.stgMgr.GetShardStore(t.storageID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("get shard store of storage %v: %w", t.storageID, err) | |||||
| } | } | ||||
| mutex, err := reqbuilder.NewBuilder(). | mutex, err := reqbuilder.NewBuilder(). | ||||
| @@ -6,16 +6,16 @@ import ( | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/accessstat" | "gitlink.org.cn/cloudream/storage/common/pkgs/accessstat" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/connectivity" | "gitlink.org.cn/cloudream/storage/common/pkgs/connectivity" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/downloader" | "gitlink.org.cn/cloudream/storage/common/pkgs/downloader" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/pool" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | |||||
| ) | ) | ||||
| // TaskContext 定义了任务执行的上下文环境,包含分布式锁服务、IO开关和网络连接状态收集器 | // TaskContext 定义了任务执行的上下文环境,包含分布式锁服务、IO开关和网络连接状态收集器 | ||||
| type TaskContext struct { | type TaskContext struct { | ||||
| distlock *distlock.Service | |||||
| connectivity *connectivity.Collector | |||||
| downloader *downloader.Downloader | |||||
| accessStat *accessstat.AccessStat | |||||
| shardStorePool *pool.ShardStorePool | |||||
| distlock *distlock.Service | |||||
| connectivity *connectivity.Collector | |||||
| downloader *downloader.Downloader | |||||
| accessStat *accessstat.AccessStat | |||||
| stgMgr *mgr.Manager | |||||
| } | } | ||||
| // CompleteFn 类型定义了任务完成时需要执行的函数,用于设置任务的执行结果 | // CompleteFn 类型定义了任务完成时需要执行的函数,用于设置任务的执行结果 | ||||
| @@ -33,12 +33,12 @@ type Task = task.Task[TaskContext] | |||||
| // CompleteOption 类型定义了任务完成时的选项,可用于定制化任务完成的处理方式 | // CompleteOption 类型定义了任务完成时的选项,可用于定制化任务完成的处理方式 | ||||
| type CompleteOption = task.CompleteOption | type CompleteOption = task.CompleteOption | ||||
| func NewManager(distlock *distlock.Service, connectivity *connectivity.Collector, downloader *downloader.Downloader, accessStat *accessstat.AccessStat, shardStorePool *pool.ShardStorePool) Manager { | |||||
| func NewManager(distlock *distlock.Service, connectivity *connectivity.Collector, downloader *downloader.Downloader, accessStat *accessstat.AccessStat, stgMgr *mgr.Manager) Manager { | |||||
| return task.NewManager(TaskContext{ | return task.NewManager(TaskContext{ | ||||
| distlock: distlock, | |||||
| connectivity: connectivity, | |||||
| downloader: downloader, | |||||
| accessStat: accessStat, | |||||
| shardStorePool: shardStorePool, | |||||
| distlock: distlock, | |||||
| connectivity: connectivity, | |||||
| downloader: downloader, | |||||
| accessStat: accessStat, | |||||
| stgMgr: stgMgr, | |||||
| }) | }) | ||||
| } | } | ||||
| @@ -1,39 +1,9 @@ | |||||
| package main | package main | ||||
| import ( | |||||
| "fmt" | |||||
| "net" | |||||
| "os" | |||||
| "time" | |||||
| "gitlink.org.cn/cloudream/storage/agent/internal/http" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| "gitlink.org.cn/cloudream/storage/agent/internal/config" | |||||
| "gitlink.org.cn/cloudream/storage/agent/internal/task" | |||||
| stgglb "gitlink.org.cn/cloudream/storage/common/globals" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/accessstat" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/connectivity" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/distlock" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/downloader" | |||||
| agtrpc "gitlink.org.cn/cloudream/storage/common/pkgs/grpc/agent" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/pool" | |||||
| "google.golang.org/grpc" | |||||
| agtmq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/agent" | |||||
| coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | |||||
| grpcsvc "gitlink.org.cn/cloudream/storage/agent/internal/grpc" | |||||
| cmdsvc "gitlink.org.cn/cloudream/storage/agent/internal/mq" | |||||
| ) | |||||
| // TODO 此数据是否在运行时会发生变化? | |||||
| var AgentIpList []string | |||||
| import "gitlink.org.cn/cloudream/storage/agent/internal/cmd" | |||||
| func main() { | func main() { | ||||
| <<<<<<< HEAD | |||||
| // TODO 放到配置里读取 | // TODO 放到配置里读取 | ||||
| AgentIpList = []string{"pcm01", "pcm1", "pcm2"} | AgentIpList = []string{"pcm01", "pcm1", "pcm2"} | ||||
| @@ -228,4 +198,7 @@ loop: | |||||
| // TODO 仅简单结束了程序 | // TODO 仅简单结束了程序 | ||||
| os.Exit(1) | os.Exit(1) | ||||
| ======= | |||||
| cmd.RootCmd.Execute() | |||||
| >>>>>>> 3fe245a05a09f784fe0081982bca46f964279b4e | |||||
| } | } | ||||
| @@ -173,7 +173,7 @@ func PackageDeletePackage(ctx CommandContext, packageID cdssdk.PackageID) error | |||||
| // error - 操作过程中发生的任何错误。 | // error - 操作过程中发生的任何错误。 | ||||
| func PackageGetCachedStorages(ctx CommandContext, packageID cdssdk.PackageID) error { | func PackageGetCachedStorages(ctx CommandContext, packageID cdssdk.PackageID) error { | ||||
| userID := cdssdk.UserID(1) | userID := cdssdk.UserID(1) | ||||
| resp, err := ctx.Cmdline.Svc.PackageSvc().GetCachedNodes(userID, packageID) | |||||
| resp, err := ctx.Cmdline.Svc.PackageSvc().GetCachedStorages(userID, packageID) | |||||
| fmt.Printf("resp: %v\n", resp) | fmt.Printf("resp: %v\n", resp) | ||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("get package %d cached nodes failed, err: %w", packageID, err) | return fmt.Errorf("get package %d cached nodes failed, err: %w", packageID, err) | ||||
| @@ -134,14 +134,14 @@ func (s *PackageService) ListBucketPackages(ctx *gin.Context) { | |||||
| func (s *PackageService) GetCachedStorages(ctx *gin.Context) { | func (s *PackageService) GetCachedStorages(ctx *gin.Context) { | ||||
| log := logger.WithField("HTTP", "Package.GetCachedStorages") | log := logger.WithField("HTTP", "Package.GetCachedStorages") | ||||
| var req cdsapi.PackageGetCachedNodesReq | |||||
| var req cdsapi.PackageGetCachedStoragesReq | |||||
| if err := ctx.ShouldBindQuery(&req); err != nil { | if err := ctx.ShouldBindQuery(&req); err != nil { | ||||
| log.Warnf("binding query: %s", err.Error()) | log.Warnf("binding query: %s", err.Error()) | ||||
| ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument")) | ctx.JSON(http.StatusBadRequest, Failed(errorcode.BadArgument, "missing argument or invalid argument")) | ||||
| return | return | ||||
| } | } | ||||
| resp, err := s.svc.PackageSvc().GetCachedNodes(req.UserID, req.PackageID) | |||||
| resp, err := s.svc.PackageSvc().GetCachedStorages(req.UserID, req.PackageID) | |||||
| if err != nil { | if err != nil { | ||||
| log.Warnf("get package cached nodes failed: %s", err.Error()) | log.Warnf("get package cached nodes failed: %s", err.Error()) | ||||
| ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package cached nodes failed")) | ctx.JSON(http.StatusOK, Failed(errorcode.OperationFailed, "get package cached nodes failed")) | ||||
| @@ -106,8 +106,8 @@ func (svc *PackageService) DeletePackage(userID cdssdk.UserID, packageID cdssdk. | |||||
| return nil | return nil | ||||
| } | } | ||||
| // GetCachedNodes 获取指定包的缓存节点信息 | |||||
| func (svc *PackageService) GetCachedNodes(userID cdssdk.UserID, packageID cdssdk.PackageID) (cdssdk.PackageCachingInfo, error) { | |||||
| // GetCachedStorages 获取指定包的缓存节点信息 | |||||
| func (svc *PackageService) GetCachedStorages(userID cdssdk.UserID, packageID cdssdk.PackageID) (cdssdk.PackageCachingInfo, error) { | |||||
| // 从协调器MQ池中获取客户端 | // 从协调器MQ池中获取客户端 | ||||
| coorCli, err := stgglb.CoordinatorMQPool.Acquire() | coorCli, err := stgglb.CoordinatorMQPool.Acquire() | ||||
| if err != nil { | if err != nil { | ||||
| @@ -133,3 +133,18 @@ type StorageDetail struct { | |||||
| Shard *cdssdk.ShardStorage `json:"shard"` | Shard *cdssdk.ShardStorage `json:"shard"` | ||||
| Shared *cdssdk.SharedStorage `json:"shared"` | Shared *cdssdk.SharedStorage `json:"shared"` | ||||
| } | } | ||||
| type ObjectStorage struct { | |||||
| Manufacturer string `json:"manufacturer"` | |||||
| Region string `json:"region"` | |||||
| AK string `json:"access_key_id"` | |||||
| SK string `json:"secret_access_key"` | |||||
| Endpoint string `json:"endpoint"` | |||||
| Bucket string `json:"bucket"` | |||||
| } | |||||
| const ( | |||||
| HuaweiCloud = "HuaweiCloud" | |||||
| AliCloud = "AliCloud" | |||||
| SugonCloud = "SugonCloud" | |||||
| ) | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "time" | "time" | ||||
| @@ -121,3 +122,4 @@ func (*CacheDB) FindCachingFileUserNodes(ctx SQLContext, userID cdssdk.NodeID, f | |||||
| " UserNode.UserID = ? and UserNode.NodeID = Node.NodeID", fileHash, userID) | " UserNode.UserID = ? and UserNode.NodeID = Node.NodeID", fileHash, userID) | ||||
| return x, err | return x, err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "context" | "context" | ||||
| "database/sql" | "database/sql" | ||||
| @@ -64,3 +65,4 @@ func (db *DB) DoTx(isolation sql.IsolationLevel, fn func(tx *sqlx.Tx) error) err | |||||
| func (db *DB) SQLCtx() SQLContext { | func (db *DB) SQLCtx() SQLContext { | ||||
| return db.d | return db.d | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| @@ -35,3 +36,4 @@ func (db *LocationDB) FindLocationByExternalIP(ctx SQLContext, ip string) (model | |||||
| return loc, nil | return loc, nil | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "time" | "time" | ||||
| @@ -39,3 +40,4 @@ func (db *NodeDB) UpdateState(ctx SQLContext, nodeID cdssdk.NodeID, state string | |||||
| _, err := ctx.Exec("update Node set State = ?, LastReportTime = ? where NodeID = ?", state, time.Now(), nodeID) | _, err := ctx.Exec("update Node set State = ?, LastReportTime = ? where NodeID = ?", state, time.Now(), nodeID) | ||||
| return err | return err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "github.com/jmoiron/sqlx" | "github.com/jmoiron/sqlx" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| @@ -38,3 +39,4 @@ func (db *NodeConnectivityDB) BatchUpdateOrCreate(ctx SQLContext, cons []model.N | |||||
| "insert into NodeConnectivity(FromNodeID, ToNodeID, Delay, TestTime) values(:FromNodeID, :ToNodeID, :Delay, :TestTime) as new"+ | "insert into NodeConnectivity(FromNodeID, ToNodeID, Delay, TestTime) values(:FromNodeID, :ToNodeID, :Delay, :TestTime) as new"+ | ||||
| " on duplicate key update Delay = new.Delay, TestTime = new.TestTime", 4, cons, nil) | " on duplicate key update Delay = new.Delay, TestTime = new.TestTime", 4, cons, nil) | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "github.com/jmoiron/sqlx" | "github.com/jmoiron/sqlx" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| @@ -119,3 +120,4 @@ func (*ObjectAccessStatDB) DeleteInPackage(ctx SQLContext, packageID cdssdk.Pack | |||||
| _, err := ctx.Exec("delete ObjectAccessStat from ObjectAccessStat inner join Object on ObjectAccessStat.ObjectID = Object.ObjectID where PackageID = ?", packageID) | _, err := ctx.Exec("delete ObjectAccessStat from ObjectAccessStat inner join Object on ObjectAccessStat.ObjectID = Object.ObjectID where PackageID = ?", packageID) | ||||
| return err | return err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "database/sql" | "database/sql" | ||||
| "strconv" | "strconv" | ||||
| @@ -134,3 +135,4 @@ func splitConcatedFileHash(idStr string) []string { | |||||
| idStrs := strings.Split(idStr, ",") | idStrs := strings.Split(idStr, ",") | ||||
| return idStrs | return idStrs | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "github.com/jmoiron/sqlx" | "github.com/jmoiron/sqlx" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| @@ -82,3 +83,4 @@ func (*PackageAccessStatDB) DeleteByPackageID(ctx SQLContext, pkgID cdssdk.Packa | |||||
| _, err := ctx.Exec("delete from PackageAccessStat where PackageID=?", pkgID) | _, err := ctx.Exec("delete from PackageAccessStat where PackageID=?", pkgID) | ||||
| return err | return err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| @@ -115,3 +116,4 @@ func (*StoragePackageDB) FindPackageStorages(ctx SQLContext, packageID cdssdk.Pa | |||||
| ) | ) | ||||
| return ret, err | return ret, err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "github.com/jmoiron/sqlx" | "github.com/jmoiron/sqlx" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| @@ -19,3 +20,4 @@ func (db *UserDB) GetByID(ctx SQLContext, userID cdssdk.UserID) (model.User, err | |||||
| err := sqlx.Get(ctx, &ret, "select * from User where UserID = ?", userID) | err := sqlx.Get(ctx, &ret, "select * from User where UserID = ?", userID) | ||||
| return ret, err | return ret, err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| type UserBucketDB struct { | type UserBucketDB struct { | ||||
| *DB | *DB | ||||
| } | } | ||||
| @@ -12,3 +13,4 @@ func (*UserBucketDB) Create(ctx SQLContext, userID int64, bucketID int64) error | |||||
| _, err := ctx.Exec("insert into UserBucket(UserID,BucketID) values(?,?)", userID, bucketID) | _, err := ctx.Exec("insert into UserBucket(UserID,BucketID) values(?,?)", userID, bucketID) | ||||
| return err | return err | ||||
| } | } | ||||
| */ | |||||
| @@ -1,5 +1,6 @@ | |||||
| package db | package db | ||||
| /* | |||||
| import ( | import ( | ||||
| "database/sql" | "database/sql" | ||||
| @@ -73,3 +74,4 @@ func BatchNamedQuery[T any](ctx SQLContext, sql string, argCnt int, arr []T, cal | |||||
| } | } | ||||
| return nil | return nil | ||||
| } | } | ||||
| */ | |||||
| @@ -76,3 +76,9 @@ func (db *StorageDB) GetUserStorageByName(ctx SQLContext, userID cdssdk.UserID, | |||||
| return stg, err | return stg, err | ||||
| } | } | ||||
| func (db *StorageDB) GetHubStorages(ctx SQLContext, hubID cdssdk.NodeID) ([]model.Storage, error) { | |||||
| var stgs []model.Storage | |||||
| err := ctx.Table("Storage").Select("Storage.*").Find(&stgs, "NodeID = ?", hubID).Error | |||||
| return stgs, err | |||||
| } | |||||
| @@ -2,10 +2,12 @@ package ops2 | |||||
| import ( | import ( | ||||
| "encoding/json" | "encoding/json" | ||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag" | "gitlink.org.cn/cloudream/common/pkgs/ioswitch/dag" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" | "gitlink.org.cn/cloudream/common/pkgs/ioswitch/exec" | ||||
| "gitlink.org.cn/cloudream/common/sdks/cloudstorage" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| ) | ) | ||||
| @@ -30,9 +32,9 @@ type MultipartManage struct { | |||||
| } | } | ||||
| func (o *MultipartManage) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | func (o *MultipartManage) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | ||||
| manager, err2 := exec.ValueByType[*mgr.Manager](ctx) | |||||
| var oss cloudstorage.ObjectStorage | |||||
| var oss stgmod.ObjectStorage | |||||
| switch addr := o.Address.(type) { | switch addr := o.Address.(type) { | ||||
| case *cdssdk.LocalStorageAddress: | case *cdssdk.LocalStorageAddress: | ||||
| err := json.Unmarshal([]byte(addr.String()), &oss) | err := json.Unmarshal([]byte(addr.String()), &oss) | ||||
| @@ -41,7 +43,7 @@ func (o *MultipartManage) Execute(ctx *exec.ExecContext, e *exec.Executor) error | |||||
| } | } | ||||
| } | } | ||||
| client, err := cloudstorage.NewObjectStorageClient(oss) | |||||
| client, err := types.NewObjectStorageClient(oss) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -96,7 +98,7 @@ type MultipartUpload struct { | |||||
| func (o *MultipartUpload) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | func (o *MultipartUpload) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | ||||
| value, err2 := exec.BindVar[*InitUploadValue](e, ctx.Context, o.UploadArgs) | value, err2 := exec.BindVar[*InitUploadValue](e, ctx.Context, o.UploadArgs) | ||||
| var oss cloudstorage.ObjectStorage | |||||
| var oss stgmod.ObjectStorage | |||||
| switch addr := o.Address.(type) { | switch addr := o.Address.(type) { | ||||
| case *cdssdk.LocalStorageAddress: | case *cdssdk.LocalStorageAddress: | ||||
| err := json.Unmarshal([]byte(addr.String()), &oss) | err := json.Unmarshal([]byte(addr.String()), &oss) | ||||
| @@ -105,7 +107,7 @@ func (o *MultipartUpload) Execute(ctx *exec.ExecContext, e *exec.Executor) error | |||||
| } | } | ||||
| } | } | ||||
| client, err := cloudstorage.NewObjectStorageClient(oss) | |||||
| client, err := types.NewObjectStorageClient(oss) | |||||
| if err != nil { | if err != nil { | ||||
| return err | return err | ||||
| } | } | ||||
| @@ -10,8 +10,8 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | "gitlink.org.cn/cloudream/common/pkgs/logger" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/io2" | "gitlink.org.cn/cloudream/common/utils/io2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/pool" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| func init() { | func init() { | ||||
| @@ -40,14 +40,14 @@ func (o *ShardRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | |||||
| Debugf("reading from shard store") | Debugf("reading from shard store") | ||||
| defer logger.Debugf("reading from shard store finished") | defer logger.Debugf("reading from shard store finished") | ||||
| pool, err := exec.ValueByType[*pool.ShardStorePool](ctx) | |||||
| stgMgr, err := exec.ValueByType[*mgr.Manager](ctx) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("getting shard store pool: %w", err) | |||||
| return fmt.Errorf("getting storage manager: %w", err) | |||||
| } | } | ||||
| store := pool.Get(o.StorageID) | |||||
| if store == nil { | |||||
| return fmt.Errorf("shard store %v not found", o.StorageID) | |||||
| store, err := stgMgr.GetShardStore(o.StorageID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("getting shard store of storage %v: %w", o.StorageID, err) | |||||
| } | } | ||||
| file, err := store.Open(o.Open) | file, err := store.Open(o.Open) | ||||
| @@ -82,14 +82,14 @@ func (o *ShardWrite) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | |||||
| Debugf("writting file to shard store") | Debugf("writting file to shard store") | ||||
| defer logger.Debugf("write to shard store finished") | defer logger.Debugf("write to shard store finished") | ||||
| pool, err := exec.ValueByType[*pool.ShardStorePool](ctx) | |||||
| stgMgr, err := exec.ValueByType[*mgr.Manager](ctx) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("getting shard store pool: %w", err) | |||||
| return fmt.Errorf("getting storage manager: %w", err) | |||||
| } | } | ||||
| store := pool.Get(o.StorageID) | |||||
| if store == nil { | |||||
| return fmt.Errorf("shard store %v not found", o.StorageID) | |||||
| store, err := stgMgr.GetShardStore(o.StorageID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("getting shard store of storage %v: %w", o.StorageID, err) | |||||
| } | } | ||||
| input, err := exec.BindVar[*exec.StreamValue](e, ctx.Context, o.Input) | input, err := exec.BindVar[*exec.StreamValue](e, ctx.Context, o.Input) | ||||
| @@ -12,7 +12,7 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | "gitlink.org.cn/cloudream/common/utils/math2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/ops2" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitch2/ops2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| type DefaultParser struct { | type DefaultParser struct { | ||||
| @@ -10,8 +10,8 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | "gitlink.org.cn/cloudream/common/pkgs/logger" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/io2" | "gitlink.org.cn/cloudream/common/utils/io2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/pool" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/mgr" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| func init() { | func init() { | ||||
| @@ -40,14 +40,14 @@ func (o *ShardRead) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | |||||
| Debugf("reading from shard store") | Debugf("reading from shard store") | ||||
| defer logger.Debugf("reading from shard store finished") | defer logger.Debugf("reading from shard store finished") | ||||
| pool, err := exec.ValueByType[*pool.ShardStorePool](ctx) | |||||
| stgMgr, err := exec.ValueByType[*mgr.Manager](ctx) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("getting shard store pool: %w", err) | |||||
| return fmt.Errorf("getting storage manager: %w", err) | |||||
| } | } | ||||
| store := pool.Get(o.StorageID) | |||||
| if store == nil { | |||||
| return fmt.Errorf("shard store %v not found", o.StorageID) | |||||
| store, err := stgMgr.GetShardStore(o.StorageID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("getting shard store of storage %v: %w", o.StorageID, err) | |||||
| } | } | ||||
| file, err := store.Open(o.Open) | file, err := store.Open(o.Open) | ||||
| @@ -82,14 +82,14 @@ func (o *ShardWrite) Execute(ctx *exec.ExecContext, e *exec.Executor) error { | |||||
| Debugf("writting file to shard store") | Debugf("writting file to shard store") | ||||
| defer logger.Debugf("write to shard store finished") | defer logger.Debugf("write to shard store finished") | ||||
| pool, err := exec.ValueByType[*pool.ShardStorePool](ctx) | |||||
| stgMgr, err := exec.ValueByType[*mgr.Manager](ctx) | |||||
| if err != nil { | if err != nil { | ||||
| return fmt.Errorf("getting shard store pool: %w", err) | |||||
| return fmt.Errorf("getting storage manager: %w", err) | |||||
| } | } | ||||
| store := pool.Get(o.StorageID) | |||||
| if store == nil { | |||||
| return fmt.Errorf("shard store %v not found", o.StorageID) | |||||
| store, err := stgMgr.GetShardStore(o.StorageID) | |||||
| if err != nil { | |||||
| return fmt.Errorf("getting shard store of storage %v: %w", o.StorageID, err) | |||||
| } | } | ||||
| input, err := exec.BindVar[*exec.StreamValue](e, ctx.Context, o.Input) | input, err := exec.BindVar[*exec.StreamValue](e, ctx.Context, o.Input) | ||||
| @@ -10,7 +10,7 @@ import ( | |||||
| "gitlink.org.cn/cloudream/common/utils/math2" | "gitlink.org.cn/cloudream/common/utils/math2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc/ops2" | "gitlink.org.cn/cloudream/storage/common/pkgs/ioswitchlrc/ops2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| // 计算输入流的打开范围。会把流的范围按条带大小取整 | // 计算输入流的打开范围。会把流的范围按条带大小取整 | ||||
| @@ -2,7 +2,7 @@ package agent | |||||
| import ( | import ( | ||||
| "gitlink.org.cn/cloudream/common/pkgs/mq" | "gitlink.org.cn/cloudream/common/pkgs/mq" | ||||
| "gitlink.org.cn/cloudream/common/utils/sync2" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| mymq "gitlink.org.cn/cloudream/storage/common/pkgs/mq" | mymq "gitlink.org.cn/cloudream/storage/common/pkgs/mq" | ||||
| ) | ) | ||||
| @@ -19,14 +19,14 @@ type Server struct { | |||||
| rabbitSvr mq.RabbitMQServer | rabbitSvr mq.RabbitMQServer | ||||
| } | } | ||||
| func NewServer(svc Service, id int64, cfg *mymq.Config) (*Server, error) { | |||||
| func NewServer(svc Service, id cdssdk.NodeID, cfg *mymq.Config) (*Server, error) { | |||||
| srv := &Server{ | srv := &Server{ | ||||
| service: svc, | service: svc, | ||||
| } | } | ||||
| rabbitSvr, err := mq.NewRabbitMQServer( | rabbitSvr, err := mq.NewRabbitMQServer( | ||||
| cfg.MakeConnectingURL(), | cfg.MakeConnectingURL(), | ||||
| mymq.MakeAgentQueueName(id), | |||||
| mymq.MakeAgentQueueName(int64(id)), | |||||
| func(msg *mq.Message) (*mq.Message, error) { | func(msg *mq.Message) (*mq.Message, error) { | ||||
| return msgDispatcher.Handle(srv.service, msg) | return msgDispatcher.Handle(srv.service, msg) | ||||
| }, | }, | ||||
| @@ -3,9 +3,12 @@ package coordinator | |||||
| import ( | import ( | ||||
| "gitlink.org.cn/cloudream/common/pkgs/mq" | "gitlink.org.cn/cloudream/common/pkgs/mq" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| ) | ) | ||||
| type NodeService interface { | type NodeService interface { | ||||
| GetHubConfig(msg *GetHubConfig) (*GetHubConfigResp, *mq.CodeMessage) | |||||
| GetUserNodes(msg *GetUserNodes) (*GetUserNodesResp, *mq.CodeMessage) | GetUserNodes(msg *GetUserNodes) (*GetUserNodesResp, *mq.CodeMessage) | ||||
| GetNodes(msg *GetNodes) (*GetNodesResp, *mq.CodeMessage) | GetNodes(msg *GetNodes) (*GetNodesResp, *mq.CodeMessage) | ||||
| @@ -15,6 +18,33 @@ type NodeService interface { | |||||
| UpdateNodeConnectivities(msg *UpdateNodeConnectivities) (*UpdateNodeConnectivitiesResp, *mq.CodeMessage) | UpdateNodeConnectivities(msg *UpdateNodeConnectivities) (*UpdateNodeConnectivitiesResp, *mq.CodeMessage) | ||||
| } | } | ||||
| var _ = Register(Service.GetHubConfig) | |||||
| type GetHubConfig struct { | |||||
| mq.MessageBodyBase | |||||
| HubID cdssdk.NodeID `json:"hubID"` | |||||
| } | |||||
| type GetHubConfigResp struct { | |||||
| mq.MessageBodyBase | |||||
| Hub cdssdk.Node `json:"hub"` | |||||
| Storages []stgmod.StorageDetail `json:"storages"` | |||||
| } | |||||
| func ReqGetHubConfig(hubID cdssdk.NodeID) *GetHubConfig { | |||||
| return &GetHubConfig{ | |||||
| HubID: hubID, | |||||
| } | |||||
| } | |||||
| func RespGetHubConfig(hub cdssdk.Node, storages []stgmod.StorageDetail) *GetHubConfigResp { | |||||
| return &GetHubConfigResp{ | |||||
| Hub: hub, | |||||
| Storages: storages, | |||||
| } | |||||
| } | |||||
| func (client *Client) GetHubConfig(msg *GetHubConfig) (*GetHubConfigResp, error) { | |||||
| return mq.Request(Service.GetHubConfig, client.rabbitCli, msg) | |||||
| } | |||||
| // 查询用户可用的节点 | // 查询用户可用的节点 | ||||
| var _ = Register(Service.GetUserNodes) | var _ = Register(Service.GetUserNodes) | ||||
| @@ -8,12 +8,11 @@ import ( | |||||
| "os" | "os" | ||||
| "path/filepath" | "path/filepath" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/async" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/logger" | "gitlink.org.cn/cloudream/common/pkgs/logger" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/common/utils/io2" | "gitlink.org.cn/cloudream/common/utils/io2" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/storages/utils" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/utils" | |||||
| ) | ) | ||||
| const ( | const ( | ||||
| @@ -21,33 +20,35 @@ const ( | |||||
| BlocksDir = "blocks" | BlocksDir = "blocks" | ||||
| ) | ) | ||||
| type Local struct { | |||||
| type ShardStore struct { | |||||
| cfg cdssdk.LocalShardStorage | cfg cdssdk.LocalShardStorage | ||||
| } | } | ||||
| func New(stg cdssdk.Storage, cfg cdssdk.LocalShardStorage) (*Local, error) { | |||||
| func NewShardStore(stg cdssdk.Storage, cfg cdssdk.LocalShardStorage) (*ShardStore, error) { | |||||
| _, ok := stg.Address.(*cdssdk.LocalStorageAddress) | _, ok := stg.Address.(*cdssdk.LocalStorageAddress) | ||||
| if !ok { | if !ok { | ||||
| return nil, fmt.Errorf("storage address(%T) is not local", stg) | return nil, fmt.Errorf("storage address(%T) is not local", stg) | ||||
| } | } | ||||
| return &Local{ | |||||
| return &ShardStore{ | |||||
| cfg: cfg, | cfg: cfg, | ||||
| }, nil | }, nil | ||||
| } | } | ||||
| func (s *Local) Start() *async.UnboundChannel[types.StoreEvent] { | |||||
| // TODO 暂时没有需要后台执行的任务 | |||||
| return async.NewUnboundChannel[types.StoreEvent]() | |||||
| func (s *ShardStore) Start(ch *types.StorageEventChan) { | |||||
| } | |||||
| func (s *ShardStore) Stop() { | |||||
| } | } | ||||
| func (s *Local) New() types.Writer { | |||||
| func (s *ShardStore) New() types.ShardWriter { | |||||
| file, err := os.CreateTemp(filepath.Join(s.cfg.Root, "tmp"), "tmp-*") | file, err := os.CreateTemp(filepath.Join(s.cfg.Root, "tmp"), "tmp-*") | ||||
| if err != nil { | if err != nil { | ||||
| return utils.ErrorWriter(err) | |||||
| return utils.ErrorShardWriter(err) | |||||
| } | } | ||||
| return &Writer{ | |||||
| return &ShardWriter{ | |||||
| path: filepath.Join(s.cfg.Root, "tmp", file.Name()), | path: filepath.Join(s.cfg.Root, "tmp", file.Name()), | ||||
| file: file, | file: file, | ||||
| hasher: sha256.New(), | hasher: sha256.New(), | ||||
| @@ -56,7 +57,7 @@ func (s *Local) New() types.Writer { | |||||
| } | } | ||||
| // 使用F函数创建Option对象 | // 使用F函数创建Option对象 | ||||
| func (s *Local) Open(opt types.OpenOption) (io.ReadCloser, error) { | |||||
| func (s *ShardStore) Open(opt types.OpenOption) (io.ReadCloser, error) { | |||||
| fileName := string(opt.FileHash) | fileName := string(opt.FileHash) | ||||
| if len(fileName) < 2 { | if len(fileName) < 2 { | ||||
| return nil, fmt.Errorf("invalid file name") | return nil, fmt.Errorf("invalid file name") | ||||
| @@ -83,7 +84,7 @@ func (s *Local) Open(opt types.OpenOption) (io.ReadCloser, error) { | |||||
| return file, nil | return file, nil | ||||
| } | } | ||||
| func (s *Local) ListAll() ([]types.FileInfo, error) { | |||||
| func (s *ShardStore) ListAll() ([]types.FileInfo, error) { | |||||
| var infos []types.FileInfo | var infos []types.FileInfo | ||||
| blockDir := filepath.Join(s.cfg.Root, BlocksDir) | blockDir := filepath.Join(s.cfg.Root, BlocksDir) | ||||
| @@ -113,7 +114,7 @@ func (s *Local) ListAll() ([]types.FileInfo, error) { | |||||
| return infos, nil | return infos, nil | ||||
| } | } | ||||
| func (s *Local) Purge(removes []cdssdk.FileHash) error { | |||||
| func (s *ShardStore) Purge(removes []cdssdk.FileHash) error { | |||||
| for _, hash := range removes { | for _, hash := range removes { | ||||
| fileName := string(hash) | fileName := string(hash) | ||||
| @@ -128,19 +129,19 @@ func (s *Local) Purge(removes []cdssdk.FileHash) error { | |||||
| return nil | return nil | ||||
| } | } | ||||
| func (s *Local) Stats() types.Stats { | |||||
| func (s *ShardStore) Stats() types.Stats { | |||||
| // TODO 统计本地存储的相关信息 | // TODO 统计本地存储的相关信息 | ||||
| return types.Stats{ | return types.Stats{ | ||||
| Status: types.StatusOK, | Status: types.StatusOK, | ||||
| } | } | ||||
| } | } | ||||
| func (s *Local) onWritterAbort(w *Writer) { | |||||
| func (s *ShardStore) onWritterAbort(w *ShardWriter) { | |||||
| logger.Debugf("writting file %v aborted", w.path) | logger.Debugf("writting file %v aborted", w.path) | ||||
| s.removeTempFile(w.path) | s.removeTempFile(w.path) | ||||
| } | } | ||||
| func (s *Local) onWritterFinish(w *Writer, hash cdssdk.FileHash) (types.FileInfo, error) { | |||||
| func (s *ShardStore) onWritterFinish(w *ShardWriter, hash cdssdk.FileHash) (types.FileInfo, error) { | |||||
| logger.Debugf("write file %v finished, size: %v, hash: %v", w.path, w.size, hash) | logger.Debugf("write file %v finished, size: %v, hash: %v", w.path, w.size, hash) | ||||
| blockDir := filepath.Join(s.cfg.Root, BlocksDir, string(hash)[:2]) | blockDir := filepath.Join(s.cfg.Root, BlocksDir, string(hash)[:2]) | ||||
| @@ -166,7 +167,7 @@ func (s *Local) onWritterFinish(w *Writer, hash cdssdk.FileHash) (types.FileInfo | |||||
| }, nil | }, nil | ||||
| } | } | ||||
| func (s *Local) removeTempFile(path string) { | |||||
| func (s *ShardStore) removeTempFile(path string) { | |||||
| err := os.Remove(path) | err := os.Remove(path) | ||||
| if err != nil { | if err != nil { | ||||
| logger.Warnf("removing temp file %v: %v", path, err) | logger.Warnf("removing temp file %v: %v", path, err) | ||||
| @@ -1,4 +1,4 @@ | |||||
| package tempstore | |||||
| package local | |||||
| import cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | import cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| @@ -8,19 +8,19 @@ import ( | |||||
| "strings" | "strings" | ||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | ) | ||||
| type Writer struct { | |||||
| type ShardWriter struct { | |||||
| path string | path string | ||||
| file *os.File | file *os.File | ||||
| hasher hash.Hash | hasher hash.Hash | ||||
| size int64 | size int64 | ||||
| closed bool | closed bool | ||||
| owner *Local | |||||
| owner *ShardStore | |||||
| } | } | ||||
| func (w *Writer) Write(data []byte) (int, error) { | |||||
| func (w *ShardWriter) Write(data []byte) (int, error) { | |||||
| n, err := w.file.Write(data) | n, err := w.file.Write(data) | ||||
| if err != nil { | if err != nil { | ||||
| return 0, err | return 0, err | ||||
| @@ -32,7 +32,7 @@ func (w *Writer) Write(data []byte) (int, error) { | |||||
| } | } | ||||
| // 取消写入 | // 取消写入 | ||||
| func (w *Writer) Abort() error { | |||||
| func (w *ShardWriter) Abort() error { | |||||
| if w.closed { | if w.closed { | ||||
| return nil | return nil | ||||
| } | } | ||||
| @@ -44,7 +44,7 @@ func (w *Writer) Abort() error { | |||||
| } | } | ||||
| // 结束写入,获得文件哈希值 | // 结束写入,获得文件哈希值 | ||||
| func (w *Writer) Finish() (types.FileInfo, error) { | |||||
| func (w *ShardWriter) Finish() (types.FileInfo, error) { | |||||
| if w.closed { | if w.closed { | ||||
| return types.FileInfo{}, fmt.Errorf("stream closed") | return types.FileInfo{}, fmt.Errorf("stream closed") | ||||
| } | } | ||||
| @@ -0,0 +1,10 @@ | |||||
| package mgr | |||||
| import ( | |||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | |||||
| func createComponents(detail stgmod.StorageDetail, ch *types.StorageEventChan, stg *storage) error { | |||||
| return nil | |||||
| } | |||||
| @@ -0,0 +1,27 @@ | |||||
| package mgr | |||||
| import ( | |||||
| "fmt" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/local" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | |||||
| func createShardStore(detail stgmod.StorageDetail, ch *types.StorageEventChan, stg *storage) error { | |||||
| switch confg := detail.Shard.Config.(type) { | |||||
| case *cdssdk.LocalShardStorage: | |||||
| store, err := local.NewShardStore(detail.Storage, *confg) | |||||
| if err != nil { | |||||
| return fmt.Errorf("new local shard store: %v", err) | |||||
| } | |||||
| store.Start(ch) | |||||
| stg.Shard = store | |||||
| return nil | |||||
| default: | |||||
| return fmt.Errorf("unsupported shard store type: %T", confg) | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,10 @@ | |||||
| package mgr | |||||
| import ( | |||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | |||||
| func createSharedStore(detail stgmod.StorageDetail, ch *types.StorageEventChan, stg *storage) error { | |||||
| return nil | |||||
| } | |||||
| @@ -0,0 +1,167 @@ | |||||
| package mgr | |||||
| import ( | |||||
| "errors" | |||||
| "reflect" | |||||
| "sync" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/async" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| "gitlink.org.cn/cloudream/common/utils/reflect2" | |||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| ) | |||||
| var ErrStorageNotFound = errors.New("storage not found") | |||||
| var ErrComponentNotFound = errors.New("component not found") | |||||
| var ErrStorageExists = errors.New("storage already exists") | |||||
| type storage struct { | |||||
| Shard types.ShardStore | |||||
| Shared types.SharedStore | |||||
| Components []types.StorageComponent | |||||
| } | |||||
| type Manager struct { | |||||
| storages map[cdssdk.StorageID]*storage | |||||
| lock sync.Mutex | |||||
| eventChan *types.StorageEventChan | |||||
| } | |||||
| func NewManager() *Manager { | |||||
| return &Manager{ | |||||
| storages: make(map[cdssdk.StorageID]*storage), | |||||
| eventChan: async.NewUnboundChannel[types.StorageEvent](), | |||||
| } | |||||
| } | |||||
| func (m *Manager) InitStorage(detail stgmod.StorageDetail) error { | |||||
| m.lock.Lock() | |||||
| defer m.lock.Unlock() | |||||
| if _, ok := m.storages[detail.Storage.StorageID]; ok { | |||||
| return ErrStorageExists | |||||
| } | |||||
| stg := &storage{} | |||||
| if detail.Shard != nil { | |||||
| err := createShardStore(detail, m.eventChan, stg) | |||||
| if err != nil { | |||||
| stopStorage(stg) | |||||
| return err | |||||
| } | |||||
| } | |||||
| if detail.Shared != nil { | |||||
| err := createSharedStore(detail, m.eventChan, stg) | |||||
| if err != nil { | |||||
| stopStorage(stg) | |||||
| return err | |||||
| } | |||||
| } | |||||
| // 创建其他组件 | |||||
| err := createComponents(detail, m.eventChan, stg) | |||||
| if err != nil { | |||||
| stopStorage(stg) | |||||
| return err | |||||
| } | |||||
| m.storages[detail.Storage.StorageID] = stg | |||||
| return nil | |||||
| } | |||||
| func stopStorage(stg *storage) { | |||||
| if stg.Shard != nil { | |||||
| stg.Shard.Stop() | |||||
| } | |||||
| if stg.Shared != nil { | |||||
| stg.Shared.Stop() | |||||
| } | |||||
| for _, c := range stg.Components { | |||||
| c.Stop() | |||||
| } | |||||
| } | |||||
| // 查找指定Storage的ShardStore组件 | |||||
| func (m *Manager) GetShardStore(stgID cdssdk.StorageID) (types.ShardStore, error) { | |||||
| m.lock.Lock() | |||||
| defer m.lock.Unlock() | |||||
| stg := m.storages[stgID] | |||||
| if stg == nil { | |||||
| return nil, ErrStorageNotFound | |||||
| } | |||||
| if stg.Shard == nil { | |||||
| return nil, ErrComponentNotFound | |||||
| } | |||||
| return stg.Shard, nil | |||||
| } | |||||
| // 查找指定Storage的SharedStore组件 | |||||
| func (m *Manager) GetSharedStore(stgID cdssdk.StorageID) (types.SharedStore, error) { | |||||
| m.lock.Lock() | |||||
| defer m.lock.Unlock() | |||||
| stg := m.storages[stgID] | |||||
| if stg == nil { | |||||
| return nil, ErrStorageNotFound | |||||
| } | |||||
| if stg.Shared == nil { | |||||
| return nil, ErrComponentNotFound | |||||
| } | |||||
| return stg.Shared, nil | |||||
| } | |||||
| // 查找指定Storage的指定类型的组件,可以是ShardStore、SharedStore、或者其他自定义的组件 | |||||
| func (m *Manager) GetComponent(stgID cdssdk.StorageID, typ reflect.Type) (types.StorageComponent, error) { | |||||
| m.lock.Lock() | |||||
| defer m.lock.Unlock() | |||||
| stg := m.storages[stgID] | |||||
| if stg == nil { | |||||
| return nil, ErrStorageNotFound | |||||
| } | |||||
| switch typ { | |||||
| case reflect2.TypeOf[types.ShardStore](): | |||||
| if stg.Shard == nil { | |||||
| return nil, ErrComponentNotFound | |||||
| } | |||||
| return stg.Shard, nil | |||||
| case reflect2.TypeOf[types.SharedStore](): | |||||
| if stg.Shared == nil { | |||||
| return nil, ErrComponentNotFound | |||||
| } | |||||
| return stg.Shared, nil | |||||
| default: | |||||
| for _, c := range stg.Components { | |||||
| if reflect.TypeOf(c) == typ { | |||||
| return c, nil | |||||
| } | |||||
| } | |||||
| return nil, ErrComponentNotFound | |||||
| } | |||||
| } | |||||
| func GetComponent[T types.StorageComponent](mgr *Manager, stgID cdssdk.StorageID) (T, error) { | |||||
| ret, err := mgr.GetComponent(stgID, reflect2.TypeOf[T]()) | |||||
| if err != nil { | |||||
| var def T | |||||
| return def, err | |||||
| } | |||||
| return ret.(T), nil | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| package obs | |||||
| type OBSClient struct { | |||||
| } | |||||
| func (c *OBSClient) InitiateMultipartUpload(objectName string) (string, error) { | |||||
| return "", nil | |||||
| } | |||||
| func (c *OBSClient) UploadPart() { | |||||
| } | |||||
| func (c *OBSClient) CompleteMultipartUpload() (string, error) { | |||||
| return "", nil | |||||
| } | |||||
| func (c *OBSClient) AbortMultipartUpload() { | |||||
| } | |||||
| func (c *OBSClient) Close() { | |||||
| } | |||||
| @@ -0,0 +1,56 @@ | |||||
| package oss | |||||
| import ( | |||||
| "fmt" | |||||
| "github.com/aliyun/aliyun-oss-go-sdk/oss" | |||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "log" | |||||
| ) | |||||
| type OSSClient struct { | |||||
| client *oss.Client | |||||
| bucket *oss.Bucket | |||||
| } | |||||
| func (c *OSSClient) InitiateMultipartUpload(objectName string) (string, error) { | |||||
| imur, err := c.bucket.InitiateMultipartUpload(objectName) | |||||
| if err != nil { | |||||
| return "", fmt.Errorf("failed to initiate multipart upload: %w", err) | |||||
| } | |||||
| return imur.UploadID, nil | |||||
| } | |||||
| func NewOSSClient(obs stgmod.ObjectStorage) *OSSClient { | |||||
| // 创建OSSClient实例。 | |||||
| client, err := oss.New(obs.Endpoint, obs.AK, obs.SK) | |||||
| if err != nil { | |||||
| log.Fatalf("Error: %v", err) | |||||
| } | |||||
| bucket, err := client.Bucket(obs.Bucket) | |||||
| if err != nil { | |||||
| log.Fatalf("Error: %v", err) | |||||
| } | |||||
| return &OSSClient{ | |||||
| client: client, | |||||
| bucket: bucket, | |||||
| } | |||||
| } | |||||
| func (c *OSSClient) UploadPart() { | |||||
| } | |||||
| func (c *OSSClient) CompleteMultipartUpload() (string, error) { | |||||
| return "", nil | |||||
| } | |||||
| func (c *OSSClient) AbortMultipartUpload() { | |||||
| } | |||||
| func (c *OSSClient) Close() { | |||||
| // 关闭client | |||||
| } | |||||
| @@ -1,68 +0,0 @@ | |||||
| package pool | |||||
| import ( | |||||
| "fmt" | |||||
| "sync" | |||||
| "gitlink.org.cn/cloudream/common/pkgs/async" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/storages/local" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| ) | |||||
| type ShardStorePool struct { | |||||
| stores map[cdssdk.StorageID]*shardStore | |||||
| lock sync.Mutex | |||||
| } | |||||
| func New() *ShardStorePool { | |||||
| return &ShardStorePool{ | |||||
| stores: make(map[cdssdk.StorageID]*shardStore), | |||||
| } | |||||
| } | |||||
| func (p *ShardStorePool) PutNew(stg cdssdk.Storage, config cdssdk.ShardStoreConfig) error { | |||||
| p.lock.Lock() | |||||
| defer p.lock.Unlock() | |||||
| switch confg := config.(type) { | |||||
| case *cdssdk.LocalShardStorage: | |||||
| if _, ok := p.stores[stg.StorageID]; ok { | |||||
| return fmt.Errorf("storage %s already exists", stg.StorageID) | |||||
| } | |||||
| store, err := local.New(stg, *confg) | |||||
| if err != nil { | |||||
| return fmt.Errorf("new local shard store: %v", err) | |||||
| } | |||||
| ch := store.Start() | |||||
| p.stores[stg.StorageID] = &shardStore{ | |||||
| Store: store, | |||||
| EventChan: ch, | |||||
| } | |||||
| return nil | |||||
| default: | |||||
| return fmt.Errorf("unsupported shard store type: %T", confg) | |||||
| } | |||||
| } | |||||
| // 不存在时返回nil | |||||
| func (p *ShardStorePool) Get(stgID cdssdk.StorageID) types.ShardStore { | |||||
| p.lock.Lock() | |||||
| defer p.lock.Unlock() | |||||
| store, ok := p.stores[stgID] | |||||
| if !ok { | |||||
| return nil | |||||
| } | |||||
| return store.Store | |||||
| } | |||||
| type shardStore struct { | |||||
| Store types.ShardStore | |||||
| EventChan *async.UnboundChannel[types.StoreEvent] | |||||
| } | |||||
| @@ -1,26 +0,0 @@ | |||||
| package utils | |||||
| import "gitlink.org.cn/cloudream/storage/common/pkgs/storage/shard/types" | |||||
| type errorWriter struct { | |||||
| err error | |||||
| } | |||||
| func (w *errorWriter) Write(data []byte) (int, error) { | |||||
| return 0, w.err | |||||
| } | |||||
| // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | |||||
| // 方便defer机制 | |||||
| func (w *errorWriter) Abort() error { | |||||
| return w.err | |||||
| } | |||||
| // 结束写入,获得文件哈希值 | |||||
| func (w *errorWriter) Finish() (types.FileInfo, error) { | |||||
| return types.FileInfo{}, w.err | |||||
| } | |||||
| func ErrorWriter(err error) types.Writer { | |||||
| return &errorWriter{err: err} | |||||
| } | |||||
| @@ -1,58 +0,0 @@ | |||||
| package types | |||||
| import ( | |||||
| "fmt" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | |||||
| ) | |||||
| type OpenOption struct { | |||||
| FileHash cdssdk.FileHash | |||||
| Offset int64 | |||||
| Length int64 | |||||
| } | |||||
| func NewOpen(fileHash cdssdk.FileHash) OpenOption { | |||||
| return OpenOption{ | |||||
| FileHash: fileHash, | |||||
| Offset: 0, | |||||
| Length: -1, | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) WithLength(len int64) OpenOption { | |||||
| o.Length = len | |||||
| return *o | |||||
| } | |||||
| // [start, end],即包含end | |||||
| func (o *OpenOption) WithRange(start int64, end int64) OpenOption { | |||||
| o.Offset = start | |||||
| o.Length = end - start + 1 | |||||
| return *o | |||||
| } | |||||
| func (o *OpenOption) WithNullableLength(offset int64, length *int64) { | |||||
| o.Offset = offset | |||||
| if length != nil { | |||||
| o.Length = *length | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) String() string { | |||||
| rangeStart := "" | |||||
| if o.Offset > 0 { | |||||
| rangeStart = fmt.Sprintf("%d", o.Offset) | |||||
| } | |||||
| rangeEnd := "" | |||||
| if o.Length >= 0 { | |||||
| rangeEnd = fmt.Sprintf("%d", o.Offset+o.Length-1) | |||||
| } | |||||
| if rangeStart == "" && rangeEnd == "" { | |||||
| return string(o.FileHash) | |||||
| } | |||||
| return fmt.Sprintf("%s[%s:%s]", string(o.FileHash), rangeStart, rangeEnd) | |||||
| } | |||||
| @@ -0,0 +1,30 @@ | |||||
| package types | |||||
| import ( | |||||
| "fmt" | |||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/obs" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/storage/oss" | |||||
| ) | |||||
| //type ObjectStorageInfo interface { | |||||
| // NewClient() (ObjectStorageClient, error) | |||||
| //} | |||||
| type ObjectStorageClient interface { | |||||
| InitiateMultipartUpload(objectName string) (string, error) | |||||
| UploadPart() | |||||
| CompleteMultipartUpload() (string, error) | |||||
| AbortMultipartUpload() | |||||
| Close() | |||||
| } | |||||
| func NewObjectStorageClient(info stgmod.ObjectStorage) (ObjectStorageClient, error) { | |||||
| switch info.Manufacturer { | |||||
| case stgmod.AliCloud: | |||||
| return oss.NewOSSClient(info), nil | |||||
| case stgmod.HuaweiCloud: | |||||
| return &obs.OBSClient{}, nil | |||||
| } | |||||
| return nil, fmt.Errorf("unknown cloud storage manufacturer %s", info.Manufacturer) | |||||
| } | |||||
| @@ -1,9 +1,9 @@ | |||||
| package types | package types | ||||
| import ( | import ( | ||||
| "fmt" | |||||
| "io" | "io" | ||||
| "gitlink.org.cn/cloudream/common/pkgs/async" | |||||
| cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | cdssdk "gitlink.org.cn/cloudream/common/sdks/storage" | ||||
| ) | ) | ||||
| @@ -23,10 +23,9 @@ type StoreEvent interface { | |||||
| } | } | ||||
| type ShardStore interface { | type ShardStore interface { | ||||
| // 启动服务 | |||||
| Start() *async.UnboundChannel[StoreEvent] | |||||
| StorageComponent | |||||
| // 准备写入一个新文件,写入后获得FileHash | // 准备写入一个新文件,写入后获得FileHash | ||||
| New() Writer | |||||
| New() ShardWriter | |||||
| // 使用F函数创建Option对象 | // 使用F函数创建Option对象 | ||||
| Open(opt OpenOption) (io.ReadCloser, error) | Open(opt OpenOption) (io.ReadCloser, error) | ||||
| // 获取所有文件信息,尽量保证操作是原子的 | // 获取所有文件信息,尽量保证操作是原子的 | ||||
| @@ -62,7 +61,7 @@ type Stats struct { | |||||
| Description string | Description string | ||||
| } | } | ||||
| type Writer interface { | |||||
| type ShardWriter interface { | |||||
| io.Writer | io.Writer | ||||
| // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | ||||
| // 方便defer机制 | // 方便defer机制 | ||||
| @@ -70,3 +69,54 @@ type Writer interface { | |||||
| // 结束写入,获得文件哈希值 | // 结束写入,获得文件哈希值 | ||||
| Finish() (FileInfo, error) | Finish() (FileInfo, error) | ||||
| } | } | ||||
| type OpenOption struct { | |||||
| FileHash cdssdk.FileHash | |||||
| Offset int64 | |||||
| Length int64 | |||||
| } | |||||
| func NewOpen(fileHash cdssdk.FileHash) OpenOption { | |||||
| return OpenOption{ | |||||
| FileHash: fileHash, | |||||
| Offset: 0, | |||||
| Length: -1, | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) WithLength(len int64) OpenOption { | |||||
| o.Length = len | |||||
| return *o | |||||
| } | |||||
| // [start, end],即包含end | |||||
| func (o *OpenOption) WithRange(start int64, end int64) OpenOption { | |||||
| o.Offset = start | |||||
| o.Length = end - start + 1 | |||||
| return *o | |||||
| } | |||||
| func (o *OpenOption) WithNullableLength(offset int64, length *int64) { | |||||
| o.Offset = offset | |||||
| if length != nil { | |||||
| o.Length = *length | |||||
| } | |||||
| } | |||||
| func (o *OpenOption) String() string { | |||||
| rangeStart := "" | |||||
| if o.Offset > 0 { | |||||
| rangeStart = fmt.Sprintf("%d", o.Offset) | |||||
| } | |||||
| rangeEnd := "" | |||||
| if o.Length >= 0 { | |||||
| rangeEnd = fmt.Sprintf("%d", o.Offset+o.Length-1) | |||||
| } | |||||
| if rangeStart == "" && rangeEnd == "" { | |||||
| return string(o.FileHash) | |||||
| } | |||||
| return fmt.Sprintf("%s[%s:%s]", string(o.FileHash), rangeStart, rangeEnd) | |||||
| } | |||||
| @@ -0,0 +1,5 @@ | |||||
| package types | |||||
| type SharedStore interface { | |||||
| StorageComponent | |||||
| } | |||||
| @@ -0,0 +1,5 @@ | |||||
| package types | |||||
| type TempStore interface { | |||||
| StorageComponent | |||||
| } | |||||
| @@ -0,0 +1,12 @@ | |||||
| package types | |||||
| import "gitlink.org.cn/cloudream/common/pkgs/async" | |||||
| type StorageEvent interface{} | |||||
| type StorageEventChan = async.UnboundChannel[StorageEvent] | |||||
| type StorageComponent interface { | |||||
| Start(ch *StorageEventChan) | |||||
| Stop() | |||||
| } | |||||
| @@ -0,0 +1,26 @@ | |||||
| package utils | |||||
| import "gitlink.org.cn/cloudream/storage/common/pkgs/storage/types" | |||||
| type errorShardWriter struct { | |||||
| err error | |||||
| } | |||||
| func (w *errorShardWriter) Write(data []byte) (int, error) { | |||||
| return 0, w.err | |||||
| } | |||||
| // 取消写入。要求允许在调用了Finish之后再调用此函数,且此时不应该有任何影响。 | |||||
| // 方便defer机制 | |||||
| func (w *errorShardWriter) Abort() error { | |||||
| return w.err | |||||
| } | |||||
| // 结束写入,获得文件哈希值 | |||||
| func (w *errorShardWriter) Finish() (types.FileInfo, error) { | |||||
| return types.FileInfo{}, w.err | |||||
| } | |||||
| func ErrorShardWriter(err error) types.ShardWriter { | |||||
| return &errorShardWriter{err: err} | |||||
| } | |||||
| @@ -2,6 +2,8 @@ package mq | |||||
| import ( | import ( | ||||
| "fmt" | "fmt" | ||||
| stgmod "gitlink.org.cn/cloudream/storage/common/models" | |||||
| "gitlink.org.cn/cloudream/storage/common/pkgs/db2" | "gitlink.org.cn/cloudream/storage/common/pkgs/db2" | ||||
| "gitlink.org.cn/cloudream/common/consts/errorcode" | "gitlink.org.cn/cloudream/common/consts/errorcode" | ||||
| @@ -11,6 +13,60 @@ import ( | |||||
| coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | coormq "gitlink.org.cn/cloudream/storage/common/pkgs/mq/coordinator" | ||||
| ) | ) | ||||
| func (svc *Service) GetHubConfig(msg *coormq.GetHubConfig) (*coormq.GetHubConfigResp, *mq.CodeMessage) { | |||||
| log := logger.WithField("HubID", msg.HubID) | |||||
| hub, err := svc.db2.Node().GetByID(svc.db2.DefCtx(), msg.HubID) | |||||
| if err != nil { | |||||
| log.Warnf("getting hub: %v", err) | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("getting hub: %v", err)) | |||||
| } | |||||
| detailsMap := make(map[cdssdk.StorageID]*stgmod.StorageDetail) | |||||
| stgs, err := svc.db2.Storage().GetHubStorages(svc.db2.DefCtx(), msg.HubID) | |||||
| if err != nil { | |||||
| log.Warnf("getting hub storages: %v", err) | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("getting hub storages: %v", err)) | |||||
| } | |||||
| var stgIDs []cdssdk.StorageID | |||||
| for _, stg := range stgs { | |||||
| detailsMap[stg.StorageID] = &stgmod.StorageDetail{ | |||||
| Storage: stg, | |||||
| MasterHub: &hub, | |||||
| } | |||||
| stgIDs = append(stgIDs, stg.StorageID) | |||||
| } | |||||
| shards, err := svc.db2.ShardStorage().BatchGetByStorageIDs(svc.db2.DefCtx(), stgIDs) | |||||
| if err != nil { | |||||
| log.Warnf("getting shard storages: %v", err) | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("getting shard storages: %v", err)) | |||||
| } | |||||
| for _, shard := range shards { | |||||
| sh := shard | |||||
| detailsMap[shard.StorageID].Shard = &sh | |||||
| } | |||||
| shareds, err := svc.db2.SharedStorage().BatchGetByStorageIDs(svc.db2.DefCtx(), stgIDs) | |||||
| if err != nil { | |||||
| log.Warnf("getting shared storages: %v", err) | |||||
| return nil, mq.Failed(errorcode.OperationFailed, fmt.Sprintf("getting shared storages: %v", err)) | |||||
| } | |||||
| for _, shared := range shareds { | |||||
| sh := shared | |||||
| detailsMap[shared.StorageID].Shared = &sh | |||||
| } | |||||
| var details []stgmod.StorageDetail | |||||
| for _, detail := range detailsMap { | |||||
| details = append(details, *detail) | |||||
| } | |||||
| return mq.ReplyOK(coormq.RespGetHubConfig(hub, details)) | |||||
| } | |||||
| func (svc *Service) GetUserNodes(msg *coormq.GetUserNodes) (*coormq.GetUserNodesResp, *mq.CodeMessage) { | func (svc *Service) GetUserNodes(msg *coormq.GetUserNodes) (*coormq.GetUserNodesResp, *mq.CodeMessage) { | ||||
| nodes, err := svc.db2.Node().GetUserNodes(svc.db2.DefCtx(), msg.UserID) | nodes, err := svc.db2.Node().GetUserNodes(svc.db2.DefCtx(), msg.UserID) | ||||
| if err != nil { | if err != nil { | ||||
| @@ -10,7 +10,6 @@ require ( | |||||
| github.com/hashicorp/golang-lru/v2 v2.0.5 | github.com/hashicorp/golang-lru/v2 v2.0.5 | ||||
| github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf | github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf | ||||
| github.com/jedib0t/go-pretty/v6 v6.4.7 | github.com/jedib0t/go-pretty/v6 v6.4.7 | ||||
| github.com/jmoiron/sqlx v1.3.5 | |||||
| github.com/klauspost/reedsolomon v1.11.8 | github.com/klauspost/reedsolomon v1.11.8 | ||||
| github.com/magefile/mage v1.15.0 | github.com/magefile/mage v1.15.0 | ||||
| github.com/samber/lo v1.38.1 | github.com/samber/lo v1.38.1 | ||||
| @@ -19,21 +18,21 @@ require ( | |||||
| gitlink.org.cn/cloudream/common v0.0.0 | gitlink.org.cn/cloudream/common v0.0.0 | ||||
| google.golang.org/grpc v1.57.0 | google.golang.org/grpc v1.57.0 | ||||
| google.golang.org/protobuf v1.31.0 | google.golang.org/protobuf v1.31.0 | ||||
| gorm.io/gorm v1.25.7 | |||||
| ) | ) | ||||
| require ( | require ( | ||||
| github.com/google/uuid v1.3.1 // indirect | github.com/google/uuid v1.3.1 // indirect | ||||
| github.com/jinzhu/inflection v1.0.0 // indirect | |||||
| github.com/jinzhu/now v1.1.5 // indirect | |||||
| github.com/stretchr/testify v1.8.4 // indirect | |||||
| gopkg.in/yaml.v2 v2.4.0 // indirect | gopkg.in/yaml.v2 v2.4.0 // indirect | ||||
| ) | ) | ||||
| require ( | require ( | ||||
| github.com/antonfisher/nested-logrus-formatter v1.3.1 // indirect | github.com/antonfisher/nested-logrus-formatter v1.3.1 // indirect | ||||
| github.com/benbjohnson/clock v1.3.0 // indirect | |||||
| github.com/blang/semver/v4 v4.0.0 // indirect | |||||
| github.com/coreos/go-semver v0.3.0 // indirect | github.com/coreos/go-semver v0.3.0 // indirect | ||||
| github.com/coreos/go-systemd/v22 v22.5.0 // indirect | github.com/coreos/go-systemd/v22 v22.5.0 // indirect | ||||
| github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 // indirect | |||||
| github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect | |||||
| github.com/gin-contrib/sse v0.1.0 // indirect | github.com/gin-contrib/sse v0.1.0 // indirect | ||||
| github.com/go-playground/locales v0.13.0 // indirect | github.com/go-playground/locales v0.13.0 // indirect | ||||
| github.com/go-playground/universal-translator v0.17.0 // indirect | github.com/go-playground/universal-translator v0.17.0 // indirect | ||||
| @@ -46,36 +45,18 @@ require ( | |||||
| github.com/hashicorp/go-multierror v1.1.1 // indirect | github.com/hashicorp/go-multierror v1.1.1 // indirect | ||||
| github.com/imdario/mergo v0.3.15 // indirect | github.com/imdario/mergo v0.3.15 // indirect | ||||
| github.com/inconshreveable/mousetrap v1.1.0 // indirect | github.com/inconshreveable/mousetrap v1.1.0 // indirect | ||||
| github.com/ipfs/boxo v0.12.0 // indirect | |||||
| github.com/ipfs/go-cid v0.4.1 // indirect | |||||
| github.com/ipfs/go-ipfs-api v0.7.0 // indirect | |||||
| github.com/json-iterator/go v1.1.12 // indirect | github.com/json-iterator/go v1.1.12 // indirect | ||||
| github.com/jtolds/gls v4.20.0+incompatible // indirect | github.com/jtolds/gls v4.20.0+incompatible // indirect | ||||
| github.com/klauspost/cpuid/v2 v2.2.4 // indirect | github.com/klauspost/cpuid/v2 v2.2.4 // indirect | ||||
| github.com/leodido/go-urn v1.2.4 // indirect | github.com/leodido/go-urn v1.2.4 // indirect | ||||
| github.com/libp2p/go-buffer-pool v0.1.0 // indirect | |||||
| github.com/libp2p/go-flow-metrics v0.1.0 // indirect | |||||
| github.com/libp2p/go-libp2p v0.26.3 // indirect | |||||
| github.com/mattn/go-isatty v0.0.19 // indirect | github.com/mattn/go-isatty v0.0.19 // indirect | ||||
| github.com/mattn/go-runewidth v0.0.13 // indirect | github.com/mattn/go-runewidth v0.0.13 // indirect | ||||
| github.com/minio/sha256-simd v1.0.0 // indirect | |||||
| github.com/mitchellh/go-homedir v1.1.0 // indirect | |||||
| github.com/mitchellh/mapstructure v1.5.0 // indirect | github.com/mitchellh/mapstructure v1.5.0 // indirect | ||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect | ||||
| github.com/modern-go/reflect2 v1.0.2 // indirect | github.com/modern-go/reflect2 v1.0.2 // indirect | ||||
| github.com/mr-tron/base58 v1.2.0 // indirect | |||||
| github.com/multiformats/go-base32 v0.1.0 // indirect | |||||
| github.com/multiformats/go-base36 v0.2.0 // indirect | |||||
| github.com/multiformats/go-multiaddr v0.8.0 // indirect | |||||
| github.com/multiformats/go-multibase v0.2.0 // indirect | |||||
| github.com/multiformats/go-multicodec v0.9.0 // indirect | |||||
| github.com/multiformats/go-multihash v0.2.3 // indirect | |||||
| github.com/multiformats/go-multistream v0.4.1 // indirect | |||||
| github.com/multiformats/go-varint v0.0.7 // indirect | |||||
| github.com/rivo/uniseg v0.2.0 // indirect | github.com/rivo/uniseg v0.2.0 // indirect | ||||
| github.com/sirupsen/logrus v1.9.2 // indirect | |||||
| github.com/sirupsen/logrus v1.9.2 | |||||
| github.com/smarty/assertions v1.15.0 // indirect | github.com/smarty/assertions v1.15.0 // indirect | ||||
| github.com/spaolacci/murmur3 v1.1.0 // indirect | |||||
| github.com/spf13/pflag v1.0.5 // indirect | github.com/spf13/pflag v1.0.5 // indirect | ||||
| github.com/streadway/amqp v1.1.0 // indirect | github.com/streadway/amqp v1.1.0 // indirect | ||||
| github.com/ugorji/go/codec v1.2.11 // indirect | github.com/ugorji/go/codec v1.2.11 // indirect | ||||
| @@ -95,7 +76,5 @@ require ( | |||||
| google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect | google.golang.org/genproto v0.0.0-20230526161137-0005af68ea54 // indirect | ||||
| google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect | google.golang.org/genproto/googleapis/api v0.0.0-20230525234035-dd9d682886f9 // indirect | ||||
| google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect | google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect | ||||
| gopkg.in/yaml.v3 v3.0.1 // indirect | |||||
| gorm.io/driver/mysql v1.5.7 | gorm.io/driver/mysql v1.5.7 | ||||
| lukechampine.com/blake3 v1.1.7 // indirect | |||||
| ) | ) | ||||
| @@ -1,23 +1,14 @@ | |||||
| github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= | github.com/antonfisher/nested-logrus-formatter v1.3.1 h1:NFJIr+pzwv5QLHTPyKz9UMEoHck02Q9L0FP13b/xSbQ= | ||||
| github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= | github.com/antonfisher/nested-logrus-formatter v1.3.1/go.mod h1:6WTfyWFkBc9+zyBaKIqRrg/KwMqBbodBjgbHjDz7zjA= | ||||
| github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= | 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/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= | |||||
| github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= | |||||
| github.com/cheekybits/is v0.0.0-20150225183255-68e9c0620927 h1:SKI1/fuSdodxmNNyVBR8d7X/HuLnRpvvFO0AgyQk764= | |||||
| github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= | github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= | ||||
| github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= | ||||
| github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= | github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= | ||||
| github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= | github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= | ||||
| github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= | ||||
| github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3 h1:HVTnpeuvF6Owjd5mniCL8DEXo7uYXdQEmOP4FJbV5tg= | |||||
| github.com/crackcomm/go-gitignore v0.0.0-20170627025303-887ab5e44cc3/go.mod h1:p1d6YEZWvFzEh4KLyvBcVSnrfNDDvK2zfK/4x2v/4pE= | |||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | 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 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.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= | |||||
| github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 h1:HbphB4TFFXpv7MNrT52FGrrgVXF1owhMVTHFZIlnvd4= | |||||
| github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0/go.mod h1:DZGJHZMqrU4JJqFAWUS2UO1+lbSKsdiOoYi9Zzey7Fc= | |||||
| github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= | ||||
| github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= | ||||
| github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= | github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs= | ||||
| @@ -31,7 +22,6 @@ github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+ | |||||
| github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= | github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= | ||||
| github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k= | github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k= | ||||
| github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk= | github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk= | ||||
| github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= | |||||
| github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= | github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= | ||||
| github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= | github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI= | ||||
| github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= | github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= | ||||
| @@ -63,20 +53,12 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 | |||||
| github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= | ||||
| github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s= | github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf h1:FtEj8sfIcaaBfAKrE1Cwb61YDtYq9JxChK1c7AKce7s= | ||||
| github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4= | github.com/inhies/go-bytesize v0.0.0-20220417184213-4913239db9cf/go.mod h1:yrqSXGoD/4EKfF26AOGzscPOgTTJcyAwM2rpixWT+t4= | ||||
| github.com/ipfs/boxo v0.12.0 h1:AXHg/1ONZdRQHQLgG5JHsSC3XoE4DjCAMgK+asZvUcQ= | |||||
| github.com/ipfs/boxo v0.12.0/go.mod h1:xAnfiU6PtxWCnRqu7dcXQ10bB5/kvI1kXRotuGqGBhg= | |||||
| github.com/ipfs/go-cid v0.4.1 h1:A/T3qGvxi4kpKWWcPC/PgbvDA2bjVLO7n4UeVwnbs/s= | |||||
| github.com/ipfs/go-cid v0.4.1/go.mod h1:uQHwDeX4c6CtyrFwdqyhpNcxVewur1M7l7fNU7LKwZk= | |||||
| github.com/ipfs/go-ipfs-api v0.7.0 h1:CMBNCUl0b45coC+lQCXEVpMhwoqjiaCwUIrM+coYW2Q= | |||||
| github.com/ipfs/go-ipfs-api v0.7.0/go.mod h1:AIxsTNB0+ZhkqIfTZpdZ0VR/cpX5zrXjATa3prSay3g= | |||||
| github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= | github.com/jedib0t/go-pretty/v6 v6.4.7 h1:lwiTJr1DEkAgzljsUsORmWsVn5MQjt1BPJdPCtJ6KXE= | ||||
| github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= | github.com/jedib0t/go-pretty/v6 v6.4.7/go.mod h1:Ndk3ase2CkQbXLLNf5QDHoYb6J9WtVfmHZu9n8rk2xs= | ||||
| github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= | 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/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= | ||||
| github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= | github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= | ||||
| github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= | github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= | ||||
| github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= | |||||
| github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= | |||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= | ||||
| github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= | ||||
| @@ -84,8 +66,6 @@ github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7 | |||||
| github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | ||||
| github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= | github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | |||||
| github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= | |||||
| github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= | github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= | ||||
| github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= | github.com/klauspost/cpuid/v2 v2.2.4/go.mod h1:RVVoqg1df56z8g3pUjL/3lE5UfnlrJX8tyFgg4nqhuY= | ||||
| github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY= | github.com/klauspost/reedsolomon v1.11.8 h1:s8RpUW5TK4hjr+djiOpbZJB4ksx+TdYbRH7vHQpwPOY= | ||||
| @@ -94,14 +74,6 @@ github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgx | |||||
| github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= | github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= | ||||
| github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= | github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= | ||||
| github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= | github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= | ||||
| github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0= | |||||
| github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= | |||||
| github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= | |||||
| github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= | |||||
| github.com/libp2p/go-flow-metrics v0.1.0 h1:0iPhMI8PskQwzh57jB9WxIuIOQ0r+15PChFGkx3Q3WM= | |||||
| github.com/libp2p/go-flow-metrics v0.1.0/go.mod h1:4Xi8MX8wj5aWNDAZttg6UPmc0ZrnFNsMtpsYUClFtro= | |||||
| github.com/libp2p/go-libp2p v0.26.3 h1:6g/psubqwdaBqNNoidbRKSTBEYgaOuKBhHl8Q5tO+PM= | |||||
| github.com/libp2p/go-libp2p v0.26.3/go.mod h1:x75BN32YbwuY0Awm2Uix4d4KOz+/4piInkp4Wr3yOo8= | |||||
| github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= | github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= | ||||
| github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= | github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= | ||||
| github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= | ||||
| @@ -109,12 +81,6 @@ github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APP | |||||
| github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= | ||||
| github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= | ||||
| github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= | ||||
| github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg= | |||||
| github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= | |||||
| github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= | |||||
| github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= | |||||
| github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= | |||||
| github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= | |||||
| github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= | ||||
| github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= | ||||
| github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||
| @@ -123,24 +89,6 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJ | |||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||
| github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= | ||||
| github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= | ||||
| github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= | |||||
| github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= | |||||
| github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= | |||||
| github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= | |||||
| github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= | |||||
| github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= | |||||
| github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= | |||||
| github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= | |||||
| github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= | |||||
| github.com/multiformats/go-multibase v0.2.0/go.mod h1:bFBZX4lKCA/2lyOFSAoKH5SS6oPyjtnzK/XTFDPkNuk= | |||||
| github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3IbPKOXWJkmg= | |||||
| github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= | |||||
| github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= | |||||
| github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= | |||||
| github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= | |||||
| github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= | |||||
| github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= | |||||
| github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= | |||||
| github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= | ||||
| github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= | github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| @@ -156,8 +104,6 @@ github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGB | |||||
| github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= | github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= | ||||
| github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= | github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= | ||||
| github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= | github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= | ||||
| github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= | |||||
| github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= | |||||
| github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= | github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= | ||||
| github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= | github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= | ||||
| github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||||
| @@ -176,6 +122,7 @@ github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO | |||||
| github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= | ||||
| github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= | ||||
| github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= | ||||
| github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= | |||||
| github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= | github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= | ||||
| github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= | ||||
| github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= | github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= | ||||
| @@ -219,8 +166,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ | |||||
| golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/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.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= | ||||
| golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= | |||||
| golang.org/x/sync v0.8.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-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-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| @@ -241,8 +186,6 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | |||||
| golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= | golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= | ||||
| golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= | ||||
| golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= | |||||
| golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= | |||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||||
| @@ -274,8 +217,5 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= | |||||
| gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= | ||||
| gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= | gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo= | ||||
| gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= | gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM= | ||||
| gorm.io/gorm v1.25.7 h1:VsD6acwRjz2zFxGO50gPO6AkNs7KKnvfzUjHQhZDz/A= | |||||
| gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= | gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8= | ||||
| gorm.io/gorm v1.25.12 h1:I0u8i2hWQItBq1WfE0o2+WuL9+8L21K9e2HHSTE/0f8= | |||||
| gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= | |||||
| lukechampine.com/blake3 v1.1.7 h1:GgRMhmdsuK8+ii6UZFDL8Nb+VyMwadAgcJyfYHxG6n0= | |||||
| lukechampine.com/blake3 v1.1.7/go.mod h1:tkKEOtDkNtklkXtLNEOGNq5tcV90tJiA1vAA12R78LA= | |||||