@@ -22,6 +22,7 @@ import (
2222 "github.com/moby/buildkit/session"
2323 "github.com/moby/buildkit/snapshot"
2424 "github.com/moby/buildkit/util/bklog"
25+ "github.com/moby/buildkit/util/disk"
2526 "github.com/moby/buildkit/util/flightcontrol"
2627 "github.com/moby/buildkit/util/progress"
2728 digest "github.com/opencontainers/go-digest"
@@ -1040,7 +1041,7 @@ func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo,
10401041 }
10411042
10421043 totalSize := int64 (0 )
1043- if opt .KeepBytes != 0 {
1044+ if opt .MaxStorage != 0 {
10441045 du , err := cm .DiskUsage (ctx , client.DiskUsageInfo {})
10451046 if err != nil {
10461047 return err
@@ -1053,27 +1054,62 @@ func (cm *cacheManager) pruneOnce(ctx context.Context, ch chan client.UsageInfo,
10531054 }
10541055 }
10551056
1057+ // TODO: pick a better path here
1058+ dstat , err := disk .GetDiskStat (cm .mountPool .tmpdirRoot )
1059+ if err != nil {
1060+ if opt .Free != 0 {
1061+ // if we are pruning based on disk space, failing to get info on it
1062+ // is fatal
1063+ return err
1064+ }
1065+ bklog .L .Warnf ("failed to get disk size: %v" , err )
1066+ }
1067+
10561068 return cm .prune (ctx , ch , pruneOpt {
10571069 filter : filter ,
10581070 all : opt .All ,
10591071 checkShared : check ,
10601072 keepDuration : opt .KeepDuration ,
1061- keepBytes : opt . KeepBytes ,
1073+ keepBytes : calculateKeepBytes ( totalSize , dstat , opt ) ,
10621074 totalSize : totalSize ,
10631075 })
10641076}
10651077
1066- func (cm * cacheManager ) prune (ctx context.Context , ch chan client.UsageInfo , opt pruneOpt ) (err error ) {
1067- var toDelete []* deleteRecord
1078+ func calculateKeepBytes (totalSize int64 , dstat disk.DiskStat , opt client.PruneInfo ) int64 {
1079+ // 0 values are special, and means we have no keep cap
1080+ if opt .MaxStorage == 0 && opt .MinStorage == 0 && opt .Free == 0 {
1081+ return 0
1082+ }
1083+
1084+ // try and keep as many bytes as we can
1085+ keepBytes := opt .MaxStorage
1086+
1087+ // if we need to free up space, then decrease to that
1088+ if excess := opt .Free - dstat .Free ; excess > 0 {
1089+ if keepBytes == 0 {
1090+ keepBytes = totalSize - excess
1091+ } else {
1092+ keepBytes = min (keepBytes , totalSize - excess )
1093+ }
1094+ }
1095+
1096+ // but make sure we don't take the total below the minimum
1097+ keepBytes = max (keepBytes , opt .MinStorage )
10681098
1099+ return keepBytes
1100+ }
1101+
1102+ func (cm * cacheManager ) prune (ctx context.Context , ch chan client.UsageInfo , opt pruneOpt ) (err error ) {
10691103 if opt .keepBytes != 0 && opt .totalSize < opt .keepBytes {
10701104 return nil
10711105 }
10721106
1107+ var toDelete []* deleteRecord
1108+
10731109 cm .mu .Lock ()
10741110
1075- gcMode := opt .keepBytes != 0
10761111 cutOff := time .Now ().Add (- opt .keepDuration )
1112+ gcMode := opt .keepBytes != 0
10771113
10781114 locked := map [* sync.Mutex ]struct {}{}
10791115
@@ -1610,8 +1646,9 @@ type pruneOpt struct {
16101646 all bool
16111647 checkShared ExternalRefChecker
16121648 keepDuration time.Duration
1613- keepBytes int64
1614- totalSize int64
1649+
1650+ keepBytes int64
1651+ totalSize int64
16151652}
16161653
16171654type deleteRecord struct {
0 commit comments