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