From 0f851bfa2ed9085b507860c0d1fddb618edb8b33 Mon Sep 17 00:00:00 2001 From: Jonathan MacMillan Date: Tue, 28 Feb 2017 17:57:48 -0800 Subject: [PATCH] [Federation] Improve the logging and user feedback in 'kubefed init'. --- federation/pkg/kubefed/init/init.go | 55 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/federation/pkg/kubefed/init/init.go b/federation/pkg/kubefed/init/init.go index 4c1dcbe3883..a889311c10a 100644 --- a/federation/pkg/kubefed/init/init.go +++ b/federation/pkg/kubefed/init/init.go @@ -284,20 +284,25 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { } } - fmt.Fprint(cmdOut, "Creating a namespace for federation system components") + fmt.Fprintf(cmdOut, "Creating a namespace %s for federation system components...", i.commonOptions.FederationSystemNamespace) + glog.V(4).Infof("Creating a namespace %s for federation system components", i.commonOptions.FederationSystemNamespace) _, err = createNamespace(hostClientset, i.commonOptions.Name, i.commonOptions.FederationSystemNamespace, i.options.dryRun) if err != nil { return err } - fmt.Fprint(cmdOut, " done\n") - fmt.Fprint(cmdOut, "Creating federation control plane objects (service, credentials, persistent volume claim)") - svc, ips, hostnames, err := createService(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun) + fmt.Fprintln(cmdOut, " done") + + fmt.Fprint(cmdOut, "Creating federation control plane service...") + glog.V(4).Info("Creating federation control plane service") + svc, ips, hostnames, err := createService(cmdOut, hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.apiServerAdvertiseAddress, i.options.apiServerServiceType, i.options.dryRun) if err != nil { return err } + fmt.Fprintln(cmdOut, " done") glog.V(4).Infof("Created service named %s with IP addresses %v, hostnames %v", svc.Name, ips, hostnames) + fmt.Fprint(cmdOut, "Creating federation control plane objects (credentials, persistent volume claim)...") glog.V(4).Info("Generating TLS certificates and credentials for communicating with the federation API server") credentials, err := generateCredentials(i.commonOptions.FederationSystemNamespace, i.commonOptions.Name, svc.Name, HostClusterLocalDNSZoneName, serverCredName, ips, hostnames, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.dryRun) if err != nil { @@ -316,7 +321,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { if err != nil { return err } - glog.V(4).Info("kubeconfig successfully updated") + glog.V(4).Info("Credentials secret successfully created") glog.V(4).Info("Creating a persistent volume and a claim to store the federation API server's state, including etcd data") var pvc *api.PersistentVolumeClaim @@ -327,7 +332,7 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { } } glog.V(4).Info("Persistent volume and claim created") - fmt.Fprint(cmdOut, " done\n") + fmt.Fprintln(cmdOut, " done") // Since only one IP address can be specified as advertise address, // we arbitrarily pick the first available IP address @@ -337,7 +342,8 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { advertiseAddress = ips[0] } - fmt.Fprint(cmdOut, "Creating federation component deployments") + fmt.Fprint(cmdOut, "Creating federation component deployments...") + glog.V(4).Info("Creating federation control plane components") _, err = createAPIServer(hostClientset, i.commonOptions.FederationSystemNamespace, serverName, i.commonOptions.Name, i.options.image, advertiseAddress, serverCredName, i.options.apiServerEnableHTTPBasicAuth, i.options.apiServerEnableTokenAuth, i.options.apiServerOverrides, pvc, i.options.dryRun) if err != nil { return err @@ -378,9 +384,10 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { return err } glog.V(4).Info("Successfully created federation controller manager deployment") - fmt.Fprint(cmdOut, " done\n") + fmt.Println(cmdOut, " done") - fmt.Fprint(cmdOut, "Updating kubeconfig ") + fmt.Fprint(cmdOut, "Updating kubeconfig...") + glog.V(4).Info("Updating kubeconfig") // Pick the first ip/hostname to update the api server endpoint in kubeconfig and also to give information to user // In case of NodePort Service for api server, ips are node external ips. endpoint := "" @@ -396,25 +403,30 @@ func (i *initFederation) Run(cmdOut io.Writer, config util.AdminConfig) error { err = updateKubeconfig(config, i.commonOptions.Name, endpoint, i.commonOptions.Kubeconfig, credentials, i.options.dryRun) if err != nil { + glog.V(4).Infof("Failed to update kubeconfig: %v", err) return err } - fmt.Fprint(cmdOut, " done\n") + fmt.Fprintln(cmdOut, " done") + glog.V(4).Info("Successfully updated kubeconfig") if !i.options.dryRun { - fmt.Fprint(cmdOut, "Waiting for federation control plane to come up ") + fmt.Fprint(cmdOut, "Waiting for federation control plane to come up...") + glog.V(4).Info("Waiting for federation control plane to come up") fedPods := []string{serverName, cmName} - err = waitForPods(hostClientset, fedPods, i.commonOptions.FederationSystemNamespace) + err = waitForPods(cmdOut, hostClientset, fedPods, i.commonOptions.FederationSystemNamespace) if err != nil { return err } - err = waitSrvHealthy(config, i.commonOptions.Name, i.commonOptions.Kubeconfig) - fmt.Fprint(cmdOut, " done\n") + err = waitSrvHealthy(cmdOut, config, i.commonOptions.Name, i.commonOptions.Kubeconfig) if err != nil { return err } + glog.V(4).Info("Federation control plane running") + fmt.Fprintln(cmdOut, " done") return printSuccess(cmdOut, ips, hostnames, svc) } - _, err = fmt.Fprintf(cmdOut, "Federation control plane runs (dry run)\n") + _, err = fmt.Fprintln(cmdOut, "Federation control plane runs (dry run)") + glog.V(4).Info("Federation control plane runs (dry run)") return err } @@ -433,7 +445,7 @@ func createNamespace(clientset client.Interface, federationName, namespace strin return clientset.Core().Namespaces().Create(ns) } -func createService(clientset client.Interface, namespace, svcName, federationName, apiserverAdvertiseAddress string, apiserverServiceType v1.ServiceType, dryRun bool) (*api.Service, []string, []string, error) { +func createService(cmdOut io.Writer, clientset client.Interface, namespace, svcName, federationName, apiserverAdvertiseAddress string, apiserverServiceType v1.ServiceType, dryRun bool) (*api.Service, []string, []string, error) { svc := &api.Service{ ObjectMeta: metav1.ObjectMeta{ Name: svcName, @@ -465,7 +477,7 @@ func createService(clientset client.Interface, namespace, svcName, federationNam ips := []string{} hostnames := []string{} if apiserverServiceType == v1.ServiceTypeLoadBalancer { - ips, hostnames, err = waitForLoadBalancerAddress(clientset, svc, dryRun) + ips, hostnames, err = waitForLoadBalancerAddress(cmdOut, clientset, svc, dryRun) } else { if apiserverAdvertiseAddress != "" { ips = append(ips, apiserverAdvertiseAddress) @@ -504,7 +516,7 @@ func getClusterNodeIPs(clientset client.Interface) ([]string, error) { return nodeAddresses, nil } -func waitForLoadBalancerAddress(clientset client.Interface, svc *api.Service, dryRun bool) ([]string, []string, error) { +func waitForLoadBalancerAddress(cmdOut io.Writer, clientset client.Interface, svc *api.Service, dryRun bool) ([]string, []string, error) { ips := []string{} hostnames := []string{} @@ -513,6 +525,7 @@ func waitForLoadBalancerAddress(clientset client.Interface, svc *api.Service, dr } err := wait.PollImmediateInfinite(lbAddrRetryInterval, func() (bool, error) { + fmt.Fprint(cmdOut, ".") pollSvc, err := clientset.Core().Services(svc.Namespace).Get(svc.Name, metav1.GetOptions{}) if err != nil { return false, nil @@ -968,8 +981,9 @@ func argMapsToArgStrings(argsMap, overrides map[string]string) []string { return args } -func waitForPods(clientset client.Interface, fedPods []string, namespace string) error { +func waitForPods(cmdOut io.Writer, clientset client.Interface, fedPods []string, namespace string) error { err := wait.PollInfinite(podWaitInterval, func() (bool, error) { + fmt.Fprint(cmdOut, ".") podCheck := len(fedPods) podList, err := clientset.Core().Pods(namespace).List(metav1.ListOptions{}) if err != nil { @@ -991,13 +1005,14 @@ func waitForPods(clientset client.Interface, fedPods []string, namespace string) return err } -func waitSrvHealthy(config util.AdminConfig, context, kubeconfig string) error { +func waitSrvHealthy(cmdOut io.Writer, config util.AdminConfig, context, kubeconfig string) error { fedClientSet, err := config.FederationClientset(context, kubeconfig) if err != nil { return err } fedDiscoveryClient := fedClientSet.Discovery() err = wait.PollInfinite(podWaitInterval, func() (bool, error) { + fmt.Fprint(cmdOut, ".") body, err := fedDiscoveryClient.RESTClient().Get().AbsPath("/healthz").Do().Raw() if err != nil { return false, nil