From 2e51e1dab2a59cf96920f405bc54a0b5d7265ff7 Mon Sep 17 00:00:00 2001 From: chrislu Date: Sun, 10 Aug 2025 16:54:44 -0700 Subject: [PATCH] ec volume UI rendering version --- weed/admin/dash/ec_shard_management.go | 113 ++- weed/admin/dash/types.go | 14 + weed/admin/view/app/cluster_ec_volumes.templ | 27 + .../view/app/cluster_ec_volumes_templ.go | 240 +++-- weed/admin/view/app/ec_volume_details.templ | 92 +- .../admin/view/app/ec_volume_details_templ.go | 835 ++++++++++++------ weed/server/volume_grpc_erasure_coding.go | 24 +- weed/storage/store_ec.go | 24 +- weed/topology/topology_ec.go | 2 +- 9 files changed, 970 insertions(+), 401 deletions(-) diff --git a/weed/admin/dash/ec_shard_management.go b/weed/admin/dash/ec_shard_management.go index 556b970bc..02f78b9d5 100644 --- a/weed/admin/dash/ec_shard_management.go +++ b/weed/admin/dash/ec_shard_management.go @@ -280,21 +280,36 @@ func (s *AdminServer) GetClusterEcVolumes(page int, pageSize int, sortBy string, // Initialize volume data if needed if volumeData[volumeId] == nil { volumeData[volumeId] = &EcVolumeWithShards{ - VolumeID: volumeId, - Collection: ecShardInfo.Collection, - TotalShards: 0, - IsComplete: false, - MissingShards: []int{}, - ShardLocations: make(map[int]string), - ShardSizes: make(map[int]int64), - DataCenters: []string{}, - Servers: []string{}, - Racks: []string{}, + VolumeID: volumeId, + Collection: ecShardInfo.Collection, + TotalShards: 0, + IsComplete: false, + MissingShards: []int{}, + ShardLocations: make(map[int]string), + ShardSizes: make(map[int]int64), + DataCenters: []string{}, + Servers: []string{}, + Racks: []string{}, + Generations: []uint32{}, + ActiveGeneration: 0, + HasMultipleGenerations: false, } } volume := volumeData[volumeId] + // Track generation information + generationExists := false + for _, existingGen := range volume.Generations { + if existingGen == ecShardInfo.Generation { + generationExists = true + break + } + } + if !generationExists { + volume.Generations = append(volume.Generations, ecShardInfo.Generation) + } + // Track data centers and servers dcExists := false for _, existingDc := range volume.DataCenters { @@ -385,6 +400,33 @@ func (s *AdminServer) GetClusterEcVolumes(page int, pageSize int, sortBy string, } } + // Get active generation information from master for each volume + err = s.WithMasterClient(func(client master_pb.SeaweedClient) error { + for volumeId, volume := range volumeData { + // Look up active generation + resp, lookupErr := client.LookupEcVolume(context.Background(), &master_pb.LookupEcVolumeRequest{ + VolumeId: volumeId, + }) + if lookupErr == nil && resp != nil { + volume.ActiveGeneration = resp.ActiveGeneration + } + + // Sort generations and check for multiple generations + if len(volume.Generations) > 1 { + // Sort generations (oldest first) + for i := 0; i < len(volume.Generations); i++ { + for j := i + 1; j < len(volume.Generations); j++ { + if volume.Generations[i] > volume.Generations[j] { + volume.Generations[i], volume.Generations[j] = volume.Generations[j], volume.Generations[i] + } + } + } + volume.HasMultipleGenerations = true + } + } + return nil // Don't fail if lookup fails + }) + // Calculate completeness for each volume completeVolumes := 0 incompleteVolumes := 0 @@ -628,6 +670,7 @@ func (s *AdminServer) GetEcVolumeDetails(volumeID uint32, sortBy string, sortOrd ModifiedTime: 0, // Not available in current API EcIndexBits: ecShardInfo.EcIndexBits, ShardCount: getShardCount(ecShardInfo.EcIndexBits), + Generation: ecShardInfo.Generation, // Include generation information } shards = append(shards, ecShard) } @@ -741,6 +784,50 @@ func (s *AdminServer) GetEcVolumeDetails(volumeID uint32, sortBy string, sortOrd } } + // Analyze generation information + generationMap := make(map[uint32]bool) + generationShards := make(map[uint32][]uint32) + generationComplete := make(map[uint32]bool) + + // Collect all generations and group shards by generation + for _, shard := range shards { + generationMap[shard.Generation] = true + generationShards[shard.Generation] = append(generationShards[shard.Generation], shard.ShardID) + } + + // Convert generation map to sorted slice + var generations []uint32 + for gen := range generationMap { + generations = append(generations, gen) + } + + // Sort generations (oldest first) + for i := 0; i < len(generations); i++ { + for j := i + 1; j < len(generations); j++ { + if generations[i] > generations[j] { + generations[i], generations[j] = generations[j], generations[i] + } + } + } + + // Check completion status for each generation + for gen, shardIDs := range generationShards { + generationComplete[gen] = len(shardIDs) == erasure_coding.TotalShardsCount + } + + // Get active generation from master + var activeGeneration uint32 + err = s.WithMasterClient(func(client master_pb.SeaweedClient) error { + // Use LookupEcVolume to get active generation + resp, lookupErr := client.LookupEcVolume(context.Background(), &master_pb.LookupEcVolumeRequest{ + VolumeId: volumeID, + }) + if lookupErr == nil && resp != nil { + activeGeneration = resp.ActiveGeneration + } + return nil // Don't fail if lookup fails, just use generation 0 as default + }) + data := &EcVolumeDetailsData{ VolumeID: volumeID, Collection: collection, @@ -759,6 +846,12 @@ func (s *AdminServer) GetEcVolumeDetails(volumeID uint32, sortBy string, sortOrd DeleteCount: volumeHealth.DeleteCount, GarbageRatio: volumeHealth.GarbageRatio, + // Generation information + Generations: generations, + ActiveGeneration: activeGeneration, + GenerationShards: generationShards, + GenerationComplete: generationComplete, + SortBy: sortBy, SortOrder: sortOrder, } diff --git a/weed/admin/dash/types.go b/weed/admin/dash/types.go index 676d51e89..881638ad2 100644 --- a/weed/admin/dash/types.go +++ b/weed/admin/dash/types.go @@ -209,6 +209,9 @@ type EcShardWithInfo struct { ShardCount int `json:"shard_count"` // Number of shards this server has for this volume IsComplete bool `json:"is_complete"` // True if this volume has all 14 shards MissingShards []int `json:"missing_shards"` // List of missing shard IDs + + // Generation information + Generation uint32 `json:"generation"` // EC volume generation } // EcVolumeDetailsData represents the data for the EC volume details page @@ -231,6 +234,12 @@ type EcVolumeDetailsData struct { DeleteCount uint64 `json:"delete_count"` // Deleted file count GarbageRatio float64 `json:"garbage_ratio"` // Deletion ratio (0.0-1.0) + // Generation information + Generations []uint32 `json:"generations"` // All generations present for this volume + ActiveGeneration uint32 `json:"active_generation"` // Currently active generation + GenerationShards map[uint32][]uint32 `json:"generation_shards"` // Generation -> list of shard IDs + GenerationComplete map[uint32]bool `json:"generation_complete"` // Generation -> completion status + // Sorting SortBy string `json:"sort_by"` SortOrder string `json:"sort_order"` @@ -502,6 +511,11 @@ type EcVolumeWithShards struct { Servers []string `json:"servers"` Racks []string `json:"racks"` ModifiedTime int64 `json:"modified_time"` + + // Generation information + Generations []uint32 `json:"generations"` // All generations present for this volume + ActiveGeneration uint32 `json:"active_generation"` // Currently active generation + HasMultipleGenerations bool `json:"has_multiple_generations"` // True if volume has multiple generations } // ClusterEcVolumesData represents the response for clustered EC volumes view diff --git a/weed/admin/view/app/cluster_ec_volumes.templ b/weed/admin/view/app/cluster_ec_volumes.templ index c84da45ca..402ff10b1 100644 --- a/weed/admin/view/app/cluster_ec_volumes.templ +++ b/weed/admin/view/app/cluster_ec_volumes.templ @@ -191,6 +191,7 @@ templ ClusterEcVolumes(data dash.ClusterEcVolumesData) { Shard Size + Generation Shard Locations @@ -237,6 +238,9 @@ templ ClusterEcVolumes(data dash.ClusterEcVolumesData) { @displayShardSizes(volume.ShardSizes) + + @displayGenerationInfo(volume) + @displayVolumeDistribution(volume) @@ -732,6 +736,29 @@ templ displayEcVolumeStatus(volume dash.EcVolumeWithShards) { } } +// displayGenerationInfo shows generation information for a volume +templ displayGenerationInfo(volume dash.EcVolumeWithShards) { + if volume.HasMultipleGenerations { +
+ + Multi-Gen + +
+ + Active: G{fmt.Sprintf("%d", volume.ActiveGeneration)} + +
+ } else if len(volume.Generations) > 0 { + if volume.ActiveGeneration > 0 { + G{fmt.Sprintf("%d", volume.ActiveGeneration)} + } else { + G{fmt.Sprintf("%d", volume.Generations[0])} + } + } else { + G0 + } +} + // calculateVolumeDistributionSummary calculates and formats the distribution summary for a volume func calculateVolumeDistributionSummary(volume dash.EcVolumeWithShards) string { dataCenters := make(map[string]bool) diff --git a/weed/admin/view/app/cluster_ec_volumes_templ.go b/weed/admin/view/app/cluster_ec_volumes_templ.go index 932075106..33d60e611 100644 --- a/weed/admin/view/app/cluster_ec_volumes_templ.go +++ b/weed/admin/view/app/cluster_ec_volumes_templ.go @@ -362,7 +362,7 @@ func ClusterEcVolumes(data dash.ClusterEcVolumesData) templ.Component { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "
Shard SizeShard LocationsStatus ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "Shard SizeGenerationShard LocationsStatus ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -406,7 +406,7 @@ func ClusterEcVolumes(data dash.ClusterEcVolumesData) templ.Component { var templ_7745c5c3_Var15 string templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", volume.VolumeID)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 219, Col: 75} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 220, Col: 75} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var15)) if templ_7745c5c3_Err != nil { @@ -429,7 +429,7 @@ func ClusterEcVolumes(data dash.ClusterEcVolumesData) templ.Component { var templ_7745c5c3_Var16 string templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(volume.Collection) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 225, Col: 101} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 226, Col: 101} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var16)) if templ_7745c5c3_Err != nil { @@ -457,7 +457,7 @@ func ClusterEcVolumes(data dash.ClusterEcVolumesData) templ.Component { var templ_7745c5c3_Var17 string templ_7745c5c3_Var17, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d/14", volume.TotalShards)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 235, Col: 104} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 236, Col: 104} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) if templ_7745c5c3_Err != nil { @@ -475,7 +475,7 @@ func ClusterEcVolumes(data dash.ClusterEcVolumesData) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = displayVolumeDistribution(volume).Render(ctx, templ_7745c5c3_Buffer) + templ_7745c5c3_Err = displayGenerationInfo(volume).Render(ctx, templ_7745c5c3_Buffer) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -483,218 +483,226 @@ func ClusterEcVolumes(data dash.ClusterEcVolumesData) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } + templ_7745c5c3_Err = displayVolumeDistribution(volume).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } templ_7745c5c3_Err = displayEcVolumeStatus(volume).Render(ctx, templ_7745c5c3_Buffer) 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, 62, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.ShowDataCenterColumn { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } for i, dc := range volume.DataCenters { if i > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, ", ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, ", ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - 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 } var templ_7745c5c3_Var18 string templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(dc) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 252, Col: 85} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 256, Col: 85} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 66, "") 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 } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "\" title=\"View EC volume details\"> ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if !volume.IsComplete { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "\" title=\"Repair missing shards\">") 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, 72, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - 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 } if data.TotalPages > 1 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - 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 } @@ -725,52 +733,52 @@ func displayShardLocationsHTML(shardLocations map[int]string) templ.Component { } ctx = templ.ClearChildren(ctx) if len(shardLocations) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "No shards") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "No shards") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { for i, serverInfo := range groupShardsByServer(shardLocations) { if i > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "\" class=\"text-primary text-decoration-none\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var29 string templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(serverInfo.Server) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 392, Col: 24} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 396, Col: 24} } _, 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, 92, ": ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, ": ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var30 string templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(serverInfo.ShardRanges) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 394, Col: 37} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 398, Col: 37} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var30)) if templ_7745c5c3_Err != nil { @@ -805,7 +813,7 @@ func displayShardSizes(shardSizes map[int]int64) templ.Component { } ctx = templ.ClearChildren(ctx) if len(shardSizes) == 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "-") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "-") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -842,38 +850,38 @@ func renderShardSizesContent(shardSizes map[int]int64) templ.Component { } ctx = templ.ClearChildren(ctx) if areAllShardSizesSame(shardSizes) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, " ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var33 string templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(getCommonShardSize(shardSizes)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 412, Col: 60} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 416, Col: 60} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 95, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 96, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var34 string templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(formatIndividualShardSizes(shardSizes)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 416, Col: 43} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 420, Col: 43} } _, 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, 97, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1193,20 +1201,20 @@ func displayVolumeDistribution(volume dash.EcVolumeWithShards) templ.Component { templ_7745c5c3_Var35 = templ.NopComponent } ctx = templ.ClearChildren(ctx) - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var36 string templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(calculateVolumeDistributionSummary(volume)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 714, Col: 52} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 718, Col: 52} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 99, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1237,80 +1245,80 @@ func displayEcVolumeStatus(volume dash.EcVolumeWithShards) templ.Component { } ctx = templ.ClearChildren(ctx) if volume.IsComplete { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "Complete") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "Complete") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { if len(volume.MissingShards) > erasure_coding.DataShardsCount { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 101, "Critical (") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "Critical (") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var38 string templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(volume.MissingShards))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 724, Col: 130} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 728, Col: 130} } _, 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, 102, " missing)") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, " missing)") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else if len(volume.MissingShards) > (erasure_coding.DataShardsCount / 2) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "Degraded (") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "Degraded (") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var39 string templ_7745c5c3_Var39, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(volume.MissingShards))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 726, Col: 146} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 730, Col: 146} } _, 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, 104, " missing)") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, " missing)") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else if len(volume.MissingShards) > (erasure_coding.ParityShardsCount / 2) { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 105, "Incomplete (") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, "Incomplete (") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var40 string templ_7745c5c3_Var40, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(volume.MissingShards))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 728, Col: 139} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 732, Col: 139} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var40)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 106, " missing)") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, " missing)") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 107, "Minor Issues (") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "Minor Issues (") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var41 string templ_7745c5c3_Var41, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(volume.MissingShards))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 730, Col: 138} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 734, Col: 138} } _, 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, 108, " missing)") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, " missing)") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -1320,6 +1328,94 @@ func displayEcVolumeStatus(volume dash.EcVolumeWithShards) templ.Component { }) } +// displayGenerationInfo shows generation information for a volume +func displayGenerationInfo(volume dash.EcVolumeWithShards) 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_Var42 := templ.GetChildren(ctx) + if templ_7745c5c3_Var42 == nil { + templ_7745c5c3_Var42 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + if volume.HasMultipleGenerations { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 110, "
Multi-Gen
Active: G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var43 string + templ_7745c5c3_Var43, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", volume.ActiveGeneration)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 748, Col: 68} + } + _, 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, 111, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else if len(volume.Generations) > 0 { + if volume.ActiveGeneration > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 112, "G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var44 string + templ_7745c5c3_Var44, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", volume.ActiveGeneration)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 753, Col: 87} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var44)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 113, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 114, "G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var45 string + templ_7745c5c3_Var45, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", volume.Generations[0])) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/cluster_ec_volumes.templ`, Line: 755, Col: 85} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var45)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 115, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 116, "G0") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + return nil + }) +} + // calculateVolumeDistributionSummary calculates and formats the distribution summary for a volume func calculateVolumeDistributionSummary(volume dash.EcVolumeWithShards) string { dataCenters := make(map[string]bool) diff --git a/weed/admin/view/app/ec_volume_details.templ b/weed/admin/view/app/ec_volume_details.templ index 1c69b489d..c0fb32187 100644 --- a/weed/admin/view/app/ec_volume_details.templ +++ b/weed/admin/view/app/ec_volume_details.templ @@ -100,6 +100,38 @@ templ EcVolumeDetails(data dash.EcVolumeDetailsData) { {fmt.Sprintf("%d servers", len(data.Servers))} + + Active Generation: + + if data.ActiveGeneration > 0 { + {fmt.Sprintf("G%d", data.ActiveGeneration)} + } else { + G0 + } + if len(data.Generations) > 1 { + + Multi-Gen + + } + + + if len(data.Generations) > 1 { + + All Generations: + + for i, gen := range data.Generations { + if i > 0 { + + } + if gen == data.ActiveGeneration { + G{fmt.Sprintf("%d", gen)} (Active) + } else { + G{fmt.Sprintf("%d", gen)} + } + } + + + } Last Updated: @@ -219,21 +251,52 @@ templ EcVolumeDetails(data dash.EcVolumeDetailsData) { - +
-
Present Shards:
-
- for _, shard := range data.Shards { - {fmt.Sprintf("%02d", shard.ShardID)} + if len(data.Generations) > 1 { + + for _, gen := range data.Generations { +
+
+ if gen == data.ActiveGeneration { + G{fmt.Sprintf("%d", gen)} (Active) + } else { + G{fmt.Sprintf("%d", gen)} + } + {fmt.Sprintf("%d/14 shards", len(data.GenerationShards[gen]))} + if data.GenerationComplete[gen] { + + } else { + + } +
+
+ for _, shardID := range data.GenerationShards[gen] { + if gen == data.ActiveGeneration { + {fmt.Sprintf("%02d", shardID)} + } else { + {fmt.Sprintf("%02d", shardID)} + } + } +
+
} -
- if len(data.MissingShards) > 0 { -
Missing Shards:
+ } else { + +
Present Shards:
- for _, shardID := range data.MissingShards { - {fmt.Sprintf("%02d", shardID)} + for _, shard := range data.Shards { + {fmt.Sprintf("%02d", shard.ShardID)} }
+ if len(data.MissingShards) > 0 { +
Missing Shards:
+
+ for _, shardID := range data.MissingShards { + {fmt.Sprintf("%02d", shardID)} + } +
+ } }
@@ -310,6 +373,7 @@ templ EcVolumeDetails(data dash.EcVolumeDetailsData) { } + Generation Disk Type Shard Size Actions @@ -332,6 +396,14 @@ templ EcVolumeDetails(data dash.EcVolumeDetailsData) { {shard.Rack} + + if shard.Generation == data.ActiveGeneration { + G{fmt.Sprintf("%d", shard.Generation)} + + } else { + G{fmt.Sprintf("%d", shard.Generation)} + } + {shard.DiskType} diff --git a/weed/admin/view/app/ec_volume_details_templ.go b/weed/admin/view/app/ec_volume_details_templ.go index 5de7b75c6..0e9fed6f8 100644 --- a/weed/admin/view/app/ec_volume_details_templ.go +++ b/weed/admin/view/app/ec_volume_details_templ.go @@ -210,435 +210,698 @@ func EcVolumeDetails(data dash.EcVolumeDetailsData) templ.Component { if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Last Updated:") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 23, "Active Generation:") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var10 string - templ_7745c5c3_Var10, 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/ec_volume_details.templ`, Line: 106, Col: 104} + if data.ActiveGeneration > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var10 string + templ_7745c5c3_Var10, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("G%d", data.ActiveGeneration)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 107, Col: 109} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 26, "G0 ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var10)) + if len(data.Generations) > 1 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 27, "Multi-Gen") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 28, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 24, "
Volume Health
") + if len(data.Generations) > 1 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 29, "All Generations:") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for i, gen := range data.Generations { + if i > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 30, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 31, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if gen == data.ActiveGeneration { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "G") + 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", gen)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 127, Col: 99} + } + _, 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, 33, " (Active)") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var12 string + templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", gen)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 129, Col: 101} + } + _, 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, 35, "") + 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 + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "Last Updated:") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var13 string + templ_7745c5c3_Var13, 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/ec_volume_details.templ`, Line: 138, Col: 104} + } + _, 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, 38, "
Volume Health
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.TotalSize > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 25, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var11 string - templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinStringErrs(bytesToHumanReadableUint64(data.TotalSize - data.DeletedByteCount)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 128, Col: 107} - } - _, 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, 26, "
Active Bytes
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var12 string - templ_7745c5c3_Var12, templ_7745c5c3_Err = templ.JoinStringErrs(bytesToHumanReadableUint64(data.DeletedByteCount)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 136, Col: 90} - } - _, 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, 27, "
Deleted Bytes
") - 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", data.FileCount-data.DeleteCount)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 148, Col: 93} - } - _, 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, 28, "
Active Files
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "
") 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", data.DeleteCount)) + templ_7745c5c3_Var14, templ_7745c5c3_Err = templ.JoinStringErrs(bytesToHumanReadableUint64(data.TotalSize - data.DeletedByteCount)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 156, Col: 76} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 160, Col: 107} } _, 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, 29, "
Deleted Files
Active Bytes
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var15 string - templ_7745c5c3_Var15, templ_7745c5c3_Err = templruntime.SanitizeStyleAttributeValues("color: " + getGarbageRatioColor(data.GarbageRatio)) + templ_7745c5c3_Var15, templ_7745c5c3_Err = templ.JoinStringErrs(bytesToHumanReadableUint64(data.DeletedByteCount)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 167, Col: 132} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 168, Col: 90} } _, 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, 30, "\">") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
Deleted Bytes
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var16 string - templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f%%", data.GarbageRatio*100)) + templ_7745c5c3_Var16, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.FileCount-data.DeleteCount)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 168, Col: 87} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 180, Col: 93} } _, 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, 31, "
Garbage Ratio ") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
Active Files
") + 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", data.DeleteCount)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 188, Col: 76} + } + _, 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, 43, "
Deleted Files
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var19 string + templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%.1f%%", data.GarbageRatio*100)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 200, Col: 87} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "
Garbage Ratio ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if data.GarbageRatio >= 0.3 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 32, "
EC Vacuum Candidate
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "
EC Vacuum Candidate
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 33, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 34, "
Volume health metrics not available
This may be normal for newly created EC volumes
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "
Volume health metrics not available
This may be normal for newly created EC volumes
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 35, "
Shard Distribution

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "

