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

"error": "ats.cnat.programming-kubernetes.info \"example-at\" not found" #15

Open
ishankhare07 opened this issue Sep 19, 2020 · 1 comment

Comments

@ishankhare07
Copy link

I'm getting the following error

2020-09-19T13:16:17.164+0530    INFO    controller-runtime.controller   Starting EventSource    {"controller": "at", "source": "kind source: /, Kind="}
2020-09-19T13:16:17.164+0530    INFO    controller-runtime.manager      starting metrics server {"path": "/metrics"}
2020-09-19T13:16:17.365+0530    INFO    controller-runtime.controller   Starting Controller     {"controller": "at"}
2020-09-19T13:16:17.365+0530    INFO    controller-runtime.controller   Starting workers        {"controller": "at", "worker count": 1}
2020-09-19T13:16:17.366+0530    INFO    controllers.At  === Reconciling At      {"namespace": "cnat", "at": "example-at"}
2020-09-19T13:16:17.366+0530    INFO    controllers.At  Phase: PENDING  {"namespace": "cnat", "at": "example-at"}
2020-09-19T13:16:17.366+0530    INFO    controllers.At  Checking schedule       {"namespace": "cnat", "at": "example-at", "Target": "2019-04-12T10:12:00Z"}
2020-09-19T13:16:17.366+0530    INFO    controllers.At  It's time!      {"namespace": "cnat", "at": "example-at", "ready to execute": "echo YAY!"}
2020-09-19T13:16:17.366+0530    INFO    controllers.At  === Updating status     {"namespace": "cnat", "at": "example-at"}
2020-09-19T13:16:17.682+0530    ERROR   controller-runtime.controller   Reconciler error        {"controller": "at", "request": "cnat/example-at", "error": "ats.cnat.programming-kubernetes.info \"example-at\" not found"}
github.com/go-logr/zapr.(*zapLogger).Error
        /Users/ishankhare/godev/pkg/mod/github.com/go-logr/[email protected]/zapr.go:128
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler
        /Users/ishankhare/godev/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:258
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).processNextWorkItem
        /Users/ishankhare/godev/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:232
sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).worker
        /Users/ishankhare/godev/pkg/mod/sigs.k8s.io/[email protected]/pkg/internal/controller/controller.go:211
k8s.io/apimachinery/pkg/util/wait.JitterUntil.func1
        /Users/ishankhare/godev/pkg/mod/k8s.io/[email protected]/pkg/util/wait/wait.go:152
k8s.io/apimachinery/pkg/util/wait.JitterUntil
        /Users/ishankhare/godev/pkg/mod/k8s.io/[email protected]/pkg/util/wait/wait.go:153
k8s.io/apimachinery/pkg/util/wait.Until
        /Users/ishankhare/godev/pkg/mod/k8s.io/[email protected]/pkg/util/wait/wait.go:88
^Cmake: *** [run] Error 1

I can find the said cr if i run kubectl get at example-at . But controller reports not found .

The specific line causing the error in my opinion is err = r.Status().Update(context.TODO(), instance)

Below is my whole code for at_controllers.go

package controllers

import (
	"context"

	"github.com/go-logr/logr"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	ctrl "sigs.k8s.io/controller-runtime"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"

	cnatv1alpha1 "cnat-controller/api/v1alpha1"
	"cnat-controller/pkg/scheduler"
	"cnat-controller/pkg/spawn"

	corev1 "k8s.io/api/core/v1"
)

// AtReconciler reconciles a At object
type AtReconciler struct {
	client.Client
	Log    logr.Logger
	Scheme *runtime.Scheme
}

// +kubebuilder:rbac:groups=cnat.programming-kubernetes.info,resources=ats,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=cnat.programming-kubernetes.info,resources=ats/status,verbs=get;update;patch

