diff --git a/pkg/bootstrap/docker/dockerhelper/helper.go b/pkg/bootstrap/docker/dockerhelper/helper.go index 0718232be54e..0acbfcdf3034 100644 --- a/pkg/bootstrap/docker/dockerhelper/helper.go +++ b/pkg/bootstrap/docker/dockerhelper/helper.go @@ -1,12 +1,14 @@ package dockerhelper import ( + "bytes" "encoding/json" "errors" "fmt" "io" "net" "net/url" + "strconv" "strings" "github.com/blang/semver" @@ -207,6 +209,22 @@ func (h *Helper) HostIP() string { return "" } +func (h *Helper) ContainerLog(container string, numLines int) string { + output := &bytes.Buffer{} + err := h.client.Logs(docker.LogsOptions{ + Container: container, + Tail: strconv.Itoa(numLines), + OutputStream: output, + ErrorStream: output, + Stdout: true, + Stderr: true, + }) + if err != nil { + glog.V(1).Infof("Error getting container %q log: %v", container, err) + } + return output.String() +} + func (h *Helper) StopAndRemoveContainer(container string) error { err := h.client.StopContainer(container, 10) if err != nil { diff --git a/pkg/bootstrap/docker/errors/errors.go b/pkg/bootstrap/docker/errors/errors.go index f1ceb8f79fd0..71f23a02751a 100644 --- a/pkg/bootstrap/docker/errors/errors.go +++ b/pkg/bootstrap/docker/errors/errors.go @@ -15,6 +15,7 @@ type Error interface { error WithCause(error) Error WithSolution(string, ...interface{}) Error + WithDetails(string) Error } func NewError(msg string, args ...interface{}) Error { @@ -42,6 +43,10 @@ func (e *internalError) Solution() string { return e.solution } +func (e *internalError) Details() string { + return e.details +} + func (e *internalError) WithCause(err error) Error { e.cause = err return e diff --git a/pkg/bootstrap/docker/openshift/admin.go b/pkg/bootstrap/docker/openshift/admin.go index 6d047bc745e9..4dfb253656fd 100644 --- a/pkg/bootstrap/docker/openshift/admin.go +++ b/pkg/bootstrap/docker/openshift/admin.go @@ -35,7 +35,7 @@ func (h *Helper) InstallRegistry(kubeClient kclient.Interface, f *clientcmd.Fact return nil } if !apierrors.IsNotFound(err) { - return errors.NewError("error retrieving docker registry service").WithCause(err) + return errors.NewError("error retrieving docker registry service").WithCause(err).WithDetails(h.OriginLog()) } imageTemplate := variable.NewDefaultImageTemplate() imageTemplate.Format = images @@ -53,7 +53,10 @@ func (h *Helper) InstallRegistry(kubeClient kclient.Interface, f *clientcmd.Fact output := &bytes.Buffer{} err = registry.RunCmdRegistry(f, cmd, output, cfg, []string{}) glog.V(4).Infof("Registry command output:\n%s", output.String()) - return err + if err != nil { + return errors.NewError("cannot install registry").WithCause(err).WithDetails(h.OriginLog()) + } + return nil } // InstallRouter installs a default router on the OpenShift server @@ -63,6 +66,9 @@ func (h *Helper) InstallRouter(kubeClient kclient.Interface, f *clientcmd.Factor // Router service already exists, nothing to do return nil } + if !apierrors.IsNotFound(err) { + return errors.NewError("error retrieving router service").WithCause(err).WithDetails(h.OriginLog()) + } masterDir := filepath.Join(configDir, "master") @@ -71,18 +77,18 @@ func (h *Helper) InstallRouter(kubeClient kclient.Interface, f *clientcmd.Factor routerSA.Name = "router" _, err = kubeClient.ServiceAccounts("default").Create(routerSA) if err != nil { - return errors.NewError("cannot create router service account").WithCause(err) + return errors.NewError("cannot create router service account").WithCause(err).WithDetails(h.OriginLog()) } // Add router SA to privileged SCC privilegedSCC, err := kubeClient.SecurityContextConstraints().Get("privileged") if err != nil { - return errors.NewError("cannot retrieve privileged SCC").WithCause(err) + return errors.NewError("cannot retrieve privileged SCC").WithCause(err).WithDetails(h.OriginLog()) } privilegedSCC.Users = append(privilegedSCC.Users, serviceaccount.MakeUsername("default", "router")) _, err = kubeClient.SecurityContextConstraints().Update(privilegedSCC) if err != nil { - return errors.NewError("cannot update privileged SCC").WithCause(err) + return errors.NewError("cannot update privileged SCC").WithCause(err).WithDetails(h.OriginLog()) } // Create router cert @@ -134,7 +140,10 @@ func (h *Helper) InstallRouter(kubeClient kclient.Interface, f *clientcmd.Factor cmd.SetOutput(output) err = router.RunCmdRouter(f, cmd, output, cfg, []string{}) glog.V(4).Infof("Router command output:\n%s", output.String()) - return err + if err != nil { + return errors.NewError("cannot install router").WithCause(err).WithDetails(h.OriginLog()) + } + return nil } // catFiles concatenates multiple source files into a single destination file diff --git a/pkg/bootstrap/docker/openshift/errors.go b/pkg/bootstrap/docker/openshift/errors.go index 4dbca725e3e1..35ab5fc769d6 100644 --- a/pkg/bootstrap/docker/openshift/errors.go +++ b/pkg/bootstrap/docker/openshift/errors.go @@ -2,17 +2,19 @@ package openshift import ( "fmt" + + "github.com/openshift/origin/pkg/bootstrap/docker/errors" ) // ErrOpenShiftFailedToStart is thrown when the OpenShift server failed to start -func ErrOpenShiftFailedToStart(container string) error { - return fmt.Errorf("Could not start OpenShift container %q", container) +func ErrOpenShiftFailedToStart(container string) errors.Error { + return errors.NewError("could not start OpenShift container %q", container) } // ErrTimedOutWaitingForStart is thrown when the OpenShift server can't be pinged after reasonable // amount of time. -func ErrTimedOutWaitingForStart(container string) error { - return fmt.Errorf("Could not start OpenShift container %q", container) +func ErrTimedOutWaitingForStart(container string) errors.Error { + return errors.NewError("timed out waiting for OpenShift container %q", container) } type errPortsNotAvailable struct { diff --git a/pkg/bootstrap/docker/openshift/helper.go b/pkg/bootstrap/docker/openshift/helper.go index 1242673faa43..d2e48ed984a2 100644 --- a/pkg/bootstrap/docker/openshift/helper.go +++ b/pkg/bootstrap/docker/openshift/helper.go @@ -268,14 +268,14 @@ func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) { return "", errors.NewError("cannot get state of OpenShift container %s", h.containerName).WithCause(err) } if !running { - return "", ErrOpenShiftFailedToStart(h.containerName) + return "", ErrOpenShiftFailedToStart(h.containerName).WithDetails(h.OriginLog()) } // Wait until the API server is listening fmt.Fprintf(out, "Waiting for API server to start listening\n") masterHost := fmt.Sprintf("%s:8443", opt.ServerIP) if err = cmdutil.WaitForSuccessfulDial(true, "tcp", masterHost, 200*time.Millisecond, 1*time.Second, serverUpTimeout); err != nil { - return "", ErrTimedOutWaitingForStart(h.containerName) + return "", ErrTimedOutWaitingForStart(h.containerName).WithDetails(h.OriginLog()) } // Check for healthz endpoint to be ready client, err := masterHTTPClient(configDir) @@ -285,7 +285,7 @@ func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) { for { resp, ierr := client.Get(h.healthzReadyURL(opt.ServerIP)) if ierr != nil { - return "", errors.NewError("cannot access master readiness URL %s", h.healthzReadyURL(opt.ServerIP)).WithCause(err) + return "", errors.NewError("cannot access master readiness URL %s", h.healthzReadyURL(opt.ServerIP)).WithCause(err).WithDetails(h.OriginLog()) } if resp.StatusCode == http.StatusOK { break @@ -300,12 +300,20 @@ func (h *Helper) Start(opt *StartOptions, out io.Writer) (string, error) { if rerr == nil { responseBody = string(body) } - return "", errors.NewError("server is not ready. Response (%d): %s", resp.StatusCode, responseBody).WithCause(ierr) + return "", errors.NewError("server is not ready. Response (%d): %s", resp.StatusCode, responseBody).WithCause(ierr).WithDetails(h.OriginLog()) } fmt.Fprintf(out, "OpenShift server started\n") return configDir, nil } +func (h *Helper) OriginLog() string { + log := h.dockerHelper.ContainerLog(h.containerName, 10) + if len(log) > 0 { + return fmt.Sprintf("Last 10 lines of %q container log:\n%s\n", h.containerName, log) + } + return fmt.Sprintf("No log available from %q container\n", h.containerName) +} + func (h *Helper) healthzReadyURL(ip string) string { return fmt.Sprintf("%s/healthz/ready", h.Master(ip)) } diff --git a/pkg/bootstrap/docker/up.go b/pkg/bootstrap/docker/up.go index 68d812600698..8031ef25a470 100644 --- a/pkg/bootstrap/docker/up.go +++ b/pkg/bootstrap/docker/up.go @@ -611,7 +611,7 @@ func (c *ClientStartConfig) importObjects(out io.Writer, locations map[string]st glog.V(2).Infof("Importing %s from %s", name, location) err = openshift.ImportObjects(f, openShiftNamespace, location) if err != nil { - return err + return errors.NewError("cannot import %s", name).WithCause(err).WithDetails(c.OpenShiftHelper().OriginLog()) } } return nil