Shard Distribution

") 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", data.TotalShards)) + var templ_7745c5c3_Var20 string + templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", data.TotalShards)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 204, Col: 98} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 236, Col: 98} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var17)) + _, 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, 36, "

Total Shards

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 50, "

Total Shards

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var18 string - templ_7745c5c3_Var18, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.DataCenters))) + var templ_7745c5c3_Var21 string + templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.DataCenters))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 210, Col: 103} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 242, Col: 103} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var18)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 37, "

Data Centers

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "

Data Centers

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var19 string - templ_7745c5c3_Var19, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.Servers))) + var templ_7745c5c3_Var22 string + templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(data.Servers))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 216, Col: 96} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 248, Col: 96} } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var19)) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 38, "

Servers
Present Shards:
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "Servers
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - for _, shard := range data.Shards { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 39, "") + if len(data.Generations) > 1 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var20 string - templ_7745c5c3_Var20, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shard.ShardID)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 227, Col: 108} - } - _, 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, 40, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 41, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(data.MissingShards) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 42, "
Missing Shards:
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, shardID := range data.MissingShards { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 43, "") + for _, gen := range data.Generations { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var21 string - templ_7745c5c3_Var21, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shardID)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 234, Col: 108} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var21)) - 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 - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 45, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 46, "
Shard Details
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if len(data.Shards) > 0 { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 47, "
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - for _, shard := range data.Shards { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 70, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "
Shard ID ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.SortBy == "shard_id" { - if data.SortOrder == "asc" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 48, "") + if gen == data.ActiveGeneration { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var23 string + templ_7745c5c3_Var23, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", gen)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 262, Col: 104} + } + _, 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, 56, " (Active) ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 49, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "G") 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, 51, "Server ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.SortBy == "server" { - if data.SortOrder == "asc" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 52, "") + var templ_7745c5c3_Var24 string + templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", gen)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 264, Col: 106} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var24)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 54, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 55, "Data Center ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.SortBy == "data_center" { - if data.SortOrder == "asc" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 57, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } else { - 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, 59, "Rack ") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - if data.SortBy == "rack" { - if data.SortOrder == "asc" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "Disk TypeShard SizeActions
") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var22 string - templ_7745c5c3_Var22, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shard.ShardID)) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 322, Col: 110} - } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var22)) - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } - var templ_7745c5c3_Var24 string - templ_7745c5c3_Var24, templ_7745c5c3_Err = templ.JoinStringErrs(shard.Server) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 326, Col: 81} - } - _, 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, 67, "") - if templ_7745c5c3_Err != nil { - return templ_7745c5c3_Err - } var templ_7745c5c3_Var25 string - templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(shard.DataCenter) + templ_7745c5c3_Var25, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d/14 shards", len(data.GenerationShards[gen]))) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 330, Col: 103} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 266, Col: 101} } _, 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, 68, "") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 59, " ") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var26 string - templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(shard.Rack) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 333, Col: 99} + if data.GenerationComplete[gen] { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 60, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } } - _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "
") + for _, shardID := range data.GenerationShards[gen] { + if gen == data.ActiveGeneration { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 63, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var26 string + templ_7745c5c3_Var26, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shardID)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 276, Col: 118} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var26)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 64, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 65, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var27 string + templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shardID)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 278, Col: 120} + } + _, 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, 66, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 67, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - var templ_7745c5c3_Var27 string - templ_7745c5c3_Var27, templ_7745c5c3_Err = templ.JoinStringErrs(shard.DiskType) - if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 336, Col: 83} - } - _, 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, 70, "") + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 68, "
Present Shards:
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, shard := range data.Shards { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 69, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var28 string - templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(bytesToHumanReadableUint64(shard.Size)) + templ_7745c5c3_Var28, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shard.ShardID)) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 339, Col: 110} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 289, Col: 112} } _, 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, 71, "
Volume Server
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 71, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if len(data.MissingShards) > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 72, "
Missing Shards:
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, shardID := range data.MissingShards { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 73, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var29 string + templ_7745c5c3_Var29, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shardID)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 296, Col: 112} + } + _, 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, 74, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 75, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 76, "
Shard Details
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if len(data.Shards) > 0 { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 77, "
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, shard := range data.Shards { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 94, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 108, "
Shard ID ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if data.SortBy == "shard_id" { + if data.SortOrder == "asc" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 78, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 79, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 80, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 81, "Server ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if data.SortBy == "server" { + if data.SortOrder == "asc" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 82, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 83, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 84, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 85, "Data Center ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if data.SortBy == "data_center" { + if data.SortOrder == "asc" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 86, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 87, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 88, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 89, "Rack ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if data.SortBy == "rack" { + if data.SortOrder == "asc" { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 90, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 91, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 92, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 93, "GenerationDisk TypeShard SizeActions
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var30 string + templ_7745c5c3_Var30, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%02d", shard.ShardID)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 386, Col: 110} + } + _, 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, 95, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var32 string + templ_7745c5c3_Var32, templ_7745c5c3_Err = templ.JoinStringErrs(shard.Server) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 390, Col: 81} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var32)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 97, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var33 string + templ_7745c5c3_Var33, templ_7745c5c3_Err = templ.JoinStringErrs(shard.DataCenter) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 394, Col: 103} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var33)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 98, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var34 string + templ_7745c5c3_Var34, templ_7745c5c3_Err = templ.JoinStringErrs(shard.Rack) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 397, Col: 99} + } + _, 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, 99, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if shard.Generation == data.ActiveGeneration { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 100, "G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var35 string + templ_7745c5c3_Var35, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", shard.Generation)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 401, Col: 116} + } + _, 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, 101, " ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 102, "G") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var36 string + templ_7745c5c3_Var36, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", shard.Generation)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 404, Col: 118} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var36)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 103, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 104, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var37 string + templ_7745c5c3_Var37, templ_7745c5c3_Err = templ.JoinStringErrs(shard.DiskType) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 408, Col: 83} + } + _, 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, 105, "") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var38 string + templ_7745c5c3_Var38, templ_7745c5c3_Err = templ.JoinStringErrs(bytesToHumanReadableUint64(shard.Size)) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `view/app/ec_volume_details.templ`, Line: 411, Col: 110} + } + _, 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, 106, "Volume Server
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 74, "
No EC shards found

This volume may not be EC encoded yet.

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 109, "
No EC shards found

This volume may not be EC encoded yet.

") 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, 110, "") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/weed/server/volume_grpc_erasure_coding.go b/weed/server/volume_grpc_erasure_coding.go index 32446bf90..f66e8eace 100644 --- a/weed/server/volume_grpc_erasure_coding.go +++ b/weed/server/volume_grpc_erasure_coding.go @@ -58,7 +58,8 @@ func isGenerationCompatible(actualGeneration, requestedGeneration uint32) bool { // VolumeEcShardsGenerate generates the .ecx and .ec00 ~ .ec13 files func (vs *VolumeServer) VolumeEcShardsGenerate(ctx context.Context, req *volume_server_pb.VolumeEcShardsGenerateRequest) (*volume_server_pb.VolumeEcShardsGenerateResponse, error) { - glog.V(0).Infof("VolumeEcShardsGenerate: %v", req) + glog.V(0).Infof("VolumeEcShardsGenerate volume %d generation %d collection %s", + req.VolumeId, req.Generation, req.Collection) v := vs.store.GetVolume(needle.VolumeId(req.VolumeId)) if v == nil { @@ -176,7 +177,8 @@ func (vs *VolumeServer) VolumeEcShardsRebuild(ctx context.Context, req *volume_s // VolumeEcShardsCopy copy the .ecx and some ec data slices func (vs *VolumeServer) VolumeEcShardsCopy(ctx context.Context, req *volume_server_pb.VolumeEcShardsCopyRequest) (*volume_server_pb.VolumeEcShardsCopyResponse, error) { - glog.V(0).Infof("VolumeEcShardsCopy: %v", req) + glog.V(0).Infof("VolumeEcShardsCopy volume %d generation %d shards %v from %s collection %s", + req.VolumeId, req.Generation, req.ShardIds, req.SourceDataNode, req.Collection) var location *storage.DiskLocation @@ -342,15 +344,16 @@ func checkEcVolumeStatus(bName string, location *storage.DiskLocation) (hasEcxFi func (vs *VolumeServer) VolumeEcShardsMount(ctx context.Context, req *volume_server_pb.VolumeEcShardsMountRequest) (*volume_server_pb.VolumeEcShardsMountResponse, error) { - glog.V(0).Infof("VolumeEcShardsMount: %v", req) + glog.V(0).Infof("VolumeEcShardsMount volume %d generation %d shards %v collection %s", + req.VolumeId, req.Generation, req.ShardIds, req.Collection) for _, shardId := range req.ShardIds { err := vs.store.MountEcShards(req.Collection, needle.VolumeId(req.VolumeId), erasure_coding.ShardId(shardId), req.Generation) if err != nil { - glog.Errorf("ec shard mount %v: %v", req, err) + glog.Errorf("ec shard mount %d.%d generation %d: %v", req.VolumeId, shardId, req.Generation, err) } else { - glog.V(2).Infof("ec shard mount %v", req) + glog.V(2).Infof("ec shard mount %d.%d generation %d success", req.VolumeId, shardId, req.Generation) } if err != nil { @@ -363,15 +366,16 @@ func (vs *VolumeServer) VolumeEcShardsMount(ctx context.Context, req *volume_ser func (vs *VolumeServer) VolumeEcShardsUnmount(ctx context.Context, req *volume_server_pb.VolumeEcShardsUnmountRequest) (*volume_server_pb.VolumeEcShardsUnmountResponse, error) { - glog.V(0).Infof("VolumeEcShardsUnmount: %v", req) + glog.V(0).Infof("VolumeEcShardsUnmount volume %d generation %d shards %v", + req.VolumeId, req.Generation, req.ShardIds) for _, shardId := range req.ShardIds { err := vs.store.UnmountEcShards(needle.VolumeId(req.VolumeId), erasure_coding.ShardId(shardId), req.Generation) if err != nil { - glog.Errorf("ec shard unmount %v: %v", req, err) + glog.Errorf("ec shard unmount %d.%d generation %d: %v", req.VolumeId, shardId, req.Generation, err) } else { - glog.V(2).Infof("ec shard unmount %v", req) + glog.V(2).Infof("ec shard unmount %d.%d generation %d success", req.VolumeId, shardId, req.Generation) } if err != nil { @@ -386,7 +390,7 @@ func (vs *VolumeServer) VolumeEcShardRead(req *volume_server_pb.VolumeEcShardRea ecVolume, found := vs.store.FindEcVolume(needle.VolumeId(req.VolumeId)) if !found { - return fmt.Errorf("VolumeEcShardRead not found ec volume id %d", req.VolumeId) + return fmt.Errorf("VolumeEcShardRead not found ec volume id %d (requested generation %d)", req.VolumeId, req.Generation) } // Validate generation matches with mixed-version compatibility @@ -397,7 +401,7 @@ func (vs *VolumeServer) VolumeEcShardRead(req *volume_server_pb.VolumeEcShardRea } ecShard, found := ecVolume.FindEcVolumeShard(erasure_coding.ShardId(req.ShardId)) if !found { - return fmt.Errorf("not found ec shard %d.%d", req.VolumeId, req.ShardId) + return fmt.Errorf("not found ec shard %d.%d generation %d", req.VolumeId, req.ShardId, ecVolume.Generation) } if req.FileKey != 0 { diff --git a/weed/storage/store_ec.go b/weed/storage/store_ec.go index 6aa6cb6cf..eb10e5ae1 100644 --- a/weed/storage/store_ec.go +++ b/weed/storage/store_ec.go @@ -61,7 +61,7 @@ func (s *Store) CollectErasureCodingHeartbeat() *master_pb.Heartbeat { func (s *Store) MountEcShards(collection string, vid needle.VolumeId, shardId erasure_coding.ShardId, generation uint32) error { for diskId, location := range s.Locations { if ecVolume, err := location.LoadEcShard(collection, vid, shardId, generation); err == nil { - glog.V(0).Infof("MountEcShards %d.%d on disk ID %d", vid, shardId, diskId) + glog.V(0).Infof("MountEcShards %d.%d generation %d on disk ID %d", vid, shardId, generation, diskId) var shardBits erasure_coding.ShardBits @@ -82,7 +82,7 @@ func (s *Store) MountEcShards(collection string, vid needle.VolumeId, shardId er } } - return fmt.Errorf("MountEcShards %d.%d not found on disk", vid, shardId) + return fmt.Errorf("MountEcShards %d.%d generation %d not found on disk", vid, shardId, generation) } func (s *Store) UnmountEcShards(vid needle.VolumeId, shardId erasure_coding.ShardId, generation uint32) error { @@ -105,12 +105,12 @@ func (s *Store) UnmountEcShards(vid needle.VolumeId, shardId erasure_coding.Shar location := s.Locations[diskId] if deleted := location.UnloadEcShard(vid, shardId); deleted { - glog.V(0).Infof("UnmountEcShards %d.%d", vid, shardId) + glog.V(0).Infof("UnmountEcShards %d.%d generation %d", vid, shardId, generation) s.DeletedEcShardsChan <- message return nil } - return fmt.Errorf("UnmountEcShards %d.%d not found on disk", vid, shardId) + return fmt.Errorf("UnmountEcShards %d.%d generation %d not found on disk", vid, shardId, generation) } func (s *Store) findEcShard(vid needle.VolumeId, shardId erasure_coding.ShardId) (diskId uint32, shard *erasure_coding.EcVolumeShard, found bool) { @@ -164,7 +164,7 @@ func (s *Store) ReadEcShardNeedle(vid needle.VolumeId, n *needle.Needle, onReadS onReadSizeFn(size) } - glog.V(3).Infof("read ec volume %d offset %d size %d intervals:%+v", vid, offset.ToActualOffset(), size, intervals) + glog.V(3).Infof("read ec volume %d generation %d offset %d size %d intervals:%+v", vid, localEcVolume.Generation, offset.ToActualOffset(), size, intervals) if len(intervals) > 1 { glog.V(3).Infof("ReadEcShardNeedle needle id %s intervals:%+v", n.String(), intervals) @@ -185,7 +185,7 @@ func (s *Store) ReadEcShardNeedle(vid needle.VolumeId, n *needle.Needle, onReadS return len(bytes), nil } } - return 0, fmt.Errorf("ec shard %d not found", vid) + return 0, fmt.Errorf("ec volume %d not found", vid) } func (s *Store) readEcShardIntervals(vid needle.VolumeId, needleId types.NeedleId, ecVolume *erasure_coding.EcVolume, intervals []erasure_coding.Interval) (data []byte, is_deleted bool, err error) { @@ -218,7 +218,7 @@ func (s *Store) readOneEcShardInterval(needleId types.NeedleId, ecVolume *erasur var readSize int if readSize, err = shard.ReadAt(data, actualOffset); err != nil { if readSize != int(interval.Size) { - glog.V(0).Infof("read local ec shard %d.%d offset %d: %v", ecVolume.VolumeId, shardId, actualOffset, err) + glog.V(0).Infof("read local ec shard %d.%d generation %d offset %d: %v", ecVolume.VolumeId, shardId, ecVolume.Generation, actualOffset, err) return } } @@ -233,7 +233,7 @@ func (s *Store) readOneEcShardInterval(needleId types.NeedleId, ecVolume *erasur if err == nil { return } - glog.V(0).Infof("clearing ec shard %d.%d locations: %v", ecVolume.VolumeId, shardId, err) + glog.V(0).Infof("clearing ec shard %d.%d generation %d locations: %v", ecVolume.VolumeId, shardId, ecVolume.Generation, err) } // try reading by recovering from other shards @@ -241,7 +241,7 @@ func (s *Store) readOneEcShardInterval(needleId types.NeedleId, ecVolume *erasur if err == nil { return } - glog.V(0).Infof("recover ec shard %d.%d : %v", ecVolume.VolumeId, shardId, err) + glog.V(0).Infof("recover ec shard %d.%d generation %d : %v", ecVolume.VolumeId, shardId, ecVolume.Generation, err) } return } @@ -317,16 +317,16 @@ func (s *Store) cachedLookupEcShardLocations(ecVolume *erasure_coding.EcVolume) func (s *Store) readRemoteEcShardInterval(sourceDataNodes []pb.ServerAddress, needleId types.NeedleId, vid needle.VolumeId, shardId erasure_coding.ShardId, buf []byte, offset int64, generation uint32) (n int, is_deleted bool, err error) { if len(sourceDataNodes) == 0 { - return 0, false, fmt.Errorf("failed to find ec shard %d.%d", vid, shardId) + return 0, false, fmt.Errorf("failed to find ec shard %d.%d generation %d", vid, shardId, generation) } for _, sourceDataNode := range sourceDataNodes { - glog.V(3).Infof("read remote ec shard %d.%d from %s", vid, shardId, sourceDataNode) + glog.V(3).Infof("read remote ec shard %d.%d generation %d from %s", vid, shardId, generation, sourceDataNode) n, is_deleted, err = s.doReadRemoteEcShardInterval(sourceDataNode, needleId, vid, shardId, buf, offset, generation) if err == nil { return } - glog.V(1).Infof("read remote ec shard %d.%d from %s: %v", vid, shardId, sourceDataNode, err) + glog.V(1).Infof("read remote ec shard %d.%d generation %d from %s: %v", vid, shardId, generation, sourceDataNode, err) } return diff --git a/weed/topology/topology_ec.go b/weed/topology/topology_ec.go index 7fa751e5e..7e0d59eb2 100644 --- a/weed/topology/topology_ec.go +++ b/weed/topology/topology_ec.go @@ -162,7 +162,7 @@ func (t *Topology) RegisterEcShards(ecShardInfos *erasure_coding.EcVolumeInfo, d } func (t *Topology) UnRegisterEcShards(ecShardInfos *erasure_coding.EcVolumeInfo, dn *DataNode) { - glog.Infof("removing ec shard info:%+v", ecShardInfos) + glog.Infof("removing ec shard info volume %d generation %d shards %v", ecShardInfos.VolumeId, ecShardInfos.Generation, ecShardInfos.ShardIds()) t.ecShardMapLock.Lock() defer t.ecShardMapLock.Unlock()