// Package buildermgr — NSWatcher for multi-tenant mode. // // Listens for Namespaces labeled fission.io/managed=true and calls // AddNamespace on envWatcher and packageWatcher so they pick up // Environments and Packages in new tenant namespaces without a restart. package buildermgr import ( "context" "time" "go.uber.org/zap" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8sInformers "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" k8sCache "k8s.io/client-go/tools/cache" "github.com/fission/fission/pkg/utils" "github.com/fission/fission/pkg/utils/manager" ) // StartNSWatcher watches for Namespaces labeled fission.io/managed=true // and immediately registers per-NS informers in envWatcher and pkgWatcher. func StartNSWatcher( ctx context.Context, logger *zap.Logger, kubeClient kubernetes.Interface, envw *environmentWatcher, pkgw *packageWatcher, mgr manager.Interface, ) { nsManager, err := utils.NewWatcherNamespaceManager(ctx, utils.DefaultNSResolver().Snapshot(), utils.NamespaceSourceEnv, time.Now().UTC(), NewNamespaceSubscriber(envw, pkgw, mgr)) if err != nil { logger.Error("buildermgr.NSWatcher: BootstrapAndDispatch failed", zap.Error(err)) } factory := k8sInformers.NewSharedInformerFactoryWithOptions( kubeClient, 30*time.Minute, k8sInformers.WithTweakListOptions(func(opts *metav1.ListOptions) { opts.LabelSelector = utils.ManagedNamespaceLabelSelector() }), ) nsInformer := factory.Core().V1().Namespaces().Informer() _, _ = nsInformer.AddEventHandler(k8sCache.ResourceEventHandlerFuncs{ AddFunc: func(obj interface{}) { nsObj, ok := obj.(*corev1.Namespace) if ok { utils.HandleWatcherNamespaceAdd(ctx, logger, "buildermgr.NSWatcher", nsManager, nsObj) } }, UpdateFunc: func(oldObj, newObj interface{}) { oldNSObj, _ := oldObj.(*corev1.Namespace) nsObj, ok := newObj.(*corev1.Namespace) if ok { utils.HandleWatcherNamespaceUpdate(ctx, logger, "buildermgr.NSWatcher", nsManager, oldNSObj, nsObj) } }, DeleteFunc: func(obj interface{}) { utils.HandleWatcherNamespaceDelete(ctx, logger, "buildermgr.NSWatcher", nsManager, obj, utils.NamespaceRemovalStrategyTrackOnly) }, }) mgr.Add(ctx, func(ctx context.Context) { logger.Info("buildermgr.NSWatcher: started", zap.String("label", utils.ManagedNamespaceLabelSelector())) factory.Start(ctx.Done()) factory.WaitForCacheSync(ctx.Done()) logger.Info("buildermgr.NSWatcher: cache synced — watching for new namespaces") <-ctx.Done() logger.Info("buildermgr.NSWatcher: stopped") }) }