Files
mc-gateway/internal/pluginmanager/gc.go
tursom eae2319328
Some checks failed
Go / build (.exe, 386, windows, windows-386) (push) Has been cancelled
Go / build (.exe, amd64, windows, windows-amd64) (push) Has been cancelled
Go / build (.exe, arm64, windows, windows-arm64) (push) Has been cancelled
Go / build (386, freebsd, freebsd-386) (push) Has been cancelled
Go / build (386, linux, linux-386) (push) Has been cancelled
Go / build (386, netbsd, netbsd-386) (push) Has been cancelled
Go / build (386, openbsd, openbsd-386) (push) Has been cancelled
Go / build (386, plan9, plan9-386) (push) Has been cancelled
Go / build (amd64, darwin, darwin-amd64) (push) Has been cancelled
Go / build (amd64, dragonfly, dragonfly-amd64) (push) Has been cancelled
Go / build (amd64, freebsd, freebsd-amd64) (push) Has been cancelled
Go / build (amd64, illumos, illumos-amd64) (push) Has been cancelled
Go / build (amd64, linux, linux-amd64) (push) Has been cancelled
Go / build (amd64, netbsd, netbsd-amd64) (push) Has been cancelled
Go / build (amd64, openbsd, openbsd-amd64) (push) Has been cancelled
Go / build (amd64, plan9, plan9-amd64) (push) Has been cancelled
Go / build (amd64, solaris, solaris-amd64) (push) Has been cancelled
Go / build (arm, 6, linux, linux-armv6) (push) Has been cancelled
Go / build (arm, 7, linux, linux-armv7) (push) Has been cancelled
Go / build (arm, freebsd, freebsd-arm) (push) Has been cancelled
Go / build (arm, netbsd, netbsd-arm) (push) Has been cancelled
Go / build (arm, openbsd, openbsd-arm) (push) Has been cancelled
Go / build (arm, plan9, plan9-arm) (push) Has been cancelled
Go / build (arm64, darwin, darwin-arm64) (push) Has been cancelled
Go / build (arm64, freebsd, freebsd-arm64) (push) Has been cancelled
Go / build (arm64, linux, linux-arm64) (push) Has been cancelled
Go / build (arm64, netbsd, netbsd-arm64) (push) Has been cancelled
Go / build (arm64, openbsd, openbsd-arm64) (push) Has been cancelled
Go / build (loong64, linux, linux-loong64) (push) Has been cancelled
Go / build (mips, linux, linux-mips) (push) Has been cancelled
Go / build (mips64, linux, linux-mips64) (push) Has been cancelled
Go / build (mips64le, linux, linux-mips64le) (push) Has been cancelled
Go / build (mipsle, linux, linux-mipsle) (push) Has been cancelled
Go / build (ppc64, aix, aix-ppc64) (push) Has been cancelled
Go / build (ppc64, linux, linux-ppc64) (push) Has been cancelled
Go / build (ppc64, openbsd, openbsd-ppc64) (push) Has been cancelled
Go / build (ppc64le, linux, linux-ppc64le) (push) Has been cancelled
Go / build (riscv64, freebsd, freebsd-riscv64) (push) Has been cancelled
Go / build (riscv64, linux, linux-riscv64) (push) Has been cancelled
Go / build (riscv64, openbsd, openbsd-riscv64) (push) Has been cancelled
Go / build (s390x, linux, linux-s390x) (push) Has been cancelled
Go / merge-artifacts (push) Has been cancelled
Docker Image / docker (push) Has been cancelled
feat(plugin): add source package builder
2026-06-26 10:53:41 +08:00

130 lines
3.6 KiB
Go

package pluginmanager
import (
"context"
"os"
"path/filepath"
"strconv"
)
func (m *Manager) GCCandidates(ctx context.Context) ([]GCCandidate, error) {
refs, err := m.repo.ReferencedArtifactIDs(ctx)
if err != nil {
return nil, err
}
artifacts, err := m.repo.ListArtifacts(ctx, "")
if err != nil {
return nil, err
}
var candidates []GCCandidate
for _, artifact := range artifacts {
referenced := refs[artifact.ID]
artifactPath := artifactGCPath(artifact)
size := artifact.SizeBytes
if info, err := os.Stat(artifactPath); err == nil && info.IsDir() {
size = dirSize(artifactPath)
} else if err == nil {
size = info.Size()
}
candidate := GCCandidate{
Kind: "artifact",
ID: artifact.ID,
PluginID: artifact.PluginID,
Path: artifactPath,
Protected: referenced,
SizeBytes: size,
CreatedAt: artifact.CreatedAt,
Referenced: referenced,
}
switch {
case referenced:
candidate.Reason = "referenced by active/desired/snapshot/build"
case artifact.ArtifactType == ArtifactTypeSource:
candidate.Reason = "unreferenced source package"
case artifact.Status == ArtifactStatusRejected || artifact.Status == ArtifactStatusDeleted:
candidate.Reason = "unreferenced rejected/deleted artifact"
default:
candidate.Reason = "unreferenced artifact"
}
if !referenced && (artifact.ArtifactType == ArtifactTypeSource || artifact.Status == ArtifactStatusRejected || artifact.Status == ArtifactStatusDeleted) {
candidates = append(candidates, candidate)
}
}
builds, err := m.repo.ListBuilds(ctx, "")
if err != nil {
return nil, err
}
for _, build := range builds {
protectedBuild := build.Status == BuildStatusRunning || build.Status == BuildStatusQueued
reason := "completed build log"
if protectedBuild {
reason = "in-flight build"
}
candidates = append(candidates, GCCandidate{
Kind: "build_log",
ID: buildIDString(build.ID),
PluginID: build.PluginID,
Protected: protectedBuild,
Reason: reason,
SizeBytes: int64(len(build.LogSummary)),
CreatedAt: build.CreatedAt,
})
}
return candidates, nil
}
func (m *Manager) RunGC(ctx context.Context, actor string, dryRun bool) ([]GCCandidate, error) {
candidates, err := m.GCCandidates(ctx)
if err != nil {
return nil, err
}
if dryRun {
_ = m.repo.RecordOperation(ctx, "", "", "artifact_gc", "dry_run", actor, "artifact gc dry-run completed", map[string]any{
"candidates": len(candidates),
})
return candidates, nil
}
var removed []GCCandidate
for _, candidate := range candidates {
if candidate.Protected || candidate.Path == "" || candidate.Kind != "artifact" {
continue
}
if err := os.RemoveAll(candidate.Path); err != nil {
_ = m.repo.RecordOperation(ctx, candidate.PluginID, candidate.ID, "artifact_gc", "failed", actor, err.Error(), map[string]any{
"path": candidate.Path,
})
continue
}
removed = append(removed, candidate)
}
_ = m.repo.RecordOperation(ctx, "", "", "artifact_gc", "succeeded", actor, "artifact gc completed", map[string]any{
"removed": len(removed),
})
return removed, nil
}
func artifactGCPath(artifact ArtifactRecord) string {
if artifact.FilePath == "" {
return ""
}
return filepath.Dir(artifact.FilePath)
}
func dirSize(root string) int64 {
var total int64
_ = filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error {
if err != nil || d.IsDir() {
return nil
}
if info, err := d.Info(); err == nil {
total += info.Size()
}
return nil
})
return total
}
func buildIDString(id int64) string {
return strconv.FormatInt(id, 10)
}