Skip to content

Commit

Permalink
Merge branch 'master' into engine-compat-sqlc
Browse files Browse the repository at this point in the history
  • Loading branch information
mastercactapus committed Nov 19, 2024
2 parents 318fc6b + b003761 commit 6773c9a
Show file tree
Hide file tree
Showing 134 changed files with 5,315 additions and 1,654 deletions.
2 changes: 2 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ module.exports = {
'react/jsx-fragments': ['error', 'element'],
'react/prop-types': 'off',

'no-useless-constructor': 'off', // buggy

// buggy, handled better by no unused imports and actual build
'import/no-unresolved': 'off',

Expand Down
30 changes: 17 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -65,9 +65,16 @@ release: container-demo container-goalert bin/goalert-linux-amd64.tgz bin/goaler
Makefile.binaries.mk: devtools/genmake/*
go run ./devtools/genmake >$@

$(BIN_DIR)/tools/k6: k6.version
go run ./devtools/gettool -t k6 -v $(shell cat k6.version) -o $@

$(BIN_DIR)/tools/protoc: protoc.version
go run ./devtools/gettool -t protoc -v $(shell cat protoc.version) -o $@


$(BIN_DIR)/tools/mailpit: mailpit.version
go run ./devtools/gettool -t mailpit -v $(shell cat mailpit.version) -o $@

$(BIN_DIR)/tools/sqlc: sqlc.version
go run ./devtools/gettool -t sqlc -v $(shell cat sqlc.version) -o $@

Expand Down Expand Up @@ -135,22 +142,22 @@ web/src/schema.d.ts: graphql2/schema.graphql graphql2/graph/*.graphqls web/src/g
help: ## Show all valid options
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)

start: bin/goalert bin/mockoidc $(NODE_DEPS) web/src/schema.d.ts $(BIN_DIR)/tools/prometheus ## Start the developer version of the application
start: bin/goalert bin/mockoidc $(NODE_DEPS) web/src/schema.d.ts $(BIN_DIR)/tools/prometheus $(BIN_DIR)/tools/mailpit ## Start the developer version of the application
@if [ -d ".vscode" ]; then \
echo "Detected .vscode directory, running 'vscode' target"; \
$(MAKE) vscode; \
fi
go run ./devtools/waitfor -timeout 1s "$(DB_URL)" || make postgres
GOALERT_VERSION=$(GIT_VERSION) GOALERT_STRICT_EXPERIMENTAL=1 go run ./devtools/runproc -f Procfile -l Procfile.local

start-prod: web/src/build/static/app.js bin/mockoidc $(BIN_DIR)/tools/prometheus ## Start the production version of the application
start-prod: web/src/build/static/app.js bin/mockoidc $(BIN_DIR)/tools/prometheus $(BIN_DIR)/tools/mailpit ## Start the production version of the application
# force rebuild to ensure build-flags are set
touch cmd/goalert/main.go
$(MAKE) $(MFLAGS) bin/goalert BUNDLE=1
go run ./devtools/runproc -f Procfile.prod -l Procfile.local


start-swo: bin/psql-lite bin/goalert bin/waitfor bin/mockoidc bin/runproc $(NODE_DEPS) web/src/schema.d.ts $(BIN_DIR)/tools/prometheus ## Start the developer version of the application in switchover mode (SWO)
start-swo: bin/psql-lite bin/goalert bin/waitfor bin/mockoidc bin/runproc $(NODE_DEPS) web/src/schema.d.ts $(BIN_DIR)/tools/prometheus $(BIN_DIR)/tools/mailpit ## Start the developer version of the application in switchover mode (SWO)
./bin/waitfor -timeout 1s "$(DB_URL)" || make postgres
./bin/goalert migrate --db-url=postgres://goalert@localhost/goalert
./bin/psql-lite -d postgres://goalert@localhost -c "update switchover_state set current_state = 'idle'; truncate table switchover_log; drop database if exists goalert2; create database goalert2;"
Expand All @@ -173,14 +180,14 @@ reset-integration: bin/waitfor bin/goalert.cover bin/psql-lite bin/resetdb
cat test/integration/setup/goalert-config.json | GOCOVERDIR=test/coverage/integration/reset ./bin/goalert.cover set-config --allow-empty-data-encryption-key --db-url "$(INT_DB_URL)"
rm -f *.session.json

start-integration: web/src/build/static/app.js bin/goalert bin/psql-lite bin/waitfor bin/runproc bin/procwrap $(BIN_DIR)/tools/prometheus reset-integration
start-integration: web/src/build/static/app.js bin/goalert bin/psql-lite bin/waitfor bin/runproc bin/procwrap $(BIN_DIR)/tools/prometheus $(BIN_DIR)/tools/mailpit reset-integration
GOALERT_DB_URL="$(INT_DB_URL)" ./bin/runproc -f Procfile.integration

jest: $(NODE_DEPS)
$(MAKE) ensure-yarn
yarn run jest $(JEST_ARGS)

test: $(NODE_DEPS) jest ## Run all unit tests
test: $(NODE_DEPS) jest $(BIN_DIR)/tools/mailpit ## Run all unit tests
rm -rf $(PWD)/test/coverage/unit
mkdir -p $(PWD)/test/coverage/unit
go test -coverpkg=./... -short ./... -args -test.gocoverdir=$(PWD)/test/coverage/unit
Expand Down Expand Up @@ -250,22 +257,19 @@ test-components: $(NODE_DEPS) bin/waitfor
storybook: ensure-yarn $(NODE_DEPS) # Start the Storybook UI
yarn storybook

bin/MailHog: go.mod go.sum
go build -o bin/MailHog github.com/mailhog/MailHog

playwright-run: $(NODE_DEPS) bin/mockoidc web/src/build/static/app.js bin/goalert.cover web/src/schema.d.ts $(BIN_DIR)/tools/prometheus reset-integration bin/MailHog ## Start playwright tests in headless mode
playwright-run: $(NODE_DEPS) bin/mockoidc web/src/build/static/app.js bin/goalert.cover web/src/schema.d.ts $(BIN_DIR)/tools/prometheus $(BIN_DIR)/tools/mailpit reset-integration ## Start playwright tests in headless mode
$(MAKE) ensure-yarn
rm -rf test/coverage/integration/playwright
mkdir -p test/coverage/integration/playwright
yarn playwright install chromium
GOCOVERDIR=test/coverage/integration/playwright yarn playwright test

playwright-ui: $(NODE_DEPS) bin/mockoidc web/src/build/static/app.js bin/goalert web/src/schema.d.ts $(BIN_DIR)/tools/prometheus reset-integration bin/MailHog ## Start the Playwright UI
playwright-ui: $(NODE_DEPS) bin/mockoidc web/src/build/static/app.js bin/goalert web/src/schema.d.ts $(BIN_DIR)/tools/prometheus $(BIN_DIR)/tools/mailpit reset-integration ## Start the Playwright UI
$(MAKE) ensure-yarn
yarn playwright install chromium
yarn playwright test --ui

smoketest:
smoketest: $(BIN_DIR)/tools/mailpit
rm -rf test/coverage/smoke
mkdir -p test/coverage/smoke
(cd test/smoke && go test -coverpkg=../../... -parallel 10 -timeout 20m -args -test.gocoverdir=$(PWD)/test/coverage/smoke)
Expand All @@ -290,8 +294,6 @@ tools:
go get -u golang.org/x/tools/cmd/bundle
go get -u golang.org/x/tools/cmd/gomvpkg
go get -u golang.org/x/tools/cmd/goimports
go get -u github.com/gordonklaus/ineffassign
go get -u honnef.co/go/tools/cmd/staticcheck
go get -u golang.org/x/tools/cmd/stringer

.pnp.cjs: yarn.lock Makefile package.json .yarnrc.yml
Expand All @@ -305,6 +307,8 @@ web/src/build/static/app.js: $(NODE_DEPS)
rm -rf web/src/build/static
mkdir -p web/src/build/static
cp -f web/src/app/public/icons/favicon-* web/src/app/public/logos/lightmode_* web/src/app/public/logos/darkmode_* web/src/build/static/
# used for email templates
cp web/src/app/public/logos/goalert-alt-logo.png web/src/build/static/
GOALERT_VERSION=$(GIT_VERSION) yarn run esbuild --prod
touch "$@"

Expand Down
2 changes: 1 addition & 1 deletion Procfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ build: while true; do make -qs bin/goalert || make bin/goalert || (echo '\033[0;
@watch-file=./bin/goalert
goalert: ./bin/goalert -l=localhost:3030 --ui-dir=web/src/build --db-url=postgres://goalert@localhost --listen-sysapi=localhost:1234 --listen-prometheus=localhost:2112 --smtp-listen=localhost:9025 --email-integration-domain=localhost --listen-pprof=localhost:6060 --pprof-mutex-profile-fraction=1 --pprof-block-profile-rate=1000

smtp: go run github.com/mailhog/MailHog -ui-bind-addr=localhost:8025 -api-bind-addr=localhost:8025 -smtp-bind-addr=localhost:1025 | grep -v KEEPALIVE
smtp: ./bin/tools/mailpit -s localhost:1025 -l localhost:8025
prom: bin/tools/prometheus --log.level=warn --config.file=devtools/prometheus/prometheus.yml --storage.tsdb.path=bin/prom-data/ --web.listen-address=localhost:9090

@watch-file=./web/src/esbuild.config.js
Expand Down
2 changes: 1 addition & 1 deletion Procfile.prod
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ build: while true; do make -qs bin/goalert BUNDLE=1 || make bin/goalert BUNDLE=1
@watch-file=./bin/goalert
goalert: ./bin/goalert -l=localhost:3030 --db-url=postgres://goalert@localhost --listen-sysapi=localhost:1234 --listen-prometheus=localhost:2112 --listen-pprof=localhost:6060 --pprof-mutex-profile-fraction=1 --pprof-block-profile-rate=1000

smtp: go run github.com/mailhog/MailHog -ui-bind-addr=localhost:8025 -api-bind-addr=localhost:8025 -smtp-bind-addr=localhost:1025 | grep -v KEEPALIVE
smtp: ./bin/tools/mailpit -s localhost:1025 -l localhost:8025
prom: bin/tools/prometheus --log.level=warn --config.file=devtools/prometheus/prometheus.yml --storage.tsdb.path=bin/prom-data/ --web.listen-address=localhost:9090

oidc: ./bin/mockoidc
2 changes: 1 addition & 1 deletion Procfile.swo
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ build: while true; do make -qs bin/goalert || make bin/goalert || (echo '\033[0;
@watch-file=./bin/goalert
goalert: ./bin/goalert -l=localhost:3040 --ui-dir=web/src/build --db-url=postgres://goalert@localhost:5435 --listen-sysapi=localhost:1234 --listen-prometheus=localhost:2112 --db-url-next=postgres://goalert@localhost:5435/goalert2

smtp: go run github.com/mailhog/MailHog -ui-bind-addr=localhost:8025 -api-bind-addr=localhost:8025 -smtp-bind-addr=localhost:1025 | grep -v KEEPALIVE
smtp: ./bin/tools/mailpit -s localhost:1025 -l localhost:8025

prom: bin/tools/prometheus --log.level=warn --config.file=devtools/prometheus/prometheus-swo.yml --storage.tsdb.path=bin/prom-data/ --web.listen-address=localhost:9090

Expand Down
28 changes: 22 additions & 6 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,15 @@ import (
"crypto/tls"
"database/sql"
"fmt"
"log/slog"
"net"
"net/http"

"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgxpool"
"github.com/jackc/pgx/v5/stdlib"
"github.com/pkg/errors"
"github.com/riverqueue/river"
"github.com/target/goalert/alert"
"github.com/target/goalert/alert/alertlog"
"github.com/target/goalert/alert/alertmetrics"
Expand Down Expand Up @@ -52,15 +57,19 @@ import (
"github.com/target/goalert/util/sqlutil"
"google.golang.org/grpc"
"google.golang.org/grpc/health"
"riverqueue.com/riverui"
)

// App represents an instance of the GoAlert application.
type App struct {
cfg Config

Logger *slog.Logger

mgr *lifecycle.Manager

db *sql.DB
pgx *pgxpool.Pool
l net.Listener
events *sqlutil.Listener

Expand Down Expand Up @@ -126,11 +135,19 @@ type App struct {
NoticeStore *notice.Store
AuthLinkStore *authlink.Store
APIKeyStore *apikey.Store
River *river.Client[pgx.Tx]
RiverUI *riverui.Server
RiverWorkers *river.Workers
}

// NewApp constructs a new App and binds the listening socket.
func NewApp(c Config, db *sql.DB) (*App, error) {
func NewApp(c Config, pool *pgxpool.Pool) (*App, error) {
if c.Logger == nil {
return nil, errors.New("Logger is required")
}

var err error
db := stdlib.OpenDBFromPool(pool)
permission.SudoContext(context.Background(), func(ctx context.Context) {
// Should not be possible for the app to ever see `use_next_db` unless misconfigured.
//
Expand Down Expand Up @@ -164,10 +181,10 @@ func NewApp(c Config, db *sql.DB) (*App, error) {
if err != nil {
return nil, errors.Wrapf(err, "listen %s", c.TLSListenAddr)
}
l = newMultiListener(c.Logger, l, l2)
l = newMultiListener(l, l2)
}

c.Logger.AddErrorMapper(func(ctx context.Context, err error) context.Context {
c.LegacyLogger.AddErrorMapper(func(ctx context.Context, err error) context.Context {
if e := sqlutil.MapError(err); e != nil && e.Detail != "" {
ctx = log.WithField(ctx, "SQLErrDetails", e.Detail)
}
Expand All @@ -178,8 +195,10 @@ func NewApp(c Config, db *sql.DB) (*App, error) {
app := &App{
l: l,
db: db,
pgx: pool,
cfg: c,
doneCh: make(chan struct{}),
Logger: c.Logger,
}

if c.StatusAddr != "" {
Expand All @@ -189,9 +208,6 @@ func NewApp(c Config, db *sql.DB) (*App, error) {
}
}

app.db.SetMaxIdleConns(c.DBMaxIdle)
app.db.SetMaxOpenConns(c.DBMaxOpen)

app.mgr = lifecycle.NewManager(app._Run, app._Shutdown)
err = app.mgr.SetStartupFunc(app.startup)
if err != nil {
Expand Down
51 changes: 45 additions & 6 deletions app/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"database/sql"
"fmt"
"io"
"log/slog"
"net/http"
"net/url"
"os"
Expand All @@ -14,8 +15,10 @@ import (
"testing"
"time"

"github.com/jackc/pgx/v5/pgxpool"
"github.com/pelletier/go-toml/v2"
"github.com/pkg/errors"
sloglogrus "github.com/samber/slog-logrus"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/target/goalert/auth/basic"
Expand Down Expand Up @@ -140,27 +143,52 @@ Available Flags:
return err
}

var db *sql.DB
var pool *pgxpool.Pool
if cfg.DBURLNext != "" {
err = migrate.VerifyIsLatest(ctx, cfg.DBURL)
if err != nil {
return errors.Wrap(err, "verify db")
}

err = doMigrations(cfg.DBURLNext)
if err != nil {
return errors.Wrap(err, "nextdb")
}

mgr, err := swo.NewManager(swo.Config{OldDBURL: cfg.DBURL, NewDBURL: cfg.DBURLNext, CanExec: !cfg.APIOnly, Logger: cfg.Logger})
mgr, err := swo.NewManager(swo.Config{
OldDBURL: cfg.DBURL,
NewDBURL: cfg.DBURLNext,
CanExec: !cfg.APIOnly,
Logger: cfg.LegacyLogger,
MaxOpen: cfg.DBMaxOpen,
MaxIdle: cfg.DBMaxIdle,
})
if err != nil {
return errors.Wrap(err, "init switchover handler")
}
db = mgr.DB()
pool = mgr.Pool()
cfg.SWO = mgr
} else {
db, err = sqldrv.NewDB(cfg.DBURL, fmt.Sprintf("GoAlert %s", version.GitVersion()))
appURL, err := sqldrv.AppURL(cfg.DBURL, fmt.Sprintf("GoAlert %s", version.GitVersion()))
if err != nil {
return errors.Wrap(err, "connect to postgres")
}

poolCfg, err := pgxpool.ParseConfig(appURL)
if err != nil {
return errors.Wrap(err, "parse db URL")
}
poolCfg.MaxConns = int32(cfg.DBMaxOpen)
poolCfg.MinConns = int32(cfg.DBMaxIdle)
sqldrv.SetConfigRetries(poolCfg)

pool, err = pgxpool.NewWithConfig(context.Background(), poolCfg)
if err != nil {
return errors.Wrap(err, "connect to postgres")
}
}

app, err := NewApp(cfg, db)
app, err := NewApp(cfg, pool)
if err != nil {
return errors.Wrap(err, "init app")
}
Expand Down Expand Up @@ -613,7 +641,7 @@ Migration: %s (#%d)
// getConfig will load the current configuration from viper
func getConfig(ctx context.Context) (Config, error) {
cfg := Config{
Logger: log.FromContext(ctx),
LegacyLogger: log.FromContext(ctx),

JSON: viper.GetBool("json"),
LogRequests: viper.GetBool("log-requests"),
Expand Down Expand Up @@ -668,6 +696,17 @@ func getConfig(ctx context.Context) (Config, error) {
UIDir: viper.GetString("ui-dir"),
}

opts := sloglogrus.Option{
Level: slog.LevelInfo,
Logger: cfg.LegacyLogger.Logrus(),
}
if viper.GetBool("log-errors-only") {
opts.Level = slog.LevelError
} else if cfg.Verbose {
opts.Level = slog.LevelDebug
}
cfg.Logger = slog.New(opts.NewLogrusHandler())

var fs expflag.FlagSet
strict := viper.GetBool("strict-experimental")
s := viper.GetStringSlice("experimental")
Expand Down
5 changes: 4 additions & 1 deletion app/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package app

import (
"crypto/tls"
"log/slog"
"time"

"github.com/target/goalert/config"
Expand All @@ -12,7 +13,9 @@ import (
)

type Config struct {
Logger *log.Logger
LegacyLogger *log.Logger

Logger *slog.Logger

ExpFlags expflag.FlagSet

Expand Down
2 changes: 1 addition & 1 deletion app/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import (
// the correct configuration is used.
func (app *App) Context(ctx context.Context) context.Context {
ctx = expflag.Context(ctx, app.cfg.ExpFlags)
ctx = log.WithLogger(ctx, app.cfg.Logger)
ctx = log.WithLogger(ctx, app.cfg.LegacyLogger)

if app.ConfigStore != nil {
ctx = app.ConfigStore.Config().Context(ctx)
Expand Down
2 changes: 2 additions & 0 deletions app/initengine.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ func (app *App) initEngine(ctx context.Context) error {

DisableCycle: app.cfg.APIOnly,
LogCycles: app.cfg.LogEngine,
River: app.River,
RiverWorkers: app.RiverWorkers,
})
if err != nil {
return errors.Wrap(err, "init engine")
Expand Down
Loading

0 comments on commit 6773c9a

Please sign in to comment.