Ensure daemon autostart lock dir exists (#1037)
Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
@@ -215,6 +215,11 @@ func isDaemonHealthy(socketPath string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func acquireStartLock(lockPath, socketPath string) bool {
|
func acquireStartLock(lockPath, socketPath string) bool {
|
||||||
|
if err := ensureLockDirectory(lockPath); err != nil {
|
||||||
|
debugLog("failed to ensure lock directory: %v", err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// nolint:gosec // G304: lockPath is derived from secure beads directory
|
// nolint:gosec // G304: lockPath is derived from secure beads directory
|
||||||
lockFile, err := os.OpenFile(lockPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600)
|
lockFile, err := os.OpenFile(lockPath, os.O_CREATE|os.O_EXCL|os.O_WRONLY, 0600)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -309,6 +314,21 @@ func determineSocketPath(socketPath string) string {
|
|||||||
return socketPath
|
return socketPath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ensureLockDirectory ensures the parent directory exists for the lock file.
|
||||||
|
// Needed when ShortSocketPath routes sockets into /tmp/beads-*/bd.sock.
|
||||||
|
func ensureLockDirectory(lockPath string) error {
|
||||||
|
dir := filepath.Dir(lockPath)
|
||||||
|
if dir == "" {
|
||||||
|
return fmt.Errorf("lock directory missing for %s", lockPath)
|
||||||
|
}
|
||||||
|
if _, err := os.Stat(dir); err == nil {
|
||||||
|
return nil
|
||||||
|
} else if !os.IsNotExist(err) {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return os.MkdirAll(dir, 0o700)
|
||||||
|
}
|
||||||
|
|
||||||
func startDaemonProcess(socketPath string) bool {
|
func startDaemonProcess(socketPath string) bool {
|
||||||
// Early check: daemon requires a git repository (unless --local mode)
|
// Early check: daemon requires a git repository (unless --local mode)
|
||||||
// Skip attempting to start and avoid the 5-second wait if not in git repo
|
// Skip attempting to start and avoid the 5-second wait if not in git repo
|
||||||
|
|||||||
@@ -127,6 +127,24 @@ func TestDaemonAutostart_AcquireStartLock_CreatesAndCleansStale(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDaemonAutostart_AcquireStartLock_CreatesMissingDir(t *testing.T) {
|
||||||
|
tmpDir := t.TempDir()
|
||||||
|
socketPath := filepath.Join(tmpDir, "missing", "bd.sock")
|
||||||
|
lockPath := socketPath + ".startlock"
|
||||||
|
|
||||||
|
if _, err := os.Stat(filepath.Dir(lockPath)); !os.IsNotExist(err) {
|
||||||
|
t.Fatalf("expected lock dir to be missing before test, got: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !acquireStartLock(lockPath, socketPath) {
|
||||||
|
t.Fatalf("expected acquireStartLock to succeed when directory missing")
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(lockPath); err != nil {
|
||||||
|
t.Fatalf("expected lock file to exist, stat error: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDaemonAutostart_SocketHealthAndReadiness(t *testing.T) {
|
func TestDaemonAutostart_SocketHealthAndReadiness(t *testing.T) {
|
||||||
socketPath, cleanup := startTestRPCServer(t)
|
socketPath, cleanup := startTestRPCServer(t)
|
||||||
defer cleanup()
|
defer cleanup()
|
||||||
|
|||||||
Reference in New Issue
Block a user