diff --git a/cmd/buildkitd/config/gcpolicy.go b/cmd/buildkitd/config/gcpolicy.go index 4078cc6d5910e..2e63da2267643 100644 --- a/cmd/buildkitd/config/gcpolicy.go +++ b/cmd/buildkitd/config/gcpolicy.go @@ -104,3 +104,20 @@ func stripQuotes(s string) string { } return s } + +func DetectDefaultGCCap() DiskSpace { + return DiskSpace{Percentage: DiskSpacePercentage} +} + +func (d DiskSpace) AsBytes(root string) int64 { + if d.Bytes != 0 { + return d.Bytes + } + if d.Percentage == 0 { + return 0 + } + + avail := getDiskSize(root) * d.Percentage / 100 + rounded := (avail/(1<<30) + 1) * 1e9 // round up + return rounded +} diff --git a/cmd/buildkitd/config/gcpolicy_unix.go b/cmd/buildkitd/config/gcpolicy_unix.go index 232a9ac336cfe..b1af6071cf4ff 100644 --- a/cmd/buildkitd/config/gcpolicy_unix.go +++ b/cmd/buildkitd/config/gcpolicy_unix.go @@ -5,25 +5,18 @@ package config import ( "syscall" -) -func DetectDefaultGCCap() DiskSpace { - return DiskSpace{Percentage: 10} -} + "github.com/moby/buildkit/util/bklog" +) -func (d DiskSpace) AsBytes(root string) int64 { - if d.Bytes != 0 { - return d.Bytes - } - if d.Percentage == 0 { - return 0 - } +var DiskSpacePercentage int64 = 10 +func getDiskSize(root string) int64 { var st syscall.Statfs_t if err := syscall.Statfs(root, &st); err != nil { + bklog.L.Warnf("failed to get disk size: %v", err) return defaultCap } diskSize := int64(st.Bsize) * int64(st.Blocks) - avail := diskSize * d.Percentage / 100 - return (avail/(1<<30) + 1) * 1e9 // round up + return diskSize } diff --git a/cmd/buildkitd/config/gcpolicy_windows.go b/cmd/buildkitd/config/gcpolicy_windows.go index 55ce4dd77278c..229f500d4a366 100644 --- a/cmd/buildkitd/config/gcpolicy_windows.go +++ b/cmd/buildkitd/config/gcpolicy_windows.go @@ -3,10 +3,32 @@ package config -func DetectDefaultGCCap() DiskSpace { - return DiskSpace{Bytes: defaultCap} -} +import ( + "github.com/moby/buildkit/util/bklog" + "golang.org/x/sys/windows" +) + +// set as double that for Linux since +// Windows images are generally larger. +var DiskSpacePercentage int64 = 20 + +func getDiskSize(root string) int64 { + rootUTF16, err := windows.UTF16FromString(root) + if err != nil { + bklog.L.Warnf("failed to convert root dir to UTF16: %v", err) + return defaultCap + } + var freeAvailableBytes uint64 + var totalBytes uint64 + var totalFreeBytes uint64 -func (d DiskSpace) AsBytes(root string) int64 { - return d.Bytes + if err := windows.GetDiskFreeSpaceEx( + &rootUTF16[0], + &freeAvailableBytes, + &totalBytes, + &totalFreeBytes); err != nil { + bklog.L.Warnf("failed to get disk size: %v", err) + return defaultCap + } + return int64(totalBytes) }