pings: bootstrap initial code logic (#55467)

This commit is contained in:
Joe Chen 2023-08-15 16:27:29 -04:00 committed by GitHub
parent 13ffb304b4
commit 6c8227ebbd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 298 additions and 5 deletions

72
cmd/pings/BUILD.bazel Normal file
View File

@ -0,0 +1,72 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
load("@rules_oci//oci:defs.bzl", "oci_image", "oci_push", "oci_tarball")
load("@rules_pkg//:pkg.bzl", "pkg_tar")
load("@container_structure_test//:defs.bzl", "container_structure_test")
load("//dev:oci_defs.bzl", "image_repository")
go_library(
name = "pings_lib",
srcs = ["main.go"],
importpath = "github.com/sourcegraph/sourcegraph/cmd/pings",
visibility = ["//visibility:private"],
deps = [
"//cmd/pings/shared",
"//internal/conf",
"//internal/env",
"//internal/sanitycheck",
"//internal/service/svcmain",
"@com_github_getsentry_sentry_go//:sentry-go",
"@com_github_sourcegraph_log//:log",
],
)
go_binary(
name = "pings",
embed = [":pings_lib"],
visibility = ["//visibility:public"],
x_defs = {
"github.com/sourcegraph/sourcegraph/internal/version.version": "{STABLE_VERSION}",
"github.com/sourcegraph/sourcegraph/internal/version.timestamp": "{VERSION_TIMESTAMP}",
},
)
pkg_tar(
name = "tar_pings",
srcs = [":pings"],
)
oci_image(
name = "image",
base = "@wolfi_base",
entrypoint = [
"/sbin/tini",
"--",
"/pings",
],
tars = [":tar_pings"],
user = "sourcegraph",
)
oci_tarball(
name = "image_tarball",
image = ":image",
repo_tags = ["pings:candidate"],
)
container_structure_test(
name = "image_test",
timeout = "short",
configs = ["image_test.yaml"],
driver = "docker",
image = ":image",
tags = [
"exclusive",
"requires-network",
],
)
oci_push(
name = "candidate_push",
image = ":image",
repository = image_repository("pings"),
)

15
cmd/pings/image_test.yaml Normal file
View File

@ -0,0 +1,15 @@
schemaVersion: "2.0.0"
commandTests:
- name: "binary is runnable"
command: "/pings"
envVars:
- key: "SANITY_CHECK"
value: "true"
- name: "not running as root"
command: "/usr/bin/id"
args:
- -u
excludedOutput: ["^0"]
exitCode: 0

34
cmd/pings/main.go Normal file
View File

@ -0,0 +1,34 @@
package main
import (
"github.com/getsentry/sentry-go"
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/cmd/pings/shared"
"github.com/sourcegraph/sourcegraph/internal/conf"
"github.com/sourcegraph/sourcegraph/internal/env"
"github.com/sourcegraph/sourcegraph/internal/sanitycheck"
"github.com/sourcegraph/sourcegraph/internal/service/svcmain"
)
var sentryDSN = env.Get("PINGS_SENTRY_DSN", "", "Sentry DSN")
func main() {
sanitycheck.Pass()
svcmain.SingleServiceMainWithoutConf(shared.Service, svcmain.Config{}, svcmain.OutOfBandConfiguration{
Logging: func() conf.LogSinksSource {
if sentryDSN == "" {
return nil
}
return conf.NewStaticLogsSinksSource(log.SinksConfig{
Sentry: &log.SentrySink{
ClientOptions: sentry.ClientOptions{
Dsn: sentryDSN,
},
},
})
}(),
Tracing: nil,
})
}

View File

@ -0,0 +1,26 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library")
go_library(
name = "shared",
srcs = [
"config.go",
"main.go",
"service.go",
],
importpath = "github.com/sourcegraph/sourcegraph/cmd/pings/shared",
visibility = ["//visibility:public"],
deps = [
"//internal/debugserver",
"//internal/env",
"//internal/goroutine",
"//internal/httpserver",
"//internal/observation",
"//internal/pubsub",
"//internal/service",
"//internal/updatecheck",
"//internal/version",
"//lib/errors",
"@com_github_gorilla_mux//:mux",
"@com_github_sourcegraph_log//:log",
],
)

View File

@ -0,0 +1,22 @@
package shared
import (
"github.com/sourcegraph/sourcegraph/internal/env"
)
type Config struct {
env.BaseConfig
Address string
PubSub struct {
ProjectID string
TopicID string
}
}
func (c *Config) Load() {
c.Address = c.Get("PINGS_ADDR", ":10086", "Address to serve Ping service on.")
c.PubSub.ProjectID = c.Get("PINGS_PUBSUB_PROJECT_ID", "", "The project ID for the Pub/Sub.")
c.PubSub.TopicID = c.Get("PINGS_PUBSUB_TOPIC_ID", "", "The topic ID for the Pub/Sub.")
}

77
cmd/pings/shared/main.go Normal file
View File

@ -0,0 +1,77 @@
package shared
import (
"context"
"net/http"
"time"
"github.com/gorilla/mux"
"github.com/sourcegraph/log"
"github.com/sourcegraph/sourcegraph/internal/goroutine"
"github.com/sourcegraph/sourcegraph/internal/httpserver"
"github.com/sourcegraph/sourcegraph/internal/observation"
"github.com/sourcegraph/sourcegraph/internal/pubsub"
"github.com/sourcegraph/sourcegraph/internal/service"
"github.com/sourcegraph/sourcegraph/internal/updatecheck"
"github.com/sourcegraph/sourcegraph/internal/version"
"github.com/sourcegraph/sourcegraph/lib/errors"
)
func Main(ctx context.Context, obctx *observation.Context, ready service.ReadyFunc, config *Config) error {
// Initialize our server
serverHandler, err := newServerHandler(obctx.Logger, config)
if err != nil {
return errors.Errorf("create server handler: %v", err)
}
server := httpserver.NewFromAddr(
config.Address,
&http.Server{
ReadTimeout: 75 * time.Second,
WriteTimeout: 10 * time.Minute,
Handler: serverHandler,
},
)
// Mark health server as ready and go!
ready()
obctx.Logger.Info("service ready", log.String("address", config.Address))
// Block until done
goroutine.MonitorBackgroundRoutines(ctx, server)
return nil
}
func newServerHandler(logger log.Logger, config *Config) (http.Handler, error) {
r := mux.NewRouter()
r.Path("/-/version").Methods(http.MethodGet).HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(version.Version()))
})
pubsubClient, err := pubsub.NewTopicClient(config.PubSub.ProjectID, config.PubSub.TopicID)
if err != nil {
return nil, errors.Errorf("create Pub/Sub client: %v", err)
}
r.Path("/-/healthz").Methods(http.MethodGet).HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
var errs error
if err = pubsubClient.Ping(context.Background()); err != nil {
errs = errors.Append(errs, errors.Errorf("Pub/Sub client: %v", err))
}
if errs != nil {
w.WriteHeader(http.StatusInternalServerError)
_, _ = w.Write([]byte(errs.Error()))
return
}
w.WriteHeader(http.StatusOK)
_, _ = w.Write([]byte(http.StatusText(http.StatusOK)))
})
r.Path("/updates").
Methods(http.MethodGet, http.MethodPost).
HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
updatecheck.HandlePingRequest(logger, pubsubClient, w, r)
})
return r, nil
}

