diff --git a/PROJECT b/PROJECT index 630ead4..d8a0d0b 100644 --- a/PROJECT +++ b/PROJECT @@ -16,4 +16,13 @@ resources: kind: OSArtifact path: github.com/kairos-io/osbuilder/api/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + controller: true + domain: kairos.io + group: build + kind: NetbootDeployment + path: github.com/kairos-io/osbuilder/api/v1alpha1 + version: v1alpha1 version: "3" diff --git a/api/v1alpha1/netbootdeployment_types.go b/api/v1alpha1/netbootdeployment_types.go new file mode 100644 index 0000000..bb44d3e --- /dev/null +++ b/api/v1alpha1/netbootdeployment_types.go @@ -0,0 +1,63 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// NetbootDeploymentSpec defines the desired state of NetbootDeployment +type NetbootDeploymentSpec struct { + CloudConfig string `json:"cloudConfig,omitempty"` + CommandLine string `json:"cmdLine,omitempty"` + + // TODO: Those below should be deprecated and reference an osbuild instead +} + +// NetbootDeploymentStatus defines the observed state of NetbootDeployment +type NetbootDeploymentStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status + +// NetbootDeployment is the Schema for the netbootdeployments API +type NetbootDeployment struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec NetbootDeploymentSpec `json:"spec,omitempty"` + Status NetbootDeploymentStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// NetbootDeploymentList contains a list of NetbootDeployment +type NetbootDeploymentList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []NetbootDeployment `json:"items"` +} + +func init() { + SchemeBuilder.Register(&NetbootDeployment{}, &NetbootDeploymentList{}) +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 52bab9d..baf95cb 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -40,6 +40,95 @@ func (in *LocalObjectReference) DeepCopy() *LocalObjectReference { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetbootDeployment) DeepCopyInto(out *NetbootDeployment) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + out.Status = in.Status +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetbootDeployment. +func (in *NetbootDeployment) DeepCopy() *NetbootDeployment { + if in == nil { + return nil + } + out := new(NetbootDeployment) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NetbootDeployment) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetbootDeploymentList) DeepCopyInto(out *NetbootDeploymentList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]NetbootDeployment, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetbootDeploymentList. +func (in *NetbootDeploymentList) DeepCopy() *NetbootDeploymentList { + if in == nil { + return nil + } + out := new(NetbootDeploymentList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *NetbootDeploymentList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetbootDeploymentSpec) DeepCopyInto(out *NetbootDeploymentSpec) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetbootDeploymentSpec. +func (in *NetbootDeploymentSpec) DeepCopy() *NetbootDeploymentSpec { + if in == nil { + return nil + } + out := new(NetbootDeploymentSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetbootDeploymentStatus) DeepCopyInto(out *NetbootDeploymentStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetbootDeploymentStatus. +func (in *NetbootDeploymentStatus) DeepCopy() *NetbootDeploymentStatus { + if in == nil { + return nil + } + out := new(NetbootDeploymentStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *OSArtifact) DeepCopyInto(out *OSArtifact) { *out = *in diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 7a07db9..9d415bd 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -3,17 +3,20 @@ # It should be run by config/default resources: - bases/build.kairos.io_osartifacts.yaml +- bases/build.kairos.io_netbootdeployments.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix. # patches here are for enabling the conversion webhook for each CRD #- patches/webhook_in_osartifacts.yaml +#- patches/webhook_in_netbootdeployments.yaml #+kubebuilder:scaffold:crdkustomizewebhookpatch # [CERTMANAGER] To enable cert-manager, uncomment all the sections with [CERTMANAGER] prefix. # patches here are for enabling the CA injection for each CRD #- patches/cainjection_in_osartifacts.yaml +#- patches/cainjection_in_netbootdeployments.yaml #+kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_netbootdeployments.yaml b/config/crd/patches/cainjection_in_netbootdeployments.yaml new file mode 100644 index 0000000..a779e50 --- /dev/null +++ b/config/crd/patches/cainjection_in_netbootdeployments.yaml @@ -0,0 +1,7 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: netbootdeployments.build.kairos.io diff --git a/config/crd/patches/webhook_in_netbootdeployments.yaml b/config/crd/patches/webhook_in_netbootdeployments.yaml new file mode 100644 index 0000000..5ed242f --- /dev/null +++ b/config/crd/patches/webhook_in_netbootdeployments.yaml @@ -0,0 +1,16 @@ +# The following patch enables a conversion webhook for the CRD +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + name: netbootdeployments.build.kairos.io +spec: + conversion: + strategy: Webhook + webhook: + clientConfig: + service: + namespace: system + name: webhook-service + path: /convert + conversionReviewVersions: + - v1 diff --git a/config/rbac/netbootdeployment_editor_role.yaml b/config/rbac/netbootdeployment_editor_role.yaml new file mode 100644 index 0000000..31da158 --- /dev/null +++ b/config/rbac/netbootdeployment_editor_role.yaml @@ -0,0 +1,24 @@ +# permissions for end users to edit netbootdeployments. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: netbootdeployment-editor-role +rules: +- apiGroups: + - build.kairos.io + resources: + - netbootdeployments + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - build.kairos.io + resources: + - netbootdeployments/status + verbs: + - get diff --git a/config/rbac/netbootdeployment_viewer_role.yaml b/config/rbac/netbootdeployment_viewer_role.yaml new file mode 100644 index 0000000..19d9b71 --- /dev/null +++ b/config/rbac/netbootdeployment_viewer_role.yaml @@ -0,0 +1,20 @@ +# permissions for end users to view netbootdeployments. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: netbootdeployment-viewer-role +rules: +- apiGroups: + - build.kairos.io + resources: + - netbootdeployments + verbs: + - get + - list + - watch +- apiGroups: + - build.kairos.io + resources: + - netbootdeployments/status + verbs: + - get diff --git a/config/samples/build_v1alpha1_netbootdeployment.yaml b/config/samples/build_v1alpha1_netbootdeployment.yaml new file mode 100644 index 0000000..0f70f76 --- /dev/null +++ b/config/samples/build_v1alpha1_netbootdeployment.yaml @@ -0,0 +1,6 @@ +apiVersion: build.kairos.io/v1alpha1 +kind: NetbootDeployment +metadata: + name: netbootdeployment-sample +spec: + # TODO(user): Add fields here diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index d7adec5..880ce03 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -1,4 +1,5 @@ ## Append samples you want in your CSV to this file as resources ## resources: - build_v1alpha1_osartifact.yaml +- build_v1alpha1_netbootdeployment.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/controllers/netboot-deployment.go b/controllers/netboot-deployment.go new file mode 100644 index 0000000..cdf5e11 --- /dev/null +++ b/controllers/netboot-deployment.go @@ -0,0 +1,99 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "fmt" + + buildv1alpha1 "github.com/kairos-io/osbuilder/api/v1alpha1" + appsv1 "k8s.io/api/apps/v1" + v1 "k8s.io/api/core/v1" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (r *NetbootDeploymentReconciler) genDeployment(artifact buildv1alpha1.NetbootDeployment) *appsv1.Deployment { + // TODO: svc is unused, but could be used in the future to generate the Netboot URL + objMeta := metav1.ObjectMeta{ + Name: artifact.Name, + Namespace: artifact.Namespace, + OwnerReferences: genNetbootOwner(artifact), + } + + privileged := false + serviceAccount := false + + servingContainer := v1.Container{ + ImagePullPolicy: v1.PullAlways, + SecurityContext: &v1.SecurityContext{Privileged: &privileged}, + Name: "serve", + Args: []string{ + + "boot", + fmt.Sprintf(), + fmt.Sprintf(), + fmt.Sprintf(), + }, + Image: r.Image, + VolumeMounts: []v1.VolumeMount{ + { + Name: "config", + MountPath: "/files/config.yaml", + SubPath: "cloudconfig", + }, + }, + } + // boot /files/kairos-core-opensuse-kernel /files/kairos-core-opensuse-initrd --cmdline='rd.neednet=1 ip=dhcp rd.cos.disable root=live:https://github.com/kairos-io/provider-kairos/releases/download/v1.2.0/kairos-alpine-ubuntu-v1.2.0-k3sv1.20.15+k3s1.squashfs netboot nodepair.enable config_url={{ ID "/files/config.yaml" }} console=tty1 console=ttyS0 console=tty0' + pod := v1.PodSpec{ + HostNetwork: true, + AutomountServiceAccountToken: &serviceAccount, + Volumes: []v1.Volume{ + { + Name: "config", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{Name: fmt.Sprintf("%s-netboot", artifact.Name)}}}, + }, + }, + } + + pod.Containers = []v1.Container{servingContainer} + + deploymentLabels := genNetDeploymentLabel(artifact.Name) + replicas := int32(1) + + return &appsv1.Deployment{ + ObjectMeta: objMeta, + + Spec: appsv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{MatchLabels: deploymentLabels}, + Replicas: &replicas, + Template: v1.PodTemplateSpec{ + + ObjectMeta: metav1.ObjectMeta{ + Labels: deploymentLabels, + }, + Spec: pod, + }, + }, + } +} +func genNetDeploymentLabel(s string) map[string]string { + return map[string]string{ + "netboot": "serve" + s, + } +} diff --git a/controllers/netbootdeployment_controller.go b/controllers/netbootdeployment_controller.go new file mode 100644 index 0000000..0ea83f9 --- /dev/null +++ b/controllers/netbootdeployment_controller.go @@ -0,0 +1,145 @@ +/* +Copyright 2022. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package controllers + +import ( + "context" + "fmt" + + v1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/kubernetes" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/log" + + buildv1alpha1 "github.com/kairos-io/osbuilder/api/v1alpha1" +) + +// NetbootDeploymentReconciler reconciles a NetbootDeployment object +type NetbootDeploymentReconciler struct { + client.Client + clientSet *kubernetes.Clientset + + Image string + Scheme *runtime.Scheme +} + +//+kubebuilder:rbac:groups=build.kairos.io,resources=netbootdeployments,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=build.kairos.io,resources=netbootdeployments/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=build.kairos.io,resources=netbootdeployments/finalizers,verbs=update + +// Reconcile is part of the main kubernetes reconciliation loop which aims to +// move the current state of the cluster closer to the desired state. +// TODO(user): Modify the Reconcile function to compare the state specified by +// the NetbootDeployment object against the actual cluster state, and then +// perform operations to make the cluster state reflect the state specified by +// the user. +// +// For more details, check Reconcile and its Result here: +// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.12.2/pkg/reconcile +func (r *NetbootDeploymentReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { + logger := log.FromContext(ctx) + var netboot buildv1alpha1.NetbootDeployment + if err := r.Get(ctx, req.NamespacedName, &netboot); err != nil { + if apierrors.IsNotFound(err) { + return ctrl.Result{}, nil + } + return ctrl.Result{}, err + } + + logger.Info(fmt.Sprintf("Reconciling %v", netboot)) + // generate configmap required for building a custom image + desiredConfigMap := r.genConfigMap(netboot) + logger.Info(fmt.Sprintf("Checking configmap %v", netboot)) + + cfgMap, err := r.clientSet.CoreV1().ConfigMaps(req.Namespace).Get(ctx, desiredConfigMap.Name, metav1.GetOptions{}) + if cfgMap == nil || apierrors.IsNotFound(err) { + logger.Info(fmt.Sprintf("Creating service %v", desiredConfigMap)) + + cfgMap, err = r.clientSet.CoreV1().ConfigMaps(req.Namespace).Create(ctx, desiredConfigMap, metav1.CreateOptions{}) + if err != nil { + logger.Error(err, "Failed while creating cfgmap") + return ctrl.Result{}, err + } + return ctrl.Result{Requeue: true}, err + } + if err != nil { + return ctrl.Result{Requeue: true}, err + } + + desiredDeployment := r.genDeployment(netboot) + deployment, err := r.clientSet.AppsV1().Deployments(req.Namespace).Get(ctx, desiredDeployment.Name, metav1.GetOptions{}) + if deployment == nil || apierrors.IsNotFound(err) { + logger.Info(fmt.Sprintf("Creating Deployment %v", deployment)) + + deployment, err = r.clientSet.AppsV1().Deployments(req.Namespace).Create(ctx, desiredDeployment, metav1.CreateOptions{}) + if err != nil { + logger.Error(err, "Failed while creating deployment") + return ctrl.Result{}, nil + } + + return ctrl.Result{Requeue: true}, nil + } + if err != nil { + return ctrl.Result{Requeue: true}, err + } + + // TODO(user): your logic here + + return ctrl.Result{}, nil +} + +// SetupWithManager sets up the controller with the Manager. +func (r *NetbootDeploymentReconciler) SetupWithManager(mgr ctrl.Manager) error { + + clientset, err := kubernetes.NewForConfig(mgr.GetConfig()) + if err != nil { + return err + } + r.clientSet = clientset + + return ctrl.NewControllerManagedBy(mgr). + For(&buildv1alpha1.NetbootDeployment{}). + Complete(r) +} + +func genNetbootOwner(artifact buildv1alpha1.NetbootDeployment) []metav1.OwnerReference { + return []metav1.OwnerReference{ + *metav1.NewControllerRef(&artifact.ObjectMeta, schema.GroupVersionKind{ + Group: buildv1alpha1.GroupVersion.Group, + Version: buildv1alpha1.GroupVersion.Version, + Kind: "NetbootDeployment", + }), + } +} + +func (r *NetbootDeploymentReconciler) genConfigMap(artifact buildv1alpha1.NetbootDeployment) *v1.ConfigMap { + return &v1.ConfigMap{ + + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("%s-netboot", artifact.Name), + Namespace: artifact.Namespace, + OwnerReferences: genNetbootOwner(artifact), + }, + Data: map[string]string{ + "cloudconfig": artifact.Spec.CloudConfig, + }} +} diff --git a/go.sum b/go.sum index 4a58aaa..4bf6301 100644 --- a/go.sum +++ b/go.sum @@ -189,7 +189,6 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng= github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobuffalo/flect v0.2.4 h1:BSYA8+T60cdyq+vynaSUjqSVI9mDEg9ZfQUXKmfjo4I= github.com/gobuffalo/flect v0.2.4/go.mod h1:1ZyCLIbg0YD7sDkzvFdPoOydPtD8y9JQnrOROolUcM8= @@ -278,7 +277,6 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= @@ -828,7 +826,6 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717 h1:hI3jKY4Hpf63ns040onEbB3dAkR/H/P83hw1TG8dD3Y= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/main.go b/main.go index 61a2ae5..3690eb4 100644 --- a/main.go +++ b/main.go @@ -103,6 +103,13 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "OSArtifact") os.Exit(1) } + if err = (&controllers.NetbootDeploymentReconciler{ + Client: mgr.GetClient(), + Scheme: mgr.GetScheme(), + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "NetbootDeployment") + os.Exit(1) + } //+kubebuilder:scaffold:builder if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {