healthReport is a more thorough health check than the '/healthz' endpoint. This endpoint not only responds if the server is running, but can do some internal diagnostics to ensure that the server is running correctly. The primary coderd will use this to determine if this workspace proxy can be used
(rw http.ResponseWriter, r *http.Request)
| 635 | // |
| 636 | // TODO: Config checks to ensure consistent with primary |
| 637 | func (s *Server) healthReport(rw http.ResponseWriter, r *http.Request) { |
| 638 | ctx := r.Context() |
| 639 | var report codersdk.ProxyHealthReport |
| 640 | |
| 641 | // This is to catch edge cases where the server is shutting down, but might |
| 642 | // still serve a web request that returns "healthy". This is mainly just for |
| 643 | // unit tests, as shutting down the test webserver is tied to the lifecycle |
| 644 | // of the test. In practice, the webserver is tied to the lifecycle of the |
| 645 | // app, so the webserver AND the proxy will be shut down at the same time. |
| 646 | if s.ctx.Err() != nil { |
| 647 | httpapi.Write(r.Context(), rw, http.StatusInternalServerError, "workspace proxy in middle of shutting down") |
| 648 | return |
| 649 | } |
| 650 | |
| 651 | // Hit the build info to do basic version checking. |
| 652 | primaryBuild, err := s.SDKClient.SDKClient.BuildInfo(ctx) |
| 653 | if err != nil { |
| 654 | report.Errors = append(report.Errors, fmt.Sprintf("failed to get build info: %s", err.Error())) |
| 655 | httpapi.Write(r.Context(), rw, http.StatusOK, report) |
| 656 | return |
| 657 | } |
| 658 | |
| 659 | if primaryBuild.WorkspaceProxy { |
| 660 | // This could be a simple mistake of using a proxy url as the dashboard url. |
| 661 | report.Errors = append(report.Errors, |
| 662 | fmt.Sprintf("dashboard url (%s) is a workspace proxy, must be a primary coderd", s.DashboardURL.String())) |
| 663 | } |
| 664 | |
| 665 | // If we are in dev mode, never check versions. |
| 666 | if !buildinfo.IsDev() && !buildinfo.VersionsMatch(primaryBuild.Version, buildinfo.Version()) { |
| 667 | // Version mismatches are not fatal, but should be reported. |
| 668 | report.Warnings = append(report.Warnings, |
| 669 | fmt.Sprintf("version mismatch: primary coderd (%s) != workspace proxy (%s)", primaryBuild.Version, buildinfo.Version())) |
| 670 | } |
| 671 | |
| 672 | s.replicaErrMut.Lock() |
| 673 | if s.replicaErr != "" { |
| 674 | report.Warnings = append(report.Warnings, |
| 675 | "High availability networking: it appears you are running more than one replica of the proxy, but the replicas are unable to establish a mesh for networking: "+s.replicaErr) |
| 676 | } |
| 677 | s.replicaErrMut.Unlock() |
| 678 | |
| 679 | // TODO: We should hit the deployment config endpoint and do some config |
| 680 | // checks. |
| 681 | |
| 682 | httpapi.Write(r.Context(), rw, http.StatusOK, report) |
| 683 | } |
| 684 | |
| 685 | type optErrors []error |
| 686 |