mirror of
https://github.com/sourcegraph/sourcegraph.git
synced 2026-02-06 18:51:59 +00:00
feat/release: appliance setup workflow and ui (#63291)
This adds the Appliance setup workflow UI. Completes https://linear.app/sourcegraph/issue/REL-73/the-user-can-perform-initial-installation-from-a-web-ui. - Adds basic HTTP routing for frontend UI using server side rendering and HTMX for more interactivity when needed. - SSR allows for an extremely simple frontend that uses almost no JS/TS and simple HTTP. - Uses `go/embed` to embed static assets and libraries in the binary making for an extremely simple deployment. - Adds some basic styling for UI - Adds foundation for tracking installation progress of install 
This commit is contained in:
parent
b3b7936ffa
commit
fec72ef241
@ -66,3 +66,7 @@ wolfi-images/*.lock.json
|
||||
|
||||
# This is downloaded from upstream directly and should not be modified
|
||||
dev/linearhooks/internal/lineargql/schema.graphql
|
||||
|
||||
# This is an embedded external minified library and should not be modified
|
||||
internal/appliance/web/static/script/htmx.min.js
|
||||
internal/appliance/web/static/script/bootstrap.bundle.min.js
|
||||
|
||||
@ -18,6 +18,7 @@ type Config struct {
|
||||
k8sConfig *rest.Config
|
||||
metrics metricsConfig
|
||||
grpc grpcConfig
|
||||
http httpConfig
|
||||
namespace string
|
||||
}
|
||||
|
||||
@ -36,9 +37,10 @@ func (c *Config) Load() {
|
||||
}
|
||||
|
||||
c.k8sConfig = k8sConfig
|
||||
c.metrics.addr = c.Get("APPLIANCE_METRICS_ADDR", ":8080", "Appliance metrics server address.")
|
||||
c.metrics.addr = c.Get("APPLIANCE_METRICS_ADDR", ":8734", "Appliance metrics server address.")
|
||||
c.metrics.secure = c.GetBool("APPLIANCE_METRICS_SECURE", "false", "Appliance metrics server uses https.")
|
||||
c.grpc.addr = c.Get("APPLIANCE_GRPC_ADDR", ":9000", "Appliance gRPC address.")
|
||||
c.http.addr = c.Get("APPLIANCE_HTTP_ADDR", ":8080", "Appliance http address.")
|
||||
c.namespace = c.Get("APPLIANCE_NAMESPACE", cache.AllNamespaces, "Namespace to monitor. Defaults to all.")
|
||||
}
|
||||
|
||||
@ -55,3 +57,7 @@ type metricsConfig struct {
|
||||
type grpcConfig struct {
|
||||
addr string
|
||||
}
|
||||
|
||||
type httpConfig struct {
|
||||
addr string
|
||||
}
|
||||
|
||||
@ -3,9 +3,11 @@ package shared
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
"google.golang.org/grpc"
|
||||
@ -23,6 +25,7 @@ import (
|
||||
"github.com/sourcegraph/sourcegraph/internal/grpc/defaults"
|
||||
"github.com/sourcegraph/sourcegraph/internal/observation"
|
||||
"github.com/sourcegraph/sourcegraph/internal/service"
|
||||
"github.com/sourcegraph/sourcegraph/lib/errors"
|
||||
)
|
||||
|
||||
var onlyOneSignalHandler = make(chan struct{})
|
||||
@ -39,7 +42,7 @@ func Start(ctx context.Context, observationCtx *observation.Context, ready servi
|
||||
return err
|
||||
}
|
||||
|
||||
app := appliance.NewAppliance(k8sClient)
|
||||
app := appliance.NewAppliance(k8sClient, logger)
|
||||
|
||||
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
|
||||
Logger: logr,
|
||||
@ -67,15 +70,20 @@ func Start(ctx context.Context, observationCtx *observation.Context, ready servi
|
||||
return err
|
||||
}
|
||||
|
||||
// Mark health server as ready
|
||||
ready()
|
||||
|
||||
listener, err := net.Listen("tcp", config.grpc.addr)
|
||||
if err != nil {
|
||||
logger.Error("unable to create tcp listener", log.Error(err))
|
||||
return err
|
||||
}
|
||||
|
||||
srv := &http.Server{
|
||||
Addr: config.http.addr,
|
||||
Handler: app.Routes(),
|
||||
IdleTimeout: time.Minute,
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
grpcServer := makeGRPCServer(logger, app)
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
@ -89,7 +97,14 @@ func Start(ctx context.Context, observationCtx *observation.Context, ready servi
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
g.Go(func() error {
|
||||
logger.Info("http server listening", log.String("address", config.http.addr))
|
||||
if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
||||
logger.Error("problem running http server", log.Error(err))
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
logger.Info("starting manager")
|
||||
if err := mgr.Start(ctx); err != nil {
|
||||
@ -98,14 +113,18 @@ func Start(ctx context.Context, observationCtx *observation.Context, ready servi
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
g.Go(func() error {
|
||||
<-ctx.Done()
|
||||
grpcServer.GracefulStop()
|
||||
logger.Info("shutting down gRPC server gracefully")
|
||||
_ = srv.Shutdown(ctx)
|
||||
logger.Info("shutting down http server gracefully")
|
||||
return ctx.Err()
|
||||
})
|
||||
|
||||
// Mark health server as ready
|
||||
ready()
|
||||
|
||||
return g.Wait()
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,18 @@ go_library(
|
||||
name = "appliance",
|
||||
srcs = [
|
||||
"appliance.go",
|
||||
"embed.go",
|
||||
"grpc.go",
|
||||
"html.go",
|
||||
"routes.go",
|
||||
],
|
||||
embedsrcs = [
|
||||
"web/static/img/favicon.png",
|
||||
"web/static/script/htmx.min.js",
|
||||
"web/template/setup.gohtml",
|
||||
"web/static/css/bootstrap.min.css",
|
||||
"web/static/css/custom.css",
|
||||
"web/static/script/bootstrap.bundle.min.js",
|
||||
],
|
||||
importpath = "github.com/sourcegraph/sourcegraph/internal/appliance",
|
||||
visibility = ["//:__subpackages__"],
|
||||
@ -12,9 +23,12 @@ go_library(
|
||||
"//internal/appliance/config",
|
||||
"//internal/appliance/v1:appliance",
|
||||
"//lib/pointers",
|
||||
"@com_github_masterminds_semver//:semver",
|
||||
"@com_github_gorilla_mux//:mux",
|
||||
"@com_github_sourcegraph_log//:log",
|
||||
"@io_k8s_api//core/v1:core",
|
||||
"@io_k8s_apimachinery//pkg/api/errors",
|
||||
"@io_k8s_apimachinery//pkg/apis/meta/v1:meta",
|
||||
"@io_k8s_apimachinery//pkg/types",
|
||||
"@io_k8s_sigs_controller_runtime//pkg/client",
|
||||
"@io_k8s_sigs_yaml//:yaml",
|
||||
],
|
||||
|
||||
@ -3,9 +3,11 @@ package appliance
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Masterminds/semver"
|
||||
"github.com/sourcegraph/log"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/yaml"
|
||||
|
||||
@ -15,11 +17,10 @@ import (
|
||||
)
|
||||
|
||||
type Appliance struct {
|
||||
client client.Client
|
||||
|
||||
version semver.Version
|
||||
client client.Client
|
||||
status Status
|
||||
sourcegraph config.Sourcegraph
|
||||
logger log.Logger
|
||||
|
||||
// Embed the UnimplementedApplianceServiceServer structs to ensure forwards compatibility (if the service is
|
||||
// compiled against a newer version of the proto file, the server will still have default implementations of any new
|
||||
@ -27,43 +28,34 @@ type Appliance struct {
|
||||
pb.UnimplementedApplianceServiceServer
|
||||
}
|
||||
|
||||
type Status struct {
|
||||
stage Stage
|
||||
}
|
||||
|
||||
// Stage is a Stage that an Appliance can be in.
|
||||
type Stage string
|
||||
// Status is a Stage that an Appliance can be in.
|
||||
type Status string
|
||||
|
||||
const (
|
||||
StageUnknown Stage = "unknown"
|
||||
StageIdle Stage = "idle"
|
||||
StageInstall Stage = "install"
|
||||
StageInstalling Stage = "installing"
|
||||
StageUpgrading Stage = "upgrading"
|
||||
StageWaitingForAdmin Stage = "waitingForAdmin"
|
||||
StageRefresh Stage = "refresh"
|
||||
StatusUnknown Status = "unknown"
|
||||
StatusSetup Status = "setup"
|
||||
StatusInstalling Status = "installing"
|
||||
)
|
||||
|
||||
func (s Stage) String() string {
|
||||
func (s Status) String() string {
|
||||
return string(s)
|
||||
}
|
||||
|
||||
func NewAppliance(client client.Client) *Appliance {
|
||||
func NewAppliance(client client.Client, logger log.Logger) *Appliance {
|
||||
return &Appliance{
|
||||
client: client,
|
||||
status: Status{
|
||||
stage: StageUnknown,
|
||||
},
|
||||
client: client,
|
||||
status: StatusSetup,
|
||||
sourcegraph: config.Sourcegraph{},
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Appliance) GetCurrentVersion(ctx context.Context) semver.Version {
|
||||
return a.version
|
||||
func (a *Appliance) GetCurrentVersion(ctx context.Context) string {
|
||||
return a.sourcegraph.Status.CurrentVersion
|
||||
}
|
||||
|
||||
func (a *Appliance) GetCurrentStage(ctx context.Context) Stage {
|
||||
return a.status.stage
|
||||
func (a *Appliance) GetCurrentStatus(ctx context.Context) Status {
|
||||
return a.status
|
||||
}
|
||||
|
||||
func (a *Appliance) CreateConfigMap(ctx context.Context, name, namespace string) (*corev1.ConfigMap, error) {
|
||||
@ -90,5 +82,40 @@ func (a *Appliance) CreateConfigMap(ctx context.Context, name, namespace string)
|
||||
},
|
||||
}
|
||||
|
||||
if err := a.client.Create(ctx, configMap); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return configMap, nil
|
||||
}
|
||||
|
||||
func (a *Appliance) GetConfigMap(ctx context.Context, name, namespace string) (*corev1.ConfigMap, error) {
|
||||
var applianceSpec corev1.ConfigMap
|
||||
err := a.client.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, &applianceSpec)
|
||||
if apierrors.IsNotFound(err) {
|
||||
return nil, nil
|
||||
} else if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &applianceSpec, nil
|
||||
}
|
||||
|
||||
func (a *Appliance) shouldSetupRun(ctx context.Context) (bool, error) {
|
||||
cfgMap, err := a.GetConfigMap(ctx, "sourcegraph-appliance", "default") //TODO unhardcode and load namespace properly
|
||||
switch {
|
||||
case err != nil:
|
||||
return false, err
|
||||
case a.status == StatusInstalling:
|
||||
// configMap does not exist but is being created
|
||||
return false, nil
|
||||
case cfgMap == nil:
|
||||
// configMap does not exist
|
||||
return true, nil
|
||||
case cfgMap.Annotations[config.AnnotationKeyManaged] == "false":
|
||||
// appliance is not managed
|
||||
return false, nil
|
||||
default:
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,11 +266,19 @@ type SourcegraphSpec struct {
|
||||
StorageClass StorageClassSpec `json:"storageClass,omitempty"`
|
||||
}
|
||||
|
||||
// SetupStatus defines the observes status of the setup process.
|
||||
type SetupStatus struct {
|
||||
Progress int32
|
||||
}
|
||||
|
||||
// SourcegraphStatus defines the observed state of Sourcegraph
|
||||
type SourcegraphStatus struct {
|
||||
// CurrentVersion is the version of Sourcegraph currently running.
|
||||
CurrentVersion string `json:"currentVersion"`
|
||||
|
||||
// Setup tracks the progress of the setup process.
|
||||
Setup SetupStatus `json:"setup,omitempty"`
|
||||
|
||||
// Represents the latest available observations of Sourcegraph's current state.
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
15
internal/appliance/embed.go
Normal file
15
internal/appliance/embed.go
Normal file
@ -0,0 +1,15 @@
|
||||
package appliance
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed web/static
|
||||
staticFiles embed.FS
|
||||
staticFS, _ = fs.Sub(staticFiles, "web/static")
|
||||
|
||||
//go:embed web/template
|
||||
templateFS embed.FS
|
||||
)
|
||||
@ -7,13 +7,11 @@ import (
|
||||
)
|
||||
|
||||
func (a *Appliance) GetApplianceVersion(ctx context.Context, request *pb.GetApplianceVersionRequest) (*pb.GetApplianceVersionResponse, error) {
|
||||
version := a.GetCurrentVersion(ctx)
|
||||
|
||||
return &pb.GetApplianceVersionResponse{Version: version.String()}, nil
|
||||
return &pb.GetApplianceVersionResponse{Version: a.GetCurrentVersion(ctx)}, nil
|
||||
}
|
||||
|
||||
func (a *Appliance) GetApplianceStage(ctx context.Context, request *pb.GetApplianceStageRequest) (*pb.GetApplianceStageResponse, error) {
|
||||
stage := a.GetCurrentStage(ctx)
|
||||
func (a *Appliance) GetApplianceStatus(ctx context.Context, request *pb.GetApplianceStatusRequest) (*pb.GetApplianceStatusResponse, error) {
|
||||
status := a.GetCurrentStatus(ctx)
|
||||
|
||||
return &pb.GetApplianceStageResponse{Stage: stage.String()}, nil
|
||||
return &pb.GetApplianceStatusResponse{Status: status.String()}, nil
|
||||
}
|
||||
|
||||
80
internal/appliance/html.go
Normal file
80
internal/appliance/html.go
Normal file
@ -0,0 +1,80 @@
|
||||
package appliance
|
||||
|
||||
import (
|
||||
"context"
|
||||
"html/template"
|
||||
"net/http"
|
||||
|
||||
"github.com/sourcegraph/log"
|
||||
|
||||
"github.com/sourcegraph/sourcegraph/internal/appliance/config"
|
||||
)
|
||||
|
||||
const (
|
||||
templateSetup = "web/template/setup.gohtml"
|
||||
)
|
||||
|
||||
var (
|
||||
setupTmpl *template.Template
|
||||
)
|
||||
|
||||
func init() {
|
||||
setupTmpl = template.Must(template.ParseFS(templateFS, templateSetup))
|
||||
}
|
||||
|
||||
func (a *Appliance) applianceHandler(w http.ResponseWriter, r *http.Request) {
|
||||
if ok, _ := a.shouldSetupRun(context.Background()); ok {
|
||||
http.Redirect(w, r, "/appliance/setup", http.StatusSeeOther)
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Appliance) getSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
err := setupTmpl.Execute(w, "")
|
||||
if err != nil {
|
||||
a.logger.Error("failed to execute templating", log.Error(err))
|
||||
// Handle err
|
||||
}
|
||||
}
|
||||
|
||||
func (a *Appliance) postSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||
err := r.ParseForm()
|
||||
if err != nil {
|
||||
a.logger.Error("failed to parse http form request", log.Error(err))
|
||||
// Handle err
|
||||
}
|
||||
|
||||
a.sourcegraph.Spec.RequestedVersion = r.FormValue("version")
|
||||
if r.FormValue("external_database") == "yes" {
|
||||
a.sourcegraph.Spec.PGSQL.DatabaseConnection = &config.DatabaseConnectionSpec{
|
||||
Host: r.FormValue("pgsqlDBHost"),
|
||||
Port: r.FormValue("pgsqlDBPort"),
|
||||
User: r.FormValue("pgsqlDBUser"),
|
||||
Password: r.FormValue("pgsqlDBPassword"),
|
||||
Database: r.FormValue("pgsqlDBName"),
|
||||
}
|
||||
a.sourcegraph.Spec.CodeIntel.DatabaseConnection = &config.DatabaseConnectionSpec{
|
||||
Host: r.FormValue("codeintelDBHost"),
|
||||
Port: r.FormValue("codeintelDBPort"),
|
||||
User: r.FormValue("codeintelDBUser"),
|
||||
Password: r.FormValue("codeintelDBPassword"),
|
||||
Database: r.FormValue("codeintelDBName"),
|
||||
}
|
||||
a.sourcegraph.Spec.CodeInsights.DatabaseConnection = &config.DatabaseConnectionSpec{
|
||||
Host: r.FormValue("codeinsightsDBHost"),
|
||||
Port: r.FormValue("codeinsightsDBPort"),
|
||||
User: r.FormValue("codeinsightsDBUser"),
|
||||
Password: r.FormValue("codeinsightsDBPassword"),
|
||||
Database: r.FormValue("codeinsightsDBName"),
|
||||
}
|
||||
}
|
||||
// TODO validate user input
|
||||
|
||||
_, err = a.CreateConfigMap(r.Context(), "sourcegraph-appliance", "default") //TODO namespace
|
||||
if err != nil {
|
||||
a.logger.Error("failed to create configMap sourcegraph-appliance", log.Error(err))
|
||||
// Handle err
|
||||
}
|
||||
a.status = StatusInstalling
|
||||
|
||||
http.Redirect(w, r, "/appliance", http.StatusSeeOther)
|
||||
}
|
||||
20
internal/appliance/routes.go
Normal file
20
internal/appliance/routes.go
Normal file
@ -0,0 +1,20 @@
|
||||
package appliance
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
func (a *Appliance) Routes() *mux.Router {
|
||||
r := mux.NewRouter()
|
||||
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", http.FileServer(http.FS(staticFS))))
|
||||
r.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Redirect(w, r, "/appliance", http.StatusFound)
|
||||
})
|
||||
r.HandleFunc("/appliance", a.applianceHandler).Methods(http.MethodGet)
|
||||
r.HandleFunc("/appliance/setup", a.getSetupHandler).Methods(http.MethodGet)
|
||||
r.HandleFunc("/appliance/setup", a.postSetupHandler).Methods(http.MethodPost)
|
||||
|
||||
return r
|
||||
}
|
||||
101
internal/appliance/v1/appliance.pb.go
generated
101
internal/appliance/v1/appliance.pb.go
generated
@ -105,14 +105,14 @@ func (x *GetApplianceVersionResponse) GetVersion() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetApplianceStageRequest struct {
|
||||
type GetApplianceStatusRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *GetApplianceStageRequest) Reset() {
|
||||
*x = GetApplianceStageRequest{}
|
||||
func (x *GetApplianceStatusRequest) Reset() {
|
||||
*x = GetApplianceStatusRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_appliance_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -120,13 +120,13 @@ func (x *GetApplianceStageRequest) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetApplianceStageRequest) String() string {
|
||||
func (x *GetApplianceStatusRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetApplianceStageRequest) ProtoMessage() {}
|
||||
func (*GetApplianceStatusRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetApplianceStageRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *GetApplianceStatusRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_appliance_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -138,21 +138,21 @@ func (x *GetApplianceStageRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetApplianceStageRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetApplianceStageRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use GetApplianceStatusRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetApplianceStatusRequest) Descriptor() ([]byte, []int) {
|
||||
return file_appliance_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
type GetApplianceStageResponse struct {
|
||||
type GetApplianceStatusResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Stage string `protobuf:"bytes,1,opt,name=stage,proto3" json:"stage,omitempty"`
|
||||
Status string `protobuf:"bytes,1,opt,name=status,proto3" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetApplianceStageResponse) Reset() {
|
||||
*x = GetApplianceStageResponse{}
|
||||
func (x *GetApplianceStatusResponse) Reset() {
|
||||
*x = GetApplianceStatusResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_appliance_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -160,13 +160,13 @@ func (x *GetApplianceStageResponse) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetApplianceStageResponse) String() string {
|
||||
func (x *GetApplianceStatusResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetApplianceStageResponse) ProtoMessage() {}
|
||||
func (*GetApplianceStatusResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetApplianceStageResponse) ProtoReflect() protoreflect.Message {
|
||||
func (x *GetApplianceStatusResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_appliance_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@ -178,14 +178,14 @@ func (x *GetApplianceStageResponse) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetApplianceStageResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetApplianceStageResponse) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use GetApplianceStatusResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetApplianceStatusResponse) Descriptor() ([]byte, []int) {
|
||||
return file_appliance_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
func (x *GetApplianceStageResponse) GetStage() string {
|
||||
func (x *GetApplianceStatusResponse) GetStatus() string {
|
||||
if x != nil {
|
||||
return x.Stage
|
||||
return x.Status
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@ -200,31 +200,32 @@ var file_appliance_proto_rawDesc = []byte{
|
||||
0x1b, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07,
|
||||
0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x1a, 0x0a, 0x18, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70,
|
||||
0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x22, 0x31, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e,
|
||||
0x63, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,
|
||||
0x73, 0x74, 0x61, 0x67, 0x65, 0x32, 0xee, 0x01, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6f, 0x0a, 0x13, 0x47, 0x65,
|
||||
0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x76, 0x31,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x65, 0x72,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x29, 0x2e, 0x61, 0x70,
|
||||
0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70,
|
||||
0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12, 0x69, 0x0a, 0x11, 0x47,
|
||||
0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65,
|
||||
0x12, 0x26, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x67,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69,
|
||||
0x61, 0x6e, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69,
|
||||
0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x42, 0x3a, 0x5a, 0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
|
||||
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68,
|
||||
0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x69, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2f,
|
||||
0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x1b, 0x0a, 0x19, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70,
|
||||
0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x22, 0x34, 0x0a, 0x1a, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x32, 0xf1, 0x01, 0x0a, 0x10, 0x41, 0x70,
|
||||
0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x6f,
|
||||
0x0a, 0x13, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x65,
|
||||
0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x28, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
|
||||
0x29, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x56, 0x65, 0x72, 0x73, 0x69,
|
||||
0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x12,
|
||||
0x6c, 0x0a, 0x12, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53,
|
||||
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x27, 0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28,
|
||||
0x2e, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x03, 0x90, 0x02, 0x01, 0x42, 0x3a, 0x5a,
|
||||
0x38, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x6f, 0x75, 0x72,
|
||||
0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72,
|
||||
0x61, 0x70, 0x68, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x61, 0x70, 0x70,
|
||||
0x6c, 0x69, 0x61, 0x6e, 0x63, 0x65, 0x2f, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
@ -243,14 +244,14 @@ var file_appliance_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
|
||||
var file_appliance_proto_goTypes = []interface{}{
|
||||
(*GetApplianceVersionRequest)(nil), // 0: appliance.v1.GetApplianceVersionRequest
|
||||
(*GetApplianceVersionResponse)(nil), // 1: appliance.v1.GetApplianceVersionResponse
|
||||
(*GetApplianceStageRequest)(nil), // 2: appliance.v1.GetApplianceStageRequest
|
||||
(*GetApplianceStageResponse)(nil), // 3: appliance.v1.GetApplianceStageResponse
|
||||
(*GetApplianceStatusRequest)(nil), // 2: appliance.v1.GetApplianceStatusRequest
|
||||
(*GetApplianceStatusResponse)(nil), // 3: appliance.v1.GetApplianceStatusResponse
|
||||
}
|
||||
var file_appliance_proto_depIdxs = []int32{
|
||||
0, // 0: appliance.v1.ApplianceService.GetApplianceVersion:input_type -> appliance.v1.GetApplianceVersionRequest
|
||||
2, // 1: appliance.v1.ApplianceService.GetApplianceStage:input_type -> appliance.v1.GetApplianceStageRequest
|
||||
2, // 1: appliance.v1.ApplianceService.GetApplianceStatus:input_type -> appliance.v1.GetApplianceStatusRequest
|
||||
1, // 2: appliance.v1.ApplianceService.GetApplianceVersion:output_type -> appliance.v1.GetApplianceVersionResponse
|
||||
3, // 3: appliance.v1.ApplianceService.GetApplianceStage:output_type -> appliance.v1.GetApplianceStageResponse
|
||||
3, // 3: appliance.v1.ApplianceService.GetApplianceStatus:output_type -> appliance.v1.GetApplianceStatusResponse
|
||||
2, // [2:4] is the sub-list for method output_type
|
||||
0, // [0:2] is the sub-list for method input_type
|
||||
0, // [0:0] is the sub-list for extension type_name
|
||||
@ -289,7 +290,7 @@ func file_appliance_proto_init() {
|
||||
}
|
||||
}
|
||||
file_appliance_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetApplianceStageRequest); i {
|
||||
switch v := v.(*GetApplianceStatusRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@ -301,7 +302,7 @@ func file_appliance_proto_init() {
|
||||
}
|
||||
}
|
||||
file_appliance_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetApplianceStageResponse); i {
|
||||
switch v := v.(*GetApplianceStatusResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
||||
@ -9,7 +9,7 @@ service ApplianceService {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
|
||||
rpc GetApplianceStage(GetApplianceStageRequest) returns (GetApplianceStageResponse) {
|
||||
rpc GetApplianceStatus(GetApplianceStatusRequest) returns (GetApplianceStatusResponse) {
|
||||
option idempotency_level = NO_SIDE_EFFECTS;
|
||||
}
|
||||
}
|
||||
@ -20,8 +20,8 @@ message GetApplianceVersionResponse {
|
||||
string version = 1;
|
||||
}
|
||||
|
||||
message GetApplianceStageRequest {}
|
||||
message GetApplianceStatusRequest {}
|
||||
|
||||
message GetApplianceStageResponse {
|
||||
string stage = 1;
|
||||
message GetApplianceStatusResponse {
|
||||
string status = 1;
|
||||
}
|
||||
|
||||
30
internal/appliance/v1/appliance_grpc.pb.go
generated
30
internal/appliance/v1/appliance_grpc.pb.go
generated
@ -20,7 +20,7 @@ const _ = grpc.SupportPackageIsVersion7
|
||||
|
||||
const (
|
||||
ApplianceService_GetApplianceVersion_FullMethodName = "/appliance.v1.ApplianceService/GetApplianceVersion"
|
||||
ApplianceService_GetApplianceStage_FullMethodName = "/appliance.v1.ApplianceService/GetApplianceStage"
|
||||
ApplianceService_GetApplianceStatus_FullMethodName = "/appliance.v1.ApplianceService/GetApplianceStatus"
|
||||
)
|
||||
|
||||
// ApplianceServiceClient is the client API for ApplianceService service.
|
||||
@ -28,7 +28,7 @@ const (
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
|
||||
type ApplianceServiceClient interface {
|
||||
GetApplianceVersion(ctx context.Context, in *GetApplianceVersionRequest, opts ...grpc.CallOption) (*GetApplianceVersionResponse, error)
|
||||
GetApplianceStage(ctx context.Context, in *GetApplianceStageRequest, opts ...grpc.CallOption) (*GetApplianceStageResponse, error)
|
||||
GetApplianceStatus(ctx context.Context, in *GetApplianceStatusRequest, opts ...grpc.CallOption) (*GetApplianceStatusResponse, error)
|
||||
}
|
||||
|
||||
type applianceServiceClient struct {
|
||||
@ -48,9 +48,9 @@ func (c *applianceServiceClient) GetApplianceVersion(ctx context.Context, in *Ge
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *applianceServiceClient) GetApplianceStage(ctx context.Context, in *GetApplianceStageRequest, opts ...grpc.CallOption) (*GetApplianceStageResponse, error) {
|
||||
out := new(GetApplianceStageResponse)
|
||||
err := c.cc.Invoke(ctx, ApplianceService_GetApplianceStage_FullMethodName, in, out, opts...)
|
||||
func (c *applianceServiceClient) GetApplianceStatus(ctx context.Context, in *GetApplianceStatusRequest, opts ...grpc.CallOption) (*GetApplianceStatusResponse, error) {
|
||||
out := new(GetApplianceStatusResponse)
|
||||
err := c.cc.Invoke(ctx, ApplianceService_GetApplianceStatus_FullMethodName, in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -62,7 +62,7 @@ func (c *applianceServiceClient) GetApplianceStage(ctx context.Context, in *GetA
|
||||
// for forward compatibility
|
||||
type ApplianceServiceServer interface {
|
||||
GetApplianceVersion(context.Context, *GetApplianceVersionRequest) (*GetApplianceVersionResponse, error)
|
||||
GetApplianceStage(context.Context, *GetApplianceStageRequest) (*GetApplianceStageResponse, error)
|
||||
GetApplianceStatus(context.Context, *GetApplianceStatusRequest) (*GetApplianceStatusResponse, error)
|
||||
mustEmbedUnimplementedApplianceServiceServer()
|
||||
}
|
||||
|
||||
@ -73,8 +73,8 @@ type UnimplementedApplianceServiceServer struct {
|
||||
func (UnimplementedApplianceServiceServer) GetApplianceVersion(context.Context, *GetApplianceVersionRequest) (*GetApplianceVersionResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetApplianceVersion not implemented")
|
||||
}
|
||||
func (UnimplementedApplianceServiceServer) GetApplianceStage(context.Context, *GetApplianceStageRequest) (*GetApplianceStageResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetApplianceStage not implemented")
|
||||
func (UnimplementedApplianceServiceServer) GetApplianceStatus(context.Context, *GetApplianceStatusRequest) (*GetApplianceStatusResponse, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetApplianceStatus not implemented")
|
||||
}
|
||||
func (UnimplementedApplianceServiceServer) mustEmbedUnimplementedApplianceServiceServer() {}
|
||||
|
||||
@ -107,20 +107,20 @@ func _ApplianceService_GetApplianceVersion_Handler(srv interface{}, ctx context.
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _ApplianceService_GetApplianceStage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetApplianceStageRequest)
|
||||
func _ApplianceService_GetApplianceStatus_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetApplianceStatusRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ApplianceServiceServer).GetApplianceStage(ctx, in)
|
||||
return srv.(ApplianceServiceServer).GetApplianceStatus(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: ApplianceService_GetApplianceStage_FullMethodName,
|
||||
FullMethod: ApplianceService_GetApplianceStatus_FullMethodName,
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ApplianceServiceServer).GetApplianceStage(ctx, req.(*GetApplianceStageRequest))
|
||||
return srv.(ApplianceServiceServer).GetApplianceStatus(ctx, req.(*GetApplianceStatusRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@ -137,8 +137,8 @@ var ApplianceService_ServiceDesc = grpc.ServiceDesc{
|
||||
Handler: _ApplianceService_GetApplianceVersion_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetApplianceStage",
|
||||
Handler: _ApplianceService_GetApplianceStage_Handler,
|
||||
MethodName: "GetApplianceStatus",
|
||||
Handler: _ApplianceService_GetApplianceStatus_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
|
||||
6
internal/appliance/web/static/css/bootstrap.min.css
vendored
Normal file
6
internal/appliance/web/static/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
17
internal/appliance/web/static/css/custom.css
Normal file
17
internal/appliance/web/static/css/custom.css
Normal file
@ -0,0 +1,17 @@
|
||||
/* Define custom CSS variables */
|
||||
:root {
|
||||
--bs-primary: #3498db;
|
||||
--bs-secondary: #2ecc71;
|
||||
--bs-success: #28a745;
|
||||
--bs-info: #17a2b8;
|
||||
--bs-warning: #ffc107;
|
||||
--bs-danger: #dc3545;
|
||||
--bs-light: #f8f9fa;
|
||||
--bs-dark: #343a40;
|
||||
}
|
||||
|
||||
/* Override Bootstrap variables */
|
||||
body {
|
||||
background-color: var(--bs-light);
|
||||
color: var(--bs-dark);
|
||||
}
|
||||
BIN
internal/appliance/web/static/img/favicon.png
Normal file
BIN
internal/appliance/web/static/img/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
7
internal/appliance/web/static/script/bootstrap.bundle.min.js
vendored
Normal file
7
internal/appliance/web/static/script/bootstrap.bundle.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
internal/appliance/web/static/script/htmx.min.js
vendored
Normal file
1
internal/appliance/web/static/script/htmx.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
148
internal/appliance/web/template/setup.gohtml
Normal file
148
internal/appliance/web/template/setup.gohtml
Normal file
@ -0,0 +1,148 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="icon" type="image/svg+xml" href="/static/img/favicon.png" />
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/bootstrap.min.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/custom.css">
|
||||
<script src="/static/script/htmx.min.js"></script>
|
||||
<script src="/static/script/bootstrap.bundle.min.js"></script>
|
||||
<title>Sourcegraph Appliance - Setup</title>
|
||||
</head>
|
||||
|
||||
<body hx-boost="true" class="container">
|
||||
<h1>Sourcegraph Appliance Setup</h1>
|
||||
|
||||
<form action="/appliance/setup" method="post">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="version" class="fw-bold">Sourcegraph Version</label>
|
||||
<p class="fw-light">Choose the Sourcegraph version that you would like to install.</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<select id="version" name="version" class="row form-select mb-3" aria-label="Sourcegraph version selection">
|
||||
<option selected>Latest</option>
|
||||
<option value="5.4">5.4</option>
|
||||
<option value="5.3">5.3</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr/>
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="external_database" class="fw-bold">Database</label>
|
||||
<p>Would you like to use an external database?</p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="form-switch mb-3">
|
||||
<input class="form-check-input" data-bs-toggle="collapse" href="#database" type="checkbox" id="external_database" name="external_database">
|
||||
<label class="form-check-label" for="external_database">Use an external database</label>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="accordion collapse mb-3" id="database">
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button" type="button" data-bs-toggle="collapse" data-bs-target="#collapseOne" aria-expanded="true" aria-controls="collapseOne">
|
||||
<strong>Sourcegraph Database</strong>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseOne" class="accordion-collapse collapse show" data-bs-parent="#database">
|
||||
<div class="accordion-body">
|
||||
<div class="mb-3">
|
||||
<label for="pgsqlDBHost" class="form-label">Database Host</label>
|
||||
<input type="text" class="form-control" id="pgsqlDBHost" name="pgsqlDBHost" placeholder="hostname">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="pgsqlDBPort" class="form-label">Database Port</label>
|
||||
<input type="text" class="form-control" id="pgsqlDBPort" name="pgsqlDBPort" placeholder="5432">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="pgsqlDBUser" class="form-label">Database User</label>
|
||||
<input type="text" class="form-control" id="pgsqlDBUser" name="pgsqlDBUser" placeholder="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="pgsqlDBPassword" class="form-label">Database Password</label>
|
||||
<input type="password" class="form-control" id="pgsqlDBPassword" name="pgsqlDBPassword" placeholder="password">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="pgsqlDBName" class="form-label">Database Name</label>
|
||||
<input type="text" class="form-control" id="pgsqlDBName" name="pgsqlDBName" placeholder="sg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
|
||||
<strong>CodeIntel Database</strong>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#database">
|
||||
<div class="accordion-body">
|
||||
<div class="mb-3">
|
||||
<label for="codeintelDBHost" class="form-label">Database Host</label>
|
||||
<input type="text" class="form-control" id="codeintelDBHost" name="codeintelDBHost" placeholder="hostname">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeintelDBPort" class="form-label">Database Port</label>
|
||||
<input type="text" class="form-control" id="codeintelDBPort" name="codeintelDBPort" placeholder="5432">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeintelDBUser" class="form-label">Database User</label>
|
||||
<input type="text" class="form-control" id="codeintelDBUser" name="codeintelDBUser" placeholder="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeintelDBPassword" class="form-label">Database Password</label>
|
||||
<input type="password" class="form-control" id="codeintelDBPassword" name="codeintelDBPassword" placeholder="password">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeintelDBName" class="form-label">Database Name</label>
|
||||
<input type="text" class="form-control" id="codeintelDBName" name="codeintelDBName" placeholder="sg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="accordion-item">
|
||||
<h2 class="accordion-header">
|
||||
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#collapseThree" aria-expanded="false" aria-controls="collapseThree">
|
||||
<strong>CodeInsights Database</strong>
|
||||
</button>
|
||||
</h2>
|
||||
<div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#database">
|
||||
<div class="accordion-body">
|
||||
<div class="mb-3">
|
||||
<label for="codeinsightsDBHost" class="form-label">Database Host</label>
|
||||
<input type="text" class="form-control" id="codeinsightsDBHost" name="codeinsightsDBHost" placeholder="hostname">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeinsightsDBPort" class="form-label">Database Port</label>
|
||||
<input type="text" class="form-control" id="codeinsightsDBPort" name="codeinsightsDBPort" placeholder="5432">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeinsightsDBUser" class="form-label">Database User</label>
|
||||
<input type="text" class="form-control" id="codeinsightsDBUser" name="codeinsightsDBUser" placeholder="username">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeinsightsDBPassword" class="form-label">Database Password</label>
|
||||
<input type="password" class="form-control" id="codeinsightsDBPassword" name="codeinsightsDBPassword" placeholder="password">
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="codeinsightsDBName" class="form-label">Database Name</label>
|
||||
<input type="text" class="form-control" id="codeinsightsDBName" name="codeinsightsDBName" placeholder="sg">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary">Start Setup</button>
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in New Issue
Block a user