From 7df43ad9b5d08de30d41a169cddef21915da58e2 Mon Sep 17 00:00:00 2001 From: Chris Lu Date: Sun, 14 Jun 2026 21:44:10 -0700 Subject: [PATCH] admin: add connected Mount Clients page and dashboard section (#9968) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * admin: add connected mount clients page and dashboard section The filer is the authority on who is subscribed to its metadata stream (FUSE/VFS mounts, S3, peer filers, ...), but its in-memory listener registry only tracked clientId->epoch and was not exposed. - Enrich the filer subscriber registry with name/type/address/path/ connected-time, populated in addClient and cleared in deleteClient so it reflects currently-connected clients only. - Add a ListMetadataSubscribers filer gRPC (optional client-type filter). - Admin server fans out to every filer, filters to mount types ("mount" Go weed mount, "sw-vfs" Rust VFS), and renders a new Cluster > Mount Clients page plus a Mount Clients dashboard section. Read-only; no behavior change to the subscribe hot path. * admin: address review — parallelize filer fan-out, guard nil map, robust CSV - GetMountClients now queries filers concurrently, each under a 5s timeout, so a slow/unreachable filer can't stall the admin dashboard. - Defensively initialize fs.subscribers before first write. - Mount Clients CSV export uses a Blob with quote-escaping instead of a data: URI, so special characters in paths export correctly. --- other/java/client/src/main/proto/filer.proto | 27 + weed/admin/dash/admin_data.go | 10 + weed/admin/dash/mount_clients.go | 80 +++ weed/admin/dash/types.go | 19 + weed/admin/handlers/admin_handlers.go | 1 + weed/admin/handlers/cluster_handlers.go | 22 + weed/admin/view/app/admin.templ | 28 + weed/admin/view/app/admin_templ.go | 405 ++++++----- weed/admin/view/app/mount_clients.templ | 139 ++++ weed/admin/view/app/mount_clients_templ.go | 181 +++++ weed/admin/view/layout/layout.templ | 7 +- weed/admin/view/layout/layout_templ.go | 553 +++++++------- weed/pb/filer.proto | 21 + weed/pb/filer_pb/filer.pb.go | 713 ++++++++++++------- weed/pb/filer_pb/filer_grpc.pb.go | 42 ++ weed/server/filer_grpc_server_sub_meta.go | 25 +- weed/server/filer_grpc_server_subscribers.go | 63 ++ weed/server/filer_server.go | 4 + 18 files changed, 1616 insertions(+), 724 deletions(-) create mode 100644 weed/admin/dash/mount_clients.go create mode 100644 weed/admin/view/app/mount_clients.templ create mode 100644 weed/admin/view/app/mount_clients_templ.go create mode 100644 weed/server/filer_grpc_server_subscribers.go diff --git a/other/java/client/src/main/proto/filer.proto b/other/java/client/src/main/proto/filer.proto index 4d7861d98..2b068967c 100644 --- a/other/java/client/src/main/proto/filer.proto +++ b/other/java/client/src/main/proto/filer.proto @@ -78,6 +78,11 @@ service SeaweedFiler { rpc SubscribeLocalMetadata (SubscribeMetadataRequest) returns (stream SubscribeMetadataResponse) { } + // List the metadata subscribers currently connected to this filer + // (FUSE mounts, S3, filer.sync, peer filers, ...). + rpc ListMetadataSubscribers (ListMetadataSubscribersRequest) returns (ListMetadataSubscribersResponse) { + } + rpc KvGet (KvGetRequest) returns (KvGetResponse) { } @@ -388,7 +393,13 @@ message PosixLockRequest { bool is_moved = 2; PosixLockOp op = 3; PosixLockRange lock = 4; + // locks carries the full set a mount holds on key for a KEEP_ALIVE + // re-assertion, so the current owner filer can rebuild its in-memory state + // after an ownership change or restart. lock.sid identifies the session. repeated PosixLockRange locks = 5; + // cooling_probe marks a dual-read a new owner sends to the previous owner + // during a ring change, so the previous owner answers from local state + // without itself cooling-off (no recursion). bool cooling_probe = 6; } @@ -615,6 +626,22 @@ message SubscribeMetadataResponse { repeated SubscribeMetadataResponse events = 4; // batch of additional events (backlog catch-up) repeated LogFileChunkRef log_file_refs = 5; // log file chunk refs for client direct-read } +message ListMetadataSubscribersRequest { + repeated string client_types = 1; // optional filter by client type, e.g. "mount"; empty = all +} +message ListMetadataSubscribersResponse { + repeated MetadataSubscriber subscribers = 1; +} +message MetadataSubscriber { + string client_name = 1; // "@
" + string client_type = 2; // e.g. "mount", "sw-vfs", "s3", "filer:" + string address = 3; // client peer address + string path_prefix = 4; // subscribed path prefix + int32 client_id = 5; + int32 client_epoch = 6; + int64 connected_at_ns = 7; + string filer_address = 8; // the filer this subscriber is connected to +} // A persisted log file that the client can read directly from volume servers. // The file format is: [4-byte size | protobuf LogEntry] repeated. // Each LogEntry.Data contains a marshaled SubscribeMetadataResponse. diff --git a/weed/admin/dash/admin_data.go b/weed/admin/dash/admin_data.go index 3c2d317d9..9c93af253 100644 --- a/weed/admin/dash/admin_data.go +++ b/weed/admin/dash/admin_data.go @@ -38,6 +38,9 @@ type AdminData struct { TotalEcVolumes int `json:"total_ec_volumes"` // Total number of EC volumes across all servers TotalEcShards int `json:"total_ec_shards"` // Total number of EC shards across all servers + // TotalMountClients is the number of connected FUSE/VFS mount clients across filers. + TotalMountClients int `json:"total_mount_clients"` + // Trends holds at-a-glance sparklines built from the admin's own recent // cluster snapshots (no Prometheus required). Trends DashboardTrends `json:"trends"` @@ -186,6 +189,12 @@ func (s *AdminServer) GetAdminData(username string) (AdminData, error) { } totalEcVolumes = len(ecVolumeSet) + // Count connected FUSE/VFS mount clients (best-effort; don't fail the dashboard) + totalMountClients := 0 + if mountData, mountErr := s.GetMountClients(); mountErr == nil { + totalMountClients = mountData.TotalMountClients + } + // Prepare admin data adminData := AdminData{ Username: username, @@ -202,6 +211,7 @@ func (s *AdminServer) GetAdminData(username string) (AdminData, error) { LastUpdated: topology.UpdatedAt, TotalEcVolumes: totalEcVolumes, TotalEcShards: totalEcShards, + TotalMountClients: totalMountClients, Trends: s.GetDashboardTrends(), } diff --git a/weed/admin/dash/mount_clients.go b/weed/admin/dash/mount_clients.go new file mode 100644 index 000000000..a5f965f6a --- /dev/null +++ b/weed/admin/dash/mount_clients.go @@ -0,0 +1,80 @@ +package dash + +import ( + "context" + "sort" + "sync" + "time" + + "github.com/seaweedfs/seaweedfs/weed/glog" + "github.com/seaweedfs/seaweedfs/weed/pb" + "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" +) + +// mountClientTypes are the metadata-subscriber client types that represent a +// FUSE/VFS mount: the Go `weed mount` ("mount") and the Rust VFS ("sw-vfs"). +var mountClientTypes = []string{"mount", "sw-vfs"} + +// mountClientsFilerTimeout bounds each per-filer ListMetadataSubscribers call so +// a slow or unreachable filer can't stall the admin dashboard. +const mountClientsFilerTimeout = 5 * time.Second + +// GetMountClients queries every filer for its connected mount subscribers and +// aggregates them. Each filer only knows the clients connected to itself, so a +// cluster-wide view requires fanning out. The filers are queried concurrently, +// each under a short timeout, and an unreachable filer is skipped. +func (s *AdminServer) GetMountClients() (*MountClientsData, error) { + var ( + mu sync.Mutex + clients []MountClient + wg sync.WaitGroup + ) + + for _, filerAddr := range s.GetAllFilers() { + wg.Add(1) + go func(filerAddr string) { + defer wg.Done() + ctx, cancel := context.WithTimeout(context.Background(), mountClientsFilerTimeout) + defer cancel() + err := pb.WithGrpcFilerClient(false, 0, pb.ServerAddress(filerAddr), s.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error { + resp, err := client.ListMetadataSubscribers(ctx, &filer_pb.ListMetadataSubscribersRequest{ + ClientTypes: mountClientTypes, + }) + if err != nil { + return err + } + mu.Lock() + for _, sub := range resp.Subscribers { + clients = append(clients, MountClient{ + ClientName: sub.ClientName, + ClientType: sub.ClientType, + Address: sub.Address, + PathPrefix: sub.PathPrefix, + ClientId: sub.ClientId, + ConnectedAt: time.Unix(0, sub.ConnectedAtNs), + FilerAddress: sub.FilerAddress, + }) + } + mu.Unlock() + return nil + }) + if err != nil { + glog.Warningf("list mount clients from filer %s: %v", filerAddr, err) + } + }(filerAddr) + } + wg.Wait() + + sort.Slice(clients, func(i, j int) bool { + if clients[i].Address != clients[j].Address { + return clients[i].Address < clients[j].Address + } + return clients[i].PathPrefix < clients[j].PathPrefix + }) + + return &MountClientsData{ + MountClients: clients, + TotalMountClients: len(clients), + LastUpdated: time.Now(), + }, nil +} diff --git a/weed/admin/dash/types.go b/weed/admin/dash/types.go index e4212347d..98d4d86f2 100644 --- a/weed/admin/dash/types.go +++ b/weed/admin/dash/types.go @@ -295,6 +295,25 @@ type ClusterFilersData struct { LastUpdated time.Time `json:"last_updated"` } +// MountClient is one connected FUSE/VFS mount as reported by a filer's +// metadata-subscriber registry. +type MountClient struct { + ClientName string `json:"client_name"` + ClientType string `json:"client_type"` // "mount" (Go) or "sw-vfs" (Rust VFS) + Address string `json:"address"` + PathPrefix string `json:"path_prefix"` + ClientId int32 `json:"client_id"` + ConnectedAt time.Time `json:"connected_at"` + FilerAddress string `json:"filer_address"` +} + +type MountClientsData struct { + Username string `json:"username"` + MountClients []MountClient `json:"mount_clients"` + TotalMountClients int `json:"total_mount_clients"` + LastUpdated time.Time `json:"last_updated"` +} + type MessageBrokerInfo struct { Address string `json:"address"` DataCenter string `json:"datacenter"` diff --git a/weed/admin/handlers/admin_handlers.go b/weed/admin/handlers/admin_handlers.go index fee4b198e..2ed2a8d4f 100644 --- a/weed/admin/handlers/admin_handlers.go +++ b/weed/admin/handlers/admin_handlers.go @@ -127,6 +127,7 @@ func (h *AdminHandlers) registerUIRoutes(r *mux.Router) { r.HandleFunc("/cluster/filers", h.clusterHandlers.ShowClusterFilers).Methods(http.MethodGet) r.HandleFunc("/cluster/s3", h.clusterHandlers.ShowClusterS3Servers).Methods(http.MethodGet) r.HandleFunc("/cluster/volume-servers", h.clusterHandlers.ShowClusterVolumeServers).Methods(http.MethodGet) + r.HandleFunc("/cluster/mount-clients", h.clusterHandlers.ShowMountClients).Methods(http.MethodGet) // Storage management routes r.HandleFunc("/storage/volumes", h.clusterHandlers.ShowClusterVolumes).Methods(http.MethodGet) diff --git a/weed/admin/handlers/cluster_handlers.go b/weed/admin/handlers/cluster_handlers.go index fe6734b60..1d7d490ab 100644 --- a/weed/admin/handlers/cluster_handlers.go +++ b/weed/admin/handlers/cluster_handlers.go @@ -51,6 +51,28 @@ func (h *ClusterHandlers) ShowClusterVolumeServers(w http.ResponseWriter, r *htt } } +// ShowMountClients renders the connected FUSE/VFS mount clients page +func (h *ClusterHandlers) ShowMountClients(w http.ResponseWriter, r *http.Request) { + data, err := h.adminServer.GetMountClients() + if err != nil { + writeJSONError(w, http.StatusInternalServerError, "Failed to get mount clients: "+err.Error()) + return + } + + username := usernameOrDefault(r) + data.Username = username + + // Render HTML template + w.Header().Set("Content-Type", "text/html") + mountClientsComponent := app.MountClients(*data) + viewCtx := layout.NewViewContext(r, username, dash.CSRFTokenFromContext(r.Context())) + layoutComponent := layout.Layout(viewCtx, mountClientsComponent) + if err := layoutComponent.Render(r.Context(), w); err != nil { + writeJSONError(w, http.StatusInternalServerError, "Failed to render template: "+err.Error()) + return + } +} + // ShowClusterVolumes renders the cluster volumes page func (h *ClusterHandlers) ShowClusterVolumes(w http.ResponseWriter, r *http.Request) { // Get pagination and sorting parameters from query string diff --git a/weed/admin/view/app/admin.templ b/weed/admin/view/app/admin.templ index b86781220..414d859bc 100644 --- a/weed/admin/view/app/admin.templ +++ b/weed/admin/view/app/admin.templ @@ -194,6 +194,34 @@ templ Admin(data dash.AdminData) { + +
+
+
+
+
+ Mount Clients +
+ + View Details + +
+
+
+ +
+
{fmt.Sprintf("%d", data.TotalMountClients)}
+
Connected FUSE/VFS mount clients
+
+
+
+
+
+
+ +
diff --git a/weed/admin/view/app/admin_templ.go b/weed/admin/view/app/admin_templ.go index 7afd68092..f4bec0d56 100644 --- a/weed/admin/view/app/admin_templ.go +++ b/weed/admin/view/app/admin_templ.go @@ -199,406 +199,406 @@ func Admin(data dash.AdminData) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
Master Nodes
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
Mount Clients
View Details
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var11 string + templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalMountClients)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 213, Col: 126} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "
Connected FUSE/VFS mount clients
Master Nodes
AddressRole
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, master := range data.MasterNodes { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "
AddressRole
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(master.Address) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 220, Col: 67} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 247, Col: 121} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var12)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 19, "\" target=\"_blank\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(master.Address) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 248, Col: 67} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if master.IsLeader { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 20, "Leader") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "Leader") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "Follower") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "Follower") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 22, "
Cluster
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var13 string - templ_7745c5c3_Var13, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.MasterNodes))) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 253, Col: 85} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var13)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
Masters
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
Cluster
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var14 string - templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.VolumeServers))) + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.MasterNodes))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 261, Col: 87} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 281, Col: 85} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var14)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
Volume Servers
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
Masters
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.FilerNodes))) + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.VolumeServers))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 269, Col: 84} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 289, Col: 87} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
Filers
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
Volume Servers
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.S3Nodes))) + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.FilerNodes))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 277, Col: 81} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 297, Col: 84} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
S3 Servers
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "
Filers
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var17 string - templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.MessageBrokers))) + templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.S3Nodes))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 285, Col: 88} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 305, Col: 81} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "
Message Brokers
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "\">View DetailsTopology View
IDAddressData CenterRackVolumesEC ShardsCapacity
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, vs := range data.VolumeServers { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, " / ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var31 string + templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(vs.DiskCapacity)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 387, Col: 107} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if len(data.VolumeServers) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "
IDAddressData CenterRackVolumesEC ShardsCapacity
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(vs.ID) + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(vs.ID) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 332, Col: 54} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var20)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "\" target=\"_blank\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var23 string - templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(vs.DataCenter) + templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(vs.GetDisplayAddress()) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 339, Col: 62} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 363, Col: 75} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var23)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var24 string - templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(vs.Rack) + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(vs.DataCenter) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 340, Col: 56} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 367, Col: 62} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 36, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues(fmt.Sprintf("width: %d%%", calculatePercent(vs.Volumes, vs.MaxVolumes))) + templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(vs.Rack) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 344, Col: 135} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 368, Col: 56} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var25)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "\">") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var27 string + templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d/%d", vs.Volumes, vs.MaxVolumes)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 373, Col: 104} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if vs.EcShards > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var27 string - templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", vs.EcShards)) + var templ_7745c5c3_Var28 string + templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", vs.EcShards)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 351, Col: 127} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 379, Col: 127} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var27)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if vs.EcVolumes > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "(") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "(") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var28 string - templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d vol", vs.EcVolumes)) + var templ_7745c5c3_Var29 string + templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d vol", vs.EcVolumes)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 353, Col: 119} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 381, Col: 119} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var28)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, ")") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, ")") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "-") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "-") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var29 string - templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(vs.DiskUsage)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 359, Col: 74} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var29)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, " / ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var30 string - templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(vs.DiskCapacity)) + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(formatBytes(vs.DiskUsage)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 359, Col: 107} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 387, Col: 74} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "
No volume servers found
No volume servers found
Filer Nodes
Actions:
File Browser
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "\">File BrowserTopology View
AddressData CenterRackLast Updated
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, filer := range data.FilerNodes { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if len(data.FilerNodes) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "
AddressData CenterRackLast Updated
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var34 string - templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(filer.Address) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 413, Col: 66} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 440, Col: 106} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var34)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "\" target=\"_blank\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var35 string - templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(filer.DataCenter) + templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(filer.Address) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 417, Col: 65} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 441, Col: 66} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var35)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var36 string - templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(filer.Rack) + templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(filer.DataCenter) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 418, Col: 59} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 445, Col: 65} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36)) if templ_7745c5c3_Err != nil { @@ -609,64 +609,64 @@ func Admin(data dash.AdminData) templ.Component { return templ_7745c5c3_Err } var templ_7745c5c3_Var37 string - templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(filer.LastUpdated.Format("2006-01-02 15:04:05")) + templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(filer.Rack) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 419, Col: 96} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 446, Col: 59} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var37)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var38 string + templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(filer.LastUpdated.Format("2006-01-02 15:04:05")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 447, Col: 96} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var38)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "
No filer nodes found
No filer nodes found
S3 Servers
Actions:
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "\">View Details
AddressData CenterLast Updated
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for _, s3Node := range data.S3Nodes { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if len(data.S3Nodes) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "
AddressData CenterLast Updated
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var39 string - templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(s3Node.Address) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 469, Col: 63} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var39)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var40 string - templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(s3Node.DataCenter) + templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(s3Node.Address) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 470, Col: 66} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 497, Col: 63} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40)) if templ_7745c5c3_Err != nil { @@ -677,39 +677,52 @@ func Admin(data dash.AdminData) templ.Component { return templ_7745c5c3_Err } var templ_7745c5c3_Var41 string - templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(s3Node.LastUpdated.Format("2006-01-02 15:04:05")) + templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(s3Node.DataCenter) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 471, Col: 97} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 498, Col: 66} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var41)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var42 string + templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(s3Node.LastUpdated.Format("2006-01-02 15:04:05")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 499, Col: 97} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "
No S3 servers found
No S3 servers found
Last updated: ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "
Last updated: ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var42 string - templ_7745c5c3_Var42, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastUpdated.Format("2006-01-02 15:04:05")) + var templ_7745c5c3_Var43 string + templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastUpdated.Format("2006-01-02 15:04:05")) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 495, Col: 81} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/admin.templ`, Line: 523, Col: 81} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var42)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var43)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/weed/admin/view/app/mount_clients.templ b/weed/admin/view/app/mount_clients.templ new file mode 100644 index 000000000..cebd7527f --- /dev/null +++ b/weed/admin/view/app/mount_clients.templ @@ -0,0 +1,139 @@ +package app + +import ( + "fmt" + "github.com/seaweedfs/seaweedfs/weed/admin/dash" +) + +templ MountClients(data dash.MountClientsData) { +
+

+ Mount Clients +

+
+
+ +
+
+
+ +
+ +
+
+
+
+
+
+
+ Connected Mount Clients +
+
+ { fmt.Sprintf("%d", data.TotalMountClients) } +
+
+
+ +
+
+
+
+
+
+ + +
+
+
+ Mount Clients +
+
+
+ if len(data.MountClients) > 0 { +
+ + + + + + + + + + + + + for _, c := range data.MountClients { + + + + + + + + + } + +
AddressTypePath PrefixClient IDConnected SinceFiler
{ c.Address } + { c.ClientType } + { c.PathPrefix }{ fmt.Sprintf("%d", c.ClientId) } + if !c.ConnectedAt.IsZero() { + { c.ConnectedAt.Format("2006-01-02 15:04:05") } + } else { + N/A + } + + { c.FilerAddress } +
+
+ } else { +
+ +
No Mount Clients Found
+

No FUSE or VFS mounts are currently connected to the cluster's filers.

+
+ } +
+
+ + +
+
+ + + Last updated: { data.LastUpdated.Format("2006-01-02 15:04:05") } + +
+
+
+ + +} diff --git a/weed/admin/view/app/mount_clients_templ.go b/weed/admin/view/app/mount_clients_templ.go new file mode 100644 index 000000000..1fee4fcd2 --- /dev/null +++ b/weed/admin/view/app/mount_clients_templ.go @@ -0,0 +1,181 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.3.1001 +package app + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "fmt" + "github.com/seaweedfs/seaweedfs/weed/admin/dash" +) + +func MountClients(data dash.MountClientsData) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil { + return templ_7745c5c3_CtxErr + } + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "

Mount Clients

Connected Mount Clients
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var2 string + templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalMountClients)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 34, Col: 52} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "
Mount Clients
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if len(data.MountClients) > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, c := range data.MountClients { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, "
AddressTypePath PrefixClient IDConnected SinceFiler
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(c.Address) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 70, Col: 31} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var4 string + templ_7745c5c3_Var4, templ_7745c5c3_Err = templ.JoinStringErrs(c.ClientType) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 72, Col: 63} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var4)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var5 string + templ_7745c5c3_Var5, templ_7745c5c3_Err = templ.JoinStringErrs(c.PathPrefix) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 74, Col: 34} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var5)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var6 string + templ_7745c5c3_Var6, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", c.ClientId)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 75, Col: 45} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var6)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !c.ConnectedAt.IsZero() { + var templ_7745c5c3_Var7 string + templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(c.ConnectedAt.Format("2006-01-02 15:04:05")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 78, Col: 57} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, "N/A") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var8 string + templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(c.FilerAddress) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 84, Col: 66} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
No Mount Clients Found

No FUSE or VFS mounts are currently connected to the cluster's filers.

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
Last updated: ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var9 string + templ_7745c5c3_Var9, templ_7745c5c3_Err = templ.JoinStringErrs(data.LastUpdated.Format("2006-01-02 15:04:05")) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/mount_clients.templ`, Line: 106, Col: 67} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var9)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return nil + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/weed/admin/view/layout/layout.templ b/weed/admin/view/layout/layout.templ index 6ebc09336..829e73485 100644 --- a/weed/admin/view/layout/layout.templ +++ b/weed/admin/view/layout/layout.templ @@ -32,7 +32,7 @@ templ Layout(view ViewContext, content templ.Component) { isStoragePage := strings.HasPrefix(currentPath, "/storage/volumes") || strings.HasPrefix(currentPath, "/storage/ec-shards") || strings.HasPrefix(currentPath, "/storage/collections") // Detect if we're on a cluster page (but not storage page) to keep submenu expanded - isClusterPage := (strings.HasPrefix(currentPath, "/cluster/masters") || strings.HasPrefix(currentPath, "/cluster/volume-servers") || strings.HasPrefix(currentPath, "/cluster/filers") || strings.HasPrefix(currentPath, "/cluster/s3")) + isClusterPage := (strings.HasPrefix(currentPath, "/cluster/masters") || strings.HasPrefix(currentPath, "/cluster/volume-servers") || strings.HasPrefix(currentPath, "/cluster/filers") || strings.HasPrefix(currentPath, "/cluster/s3") || strings.HasPrefix(currentPath, "/cluster/mount-clients")) isDefaultWorkerPage := currentPath == "/plugin" || strings.HasPrefix(currentPath, "/plugin/configuration") || @@ -139,6 +139,11 @@ templ Layout(view ViewContext, content templ.Component) { S3 Servers + diff --git a/weed/admin/view/layout/layout_templ.go b/weed/admin/view/layout/layout_templ.go index 3354d2ffb..d37f0a4dc 100644 --- a/weed/admin/view/layout/layout_templ.go +++ b/weed/admin/view/layout/layout_templ.go @@ -65,7 +65,7 @@ func Layout(view ViewContext, content templ.Component) templ.Component { isStoragePage := strings.HasPrefix(currentPath, "/storage/volumes") || strings.HasPrefix(currentPath, "/storage/ec-shards") || strings.HasPrefix(currentPath, "/storage/collections") // Detect if we're on a cluster page (but not storage page) to keep submenu expanded - isClusterPage := (strings.HasPrefix(currentPath, "/cluster/masters") || strings.HasPrefix(currentPath, "/cluster/volume-servers") || strings.HasPrefix(currentPath, "/cluster/filers") || strings.HasPrefix(currentPath, "/cluster/s3")) + isClusterPage := (strings.HasPrefix(currentPath, "/cluster/masters") || strings.HasPrefix(currentPath, "/cluster/volume-servers") || strings.HasPrefix(currentPath, "/cluster/filers") || strings.HasPrefix(currentPath, "/cluster/s3") || strings.HasPrefix(currentPath, "/cluster/mount-clients")) isDefaultWorkerPage := currentPath == "/plugin" || strings.HasPrefix(currentPath, "/plugin/configuration") || @@ -324,451 +324,464 @@ func Layout(view ViewContext, content templ.Component) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\">S3 Servers
  • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 21, "\">S3 Servers
  • Mount Clients
  • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var21).String()) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 1, Col: 0} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) + var templ_7745c5c3_Var22 = []any{"nav-link", templ.KV("collapsed", !isStoragePage)} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var22...) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "\" href=\"#\" data-bs-toggle=\"collapse\" data-bs-target=\"#storageSubmenu\" aria-expanded=\"") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Storage ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "\" href=\"#\" data-bs-toggle=\"collapse\" data-bs-target=\"#storageSubmenu\" aria-expanded=\"") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var24 = []any{"collapse", templ.KV("show", isStoragePage)} - templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var24...) + var templ_7745c5c3_Var24 string + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%t", isStoragePage)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 151, Col: 207} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
    Storage ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(templ.CSSClasses(templ_7745c5c3_Var24).String()) + var templ_7745c5c3_Var25 = []any{"collapse", templ.KV("show", isStoragePage)} + templ_7745c5c3_Err = templ.RenderCSSItems(ctx, templ_7745c5c3_Buffer, templ_7745c5c3_Var25...) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "
  • OBJECT STORE
    OBJECT STORE
    MANAGEMENT
    MANAGEMENT
    • File Browser
    • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if isMQPage { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "Message Queue ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "Message Queue ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "Message Queue ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "Message Queue ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if isMQPage { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
      • ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "
        • ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if currentPath == "/mq/brokers" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 40, "Brokers") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "Brokers") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "\">Brokers") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "
        • ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if currentPath == "/mq/topics" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "Topics") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 44, "\">Brokers") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
        • ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if currentPath == "/mq/topics" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "Topics") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "\">Topics") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "Topics") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "
        ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "
      ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "
    WORKERS
    • ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if isDefaultWorkerPage { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "Brokers
    • Default") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "\">Topics
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "
    WORKERS
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -776,108 +789,95 @@ func Layout(view ViewContext, content templ.Component) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "
    © ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var48 string - templ_7745c5c3_Var48, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", time.Now().Year())) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 334, Col: 60} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var48)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, " SeaweedFS Admin v") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "
    © ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var49 string - templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(version.VERSION_NUMBER) + templ_7745c5c3_Var49, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", time.Now().Year())) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 334, Col: 102} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 339, Col: 60} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var49)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, " SeaweedFS Admin v") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var50 string + templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(version.VERSION_NUMBER) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 339, Col: 102} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if version.COMMIT != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "(") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "(") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var50 string - templ_7745c5c3_Var50, templ_7745c5c3_Err = templ.JoinStringErrs(version.COMMIT) + var templ_7745c5c3_Var51 string + templ_7745c5c3_Var51, templ_7745c5c3_Err = templ.JoinStringErrs(version.COMMIT) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 336, Col: 55} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 341, Col: 55} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var50)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var51)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, ") ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, ") ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } if !strings.Contains(version.VERSION, "enterprise") { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, " Enterprise Version Available") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, " Enterprise Version Available") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -920,140 +933,140 @@ func LoginForm(title string, errorMessage string, csrfToken string) templ.Compon }() } ctx = templ.InitializeContext(ctx) - templ_7745c5c3_Var56 := templ.GetChildren(ctx) - if templ_7745c5c3_Var56 == nil { - templ_7745c5c3_Var56 = templ.NopComponent + templ_7745c5c3_Var57 := templ.GetChildren(ctx) + if templ_7745c5c3_Var57 == nil { + templ_7745c5c3_Var57 = templ.NopComponent } ctx = templ.ClearChildren(ctx) prefix := dash.URLPrefixFromContext(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "<!doctype html><html lang=\"en\"><head><meta charset=\"UTF-8\"><title>") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var57 string - templ_7745c5c3_Var57, templ_7745c5c3_Err = templ.JoinStringErrs(title) + var templ_7745c5c3_Var58 string + templ_7745c5c3_Var58, templ_7745c5c3_Err = templ.JoinStringErrs(title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 368, Col: 17} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var57)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, " - Login

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "\" rel=\"stylesheet\">

    Please sign in to continue

    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "\" rel=\"stylesheet\">

    ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var62 string + templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 387, Col: 57} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "

    Please sign in to continue

    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if errorMessage != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var62 string - templ_7745c5c3_Var62, templ_7745c5c3_Err = templ.JoinStringErrs(errorMessage) + var templ_7745c5c3_Var63 string + templ_7745c5c3_Var63, templ_7745c5c3_Err = templ.JoinStringErrs(errorMessage) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 389, Col: 45} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/layout/layout.templ`, Line: 394, Col: 45} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var62)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var63)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "
    ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "\">
    ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/weed/pb/filer.proto b/weed/pb/filer.proto index 6e5abd3f0..2b068967c 100644 --- a/weed/pb/filer.proto +++ b/weed/pb/filer.proto @@ -78,6 +78,11 @@ service SeaweedFiler { rpc SubscribeLocalMetadata (SubscribeMetadataRequest) returns (stream SubscribeMetadataResponse) { } + // List the metadata subscribers currently connected to this filer + // (FUSE mounts, S3, filer.sync, peer filers, ...). + rpc ListMetadataSubscribers (ListMetadataSubscribersRequest) returns (ListMetadataSubscribersResponse) { + } + rpc KvGet (KvGetRequest) returns (KvGetResponse) { } @@ -621,6 +626,22 @@ message SubscribeMetadataResponse { repeated SubscribeMetadataResponse events = 4; // batch of additional events (backlog catch-up) repeated LogFileChunkRef log_file_refs = 5; // log file chunk refs for client direct-read } +message ListMetadataSubscribersRequest { + repeated string client_types = 1; // optional filter by client type, e.g. "mount"; empty = all +} +message ListMetadataSubscribersResponse { + repeated MetadataSubscriber subscribers = 1; +} +message MetadataSubscriber { + string client_name = 1; // "@
    " + string client_type = 2; // e.g. "mount", "sw-vfs", "s3", "filer:" + string address = 3; // client peer address + string path_prefix = 4; // subscribed path prefix + int32 client_id = 5; + int32 client_epoch = 6; + int64 connected_at_ns = 7; + string filer_address = 8; // the filer this subscriber is connected to +} // A persisted log file that the client can read directly from volume servers. // The file format is: [4-byte size | protobuf LogEntry] repeated. // Each LogEntry.Data contains a marshaled SubscribeMetadataResponse. diff --git a/weed/pb/filer_pb/filer.pb.go b/weed/pb/filer_pb/filer.pb.go index 0c12c0e7e..202bedbe7 100644 --- a/weed/pb/filer_pb/filer.pb.go +++ b/weed/pb/filer_pb/filer.pb.go @@ -4274,6 +4274,194 @@ func (x *SubscribeMetadataResponse) GetLogFileRefs() []*LogFileChunkRef { return nil } +type ListMetadataSubscribersRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ClientTypes []string `protobuf:"bytes,1,rep,name=client_types,json=clientTypes,proto3" json:"client_types,omitempty"` // optional filter by client type, e.g. "mount"; empty = all + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListMetadataSubscribersRequest) Reset() { + *x = ListMetadataSubscribersRequest{} + mi := &file_filer_proto_msgTypes[55] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListMetadataSubscribersRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMetadataSubscribersRequest) ProtoMessage() {} + +func (x *ListMetadataSubscribersRequest) ProtoReflect() protoreflect.Message { + mi := &file_filer_proto_msgTypes[55] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMetadataSubscribersRequest.ProtoReflect.Descriptor instead. +func (*ListMetadataSubscribersRequest) Descriptor() ([]byte, []int) { + return file_filer_proto_rawDescGZIP(), []int{55} +} + +func (x *ListMetadataSubscribersRequest) GetClientTypes() []string { + if x != nil { + return x.ClientTypes + } + return nil +} + +type ListMetadataSubscribersResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Subscribers []*MetadataSubscriber `protobuf:"bytes,1,rep,name=subscribers,proto3" json:"subscribers,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *ListMetadataSubscribersResponse) Reset() { + *x = ListMetadataSubscribersResponse{} + mi := &file_filer_proto_msgTypes[56] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *ListMetadataSubscribersResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ListMetadataSubscribersResponse) ProtoMessage() {} + +func (x *ListMetadataSubscribersResponse) ProtoReflect() protoreflect.Message { + mi := &file_filer_proto_msgTypes[56] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ListMetadataSubscribersResponse.ProtoReflect.Descriptor instead. +func (*ListMetadataSubscribersResponse) Descriptor() ([]byte, []int) { + return file_filer_proto_rawDescGZIP(), []int{56} +} + +func (x *ListMetadataSubscribersResponse) GetSubscribers() []*MetadataSubscriber { + if x != nil { + return x.Subscribers + } + return nil +} + +type MetadataSubscriber struct { + state protoimpl.MessageState `protogen:"open.v1"` + ClientName string `protobuf:"bytes,1,opt,name=client_name,json=clientName,proto3" json:"client_name,omitempty"` // "@
    " + ClientType string `protobuf:"bytes,2,opt,name=client_type,json=clientType,proto3" json:"client_type,omitempty"` // e.g. "mount", "sw-vfs", "s3", "filer:" + Address string `protobuf:"bytes,3,opt,name=address,proto3" json:"address,omitempty"` // client peer address + PathPrefix string `protobuf:"bytes,4,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` // subscribed path prefix + ClientId int32 `protobuf:"varint,5,opt,name=client_id,json=clientId,proto3" json:"client_id,omitempty"` + ClientEpoch int32 `protobuf:"varint,6,opt,name=client_epoch,json=clientEpoch,proto3" json:"client_epoch,omitempty"` + ConnectedAtNs int64 `protobuf:"varint,7,opt,name=connected_at_ns,json=connectedAtNs,proto3" json:"connected_at_ns,omitempty"` + FilerAddress string `protobuf:"bytes,8,opt,name=filer_address,json=filerAddress,proto3" json:"filer_address,omitempty"` // the filer this subscriber is connected to + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *MetadataSubscriber) Reset() { + *x = MetadataSubscriber{} + mi := &file_filer_proto_msgTypes[57] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *MetadataSubscriber) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*MetadataSubscriber) ProtoMessage() {} + +func (x *MetadataSubscriber) ProtoReflect() protoreflect.Message { + mi := &file_filer_proto_msgTypes[57] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use MetadataSubscriber.ProtoReflect.Descriptor instead. +func (*MetadataSubscriber) Descriptor() ([]byte, []int) { + return file_filer_proto_rawDescGZIP(), []int{57} +} + +func (x *MetadataSubscriber) GetClientName() string { + if x != nil { + return x.ClientName + } + return "" +} + +func (x *MetadataSubscriber) GetClientType() string { + if x != nil { + return x.ClientType + } + return "" +} + +func (x *MetadataSubscriber) GetAddress() string { + if x != nil { + return x.Address + } + return "" +} + +func (x *MetadataSubscriber) GetPathPrefix() string { + if x != nil { + return x.PathPrefix + } + return "" +} + +func (x *MetadataSubscriber) GetClientId() int32 { + if x != nil { + return x.ClientId + } + return 0 +} + +func (x *MetadataSubscriber) GetClientEpoch() int32 { + if x != nil { + return x.ClientEpoch + } + return 0 +} + +func (x *MetadataSubscriber) GetConnectedAtNs() int64 { + if x != nil { + return x.ConnectedAtNs + } + return 0 +} + +func (x *MetadataSubscriber) GetFilerAddress() string { + if x != nil { + return x.FilerAddress + } + return "" +} + // A persisted log file that the client can read directly from volume servers. // The file format is: [4-byte size | protobuf LogEntry] repeated. // Each LogEntry.Data contains a marshaled SubscribeMetadataResponse. @@ -4288,7 +4476,7 @@ type LogFileChunkRef struct { func (x *LogFileChunkRef) Reset() { *x = LogFileChunkRef{} - mi := &file_filer_proto_msgTypes[55] + mi := &file_filer_proto_msgTypes[58] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4300,7 +4488,7 @@ func (x *LogFileChunkRef) String() string { func (*LogFileChunkRef) ProtoMessage() {} func (x *LogFileChunkRef) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[55] + mi := &file_filer_proto_msgTypes[58] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4313,7 +4501,7 @@ func (x *LogFileChunkRef) ProtoReflect() protoreflect.Message { // Deprecated: Use LogFileChunkRef.ProtoReflect.Descriptor instead. func (*LogFileChunkRef) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{55} + return file_filer_proto_rawDescGZIP(), []int{58} } func (x *LogFileChunkRef) GetChunks() []*FileChunk { @@ -4347,7 +4535,7 @@ type TraverseBfsMetadataRequest struct { func (x *TraverseBfsMetadataRequest) Reset() { *x = TraverseBfsMetadataRequest{} - mi := &file_filer_proto_msgTypes[56] + mi := &file_filer_proto_msgTypes[59] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4359,7 +4547,7 @@ func (x *TraverseBfsMetadataRequest) String() string { func (*TraverseBfsMetadataRequest) ProtoMessage() {} func (x *TraverseBfsMetadataRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[56] + mi := &file_filer_proto_msgTypes[59] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4372,7 +4560,7 @@ func (x *TraverseBfsMetadataRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TraverseBfsMetadataRequest.ProtoReflect.Descriptor instead. func (*TraverseBfsMetadataRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{56} + return file_filer_proto_rawDescGZIP(), []int{59} } func (x *TraverseBfsMetadataRequest) GetDirectory() string { @@ -4399,7 +4587,7 @@ type TraverseBfsMetadataResponse struct { func (x *TraverseBfsMetadataResponse) Reset() { *x = TraverseBfsMetadataResponse{} - mi := &file_filer_proto_msgTypes[57] + mi := &file_filer_proto_msgTypes[60] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4411,7 +4599,7 @@ func (x *TraverseBfsMetadataResponse) String() string { func (*TraverseBfsMetadataResponse) ProtoMessage() {} func (x *TraverseBfsMetadataResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[57] + mi := &file_filer_proto_msgTypes[60] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4424,7 +4612,7 @@ func (x *TraverseBfsMetadataResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TraverseBfsMetadataResponse.ProtoReflect.Descriptor instead. func (*TraverseBfsMetadataResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{57} + return file_filer_proto_rawDescGZIP(), []int{60} } func (x *TraverseBfsMetadataResponse) GetDirectory() string { @@ -4454,7 +4642,7 @@ type LogEntry struct { func (x *LogEntry) Reset() { *x = LogEntry{} - mi := &file_filer_proto_msgTypes[58] + mi := &file_filer_proto_msgTypes[61] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4466,7 +4654,7 @@ func (x *LogEntry) String() string { func (*LogEntry) ProtoMessage() {} func (x *LogEntry) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[58] + mi := &file_filer_proto_msgTypes[61] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4479,7 +4667,7 @@ func (x *LogEntry) ProtoReflect() protoreflect.Message { // Deprecated: Use LogEntry.ProtoReflect.Descriptor instead. func (*LogEntry) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{58} + return file_filer_proto_rawDescGZIP(), []int{61} } func (x *LogEntry) GetTsNs() int64 { @@ -4528,7 +4716,7 @@ type KeepConnectedRequest struct { func (x *KeepConnectedRequest) Reset() { *x = KeepConnectedRequest{} - mi := &file_filer_proto_msgTypes[59] + mi := &file_filer_proto_msgTypes[62] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4540,7 +4728,7 @@ func (x *KeepConnectedRequest) String() string { func (*KeepConnectedRequest) ProtoMessage() {} func (x *KeepConnectedRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[59] + mi := &file_filer_proto_msgTypes[62] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4553,7 +4741,7 @@ func (x *KeepConnectedRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use KeepConnectedRequest.ProtoReflect.Descriptor instead. func (*KeepConnectedRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{59} + return file_filer_proto_rawDescGZIP(), []int{62} } func (x *KeepConnectedRequest) GetName() string { @@ -4585,7 +4773,7 @@ type KeepConnectedResponse struct { func (x *KeepConnectedResponse) Reset() { *x = KeepConnectedResponse{} - mi := &file_filer_proto_msgTypes[60] + mi := &file_filer_proto_msgTypes[63] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4597,7 +4785,7 @@ func (x *KeepConnectedResponse) String() string { func (*KeepConnectedResponse) ProtoMessage() {} func (x *KeepConnectedResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[60] + mi := &file_filer_proto_msgTypes[63] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4610,7 +4798,7 @@ func (x *KeepConnectedResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use KeepConnectedResponse.ProtoReflect.Descriptor instead. func (*KeepConnectedResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{60} + return file_filer_proto_rawDescGZIP(), []int{63} } type LocateBrokerRequest struct { @@ -4622,7 +4810,7 @@ type LocateBrokerRequest struct { func (x *LocateBrokerRequest) Reset() { *x = LocateBrokerRequest{} - mi := &file_filer_proto_msgTypes[61] + mi := &file_filer_proto_msgTypes[64] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4634,7 +4822,7 @@ func (x *LocateBrokerRequest) String() string { func (*LocateBrokerRequest) ProtoMessage() {} func (x *LocateBrokerRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[61] + mi := &file_filer_proto_msgTypes[64] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4647,7 +4835,7 @@ func (x *LocateBrokerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LocateBrokerRequest.ProtoReflect.Descriptor instead. func (*LocateBrokerRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{61} + return file_filer_proto_rawDescGZIP(), []int{64} } func (x *LocateBrokerRequest) GetResource() string { @@ -4667,7 +4855,7 @@ type LocateBrokerResponse struct { func (x *LocateBrokerResponse) Reset() { *x = LocateBrokerResponse{} - mi := &file_filer_proto_msgTypes[62] + mi := &file_filer_proto_msgTypes[65] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4679,7 +4867,7 @@ func (x *LocateBrokerResponse) String() string { func (*LocateBrokerResponse) ProtoMessage() {} func (x *LocateBrokerResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[62] + mi := &file_filer_proto_msgTypes[65] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4692,7 +4880,7 @@ func (x *LocateBrokerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LocateBrokerResponse.ProtoReflect.Descriptor instead. func (*LocateBrokerResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{62} + return file_filer_proto_rawDescGZIP(), []int{65} } func (x *LocateBrokerResponse) GetFound() bool { @@ -4721,7 +4909,7 @@ type KvGetRequest struct { func (x *KvGetRequest) Reset() { *x = KvGetRequest{} - mi := &file_filer_proto_msgTypes[63] + mi := &file_filer_proto_msgTypes[66] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4733,7 +4921,7 @@ func (x *KvGetRequest) String() string { func (*KvGetRequest) ProtoMessage() {} func (x *KvGetRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[63] + mi := &file_filer_proto_msgTypes[66] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4746,7 +4934,7 @@ func (x *KvGetRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use KvGetRequest.ProtoReflect.Descriptor instead. func (*KvGetRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{63} + return file_filer_proto_rawDescGZIP(), []int{66} } func (x *KvGetRequest) GetKey() []byte { @@ -4766,7 +4954,7 @@ type KvGetResponse struct { func (x *KvGetResponse) Reset() { *x = KvGetResponse{} - mi := &file_filer_proto_msgTypes[64] + mi := &file_filer_proto_msgTypes[67] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4778,7 +4966,7 @@ func (x *KvGetResponse) String() string { func (*KvGetResponse) ProtoMessage() {} func (x *KvGetResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[64] + mi := &file_filer_proto_msgTypes[67] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4791,7 +4979,7 @@ func (x *KvGetResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use KvGetResponse.ProtoReflect.Descriptor instead. func (*KvGetResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{64} + return file_filer_proto_rawDescGZIP(), []int{67} } func (x *KvGetResponse) GetValue() []byte { @@ -4818,7 +5006,7 @@ type KvPutRequest struct { func (x *KvPutRequest) Reset() { *x = KvPutRequest{} - mi := &file_filer_proto_msgTypes[65] + mi := &file_filer_proto_msgTypes[68] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4830,7 +5018,7 @@ func (x *KvPutRequest) String() string { func (*KvPutRequest) ProtoMessage() {} func (x *KvPutRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[65] + mi := &file_filer_proto_msgTypes[68] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4843,7 +5031,7 @@ func (x *KvPutRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use KvPutRequest.ProtoReflect.Descriptor instead. func (*KvPutRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{65} + return file_filer_proto_rawDescGZIP(), []int{68} } func (x *KvPutRequest) GetKey() []byte { @@ -4869,7 +5057,7 @@ type KvPutResponse struct { func (x *KvPutResponse) Reset() { *x = KvPutResponse{} - mi := &file_filer_proto_msgTypes[66] + mi := &file_filer_proto_msgTypes[69] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4881,7 +5069,7 @@ func (x *KvPutResponse) String() string { func (*KvPutResponse) ProtoMessage() {} func (x *KvPutResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[66] + mi := &file_filer_proto_msgTypes[69] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4894,7 +5082,7 @@ func (x *KvPutResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use KvPutResponse.ProtoReflect.Descriptor instead. func (*KvPutResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{66} + return file_filer_proto_rawDescGZIP(), []int{69} } func (x *KvPutResponse) GetError() string { @@ -4917,7 +5105,7 @@ type FilerConf struct { func (x *FilerConf) Reset() { *x = FilerConf{} - mi := &file_filer_proto_msgTypes[67] + mi := &file_filer_proto_msgTypes[70] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4929,7 +5117,7 @@ func (x *FilerConf) String() string { func (*FilerConf) ProtoMessage() {} func (x *FilerConf) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[67] + mi := &file_filer_proto_msgTypes[70] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4942,7 +5130,7 @@ func (x *FilerConf) ProtoReflect() protoreflect.Message { // Deprecated: Use FilerConf.ProtoReflect.Descriptor instead. func (*FilerConf) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{67} + return file_filer_proto_rawDescGZIP(), []int{70} } func (x *FilerConf) GetVersion() int32 { @@ -4974,7 +5162,7 @@ type CacheRemoteObjectToLocalClusterRequest struct { func (x *CacheRemoteObjectToLocalClusterRequest) Reset() { *x = CacheRemoteObjectToLocalClusterRequest{} - mi := &file_filer_proto_msgTypes[68] + mi := &file_filer_proto_msgTypes[71] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -4986,7 +5174,7 @@ func (x *CacheRemoteObjectToLocalClusterRequest) String() string { func (*CacheRemoteObjectToLocalClusterRequest) ProtoMessage() {} func (x *CacheRemoteObjectToLocalClusterRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[68] + mi := &file_filer_proto_msgTypes[71] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -4999,7 +5187,7 @@ func (x *CacheRemoteObjectToLocalClusterRequest) ProtoReflect() protoreflect.Mes // Deprecated: Use CacheRemoteObjectToLocalClusterRequest.ProtoReflect.Descriptor instead. func (*CacheRemoteObjectToLocalClusterRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{68} + return file_filer_proto_rawDescGZIP(), []int{71} } func (x *CacheRemoteObjectToLocalClusterRequest) GetDirectory() string { @@ -5040,7 +5228,7 @@ type CacheRemoteObjectToLocalClusterResponse struct { func (x *CacheRemoteObjectToLocalClusterResponse) Reset() { *x = CacheRemoteObjectToLocalClusterResponse{} - mi := &file_filer_proto_msgTypes[69] + mi := &file_filer_proto_msgTypes[72] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5052,7 +5240,7 @@ func (x *CacheRemoteObjectToLocalClusterResponse) String() string { func (*CacheRemoteObjectToLocalClusterResponse) ProtoMessage() {} func (x *CacheRemoteObjectToLocalClusterResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[69] + mi := &file_filer_proto_msgTypes[72] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5065,7 +5253,7 @@ func (x *CacheRemoteObjectToLocalClusterResponse) ProtoReflect() protoreflect.Me // Deprecated: Use CacheRemoteObjectToLocalClusterResponse.ProtoReflect.Descriptor instead. func (*CacheRemoteObjectToLocalClusterResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{69} + return file_filer_proto_rawDescGZIP(), []int{72} } func (x *CacheRemoteObjectToLocalClusterResponse) GetEntry() *Entry { @@ -5098,7 +5286,7 @@ type LockRequest struct { func (x *LockRequest) Reset() { *x = LockRequest{} - mi := &file_filer_proto_msgTypes[70] + mi := &file_filer_proto_msgTypes[73] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5110,7 +5298,7 @@ func (x *LockRequest) String() string { func (*LockRequest) ProtoMessage() {} func (x *LockRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[70] + mi := &file_filer_proto_msgTypes[73] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5123,7 +5311,7 @@ func (x *LockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use LockRequest.ProtoReflect.Descriptor instead. func (*LockRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{70} + return file_filer_proto_rawDescGZIP(), []int{73} } func (x *LockRequest) GetName() string { @@ -5174,7 +5362,7 @@ type LockResponse struct { func (x *LockResponse) Reset() { *x = LockResponse{} - mi := &file_filer_proto_msgTypes[71] + mi := &file_filer_proto_msgTypes[74] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5186,7 +5374,7 @@ func (x *LockResponse) String() string { func (*LockResponse) ProtoMessage() {} func (x *LockResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[71] + mi := &file_filer_proto_msgTypes[74] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5199,7 +5387,7 @@ func (x *LockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use LockResponse.ProtoReflect.Descriptor instead. func (*LockResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{71} + return file_filer_proto_rawDescGZIP(), []int{74} } func (x *LockResponse) GetRenewToken() string { @@ -5248,7 +5436,7 @@ type UnlockRequest struct { func (x *UnlockRequest) Reset() { *x = UnlockRequest{} - mi := &file_filer_proto_msgTypes[72] + mi := &file_filer_proto_msgTypes[75] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5260,7 +5448,7 @@ func (x *UnlockRequest) String() string { func (*UnlockRequest) ProtoMessage() {} func (x *UnlockRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[72] + mi := &file_filer_proto_msgTypes[75] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5273,7 +5461,7 @@ func (x *UnlockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use UnlockRequest.ProtoReflect.Descriptor instead. func (*UnlockRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{72} + return file_filer_proto_rawDescGZIP(), []int{75} } func (x *UnlockRequest) GetName() string { @@ -5307,7 +5495,7 @@ type UnlockResponse struct { func (x *UnlockResponse) Reset() { *x = UnlockResponse{} - mi := &file_filer_proto_msgTypes[73] + mi := &file_filer_proto_msgTypes[76] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5319,7 +5507,7 @@ func (x *UnlockResponse) String() string { func (*UnlockResponse) ProtoMessage() {} func (x *UnlockResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[73] + mi := &file_filer_proto_msgTypes[76] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5332,7 +5520,7 @@ func (x *UnlockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use UnlockResponse.ProtoReflect.Descriptor instead. func (*UnlockResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{73} + return file_filer_proto_rawDescGZIP(), []int{76} } func (x *UnlockResponse) GetError() string { @@ -5359,7 +5547,7 @@ type FindLockOwnerRequest struct { func (x *FindLockOwnerRequest) Reset() { *x = FindLockOwnerRequest{} - mi := &file_filer_proto_msgTypes[74] + mi := &file_filer_proto_msgTypes[77] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5371,7 +5559,7 @@ func (x *FindLockOwnerRequest) String() string { func (*FindLockOwnerRequest) ProtoMessage() {} func (x *FindLockOwnerRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[74] + mi := &file_filer_proto_msgTypes[77] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5384,7 +5572,7 @@ func (x *FindLockOwnerRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use FindLockOwnerRequest.ProtoReflect.Descriptor instead. func (*FindLockOwnerRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{74} + return file_filer_proto_rawDescGZIP(), []int{77} } func (x *FindLockOwnerRequest) GetName() string { @@ -5410,7 +5598,7 @@ type FindLockOwnerResponse struct { func (x *FindLockOwnerResponse) Reset() { *x = FindLockOwnerResponse{} - mi := &file_filer_proto_msgTypes[75] + mi := &file_filer_proto_msgTypes[78] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5422,7 +5610,7 @@ func (x *FindLockOwnerResponse) String() string { func (*FindLockOwnerResponse) ProtoMessage() {} func (x *FindLockOwnerResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[75] + mi := &file_filer_proto_msgTypes[78] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5435,7 +5623,7 @@ func (x *FindLockOwnerResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use FindLockOwnerResponse.ProtoReflect.Descriptor instead. func (*FindLockOwnerResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{75} + return file_filer_proto_rawDescGZIP(), []int{78} } func (x *FindLockOwnerResponse) GetOwner() string { @@ -5460,7 +5648,7 @@ type Lock struct { func (x *Lock) Reset() { *x = Lock{} - mi := &file_filer_proto_msgTypes[76] + mi := &file_filer_proto_msgTypes[79] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5472,7 +5660,7 @@ func (x *Lock) String() string { func (*Lock) ProtoMessage() {} func (x *Lock) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[76] + mi := &file_filer_proto_msgTypes[79] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5485,7 +5673,7 @@ func (x *Lock) ProtoReflect() protoreflect.Message { // Deprecated: Use Lock.ProtoReflect.Descriptor instead. func (*Lock) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{76} + return file_filer_proto_rawDescGZIP(), []int{79} } func (x *Lock) GetName() string { @@ -5546,7 +5734,7 @@ type TransferLocksRequest struct { func (x *TransferLocksRequest) Reset() { *x = TransferLocksRequest{} - mi := &file_filer_proto_msgTypes[77] + mi := &file_filer_proto_msgTypes[80] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5558,7 +5746,7 @@ func (x *TransferLocksRequest) String() string { func (*TransferLocksRequest) ProtoMessage() {} func (x *TransferLocksRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[77] + mi := &file_filer_proto_msgTypes[80] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5571,7 +5759,7 @@ func (x *TransferLocksRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use TransferLocksRequest.ProtoReflect.Descriptor instead. func (*TransferLocksRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{77} + return file_filer_proto_rawDescGZIP(), []int{80} } func (x *TransferLocksRequest) GetLocks() []*Lock { @@ -5589,7 +5777,7 @@ type TransferLocksResponse struct { func (x *TransferLocksResponse) Reset() { *x = TransferLocksResponse{} - mi := &file_filer_proto_msgTypes[78] + mi := &file_filer_proto_msgTypes[81] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5601,7 +5789,7 @@ func (x *TransferLocksResponse) String() string { func (*TransferLocksResponse) ProtoMessage() {} func (x *TransferLocksResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[78] + mi := &file_filer_proto_msgTypes[81] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5614,7 +5802,7 @@ func (x *TransferLocksResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use TransferLocksResponse.ProtoReflect.Descriptor instead. func (*TransferLocksResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{78} + return file_filer_proto_rawDescGZIP(), []int{81} } type ReplicateLockRequest struct { @@ -5632,7 +5820,7 @@ type ReplicateLockRequest struct { func (x *ReplicateLockRequest) Reset() { *x = ReplicateLockRequest{} - mi := &file_filer_proto_msgTypes[79] + mi := &file_filer_proto_msgTypes[82] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5644,7 +5832,7 @@ func (x *ReplicateLockRequest) String() string { func (*ReplicateLockRequest) ProtoMessage() {} func (x *ReplicateLockRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[79] + mi := &file_filer_proto_msgTypes[82] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5657,7 +5845,7 @@ func (x *ReplicateLockRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ReplicateLockRequest.ProtoReflect.Descriptor instead. func (*ReplicateLockRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{79} + return file_filer_proto_rawDescGZIP(), []int{82} } func (x *ReplicateLockRequest) GetName() string { @@ -5717,7 +5905,7 @@ type ReplicateLockResponse struct { func (x *ReplicateLockResponse) Reset() { *x = ReplicateLockResponse{} - mi := &file_filer_proto_msgTypes[80] + mi := &file_filer_proto_msgTypes[83] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5729,7 +5917,7 @@ func (x *ReplicateLockResponse) String() string { func (*ReplicateLockResponse) ProtoMessage() {} func (x *ReplicateLockResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[80] + mi := &file_filer_proto_msgTypes[83] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5742,7 +5930,7 @@ func (x *ReplicateLockResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ReplicateLockResponse.ProtoReflect.Descriptor instead. func (*ReplicateLockResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{80} + return file_filer_proto_rawDescGZIP(), []int{83} } type StreamMutateEntryRequest struct { @@ -5761,7 +5949,7 @@ type StreamMutateEntryRequest struct { func (x *StreamMutateEntryRequest) Reset() { *x = StreamMutateEntryRequest{} - mi := &file_filer_proto_msgTypes[81] + mi := &file_filer_proto_msgTypes[84] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5773,7 +5961,7 @@ func (x *StreamMutateEntryRequest) String() string { func (*StreamMutateEntryRequest) ProtoMessage() {} func (x *StreamMutateEntryRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[81] + mi := &file_filer_proto_msgTypes[84] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5786,7 +5974,7 @@ func (x *StreamMutateEntryRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamMutateEntryRequest.ProtoReflect.Descriptor instead. func (*StreamMutateEntryRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{81} + return file_filer_proto_rawDescGZIP(), []int{84} } func (x *StreamMutateEntryRequest) GetRequestId() uint64 { @@ -5886,7 +6074,7 @@ type StreamMutateEntryResponse struct { func (x *StreamMutateEntryResponse) Reset() { *x = StreamMutateEntryResponse{} - mi := &file_filer_proto_msgTypes[82] + mi := &file_filer_proto_msgTypes[85] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -5898,7 +6086,7 @@ func (x *StreamMutateEntryResponse) String() string { func (*StreamMutateEntryResponse) ProtoMessage() {} func (x *StreamMutateEntryResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[82] + mi := &file_filer_proto_msgTypes[85] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -5911,7 +6099,7 @@ func (x *StreamMutateEntryResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StreamMutateEntryResponse.ProtoReflect.Descriptor instead. func (*StreamMutateEntryResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{82} + return file_filer_proto_rawDescGZIP(), []int{85} } func (x *StreamMutateEntryResponse) GetRequestId() uint64 { @@ -6025,7 +6213,7 @@ type MountRegisterRequest struct { func (x *MountRegisterRequest) Reset() { *x = MountRegisterRequest{} - mi := &file_filer_proto_msgTypes[83] + mi := &file_filer_proto_msgTypes[86] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6037,7 +6225,7 @@ func (x *MountRegisterRequest) String() string { func (*MountRegisterRequest) ProtoMessage() {} func (x *MountRegisterRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[83] + mi := &file_filer_proto_msgTypes[86] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6050,7 +6238,7 @@ func (x *MountRegisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountRegisterRequest.ProtoReflect.Descriptor instead. func (*MountRegisterRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{83} + return file_filer_proto_rawDescGZIP(), []int{86} } func (x *MountRegisterRequest) GetPeerAddr() string { @@ -6089,7 +6277,7 @@ type MountRegisterResponse struct { func (x *MountRegisterResponse) Reset() { *x = MountRegisterResponse{} - mi := &file_filer_proto_msgTypes[84] + mi := &file_filer_proto_msgTypes[87] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6101,7 +6289,7 @@ func (x *MountRegisterResponse) String() string { func (*MountRegisterResponse) ProtoMessage() {} func (x *MountRegisterResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[84] + mi := &file_filer_proto_msgTypes[87] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6114,7 +6302,7 @@ func (x *MountRegisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountRegisterResponse.ProtoReflect.Descriptor instead. func (*MountRegisterResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{84} + return file_filer_proto_rawDescGZIP(), []int{87} } type MountListRequest struct { @@ -6125,7 +6313,7 @@ type MountListRequest struct { func (x *MountListRequest) Reset() { *x = MountListRequest{} - mi := &file_filer_proto_msgTypes[85] + mi := &file_filer_proto_msgTypes[88] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6137,7 +6325,7 @@ func (x *MountListRequest) String() string { func (*MountListRequest) ProtoMessage() {} func (x *MountListRequest) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[85] + mi := &file_filer_proto_msgTypes[88] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6150,7 +6338,7 @@ func (x *MountListRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use MountListRequest.ProtoReflect.Descriptor instead. func (*MountListRequest) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{85} + return file_filer_proto_rawDescGZIP(), []int{88} } type MountListResponse struct { @@ -6162,7 +6350,7 @@ type MountListResponse struct { func (x *MountListResponse) Reset() { *x = MountListResponse{} - mi := &file_filer_proto_msgTypes[86] + mi := &file_filer_proto_msgTypes[89] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6174,7 +6362,7 @@ func (x *MountListResponse) String() string { func (*MountListResponse) ProtoMessage() {} func (x *MountListResponse) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[86] + mi := &file_filer_proto_msgTypes[89] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6187,7 +6375,7 @@ func (x *MountListResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use MountListResponse.ProtoReflect.Descriptor instead. func (*MountListResponse) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{86} + return file_filer_proto_rawDescGZIP(), []int{89} } func (x *MountListResponse) GetMounts() []*MountInfo { @@ -6209,7 +6397,7 @@ type MountInfo struct { func (x *MountInfo) Reset() { *x = MountInfo{} - mi := &file_filer_proto_msgTypes[87] + mi := &file_filer_proto_msgTypes[90] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6221,7 +6409,7 @@ func (x *MountInfo) String() string { func (*MountInfo) ProtoMessage() {} func (x *MountInfo) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[87] + mi := &file_filer_proto_msgTypes[90] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6234,7 +6422,7 @@ func (x *MountInfo) ProtoReflect() protoreflect.Message { // Deprecated: Use MountInfo.ProtoReflect.Descriptor instead. func (*MountInfo) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{87} + return file_filer_proto_rawDescGZIP(), []int{90} } func (x *MountInfo) GetPeerAddr() string { @@ -6293,7 +6481,7 @@ type WriteCondition_Clause struct { func (x *WriteCondition_Clause) Reset() { *x = WriteCondition_Clause{} - mi := &file_filer_proto_msgTypes[89] + mi := &file_filer_proto_msgTypes[92] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6305,7 +6493,7 @@ func (x *WriteCondition_Clause) String() string { func (*WriteCondition_Clause) ProtoMessage() {} func (x *WriteCondition_Clause) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[89] + mi := &file_filer_proto_msgTypes[92] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6389,7 +6577,7 @@ type LocateBrokerResponse_Resource struct { func (x *LocateBrokerResponse_Resource) Reset() { *x = LocateBrokerResponse_Resource{} - mi := &file_filer_proto_msgTypes[94] + mi := &file_filer_proto_msgTypes[97] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6401,7 +6589,7 @@ func (x *LocateBrokerResponse_Resource) String() string { func (*LocateBrokerResponse_Resource) ProtoMessage() {} func (x *LocateBrokerResponse_Resource) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[94] + mi := &file_filer_proto_msgTypes[97] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6414,7 +6602,7 @@ func (x *LocateBrokerResponse_Resource) ProtoReflect() protoreflect.Message { // Deprecated: Use LocateBrokerResponse_Resource.ProtoReflect.Descriptor instead. func (*LocateBrokerResponse_Resource) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{62, 0} + return file_filer_proto_rawDescGZIP(), []int{65, 0} } func (x *LocateBrokerResponse_Resource) GetGrpcAddresses() string { @@ -6455,7 +6643,7 @@ type FilerConf_PathConf struct { func (x *FilerConf_PathConf) Reset() { *x = FilerConf_PathConf{} - mi := &file_filer_proto_msgTypes[95] + mi := &file_filer_proto_msgTypes[98] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -6467,7 +6655,7 @@ func (x *FilerConf_PathConf) String() string { func (*FilerConf_PathConf) ProtoMessage() {} func (x *FilerConf_PathConf) ProtoReflect() protoreflect.Message { - mi := &file_filer_proto_msgTypes[95] + mi := &file_filer_proto_msgTypes[98] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -6480,7 +6668,7 @@ func (x *FilerConf_PathConf) ProtoReflect() protoreflect.Message { // Deprecated: Use FilerConf_PathConf.ProtoReflect.Descriptor instead. func (*FilerConf_PathConf) Descriptor() ([]byte, []int) { - return file_filer_proto_rawDescGZIP(), []int{67, 0} + return file_filer_proto_rawDescGZIP(), []int{70, 0} } func (x *FilerConf_PathConf) GetLocationPrefix() string { @@ -6999,7 +7187,23 @@ const file_filer_proto_rawDesc = "" + "\x12event_notification\x18\x02 \x01(\v2\x1b.filer_pb.EventNotificationR\x11eventNotification\x12\x13\n" + "\x05ts_ns\x18\x03 \x01(\x03R\x04tsNs\x12;\n" + "\x06events\x18\x04 \x03(\v2#.filer_pb.SubscribeMetadataResponseR\x06events\x12=\n" + - "\rlog_file_refs\x18\x05 \x03(\v2\x19.filer_pb.LogFileChunkRefR\vlogFileRefs\"w\n" + + "\rlog_file_refs\x18\x05 \x03(\v2\x19.filer_pb.LogFileChunkRefR\vlogFileRefs\"C\n" + + "\x1eListMetadataSubscribersRequest\x12!\n" + + "\fclient_types\x18\x01 \x03(\tR\vclientTypes\"a\n" + + "\x1fListMetadataSubscribersResponse\x12>\n" + + "\vsubscribers\x18\x01 \x03(\v2\x1c.filer_pb.MetadataSubscriberR\vsubscribers\"\x9e\x02\n" + + "\x12MetadataSubscriber\x12\x1f\n" + + "\vclient_name\x18\x01 \x01(\tR\n" + + "clientName\x12\x1f\n" + + "\vclient_type\x18\x02 \x01(\tR\n" + + "clientType\x12\x18\n" + + "\aaddress\x18\x03 \x01(\tR\aaddress\x12\x1f\n" + + "\vpath_prefix\x18\x04 \x01(\tR\n" + + "pathPrefix\x12\x1b\n" + + "\tclient_id\x18\x05 \x01(\x05R\bclientId\x12!\n" + + "\fclient_epoch\x18\x06 \x01(\x05R\vclientEpoch\x12&\n" + + "\x0fconnected_at_ns\x18\a \x01(\x03R\rconnectedAtNs\x12#\n" + + "\rfiler_address\x18\b \x01(\tR\ffilerAddress\"w\n" + "\x0fLogFileChunkRef\x12+\n" + "\x06chunks\x18\x01 \x03(\v2\x13.filer_pb.FileChunkR\x06chunks\x12\x1c\n" + "\n" + @@ -7190,7 +7394,7 @@ const file_filer_proto_rawDesc = "" + "\x13RELEASE_POSIX_OWNER\x10\x03\x12\x17\n" + "\x13RELEASE_FLOCK_OWNER\x10\x04\x12\x0e\n" + "\n" + - "KEEP_ALIVE\x10\x052\xbc\x16\n" + + "KEEP_ALIVE\x10\x052\xae\x17\n" + "\fSeaweedFiler\x12g\n" + "\x14LookupDirectoryEntry\x12%.filer_pb.LookupDirectoryEntryRequest\x1a&.filer_pb.LookupDirectoryEntryResponse\"\x00\x12N\n" + "\vListEntries\x12\x1c.filer_pb.ListEntriesRequest\x1a\x1d.filer_pb.ListEntriesResponse\"\x000\x01\x12L\n" + @@ -7215,7 +7419,8 @@ const file_filer_proto_rawDesc = "" + "\x15GetFilerConfiguration\x12&.filer_pb.GetFilerConfigurationRequest\x1a'.filer_pb.GetFilerConfigurationResponse\"\x00\x12f\n" + "\x13TraverseBfsMetadata\x12$.filer_pb.TraverseBfsMetadataRequest\x1a%.filer_pb.TraverseBfsMetadataResponse\"\x000\x01\x12`\n" + "\x11SubscribeMetadata\x12\".filer_pb.SubscribeMetadataRequest\x1a#.filer_pb.SubscribeMetadataResponse\"\x000\x01\x12e\n" + - "\x16SubscribeLocalMetadata\x12\".filer_pb.SubscribeMetadataRequest\x1a#.filer_pb.SubscribeMetadataResponse\"\x000\x01\x12:\n" + + "\x16SubscribeLocalMetadata\x12\".filer_pb.SubscribeMetadataRequest\x1a#.filer_pb.SubscribeMetadataResponse\"\x000\x01\x12p\n" + + "\x17ListMetadataSubscribers\x12(.filer_pb.ListMetadataSubscribersRequest\x1a).filer_pb.ListMetadataSubscribersResponse\"\x00\x12:\n" + "\x05KvGet\x12\x16.filer_pb.KvGetRequest\x1a\x17.filer_pb.KvGetResponse\"\x00\x12:\n" + "\x05KvPut\x12\x16.filer_pb.KvPutRequest\x1a\x17.filer_pb.KvPutResponse\"\x00\x12\x88\x01\n" + "\x1fCacheRemoteObjectToLocalCluster\x120.filer_pb.CacheRemoteObjectToLocalClusterRequest\x1a1.filer_pb.CacheRemoteObjectToLocalClusterResponse\"\x00\x12B\n" + @@ -7242,7 +7447,7 @@ func file_filer_proto_rawDescGZIP() []byte { } var file_filer_proto_enumTypes = make([]protoimpl.EnumInfo, 5) -var file_filer_proto_msgTypes = make([]protoimpl.MessageInfo, 96) +var file_filer_proto_msgTypes = make([]protoimpl.MessageInfo, 99) var file_filer_proto_goTypes = []any{ (SSEType)(0), // 0: filer_pb.SSEType (FilerError)(0), // 1: filer_pb.FilerError @@ -7304,54 +7509,57 @@ var file_filer_proto_goTypes = []any{ (*GetFilerConfigurationResponse)(nil), // 57: filer_pb.GetFilerConfigurationResponse (*SubscribeMetadataRequest)(nil), // 58: filer_pb.SubscribeMetadataRequest (*SubscribeMetadataResponse)(nil), // 59: filer_pb.SubscribeMetadataResponse - (*LogFileChunkRef)(nil), // 60: filer_pb.LogFileChunkRef - (*TraverseBfsMetadataRequest)(nil), // 61: filer_pb.TraverseBfsMetadataRequest - (*TraverseBfsMetadataResponse)(nil), // 62: filer_pb.TraverseBfsMetadataResponse - (*LogEntry)(nil), // 63: filer_pb.LogEntry - (*KeepConnectedRequest)(nil), // 64: filer_pb.KeepConnectedRequest - (*KeepConnectedResponse)(nil), // 65: filer_pb.KeepConnectedResponse - (*LocateBrokerRequest)(nil), // 66: filer_pb.LocateBrokerRequest - (*LocateBrokerResponse)(nil), // 67: filer_pb.LocateBrokerResponse - (*KvGetRequest)(nil), // 68: filer_pb.KvGetRequest - (*KvGetResponse)(nil), // 69: filer_pb.KvGetResponse - (*KvPutRequest)(nil), // 70: filer_pb.KvPutRequest - (*KvPutResponse)(nil), // 71: filer_pb.KvPutResponse - (*FilerConf)(nil), // 72: filer_pb.FilerConf - (*CacheRemoteObjectToLocalClusterRequest)(nil), // 73: filer_pb.CacheRemoteObjectToLocalClusterRequest - (*CacheRemoteObjectToLocalClusterResponse)(nil), // 74: filer_pb.CacheRemoteObjectToLocalClusterResponse - (*LockRequest)(nil), // 75: filer_pb.LockRequest - (*LockResponse)(nil), // 76: filer_pb.LockResponse - (*UnlockRequest)(nil), // 77: filer_pb.UnlockRequest - (*UnlockResponse)(nil), // 78: filer_pb.UnlockResponse - (*FindLockOwnerRequest)(nil), // 79: filer_pb.FindLockOwnerRequest - (*FindLockOwnerResponse)(nil), // 80: filer_pb.FindLockOwnerResponse - (*Lock)(nil), // 81: filer_pb.Lock - (*TransferLocksRequest)(nil), // 82: filer_pb.TransferLocksRequest - (*TransferLocksResponse)(nil), // 83: filer_pb.TransferLocksResponse - (*ReplicateLockRequest)(nil), // 84: filer_pb.ReplicateLockRequest - (*ReplicateLockResponse)(nil), // 85: filer_pb.ReplicateLockResponse - (*StreamMutateEntryRequest)(nil), // 86: filer_pb.StreamMutateEntryRequest - (*StreamMutateEntryResponse)(nil), // 87: filer_pb.StreamMutateEntryResponse - (*MountRegisterRequest)(nil), // 88: filer_pb.MountRegisterRequest - (*MountRegisterResponse)(nil), // 89: filer_pb.MountRegisterResponse - (*MountListRequest)(nil), // 90: filer_pb.MountListRequest - (*MountListResponse)(nil), // 91: filer_pb.MountListResponse - (*MountInfo)(nil), // 92: filer_pb.MountInfo - nil, // 93: filer_pb.Entry.ExtendedEntry - (*WriteCondition_Clause)(nil), // 94: filer_pb.WriteCondition.Clause - nil, // 95: filer_pb.ObjectMutation.SetExtendedEntry - nil, // 96: filer_pb.Recompute.CopyExtendedEntry - nil, // 97: filer_pb.UpdateEntryRequest.ExpectedExtendedEntry - nil, // 98: filer_pb.LookupVolumeResponse.LocationsMapEntry - (*LocateBrokerResponse_Resource)(nil), // 99: filer_pb.LocateBrokerResponse.Resource - (*FilerConf_PathConf)(nil), // 100: filer_pb.FilerConf.PathConf + (*ListMetadataSubscribersRequest)(nil), // 60: filer_pb.ListMetadataSubscribersRequest + (*ListMetadataSubscribersResponse)(nil), // 61: filer_pb.ListMetadataSubscribersResponse + (*MetadataSubscriber)(nil), // 62: filer_pb.MetadataSubscriber + (*LogFileChunkRef)(nil), // 63: filer_pb.LogFileChunkRef + (*TraverseBfsMetadataRequest)(nil), // 64: filer_pb.TraverseBfsMetadataRequest + (*TraverseBfsMetadataResponse)(nil), // 65: filer_pb.TraverseBfsMetadataResponse + (*LogEntry)(nil), // 66: filer_pb.LogEntry + (*KeepConnectedRequest)(nil), // 67: filer_pb.KeepConnectedRequest + (*KeepConnectedResponse)(nil), // 68: filer_pb.KeepConnectedResponse + (*LocateBrokerRequest)(nil), // 69: filer_pb.LocateBrokerRequest + (*LocateBrokerResponse)(nil), // 70: filer_pb.LocateBrokerResponse + (*KvGetRequest)(nil), // 71: filer_pb.KvGetRequest + (*KvGetResponse)(nil), // 72: filer_pb.KvGetResponse + (*KvPutRequest)(nil), // 73: filer_pb.KvPutRequest + (*KvPutResponse)(nil), // 74: filer_pb.KvPutResponse + (*FilerConf)(nil), // 75: filer_pb.FilerConf + (*CacheRemoteObjectToLocalClusterRequest)(nil), // 76: filer_pb.CacheRemoteObjectToLocalClusterRequest + (*CacheRemoteObjectToLocalClusterResponse)(nil), // 77: filer_pb.CacheRemoteObjectToLocalClusterResponse + (*LockRequest)(nil), // 78: filer_pb.LockRequest + (*LockResponse)(nil), // 79: filer_pb.LockResponse + (*UnlockRequest)(nil), // 80: filer_pb.UnlockRequest + (*UnlockResponse)(nil), // 81: filer_pb.UnlockResponse + (*FindLockOwnerRequest)(nil), // 82: filer_pb.FindLockOwnerRequest + (*FindLockOwnerResponse)(nil), // 83: filer_pb.FindLockOwnerResponse + (*Lock)(nil), // 84: filer_pb.Lock + (*TransferLocksRequest)(nil), // 85: filer_pb.TransferLocksRequest + (*TransferLocksResponse)(nil), // 86: filer_pb.TransferLocksResponse + (*ReplicateLockRequest)(nil), // 87: filer_pb.ReplicateLockRequest + (*ReplicateLockResponse)(nil), // 88: filer_pb.ReplicateLockResponse + (*StreamMutateEntryRequest)(nil), // 89: filer_pb.StreamMutateEntryRequest + (*StreamMutateEntryResponse)(nil), // 90: filer_pb.StreamMutateEntryResponse + (*MountRegisterRequest)(nil), // 91: filer_pb.MountRegisterRequest + (*MountRegisterResponse)(nil), // 92: filer_pb.MountRegisterResponse + (*MountListRequest)(nil), // 93: filer_pb.MountListRequest + (*MountListResponse)(nil), // 94: filer_pb.MountListResponse + (*MountInfo)(nil), // 95: filer_pb.MountInfo + nil, // 96: filer_pb.Entry.ExtendedEntry + (*WriteCondition_Clause)(nil), // 97: filer_pb.WriteCondition.Clause + nil, // 98: filer_pb.ObjectMutation.SetExtendedEntry + nil, // 99: filer_pb.Recompute.CopyExtendedEntry + nil, // 100: filer_pb.UpdateEntryRequest.ExpectedExtendedEntry + nil, // 101: filer_pb.LookupVolumeResponse.LocationsMapEntry + (*LocateBrokerResponse_Resource)(nil), // 102: filer_pb.LocateBrokerResponse.Resource + (*FilerConf_PathConf)(nil), // 103: filer_pb.FilerConf.PathConf } var file_filer_proto_depIdxs = []int32{ 10, // 0: filer_pb.LookupDirectoryEntryResponse.entry:type_name -> filer_pb.Entry 10, // 1: filer_pb.ListEntriesResponse.entry:type_name -> filer_pb.Entry 13, // 2: filer_pb.Entry.chunks:type_name -> filer_pb.FileChunk 16, // 3: filer_pb.Entry.attributes:type_name -> filer_pb.FuseAttributes - 93, // 4: filer_pb.Entry.extended:type_name -> filer_pb.Entry.ExtendedEntry + 96, // 4: filer_pb.Entry.extended:type_name -> filer_pb.Entry.ExtendedEntry 9, // 5: filer_pb.Entry.remote_entry:type_name -> filer_pb.RemoteEntry 10, // 6: filer_pb.FullEntry.entry:type_name -> filer_pb.Entry 10, // 7: filer_pb.EventNotification.old_entry:type_name -> filer_pb.Entry @@ -7362,12 +7570,12 @@ var file_filer_proto_depIdxs = []int32{ 13, // 12: filer_pb.FileChunkManifest.chunks:type_name -> filer_pb.FileChunk 10, // 13: filer_pb.CreateEntryRequest.entry:type_name -> filer_pb.Entry 18, // 14: filer_pb.CreateEntryRequest.condition:type_name -> filer_pb.WriteCondition - 94, // 15: filer_pb.WriteCondition.clauses:type_name -> filer_pb.WriteCondition.Clause + 97, // 15: filer_pb.WriteCondition.clauses:type_name -> filer_pb.WriteCondition.Clause 4, // 16: filer_pb.ObjectMutation.type:type_name -> filer_pb.ObjectMutation.Type 10, // 17: filer_pb.ObjectMutation.entry:type_name -> filer_pb.Entry - 95, // 18: filer_pb.ObjectMutation.set_extended:type_name -> filer_pb.ObjectMutation.SetExtendedEntry + 98, // 18: filer_pb.ObjectMutation.set_extended:type_name -> filer_pb.ObjectMutation.SetExtendedEntry 20, // 19: filer_pb.ObjectMutation.recompute:type_name -> filer_pb.Recompute - 96, // 20: filer_pb.Recompute.copy_extended:type_name -> filer_pb.Recompute.CopyExtendedEntry + 99, // 20: filer_pb.Recompute.copy_extended:type_name -> filer_pb.Recompute.CopyExtendedEntry 18, // 21: filer_pb.ObjectTransactionRequest.condition:type_name -> filer_pb.WriteCondition 19, // 22: filer_pb.ObjectTransactionRequest.mutations:type_name -> filer_pb.ObjectMutation 1, // 23: filer_pb.ObjectTransactionResponse.error_code:type_name -> filer_pb.FilerError @@ -7380,107 +7588,110 @@ var file_filer_proto_depIdxs = []int32{ 59, // 30: filer_pb.CreateEntryResponse.metadata_event:type_name -> filer_pb.SubscribeMetadataResponse 1, // 31: filer_pb.CreateEntryResponse.error_code:type_name -> filer_pb.FilerError 10, // 32: filer_pb.UpdateEntryRequest.entry:type_name -> filer_pb.Entry - 97, // 33: filer_pb.UpdateEntryRequest.expected_extended:type_name -> filer_pb.UpdateEntryRequest.ExpectedExtendedEntry + 100, // 33: filer_pb.UpdateEntryRequest.expected_extended:type_name -> filer_pb.UpdateEntryRequest.ExpectedExtendedEntry 59, // 34: filer_pb.UpdateEntryResponse.metadata_event:type_name -> filer_pb.SubscribeMetadataResponse 13, // 35: filer_pb.AppendToEntryRequest.chunks:type_name -> filer_pb.FileChunk 59, // 36: filer_pb.DeleteEntryResponse.metadata_event:type_name -> filer_pb.SubscribeMetadataResponse 12, // 37: filer_pb.StreamRenameEntryResponse.event_notification:type_name -> filer_pb.EventNotification 45, // 38: filer_pb.AssignVolumeResponse.location:type_name -> filer_pb.Location 45, // 39: filer_pb.Locations.locations:type_name -> filer_pb.Location - 98, // 40: filer_pb.LookupVolumeResponse.locations_map:type_name -> filer_pb.LookupVolumeResponse.LocationsMapEntry + 101, // 40: filer_pb.LookupVolumeResponse.locations_map:type_name -> filer_pb.LookupVolumeResponse.LocationsMapEntry 47, // 41: filer_pb.CollectionListResponse.collections:type_name -> filer_pb.Collection 12, // 42: filer_pb.SubscribeMetadataResponse.event_notification:type_name -> filer_pb.EventNotification 59, // 43: filer_pb.SubscribeMetadataResponse.events:type_name -> filer_pb.SubscribeMetadataResponse - 60, // 44: filer_pb.SubscribeMetadataResponse.log_file_refs:type_name -> filer_pb.LogFileChunkRef - 13, // 45: filer_pb.LogFileChunkRef.chunks:type_name -> filer_pb.FileChunk - 10, // 46: filer_pb.TraverseBfsMetadataResponse.entry:type_name -> filer_pb.Entry - 99, // 47: filer_pb.LocateBrokerResponse.resources:type_name -> filer_pb.LocateBrokerResponse.Resource - 100, // 48: filer_pb.FilerConf.locations:type_name -> filer_pb.FilerConf.PathConf - 10, // 49: filer_pb.CacheRemoteObjectToLocalClusterResponse.entry:type_name -> filer_pb.Entry - 59, // 50: filer_pb.CacheRemoteObjectToLocalClusterResponse.metadata_event:type_name -> filer_pb.SubscribeMetadataResponse - 81, // 51: filer_pb.TransferLocksRequest.locks:type_name -> filer_pb.Lock - 17, // 52: filer_pb.StreamMutateEntryRequest.create_request:type_name -> filer_pb.CreateEntryRequest - 29, // 53: filer_pb.StreamMutateEntryRequest.update_request:type_name -> filer_pb.UpdateEntryRequest - 35, // 54: filer_pb.StreamMutateEntryRequest.delete_request:type_name -> filer_pb.DeleteEntryRequest - 39, // 55: filer_pb.StreamMutateEntryRequest.rename_request:type_name -> filer_pb.StreamRenameEntryRequest - 28, // 56: filer_pb.StreamMutateEntryResponse.create_response:type_name -> filer_pb.CreateEntryResponse - 30, // 57: filer_pb.StreamMutateEntryResponse.update_response:type_name -> filer_pb.UpdateEntryResponse - 36, // 58: filer_pb.StreamMutateEntryResponse.delete_response:type_name -> filer_pb.DeleteEntryResponse - 40, // 59: filer_pb.StreamMutateEntryResponse.rename_response:type_name -> filer_pb.StreamRenameEntryResponse - 92, // 60: filer_pb.MountListResponse.mounts:type_name -> filer_pb.MountInfo - 3, // 61: filer_pb.WriteCondition.Clause.kind:type_name -> filer_pb.WriteCondition.Kind - 44, // 62: filer_pb.LookupVolumeResponse.LocationsMapEntry.value:type_name -> filer_pb.Locations - 5, // 63: filer_pb.SeaweedFiler.LookupDirectoryEntry:input_type -> filer_pb.LookupDirectoryEntryRequest - 7, // 64: filer_pb.SeaweedFiler.ListEntries:input_type -> filer_pb.ListEntriesRequest - 17, // 65: filer_pb.SeaweedFiler.CreateEntry:input_type -> filer_pb.CreateEntryRequest - 29, // 66: filer_pb.SeaweedFiler.UpdateEntry:input_type -> filer_pb.UpdateEntryRequest - 31, // 67: filer_pb.SeaweedFiler.TouchAccessTime:input_type -> filer_pb.TouchAccessTimeRequest - 33, // 68: filer_pb.SeaweedFiler.AppendToEntry:input_type -> filer_pb.AppendToEntryRequest - 35, // 69: filer_pb.SeaweedFiler.DeleteEntry:input_type -> filer_pb.DeleteEntryRequest - 21, // 70: filer_pb.SeaweedFiler.ObjectTransaction:input_type -> filer_pb.ObjectTransactionRequest - 26, // 71: filer_pb.SeaweedFiler.ObjectTransactionBatch:input_type -> filer_pb.ObjectTransactionBatchRequest - 24, // 72: filer_pb.SeaweedFiler.PosixLock:input_type -> filer_pb.PosixLockRequest - 37, // 73: filer_pb.SeaweedFiler.AtomicRenameEntry:input_type -> filer_pb.AtomicRenameEntryRequest - 39, // 74: filer_pb.SeaweedFiler.StreamRenameEntry:input_type -> filer_pb.StreamRenameEntryRequest - 86, // 75: filer_pb.SeaweedFiler.StreamMutateEntry:input_type -> filer_pb.StreamMutateEntryRequest - 41, // 76: filer_pb.SeaweedFiler.AssignVolume:input_type -> filer_pb.AssignVolumeRequest - 43, // 77: filer_pb.SeaweedFiler.LookupVolume:input_type -> filer_pb.LookupVolumeRequest - 48, // 78: filer_pb.SeaweedFiler.CollectionList:input_type -> filer_pb.CollectionListRequest - 50, // 79: filer_pb.SeaweedFiler.DeleteCollection:input_type -> filer_pb.DeleteCollectionRequest - 52, // 80: filer_pb.SeaweedFiler.Statistics:input_type -> filer_pb.StatisticsRequest - 54, // 81: filer_pb.SeaweedFiler.Ping:input_type -> filer_pb.PingRequest - 56, // 82: filer_pb.SeaweedFiler.GetFilerConfiguration:input_type -> filer_pb.GetFilerConfigurationRequest - 61, // 83: filer_pb.SeaweedFiler.TraverseBfsMetadata:input_type -> filer_pb.TraverseBfsMetadataRequest - 58, // 84: filer_pb.SeaweedFiler.SubscribeMetadata:input_type -> filer_pb.SubscribeMetadataRequest - 58, // 85: filer_pb.SeaweedFiler.SubscribeLocalMetadata:input_type -> filer_pb.SubscribeMetadataRequest - 68, // 86: filer_pb.SeaweedFiler.KvGet:input_type -> filer_pb.KvGetRequest - 70, // 87: filer_pb.SeaweedFiler.KvPut:input_type -> filer_pb.KvPutRequest - 73, // 88: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:input_type -> filer_pb.CacheRemoteObjectToLocalClusterRequest - 75, // 89: filer_pb.SeaweedFiler.DistributedLock:input_type -> filer_pb.LockRequest - 77, // 90: filer_pb.SeaweedFiler.DistributedUnlock:input_type -> filer_pb.UnlockRequest - 79, // 91: filer_pb.SeaweedFiler.FindLockOwner:input_type -> filer_pb.FindLockOwnerRequest - 82, // 92: filer_pb.SeaweedFiler.TransferLocks:input_type -> filer_pb.TransferLocksRequest - 84, // 93: filer_pb.SeaweedFiler.ReplicateLock:input_type -> filer_pb.ReplicateLockRequest - 88, // 94: filer_pb.SeaweedFiler.MountRegister:input_type -> filer_pb.MountRegisterRequest - 90, // 95: filer_pb.SeaweedFiler.MountList:input_type -> filer_pb.MountListRequest - 6, // 96: filer_pb.SeaweedFiler.LookupDirectoryEntry:output_type -> filer_pb.LookupDirectoryEntryResponse - 8, // 97: filer_pb.SeaweedFiler.ListEntries:output_type -> filer_pb.ListEntriesResponse - 28, // 98: filer_pb.SeaweedFiler.CreateEntry:output_type -> filer_pb.CreateEntryResponse - 30, // 99: filer_pb.SeaweedFiler.UpdateEntry:output_type -> filer_pb.UpdateEntryResponse - 32, // 100: filer_pb.SeaweedFiler.TouchAccessTime:output_type -> filer_pb.TouchAccessTimeResponse - 34, // 101: filer_pb.SeaweedFiler.AppendToEntry:output_type -> filer_pb.AppendToEntryResponse - 36, // 102: filer_pb.SeaweedFiler.DeleteEntry:output_type -> filer_pb.DeleteEntryResponse - 22, // 103: filer_pb.SeaweedFiler.ObjectTransaction:output_type -> filer_pb.ObjectTransactionResponse - 27, // 104: filer_pb.SeaweedFiler.ObjectTransactionBatch:output_type -> filer_pb.ObjectTransactionBatchResponse - 25, // 105: filer_pb.SeaweedFiler.PosixLock:output_type -> filer_pb.PosixLockResponse - 38, // 106: filer_pb.SeaweedFiler.AtomicRenameEntry:output_type -> filer_pb.AtomicRenameEntryResponse - 40, // 107: filer_pb.SeaweedFiler.StreamRenameEntry:output_type -> filer_pb.StreamRenameEntryResponse - 87, // 108: filer_pb.SeaweedFiler.StreamMutateEntry:output_type -> filer_pb.StreamMutateEntryResponse - 42, // 109: filer_pb.SeaweedFiler.AssignVolume:output_type -> filer_pb.AssignVolumeResponse - 46, // 110: filer_pb.SeaweedFiler.LookupVolume:output_type -> filer_pb.LookupVolumeResponse - 49, // 111: filer_pb.SeaweedFiler.CollectionList:output_type -> filer_pb.CollectionListResponse - 51, // 112: filer_pb.SeaweedFiler.DeleteCollection:output_type -> filer_pb.DeleteCollectionResponse - 53, // 113: filer_pb.SeaweedFiler.Statistics:output_type -> filer_pb.StatisticsResponse - 55, // 114: filer_pb.SeaweedFiler.Ping:output_type -> filer_pb.PingResponse - 57, // 115: filer_pb.SeaweedFiler.GetFilerConfiguration:output_type -> filer_pb.GetFilerConfigurationResponse - 62, // 116: filer_pb.SeaweedFiler.TraverseBfsMetadata:output_type -> filer_pb.TraverseBfsMetadataResponse - 59, // 117: filer_pb.SeaweedFiler.SubscribeMetadata:output_type -> filer_pb.SubscribeMetadataResponse - 59, // 118: filer_pb.SeaweedFiler.SubscribeLocalMetadata:output_type -> filer_pb.SubscribeMetadataResponse - 69, // 119: filer_pb.SeaweedFiler.KvGet:output_type -> filer_pb.KvGetResponse - 71, // 120: filer_pb.SeaweedFiler.KvPut:output_type -> filer_pb.KvPutResponse - 74, // 121: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:output_type -> filer_pb.CacheRemoteObjectToLocalClusterResponse - 76, // 122: filer_pb.SeaweedFiler.DistributedLock:output_type -> filer_pb.LockResponse - 78, // 123: filer_pb.SeaweedFiler.DistributedUnlock:output_type -> filer_pb.UnlockResponse - 80, // 124: filer_pb.SeaweedFiler.FindLockOwner:output_type -> filer_pb.FindLockOwnerResponse - 83, // 125: filer_pb.SeaweedFiler.TransferLocks:output_type -> filer_pb.TransferLocksResponse - 85, // 126: filer_pb.SeaweedFiler.ReplicateLock:output_type -> filer_pb.ReplicateLockResponse - 89, // 127: filer_pb.SeaweedFiler.MountRegister:output_type -> filer_pb.MountRegisterResponse - 91, // 128: filer_pb.SeaweedFiler.MountList:output_type -> filer_pb.MountListResponse - 96, // [96:129] is the sub-list for method output_type - 63, // [63:96] is the sub-list for method input_type - 63, // [63:63] is the sub-list for extension type_name - 63, // [63:63] is the sub-list for extension extendee - 0, // [0:63] is the sub-list for field type_name + 63, // 44: filer_pb.SubscribeMetadataResponse.log_file_refs:type_name -> filer_pb.LogFileChunkRef + 62, // 45: filer_pb.ListMetadataSubscribersResponse.subscribers:type_name -> filer_pb.MetadataSubscriber + 13, // 46: filer_pb.LogFileChunkRef.chunks:type_name -> filer_pb.FileChunk + 10, // 47: filer_pb.TraverseBfsMetadataResponse.entry:type_name -> filer_pb.Entry + 102, // 48: filer_pb.LocateBrokerResponse.resources:type_name -> filer_pb.LocateBrokerResponse.Resource + 103, // 49: filer_pb.FilerConf.locations:type_name -> filer_pb.FilerConf.PathConf + 10, // 50: filer_pb.CacheRemoteObjectToLocalClusterResponse.entry:type_name -> filer_pb.Entry + 59, // 51: filer_pb.CacheRemoteObjectToLocalClusterResponse.metadata_event:type_name -> filer_pb.SubscribeMetadataResponse + 84, // 52: filer_pb.TransferLocksRequest.locks:type_name -> filer_pb.Lock + 17, // 53: filer_pb.StreamMutateEntryRequest.create_request:type_name -> filer_pb.CreateEntryRequest + 29, // 54: filer_pb.StreamMutateEntryRequest.update_request:type_name -> filer_pb.UpdateEntryRequest + 35, // 55: filer_pb.StreamMutateEntryRequest.delete_request:type_name -> filer_pb.DeleteEntryRequest + 39, // 56: filer_pb.StreamMutateEntryRequest.rename_request:type_name -> filer_pb.StreamRenameEntryRequest + 28, // 57: filer_pb.StreamMutateEntryResponse.create_response:type_name -> filer_pb.CreateEntryResponse + 30, // 58: filer_pb.StreamMutateEntryResponse.update_response:type_name -> filer_pb.UpdateEntryResponse + 36, // 59: filer_pb.StreamMutateEntryResponse.delete_response:type_name -> filer_pb.DeleteEntryResponse + 40, // 60: filer_pb.StreamMutateEntryResponse.rename_response:type_name -> filer_pb.StreamRenameEntryResponse + 95, // 61: filer_pb.MountListResponse.mounts:type_name -> filer_pb.MountInfo + 3, // 62: filer_pb.WriteCondition.Clause.kind:type_name -> filer_pb.WriteCondition.Kind + 44, // 63: filer_pb.LookupVolumeResponse.LocationsMapEntry.value:type_name -> filer_pb.Locations + 5, // 64: filer_pb.SeaweedFiler.LookupDirectoryEntry:input_type -> filer_pb.LookupDirectoryEntryRequest + 7, // 65: filer_pb.SeaweedFiler.ListEntries:input_type -> filer_pb.ListEntriesRequest + 17, // 66: filer_pb.SeaweedFiler.CreateEntry:input_type -> filer_pb.CreateEntryRequest + 29, // 67: filer_pb.SeaweedFiler.UpdateEntry:input_type -> filer_pb.UpdateEntryRequest + 31, // 68: filer_pb.SeaweedFiler.TouchAccessTime:input_type -> filer_pb.TouchAccessTimeRequest + 33, // 69: filer_pb.SeaweedFiler.AppendToEntry:input_type -> filer_pb.AppendToEntryRequest + 35, // 70: filer_pb.SeaweedFiler.DeleteEntry:input_type -> filer_pb.DeleteEntryRequest + 21, // 71: filer_pb.SeaweedFiler.ObjectTransaction:input_type -> filer_pb.ObjectTransactionRequest + 26, // 72: filer_pb.SeaweedFiler.ObjectTransactionBatch:input_type -> filer_pb.ObjectTransactionBatchRequest + 24, // 73: filer_pb.SeaweedFiler.PosixLock:input_type -> filer_pb.PosixLockRequest + 37, // 74: filer_pb.SeaweedFiler.AtomicRenameEntry:input_type -> filer_pb.AtomicRenameEntryRequest + 39, // 75: filer_pb.SeaweedFiler.StreamRenameEntry:input_type -> filer_pb.StreamRenameEntryRequest + 89, // 76: filer_pb.SeaweedFiler.StreamMutateEntry:input_type -> filer_pb.StreamMutateEntryRequest + 41, // 77: filer_pb.SeaweedFiler.AssignVolume:input_type -> filer_pb.AssignVolumeRequest + 43, // 78: filer_pb.SeaweedFiler.LookupVolume:input_type -> filer_pb.LookupVolumeRequest + 48, // 79: filer_pb.SeaweedFiler.CollectionList:input_type -> filer_pb.CollectionListRequest + 50, // 80: filer_pb.SeaweedFiler.DeleteCollection:input_type -> filer_pb.DeleteCollectionRequest + 52, // 81: filer_pb.SeaweedFiler.Statistics:input_type -> filer_pb.StatisticsRequest + 54, // 82: filer_pb.SeaweedFiler.Ping:input_type -> filer_pb.PingRequest + 56, // 83: filer_pb.SeaweedFiler.GetFilerConfiguration:input_type -> filer_pb.GetFilerConfigurationRequest + 64, // 84: filer_pb.SeaweedFiler.TraverseBfsMetadata:input_type -> filer_pb.TraverseBfsMetadataRequest + 58, // 85: filer_pb.SeaweedFiler.SubscribeMetadata:input_type -> filer_pb.SubscribeMetadataRequest + 58, // 86: filer_pb.SeaweedFiler.SubscribeLocalMetadata:input_type -> filer_pb.SubscribeMetadataRequest + 60, // 87: filer_pb.SeaweedFiler.ListMetadataSubscribers:input_type -> filer_pb.ListMetadataSubscribersRequest + 71, // 88: filer_pb.SeaweedFiler.KvGet:input_type -> filer_pb.KvGetRequest + 73, // 89: filer_pb.SeaweedFiler.KvPut:input_type -> filer_pb.KvPutRequest + 76, // 90: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:input_type -> filer_pb.CacheRemoteObjectToLocalClusterRequest + 78, // 91: filer_pb.SeaweedFiler.DistributedLock:input_type -> filer_pb.LockRequest + 80, // 92: filer_pb.SeaweedFiler.DistributedUnlock:input_type -> filer_pb.UnlockRequest + 82, // 93: filer_pb.SeaweedFiler.FindLockOwner:input_type -> filer_pb.FindLockOwnerRequest + 85, // 94: filer_pb.SeaweedFiler.TransferLocks:input_type -> filer_pb.TransferLocksRequest + 87, // 95: filer_pb.SeaweedFiler.ReplicateLock:input_type -> filer_pb.ReplicateLockRequest + 91, // 96: filer_pb.SeaweedFiler.MountRegister:input_type -> filer_pb.MountRegisterRequest + 93, // 97: filer_pb.SeaweedFiler.MountList:input_type -> filer_pb.MountListRequest + 6, // 98: filer_pb.SeaweedFiler.LookupDirectoryEntry:output_type -> filer_pb.LookupDirectoryEntryResponse + 8, // 99: filer_pb.SeaweedFiler.ListEntries:output_type -> filer_pb.ListEntriesResponse + 28, // 100: filer_pb.SeaweedFiler.CreateEntry:output_type -> filer_pb.CreateEntryResponse + 30, // 101: filer_pb.SeaweedFiler.UpdateEntry:output_type -> filer_pb.UpdateEntryResponse + 32, // 102: filer_pb.SeaweedFiler.TouchAccessTime:output_type -> filer_pb.TouchAccessTimeResponse + 34, // 103: filer_pb.SeaweedFiler.AppendToEntry:output_type -> filer_pb.AppendToEntryResponse + 36, // 104: filer_pb.SeaweedFiler.DeleteEntry:output_type -> filer_pb.DeleteEntryResponse + 22, // 105: filer_pb.SeaweedFiler.ObjectTransaction:output_type -> filer_pb.ObjectTransactionResponse + 27, // 106: filer_pb.SeaweedFiler.ObjectTransactionBatch:output_type -> filer_pb.ObjectTransactionBatchResponse + 25, // 107: filer_pb.SeaweedFiler.PosixLock:output_type -> filer_pb.PosixLockResponse + 38, // 108: filer_pb.SeaweedFiler.AtomicRenameEntry:output_type -> filer_pb.AtomicRenameEntryResponse + 40, // 109: filer_pb.SeaweedFiler.StreamRenameEntry:output_type -> filer_pb.StreamRenameEntryResponse + 90, // 110: filer_pb.SeaweedFiler.StreamMutateEntry:output_type -> filer_pb.StreamMutateEntryResponse + 42, // 111: filer_pb.SeaweedFiler.AssignVolume:output_type -> filer_pb.AssignVolumeResponse + 46, // 112: filer_pb.SeaweedFiler.LookupVolume:output_type -> filer_pb.LookupVolumeResponse + 49, // 113: filer_pb.SeaweedFiler.CollectionList:output_type -> filer_pb.CollectionListResponse + 51, // 114: filer_pb.SeaweedFiler.DeleteCollection:output_type -> filer_pb.DeleteCollectionResponse + 53, // 115: filer_pb.SeaweedFiler.Statistics:output_type -> filer_pb.StatisticsResponse + 55, // 116: filer_pb.SeaweedFiler.Ping:output_type -> filer_pb.PingResponse + 57, // 117: filer_pb.SeaweedFiler.GetFilerConfiguration:output_type -> filer_pb.GetFilerConfigurationResponse + 65, // 118: filer_pb.SeaweedFiler.TraverseBfsMetadata:output_type -> filer_pb.TraverseBfsMetadataResponse + 59, // 119: filer_pb.SeaweedFiler.SubscribeMetadata:output_type -> filer_pb.SubscribeMetadataResponse + 59, // 120: filer_pb.SeaweedFiler.SubscribeLocalMetadata:output_type -> filer_pb.SubscribeMetadataResponse + 61, // 121: filer_pb.SeaweedFiler.ListMetadataSubscribers:output_type -> filer_pb.ListMetadataSubscribersResponse + 72, // 122: filer_pb.SeaweedFiler.KvGet:output_type -> filer_pb.KvGetResponse + 74, // 123: filer_pb.SeaweedFiler.KvPut:output_type -> filer_pb.KvPutResponse + 77, // 124: filer_pb.SeaweedFiler.CacheRemoteObjectToLocalCluster:output_type -> filer_pb.CacheRemoteObjectToLocalClusterResponse + 79, // 125: filer_pb.SeaweedFiler.DistributedLock:output_type -> filer_pb.LockResponse + 81, // 126: filer_pb.SeaweedFiler.DistributedUnlock:output_type -> filer_pb.UnlockResponse + 83, // 127: filer_pb.SeaweedFiler.FindLockOwner:output_type -> filer_pb.FindLockOwnerResponse + 86, // 128: filer_pb.SeaweedFiler.TransferLocks:output_type -> filer_pb.TransferLocksResponse + 88, // 129: filer_pb.SeaweedFiler.ReplicateLock:output_type -> filer_pb.ReplicateLockResponse + 92, // 130: filer_pb.SeaweedFiler.MountRegister:output_type -> filer_pb.MountRegisterResponse + 94, // 131: filer_pb.SeaweedFiler.MountList:output_type -> filer_pb.MountListResponse + 98, // [98:132] is the sub-list for method output_type + 64, // [64:98] is the sub-list for method input_type + 64, // [64:64] is the sub-list for extension type_name + 64, // [64:64] is the sub-list for extension extendee + 0, // [0:64] is the sub-list for field type_name } func init() { file_filer_proto_init() } @@ -7488,13 +7699,13 @@ func file_filer_proto_init() { if File_filer_proto != nil { return } - file_filer_proto_msgTypes[81].OneofWrappers = []any{ + file_filer_proto_msgTypes[84].OneofWrappers = []any{ (*StreamMutateEntryRequest_CreateRequest)(nil), (*StreamMutateEntryRequest_UpdateRequest)(nil), (*StreamMutateEntryRequest_DeleteRequest)(nil), (*StreamMutateEntryRequest_RenameRequest)(nil), } - file_filer_proto_msgTypes[82].OneofWrappers = []any{ + file_filer_proto_msgTypes[85].OneofWrappers = []any{ (*StreamMutateEntryResponse_CreateResponse)(nil), (*StreamMutateEntryResponse_UpdateResponse)(nil), (*StreamMutateEntryResponse_DeleteResponse)(nil), @@ -7506,7 +7717,7 @@ func file_filer_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_filer_proto_rawDesc), len(file_filer_proto_rawDesc)), NumEnums: 5, - NumMessages: 96, + NumMessages: 99, NumExtensions: 0, NumServices: 1, }, diff --git a/weed/pb/filer_pb/filer_grpc.pb.go b/weed/pb/filer_pb/filer_grpc.pb.go index f30e8d92a..196b3f5e4 100644 --- a/weed/pb/filer_pb/filer_grpc.pb.go +++ b/weed/pb/filer_pb/filer_grpc.pb.go @@ -42,6 +42,7 @@ const ( SeaweedFiler_TraverseBfsMetadata_FullMethodName = "/filer_pb.SeaweedFiler/TraverseBfsMetadata" SeaweedFiler_SubscribeMetadata_FullMethodName = "/filer_pb.SeaweedFiler/SubscribeMetadata" SeaweedFiler_SubscribeLocalMetadata_FullMethodName = "/filer_pb.SeaweedFiler/SubscribeLocalMetadata" + SeaweedFiler_ListMetadataSubscribers_FullMethodName = "/filer_pb.SeaweedFiler/ListMetadataSubscribers" SeaweedFiler_KvGet_FullMethodName = "/filer_pb.SeaweedFiler/KvGet" SeaweedFiler_KvPut_FullMethodName = "/filer_pb.SeaweedFiler/KvPut" SeaweedFiler_CacheRemoteObjectToLocalCluster_FullMethodName = "/filer_pb.SeaweedFiler/CacheRemoteObjectToLocalCluster" @@ -81,6 +82,9 @@ type SeaweedFilerClient interface { TraverseBfsMetadata(ctx context.Context, in *TraverseBfsMetadataRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[TraverseBfsMetadataResponse], error) SubscribeMetadata(ctx context.Context, in *SubscribeMetadataRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SubscribeMetadataResponse], error) SubscribeLocalMetadata(ctx context.Context, in *SubscribeMetadataRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[SubscribeMetadataResponse], error) + // List the metadata subscribers currently connected to this filer + // (FUSE mounts, S3, filer.sync, peer filers, ...). + ListMetadataSubscribers(ctx context.Context, in *ListMetadataSubscribersRequest, opts ...grpc.CallOption) (*ListMetadataSubscribersResponse, error) KvGet(ctx context.Context, in *KvGetRequest, opts ...grpc.CallOption) (*KvGetResponse, error) KvPut(ctx context.Context, in *KvPutRequest, opts ...grpc.CallOption) (*KvPutResponse, error) CacheRemoteObjectToLocalCluster(ctx context.Context, in *CacheRemoteObjectToLocalClusterRequest, opts ...grpc.CallOption) (*CacheRemoteObjectToLocalClusterResponse, error) @@ -382,6 +386,16 @@ func (c *seaweedFilerClient) SubscribeLocalMetadata(ctx context.Context, in *Sub // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type SeaweedFiler_SubscribeLocalMetadataClient = grpc.ServerStreamingClient[SubscribeMetadataResponse] +func (c *seaweedFilerClient) ListMetadataSubscribers(ctx context.Context, in *ListMetadataSubscribersRequest, opts ...grpc.CallOption) (*ListMetadataSubscribersResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + out := new(ListMetadataSubscribersResponse) + err := c.cc.Invoke(ctx, SeaweedFiler_ListMetadataSubscribers_FullMethodName, in, out, cOpts...) + if err != nil { + return nil, err + } + return out, nil +} + func (c *seaweedFilerClient) KvGet(ctx context.Context, in *KvGetRequest, opts ...grpc.CallOption) (*KvGetResponse, error) { cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(KvGetResponse) @@ -509,6 +523,9 @@ type SeaweedFilerServer interface { TraverseBfsMetadata(*TraverseBfsMetadataRequest, grpc.ServerStreamingServer[TraverseBfsMetadataResponse]) error SubscribeMetadata(*SubscribeMetadataRequest, grpc.ServerStreamingServer[SubscribeMetadataResponse]) error SubscribeLocalMetadata(*SubscribeMetadataRequest, grpc.ServerStreamingServer[SubscribeMetadataResponse]) error + // List the metadata subscribers currently connected to this filer + // (FUSE mounts, S3, filer.sync, peer filers, ...). + ListMetadataSubscribers(context.Context, *ListMetadataSubscribersRequest) (*ListMetadataSubscribersResponse, error) KvGet(context.Context, *KvGetRequest) (*KvGetResponse, error) KvPut(context.Context, *KvPutRequest) (*KvPutResponse, error) CacheRemoteObjectToLocalCluster(context.Context, *CacheRemoteObjectToLocalClusterRequest) (*CacheRemoteObjectToLocalClusterResponse, error) @@ -601,6 +618,9 @@ func (UnimplementedSeaweedFilerServer) SubscribeMetadata(*SubscribeMetadataReque func (UnimplementedSeaweedFilerServer) SubscribeLocalMetadata(*SubscribeMetadataRequest, grpc.ServerStreamingServer[SubscribeMetadataResponse]) error { return status.Error(codes.Unimplemented, "method SubscribeLocalMetadata not implemented") } +func (UnimplementedSeaweedFilerServer) ListMetadataSubscribers(context.Context, *ListMetadataSubscribersRequest) (*ListMetadataSubscribersResponse, error) { + return nil, status.Error(codes.Unimplemented, "method ListMetadataSubscribers not implemented") +} func (UnimplementedSeaweedFilerServer) KvGet(context.Context, *KvGetRequest) (*KvGetResponse, error) { return nil, status.Error(codes.Unimplemented, "method KvGet not implemented") } @@ -1020,6 +1040,24 @@ func _SeaweedFiler_SubscribeLocalMetadata_Handler(srv interface{}, stream grpc.S // This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. type SeaweedFiler_SubscribeLocalMetadataServer = grpc.ServerStreamingServer[SubscribeMetadataResponse] +func _SeaweedFiler_ListMetadataSubscribers_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListMetadataSubscribersRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(SeaweedFilerServer).ListMetadataSubscribers(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: SeaweedFiler_ListMetadataSubscribers_FullMethodName, + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(SeaweedFilerServer).ListMetadataSubscribers(ctx, req.(*ListMetadataSubscribersRequest)) + } + return interceptor(ctx, in, info, handler) +} + func _SeaweedFiler_KvGet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(KvGetRequest) if err := dec(in); err != nil { @@ -1275,6 +1313,10 @@ var SeaweedFiler_ServiceDesc = grpc.ServiceDesc{ MethodName: "GetFilerConfiguration", Handler: _SeaweedFiler_GetFilerConfiguration_Handler, }, + { + MethodName: "ListMetadataSubscribers", + Handler: _SeaweedFiler_ListMetadataSubscribers_Handler, + }, { MethodName: "KvGet", Handler: _SeaweedFiler_KvGet_Handler, diff --git a/weed/server/filer_grpc_server_sub_meta.go b/weed/server/filer_grpc_server_sub_meta.go index 678f3629b..adf0cb644 100644 --- a/weed/server/filer_grpc_server_sub_meta.go +++ b/weed/server/filer_grpc_server_sub_meta.go @@ -165,7 +165,7 @@ func (fs *FilerServer) SubscribeMetadata(req *filer_pb.SubscribeMetadataRequest, ctx := stream.Context() peerAddress := findClientAddress(ctx, 0) - isReplacing, alreadyKnown, clientName := fs.addClient("", req.ClientName, peerAddress, req.ClientId, req.ClientEpoch) + isReplacing, alreadyKnown, clientName := fs.addClient("", req.ClientName, peerAddress, req.PathPrefix, req.ClientId, req.ClientEpoch) if isReplacing { fs.filer.MetaAggregator.ListenersCond.Broadcast() // nudges the subscribers that are waiting } else if alreadyKnown { @@ -314,7 +314,7 @@ func (fs *FilerServer) SubscribeLocalMetadata(req *filer_pb.SubscribeMetadataReq // use negative client id to differentiate from addClient()/deleteClient() used in SubscribeMetadata() req.ClientId = -req.ClientId - isReplacing, alreadyKnown, clientName := fs.addClient("local", req.ClientName, peerAddress, req.ClientId, req.ClientEpoch) + isReplacing, alreadyKnown, clientName := fs.addClient("local", req.ClientName, peerAddress, req.PathPrefix, req.ClientId, req.ClientEpoch) if isReplacing { fs.listenersCond.Broadcast() // nudges the subscribers that are waiting } else if alreadyKnown { @@ -669,9 +669,9 @@ func (fs *FilerServer) eachEventNotificationFn(req *filer_pb.SubscribeMetadataRe } } -func (fs *FilerServer) addClient(prefix string, clientType string, clientAddress string, clientId int32, clientEpoch int32) (isReplacing, alreadyKnown bool, clientName string) { +func (fs *FilerServer) addClient(scope string, clientType string, clientAddress string, pathPrefix string, clientId int32, clientEpoch int32) (isReplacing, alreadyKnown bool, clientName string) { clientName = clientType + "@" + clientAddress - glog.V(0).Infof("+ %v listener %v clientId %v clientEpoch %v", prefix, clientName, clientId, clientEpoch) + glog.V(0).Infof("+ %v listener %v clientId %v clientEpoch %v", scope, clientName, clientId, clientEpoch) if clientId != 0 { fs.knownListenersLock.Lock() defer fs.knownListenersLock.Unlock() @@ -679,6 +679,18 @@ func (fs *FilerServer) addClient(prefix string, clientType string, clientAddress if !found || epoch < clientEpoch { fs.knownListeners[clientId] = clientEpoch isReplacing = true + if fs.subscribers == nil { + fs.subscribers = make(map[int32]*metadataSubscriber) + } + fs.subscribers[clientId] = &metadataSubscriber{ + clientName: clientName, + clientType: clientType, + address: clientAddress, + pathPrefix: pathPrefix, + clientId: clientId, + clientEpoch: clientEpoch, + connectedAtNs: time.Now().UnixNano(), + } } else { alreadyKnown = true } @@ -686,14 +698,15 @@ func (fs *FilerServer) addClient(prefix string, clientType string, clientAddress return } -func (fs *FilerServer) deleteClient(prefix string, clientName string, clientId int32, clientEpoch int32) { - glog.V(0).Infof("- %v listener %v clientId %v clientEpoch %v", prefix, clientName, clientId, clientEpoch) +func (fs *FilerServer) deleteClient(scope string, clientName string, clientId int32, clientEpoch int32) { + glog.V(0).Infof("- %v listener %v clientId %v clientEpoch %v", scope, clientName, clientId, clientEpoch) if clientId != 0 { fs.knownListenersLock.Lock() defer fs.knownListenersLock.Unlock() epoch, found := fs.knownListeners[clientId] if found && epoch <= clientEpoch { delete(fs.knownListeners, clientId) + delete(fs.subscribers, clientId) } } } diff --git a/weed/server/filer_grpc_server_subscribers.go b/weed/server/filer_grpc_server_subscribers.go new file mode 100644 index 000000000..e534c692a --- /dev/null +++ b/weed/server/filer_grpc_server_subscribers.go @@ -0,0 +1,63 @@ +package weed_server + +import ( + "context" + "sort" + + "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" +) + +// metadataSubscriber is the live record of one connected metadata subscriber +// (a FUSE mount, S3, filer.sync, peer filer, ...). It is created in addClient +// and removed in deleteClient, so the registry reflects currently-connected +// clients only. Guarded by FilerServer.knownListenersLock. +type metadataSubscriber struct { + clientName string // "@
    " + clientType string // e.g. "mount", "sw-vfs", "s3", "filer:" + address string + pathPrefix string + clientId int32 + clientEpoch int32 + connectedAtNs int64 +} + +// ListMetadataSubscribers returns the metadata subscribers currently connected +// to this filer, optionally filtered by client type. Each filer only knows its +// own subscribers, so cluster-wide callers query every filer and aggregate. +func (fs *FilerServer) ListMetadataSubscribers(ctx context.Context, req *filer_pb.ListMetadataSubscribersRequest) (*filer_pb.ListMetadataSubscribersResponse, error) { + typeFilter := make(map[string]bool, len(req.ClientTypes)) + for _, t := range req.ClientTypes { + typeFilter[t] = true + } + + filerAddress := string(fs.option.Host) + + fs.knownListenersLock.Lock() + subs := make([]*filer_pb.MetadataSubscriber, 0, len(fs.subscribers)) + for _, s := range fs.subscribers { + if len(typeFilter) > 0 && !typeFilter[s.clientType] { + continue + } + subs = append(subs, &filer_pb.MetadataSubscriber{ + ClientName: s.clientName, + ClientType: s.clientType, + Address: s.address, + PathPrefix: s.pathPrefix, + ClientId: s.clientId, + ClientEpoch: s.clientEpoch, + ConnectedAtNs: s.connectedAtNs, + FilerAddress: filerAddress, + }) + } + fs.knownListenersLock.Unlock() + + // Stable ordering so the admin page doesn't shuffle rows between refreshes. + sort.Slice(subs, func(i, j int) bool { + if subs[i].ClientName != subs[j].ClientName { + return subs[i].ClientName < subs[j].ClientName + } + return subs[i].PathPrefix < subs[j].PathPrefix + }) + + return &filer_pb.ListMetadataSubscribersResponse{Subscribers: subs}, nil +} diff --git a/weed/server/filer_server.go b/weed/server/filer_server.go index 64dbf3324..81cf80d7a 100644 --- a/weed/server/filer_server.go +++ b/weed/server/filer_server.go @@ -113,6 +113,9 @@ type FilerServer struct { // track known metadata listeners knownListenersLock sync.Mutex knownListeners map[int32]int32 + // live metadata subscribers (FUSE mounts, S3, peer filers, ...) keyed by + // clientId, guarded by knownListenersLock. Exposed via ListMetadataSubscribers. + subscribers map[int32]*metadataSubscriber // deduplicates concurrent remote object caching operations remoteCacheGroup singleflight.Group @@ -183,6 +186,7 @@ func NewFilerServer(defaultMux, readonlyMux *http.ServeMux, option *FilerOption) option: option, grpcDialOption: security.LoadClientTLS(util.GetViper(), "grpc.filer"), knownListeners: make(map[int32]int32), + subscribers: make(map[int32]*metadataSubscriber), inFlightDataLimitCond: sync.NewCond(new(sync.Mutex)), recentCopyRequests: make(map[string]recentCopyRequest), CredentialManager: option.CredentialManager,