Compare commits
5 Commits
b86ea2737d
...
94ab31c756
Author | SHA1 | Date | |
---|---|---|---|
94ab31c756 | |||
d8df6d577e | |||
085202c174 | |||
8fc7181bec | |||
bb0bf6d39f |
6
.idea/swagger-settings.xml
Normal file
6
.idea/swagger-settings.xml
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="SwaggerSettings">
|
||||
<option name="defaultPreviewType" value="SWAGGER_UI" />
|
||||
</component>
|
||||
</project>
|
4
Makefile
4
Makefile
@ -2,10 +2,12 @@ GO := go
|
||||
|
||||
PKG_BASE := $(shell head -n 1 go.mod | awk '{print $$2}')
|
||||
BUILD_TIME := $(shell date -u '+%Y%m%d-%I%M%S')
|
||||
VERSION := $(shell cat VERSION)+$(shell git rev-parse --short HEAD)
|
||||
VERSION := $(shell cat VERSION)
|
||||
GIT_COMMIT := $(shell git rev-parse HEAD)
|
||||
|
||||
LDFLAGS += -X $(PKG_BASE)/cmd.BuildTime=$(BUILD_TIME)
|
||||
LDFLAGS += -X $(PKG_BASE)/cmd.Version=$(VERSION)
|
||||
LDFLAGS += -X $(PKG_BASE)/cmd.GitCommit=$(GIT_COMMIT)
|
||||
LDFLAGS += -X $(PKG_BASE)/cmd.SentryDSN=$(shell cat dsn.txt)
|
||||
LDFLAGS += -s -w
|
||||
|
||||
|
@ -39,20 +39,26 @@ var App = &cli.App{
|
||||
var (
|
||||
BuildTime string
|
||||
Version string
|
||||
GitCommit string
|
||||
SentryDSN string
|
||||
)
|
||||
|
||||
func init() {
|
||||
if BuildTime == "" {
|
||||
BuildTime = "2022-09-06-01-00-00"
|
||||
// First Commit
|
||||
BuildTime = "20220907-153437"
|
||||
}
|
||||
App.Compiled = getBuildTime()
|
||||
|
||||
if Version == "" {
|
||||
Version = "0.0.0+None"
|
||||
Version = "0.0.0"
|
||||
}
|
||||
App.Version = Version
|
||||
|
||||
if GitCommit == "" {
|
||||
GitCommit = "out-of-tree"
|
||||
}
|
||||
|
||||
if SentryDSN != "" {
|
||||
setupSentry()
|
||||
}
|
||||
@ -73,7 +79,7 @@ func setupSentry() {
|
||||
EnableTracing: true,
|
||||
TracesSampleRate: 1.0,
|
||||
SendDefaultPII: true,
|
||||
Release: Version,
|
||||
Release: GitCommit,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("sentry.Init: %s", err)
|
||||
|
@ -37,10 +37,10 @@ func main() {
|
||||
Action: wrap(appServer.RunServer),
|
||||
},
|
||||
{
|
||||
Name: "init",
|
||||
Aliases: []string{"i"},
|
||||
Usage: "init database",
|
||||
Action: wrap(appServer.RunServerInit),
|
||||
Name: "migrate",
|
||||
Aliases: []string{"m"},
|
||||
Usage: "migrate database",
|
||||
Action: wrap(appServer.RunServerMigrate),
|
||||
},
|
||||
{
|
||||
Name: "runner",
|
||||
@ -94,10 +94,13 @@ func prepareServices(c *cli.Context) *do.Injector {
|
||||
func wrap(f func(i *do.Injector) error) func(*cli.Context) error {
|
||||
return func(c *cli.Context) error {
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
sentry.CaptureException(r.(error))
|
||||
sentry.Flush(time.Second * 2)
|
||||
slog.Printf("Panic Captured: %v", r)
|
||||
if cmd.SentryDSN != "" {
|
||||
// only recover when sentry is enabled
|
||||
if r := recover(); r != nil {
|
||||
sentry.CaptureException(r.(error))
|
||||
sentry.Flush(time.Second * 2)
|
||||
slog.Printf("Panic Captured: %v", r)
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
|
@ -23,7 +23,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func RunServerInit(i *do.Injector) error {
|
||||
func RunServerMigrate(i *do.Injector) error {
|
||||
slog := do.MustInvoke[log.Service](i).GetLogger("app.server")
|
||||
|
||||
// Migrate and shutdown database
|
||||
|
@ -1,6 +1,7 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"git.0x7f.app/WOJ/woj-server/cmd"
|
||||
"git.0x7f.app/WOJ/woj-server/internal/misc/config"
|
||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||
"github.com/TheZeroSlave/zapsentry"
|
||||
@ -48,7 +49,9 @@ func NewService(i *do.Injector) (Service, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
srv.logger = attachSentry(srv.logger)
|
||||
if cmd.SentryDSN != "" {
|
||||
srv.logger = attachSentry(srv.logger)
|
||||
}
|
||||
|
||||
return srv, nil
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ import (
|
||||
"git.0x7f.app/WOJ/woj-server/internal/misc/config"
|
||||
"git.0x7f.app/WOJ/woj-server/internal/misc/log"
|
||||
"git.0x7f.app/WOJ/woj-server/internal/model"
|
||||
"git.0x7f.app/WOJ/woj-server/pkg/utils"
|
||||
"github.com/samber/do"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/driver/postgres"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/schema"
|
||||
"hash/fnv"
|
||||
"moul.io/zapgorm2"
|
||||
"time"
|
||||
)
|
||||
@ -108,11 +110,34 @@ func (s *service) setup(conf *model.Config) {
|
||||
func (s *service) migrateDatabase() {
|
||||
s.log.Info("Auto Migrating database...")
|
||||
|
||||
// Running AutoMigrate concurrently on the same model fails with various race conditions
|
||||
// https://github.com/go-gorm/gorm/pull/6680
|
||||
// https://github.com/go-gorm/postgres/pull/224
|
||||
|
||||
// Obtain a lock to prevent concurrent AutoMigrate
|
||||
|
||||
lockID := func(s string) int64 {
|
||||
h := fnv.New64a()
|
||||
_, err := h.Write([]byte(s))
|
||||
return utils.If(err != nil, int64(0x4242AA55), int64(h.Sum64()))
|
||||
}("gorm:migrator")
|
||||
|
||||
s.err = s.db.Exec("SELECT pg_advisory_lock(?)", lockID).Error
|
||||
if s.err != nil {
|
||||
s.log.Error("Failed to obtain lock", zap.Error(s.err))
|
||||
return
|
||||
}
|
||||
|
||||
_ = s.db.AutoMigrate(&model.User{})
|
||||
_ = s.db.AutoMigrate(&model.Problem{})
|
||||
_ = s.db.AutoMigrate(&model.ProblemVersion{})
|
||||
_ = s.db.AutoMigrate(&model.Submission{})
|
||||
_ = s.db.AutoMigrate(&model.Status{})
|
||||
|
||||
s.err = s.db.Exec("SELECT pg_advisory_unlock(?)", lockID).Error
|
||||
if s.err != nil {
|
||||
s.log.Error("Failed to release lock", zap.Error(s.err))
|
||||
}
|
||||
}
|
||||
|
||||
func (s *service) checkAlive(retry int) (*sql.DB, error) {
|
||||
|
@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func (s *service) EnsureDeps(force bool) e.Status {
|
||||
mark := filepath.Join(Prefix, ".mark.container")
|
||||
mark := filepath.Join(Prefix, ".mark.image")
|
||||
|
||||
if force {
|
||||
_ = os.Remove(mark)
|
||||
|
@ -79,7 +79,7 @@ func (s *service) initRouters(conf *model.Config, injector *do.Injector) *gin.En
|
||||
r.Use(cors.New(cors.Config{
|
||||
AllowAllOrigins: true,
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "OPTIONS"},
|
||||
AllowHeaders: []string{"Origin", "Content-Length", "Content-Type"},
|
||||
AllowHeaders: []string{"Authorization", "Origin", "Content-Length", "Content-Type"},
|
||||
AllowCredentials: true,
|
||||
}))
|
||||
|
||||
|
@ -1,16 +1,5 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: woj
|
||||
name: cache-config
|
||||
labels:
|
||||
app: cache
|
||||
data:
|
||||
redis.conf: |
|
||||
requirepass YeT_An0tHeR_VeRy-S3cUr3^PaSsWoRd
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
namespace: woj
|
||||
@ -45,22 +34,23 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: cache
|
||||
image: docker.io/library/redis:7-alpine
|
||||
image: docker.io/bitnami/redis:7.2
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
env:
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: REDIS_PASSWORD
|
||||
volumeMounts:
|
||||
- name: cache-vol
|
||||
mountPath: /data
|
||||
- name: cache-config
|
||||
mountPath: /etc/redis/
|
||||
volumes:
|
||||
- name: cache-vol
|
||||
persistentVolumeClaim:
|
||||
claimName: cache-pvc
|
||||
- name: cache-config
|
||||
configMap:
|
||||
name: cache-config
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
12
resource/deploy/config.yaml
Normal file
12
resource/deploy/config.yaml
Normal file
@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: woj
|
||||
name: shared-config
|
||||
data:
|
||||
POSTGRES_USER: "woj"
|
||||
POSTGRES_PASSWORD: "A_VeRy-S3cUr3^PaSsWoRd"
|
||||
POSTGRES_DB: "woj"
|
||||
MINIO_ROOT_USER: "A_VeRy_CoMpLeX_AcCeSs_KeY"
|
||||
MINIO_ROOT_PASSWORD: "A_VeRy_CoMpLeX_ScReT_KeY"
|
||||
REDIS_PASSWORD: "YeT_An0tHeR_VeRy-S3cUr3^PaSsWoRd"
|
@ -1,17 +1,5 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: woj
|
||||
name: db-config
|
||||
labels:
|
||||
app: db
|
||||
data:
|
||||
POSTGRES_USER: "woj"
|
||||
POSTGRES_PASSWORD: "A_VeRy-S3cUr3^PaSsWoRd"
|
||||
POSTGRES_DB: "woj"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
namespace: woj
|
||||
@ -50,9 +38,22 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 5432
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: db-config
|
||||
env:
|
||||
- name: POSTGRES_USER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_USER
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_PASSWORD
|
||||
- name: POSTGRES_DB
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_DB
|
||||
volumeMounts:
|
||||
- name: db-vol
|
||||
mountPath: /var/lib/postgresql/data
|
||||
|
@ -1,26 +1,5 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: woj
|
||||
name: runner-config
|
||||
labels:
|
||||
app: runner
|
||||
data:
|
||||
DATABASE_HOST: "db-service.woj.svc.cluster.local"
|
||||
DATABASE_USER: "woj"
|
||||
DATABASE_PASSWORD: "A_VeRy-S3cUr3^PaSsWoRd"
|
||||
DATABASE_NAME: "woj"
|
||||
|
||||
REDIS_ADDRESS: "cache-service.woj.svc.cluster.local"
|
||||
REDIS_PASSWORD: "YeT_An0tHeR_VeRy-S3cUr3^PaSsWoRd"
|
||||
|
||||
STORAGE_ENDPOINT: "storage-service.woj.svc.cluster.local:9000"
|
||||
STORAGE_ACCESS_KEY: "A_VeRy_CoMpLeX_AcCeSs_KeY"
|
||||
STORAGE_SECRET_KEY: "A_VeRy_CoMpLeX_ScReT_KeY"
|
||||
STORAGE_BUCKET: "woj"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
namespace: woj
|
||||
@ -60,9 +39,28 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- runner
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: runner-config
|
||||
env:
|
||||
- name: REDIS_ADDRESS
|
||||
value: "cache-service.woj.svc.cluster.local"
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: REDIS_PASSWORD
|
||||
- name: STORAGE_ENDPOINT
|
||||
value: "storage-service.woj.svc.cluster.local:9000"
|
||||
- name: STORAGE_ACCESS_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: MINIO_ROOT_USER
|
||||
- name: STORAGE_SECRET_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: MINIO_ROOT_PASSWORD
|
||||
- name: STORAGE_BUCKET
|
||||
value: "woj"
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
|
@ -1,25 +1,4 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: woj
|
||||
name: server-config
|
||||
labels:
|
||||
app: server
|
||||
data:
|
||||
DATABASE_HOST: "db-service.woj.svc.cluster.local"
|
||||
DATABASE_USER: "woj"
|
||||
DATABASE_PASSWORD: "A_VeRy-S3cUr3^PaSsWoRd"
|
||||
DATABASE_NAME: "woj"
|
||||
|
||||
REDIS_ADDRESS: "cache-service.woj.svc.cluster.local"
|
||||
REDIS_PASSWORD: "YeT_An0tHeR_VeRy-S3cUr3^PaSsWoRd"
|
||||
|
||||
STORAGE_ENDPOINT: "storage-service.woj.svc.cluster.local:9000"
|
||||
STORAGE_ACCESS_KEY: "A_VeRy_CoMpLeX_AcCeSs_KeY"
|
||||
STORAGE_SECRET_KEY: "A_VeRy_CoMpLeX_ScReT_KeY"
|
||||
STORAGE_BUCKET: "woj"
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@ -45,18 +24,69 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- init
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: server-config
|
||||
env:
|
||||
- name: DATABASE_HOST
|
||||
value: "db-service.woj.svc.cluster.local"
|
||||
- name: DATABASE_USER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_USER
|
||||
- name: DATABASE_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_PASSWORD
|
||||
- name: DATABASE_NAME
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_DB
|
||||
containers:
|
||||
- name: server
|
||||
image: git.0x7f.app/woj/woj-server:1.1.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
args:
|
||||
- server
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: server-config
|
||||
env:
|
||||
- name: DATABASE_HOST
|
||||
value: "db-service.woj.svc.cluster.local"
|
||||
- name: DATABASE_USER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_USER
|
||||
- name: DATABASE_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_PASSWORD
|
||||
- name: DATABASE_NAME
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: POSTGRES_DB
|
||||
- name: REDIS_ADDRESS
|
||||
value: "cache-service.woj.svc.cluster.local"
|
||||
- name: REDIS_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: REDIS_PASSWORD
|
||||
- name: STORAGE_ENDPOINT
|
||||
value: "storage-service.woj.svc.cluster.local:9000"
|
||||
- name: STORAGE_ACCESS_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: MINIO_ROOT_USER
|
||||
- name: STORAGE_SECRET_KEY
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: MINIO_ROOT_PASSWORD
|
||||
- name: STORAGE_BUCKET
|
||||
value: "woj"
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
---
|
||||
|
@ -1,17 +1,5 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
namespace: woj
|
||||
name: storage-config
|
||||
labels:
|
||||
app: storage
|
||||
data:
|
||||
MINIO_ROOT_USER: "A_VeRy_CoMpLeX_AcCeSs_KeY"
|
||||
MINIO_ROOT_PASSWORD: "A_VeRy_CoMpLeX_ScReT_KeY"
|
||||
MINIO_VOLUMES: "/data"
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
namespace: woj
|
||||
@ -56,9 +44,17 @@ spec:
|
||||
ports:
|
||||
- containerPort: 9000
|
||||
- containerPort: 9001
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: storage-config
|
||||
env:
|
||||
- name: MINIO_ROOT_USER
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: MINIO_ROOT_USER
|
||||
- name: MINIO_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: shared-config
|
||||
key: MINIO_ROOT_PASSWORD
|
||||
volumeMounts:
|
||||
- name: storage-vol
|
||||
mountPath: /data
|
||||
|
Loading…
Reference in New Issue
Block a user