Skip to content

Commit ff53523

Browse files
committed
add logs at end of install for kubeadmin, consoleURL
1 parent b4f5ceb commit ff53523

File tree

1 file changed

+77
-11
lines changed

1 file changed

+77
-11
lines changed

cmd/openshift-install/create.go

Lines changed: 77 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package main
22

33
import (
44
"context"
5+
"fmt"
56
"io/ioutil"
67
"os/exec"
78
"path/filepath"
@@ -16,8 +17,10 @@ import (
1617
"k8s.io/apimachinery/pkg/util/wait"
1718
"k8s.io/apimachinery/pkg/watch"
1819
"k8s.io/client-go/kubernetes"
20+
"k8s.io/client-go/rest"
1921
"k8s.io/client-go/tools/clientcmd"
2022

23+
routeclient "github.com/openshift/client-go/route/clientset/versioned"
2124
"github.com/openshift/installer/pkg/asset"
2225
"github.com/openshift/installer/pkg/asset/cluster"
2326
"github.com/openshift/installer/pkg/asset/ignition/bootstrap"
@@ -89,11 +92,22 @@ var (
8992
// FIXME: add longer descriptions for our commands with examples for better UX.
9093
// Long: "",
9194
PostRunE: func(_ *cobra.Command, _ []string) error {
92-
err := destroyBootstrap(context.Background(), rootOpts.dir)
95+
ctx := context.Background()
96+
config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(rootOpts.dir, "auth", "kubeconfig"))
97+
if err != nil {
98+
return errors.Wrap(err, "loading kubeconfig")
99+
}
100+
101+
err = destroyBootstrap(ctx, config, rootOpts.dir)
102+
if err != nil {
103+
return err
104+
}
105+
consoleURL, err := waitForConsole(ctx, config, rootOpts.dir)
93106
if err != nil {
94107
return err
95108
}
96-
return logComplete(rootOpts.dir)
109+
110+
return logComplete(rootOpts.dir, consoleURL)
97111
},
98112
},
99113
assets: []asset.WritableAsset{&cluster.TerraformVariables{}, &kubeconfig.Admin{}, &cluster.Cluster{}},
@@ -160,18 +174,13 @@ func runTargetCmd(targets ...asset.WritableAsset) func(cmd *cobra.Command, args
160174

161175
// FIXME: pulling the kubeconfig and metadata out of the root
162176
// directory is a bit cludgy when we already have them in memory.
163-
func destroyBootstrap(ctx context.Context, directory string) (err error) {
177+
func destroyBootstrap(ctx context.Context, config *rest.Config, directory string) (err error) {
164178
cleanup, err := setupFileHook(rootOpts.dir)
165179
if err != nil {
166180
return errors.Wrap(err, "failed to setup logging hook")
167181
}
168182
defer cleanup()
169183

170-
config, err := clientcmd.BuildConfigFromFlags("", filepath.Join(directory, "auth", "kubeconfig"))
171-
if err != nil {
172-
return errors.Wrap(err, "loading kubeconfig")
173-
}
174-
175184
client, err := kubernetes.NewForConfig(config)
176185
if err != nil {
177186
return errors.Wrap(err, "creating a Kubernetes client")
@@ -262,8 +271,62 @@ func destroyBootstrap(ctx context.Context, directory string) (err error) {
262271
return destroybootstrap.Destroy(rootOpts.dir)
263272
}
264273

274+
// waitForconsole returns the console URL from the route 'console' in namespace openshift-console
275+
func waitForConsole(ctx context.Context, config *rest.Config, directory string) (string, error) {
276+
url := ""
277+
// Need to keep these updated if they change
278+
consoleNamespace := "openshift-console"
279+
consoleRouteName := "console"
280+
rc, err := routeclient.NewForConfig(config)
281+
if err != nil {
282+
return "", errors.Wrap(err, "creating a route client")
283+
}
284+
285+
consoleRouteTimeout := 10 * time.Minute
286+
logrus.Infof("Waiting %v for the openshift-console route to be created...", consoleRouteTimeout)
287+
consoleRouteContext, cancel := context.WithTimeout(ctx, consoleRouteTimeout)
288+
defer cancel()
289+
// Poll quickly but only log when the response
290+
// when we've seen 15 of the same errors or output of
291+
// no route in a row (to show we're still alive).
292+
logDownsample := 15
293+
silenceRemaining := logDownsample
294+
wait.Until(func() {
295+
consoleRoutes, err := rc.RouteV1().Routes(consoleNamespace).List(metav1.ListOptions{})
296+
if err == nil && len(consoleRoutes.Items) > 0 {
297+
for _, route := range consoleRoutes.Items {
298+
logrus.Debugf("Route found in openshift-console namespace: %s\n", route.Name)
299+
if route.Name == consoleRouteName {
300+
url = fmt.Sprintf("https://%s", route.Spec.Host)
301+
}
302+
}
303+
logrus.Debug("OpenShift console route is created")
304+
cancel()
305+
} else if err != nil {
306+
silenceRemaining--
307+
if silenceRemaining == 0 {
308+
logrus.Debugf("Still waiting for the console route: %v", err)
309+
silenceRemaining = logDownsample
310+
}
311+
} else if len(consoleRoutes.Items) == 0 {
312+
silenceRemaining--
313+
if silenceRemaining == 0 {
314+
logrus.Debug("Still waiting for the console route...")
315+
silenceRemaining = logDownsample
316+
}
317+
}
318+
}, 2*time.Second, consoleRouteContext.Done())
319+
if err != nil {
320+
return "", errors.Wrap(err, "waiting for console route to be created")
321+
}
322+
if url == "" {
323+
return url, errors.Wrap(err, "could not obtain openshift-console URL from route")
324+
}
325+
return url, nil
326+
}
327+
265328
// logComplete prints info upon completion
266-
func logComplete(directory string) error {
329+
func logComplete(directory, consoleURL string) error {
267330
absDir, err := filepath.Abs(directory)
268331
if err != nil {
269332
return err
@@ -274,7 +337,10 @@ func logComplete(directory string) error {
274337
if err != nil {
275338
return err
276339
}
277-
logrus.Infof("kubeadmin user password: %s", pw)
278-
logrus.Infof("Install complete! The kubeconfig is located here: %s", kubeconfig)
340+
logrus.Info("Install complete!")
341+
logrus.Infof("Run 'export KUBECONFIG=%s' to manage the cluster with 'oc', the OpenShift CLI.", kubeconfig)
342+
logrus.Infof("The cluster is ready when 'oc login -u kubeadmin -p %s' succeeds (wait a few minutes).", pw)
343+
logrus.Infof("Access the OpenShift web-console here: %s", consoleURL)
344+
logrus.Infof("Login to the console with user: kubeadmin, password: %s", pw)
279345
return nil
280346
}

0 commit comments

Comments
 (0)