...
1 package xserver
2
3 import (
4 "context"
5
6 corev1 "k8s.io/api/core/v1"
7 kerrors "k8s.io/apimachinery/pkg/api/errors"
8 ctrl "sigs.k8s.io/controller-runtime"
9 "sigs.k8s.io/controller-runtime/pkg/builder"
10 "sigs.k8s.io/controller-runtime/pkg/client"
11 "sigs.k8s.io/controller-runtime/pkg/event"
12 "sigs.k8s.io/controller-runtime/pkg/predicate"
13
14 "edge-infra.dev/pkg/sds/display/constants"
15 xserverconfig "edge-infra.dev/pkg/sds/display/k8s/controllers/xserver/config"
16 )
17
18 type configChannel chan *xserverconfig.Config
19
20
21
22 type ConfigController struct {
23 Name string
24 Hostname string
25
26
27 configChan configChannel
28
29 currentConfig *xserverconfig.Config
30
31 client client.Client
32 }
33
34 func NewConfigController(hostname string, configChan configChannel, c client.Client) *ConfigController {
35 return &ConfigController{
36 Name: constants.XServerConfigControllerName,
37 Hostname: hostname,
38 configChan: configChan,
39 client: c,
40 }
41 }
42
43 func (c *ConfigController) SetupWithManager(mgr ctrl.Manager) error {
44 return ctrl.NewControllerManagedBy(mgr).
45 For(&corev1.ConfigMap{}, c.createPredicates()).
46 WithEventFilter(createEventFilter()).
47 Complete(c)
48 }
49
50 func (c *ConfigController) createPredicates() builder.Predicates {
51 return builder.WithPredicates(
52 predicate.NewPredicateFuncs(configMapFilter(c.Hostname)),
53 )
54 }
55
56
57 func configMapFilter(hostname string) func(client.Object) bool {
58 return func(obj client.Object) bool {
59 if obj.GetNamespace() != constants.Namespace {
60 return false
61 }
62 return obj.GetName() == xserverconfig.ConfigMapNameFromHostname(hostname) || obj.GetName() == xserverconfig.GlobalOpenboxConfig
63 }
64 }
65
66 func createEventFilter() predicate.Predicate {
67 return predicate.Funcs{
68 CreateFunc: func(event.CreateEvent) bool {
69 return true
70 },
71 UpdateFunc: func(event.UpdateEvent) bool {
72 return true
73 },
74 DeleteFunc: func(event.DeleteEvent) bool {
75 return true
76 },
77 }
78 }
79
80
81
82 func (c *ConfigController) Reconcile(ctx context.Context, _ ctrl.Request) (ctrl.Result, error) {
83 log := ctrl.LoggerFrom(ctx).WithName(c.Name)
84 ctx = ctrl.LoggerInto(ctx, log)
85
86
87 config, err := xserverconfig.FromClient(ctx, c.Hostname, c.client)
88 if client.IgnoreNotFound(err) != nil {
89 return ctrl.Result{}, err
90 }
91
92
93 if kerrors.IsNotFound(err) {
94 log.Info("X server config not found, using default config")
95 config = xserverconfig.New(c.Hostname)
96 }
97
98
99 if config.OpenboxConf() == "" {
100 if err := useGlobalOpenboxConf(ctx, config, c.client); err != nil {
101 return ctrl.Result{}, err
102 }
103 }
104
105
106 if !xserverconfig.Equal(c.currentConfig, config) {
107 c.configChan <- config
108 c.currentConfig = config
109 }
110
111 return ctrl.Result{}, nil
112 }
113
114 func useGlobalOpenboxConf(ctx context.Context, config *xserverconfig.Config, c client.Client) error {
115 globalOpenboxConf, err := xserverconfig.GlobalOpenboxConfFromClient(ctx, c)
116 if err != nil {
117 return err
118 }
119 config.SetOpenboxConf(globalOpenboxConf)
120 return nil
121 }
122
View as plain text