func (r *AtReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
	_ = context.Background()
	reqLogger := r.Log.WithValues("namespace", req.Namespace, "at", req.Name)
	reqLogger.Info("=== Reconciling At")

	// your logic here

	// fetch the At instance
	instance := &cnatv1alpha1.At{}
	err := r.Get(context.TODO(), req.NamespacedName, instance)
	if err != nil {
		if errors.IsNotFound(err) {
			return reconcile.Result{}, nil
		}

		return reconcile.Result{}, err
	}

	// if no phase set, default to pending (the initial phase):
	if instance.Status.Phase == "" {
		instance.Status.Phase = cnatv1alpha1.PhasePending
	}

	// the state diagram PENDING -> RUNNING -> DONE
	switch instance.Status.Phase {
	case cnatv1alpha1.PhasePending:
		reqLogger.Info("Phase: PENDING")
		reqLogger.Info("Checking schedule", "Target", instance.Spec.Schedule)

		// check with a tolerance of 2 seconds
		d, err := scheduler.TimeUntilSchedule(instance.Spec.Schedule)
		if err != nil {
			reqLogger.Error(err, "Schedule parsing failure")
			return reconcile.Result{}, err
		}

		// reqLogger.Info("Schedule parsing done", "Result", "diff", fmt.Sprintf("%v", d))

		if d > 0 {
			// Not yet time to execute, wait until scheduled time
			return reconcile.Result{RequeueAfter: d}, nil
		}

		reqLogger.Info("It's time!", "ready to execute", instance.Spec.Command)
		instance.Status.Phase = cnatv1alpha1.PhaseRunning
	case cnatv1alpha1.PhaseRunning:
		reqLogger.Info("Phase: RUNNING")
		pod := spawn.NewPodForCR(instance)

		// set At instance as owner and controller
		err := controllerutil.SetControllerReference(instance, pod, r.Scheme)
		if err != nil {
			return reconcile.Result{}, err
		}

		query := &corev1.Pod{}
		nsName := types.NamespacedName{Name: pod.Name, Namespace: pod.Namespace}
		err = r.Get(context.TODO(), nsName, query)

		if err != nil && errors.IsNotFound(err) {
			// create the pod
			err = r.Create(context.TODO(), pod)
			if err != nil {
				return reconcile.Result{}, err
			}
			reqLogger.Info("Pod Launched", "name", pod.Name)
		} else if err != nil {
			return reconcile.Result{}, err
		} else if query.Status.Phase == corev1.PodFailed ||
			query.Status.Phase == corev1.PodSucceeded {
			reqLogger.Info("Container terminated", "reason",
				query.Status.Reason, "message", query.Status.Message)
			instance.Status.Phase = cnatv1alpha1.PhaseDone
		} else {
			// don't requeue, it will happen automatically when pod status changes
			return reconcile.Result{}, nil
		}
	case cnatv1alpha1.PhaseDone:
		reqLogger.Info("Phase: DONE")
		return reconcile.Result{}, nil
	default:
		reqLogger.Info("NOP")
		return reconcile.Result{}, nil
	}

	// update the At instance
	reqLogger.Info("=== Updating status")
	err = r.Status().Update(context.TODO(), instance)
	if err != nil {
		reqLogger.Info("Unable to update status")
		return reconcile.Result{}, err
	}

	return reconcile.Result{}, nil
}

func (r *AtReconciler) SetupWithManager(mgr ctrl.Manager) error {
	return ctrl.NewControllerManagedBy(mgr).
		For(&cnatv1alpha1.At{}).
		Complete(r)
}
@SachinMaharana
Copy link

SachinMaharana commented Sep 29, 2020

@ishankhare07 In your, at_types.go file, add
// +kubebuilder:subresource:status
above the At struct. For example,

// +kubebuilder:object:root=true
// +kubebuilder:subresource:status

// At is the Schema for the cnats API
type At struct {
	metav1.TypeMeta   `json:",inline"`
	metav1.ObjectMeta `json:"metadata,omitempty"`

	Spec   AtSpec   `json:"spec,omitempty"`
	Status AtStatus `json:"status,omitempty"`
}

make sure to delete the existing crd, then make manifests to generate crd again and the usual commands after that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants