263 lines
5.8 KiB
Go
263 lines
5.8 KiB
Go
package cache
|
|
|
|
import (
|
|
"time"
|
|
|
|
"github.com/boltdb/bolt"
|
|
"github.com/moby/buildkit/cache/metadata"
|
|
"github.com/moby/buildkit/client"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
const sizeUnknown int64 = -1
|
|
const keySize = "snapshot.size"
|
|
const keyEqualMutable = "cache.equalMutable"
|
|
const keyCachePolicy = "cache.cachePolicy"
|
|
const keyDescription = "cache.description"
|
|
const keyCreatedAt = "cache.createdAt"
|
|
const keyLastUsedAt = "cache.lastUsedAt"
|
|
const keyUsageCount = "cache.usageCount"
|
|
const keyLayerType = "cache.layerType"
|
|
const keyRecordType = "cache.recordType"
|
|
|
|
const keyDeleted = "cache.deleted"
|
|
|
|
func setDeleted(si *metadata.StorageItem) error {
|
|
v, err := metadata.NewValue(true)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create size value")
|
|
}
|
|
si.Update(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyDeleted, v)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func getDeleted(si *metadata.StorageItem) bool {
|
|
v := si.Get(keyDeleted)
|
|
if v == nil {
|
|
return false
|
|
}
|
|
var deleted bool
|
|
if err := v.Unmarshal(&deleted); err != nil {
|
|
return false
|
|
}
|
|
return deleted
|
|
}
|
|
|
|
func setSize(si *metadata.StorageItem, s int64) error {
|
|
v, err := metadata.NewValue(s)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create size value")
|
|
}
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keySize, v)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func getSize(si *metadata.StorageItem) int64 {
|
|
v := si.Get(keySize)
|
|
if v == nil {
|
|
return sizeUnknown
|
|
}
|
|
var size int64
|
|
if err := v.Unmarshal(&size); err != nil {
|
|
return sizeUnknown
|
|
}
|
|
return size
|
|
}
|
|
|
|
func getEqualMutable(si *metadata.StorageItem) string {
|
|
v := si.Get(keyEqualMutable)
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
var str string
|
|
if err := v.Unmarshal(&str); err != nil {
|
|
return ""
|
|
}
|
|
return str
|
|
}
|
|
|
|
func setEqualMutable(si *metadata.StorageItem, s string) error {
|
|
v, err := metadata.NewValue(s)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to create %s meta value", keyEqualMutable)
|
|
}
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyEqualMutable, v)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func clearEqualMutable(si *metadata.StorageItem) error {
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyEqualMutable, nil)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func queueCachePolicy(si *metadata.StorageItem, p cachePolicy) error {
|
|
v, err := metadata.NewValue(p)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create cachePolicy value")
|
|
}
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyCachePolicy, v)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func getCachePolicy(si *metadata.StorageItem) cachePolicy {
|
|
v := si.Get(keyCachePolicy)
|
|
if v == nil {
|
|
return cachePolicyDefault
|
|
}
|
|
var p cachePolicy
|
|
if err := v.Unmarshal(&p); err != nil {
|
|
return cachePolicyDefault
|
|
}
|
|
return p
|
|
}
|
|
|
|
func queueDescription(si *metadata.StorageItem, descr string) error {
|
|
v, err := metadata.NewValue(descr)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create description value")
|
|
}
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyDescription, v)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func GetDescription(si *metadata.StorageItem) string {
|
|
v := si.Get(keyDescription)
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
var str string
|
|
if err := v.Unmarshal(&str); err != nil {
|
|
return ""
|
|
}
|
|
return str
|
|
}
|
|
|
|
func queueCreatedAt(si *metadata.StorageItem, tm time.Time) error {
|
|
v, err := metadata.NewValue(tm.UnixNano())
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create createdAt value")
|
|
}
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyCreatedAt, v)
|
|
})
|
|
return nil
|
|
}
|
|
|
|
func GetCreatedAt(si *metadata.StorageItem) time.Time {
|
|
v := si.Get(keyCreatedAt)
|
|
if v == nil {
|
|
return time.Time{}
|
|
}
|
|
var tm int64
|
|
if err := v.Unmarshal(&tm); err != nil {
|
|
return time.Time{}
|
|
}
|
|
return time.Unix(tm/1e9, tm%1e9)
|
|
}
|
|
|
|
func getLastUsed(si *metadata.StorageItem) (int, *time.Time) {
|
|
v := si.Get(keyUsageCount)
|
|
if v == nil {
|
|
return 0, nil
|
|
}
|
|
var usageCount int
|
|
if err := v.Unmarshal(&usageCount); err != nil {
|
|
return 0, nil
|
|
}
|
|
v = si.Get(keyLastUsedAt)
|
|
if v == nil {
|
|
return usageCount, nil
|
|
}
|
|
var lastUsedTs int64
|
|
if err := v.Unmarshal(&lastUsedTs); err != nil || lastUsedTs == 0 {
|
|
return usageCount, nil
|
|
}
|
|
tm := time.Unix(lastUsedTs/1e9, lastUsedTs%1e9)
|
|
return usageCount, &tm
|
|
}
|
|
|
|
func updateLastUsed(si *metadata.StorageItem) error {
|
|
count, _ := getLastUsed(si)
|
|
count++
|
|
|
|
v, err := metadata.NewValue(count)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create usageCount value")
|
|
}
|
|
v2, err := metadata.NewValue(time.Now().UnixNano())
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create lastUsedAt value")
|
|
}
|
|
return si.Update(func(b *bolt.Bucket) error {
|
|
if err := si.SetValue(b, keyUsageCount, v); err != nil {
|
|
return err
|
|
}
|
|
return si.SetValue(b, keyLastUsedAt, v2)
|
|
})
|
|
}
|
|
|
|
func SetLayerType(m withMetadata, value string) error {
|
|
v, err := metadata.NewValue(value)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create layertype value")
|
|
}
|
|
m.Metadata().Queue(func(b *bolt.Bucket) error {
|
|
return m.Metadata().SetValue(b, keyLayerType, v)
|
|
})
|
|
return m.Metadata().Commit()
|
|
}
|
|
|
|
func GetLayerType(m withMetadata) string {
|
|
v := m.Metadata().Get(keyLayerType)
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
var str string
|
|
if err := v.Unmarshal(&str); err != nil {
|
|
return ""
|
|
}
|
|
return str
|
|
}
|
|
|
|
func GetRecordType(m withMetadata) client.UsageRecordType {
|
|
v := m.Metadata().Get(keyRecordType)
|
|
if v == nil {
|
|
return ""
|
|
}
|
|
var str string
|
|
if err := v.Unmarshal(&str); err != nil {
|
|
return ""
|
|
}
|
|
return client.UsageRecordType(str)
|
|
}
|
|
|
|
func SetRecordType(m withMetadata, value client.UsageRecordType) error {
|
|
if err := queueRecordType(m.Metadata(), value); err != nil {
|
|
return err
|
|
}
|
|
return m.Metadata().Commit()
|
|
}
|
|
|
|
func queueRecordType(si *metadata.StorageItem, value client.UsageRecordType) error {
|
|
v, err := metadata.NewValue(value)
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to create recordtype value")
|
|
}
|
|
si.Queue(func(b *bolt.Bucket) error {
|
|
return si.SetValue(b, keyRecordType, v)
|
|
})
|
|
return nil
|
|
}
|