...
1 package displayctl
2
3 import (
4 "context"
5 "fmt"
6 "os"
7
8 "k8s.io/apimachinery/pkg/api/errors"
9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10 kruntime "k8s.io/apimachinery/pkg/runtime"
11 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
12 clientgoscheme "k8s.io/client-go/kubernetes/scheme"
13 "k8s.io/client-go/rest"
14 ctrl "sigs.k8s.io/controller-runtime"
15 "sigs.k8s.io/controller-runtime/pkg/client"
16
17 "edge-infra.dev/pkg/k8s/runtime/controller"
18 "edge-infra.dev/pkg/sds/display/constants"
19 "edge-infra.dev/pkg/sds/display/displaymanager/manager"
20 xorgmanager "edge-infra.dev/pkg/sds/display/displaymanager/manager/xorg"
21 v2 "edge-infra.dev/pkg/sds/display/k8s/apis/v2"
22 )
23
24 var scheme = kruntime.NewScheme()
25
26 func init() {
27 utilruntime.Must(clientgoscheme.AddToScheme(scheme))
28 utilruntime.Must(v2.AddToScheme(scheme))
29 }
30
31 const hostnameEnvvar = "HOSTNAME"
32
33 var errHostnameEnvvarNotSet = fmt.Errorf("%s envvar is not set", hostnameEnvvar)
34
35 func Run(ctx context.Context, opts ...controller.Option) error {
36 log := ctrl.LoggerFrom(ctx).WithName(constants.DisplayctlName)
37
38 mgr, err := CreateManager(opts...)
39 if err != nil {
40 log.Error(err, "unable to create controller manager")
41 return err
42 }
43
44 hostname := os.Getenv(hostnameEnvvar)
45 if hostname == "" {
46 log.Error(errHostnameEnvvarNotSet, "unable to find hostname")
47 return errHostnameEnvvarNotSet
48 }
49
50
51 if err := createHostNodeDisplayConfig(ctx, mgr.GetConfig(), hostname); err != nil {
52 log.Error(err, "unable to create host NodeDisplayConfig")
53 return err
54 }
55
56 displayManager := xorgmanager.NewXorgDisplayManager(hostname, mgr.GetClient(), log)
57
58 if err := registerComponentsWithManager(mgr, displayManager); err != nil {
59 log.Error(err, "unable to register components with manager")
60 return err
61 }
62
63 if err := mgr.Start(ctx); err != nil {
64 log.Error(err, "displayctl received an error")
65 return err
66 }
67
68 return nil
69 }
70
71 func CreateManager(opts ...controller.Option) (ctrl.Manager, error) {
72 mgrCfg, mgrOpts := controller.ProcessOptions(opts...)
73 mgrOpts.Scheme = scheme
74 return ctrl.NewManager(mgrCfg, mgrOpts)
75 }
76
77
78 func createHostNodeDisplayConfig(ctx context.Context, restConfig *rest.Config, hostname string) error {
79 nodeDisplayConfig := &v2.NodeDisplayConfig{
80 ObjectMeta: metav1.ObjectMeta{
81 Name: hostname,
82 },
83 }
84
85
86 c, err := client.New(restConfig, client.Options{Scheme: scheme})
87 if err != nil {
88 return err
89 }
90
91 err = c.Get(ctx, client.ObjectKeyFromObject(nodeDisplayConfig), &v2.NodeDisplayConfig{})
92 if errors.IsNotFound(err) {
93 return c.Create(ctx, nodeDisplayConfig)
94 }
95 return err
96 }
97
98 func registerComponentsWithManager(mgr ctrl.Manager, displayManager manager.DisplayManager) error {
99 displayManagerWatcher := NewDisplayManagerWatcherRunnable(displayManager, mgr.GetClient())
100 if err := displayManagerWatcher.SetupWithManager(mgr); err != nil {
101 return err
102 }
103
104 deviceWatcher := NewDeviceWatcherRunnable(displayManager.Hostname(), mgr.GetClient())
105 if err := deviceWatcher.SetupWithManager(mgr); err != nil {
106 return err
107 }
108
109 nodeDisplayConfigController := NewNodeDisplayConfigController(displayManager, mgr)
110 return nodeDisplayConfigController.SetupWithManager(mgr)
111 }
112
View as plain text