ce7cb702218693d08ea6d83464d2457c9250027c
This commit is contained in:
commit
34c5f8963c
1 changed files with 145336 additions and 0 deletions
97
services/project-delivery/controller/records.go
Normal file
97
services/project-delivery/controller/records.go
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"slices"
|
||||
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
)
|
||||
|
||||
const recordKey = "delivery.quorate.dev/record"
|
||||
|
||||
func (c *controller) releaseRecords(ctx context.Context, delivery *projectDelivery) error {
|
||||
known := make(map[string]bool)
|
||||
for _, attempt := range delivery.Status.Points {
|
||||
known[attempt.WorkflowName] = true
|
||||
}
|
||||
if status := delivery.Status.Continuous; status != nil && status.Attempt != nil {
|
||||
known[status.Attempt.WorkflowName] = true
|
||||
if status.Attempt.History != nil {
|
||||
for _, name := range status.Attempt.History.Workflows {
|
||||
known[name] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if status := delivery.Status.Qualification; status != nil {
|
||||
for _, attempt := range status.Attempts {
|
||||
if attempt.Phase != "Pending" && attempt.Phase != "Reserved" {
|
||||
known[attempt.WorkflowName] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
items, err := c.client.Resource(workflowGVR).Namespace(delivery.Metadata.Namespace).List(ctx, metav1.ListOptions{LabelSelector: recordKey + "=pending"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range items.Items {
|
||||
if known[item.GetName()] && ownedBy(&item, delivery.Metadata.UID) {
|
||||
if err := c.clearRecord(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *controller) releaseOrphans(ctx context.Context) error {
|
||||
items, err := c.client.Resource(workflowGVR).Namespace(metav1.NamespaceAll).List(ctx, metav1.ListOptions{LabelSelector: recordKey + "=pending"})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, item := range items.Items {
|
||||
for _, owner := range item.GetOwnerReferences() {
|
||||
if owner.Kind != "ProjectDelivery" || owner.APIVersion != "delivery.quorate.dev/v1alpha1" {
|
||||
continue
|
||||
}
|
||||
parent, err := c.client.Resource(projectDeliveryGVR).Namespace(item.GetNamespace()).Get(ctx, owner.Name, metav1.GetOptions{})
|
||||
if apierrors.IsNotFound(err) || err == nil && (parent.GetUID() != owner.UID || parent.GetDeletionTimestamp() != nil) {
|
||||
if err := c.clearRecord(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ownedBy(workflow *unstructured.Unstructured, uid string) bool {
|
||||
return slices.ContainsFunc(workflow.GetOwnerReferences(), func(owner metav1.OwnerReference) bool {
|
||||
return owner.Kind == "ProjectDelivery" && owner.APIVersion == "delivery.quorate.dev/v1alpha1" && string(owner.UID) == uid
|
||||
})
|
||||
}
|
||||
|
||||
func (c *controller) clearRecord(ctx context.Context, workflow *unstructured.Unstructured) error {
|
||||
finalizers := slices.DeleteFunc(slices.Clone(workflow.GetFinalizers()), func(name string) bool { return name == recordKey })
|
||||
if finalizers == nil {
|
||||
finalizers = []string{}
|
||||
}
|
||||
patch, err := json.Marshal(map[string]any{"metadata": map[string]any{
|
||||
"resourceVersion": workflow.GetResourceVersion(),
|
||||
"finalizers": finalizers,
|
||||
"labels": map[string]any{recordKey: nil},
|
||||
}})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = c.client.Resource(workflowGVR).Namespace(workflow.GetNamespace()).Patch(ctx, workflow.GetName(), types.MergePatchType, patch, metav1.PatchOptions{})
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
Loading…
Reference in a new issue