diff --git a/disk/disk_darwin.go b/disk/disk_darwin.go index 94f10b9..ff66063 100644 --- a/disk/disk_darwin.go +++ b/disk/disk_darwin.go @@ -5,8 +5,10 @@ package disk import ( "context" + "encoding/json" "errors" "fmt" + "strings" "unsafe" "golang.org/x/sys/unix" @@ -88,8 +90,58 @@ func getFsType(stat unix.Statfs_t) string { return common.ByteToString(stat.Fstypename[:]) } +type spnvmeDataTypeItem struct { + Name string `json:"_name"` + BsdName string `json:"bsd_name"` + DetachableDrive string `json:"detachable_drive"` + DeviceModel string `json:"device_model"` + DeviceRevision string `json:"device_revision"` + DeviceSerial string `json:"device_serial"` + PartitionMapType string `json:"partition_map_type"` + RemovableMedia string `json:"removable_media"` + Size string `json:"size"` + SizeInBytes int64 `json:"size_in_bytes"` + SmartStatus string `json:"smart_status"` + SpnvmeTrimSupport string `json:"spnvme_trim_support"` + Volumes []struct { + Name string `json:"_name"` + BsdName string `json:"bsd_name"` + Iocontent string `json:"iocontent"` + Size string `json:"size"` + SizeInBytes int `json:"size_in_bytes"` + } `json:"volumes"` +} + +type spnvmeDataWrapper struct { + SPNVMeDataType []struct { + Items []spnvmeDataTypeItem `json:"_items"` + } `json:"SPNVMeDataType"` +} + func SerialNumberWithContext(ctx context.Context, name string) (string, error) { - return "", common.ErrNotImplementedError + output, err := invoke.CommandWithContext(ctx, "system_profiler", "SPNVMeDataType", "-json") + if err != nil { + return "", err + } + + var data spnvmeDataWrapper + if err := json.Unmarshal(output, &data); err != nil { + return "", fmt.Errorf("failed to unmarshal JSON: %w", err) + } + + // Extract all serial numbers into a single string + var serialNumbers []string + for _, spnvmeData := range data.SPNVMeDataType { + for _, item := range spnvmeData.Items { + serialNumbers = append(serialNumbers, item.DeviceSerial) + } + } + + if len(serialNumbers) == 0 { + return "", fmt.Errorf("no serial numbers found") + } + + return strings.Join(serialNumbers, ", "), nil } func LabelWithContext(ctx context.Context, name string) (string, error) {