View File

@ -0,0 +1,27 @@
package shared
import (
"context"
"github.com/sourcegraph/sourcegraph/internal/debugserver"
"github.com/sourcegraph/sourcegraph/internal/env"
"github.com/sourcegraph/sourcegraph/internal/observation"
"github.com/sourcegraph/sourcegraph/internal/service"
)
// Service is the shared ping service.
var Service service.Service = svc{}
type svc struct{}
func (svc) Name() string { return "pings" }
func (svc) Configure() (env.Config, []debugserver.Endpoint) {
c := &Config{}
c.Load()
return c, []debugserver.Endpoint{}
}
func (svc) Start(ctx context.Context, observationCtx *observation.Context, ready service.ReadyFunc, config env.Config) error {
return Main(ctx, observationCtx, ready, config.(*Config))
}

View File

@ -27,6 +27,8 @@ allowed_prefix=(
github.com/sourcegraph/sourcegraph/cmd/symbols
# Transitively depends on zoekt package which imports but does not use DB
github.com/sourcegraph/sourcegraph/cmd/searcher
# Transitively depends on updatecheck package which imports but does not use DB
github.com/sourcegraph/sourcegraph/cmd/pings
# Main entrypoints for running all services, so they must be allowed to import it.
github.com/sourcegraph/sourcegraph/cmd/sourcegraph-oss
github.com/sourcegraph/sourcegraph/enterprise/cmd/sourcegraph

View File

@ -123,6 +123,7 @@ Available commands in `sg.config.yaml`:
* monitoring-generator
* multiqueue-executor
* otel-collector: OpenTelemetry collector
* pings
* postgres_exporter
* prometheus
* qdrant

View File

@ -10,7 +10,7 @@ go_library(
"handler.go",
],
importpath = "github.com/sourcegraph/sourcegraph/internal/updatecheck",
visibility = ["//cmd/frontend:__subpackages__"],
visibility = ["//:__subpackages__"],
deps = [
"//cmd/frontend/envvar",
"//cmd/frontend/globals",

View File

@ -84,13 +84,13 @@ func HandlerWithLog(logger log.Logger) (http.HandlerFunc, error) {
}
}
return func(w http.ResponseWriter, r *http.Request) {
handler(logger, pubsubClient, w, r)
HandlePingRequest(logger, pubsubClient, w, r)
}, nil
}
// handler is an HTTP handler that responds with information about software updates
// for Sourcegraph.
func handler(logger log.Logger, pubsubClient pubsub.TopicClient, w http.ResponseWriter, r *http.Request) {
// HandlePingRequest handles the ping requests and responds with information
// about software updates for Sourcegraph.
func HandlePingRequest(logger log.Logger, pubsubClient pubsub.TopicClient, w http.ResponseWriter, r *http.Request) {
requestCounter.Inc()
pr, err := readPingRequest(r)

View File

@ -316,6 +316,23 @@ commands:
- internal
- cmd/cody-gateway
pings:
cmd: |
.bin/pings
install: |
if [ -n "$DELVE" ]; then
export GCFLAGS='-N -l'
fi
go build -gcflags="$GCFLAGS" -o .bin/pings github.com/sourcegraph/sourcegraph/cmd/pings
checkBinary: .bin/pings
env:
SRC_LOG_LEVEL: info
watch:
- lib
- internal
- cmd/pings
searcher:
cmd: .bin/searcher
install: |