diff --git a/.github/workflows/beeai-build.yml b/.github/workflows/beeai-build.yml index 3a0e1950..9eccebf5 100644 --- a/.github/workflows/beeai-build.yml +++ b/.github/workflows/beeai-build.yml @@ -13,6 +13,7 @@ on: push: branches: - main + - tekton-pod-cleanup paths: - 'beeai/**' pull_request: diff --git a/beeai/INSTALL.md b/beeai/INSTALL.md index 0dac7c71..2f8b1b29 100644 --- a/beeai/INSTALL.md +++ b/beeai/INSTALL.md @@ -92,6 +92,10 @@ spec: # auto deploy the agent when pipeline succeeds deployAfterBuild: true + + # auto cleanup Tekton pods when pipeline succeeds + cleanupAfterBuild: true + # define agent configuration parameters agent: name: "research-agent" @@ -133,10 +137,7 @@ When a Tekton pipeline succeeds you should see the following pods: ``` NAME READY STATUS RESTARTS AGE kagenti-operator-controller-manager-585c587f7f-nxctl 1/1 Running 0 85s -research-agent-build-183740ed-build-and-push-pod 0/1 Completed 0 47s -research-agent-build-183740ed-check-subfolder-pod 0/1 Completed 0 56s -research-agent-build-183740ed-git-clone-pod 0/1 Completed 0 66s -research-agent-c7cc5f568-82chd 1/1 Running 0 9s +research-agent-c7cc5f568-82chd 1/1 Running 0 9s ``` `Important:` Take note of the agent pod name research-agent-c7cc5f568-82chd. diff --git a/beeai/api/v1/agentbuild_types.go b/beeai/api/v1/agentbuild_types.go index 4c62eabf..e479947e 100644 --- a/beeai/api/v1/agentbuild_types.go +++ b/beeai/api/v1/agentbuild_types.go @@ -60,6 +60,10 @@ type AgentBuildSpec struct { // +optional DeployAfterBuild bool `json:"deployAfterBuild,omitempty"` + // DeployAfterBuild indicates whether to automatically deploy the agent after build + // +optional + CleanupAfterBuild bool `json:"cleanupAfterBuild,omitempty"` + // Agent defines the configuration for the Agent CR that will be created // +optional Agent AgentTemplate `json:"agent,omitempty"` diff --git a/beeai/bin/controller-gen b/beeai/bin/controller-gen index 573edeeb..04cd1e7c 120000 --- a/beeai/bin/controller-gen +++ b/beeai/bin/controller-gen @@ -1 +1 @@ -/Users/cwiklik/dev/aiplatform/kagenti-operator/bin/controller-gen-v0.17.1 \ No newline at end of file +/Users/cwiklik/dev/aiplatform/public/kagenti-operator-pod-cleanup/kagenti-operator/beeai/bin/controller-gen-v0.17.1 \ No newline at end of file diff --git a/beeai/bin/kustomize b/beeai/bin/kustomize index 747cef26..a936265b 120000 --- a/beeai/bin/kustomize +++ b/beeai/bin/kustomize @@ -1 +1 @@ -/Users/cwiklik/dev/aiplatform/kagenti-operator/bin/kustomize-v5.5.0 \ No newline at end of file +/Users/cwiklik/dev/aiplatform/public/kagenti-operator-pod-cleanup/kagenti-operator/beeai/bin/kustomize-v5.5.0 \ No newline at end of file diff --git a/beeai/config/crd/bases/beeai.beeai.dev_agentbuilds.yaml b/beeai/config/crd/bases/beeai.beeai.dev_agentbuilds.yaml index 4ff85298..4f09a4a3 100644 --- a/beeai/config/crd/bases/beeai.beeai.dev_agentbuilds.yaml +++ b/beeai/config/crd/bases/beeai.beeai.dev_agentbuilds.yaml @@ -244,6 +244,10 @@ spec: type: object type: object type: object + cleanupAfterBuild: + description: DeployAfterBuild indicates whether to automatically deploy + the agent after build + type: boolean deployAfterBuild: description: DeployAfterBuild indicates whether to automatically deploy the agent after build diff --git a/beeai/config/rbac/role.yaml b/beeai/config/rbac/role.yaml index 1c1a0cdb..e4bee1b1 100644 --- a/beeai/config/rbac/role.yaml +++ b/beeai/config/rbac/role.yaml @@ -19,6 +19,15 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - delete - apiGroups: - "" resources: diff --git a/beeai/config/samples/beeai-agentbuild-local-registry.yaml b/beeai/config/samples/beeai-agentbuild-local-registry.yaml index 0fa7468e..d9273566 100644 --- a/beeai/config/samples/beeai-agentbuild-local-registry.yaml +++ b/beeai/config/samples/beeai-agentbuild-local-registry.yaml @@ -22,7 +22,8 @@ spec: # auto deploy the agent when pipeline succeeds deployAfterBuild: true - + cleanupAfterBuild: true + # define the agent configuration to deploy agent: name: "research-agent" diff --git a/beeai/internal/controller/agentbuild_controller.go b/beeai/internal/controller/agentbuild_controller.go index b2f68dfc..2e6867b4 100644 --- a/beeai/internal/controller/agentbuild_controller.go +++ b/beeai/internal/controller/agentbuild_controller.go @@ -76,7 +76,7 @@ const ( // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.20.0/pkg/reconcile func (r *AgentBuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { logger := log.FromContext(ctx) - logger.Info("Reconciling AgentBuild", "namespacedName", req.NamespacedName) + logger.Info("- Reconciling AgentBuild - ", "namespacedName", req.NamespacedName) agentBuild := &beeaiv1.AgentBuild{} err := r.Get(ctx, req.NamespacedName, agentBuild) @@ -167,14 +167,19 @@ func (r *AgentBuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) // pullRepoSecret, err := r.createSecret(ctx, agentBuild, ".dockerconfigjson", token, corev1.SecretTypeDockerConfigJson, "docker") if err != nil { - logger.Error(err, "Failed to create secret for the image repository", - "pipelineRunName", agentBuild.Status.PipelineRunName) + logger.Error(err, "Failed to create secret for the image repository", "pipelineRunName", agentBuild.Status.PipelineRunName) return ctrl.Result{}, err } return r.createAgentCR(ctx, agentBuild, pullRepoSecret, logger) } + } else if agentBuild.Status.BuildStatus == "Completed" && agentBuild.Spec.CleanupAfterBuild { + logger.Info("Reconciling AgentBuild", "Cleaning Up Tekton Pods", req.NamespacedName) + if err := r.cleanupTektonCompletedPods(ctx, agentBuild, logger); err != nil { + logger.Error(err, "Failed to cleanup tekton pods", + "pipelineRunName", agentBuild.Status.PipelineRunName) + return ctrl.Result{}, err + } } - return ctrl.Result{}, nil } else { if agentBuild.Status.BuildStatus != "Failed" { @@ -200,6 +205,39 @@ func (r *AgentBuildReconciler) Reconcile(ctx context.Context, req ctrl.Request) } } +func (r *AgentBuildReconciler) cleanupTektonCompletedPods(ctx context.Context, agentBuild *beeaiv1.AgentBuild, logger logr.Logger) error { + // Get the pods associated with the PipelineRun + pipelineRunName := agentBuild.Status.PipelineRunName + + // List the pods with the PipelineRun label + podList := &corev1.PodList{} + err := r.List(ctx, podList, client.MatchingLabels{"tekton.dev/pipelineRun": pipelineRunName}) + if err != nil { + logger.Error(err, "Failed to list pods for PipelineRun", "pipelineRunName", pipelineRunName) + return err + } + + // Filter for completed pods (Succeeded) + var completedPods []corev1.Pod + for _, pod := range podList.Items { + if pod.Status.Phase == corev1.PodSucceeded { //|| pod.Status.Phase == corev1.PodFailed { + completedPods = append(completedPods, pod) + } + } + + // Delete completed pods + for _, pod := range completedPods { + logger.Info("Deleting completed pod", "podName", pod.Name) + err := r.Delete(ctx, &pod) + if err != nil { + logger.Error(err, "Failed to delete completed pod", "podName", pod.Name) + // Continue with other pods rather than failing the cleanup + } + } + + return nil +} + func (r *AgentBuildReconciler) handleDeletion(ctx context.Context, agentBuild *beeaiv1.AgentBuild, logger logr.Logger) (ctrl.Result, error) { if controllerutil.ContainsFinalizer(agentBuild, agentBuildFinalizer) { diff --git a/charts/beeai-operator/templates/crd/beeai.beeai.dev_agentbuilds.yaml b/charts/beeai-operator/templates/crd/beeai.beeai.dev_agentbuilds.yaml index 4ff85298..4f09a4a3 100755 --- a/charts/beeai-operator/templates/crd/beeai.beeai.dev_agentbuilds.yaml +++ b/charts/beeai-operator/templates/crd/beeai.beeai.dev_agentbuilds.yaml @@ -244,6 +244,10 @@ spec: type: object type: object type: object + cleanupAfterBuild: + description: DeployAfterBuild indicates whether to automatically deploy + the agent after build + type: boolean deployAfterBuild: description: DeployAfterBuild indicates whether to automatically deploy the agent after build diff --git a/charts/beeai-operator/templates/rbac/role.yaml b/charts/beeai-operator/templates/rbac/role.yaml index 622b5beb..85e5e70d 100755 --- a/charts/beeai-operator/templates/rbac/role.yaml +++ b/charts/beeai-operator/templates/rbac/role.yaml @@ -23,6 +23,15 @@ rules: - get - list - watch +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - delete - apiGroups: - "" resources: ["persistentvolumes", "persistentvolumeclaims"]