diff --git a/cli/cmd/installRunner.go b/cli/cmd/installRunner.go index 7167f36b4..c8d87d614 100644 --- a/cli/cmd/installRunner.go +++ b/cli/cmd/installRunner.go @@ -4,6 +4,10 @@ import ( "context" "errors" "fmt" + "github.com/up9inc/mizu/shared/kubernetes" + core "k8s.io/api/core/v1" + "regexp" + "time" "github.com/creasty/defaults" "github.com/up9inc/mizu/cli/config" @@ -58,7 +62,21 @@ func runMizuInstall() { return } - logger.Log.Infof(uiUtils.Magenta, "Created Mizu Agent components, run `mizu view` to connect to the mizu daemon instance") + logger.Log.Infof("Waiting for Mizu server to start...") + readyChan := make(chan string) + readyErrorChan := make(chan error) + go watchApiServerPodReady(ctx, kubernetesProvider, readyChan, readyErrorChan) + + select { + case readyMessage := <-readyChan: + logger.Log.Infof(readyMessage) + case err := <-readyErrorChan: + defer resources.CleanUpMizuResources(ctx, cancel, kubernetesProvider, config.Config.IsNsRestrictedMode(), config.Config.MizuResourcesNamespace) + logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("%v", errormessage.FormatError(err))) + return + } + + logger.Log.Infof(uiUtils.Magenta, "Installation completed, run `mizu view` to connect to the mizu daemon instance") } func getInstallMizuAgentConfig(maxDBSizeBytes int64, tapperResources shared.Resources) *shared.MizuAgentConfig { @@ -75,3 +93,58 @@ func getInstallMizuAgentConfig(maxDBSizeBytes int64, tapperResources shared.Reso return &mizuAgentConfig } + +func watchApiServerPodReady(ctx context.Context, kubernetesProvider *kubernetes.Provider, readyChan chan string, readyErrorChan chan error) { + podExactRegex := regexp.MustCompile(fmt.Sprintf("^%s.*", kubernetes.ApiServerPodName)) + podWatchHelper := kubernetes.NewPodWatchHelper(kubernetesProvider, podExactRegex) + eventChan, errorChan := kubernetes.FilteredWatch(ctx, podWatchHelper, []string{config.Config.MizuResourcesNamespace}, podWatchHelper) + + timeAfter := time.After(30 * time.Second) + for { + select { + case wEvent, ok := <-eventChan: + if !ok { + eventChan = nil + continue + } + + switch wEvent.Type { + case kubernetes.EventAdded: + logger.Log.Debugf("Watching API Server pod ready loop, added") + case kubernetes.EventDeleted: + logger.Log.Debugf("Watching API Server pod ready loop, %s removed", kubernetes.ApiServerPodName) + case kubernetes.EventModified: + modifiedPod, err := wEvent.ToPod() + if err != nil { + readyErrorChan <- err + return + } + + logger.Log.Debugf("Watching API Server pod ready loop, modified: %v", modifiedPod.Status.Phase) + + if modifiedPod.Status.Phase == core.PodRunning { + readyChan <- fmt.Sprintf("%v pod is running", modifiedPod.Name) + return + } + case kubernetes.EventBookmark: + break + case kubernetes.EventError: + break + } + case err, ok := <-errorChan: + if !ok { + errorChan = nil + continue + } + + readyErrorChan <- fmt.Errorf("[ERROR] Agent creation, watching %v namespace, error: %v", config.Config.MizuResourcesNamespace, err) + return + case <-timeAfter: + readyErrorChan <- fmt.Errorf("mizu API server was not ready in time") + return + case <-ctx.Done(): + logger.Log.Debugf("Watching API Server pod ready loop, ctx done") + return + } + } +}