Skip to content

Commit

Permalink
Merge pull request #48 from grafana/fedor/group_by
Browse files Browse the repository at this point in the history
Add '-group-by' flag to compute aggregated disk usage
  • Loading branch information
fedordikarev authored Apr 19, 2023
2 parents 527f5e6 + a552ac5 commit 5fed19a
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 0 deletions.
90 changes: 90 additions & 0 deletions cmd/unused/internal/ui/group_table.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package ui

import (
"context"
"fmt"
"os"
"sort"
"strconv"
"strings"
"text/tabwriter"

"github.com/grafana/unused"
)

// Disks are aggregated by the key composed by these 3 strings:
// 1. Provider
// 2. Value of the tag from disk metadata
// Name of key passed in the options.Group
// If requested key is absent in disk metadata, use value "NONE"
// 3. Disk type: "hdd", "ssd" or "unknown"
type groupKey [3]string

func GroupTable(ctx context.Context, options Options) error {
disks, err := listUnusedDisks(ctx, options.Providers)
if err != nil {
return err
}

if options.Filter.Key != "" {
filtered := make(unused.Disks, 0, len(disks))
for _, d := range disks {
if d.Meta().Matches(options.Filter.Key, options.Filter.Value) {
filtered = append(filtered, d)
}
}
disks = filtered
}

if len(disks) == 0 {
fmt.Println("No disks found")
return nil
}

w := tabwriter.NewWriter(os.Stdout, 8, 4, 2, ' ', 0)

headers := []string{"PROVIDER", options.Group, "TYPE", "DISKS_COUNT", "TOTAL_SIZE_GB"}
totalSize := make(map[groupKey]int)
totalCount := make(map[groupKey]int)

fmt.Fprintln(w, strings.Join(headers, "\t"))

var aggrValue string
for _, d := range disks {
p := d.Provider()
if value, ok := d.Meta()[options.Group]; ok {
aggrValue = value
} else {
aggrValue = "NONE"
}
aggrKey := groupKey{p.Name(), aggrValue, string(d.DiskType())}
totalSize[aggrKey] += d.SizeGB()
totalCount[aggrKey] += 1
}

keys := make([]groupKey, 0, len(totalSize))
for k := range totalSize {
keys = append(keys, k)
}

sort.Slice(keys, func(i, j int) bool {
for k := 0; k < len(keys[i]); k++ {
if keys[i][k] != keys[j][k] {
return keys[i][k] < keys[j][k]
}
}
return true
})

for _, aggrKey := range keys {
row := aggrKey[:]
row = append(row, strconv.Itoa(totalCount[aggrKey]), strconv.Itoa(totalSize[aggrKey]))
fmt.Fprintln(w, strings.Join(row, "\t"))
}

if err := w.Flush(); err != nil {
return fmt.Errorf("flushing table contents: %w", err)
}

return nil
}
1 change: 1 addition & 0 deletions cmd/unused/internal/ui/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type Options struct {
Providers []unused.Provider
ExtraColumns []string
Filter Filter
Group string
Verbose bool
}

Expand Down
5 changes: 5 additions & 0 deletions cmd/unused/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ func main() {
return nil
})

flag.StringVar(&options.Group, "group-by", "", "Group by disk metadata values")

flag.Parse()

ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
Expand All @@ -78,6 +80,9 @@ func main() {
options.Providers = providers

var display ui.DisplayFunc = ui.Table
if options.Group != "" {
display = ui.GroupTable
}
if interactiveMode {
display = ui.Interactive
}
Expand Down

0 comments on commit 5fed19a

Please sign in to comment.