fix(federation): add configurable ports, password support, fix log leak
- Add --federation-port and --remotesapi-port flags (default 3306/8080) - Fix log file leak in server.go - track and close on Stop() - Add BEADS_DOLT_PASSWORD env var for server mode authentication - Update DSN to include password when set Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
committed by
Steve Yegge
parent
83e3c75635
commit
ea51c4b0bd
@@ -48,6 +48,7 @@ type Server struct {
|
||||
mu sync.Mutex
|
||||
running bool
|
||||
pidFile string
|
||||
logFile *os.File // Track log file for cleanup
|
||||
}
|
||||
|
||||
// NewServer creates a new dolt sql-server manager
|
||||
@@ -116,6 +117,7 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open log file: %w", err)
|
||||
}
|
||||
s.logFile = logFile // Track for cleanup on Stop()
|
||||
s.cmd.Stdout = logFile
|
||||
s.cmd.Stderr = logFile
|
||||
} else {
|
||||
@@ -140,6 +142,10 @@ func (s *Server) Start(ctx context.Context) error {
|
||||
// Server failed to start, clean up
|
||||
_ = s.cmd.Process.Kill()
|
||||
_ = os.Remove(s.pidFile)
|
||||
if s.logFile != nil {
|
||||
_ = s.logFile.Close()
|
||||
s.logFile = nil
|
||||
}
|
||||
return fmt.Errorf("server failed to become ready: %w", err)
|
||||
}
|
||||
|
||||
@@ -180,8 +186,12 @@ func (s *Server) Stop() error {
|
||||
<-done // Wait for process to be reaped
|
||||
}
|
||||
|
||||
// Clean up PID file
|
||||
// Clean up PID file and log file
|
||||
_ = os.Remove(s.pidFile)
|
||||
if s.logFile != nil {
|
||||
_ = s.logFile.Close()
|
||||
s.logFile = nil
|
||||
}
|
||||
s.running = false
|
||||
s.cmd = nil
|
||||
|
||||
|
||||
@@ -60,10 +60,11 @@ type Config struct {
|
||||
ReadOnly bool // Open in read-only mode (skip schema init)
|
||||
|
||||
// Server mode options (federation)
|
||||
ServerMode bool // Connect to dolt sql-server instead of embedded
|
||||
ServerHost string // Server host (default: 127.0.0.1)
|
||||
ServerPort int // Server port (default: 3306)
|
||||
ServerUser string // MySQL user (default: root)
|
||||
ServerMode bool // Connect to dolt sql-server instead of embedded
|
||||
ServerHost string // Server host (default: 127.0.0.1)
|
||||
ServerPort int // Server port (default: 3306)
|
||||
ServerUser string // MySQL user (default: root)
|
||||
ServerPassword string // MySQL password (default: empty, can be set via BEADS_DOLT_PASSWORD)
|
||||
}
|
||||
|
||||
// New creates a new Dolt storage backend
|
||||
@@ -103,6 +104,10 @@ func New(ctx context.Context, cfg *Config) (*DoltStore, error) {
|
||||
if cfg.ServerUser == "" {
|
||||
cfg.ServerUser = "root"
|
||||
}
|
||||
// Check environment variable for password (more secure than command-line)
|
||||
if cfg.ServerPassword == "" {
|
||||
cfg.ServerPassword = os.Getenv("BEADS_DOLT_PASSWORD")
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure directory exists
|
||||
@@ -199,10 +204,16 @@ func openEmbeddedConnection(ctx context.Context, cfg *Config) (*sql.DB, string,
|
||||
|
||||
// openServerConnection opens a connection to a dolt sql-server via MySQL protocol
|
||||
func openServerConnection(ctx context.Context, cfg *Config) (*sql.DB, string, error) {
|
||||
// DSN format: user@tcp(host:port)/database?parseTime=true
|
||||
// DSN format: user:password@tcp(host:port)/database?parseTime=true
|
||||
// parseTime=true tells the MySQL driver to parse DATETIME/TIMESTAMP to time.Time
|
||||
connStr := fmt.Sprintf("%s@tcp(%s:%d)/%s?parseTime=true",
|
||||
cfg.ServerUser, cfg.ServerHost, cfg.ServerPort, cfg.Database)
|
||||
var connStr string
|
||||
if cfg.ServerPassword != "" {
|
||||
connStr = fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?parseTime=true",
|
||||
cfg.ServerUser, cfg.ServerPassword, cfg.ServerHost, cfg.ServerPort, cfg.Database)
|
||||
} else {
|
||||
connStr = fmt.Sprintf("%s@tcp(%s:%d)/%s?parseTime=true",
|
||||
cfg.ServerUser, cfg.ServerHost, cfg.ServerPort, cfg.Database)
|
||||
}
|
||||
|
||||
db, err := sql.Open("mysql", connStr)
|
||||
if err != nil {
|
||||
@@ -216,8 +227,14 @@ func openServerConnection(ctx context.Context, cfg *Config) (*sql.DB, string, er
|
||||
|
||||
// Ensure database exists (may need to create it)
|
||||
// First connect without database to create it
|
||||
initConnStr := fmt.Sprintf("%s@tcp(%s:%d)/?parseTime=true",
|
||||
cfg.ServerUser, cfg.ServerHost, cfg.ServerPort)
|
||||
var initConnStr string
|
||||
if cfg.ServerPassword != "" {
|
||||
initConnStr = fmt.Sprintf("%s:%s@tcp(%s:%d)/?parseTime=true",
|
||||
cfg.ServerUser, cfg.ServerPassword, cfg.ServerHost, cfg.ServerPort)
|
||||
} else {
|
||||
initConnStr = fmt.Sprintf("%s@tcp(%s:%d)/?parseTime=true",
|
||||
cfg.ServerUser, cfg.ServerHost, cfg.ServerPort)
|
||||
}
|
||||
initDB, err := sql.Open("mysql", initConnStr)
|
||||
if err != nil {
|
||||
_ = db.Close()
|
||||
|
||||
Reference in New Issue
Block a user