Skip to content

Commit

Permalink
Maintenance Splash Page (sourcegraph#64019)
Browse files Browse the repository at this point in the history
This PR makes a maintenance splash page intended to display service
health after installation completes.
Intended as WIP no nav yet

<img width="973" alt="Screenshot 2024-07-24 at 12 00 44 AM"
src="https://github.com/user-attachments/assets/3e2ecd67-3ef7-4bdc-9f45-d8740eb426f8">

## Test plan
Run local Golden Tests

<!-- REQUIRED; info at
https://docs-legacy.sourcegraph.com/dev/background-information/testing_principles
-->

## Changelog

<!-- OPTIONAL; info at
https://www.notion.so/sourcegraph/Writing-a-changelog-entry-dd997f411d524caabf0d8d38a24a878c
-->
  • Loading branch information
DaedalusG authored Jul 25, 2024
1 parent 3814fd7 commit c68e92b
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 11 deletions.
1 change: 1 addition & 0 deletions internal/appliance/config/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const (
StatusUpgrading Status = "upgrading"
StatusWaitingForAdmin Status = "wait-for-admin"
StatusRefresh Status = "refresh"
StatusMaintenance Status = "maintenance"
)

// TODO think about this
Expand Down
23 changes: 23 additions & 0 deletions internal/appliance/config/spec.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,6 +269,29 @@ type SourcegraphSpec struct {
StorageClass StorageClassSpec `json:"storageClass,omitempty"`
}

// SourcegraphServicesToReconcile is a list of all Sourcegraph services that will be reconciled by appliance.
var SourcegraphServicesToReconcile = []string{
"blobstore",
"repo-updater",
"symbols",
"gitserver",
"redis",
"pgsql",
"syntect",
"precise-code-intel",
"code-insights-db",
"code-intel-db",
"prometheus",
"cadvisor",
"worker",
"frontend",
"searcher",
"indexed-searcher",
"grafana",
"jaeger",
"otel",
}

// SourcegraphStatus defines the observed state of Sourcegraph
type SourcegraphStatus struct {
// CurrentVersion is the version of Sourcegraph currently running.
Expand Down
17 changes: 9 additions & 8 deletions internal/appliance/frontend/maintenance/src/Maintenance.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Fragment, useEffect, useState } from 'react'
import type React from 'react'
import { Fragment, useEffect, useState } from 'react'

import Unhealthy from '@mui/icons-material/CarCrashOutlined'
import Healthy from '@mui/icons-material/ThumbUp'
Expand All @@ -17,7 +18,7 @@ type Service = {
message: string
}

type Status = {
type ServiceStatuses = {
services: Service[]
}

Expand Down Expand Up @@ -54,14 +55,14 @@ const ShowServices: React.FC<{ services: Service[] }> = ({ services }) =>
) : null

export const Maintenance: React.FC = () => {
const [status, setStatus] = useState<Status | undefined>()
const [serviceStatuses, setServiceStatuses] = useState<ServiceStatuses | undefined>()
const [fixing, setFixing] = useState<boolean>(false)

useEffect(() => {
const timer = setInterval(() => {
call('/api/v1/appliance/maintenance/status')
call('/api/v1/appliance/maintenance/serviceStatuses')
.then(response => response.json())
.then(setStatus)
.then(serviceStatuses => setServiceStatuses(serviceStatuses))
}, MaintenanceStatusTimerMs)
return () => clearInterval(timer)
}, [])
Expand All @@ -75,8 +76,8 @@ export const Maintenance: React.FC = () => {
}
}, [fixing])

const ready = status?.services.length !== undefined
const unhealthy = status?.services?.find((s: Service) => !s.healthy)
const ready = serviceStatuses?.services.length !== undefined
const unhealthy = serviceStatuses?.services?.find((s: Service) => !s.healthy)

return (
<div className="maintenance">
Expand All @@ -97,7 +98,7 @@ export const Maintenance: React.FC = () => {
{ready ? (
<>
<Typography variant="h5">Service Status</Typography>
<ShowServices services={status?.services ?? []} />
<ShowServices services={serviceStatuses?.services ?? []} />
</>
) : null}

Expand Down
23 changes: 21 additions & 2 deletions internal/appliance/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package appliance

import (
"encoding/json"
"fmt"
"io"
"net/http"
"strings"
Expand Down Expand Up @@ -101,7 +102,7 @@ func (a *Appliance) getStatusJSONHandler() http.Handler {
Data: "",
}

if err := a.writeJSON(w, http.StatusOK, responseData{"status": data}, nil); err != nil {
if err := a.writeJSON(w, http.StatusOK, responseData{"status": data}, http.Header{}); err != nil {
a.serverErrorResponse(w, r, err)
}
})
Expand All @@ -123,7 +124,7 @@ func (a *Appliance) getInstallProgressJSONHandler() http.Handler {
Tasks: currentTasks,
}

if err := a.writeJSON(w, http.StatusOK, responseData{"progress": installProgress}, nil); err != nil {
if err := a.writeJSON(w, http.StatusOK, responseData{"progress": installProgress}, http.Header{}); err != nil {
a.serverErrorResponse(w, r, err)
}
})
Expand All @@ -132,6 +133,24 @@ func (a *Appliance) getInstallProgressJSONHandler() http.Handler {
func (a *Appliance) getMaintenanceStatusHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

type service struct {
Name string `json:"name"`
Healthy bool `json:"healthy"`
Message string `json:"message"`
}

services := []service{}
for _, name := range config.SourcegraphServicesToReconcile {
services = append(services, service{
Name: name,
Healthy: true,
Message: "fake event",
})
}
fmt.Println(services)
if err := a.writeJSON(w, http.StatusOK, responseData{"services": services}, http.Header{}); err != nil {
a.serverErrorResponse(w, r, err)
}
})
}

Expand Down
2 changes: 1 addition & 1 deletion internal/appliance/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func (a *Appliance) Routes() *mux.Router {
r.Handle("/api/v1/appliance/status", a.getStatusJSONHandler()).Methods("GET")
r.Handle("/api/v1/appliance/status", a.postStatusJSONHandler()).Methods("POST")
r.Handle("/api/v1/appliance/install/progress", a.getInstallProgressJSONHandler()).Methods("GET")
r.Handle("/api/v1/appliance/maintenance/status", a.getMaintenanceStatusHandler()).Methods("GET")
r.Handle("/api/v1/appliance/maintenance/serviceStatuses", a.getMaintenanceStatusHandler()).Methods("GET")

return r
}

0 comments on commit c68e92b

Please sign in to comment.