package execenv import ( "os" "path/filepath" "time" ) // GC 删除未被 current、绑定或锁引用、且早于 ttl 的层目录。ttl<=0 时用 7 天。 func (b *Broker) GC(ttl time.Duration) ([]string, error) { if ttl <= 0 { ttl = 7 * 24 * time.Hour } keep := map[string]bool{} if id, err := b.Root.CurrentBase(); err != nil { return nil, err } else if id != "" { keep[id] = true } if b.Store != nil { binds, err := b.Store.ListExecEnvBindings() if err != nil { return nil, err } for _, bind := range binds { if bind.BaseID != "" { keep[bind.BaseID] = true } if bind.Isolated != "" { keep[bind.Isolated] = true } for _, id := range bind.Extensions { keep[id] = true } } } ents, err := os.ReadDir(b.Root.LayersDir()) if err != nil { return nil, err } cut := time.Now().Add(-ttl) var removed []string for _, ent := range ents { if !ent.IsDir() || keep[ent.Name()] { continue } info, err := ent.Info() if err != nil { return removed, err } if info.ModTime().After(cut) { continue } if err := os.RemoveAll(filepath.Join(b.Root.LayersDir(), ent.Name())); err != nil { return removed, err } _ = os.Remove(filepath.Join(b.Root.LocksDir(), ent.Name()+".json")) removed = append(removed, ent.Name()) } return removed, nil }