From 1c140c7cbc9e1cf5718979ac0af8be7ebcce209e Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Mon, 27 Jul 2020 12:05:58 -0700 Subject: [PATCH 1/3] Added call to start request controller in cns if provided in config --- cns/service/main.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/cns/service/main.go b/cns/service/main.go index 4caaec20ae..0c136ad044 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -24,6 +24,8 @@ import ( "github.com/Azure/azure-container-networking/cns/configuration" "github.com/Azure/azure-container-networking/cns/hnsclient" "github.com/Azure/azure-container-networking/cns/logger" + "github.com/Azure/azure-container-networking/cns/requestcontroller" + "github.com/Azure/azure-container-networking/cns/requestcontroller/kubecontroller" "github.com/Azure/azure-container-networking/cns/restserver" acn "github.com/Azure/azure-container-networking/common" "github.com/Azure/azure-container-networking/log" @@ -323,6 +325,8 @@ func main() { privateEndpoint = cnsconfig.ManagedSettings.PrivateEndpoint infravnet = cnsconfig.ManagedSettings.InfrastructureNetworkID nodeID = cnsconfig.ManagedSettings.NodeID + } else if cnsconfig.ChannelMode == cns.CRD { + config.ChannelMode = cns.CRD } else if acn.GetArg(acn.OptManaged).(bool) { config.ChannelMode = cns.Managed } @@ -423,6 +427,46 @@ func main() { httpRestService.SyncNodeStatus(ep, vnet, node, json.RawMessage{}) } }(privateEndpoint, infravnet, nodeID) + } else if config.ChannelMode == cns.CRD { + var requestController requestcontroller.RequestController + + logger.Printf("[Azure CNS] Starting request controller") + + kubeConfig, err := kubecontroller.GetKubeConfig() + if err != nil { + logger.Errorf("[Azure CNS] Failed to get kubeconfig for request controller: %v", err) + return + } + + //convert interface type to implementation type + httpRestServiceImplementation, ok := httpRestService.(*restserver.HTTPRestService) + if !ok { + logger.Errorf("[Azure CNS] Failed to convert interface httpRestService to implementation: %v", httpRestService) + return + } + + // Set orchestrator type + orchestrator := cns.SetOrchestratorTypeRequest{ + OrchestratorType: cns.KubernetesCRD, + } + httpRestServiceImplementation.SetNodeOrchestrator(&orchestrator) + + // Get crd implementation of request controller + requestController, err = kubecontroller.NewCrdRequestController(httpRestServiceImplementation, kubeConfig) + if err != nil { + logger.Errorf("[Azure CNS] Failed to make crd request controller :%v", err) + return + } + + // TODO: need to figure out where to use this exit channel + requestControllerExitChannel := make(chan bool, 1) + //Start the RequestController which starts the reconcile loop, blocks + go func() { + if err := requestController.StartRequestController(requestControllerExitChannel); err != nil { + logger.Errorf("[Azure CNS] Failed to start request controller: %v", err) + return + } + }() } var netPlugin network.NetPlugin From a0f48c567591253560954af472ed6eb7d1b717d0 Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Mon, 27 Jul 2020 14:52:25 -0700 Subject: [PATCH 2/3] Added request controller stop channel to be notified from CNS --- .../kubecontroller/crdrequestcontroller.go | 4 ++-- cns/requestcontroller/requestcontrollerintreface.go | 2 +- cns/service/main.go | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/cns/requestcontroller/kubecontroller/crdrequestcontroller.go b/cns/requestcontroller/kubecontroller/crdrequestcontroller.go index 6658ac4a42..d17b43919c 100644 --- a/cns/requestcontroller/kubecontroller/crdrequestcontroller.go +++ b/cns/requestcontroller/kubecontroller/crdrequestcontroller.go @@ -142,7 +142,7 @@ func NewCrdRequestController(restService *restserver.HTTPRestService, kubeconfig // StartRequestController starts the Reconciler loop which watches for CRD status updates // Blocks until SIGINT or SIGTERM is received // Notifies exitChan when kill signal received -func (crdRC *crdRequestController) StartRequestController(exitChan chan bool) error { +func (crdRC *crdRequestController) StartRequestController(exitChan <-chan struct{}) error { var ( err error ) @@ -154,7 +154,7 @@ func (crdRC *crdRequestController) StartRequestController(exitChan chan bool) er } logger.Printf("Starting reconcile loop") - if err := crdRC.mgr.Start(SetupSignalHandler(exitChan)); err != nil { + if err := crdRC.mgr.Start(exitChan); err != nil { if crdRC.isNotDefined(err) { logger.Errorf("[cns-rc] CRD is not defined on cluster, starting reconcile loop failed: %v", err) os.Exit(1) diff --git a/cns/requestcontroller/requestcontrollerintreface.go b/cns/requestcontroller/requestcontrollerintreface.go index 3c964e64b6..24336b8061 100644 --- a/cns/requestcontroller/requestcontrollerintreface.go +++ b/cns/requestcontroller/requestcontrollerintreface.go @@ -8,6 +8,6 @@ import ( // RequestController interface for cns to interact with the request controller type RequestController interface { - StartRequestController(exitChan chan bool) error + StartRequestController(exitChan <-chan struct{}) error UpdateCRDSpec(cntxt context.Context, crdSpec nnc.NodeNetworkConfigSpec) error } diff --git a/cns/service/main.go b/cns/service/main.go index 0c136ad044..8977a4dc82 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -458,11 +458,11 @@ func main() { return } - // TODO: need to figure out where to use this exit channel - requestControllerExitChannel := make(chan bool, 1) - //Start the RequestController which starts the reconcile loop, blocks + //Start the RequestController which starts the reconcile loop + requestControllerStopChannel := make(chan struct{}) + defer close(requestControllerStopChannel) go func() { - if err := requestController.StartRequestController(requestControllerExitChannel); err != nil { + if err := requestController.StartRequestController(requestControllerStopChannel); err != nil { logger.Errorf("[Azure CNS] Failed to start request controller: %v", err) return } From a3b549b7abe0666ec9d6ad95d0d60d2917042fcc Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Mon, 27 Jul 2020 15:06:50 -0700 Subject: [PATCH 3/3] Removed unused signal handler since request controller is reusing cns's signal handler --- .../kubecontroller/signalhandler.go | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 cns/requestcontroller/kubecontroller/signalhandler.go diff --git a/cns/requestcontroller/kubecontroller/signalhandler.go b/cns/requestcontroller/kubecontroller/signalhandler.go deleted file mode 100644 index f6b73124ec..0000000000 --- a/cns/requestcontroller/kubecontroller/signalhandler.go +++ /dev/null @@ -1,35 +0,0 @@ -package kubecontroller - -import ( - "fmt" - "os" - "os/signal" - "syscall" -) - -var onlyOneSignalHandler = make(chan struct{}) -var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM} - -// SetupSignalHandler registers for SIGTERM and SIGINT. A stop channel is returned -// which is closed on one of these signals. If a second signal is caught, the program -// is terminated with exit code 1. -// exitChan is notified when a SIGINT or SIGTERM signal is received. -func SetupSignalHandler(exitChan chan<- bool) (stopCh <-chan struct{}) { - close(onlyOneSignalHandler) // panics when called twice - - stop := make(chan struct{}) - c := make(chan os.Signal, 2) - signal.Notify(c, shutdownSignals...) - go func() { - <-c - // Notify the provided exitChan - // this will allow whoever provided the channel time to cleanup before requestController exits - exitChan <- true - fmt.Println("Sending to exitChan") - close(stop) - <-c - os.Exit(1) // second signal. Exit directly. - }() - - return stop -}