Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add devbox phase and controller #5042

Merged
merged 13 commits into from
Sep 5, 2024
18 changes: 18 additions & 0 deletions controllers/devbox/api/v1alpha1/devbox_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,21 @@ type CommitHistory struct {
Status CommitStatus `json:"status"`
}

type DevboxPhase string

const (
// DevboxPhaseRunning means Devbox is run and run success
DevboxPhaseRunning DevboxPhase = "Running"
// DevboxPhasePending means Devbox is run but not run success
DevboxPhasePending DevboxPhase = "Pending"
//DevboxPhaseStopped means Devbox is stop and stopped success
DevboxPhaseStopped DevboxPhase = "Stopped"
//DevboxPhaseStopping means Devbox is stop and not stopped success
DevboxPhaseStopping DevboxPhase = "Stopping"
//DevboxPhaseError means Devbox is error
DevboxPhaseError DevboxPhase = "Error"
)

// DevboxStatus defines the observed state of Devbox
type DevboxStatus struct {
// +kubebuilder:validation:Optional
Expand All @@ -149,6 +164,8 @@ type DevboxStatus struct {
Network NetworkStatus `json:"network"`
// +kubebuilder:validation:Optional
CommitHistory []*CommitHistory `json:"commitHistory"`
// +kubebuilder:validation:Optional
Phase DevboxPhase `json:"phase"`
}

// +kubebuilder:object:root=true
Expand All @@ -158,6 +175,7 @@ type DevboxStatus struct {
// +kubebuilder:printcolumn:name="PodPhase",type="string",JSONPath=".status.podPhase"
// +kubebuilder:printcolumn:name="NetworkType",type="string",JSONPath=".status.network.type"
// +kubebuilder:printcolumn:name="NodePort",type="integer",JSONPath=".status.network.nodePort"
// +kubebuilder:printcolumn:name="Phase",type="string",JSONPath=".status.phase"

// Devbox is the Schema for the devboxes API
type Devbox struct {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ spec:
- jsonPath: .status.network.nodePort
name: NodePort
type: integer
- jsonPath: .status.phase
name: Phase
type: string
name: v1alpha1
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -2762,6 +2765,8 @@ spec:
required:
- type
type: object
phase:
type: string
podPhase:
description: PodPhase is a label for the condition of a pod at the
current time.
Expand Down
5 changes: 5 additions & 0 deletions controllers/devbox/deploy/manifests/deploy.yaml.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ spec:
- jsonPath: .status.network.nodePort
name: NodePort
type: integer
- jsonPath: .status.phase
name: Phase
type: string
name: v1alpha1
schema:
openAPIV3Schema:
Expand Down Expand Up @@ -2770,6 +2773,8 @@ spec:
required:
- type
type: object
phase:
type: string
podPhase:
description: PodPhase is a label for the condition of a pod at the
current time.
Expand Down
46 changes: 46 additions & 0 deletions controllers/devbox/internal/controller/devbox_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D
// only one pod is allowed, if more than one pod found, return error
if len(podList.Items) > 1 {
logger.Error(fmt.Errorf("more than one pod found"), "more than one pod found")
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseError
err := r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
return err
}
return fmt.Errorf("more than one pod found")
}

Expand Down Expand Up @@ -231,6 +237,12 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D
if len(podList.Items) == 0 {
if err := r.Create(ctx, expectPod); err != nil {
logger.Error(err, "create pod failed")
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseError
err := r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
return err
}
return err
}
// add next commit history to status
Expand Down Expand Up @@ -268,6 +280,12 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D
logger.Info("expect pod", "pod", expectPod.Name, "pod spec", expectPod.Spec)
_ = r.Delete(ctx, &podList.Items[0])
}
devbox.Status.Phase = devboxv1alpha1.DevboxPhasePending
lingdie marked this conversation as resolved.
Show resolved Hide resolved
err := r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
return err
}
case corev1.PodRunning:
//if pod is running,check pod need restart
if !helper.CheckPodConsistency(expectPod, &podList.Items[0]) {
Expand All @@ -276,6 +294,12 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D
logger.Info("expect pod", "pod", expectPod.Name, "pod spec", expectPod.Spec)
_ = r.Delete(ctx, &podList.Items[0])
}
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseRunning
err = r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
return err
}
return r.updateDevboxCommitHistory(ctx, devbox, &podList.Items[0])
case corev1.PodSucceeded:
if controllerutil.RemoveFinalizer(&podList.Items[0], FinalizerName) {
Expand All @@ -290,16 +314,33 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D
case corev1.PodFailed:
// we can't find the reason of failure, we assume the commit status is failed
// todo maybe use pod condition to get the reason of failure and update commit history status to failed by pod name
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseError
err = r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
return err
}
return r.updateDevboxCommitHistory(ctx, devbox, &podList.Items[0])
}
}
case devboxv1alpha1.DevboxStateStopped:
// check pod status, if no pod found, do nothing
if len(podList.Items) == 0 {
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseStopped
err = r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
}
return nil
}
// if pod found, remove finalizer and delete pod
if len(podList.Items) == 1 {
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseStopping
lingdie marked this conversation as resolved.
Show resolved Hide resolved
err := r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
return err
}
// remove finalizer and delete pod
if controllerutil.RemoveFinalizer(&podList.Items[0], FinalizerName) {
if err := r.Update(ctx, &podList.Items[0]); err != nil {
Expand All @@ -308,6 +349,11 @@ func (r *DevboxReconciler) syncPod(ctx context.Context, devbox *devboxv1alpha1.D
}
}
_ = r.Delete(ctx, &podList.Items[0])
devbox.Status.Phase = devboxv1alpha1.DevboxPhaseStopped
err = r.Status().Update(ctx, devbox)
if err != nil {
logger.Error(err, "update devbox phase failed")
}
return r.updateDevboxCommitHistory(ctx, devbox, &podList.Items[0])
}
}
Expand Down
Loading