...

Source file src/edge-infra.dev/pkg/sds/display/k8s/controllers/xserver/xserverconfig_controller.go

Documentation: edge-infra.dev/pkg/sds/display/k8s/controllers/xserver

     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  // ConfigController watches for the node's xserver-config ConfigMap and writes it to a file
    21  // on updates, also sending it to the xserver-manager's config channel.
    22  type ConfigController struct {
    23  	Name     string
    24  	Hostname string
    25  
    26  	// configChan is used by the X server config controller to send configuration to the X server.
    27  	configChan configChannel
    28  	// The X server config which is currently applied.
    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  // Reconcile display/xserver-config-HOSTNAME and display/global-openbox-config ConfigMaps.
    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  // +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch
    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  	// fetch X server config from client
    87  	config, err := xserverconfig.FromClient(ctx, c.Hostname, c.client)
    88  	if client.IgnoreNotFound(err) != nil {
    89  		return ctrl.Result{}, err
    90  	}
    91  
    92  	// if X server config does not exist, use new empty config
    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  	// if Openbox config has not been set in X server config, use the global config
    99  	if config.OpenboxConf() == "" {
   100  		if err := useGlobalOpenboxConf(ctx, config, c.client); err != nil {
   101  			return ctrl.Result{}, err
   102  		}
   103  	}
   104  
   105  	// if config has changed, send it to xserver
   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