snapshot of https://github.com/seaweedfs/seaweedfs.git (master, 2026-09-16; blobs > 131072B omitted)
Some checks failed
go: build dev binaries / cleanup (push) Successful in 4s
Codespell / Check for spelling errors (push) Failing after 3s
docker: build dev containers / build-rust-binaries (amd64, x86_64-unknown-linux-musl) (push) Failing after 3s
docker: build dev containers / build-dev-containers (push) Has been skipped
docker: build dev containers / build-rust-binaries (arm64, true, aarch64-unknown-linux-musl) (push) Failing after 3s
End to End / FUSE Mount (push) Failing after 2s
EC Integration Tests / EC Integration Tests (push) Failing after 30s
FUSE DLM Integration Tests / FUSE DLM Integration Tests (push) Failing after 3s
FUSE Volume Server Failover Tests / FUSE Volume Server Failover (push) Failing after 3s
FUSE Integration Tests / FUSE Integration Testing (push) Failing after 2s
FUSE P2P Peer Chunk Sharing Integration Tests / FUSE P2P Peer Chunk Sharing (push) Failing after 3s
go: build binary / Go Vet (push) Failing after 2s
go: build binary / Go Vet 32-bit (push) Failing after 3s
go: build binary / Build (push) Failing after 4s
go: build binary / Build cross-platform (freebsd/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (darwin/arm64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/arm64) (push) Failing after 3s
go: build binary / Test (push) Failing after 2s
go: build binary / Test 32-bit (push) Failing after 3s
helm: lint and test charts / lint-test (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (11) (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (17) (push) Failing after 3s
go: build dev binaries / build_dev_linux_windows (amd64, linux) (push) Failing after 2s
go: build dev binaries / build_dev_linux_windows (amd64, windows) (push) Failing after 3s
go: build dev binaries / build_dev_darwin (amd64, darwin) (push) Has been skipped
go: build dev binaries / build_dev_darwin (arm64, darwin) (push) Has been skipped
Java Client Unit Tests / Java Unit Tests (11) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (17) (push) Failing after 2s
Java Client Unit Tests / Java Unit Tests (21) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (8) (push) Failing after 3s
Kafka Quick Test (Load Test with Schema Registry) / Kafka Client Load Test (Quick) (push) Failing after 3s
Kafka Gateway Tests / Kafka Unit Tests (unit-tests-1) (push) Failing after 11s
Kafka Gateway Tests / Kafka Integration Tests (Critical) (integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka End-to-End Tests (with SMQ) (e2e-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Consumer Group Tests (Highly Isolated) (consumer-group-1) (push) Failing after 2s
Kafka Gateway Tests / Kafka Client Compatibility (with SMQ) (client-compat-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka SMQ Integration Tests (Full Stack) (smq-integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Protocol Tests (Isolated) (protocol-1) (push) Failing after 3s
KMS Tests / KMS Provider Integration Tests (push) Failing after 2s
KMS Tests / S3 KMS End-to-End Tests (push) Failing after 3s
Master Cold Start Tests / Master Cold Start Tests (push) Failing after 4s
Metadata Subscribe Integration Tests / Metadata Subscribe Integration Tests (push) Failing after 3s
Multi-Master Tests / Multi-Master Failover Tests (push) Failing after 3s
Performance / CPU and Heap Profile (push) Failing after 2s
Performance / S3 Read/Write Benchmark (rust volume) (push) Failing after 3s
pjdfstest POSIX Compliance / pjdfstest (push) Failing after 2s
Plugin Worker Integration Tests / Plugin Worker: erasure_coding (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: vacuum (push) Failing after 3s
Rust Volume Server Tests / Rust Integration Tests (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 1) (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 1) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 3) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Distributed Tests (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Performance Tests (push) Failing after 3s
Performance / Throughput Benchmark (go volume) (push) Failing after 3s
Performance / Throughput Benchmark (rust volume) (push) Failing after 2s
Performance / S3 Read/Write Benchmark (go volume) (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: volume_balance (push) Failing after 3s
PostgreSQL Gateway Tests / PostgreSQL Basic Tests (push) Failing after 3s
Rust Volume Server Tests / Rust Unit Tests (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 3) (push) Failing after 3s
Rust Plugin Worker Tests / Rust Plugin Worker Build and Unit Tests (push) Failing after 3s
rust: build dev volume server binaries / cleanup (push) Successful in 3s
S3 ETag and ACL Tests / S3 ETag + ACL Integration Tests (push) Failing after 3s
S3 IAM Integration Tests / IAM Unit Tests (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (advanced) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (basic) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (group) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (policy-enforcement) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (sts) (push) Failing after 4s
S3 Keycloak Integration Tests / S3 Keycloak Integration Tests (push) Failing after 3s
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.11) (push) Failing after 3s
S3 PyArrow Parquet Tests / Go Unit Tests (Implicit Directory) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.12) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-amd64, x86_64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-arm64, aarch64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-linux (linux-amd64, x86_64-unknown-linux-gnu) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.9) (push) Has been cancelled
S3 Proxy Signature Tests / S3 Proxy Signature Verification Tests (push) Has been cancelled
S3 SDK V2 Route Disambiguation Tests / S3 SDK V2 Routing Tests (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (quick) (push) Has been cancelled
S3 SSE Tests / S3 SSE Compatibility Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Metadata Persistence Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Copy Operations Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Multipart Upload Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Performance Test (push) Has been cancelled
S3 SSE Tests / S3 Volume Encryption Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (comprehensive) (push) Has been cancelled
Spark Integration Tests / Spark Integration Tests (push) Failing after 2s
Telemetry Integration Tests / telemetry-integration-test (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 1) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 1) (push) Failing after 3s
Ceph S3 tests / Basic S3 tests (KV store) (push) Has been cancelled
Ceph S3 tests / S3 Versioning & Object Lock tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Unit Tests (push) Failing after 3s
Ceph S3 tests / S3 CORS tests (push) Has been cancelled
Ceph S3 tests / SeaweedFS Custom S3 Copy tests (push) Has been cancelled
Ceph S3 tests / Basic S3 tests (SQL store) (push) Has been cancelled
test s3 over https using aws-cli / awscli-tests (push) Has been cancelled
TLS Rotation Integration Tests / TLS Rotation Integration Tests (push) Has been cancelled
Vacuum Integration Tests / Vacuum Integration Tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Variables Integration Tests (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (advanced-policy) (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (basic-policy) (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (contextual-policy) (push) Failing after 4s
S3 Policy Integration Tests / Trusted Proxy Detection Tests (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Shell Integration Tests (push) Failing after 3s
Samba on FUSE Integration / samba-integration (push) Failing after 2s
SFTP Integration Tests / SFTP Integration Testing (push) Failing after 3s
terraform: validate and test modules / fmt, validate, plan-level tests (push) Failing after 3s
terraform: validate and test modules / local cluster smoke test (real weed) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 3) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 2) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 2) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 3) (push) Failing after 5s
mount: windows conformance / WinFsp conformance (push) Has been cancelled
mount: windows / Mount on Windows (push) Has been cancelled
Some checks failed
go: build dev binaries / cleanup (push) Successful in 4s
Codespell / Check for spelling errors (push) Failing after 3s
docker: build dev containers / build-rust-binaries (amd64, x86_64-unknown-linux-musl) (push) Failing after 3s
docker: build dev containers / build-dev-containers (push) Has been skipped
docker: build dev containers / build-rust-binaries (arm64, true, aarch64-unknown-linux-musl) (push) Failing after 3s
End to End / FUSE Mount (push) Failing after 2s
EC Integration Tests / EC Integration Tests (push) Failing after 30s
FUSE DLM Integration Tests / FUSE DLM Integration Tests (push) Failing after 3s
FUSE Volume Server Failover Tests / FUSE Volume Server Failover (push) Failing after 3s
FUSE Integration Tests / FUSE Integration Testing (push) Failing after 2s
FUSE P2P Peer Chunk Sharing Integration Tests / FUSE P2P Peer Chunk Sharing (push) Failing after 3s
go: build binary / Go Vet (push) Failing after 2s
go: build binary / Go Vet 32-bit (push) Failing after 3s
go: build binary / Build (push) Failing after 4s
go: build binary / Build cross-platform (freebsd/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/amd64) (push) Failing after 3s
go: build binary / Build cross-platform (darwin/arm64) (push) Failing after 3s
go: build binary / Build cross-platform (windows/arm64) (push) Failing after 3s
go: build binary / Test (push) Failing after 2s
go: build binary / Test 32-bit (push) Failing after 3s
helm: lint and test charts / lint-test (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (11) (push) Failing after 3s
Java Client Integration Tests / Java Integration Tests (17) (push) Failing after 3s
go: build dev binaries / build_dev_linux_windows (amd64, linux) (push) Failing after 2s
go: build dev binaries / build_dev_linux_windows (amd64, windows) (push) Failing after 3s
go: build dev binaries / build_dev_darwin (amd64, darwin) (push) Has been skipped
go: build dev binaries / build_dev_darwin (arm64, darwin) (push) Has been skipped
Java Client Unit Tests / Java Unit Tests (11) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (17) (push) Failing after 2s
Java Client Unit Tests / Java Unit Tests (21) (push) Failing after 3s
Java Client Unit Tests / Java Unit Tests (8) (push) Failing after 3s
Kafka Quick Test (Load Test with Schema Registry) / Kafka Client Load Test (Quick) (push) Failing after 3s
Kafka Gateway Tests / Kafka Unit Tests (unit-tests-1) (push) Failing after 11s
Kafka Gateway Tests / Kafka Integration Tests (Critical) (integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka End-to-End Tests (with SMQ) (e2e-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Consumer Group Tests (Highly Isolated) (consumer-group-1) (push) Failing after 2s
Kafka Gateway Tests / Kafka Client Compatibility (with SMQ) (client-compat-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka SMQ Integration Tests (Full Stack) (smq-integration-1) (push) Failing after 3s
Kafka Gateway Tests / Kafka Protocol Tests (Isolated) (protocol-1) (push) Failing after 3s
KMS Tests / KMS Provider Integration Tests (push) Failing after 2s
KMS Tests / S3 KMS End-to-End Tests (push) Failing after 3s
Master Cold Start Tests / Master Cold Start Tests (push) Failing after 4s
Metadata Subscribe Integration Tests / Metadata Subscribe Integration Tests (push) Failing after 3s
Multi-Master Tests / Multi-Master Failover Tests (push) Failing after 3s
Performance / CPU and Heap Profile (push) Failing after 2s
Performance / S3 Read/Write Benchmark (rust volume) (push) Failing after 3s
pjdfstest POSIX Compliance / pjdfstest (push) Failing after 2s
Plugin Worker Integration Tests / Plugin Worker: erasure_coding (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: vacuum (push) Failing after 3s
Rust Volume Server Tests / Rust Integration Tests (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 1) (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 1) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 2) (push) Failing after 3s
Rust Volume Server Tests / Go Tests with Rust Volume (grpc - Shard 3) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Distributed Tests (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Performance Tests (push) Failing after 3s
Performance / Throughput Benchmark (go volume) (push) Failing after 3s
Performance / Throughput Benchmark (rust volume) (push) Failing after 2s
Performance / S3 Read/Write Benchmark (go volume) (push) Failing after 3s
Plugin Worker Integration Tests / Plugin Worker: volume_balance (push) Failing after 3s
PostgreSQL Gateway Tests / PostgreSQL Basic Tests (push) Failing after 3s
Rust Volume Server Tests / Rust Unit Tests (push) Failing after 2s
Rust Volume Server Tests / Go Tests with Rust Volume (http - Shard 3) (push) Failing after 3s
Rust Plugin Worker Tests / Rust Plugin Worker Build and Unit Tests (push) Failing after 3s
rust: build dev volume server binaries / cleanup (push) Successful in 3s
S3 ETag and ACL Tests / S3 ETag + ACL Integration Tests (push) Failing after 3s
S3 IAM Integration Tests / IAM Unit Tests (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (advanced) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (basic) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (group) (push) Failing after 3s
S3 IAM Integration Tests / S3 IAM Integration Tests (policy-enforcement) (push) Failing after 2s
S3 IAM Integration Tests / S3 IAM Integration Tests (sts) (push) Failing after 4s
S3 Keycloak Integration Tests / S3 Keycloak Integration Tests (push) Failing after 3s
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.11) (push) Failing after 3s
S3 PyArrow Parquet Tests / Go Unit Tests (Implicit Directory) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.12) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-amd64, x86_64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-darwin (darwin-arm64, aarch64-apple-darwin) (push) Has been cancelled
rust: build dev volume server binaries / build-rust-volume-dev-linux (linux-amd64, x86_64-unknown-linux-gnu) (push) Has been cancelled
S3 PyArrow Parquet Tests / PyArrow Parquet Tests (Python 3.9) (push) Has been cancelled
S3 Proxy Signature Tests / S3 Proxy Signature Verification Tests (push) Has been cancelled
S3 SDK V2 Route Disambiguation Tests / S3 SDK V2 Routing Tests (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (quick) (push) Has been cancelled
S3 SSE Tests / S3 SSE Compatibility Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Metadata Persistence Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Copy Operations Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Multipart Upload Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Performance Test (push) Has been cancelled
S3 SSE Tests / S3 Volume Encryption Test (push) Has been cancelled
S3 SSE Tests / S3 SSE Integration Tests (comprehensive) (push) Has been cancelled
Spark Integration Tests / Spark Integration Tests (push) Failing after 2s
Telemetry Integration Tests / telemetry-integration-test (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 1) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 1) (push) Failing after 3s
Ceph S3 tests / Basic S3 tests (KV store) (push) Has been cancelled
Ceph S3 tests / S3 Versioning & Object Lock tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Unit Tests (push) Failing after 3s
Ceph S3 tests / S3 CORS tests (push) Has been cancelled
Ceph S3 tests / SeaweedFS Custom S3 Copy tests (push) Has been cancelled
Ceph S3 tests / Basic S3 tests (SQL store) (push) Has been cancelled
test s3 over https using aws-cli / awscli-tests (push) Has been cancelled
TLS Rotation Integration Tests / TLS Rotation Integration Tests (push) Has been cancelled
Vacuum Integration Tests / Vacuum Integration Tests (push) Has been cancelled
S3 Policy Integration Tests / S3 Policy Variables Integration Tests (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (advanced-policy) (push) Failing after 3s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (basic-policy) (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Enforcement Integration Tests (contextual-policy) (push) Failing after 4s
S3 Policy Integration Tests / Trusted Proxy Detection Tests (push) Failing after 2s
S3 Policy Integration Tests / S3 Policy Shell Integration Tests (push) Failing after 3s
Samba on FUSE Integration / samba-integration (push) Failing after 2s
SFTP Integration Tests / SFTP Integration Testing (push) Failing after 3s
terraform: validate and test modules / fmt, validate, plan-level tests (push) Failing after 3s
terraform: validate and test modules / local cluster smoke test (real weed) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 3) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (grpc - Shard 2) (push) Failing after 3s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 2) (push) Failing after 2s
Volume Server Integration Tests / Volume Server Integration Tests (http - Shard 3) (push) Failing after 5s
mount: windows conformance / WinFsp conformance (push) Has been cancelled
mount: windows / Mount on Windows (push) Has been cancelled
This commit is contained in:
339
weed/admin/dash/volume_export.go
Normal file
339
weed/admin/dash/volume_export.go
Normal file
@@ -0,0 +1,339 @@
|
||||
package dash
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/pb/master_pb"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage"
|
||||
"github.com/seaweedfs/seaweedfs/weed/storage/erasure_coding"
|
||||
)
|
||||
|
||||
// VolumeListExport is a full-cluster volume report, downloadable from the admin
|
||||
// UI as JSON. It mirrors the topology the `volume.list` shell command walks
|
||||
// (data center -> rack -> node -> disk -> volumes / EC shards) and adds derived
|
||||
// fields the shell command does not print: garbage and fullness ratios, a
|
||||
// human-readable modified time, remote-tiering keys, per-disk capacity counts,
|
||||
// and the cluster-wide duplicate-volume-id scan.
|
||||
type VolumeListExport struct {
|
||||
GeneratedAt time.Time `json:"generated_at"`
|
||||
VolumeSizeLimitMB uint64 `json:"volume_size_limit_mb"`
|
||||
FilterCollection string `json:"filter_collection,omitempty"`
|
||||
Totals VolumeExportTotals `json:"totals"`
|
||||
DuplicateVolumeIds []DuplicateVolumeId `json:"duplicate_volume_ids"`
|
||||
DataCenters []*ExportDataCenter `json:"data_centers"`
|
||||
}
|
||||
|
||||
// VolumeExportTotals aggregates the included records. TotalSize sums normal
|
||||
// volume sizes and EC shard sizes (matching volume.list's statistics); the
|
||||
// file/delete totals cover normal volumes only.
|
||||
type VolumeExportTotals struct {
|
||||
VolumeCount int `json:"volume_count"`
|
||||
EcShardCount int `json:"ec_shard_count"`
|
||||
TotalSize uint64 `json:"total_size"`
|
||||
FileCount uint64 `json:"file_count"`
|
||||
DeletedFileCount uint64 `json:"deleted_file_count"`
|
||||
DeletedBytes uint64 `json:"deleted_bytes"`
|
||||
}
|
||||
|
||||
// DuplicateVolumeId flags a volume id that appears under more than one
|
||||
// collection, where collection.delete or a bare-id operation is dangerous.
|
||||
type DuplicateVolumeId struct {
|
||||
VolumeId uint32 `json:"volume_id"`
|
||||
Collections []string `json:"collections"`
|
||||
}
|
||||
|
||||
type ExportDataCenter struct {
|
||||
Id string `json:"id"`
|
||||
Racks []*ExportRack `json:"racks"`
|
||||
}
|
||||
|
||||
type ExportRack struct {
|
||||
Id string `json:"id"`
|
||||
Nodes []*ExportNode `json:"nodes"`
|
||||
}
|
||||
|
||||
type ExportNode struct {
|
||||
Id string `json:"id"`
|
||||
GrpcPort uint32 `json:"grpc_port,omitempty"`
|
||||
Disks []*ExportDisk `json:"disks"`
|
||||
}
|
||||
|
||||
// ExportDisk capacity counts describe the whole physical disk; the Volumes /
|
||||
// EcShards lists are filtered when a collection filter is active.
|
||||
type ExportDisk struct {
|
||||
DiskType string `json:"disk_type"`
|
||||
DiskId uint32 `json:"disk_id"`
|
||||
VolumeCount int64 `json:"volume_count"`
|
||||
MaxVolumeCount int64 `json:"max_volume_count"`
|
||||
ActiveVolumeCount int64 `json:"active_volume_count"`
|
||||
FreeVolumeCount int64 `json:"free_volume_count"`
|
||||
RemoteVolumeCount int64 `json:"remote_volume_count"`
|
||||
Volumes []*ExportVolume `json:"volumes,omitempty"`
|
||||
EcShards []*ExportEcShard `json:"ec_shards,omitempty"`
|
||||
}
|
||||
|
||||
type ExportVolume struct {
|
||||
Id uint32 `json:"id"`
|
||||
Collection string `json:"collection"`
|
||||
Size uint64 `json:"size"`
|
||||
FileCount uint64 `json:"file_count"`
|
||||
DeleteCount uint64 `json:"delete_count"`
|
||||
DeletedByteCount uint64 `json:"deleted_byte_count"`
|
||||
GarbageRatio float64 `json:"garbage_ratio"`
|
||||
FullnessRatio float64 `json:"fullness_ratio"`
|
||||
ReplicaPlacement string `json:"replica_placement"`
|
||||
Version uint32 `json:"version"`
|
||||
Ttl string `json:"ttl"`
|
||||
ReadOnly bool `json:"read_only"`
|
||||
CompactRevision uint32 `json:"compact_revision"`
|
||||
ModifiedAtSecond int64 `json:"modified_at_second"`
|
||||
ModifiedAt string `json:"modified_at,omitempty"`
|
||||
DiskType string `json:"disk_type"`
|
||||
DiskId uint32 `json:"disk_id"`
|
||||
RemoteStorageName string `json:"remote_storage_name,omitempty"`
|
||||
}
|
||||
|
||||
type ExportEcShard struct {
|
||||
Id uint32 `json:"id"`
|
||||
Collection string `json:"collection"`
|
||||
ShardIds []uint32 `json:"shard_ids"`
|
||||
ShardSizes []int64 `json:"shard_sizes"`
|
||||
TotalSize int64 `json:"total_size"`
|
||||
FileCount uint64 `json:"file_count"`
|
||||
DeleteCount uint64 `json:"delete_count"`
|
||||
DiskType string `json:"disk_type"`
|
||||
DiskId uint32 `json:"disk_id"`
|
||||
ExpireAtSec uint64 `json:"expire_at_sec,omitempty"`
|
||||
}
|
||||
|
||||
// ExportClusterVolumeList builds a full-cluster volume report from the master
|
||||
// topology. A non-empty collection limits the listed volumes and EC shards to
|
||||
// that collection; the duplicate-id scan always covers the whole cluster.
|
||||
// generatedAt is passed in so the report is deterministic and testable.
|
||||
func (s *AdminServer) ExportClusterVolumeList(ctx context.Context, collection string, generatedAt time.Time) (*VolumeListExport, error) {
|
||||
export := &VolumeListExport{
|
||||
GeneratedAt: generatedAt,
|
||||
FilterCollection: collection,
|
||||
DuplicateVolumeIds: []DuplicateVolumeId{},
|
||||
DataCenters: []*ExportDataCenter{},
|
||||
}
|
||||
|
||||
err := s.WithMasterClient(func(client master_pb.SeaweedClient) error {
|
||||
resp, err := pb.CollectVolumeList(ctx, client, &master_pb.VolumeListRequest{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
export.VolumeSizeLimitMB = resp.VolumeSizeLimitMb
|
||||
topo := resp.TopologyInfo
|
||||
if topo == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
volumeSizeLimit := resp.VolumeSizeLimitMb * 1024 * 1024
|
||||
export.DuplicateVolumeIds = findDuplicateVolumeIdsForExport(topo)
|
||||
|
||||
dcs := append([]*master_pb.DataCenterInfo(nil), topo.DataCenterInfos...)
|
||||
sort.Slice(dcs, func(i, j int) bool { return dcs[i].Id < dcs[j].Id })
|
||||
for _, dc := range dcs {
|
||||
exportDc := &ExportDataCenter{Id: dc.Id, Racks: []*ExportRack{}}
|
||||
racks := append([]*master_pb.RackInfo(nil), dc.RackInfos...)
|
||||
sort.Slice(racks, func(i, j int) bool { return racks[i].Id < racks[j].Id })
|
||||
for _, rack := range racks {
|
||||
exportRack := &ExportRack{Id: rack.Id, Nodes: []*ExportNode{}}
|
||||
nodes := append([]*master_pb.DataNodeInfo(nil), rack.DataNodeInfos...)
|
||||
sort.Slice(nodes, func(i, j int) bool { return nodes[i].Id < nodes[j].Id })
|
||||
for _, node := range nodes {
|
||||
exportNode := &ExportNode{Id: node.Id, GrpcPort: node.GrpcPort, Disks: []*ExportDisk{}}
|
||||
for _, diskType := range sortedDiskTypes(node.DiskInfos) {
|
||||
// Split per physical disk like volume.list so DiskId is meaningful.
|
||||
for _, diskInfo := range node.DiskInfos[diskType].SplitByPhysicalDisk() {
|
||||
if disk := buildExportDisk(diskInfo, collection, volumeSizeLimit, &export.Totals); disk != nil {
|
||||
exportNode.Disks = append(exportNode.Disks, disk)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(exportNode.Disks) > 0 {
|
||||
exportRack.Nodes = append(exportRack.Nodes, exportNode)
|
||||
}
|
||||
}
|
||||
if len(exportRack.Nodes) > 0 {
|
||||
exportDc.Racks = append(exportDc.Racks, exportRack)
|
||||
}
|
||||
}
|
||||
if len(exportDc.Racks) > 0 {
|
||||
export.DataCenters = append(export.DataCenters, exportDc)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return export, nil
|
||||
}
|
||||
|
||||
func sortedDiskTypes(diskInfos map[string]*master_pb.DiskInfo) []string {
|
||||
types := make([]string, 0, len(diskInfos))
|
||||
for t := range diskInfos {
|
||||
types = append(types, t)
|
||||
}
|
||||
sort.Strings(types)
|
||||
return types
|
||||
}
|
||||
|
||||
// buildExportDisk returns nil when the disk holds nothing matching the filter.
|
||||
func buildExportDisk(diskInfo *master_pb.DiskInfo, collection string, volumeSizeLimit uint64, totals *VolumeExportTotals) *ExportDisk {
|
||||
diskType := diskInfo.Type
|
||||
if diskType == "" {
|
||||
diskType = "hdd"
|
||||
}
|
||||
|
||||
vols := append([]*master_pb.VolumeInformationMessage(nil), diskInfo.VolumeInfos...)
|
||||
sort.Slice(vols, func(i, j int) bool { return vols[i].Id < vols[j].Id })
|
||||
var volumes []*ExportVolume
|
||||
for _, vi := range vols {
|
||||
if collection != "" && !matchesCollection(vi.Collection, collection) {
|
||||
continue
|
||||
}
|
||||
volumes = append(volumes, buildExportVolume(vi, volumeSizeLimit))
|
||||
totals.VolumeCount++
|
||||
totals.TotalSize += vi.Size
|
||||
totals.FileCount += vi.FileCount
|
||||
totals.DeletedFileCount += vi.DeleteCount
|
||||
totals.DeletedBytes += vi.DeletedByteCount
|
||||
}
|
||||
|
||||
shards := append([]*master_pb.VolumeEcShardInformationMessage(nil), diskInfo.EcShardInfos...)
|
||||
sort.Slice(shards, func(i, j int) bool { return shards[i].Id < shards[j].Id })
|
||||
var ecShards []*ExportEcShard
|
||||
for _, eci := range shards {
|
||||
if collection != "" && !matchesCollection(eci.Collection, collection) {
|
||||
continue
|
||||
}
|
||||
shard := buildExportEcShard(eci)
|
||||
ecShards = append(ecShards, shard)
|
||||
totals.EcShardCount++
|
||||
totals.TotalSize += uint64(shard.TotalSize)
|
||||
}
|
||||
|
||||
if len(volumes) == 0 && len(ecShards) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &ExportDisk{
|
||||
DiskType: diskType,
|
||||
DiskId: diskInfo.DiskId,
|
||||
VolumeCount: diskInfo.VolumeCount,
|
||||
MaxVolumeCount: diskInfo.MaxVolumeCount,
|
||||
ActiveVolumeCount: diskInfo.ActiveVolumeCount,
|
||||
FreeVolumeCount: diskInfo.FreeVolumeCount,
|
||||
RemoteVolumeCount: diskInfo.RemoteVolumeCount,
|
||||
Volumes: volumes,
|
||||
EcShards: ecShards,
|
||||
}
|
||||
}
|
||||
|
||||
func buildExportVolume(m *master_pb.VolumeInformationMessage, volumeSizeLimit uint64) *ExportVolume {
|
||||
v := &ExportVolume{
|
||||
Id: m.Id,
|
||||
Collection: m.Collection,
|
||||
Size: m.Size,
|
||||
FileCount: m.FileCount,
|
||||
DeleteCount: m.DeleteCount,
|
||||
DeletedByteCount: m.DeletedByteCount,
|
||||
Version: m.Version,
|
||||
ReadOnly: m.ReadOnly,
|
||||
CompactRevision: m.CompactRevision,
|
||||
ModifiedAtSecond: m.ModifiedAtSecond,
|
||||
DiskType: m.DiskType,
|
||||
DiskId: m.DiskId,
|
||||
RemoteStorageName: m.RemoteStorageName,
|
||||
}
|
||||
// Decode replica placement and TTL the way volume.list does.
|
||||
if vi, err := storage.NewVolumeInfo(m); err == nil {
|
||||
v.ReplicaPlacement = vi.ReplicaPlacement.String()
|
||||
v.Ttl = vi.Ttl.String()
|
||||
}
|
||||
if m.Size > 0 {
|
||||
v.GarbageRatio = float64(m.DeletedByteCount) / float64(m.Size)
|
||||
}
|
||||
if volumeSizeLimit > 0 {
|
||||
v.FullnessRatio = float64(m.Size) / float64(volumeSizeLimit)
|
||||
}
|
||||
if m.ModifiedAtSecond > 0 {
|
||||
v.ModifiedAt = time.Unix(m.ModifiedAtSecond, 0).UTC().Format(time.RFC3339)
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func buildExportEcShard(m *master_pb.VolumeEcShardInformationMessage) *ExportEcShard {
|
||||
si := erasure_coding.ShardsInfoFromVolumeEcShardInformationMessage(m)
|
||||
return &ExportEcShard{
|
||||
Id: m.Id,
|
||||
Collection: m.Collection,
|
||||
ShardIds: si.IdsUint32(),
|
||||
ShardSizes: si.SizesInt64(),
|
||||
TotalSize: int64(si.TotalSize()),
|
||||
FileCount: m.FileCount,
|
||||
DeleteCount: m.DeleteCount,
|
||||
DiskType: m.DiskType,
|
||||
DiskId: m.DiskId,
|
||||
ExpireAtSec: m.ExpireAtSec,
|
||||
}
|
||||
}
|
||||
|
||||
// findDuplicateVolumeIdsForExport reports volume ids living under more than one
|
||||
// collection. Volume ids are meant to be globally unique; a duplicate is a
|
||||
// cluster-health hazard (collection.delete destroys one collection's copy,
|
||||
// bare-id lookups are ambiguous). This mirrors volume.list's findDuplicateVolumeIds
|
||||
// rather than reaching into the shell package, per the admin-renderer design.
|
||||
// First collection per id is tracked alone, and a set is allocated only on the
|
||||
// first clash, keeping allocations O(duplicates) on million-volume clusters.
|
||||
func findDuplicateVolumeIdsForExport(topo *master_pb.TopologyInfo) []DuplicateVolumeId {
|
||||
firstCollectionByVid := make(map[uint32]string)
|
||||
collectionsByVid := make(map[uint32]map[string]struct{})
|
||||
note := func(vid uint32, collection string) {
|
||||
if collections := collectionsByVid[vid]; collections != nil {
|
||||
collections[collection] = struct{}{}
|
||||
return
|
||||
}
|
||||
first, seen := firstCollectionByVid[vid]
|
||||
if !seen {
|
||||
firstCollectionByVid[vid] = collection
|
||||
return
|
||||
}
|
||||
if first == collection {
|
||||
return
|
||||
}
|
||||
collectionsByVid[vid] = map[string]struct{}{first: {}, collection: {}}
|
||||
}
|
||||
for _, dc := range topo.DataCenterInfos {
|
||||
for _, rack := range dc.RackInfos {
|
||||
for _, node := range rack.DataNodeInfos {
|
||||
for _, disk := range node.DiskInfos {
|
||||
for _, vi := range disk.VolumeInfos {
|
||||
note(vi.Id, vi.Collection)
|
||||
}
|
||||
for _, ec := range disk.EcShardInfos {
|
||||
note(ec.Id, ec.Collection)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
duplicates := make([]DuplicateVolumeId, 0, len(collectionsByVid))
|
||||
for vid, set := range collectionsByVid {
|
||||
names := make([]string, 0, len(set))
|
||||
for name := range set {
|
||||
names = append(names, name)
|
||||
}
|
||||
sort.Strings(names)
|
||||
duplicates = append(duplicates, DuplicateVolumeId{VolumeId: vid, Collections: names})
|
||||
}
|
||||
sort.Slice(duplicates, func(i, j int) bool { return duplicates[i].VolumeId < duplicates[j].VolumeId })
|
||||
return duplicates
|
||||
}
|
||||
Reference in New Issue
Block a user