mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-19 12:34:29 +02:00
CP8-1: HTTP REST API (create/delete/lookup/list/assign/servers), blockapi Go client with multi-master failover, 5 shell commands, HTML dashboard at /block/. CP8-2: RF=2/RF=3 multi-replica support -- ShipperGroup fan-out, distributed sync, health scoring, segment-based scrub, gated promotion (heartbeat freshness + WAL LSN + role checks), failover/rebuild for N>2 replicas. CP8-3: CSI snapshot + expansion -- CreateSnapshot/DeleteSnapshot/ListSnapshots RPCs, NodeExpandVolume with iSCSI rescan, snapshot ID helpers, 20 adversarial tests covering concurrent ops, edge cases, and error injection. CP8-4: Observability -- EngineMetrics atomic counters for flusher/group-commit/ WAL-shipper/scrub, 10 new Prometheus metrics, barrier_lag_lsn SLO gauge, failover/promotion/rebuild counters, request ID correlation in master gRPC logs, baseline regression framework with 7 hard-fail conditions. Total: 63 files, ~11.2K LOC, 160+ new tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
45 lines
1.2 KiB
Go
45 lines
1.2 KiB
Go
package csi
|
|
|
|
import (
|
|
"fmt"
|
|
"hash/fnv"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
// FormatSnapshotID creates a CSI-standard snapshot ID: "snap-{volumeID}-{snapID}".
|
|
func FormatSnapshotID(volumeID string, snapID uint32) string {
|
|
return fmt.Sprintf("snap-%s-%d", volumeID, snapID)
|
|
}
|
|
|
|
// ParseSnapshotID reverses FormatSnapshotID, returning volumeID and snapID.
|
|
// The volumeID may contain dashes, so we split on the last dash.
|
|
func ParseSnapshotID(csiSnapID string) (string, uint32, error) {
|
|
if !strings.HasPrefix(csiSnapID, "snap-") {
|
|
return "", 0, fmt.Errorf("invalid snapshot ID format: missing snap- prefix")
|
|
}
|
|
rest := csiSnapID[len("snap-"):]
|
|
|
|
lastDash := strings.LastIndex(rest, "-")
|
|
if lastDash < 0 || lastDash == 0 {
|
|
return "", 0, fmt.Errorf("invalid snapshot ID format: no volume/snap separator")
|
|
}
|
|
|
|
volumeID := rest[:lastDash]
|
|
numStr := rest[lastDash+1:]
|
|
|
|
id, err := strconv.ParseUint(numStr, 10, 32)
|
|
if err != nil {
|
|
return "", 0, fmt.Errorf("invalid snapshot ID format: %w", err)
|
|
}
|
|
|
|
return volumeID, uint32(id), nil
|
|
}
|
|
|
|
// snapshotNameToID converts a snapshot name to a deterministic uint32 via FNV-32a hash.
|
|
func snapshotNameToID(name string) uint32 {
|
|
h := fnv.New32a()
|
|
h.Write([]byte(name))
|
|
return h.Sum32()
|
|
}
|