feat: 自动清理终态 Pod 执行器
This commit is contained in:
@@ -13,7 +13,10 @@ import (
|
||||
"git.ddupan.top/panxiao81/gitea-dynamic-runner/internal/taskworker"
|
||||
)
|
||||
|
||||
const assignmentLabel = "ci.ddupan.top/assignment-id"
|
||||
const (
|
||||
assignmentLabel = "ci.ddupan.top/assignment-id"
|
||||
terminalLabel = "ci.ddupan.top/terminal"
|
||||
)
|
||||
|
||||
// Pod is the backend state required by the reconciler, not an in-memory lifecycle record.
|
||||
type Pod struct {
|
||||
@@ -53,10 +56,49 @@ type API interface {
|
||||
ListPods(context.Context, string, string) ([]Pod, error)
|
||||
CreatePod(context.Context, PodManifest) (Pod, error)
|
||||
DeletePod(context.Context, string, string) error
|
||||
LabelPod(context.Context, string, string, map[string]string) error
|
||||
EnsureIdentityEntry(context.Context, IdentityEntry) error
|
||||
DeleteIdentityEntry(context.Context, string) error
|
||||
}
|
||||
|
||||
// MarkTerminal persists Gitea's accepted terminal state on the backend
|
||||
// resource. Cleanup can therefore resume after a controller restart.
|
||||
func (b Backend) MarkTerminal(ctx context.Context, assignmentID string) error {
|
||||
if err := b.validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if assignmentID == "" {
|
||||
return errors.New("assignment ID is required")
|
||||
}
|
||||
if err := b.API.LabelPod(ctx, b.Config.Namespace, assignmentID, map[string]string{terminalLabel: "true"}); err != nil {
|
||||
return fmt.Errorf("mark assignment Pod terminal: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CleanupTerminated removes only executors whose terminal update was accepted
|
||||
// by Gitea and whose process has exited.
|
||||
func (b Backend) CleanupTerminated(ctx context.Context) (int, error) {
|
||||
if err := b.validate(); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
pods, err := b.API.ListPods(ctx, b.Config.Namespace, terminalLabel+"=true")
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("list terminal assignment Pods: %w", err)
|
||||
}
|
||||
cleaned := 0
|
||||
for _, pod := range pods {
|
||||
if pod.Phase != "Succeeded" && pod.Phase != "Failed" {
|
||||
continue
|
||||
}
|
||||
if err := b.Delete(ctx, executor(pod)); err != nil {
|
||||
return cleaned, err
|
||||
}
|
||||
cleaned++
|
||||
}
|
||||
return cleaned, nil
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
Namespace string
|
||||
Image string
|
||||
|
||||
Reference in New Issue
Block a user