-
Notifications
You must be signed in to change notification settings - Fork 63
Implement operator logic #25
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
Changes from 10 commits
4e5621a
d0b58db
89d921c
195dd9f
b9ed4e6
cc903d3
c58d32f
4e7b6d9
3bb4d65
333d284
306f0ba
6be8f31
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,25 +9,30 @@ import ( | |
|
|
||
| "github.com/openshift-kni/performance-addon-operators/pkg/apis" | ||
| "github.com/openshift-kni/performance-addon-operators/pkg/controller" | ||
| "github.com/openshift-kni/performance-addon-operators/pkg/controller/performanceprofile/components" | ||
| "github.com/openshift-kni/performance-addon-operators/version" | ||
|
|
||
| configv1 "github.com/openshift/api/config/v1" | ||
| tunedv1 "github.com/openshift/cluster-node-tuning-operator/pkg/apis/tuned/v1" | ||
| mcov1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" | ||
| "github.com/operator-framework/operator-sdk/pkg/k8sutil" | ||
| kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics" | ||
| "github.com/operator-framework/operator-sdk/pkg/log/zap" | ||
| "github.com/operator-framework/operator-sdk/pkg/metrics" | ||
| "github.com/operator-framework/operator-sdk/pkg/restmapper" | ||
| sdkVersion "github.com/operator-framework/operator-sdk/version" | ||
| "github.com/spf13/pflag" | ||
|
|
||
| v1 "k8s.io/api/core/v1" | ||
| metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
| "k8s.io/apimachinery/pkg/util/intstr" | ||
| "k8s.io/klog" | ||
|
|
||
| // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) | ||
| _ "k8s.io/client-go/plugin/pkg/client/auth" | ||
| "k8s.io/client-go/rest" | ||
|
|
||
| "sigs.k8s.io/controller-runtime/pkg/cache" | ||
| "sigs.k8s.io/controller-runtime/pkg/client/config" | ||
| logf "sigs.k8s.io/controller-runtime/pkg/log" | ||
| "sigs.k8s.io/controller-runtime/pkg/manager" | ||
| "sigs.k8s.io/controller-runtime/pkg/manager/signals" | ||
| ) | ||
|
|
@@ -38,53 +43,50 @@ var ( | |
| metricsPort int32 = 8383 | ||
| operatorMetricsPort int32 = 8686 | ||
| ) | ||
| var log = logf.Log.WithName("cmd") | ||
|
|
||
| func printVersion() { | ||
| log.Info(fmt.Sprintf("Operator Version: %s", version.Version)) | ||
| log.Info(fmt.Sprintf("Go Version: %s", runtime.Version())) | ||
| log.Info(fmt.Sprintf("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH)) | ||
| log.Info(fmt.Sprintf("Version of operator-sdk: %v", sdkVersion.Version)) | ||
| klog.Infof("Operator Version: %s", version.Version) | ||
| klog.Infof("Go Version: %s", runtime.Version()) | ||
| klog.Infof("Go OS/Arch: %s/%s", runtime.GOOS, runtime.GOARCH) | ||
| klog.Infof("Version of operator-sdk: %v", sdkVersion.Version) | ||
| } | ||
|
|
||
| func main() { | ||
| // Add the zap logger flag set to the CLI. The flag set must | ||
| // be added before calling pflag.Parse(). | ||
| pflag.CommandLine.AddFlagSet(zap.FlagSet()) | ||
| // Add klog flags | ||
| klog.InitFlags(nil) | ||
|
|
||
| // Add flags registered by imported packages (e.g. glog and | ||
| // controller-runtime) | ||
| pflag.CommandLine.AddGoFlagSet(flag.CommandLine) | ||
|
|
||
| pflag.Parse() | ||
|
|
||
| // Use a zap logr.Logger implementation. If none of the zap | ||
| // flags are configured (or if the zap flag set is not being | ||
| // used), this defaults to a production zap logger. | ||
| // | ||
| // The logger instantiated here can be changed to any logger | ||
| // implementing the logr.Logger interface. This logger will | ||
| // be propagated through the whole operator, generating | ||
| // uniform and structured logs. | ||
| logf.SetLogger(zap.Logger()) | ||
|
|
||
| printVersion() | ||
|
|
||
| namespace, err := k8sutil.GetWatchNamespace() | ||
| if err != nil { | ||
| log.Error(err, "Failed to get watch namespace") | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| // we have two namespaces that we need to watch | ||
| // 1. tuned namespace - for tuned resources | ||
| // 2. None namespace - for cluster wide resources | ||
| namespaces := []string{ | ||
| components.NamespaceNodeTuningOperator, | ||
| metav1.NamespaceNone, | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please add a one-line comment to remind our future selves what "None namespace" means in this context? (e.g. watch all the namespaces, even though IIRC this is not the case)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
| } | ||
|
|
||
| // Get a config to talk to the apiserver | ||
| cfg, err := config.GetConfig() | ||
| if err != nil { | ||
| log.Error(err, "") | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| // Create a new Cmd to provide shared dependencies and start components | ||
| mgr, err := manager.New(cfg, manager.Options{ | ||
| NewCache: cache.MultiNamespacedCacheBuilder(namespaces), | ||
| LeaderElection: true, | ||
| LeaderElectionID: "performance-addon-operators", | ||
| LeaderElectionNamespace: namespace, | ||
|
|
@@ -93,26 +95,41 @@ func main() { | |
| MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort), | ||
| }) | ||
| if err != nil { | ||
| log.Error(err, "") | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| log.Info("Registering Components.") | ||
| klog.Info("Registering Components.") | ||
|
|
||
| // Setup Scheme for all resources | ||
| if err := apis.AddToScheme(mgr.GetScheme()); err != nil { | ||
| log.Error(err, "") | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| if err := configv1.AddToScheme(mgr.GetScheme()); err != nil { | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| if err := mcov1.AddToScheme(mgr.GetScheme()); err != nil { | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| if err := tunedv1.AddToScheme(mgr.GetScheme()); err != nil { | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| // Setup all Controllers | ||
| if err := controller.AddToManager(mgr); err != nil { | ||
| log.Error(err, "") | ||
| klog.Error(err.Error()) | ||
| os.Exit(1) | ||
| } | ||
|
|
||
| if err = serveCRMetrics(cfg); err != nil { | ||
| log.Info("Could not generate and serve custom resource metrics", "error", err.Error()) | ||
| klog.Errorf("Could not generate and serve custom resource metrics: %v", err) | ||
| } | ||
|
|
||
| // Add to the below struct any other metrics ports you want to expose. | ||
|
|
@@ -123,27 +140,27 @@ func main() { | |
| // Create Service object to expose the metrics port(s). | ||
| service, err := metrics.CreateMetricsService(context.TODO(), cfg, servicePorts) | ||
| if err != nil { | ||
| log.Info("Could not create metrics Service", "error", err.Error()) | ||
| klog.Errorf("Could not create metrics Service: %v", err) | ||
| } | ||
|
|
||
| // CreateServiceMonitors will automatically create the prometheus-operator ServiceMonitor resources | ||
| // necessary to configure Prometheus to scrape metrics from this operator. | ||
| services := []*v1.Service{service} | ||
| _, err = metrics.CreateServiceMonitors(cfg, namespace, services) | ||
| if err != nil { | ||
| log.Info("Could not create ServiceMonitor object", "error", err.Error()) | ||
| klog.Errorf("Could not create ServiceMonitor object: %v", err) | ||
| // If this operator is deployed to a cluster without the prometheus-operator running, it will return | ||
| // ErrServiceMonitorNotPresent, which can be used to safely skip ServiceMonitor creation. | ||
| if err == metrics.ErrServiceMonitorNotPresent { | ||
| log.Info("Install prometheus-operator in your cluster to create ServiceMonitor objects", "error", err.Error()) | ||
| klog.Errorf("Install prometheus-operator in your cluster to create ServiceMonitor objects: %v", err) | ||
| } | ||
| } | ||
|
|
||
| log.Info("Starting the Cmd.") | ||
| klog.Info("Starting the Cmd.") | ||
|
|
||
| // Start the Cmd | ||
| if err := mgr.Start(signals.SetupSignalHandler()); err != nil { | ||
| log.Error(err, "Manager exited non-zero") | ||
| klog.Errorf("Manager exited with non-zero code: %v", err) | ||
| os.Exit(1) | ||
| } | ||
| } | ||
|
|
@@ -157,13 +174,9 @@ func serveCRMetrics(cfg *rest.Config) error { | |
| if err != nil { | ||
| return err | ||
| } | ||
| // Get the namespace the operator is currently deployed in. | ||
| operatorNs, err := k8sutil.GetOperatorNamespace() | ||
| if err != nil { | ||
| return err | ||
| } | ||
|
|
||
| // To generate metrics in other namespaces, add the values below. | ||
| ns := []string{operatorNs} | ||
| ns := []string{metav1.NamespaceNone} | ||
| // Generate and serve custom resource specific metrics. | ||
| err = kubemetrics.GenerateAndServeCRMetrics(cfg, ns, filteredGVK, metricsHost, operatorMetricsPort) | ||
| if err != nil { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
|
|
@@ -3,5 +3,16 @@ kind: PerformanceProfile | |||
| metadata: | ||||
| name: example-performanceprofile | ||||
| spec: | ||||
| # Add fields here | ||||
| size: 3 | ||||
| cpu: | ||||
| isolated: "2-3" | ||||
| nonIsolated: "0" | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you please clarify the state of CPU 1? how could it be neither
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe even add a validation hook on that later on ?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it is just example that will be injected under the CSV and does not the real case performance-addon-operators/pkg/controller/performanceprofile/performanceprofile_controller.go Line 229 in fd9054e
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ack, good enough for me now
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMHO examples should be easy to understand, people will see and copy/paste this.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @slintes this CR example injected into CSV, so I do not add some comments to it(unsure regarding parsing), what example do you prefer? |
||||
| reserved: "0-1" | ||||
| hugepages: | ||||
| defaultHugepagesSize: "1G" | ||||
| pages: | ||||
| - size: "1G" | ||||
| count: 2 | ||||
| realTimeKernel: | ||||
| repoURL: "http://download-node-02.eng.bos.redhat.com/rhel-8/nightly/RHEL-8/latest-RHEL-8.1.1/compose/RT/x86_64/os" | ||||
| nodeSelector: | ||||
| node-role.kubernetes.io/performance: "" | ||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: klog.Exit(...) is a shortcut (same below)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done