diff --git a/cmd/main.go b/cmd/main.go index f2f602d..194666f 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -17,9 +17,11 @@ limitations under the License. package main import ( + "context" "crypto/tls" "flag" "os" + "os/signal" // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) // to ensure that exec-entrypoint and run can make use of them. @@ -35,7 +37,7 @@ import ( metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" "github.com/miscord-dev/cluster-api-provider-incus/internal/controller" // +kubebuilder:scaffold:imports ) @@ -48,11 +50,14 @@ var ( func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) - utilruntime.Must(infra1alpha1.AddToScheme(scheme)) + utilruntime.Must(infrav1alpha1.AddToScheme(scheme)) // +kubebuilder:scaffold:scheme } func main() { + ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt) + defer cancel() + var metricsAddr string var enableLeaderElection bool var probeAddr string @@ -143,18 +148,20 @@ func main() { setupLog.Error(err, "unable to start manager") os.Exit(1) } + logger := mgr.GetLogger() + ctx = ctrl.LoggerInto(ctx, logger) if err = (&controller.IncusClusterReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { + }).SetupWithManager(ctx, mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "IncusCluster") os.Exit(1) } if err = (&controller.IncusMachineReconciler{ Client: mgr.GetClient(), Scheme: mgr.GetScheme(), - }).SetupWithManager(mgr); err != nil { + }).SetupWithManager(ctx, mgr); err != nil { setupLog.Error(err, "unable to create controller", "controller", "IncusMachine") os.Exit(1) } diff --git a/internal/controller/incuscluster_controller.go b/internal/controller/incuscluster_controller.go index cd60ca8..63a9a28 100644 --- a/internal/controller/incuscluster_controller.go +++ b/internal/controller/incuscluster_controller.go @@ -26,12 +26,15 @@ import ( clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" "sigs.k8s.io/cluster-api/util" "sigs.k8s.io/cluster-api/util/patch" + "sigs.k8s.io/cluster-api/util/predicates" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + "sigs.k8s.io/controller-runtime/pkg/handler" "sigs.k8s.io/controller-runtime/pkg/log" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" ) // IncusClusterReconciler reconciles a IncusCluster object @@ -57,7 +60,7 @@ func (r *IncusClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request log := log.FromContext(ctx) // Fetch the IncusCluster instance - incusCluster := &infra1alpha1.IncusCluster{} + incusCluster := &infrav1alpha1.IncusCluster{} if err := r.Client.Get(ctx, req.NamespacedName, incusCluster); err != nil { if apierrors.IsNotFound(err) { return ctrl.Result{}, nil @@ -98,8 +101,8 @@ func (r *IncusClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request // Add finalizer first if not set to avoid the race condition between init and delete. // Note: Finalizers in general can only be added when the deletionTimestamp is not set. - if !controllerutil.ContainsFinalizer(incusCluster, infra1alpha1.ClusterFinalizer) { - controllerutil.AddFinalizer(incusCluster, infra1alpha1.ClusterFinalizer) + if !controllerutil.ContainsFinalizer(incusCluster, infrav1alpha1.ClusterFinalizer) { + controllerutil.AddFinalizer(incusCluster, infrav1alpha1.ClusterFinalizer) return ctrl.Result{}, nil } @@ -107,13 +110,13 @@ func (r *IncusClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request return r.reconcileNormal(ctx, cluster, incusCluster) } -func (r *IncusClusterReconciler) reconcileDelete(_ context.Context, cluster *clusterv1.Cluster, incusCluster *infra1alpha1.IncusCluster) error { - controllerutil.RemoveFinalizer(incusCluster, infra1alpha1.ClusterFinalizer) +func (r *IncusClusterReconciler) reconcileDelete(_ context.Context, cluster *clusterv1.Cluster, incusCluster *infrav1alpha1.IncusCluster) error { + controllerutil.RemoveFinalizer(incusCluster, infrav1alpha1.ClusterFinalizer) return nil } -func (r *IncusClusterReconciler) reconcileNormal(ctx context.Context, cluster *clusterv1.Cluster, incusCluster *infra1alpha1.IncusCluster) (ctrl.Result, error) { +func (r *IncusClusterReconciler) reconcileNormal(ctx context.Context, cluster *clusterv1.Cluster, incusCluster *infrav1alpha1.IncusCluster) (ctrl.Result, error) { log := log.FromContext(ctx) if incusCluster.Spec.ControlPlaneEndpoint.Host == "" { @@ -134,9 +137,16 @@ func (r *IncusClusterReconciler) reconcileNormal(ctx context.Context, cluster *c } // SetupWithManager sets up the controller with the Manager. -func (r *IncusClusterReconciler) SetupWithManager(mgr ctrl.Manager) error { +func (r *IncusClusterReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error { return ctrl.NewControllerManagedBy(mgr). - For(&infra1alpha1.IncusCluster{}). + For(&infrav1alpha1.IncusCluster{}). + Watches( + &clusterv1.Cluster{}, + handler.EnqueueRequestsFromMapFunc(util.ClusterToInfrastructureMapFunc(ctx, infrav1alpha1.GroupVersion.WithKind("IncusCluster"), mgr.GetClient(), &infrav1alpha1.IncusCluster{})), + builder.WithPredicates( + predicates.ClusterUnpaused(ctrl.LoggerFrom(ctx)), + ), + ). Named("incuscluster"). Complete(r) } diff --git a/internal/controller/incuscluster_controller_test.go b/internal/controller/incuscluster_controller_test.go index ddd8ee3..d72b8e5 100644 --- a/internal/controller/incuscluster_controller_test.go +++ b/internal/controller/incuscluster_controller_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" ) var _ = Describe("IncusCluster Controller", func() { @@ -40,13 +40,13 @@ var _ = Describe("IncusCluster Controller", func() { Name: resourceName, Namespace: "default", // TODO(user):Modify as needed } - incuscluster := &infra1alpha1.IncusCluster{} + incuscluster := &infrav1alpha1.IncusCluster{} BeforeEach(func() { By("creating the custom resource for the Kind IncusCluster") err := k8sClient.Get(ctx, typeNamespacedName, incuscluster) if err != nil && errors.IsNotFound(err) { - resource := &infra1alpha1.IncusCluster{ + resource := &infrav1alpha1.IncusCluster{ ObjectMeta: metav1.ObjectMeta{ Name: resourceName, Namespace: "default", @@ -59,7 +59,7 @@ var _ = Describe("IncusCluster Controller", func() { AfterEach(func() { // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &infra1alpha1.IncusCluster{} + resource := &infrav1alpha1.IncusCluster{} err := k8sClient.Get(ctx, typeNamespacedName, resource) Expect(err).NotTo(HaveOccurred()) diff --git a/internal/controller/incusmachine_controller.go b/internal/controller/incusmachine_controller.go index d5de3f2..dace25a 100644 --- a/internal/controller/incusmachine_controller.go +++ b/internal/controller/incusmachine_controller.go @@ -22,7 +22,7 @@ import ( "fmt" "github.com/lxc/incus/shared/api" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" "github.com/miscord-dev/cluster-api-provider-incus/pkg/incus" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -68,7 +68,7 @@ func (r *IncusMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request ctx = ctrl.LoggerInto(ctx, log) // Fetch the IncusMachine instance. - incusMachine := &infra1alpha1.IncusMachine{} + incusMachine := &infrav1alpha1.IncusMachine{} if err := r.Client.Get(ctx, req.NamespacedName, incusMachine); err != nil { if apierrors.IsNotFound(err) { return ctrl.Result{}, nil @@ -122,7 +122,7 @@ func (r *IncusMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request } // Fetch the Incus Cluster. - incusCluster := &infra1alpha1.IncusCluster{} + incusCluster := &infrav1alpha1.IncusCluster{} incusClusterName := client.ObjectKey{ Namespace: incusMachine.Namespace, Name: cluster.Spec.InfrastructureRef.Name, @@ -149,8 +149,8 @@ func (r *IncusMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request // Add finalizer first if not set to avoid the race condition between init and delete. // Note: Finalizers in general can only be added when the deletionTimestamp is not set. - if incusMachine.ObjectMeta.DeletionTimestamp.IsZero() && !controllerutil.ContainsFinalizer(incusMachine, infra1alpha1.MachineFinalizer) { - controllerutil.AddFinalizer(incusMachine, infra1alpha1.MachineFinalizer) + if incusMachine.ObjectMeta.DeletionTimestamp.IsZero() && !controllerutil.ContainsFinalizer(incusMachine, infrav1alpha1.MachineFinalizer) { + controllerutil.AddFinalizer(incusMachine, infrav1alpha1.MachineFinalizer) return ctrl.Result{}, nil } @@ -163,13 +163,13 @@ func (r *IncusMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request return r.reconcileNormal(ctx, cluster, incusCluster, machine, incusMachine) } -func patchIncusMachine(ctx context.Context, patchHelper *patch.Helper, incusMachine *infra1alpha1.IncusMachine) error { +func patchIncusMachine(ctx context.Context, patchHelper *patch.Helper, incusMachine *infrav1alpha1.IncusMachine) error { // Always update the readyCondition by summarizing the state of other conditions. // A step counter is added to represent progress during the provisioning process (instead we are hiding the step counter during the deletion process). // conditions.SetSummary(incusMachine, // conditions.WithConditions( - // infra1alpha1.ContainerProvisionedCondition, - // infra1alpha1.BootstrapExecSucceededCondition, + // infrav1alpha1.ContainerProvisionedCondition, + // infrav1alpha1.BootstrapExecSucceededCondition, // ), // conditions.WithStepCounterIf(incusMachine.ObjectMeta.DeletionTimestamp.IsZero() && incusMachine.Spec.ProviderID == nil), // ) @@ -180,13 +180,13 @@ func patchIncusMachine(ctx context.Context, patchHelper *patch.Helper, incusMach incusMachine, // patch.WithOwnedConditions{Conditions: []clusterv1.ConditionType{ // clusterv1.ReadyCondition, - // infra1alpha1.ContainerProvisionedCondition, - // infra1alpha1.BootstrapExecSucceededCondition, + // infrav1alpha1.ContainerProvisionedCondition, + // infrav1alpha1.BootstrapExecSucceededCondition, // }}, ) } -func (r *IncusMachineReconciler) reconcileDelete(ctx context.Context, incusCluster *infra1alpha1.IncusCluster, machine *clusterv1.Machine, incusMachine *infra1alpha1.IncusMachine) (ctrl.Result, error) { +func (r *IncusMachineReconciler) reconcileDelete(ctx context.Context, incusCluster *infrav1alpha1.IncusCluster, machine *clusterv1.Machine, incusMachine *infrav1alpha1.IncusMachine) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) // If the IncusMachine is being deleted, handle its deletion. @@ -199,7 +199,7 @@ func (r *IncusMachineReconciler) reconcileDelete(ctx context.Context, incusClust output, err := r.incusClient.GetInstance(ctx, incusMachine.Name) if errors.Is(err, incus.ErrorInstanceNotFound) { // Instance is already deleted so remove the finalizer. - controllerutil.RemoveFinalizer(incusMachine, infra1alpha1.MachineFinalizer) + controllerutil.RemoveFinalizer(incusMachine, infrav1alpha1.MachineFinalizer) return ctrl.Result{}, nil } if err != nil { @@ -222,7 +222,7 @@ func (r *IncusMachineReconciler) reconcileDelete(ctx context.Context, incusClust }, nil } -func (r *IncusMachineReconciler) reconcileNormal(ctx context.Context, cluster *clusterv1.Cluster, incusCluster *infra1alpha1.IncusCluster, machine *clusterv1.Machine, incusMachine *infra1alpha1.IncusMachine) (ctrl.Result, error) { +func (r *IncusMachineReconciler) reconcileNormal(ctx context.Context, cluster *clusterv1.Cluster, incusCluster *infrav1alpha1.IncusCluster, machine *clusterv1.Machine, incusMachine *infrav1alpha1.IncusMachine) (ctrl.Result, error) { log := ctrl.LoggerFrom(ctx) // Check if the infrastructure is ready, otherwise return and wait for the cluster object to be updated @@ -288,19 +288,19 @@ func (r *IncusMachineReconciler) getBootstrapData(ctx context.Context, namespace // SetupWithManager sets up the controller with the Manager. func (r *IncusMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Manager) error { - clusterToIncusMachines, err := util.ClusterToTypedObjectsMapper(mgr.GetClient(), &infra1alpha1.IncusMachineList{}, mgr.GetScheme()) + clusterToIncusMachines, err := util.ClusterToTypedObjectsMapper(mgr.GetClient(), &infrav1alpha1.IncusMachineList{}, mgr.GetScheme()) if err != nil { return err } return ctrl.NewControllerManagedBy(mgr). - For(&infra1alpha1.IncusMachine{}). + For(&infrav1alpha1.IncusMachine{}). Watches( &clusterv1.Machine{}, - handler.EnqueueRequestsFromMapFunc(util.MachineToInfrastructureMapFunc(infra1alpha1.GroupVersion.WithKind("IncusMachine"))), + handler.EnqueueRequestsFromMapFunc(util.MachineToInfrastructureMapFunc(infrav1alpha1.GroupVersion.WithKind("IncusMachine"))), ). Watches( - &infra1alpha1.IncusCluster{}, + &infrav1alpha1.IncusCluster{}, handler.EnqueueRequestsFromMapFunc(r.IncusClusterToIncusMachines), ). Watches( @@ -310,6 +310,7 @@ func (r *IncusMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl. predicates.ClusterUnpausedAndInfrastructureReady(ctrl.LoggerFrom(ctx)), ), ). + Named("incusmachine"). Complete(r) } @@ -317,7 +318,7 @@ func (r *IncusMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl. // requests for reconciliation of IncusMachines. func (r *IncusMachineReconciler) IncusClusterToIncusMachines(ctx context.Context, o client.Object) []ctrl.Request { result := []ctrl.Request{} - c, ok := o.(*infra1alpha1.IncusCluster) + c, ok := o.(*infrav1alpha1.IncusCluster) if !ok { panic(fmt.Sprintf("Expected a IncusCluster but got a %T", o)) } diff --git a/internal/controller/incusmachine_controller_test.go b/internal/controller/incusmachine_controller_test.go index f6d5628..cbbadeb 100644 --- a/internal/controller/incusmachine_controller_test.go +++ b/internal/controller/incusmachine_controller_test.go @@ -27,7 +27,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" ) var _ = Describe("IncusMachine Controller", func() { @@ -40,13 +40,13 @@ var _ = Describe("IncusMachine Controller", func() { Name: resourceName, Namespace: "default", // TODO(user):Modify as needed } - incusmachine := &infra1alpha1.IncusMachine{} + incusmachine := &infrav1alpha1.IncusMachine{} BeforeEach(func() { By("creating the custom resource for the Kind IncusMachine") err := k8sClient.Get(ctx, typeNamespacedName, incusmachine) if err != nil && errors.IsNotFound(err) { - resource := &infra1alpha1.IncusMachine{ + resource := &infrav1alpha1.IncusMachine{ ObjectMeta: metav1.ObjectMeta{ Name: resourceName, Namespace: "default", @@ -59,7 +59,7 @@ var _ = Describe("IncusMachine Controller", func() { AfterEach(func() { // TODO(user): Cleanup logic after each test, like removing the resource instance. - resource := &infra1alpha1.IncusMachine{} + resource := &infrav1alpha1.IncusMachine{} err := k8sClient.Get(ctx, typeNamespacedName, resource) Expect(err).NotTo(HaveOccurred()) diff --git a/internal/controller/suite_test.go b/internal/controller/suite_test.go index cd6f91c..f0b6936 100644 --- a/internal/controller/suite_test.go +++ b/internal/controller/suite_test.go @@ -33,7 +33,7 @@ import ( logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" // +kubebuilder:scaffold:imports ) @@ -77,7 +77,7 @@ var _ = BeforeSuite(func() { Expect(err).NotTo(HaveOccurred()) Expect(cfg).NotTo(BeNil()) - err = infra1alpha1.AddToScheme(scheme.Scheme) + err = infrav1alpha1.AddToScheme(scheme.Scheme) Expect(err).NotTo(HaveOccurred()) // +kubebuilder:scaffold:scheme diff --git a/pkg/incus/incus.go b/pkg/incus/incus.go index 75c8234..537868f 100644 --- a/pkg/incus/incus.go +++ b/pkg/incus/incus.go @@ -8,7 +8,7 @@ import ( incusclient "github.com/lxc/incus/client" "github.com/lxc/incus/shared/api" - infra1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" + infrav1alpha1 "github.com/miscord-dev/cluster-api-provider-incus/api/v1alpha1" ) var ( @@ -24,12 +24,12 @@ type CreateInstanceInput struct { Name string BootstrapData BootstrapData - infra1alpha1.InstanceSpec + infrav1alpha1.InstanceSpec } type GetInstanceOutput struct { Name string - infra1alpha1.InstanceSpec + infrav1alpha1.InstanceSpec // TODO: Add status StatusCode api.StatusCode @@ -120,7 +120,7 @@ func (c *client) GetInstance(ctx context.Context, name string) (*GetInstanceOutp return &GetInstanceOutput{ Name: name, - InstanceSpec: infra1alpha1.InstanceSpec{ + InstanceSpec: infrav1alpha1.InstanceSpec{ Architecture: resp.Architecture, Config: resp.Config, Devices: resp.Devices, @@ -129,7 +129,7 @@ func (c *client) GetInstance(ctx context.Context, name string) (*GetInstanceOutp Restore: resp.Restore, Stateful: resp.Stateful, Description: resp.Description, - Type: infra1alpha1.InstanceType(resp.Type), + Type: infrav1alpha1.InstanceType(resp.Type), }, StatusCode: resp.StatusCode, }, nil