github.com/tilt-dev/tilt@v0.33.15-0.20240515162809-0a22ed45d8a0/internal/controllers/manager.go (about) 1 package controllers 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "k8s.io/apimachinery/pkg/runtime" 9 "k8s.io/client-go/rest" 10 ctrl "sigs.k8s.io/controller-runtime" 11 "sigs.k8s.io/controller-runtime/pkg/client" 12 ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" 13 metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server" 14 15 "github.com/go-logr/logr" 16 "github.com/go-logr/logr/funcr" 17 18 "github.com/tilt-dev/tilt/internal/hud/server" 19 "github.com/tilt-dev/tilt/internal/store" 20 "github.com/tilt-dev/tilt/pkg/logger" 21 ) 22 23 type UncachedObjects []ctrlclient.Object 24 25 func ProvideUncachedObjects() UncachedObjects { 26 return nil 27 } 28 29 type TiltServerControllerManager struct { 30 config *rest.Config 31 scheme *runtime.Scheme 32 deferredClient *DeferredClient 33 uncachedObjects UncachedObjects 34 35 manager ctrl.Manager 36 cancel context.CancelFunc 37 } 38 39 var _ store.SetUpper = &TiltServerControllerManager{} 40 var _ store.Subscriber = &TiltServerControllerManager{} 41 var _ store.TearDowner = &TiltServerControllerManager{} 42 43 func NewTiltServerControllerManager(config *server.APIServerConfig, scheme *runtime.Scheme, deferredClient *DeferredClient, uncachedObjects UncachedObjects) (*TiltServerControllerManager, error) { 44 return &TiltServerControllerManager{ 45 config: config.GenericConfig.LoopbackClientConfig, 46 scheme: scheme, 47 deferredClient: deferredClient, 48 uncachedObjects: uncachedObjects, 49 }, nil 50 } 51 52 func (m *TiltServerControllerManager) GetManager() ctrl.Manager { 53 return m.manager 54 } 55 56 func (m *TiltServerControllerManager) GetClient() ctrlclient.Client { 57 if m.manager == nil { 58 return nil 59 } 60 return m.manager.GetClient() 61 } 62 63 func (m *TiltServerControllerManager) SetUp(ctx context.Context, _ store.RStore) error { 64 ctx, m.cancel = context.WithCancel(ctx) 65 66 // controller-runtime internals don't really make use of verbosity levels, so in lieu of a better 67 // mechanism, all its logs are redirected to a custom logger that filters out logs 68 // we don't care about. 69 logr := logr.New(&logSink{ctx: ctx, logger: logger.Get(ctx), Formatter: funcr.NewFormatter(funcr.Options{})}) 70 timeout := time.Duration(0) 71 72 mgr, err := ctrl.NewManager(m.config, ctrl.Options{ 73 Scheme: m.scheme, 74 75 // Disable metrics server. 76 Metrics: metricsserver.Options{ 77 BindAddress: "0", 78 }, 79 80 // Disable health probe. 81 HealthProbeBindAddress: "0", 82 // leader election is unnecessary as a single manager instance is run in-process with 83 // the apiserver 84 LeaderElection: false, 85 LeaderElectionID: "tilt-apiserver-ctrl", 86 87 Client: client.Options{ 88 Cache: &client.CacheOptions{ 89 DisableFor: m.uncachedObjects, 90 }, 91 }, 92 93 Logger: logr, 94 GracefulShutdownTimeout: &timeout, 95 }) 96 if err != nil { 97 return fmt.Errorf("unable to create controller manager: %v", err) 98 } 99 100 // provide the deferred client with the real client now that it has been initialized 101 m.deferredClient.initialize(mgr.GetClient()) 102 m.manager = mgr 103 104 return nil 105 } 106 107 func (m *TiltServerControllerManager) TearDown(_ context.Context) { 108 if m.cancel != nil { 109 m.cancel() 110 } 111 } 112 113 // OnChange is a no-op but used to get initialized in upper along with the API server 114 func (m *TiltServerControllerManager) OnChange(_ context.Context, _ store.RStore, _ store.ChangeSummary) error { 115 return nil 116 }