okami.mom/albedo
git clone https://git.nkp.pet/okami.mom/albedo
7e45521
main
1package daemon 2 3import ( 4"context" 5"io" 6"net/http" 7 8"albedo/cli/internal/daemon/protocol" 9) 10 11type StorageFile struct { 12Path string `json:"path"` 13Bytes int64 `json:"bytes"` 14} 15 16type StorageSession struct { 17ID string `json:"id"` 18Bytes int64 `json:"bytes"` 19} 20 21type StorageDatabase struct { 22Sessions []StorageSession `json:"sessions"` 23Images int64 `json:"images"` 24FreePages int64 `json:"free_pages"` 25PageSize int64 `json:"page_size"` 26} 27 28type StorageReport struct { 29OldKernels []StorageFile `json:"old_kernels"` 30OldBackups []StorageFile `json:"old_backups"` 31DB StorageDatabase `json:"db"` 32Database int64 `json:"database"` 33WAL int64 `json:"wal"` 34Kernels int64 `json:"kernels"` 35Backups int64 `json:"backups"` 36Other int64 `json:"other"` 37RecentBackups int64 `json:"recent_backups"` 38RecentBackupCount int `json:"recent_backup_count"` 39} 40 41func GetStorageReport (ctx context.Context ,conn * Connection ) (StorageReport ,error ) { 42result := StorageReport {OldKernels : []StorageFile {},OldBackups : []StorageFile {},DB :StorageDatabase {Sessions : []StorageSession {}}} 43params := protocol.GetStorageParams {Limit :new (int64 (200 ))} 44seenSessions ,seenFiles := map [string ]bool {},map [string ]bool {} 45seenTokens := map [[2 ]string ]bool {} 46for { 47var w protocol.StorageReport 48err := executeRead (ctx ,conn ,operation {Capability :"storage_report" ,Name :"read storage" ,BuildRequest :func (base string ,body io.Reader ) (* http.Request ,error ) { 49return protocol .NewGetStorageRequest (base ,& params ) 50 },Policy :readRecovery },func (data []byte )error { 51return decodeRequired (data ,& w ) 52 }) 53if err != nil { 54return result ,err 55 } 56result .Database = w .Database .MainFileBytes 57result .WAL = w .Database .WalBytes 58result .DB .Images = w .Images .Bytes 59result .DB .FreePages = w .Database .FreePageCount 60result .DB .PageSize = w .Database .PageSizeBytes 61result .Kernels = w .Files .Totals .KernelBytes 62result .Backups = w .Files .Totals .BackupBytes 63result .Other = w .Files .Totals .OtherBytes 64result .RecentBackups = w .Files .Totals .RecentBackupBytes 65result .RecentBackupCount = int (w .Files .Totals .RecentBackupCount ) 66for _ ,row := range w .Sessions .Items { 67if ! seenSessions [row .ID ] { 68seenSessions [row .ID ]= true 69result .DB .Sessions = append (result .DB .Sessions ,StorageSession {ID :row .ID ,Bytes :row .EstimatedContentBytes }) 70 } 71 } 72for _ ,row := range w .Files .Items { 73if seenFiles [row .Path ] { 74continue 75 } 76seenFiles [row .Path ]= true 77file := StorageFile {Path :row .Path ,Bytes :row .Bytes } 78if row .CleanupCandidate { 79switch row .Category { 80case "kernel" : 81result .OldKernels = append (result .OldKernels ,file ) 82case "backup" : 83result .OldBackups = append (result .OldBackups ,file ) 84 } 85 } 86 } 87if w .Sessions .Next == nil && w .Files .Next == nil { 88return result ,nil 89 } 90if w .Sessions .Next != nil { 91params .SessionsNext = w .Sessions .Next 92 } 93if w .Files .Next != nil { 94params .FilesNext = w .Files .Next 95 } 96key := [2 ]string {value (params .SessionsNext ),value (params .FilesNext )} 97if seenTokens [key ] { 98return result ,fieldError ("storage page cursor" ) 99 } 100seenTokens [key ]= true 101 } 102}