feat: implement database and storage abstractions
- Added `internal/db/store.go` to define the Store interface for database operations, including user, organization, app, channel, release, patch, and artifact management. - Introduced `internal/models/models.go` changes to reflect updated organization and artifact response structures. - Created `internal/storage/factory.go`, `local.go`, and `s3.go` to implement storage backends for local filesystem and S3-compatible services. - Removed deprecated `internal/storage/storage.go` and refactored storage interface into `internal/storage/store.go`. - Updated frontend JavaScript in `web/js/app.js` to display server health information, including storage and database backend details.
This commit is contained in:
+37
-30
@@ -18,40 +18,48 @@ import (
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Load configuration
|
||||
cfg := config.Load()
|
||||
|
||||
// Initialize database
|
||||
ctx := context.Background()
|
||||
database, err := db.New(ctx, cfg.Database.URL)
|
||||
|
||||
// --- Database ---
|
||||
var dsn string
|
||||
switch cfg.DB.Driver {
|
||||
case "postgres", "postgresql", "pg":
|
||||
dsn = cfg.DB.URL
|
||||
default:
|
||||
dsn = cfg.DB.Path
|
||||
}
|
||||
database, err := db.NewStore(ctx, cfg.DB.Driver, dsn)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to database: %v", err)
|
||||
log.Fatalf("Failed to open database: %v", err)
|
||||
}
|
||||
defer database.Close()
|
||||
log.Println("Connected to PostgreSQL")
|
||||
log.Printf("Database: %s (%s)", cfg.DB.Driver, cfg.DB.Path)
|
||||
|
||||
// Initialize auth service
|
||||
// --- Auth ---
|
||||
authService := auth.NewService(cfg.Auth.JWTSecret, cfg.Auth.TokenDuration)
|
||||
log.Println("Auth service initialized")
|
||||
|
||||
// Initialize storage service
|
||||
store, err := storage.NewService(
|
||||
cfg.Storage.Endpoint,
|
||||
cfg.Storage.AccessKeyID,
|
||||
cfg.Storage.SecretAccessKey,
|
||||
cfg.Storage.ReleaseBucket,
|
||||
cfg.Storage.PatchBucket,
|
||||
cfg.Storage.UseSSL,
|
||||
)
|
||||
// --- Storage ---
|
||||
store, err := storage.NewStore(storage.Config{
|
||||
Type: cfg.Storage.Driver,
|
||||
LocalDir: cfg.Storage.LocalDir,
|
||||
ServerBaseURL: cfg.Server.BaseURL,
|
||||
S3Endpoint: cfg.Storage.S3Endpoint,
|
||||
S3AccessKey: cfg.Storage.S3AccessKey,
|
||||
S3SecretKey: cfg.Storage.S3SecretKey,
|
||||
S3UseSSL: cfg.Storage.S3UseSSL,
|
||||
S3ReleaseBucket: cfg.Storage.S3ReleaseBucket,
|
||||
S3PatchBucket: cfg.Storage.S3PatchBucket,
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to initialize storage: %v", err)
|
||||
}
|
||||
log.Println("Storage service initialized")
|
||||
log.Printf("Storage: %s", store.BackendName())
|
||||
|
||||
// Create router
|
||||
// --- Router ---
|
||||
router := handlers.NewRouter(authService, database, store)
|
||||
|
||||
// Configure HTTP server
|
||||
// --- HTTP Server ---
|
||||
addr := fmt.Sprintf("%s:%s", cfg.Server.Host, cfg.Server.Port)
|
||||
srv := &http.Server{
|
||||
Addr: addr,
|
||||
@@ -61,29 +69,28 @@ func main() {
|
||||
IdleTimeout: 60 * time.Second,
|
||||
}
|
||||
|
||||
// Start server in goroutine
|
||||
go func() {
|
||||
log.Printf("Shorebird self-hosted server starting on %s", addr)
|
||||
log.Printf("API: http://%s/api/v1", addr)
|
||||
log.Printf("Auth: http://%s/auth", addr)
|
||||
log.Printf("Health: http://%s/health", addr)
|
||||
log.Printf("Shorebird server starting on %s", addr)
|
||||
log.Printf(" Dashboard: http://%s", addr)
|
||||
log.Printf(" API: http://%s/api/v1", addr)
|
||||
log.Printf(" Auth: http://%s/auth", addr)
|
||||
log.Printf(" Storage: %s", store.BackendName())
|
||||
log.Printf(" Database: %s", cfg.DB.Driver)
|
||||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Fatalf("Server failed: %v", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for interrupt signal
|
||||
// Graceful shutdown
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
|
||||
log.Println("Shutting down server...")
|
||||
log.Println("Shutting down...")
|
||||
shutdownCtx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||
log.Fatalf("Server forced to shutdown: %v", err)
|
||||
log.Fatalf("Shutdown error: %v", err)
|
||||
}
|
||||
|
||||
log.Println("Server stopped")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user