mirror of
https://gitea.com/Lydanne/buildx.git
synced 2025-05-18 09:17:49 +08:00

Integrates vtproto into buildx. The generated files dockerfile has been modified to copy the buildkit equivalent file to ensure files are laid out in the appropriate way for imports. An import has also been included to change the grpc codec to the version in buildkit that supports vtproto. This will allow buildx to utilize the speed and memory improvements from that. Also updates the gc control options for prune. Signed-off-by: Jonathan A. Sternberg <jonathan.sternberg@docker.com>
154 lines
3.5 KiB
Go
154 lines
3.5 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding"
|
|
"strconv"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/docker/go-units"
|
|
"github.com/moby/buildkit/util/disk"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Duration struct {
|
|
time.Duration
|
|
}
|
|
|
|
func (d *Duration) UnmarshalText(textb []byte) error {
|
|
text := stripQuotes(string(textb))
|
|
if len(text) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if duration, err := time.ParseDuration(text); err == nil {
|
|
d.Duration = duration
|
|
return nil
|
|
}
|
|
|
|
if i, err := strconv.ParseInt(text, 10, 64); err == nil {
|
|
d.Duration = time.Duration(i) * time.Second
|
|
return nil
|
|
}
|
|
|
|
return errors.Errorf("invalid duration %s", text)
|
|
}
|
|
|
|
var _ encoding.TextUnmarshaler = &Duration{}
|
|
|
|
type DiskSpace struct {
|
|
Bytes int64
|
|
Percentage int64
|
|
}
|
|
|
|
var _ encoding.TextUnmarshaler = &DiskSpace{}
|
|
|
|
func (d *DiskSpace) UnmarshalText(textb []byte) error {
|
|
text := stripQuotes(string(textb))
|
|
if len(text) == 0 {
|
|
return nil
|
|
}
|
|
|
|
if text2 := strings.TrimSuffix(text, "%"); len(text2) < len(text) {
|
|
i, err := strconv.ParseInt(text2, 10, 64)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
d.Percentage = i
|
|
return nil
|
|
}
|
|
|
|
if i, err := units.RAMInBytes(text); err == nil {
|
|
d.Bytes = i
|
|
return nil
|
|
}
|
|
|
|
return errors.Errorf("invalid disk space %s", text)
|
|
}
|
|
|
|
const defaultCap int64 = 2e9 // 2GB
|
|
|
|
func DefaultGCPolicy(cfg GCConfig, dstat disk.DiskStat) []GCPolicy {
|
|
if cfg.IsUnset() {
|
|
cfg.GCReservedSpace = cfg.GCKeepStorage
|
|
}
|
|
if cfg.IsUnset() {
|
|
cfg = DetectDefaultGCCap(dstat)
|
|
}
|
|
return []GCPolicy{
|
|
// if build cache uses more than 512MB delete the most easily reproducible data after it has not been used for 2 days
|
|
{
|
|
Filters: []string{"type==source.local,type==exec.cachemount,type==source.git.checkout"},
|
|
KeepDuration: Duration{Duration: time.Duration(48) * time.Hour}, // 48h
|
|
MaxUsedSpace: DiskSpace{Bytes: 512 * 1e6}, // 512MB
|
|
},
|
|
// remove any data not used for 60 days
|
|
{
|
|
KeepDuration: Duration{Duration: time.Duration(60) * 24 * time.Hour}, // 60d
|
|
MinFreeSpace: cfg.GCMinFreeSpace,
|
|
ReservedSpace: cfg.GCReservedSpace,
|
|
MaxUsedSpace: cfg.GCMaxUsedSpace,
|
|
},
|
|
// keep the unshared build cache under cap
|
|
{
|
|
MinFreeSpace: cfg.GCMinFreeSpace,
|
|
ReservedSpace: cfg.GCReservedSpace,
|
|
MaxUsedSpace: cfg.GCMaxUsedSpace,
|
|
},
|
|
// if previous policies were insufficient start deleting internal data to keep build cache under cap
|
|
{
|
|
All: true,
|
|
MinFreeSpace: cfg.GCMinFreeSpace,
|
|
ReservedSpace: cfg.GCReservedSpace,
|
|
MaxUsedSpace: cfg.GCMaxUsedSpace,
|
|
},
|
|
}
|
|
}
|
|
|
|
func stripQuotes(s string) string {
|
|
if len(s) == 0 {
|
|
return s
|
|
}
|
|
if s[0] == '"' && s[len(s)-1] == '"' {
|
|
return s[1 : len(s)-1]
|
|
}
|
|
return s
|
|
}
|
|
|
|
func DetectDefaultGCCap(dstat disk.DiskStat) GCConfig {
|
|
reserve := DiskSpace{Percentage: DiskSpaceReservePercentage}
|
|
if reserve.AsBytes(dstat) > DiskSpaceReserveBytes {
|
|
reserve = DiskSpace{Bytes: DiskSpaceReserveBytes}
|
|
}
|
|
max := DiskSpace{Percentage: DiskSpaceMaxPercentage}
|
|
if max.AsBytes(dstat) > DiskSpaceMaxBytes {
|
|
max = DiskSpace{Bytes: DiskSpaceMaxBytes}
|
|
}
|
|
return GCConfig{
|
|
GCReservedSpace: reserve,
|
|
GCMinFreeSpace: DiskSpace{Percentage: DiskSpaceFreePercentage},
|
|
GCMaxUsedSpace: max,
|
|
}
|
|
}
|
|
|
|
func (d DiskSpace) AsBytes(dstat disk.DiskStat) int64 {
|
|
if d.Bytes != 0 {
|
|
return d.Bytes
|
|
}
|
|
if d.Percentage == 0 {
|
|
return 0
|
|
}
|
|
|
|
if dstat.Total == 0 {
|
|
return defaultCap
|
|
}
|
|
|
|
avail := dstat.Total * d.Percentage / 100
|
|
rounded := (avail/(1<<30) + 1) * 1e9 // round up
|
|
return rounded
|
|
}
|
|
|
|
func (cfg *GCConfig) IsUnset() bool {
|
|
return cfg.GCReservedSpace == DiskSpace{} && cfg.GCMaxUsedSpace == DiskSpace{} && cfg.GCMinFreeSpace == DiskSpace{}
|
|
}
|