func (r *ReconcileTrial) Reconcile(ctx context.Context, request reconcile.Request) (reconcile.Result, error) {
	logger := log.WithValues("Trial", request.NamespacedName)
	original := &trialsv1beta1.Trial{}
	err := r.Get(ctx, request.NamespacedName, original)
	if err != nil {
		if errors.IsNotFound(err) {
			return reconcile.Result{}, nil
		}
		logger.Error(err, "Trial Get error")
		return reconcile.Result{}, err
	}
	instance := original.DeepCopy()
	if needUpdate, finalizers := needUpdateFinalizers(instance); needUpdate {
		return r.updateFinalizers(instance, finalizers)
	}
	if !instance.IsCreated() {
		if instance.Status.StartTime == nil {
			now := metav1.Now()
			instance.Status.StartTime = &now
		}
		if instance.Status.CompletionTime == nil {
			instance.Status.CompletionTime = &metav1.Time{}
		}
		msg := "Trial is created"
		instance.MarkTrialStatusCreated(TrialCreatedReason, msg)
	} else {
		err := r.reconcileTrial(instance)
		if err != nil {
			if err == errMetricsNotReported {
				return reconcile.Result{
					RequeueAfter: time.Second * 1,
				}, nil
			}
			logger.Error(err, "Reconcile trial error")
			r.recorder.Eventf(instance,
				corev1.EventTypeWarning, consts.ReconcileErrorReason,
				"Failed to reconcile: %v", err)
			return reconcile.Result{}, err
		}
	}
	if !equality.Semantic.DeepEqual(original.Status, instance.Status) {
		err = r.updateStatusHandler(instance)
		if err != nil {
			logger.Info("Update trial instance status failed, reconcile requeued", "err", err)
			return reconcile.Result{
				Requeue: true,
			}, nil
		}
	}
	return reconcile.Result{}, nil
}
Reconcile reads that state of the cluster for a Trial object and makes changes based on the state read
and what is in the Trial.Spec
+kubebuilder:rbac:groups=trials.kubeflow.org,resources=trials,verbs=get;list;watch;create;update;patch;delete
+kubebuilder:rbac:groups=trials.kubeflow.org,resources=trials/status,verbs=get;update;patch
package trial
import (
	"context"
	"fmt"
	"time"
	"github.com/spf13/viper"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/equality"
	"k8s.io/apimachinery/pkg/api/errors"
	"k8s.io/apimachinery/pkg/api/meta"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/runtime/schema"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/tools/record"
	"sigs.k8s.io/controller-runtime/pkg/client"
	"sigs.k8s.io/controller-runtime/pkg/controller"
	"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
	"sigs.k8s.io/controller-runtime/pkg/handler"
	logf "sigs.k8s.io/controller-runtime/pkg/log"
	"sigs.k8s.io/controller-runtime/pkg/manager"
	"sigs.k8s.io/controller-runtime/pkg/metrics"
	"sigs.k8s.io/controller-runtime/pkg/reconcile"
	"sigs.k8s.io/controller-runtime/pkg/source"
	trialsv1beta1 "github.com/kubeflow/katib/pkg/apis/controller/trials/v1beta1"
	"github.com/kubeflow/katib/pkg/controller.v1beta1/consts"
	"github.com/kubeflow/katib/pkg/controller.v1beta1/trial/managerclient"
	trialutil "github.com/kubeflow/katib/pkg/controller.v1beta1/trial/util"
)
const (
	ControllerName = "trial-controller"
)
var (
	log = logf.Log.WithName(ControllerName)
	errMetricsNotReported = fmt.Errorf("metrics are not reported yet")
)
func Add(mgr manager.Manager) error {
	return add(mgr, newReconciler(mgr))
}
func newReconciler(mgr manager.Manager) reconcile.Reconciler {
	r := &ReconcileTrial{
		Client:        mgr.GetClient(),
		scheme:        mgr.GetScheme(),
		ManagerClient: managerclient.New(),
		recorder:      mgr.GetEventRecorderFor(ControllerName),
		collector:     trialutil.NewTrialsCollector(mgr.GetCache(), metrics.Registry),
	}
	r.updateStatusHandler = r.updateStatus
	return r
}
func add(mgr manager.Manager, r reconcile.Reconciler) error {
	c, err := controller.New("trial-controller", mgr, controller.Options{Reconciler: r})
	if err != nil {
		log.Error(err, "Create trial controller error")
		return err
	}
	err = c.Watch(&source.Kind{Type: &trialsv1beta1.Trial{}}, &handler.EnqueueRequestForObject{})
	if err != nil {
		log.Error(err, "Trial watch error")
		return err
	}
	trialResources := viper.Get(consts.ConfigTrialResources)
	if trialResources != nil {
		gvkList := trialResources.(trialutil.GvkListFlag)
		for _, gvk := range gvkList {
			_, err := mgr.GetRESTMapper().RESTMapping(gvk.GroupKind(), gvk.Version)
			if err != nil {
				if meta.IsNoMatchError(err) {
					log.Info("Job watch error. CRD might be missing. Please install CRD and restart katib-controller",
						"CRD Group", gvk.Group, "CRD Version", gvk.Version, "CRD Kind", gvk.Kind)
					continue
				}
				return err
			}
			unstructuredJob := &unstructured.Unstructured{}
			unstructuredJob.SetGroupVersionKind(gvk)
			err = c.Watch(
				&source.Kind{Type: unstructuredJob},
				&handler.EnqueueRequestForOwner{
					IsController: true,
					OwnerType:    &trialsv1beta1.Trial{},
				})
			if err != nil {
				return err
			}
			log.Info("Job watch added successfully",
				"CRD Group", gvk.Group, "CRD Version", gvk.Version, "CRD Kind", gvk.Kind)
		}
	}
	log.Info("Trial controller created")
	return nil
}
var _ reconcile.Reconciler = &ReconcileTrial{}
type ReconcileTrial struct {
	client.Client
	scheme   *runtime.Scheme
	recorder record.EventRecorder
	managerclient.ManagerClient
	updateStatusHandler updateStatusFunc
	collector *trialutil.TrialsCollector
}