package collect import ( "bytes" "encoding/json" "fmt" "os" "path/filepath" "github.com/pkg/errors" troubleshootv1beta2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" "github.com/shirou/gopsutil/v4/disk" ) type DiskUsageInfo struct { TotalBytes uint64 `json:"total_bytes"` UsedBytes uint64 `json:"used_bytes"` } type CollectHostDiskUsage struct { hostCollector *troubleshootv1beta2.DiskUsage BundlePath string } func (c *CollectHostDiskUsage) Title() string { return hostCollectorTitleOrDefault(c.hostCollector.HostCollectorMeta, fmt.Sprintf("Disk Usage %s", c.hostCollector.CollectorName)) } func (c *CollectHostDiskUsage) IsExcluded() (bool, error) { return isExcluded(c.hostCollector.Exclude) } func (c *CollectHostDiskUsage) Collect(progressChan chan<- interface{}) (map[string][]byte, error) { result := map[string][]byte{} if c.hostCollector == nil { return map[string][]byte{}, nil } pathExists, err := traverseFiletreeDirExists(c.hostCollector.Path) if err != nil { return result, errors.Wrap(err, "traverse file tree") } du, err := disk.Usage(pathExists) if err != nil { return result, errors.Wrapf(err, "collect disk usage for %s", pathExists) } diskSpaceInfo := DiskUsageInfo{ TotalBytes: du.Total, UsedBytes: du.Used, } b, err := json.Marshal(diskSpaceInfo) if err != nil { return nil, errors.Wrap(err, "failed to marshal disk space info") } collectorName := c.hostCollector.CollectorName if collectorName == "" { collectorName = "diskUsage" } name := filepath.Join("host-collectors/diskUsage", collectorName+".json") result[name] = b output := NewResult() output.SaveResult(c.BundlePath, name, bytes.NewBuffer(b)) return result, nil } func traverseFiletreeDirExists(filename string) (string, error) { filename = filepath.Clean(filename) for i := 0; i < 50; i++ { _, err := os.Stat(filename) if err == nil { return filename, nil } else if os.IsNotExist(err) { filename = filepath.Dir(filename) if filename == "/" { return filename, nil } } else { return "", err } } return "", errors.New("max recursion exceeded") } func (c *CollectHostDiskUsage) RemoteCollect(progressChan chan<- interface{}) (map[string][]byte, error) { return nil, ErrRemoteCollectorNotImplemented }