Replace Air's kill-and-rerun loop in the debug image with the pilot persistent-delve supervisor: src/dev/dlv-watch.sh owns one headless `dlv exec --multiclient --continue` server, rebuilds ./tmp/main on save and restarts only the debug target through the tiny rpc2 client in src/dev/dlv-restart. An attached VS Code session (and its breakpoints) now survives saves instead of reconnecting after every reload. The debug compose builds locally with `pull_policy: build` and without `build.network: host`: compose cannot grant the network.host entitlement, so a cold `up` previously failed with "additional privileges requested"; the default bridge reaches the dev Gitea for module resolution.
63 lines
2.3 KiB
Go
63 lines
2.3 KiB
Go
// Copyright (C) 2026 Dcntrlized
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU Affero General Public License as published
|
|
// by the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU Affero General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Affero General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
// dlv-restart is a minimal JSON-RPC client (delve service/rpc2) that restarts
|
|
// the debug target of a persistent headless dlv server and resumes it.
|
|
//
|
|
// Why not `printf 'restart\n' | dlv connect ...`? `dlv connect` is an
|
|
// interactive terminal client: its stdout/stderr is distinct from the debug
|
|
// target's, it always reads go-ahead from the same stream, and its stdin EOF
|
|
// makes it drop into the (dlv) prompt and exit with a "kill the headless
|
|
// instance?" prompt — dumping the debugee's full state and racing the attached
|
|
// vscode-go client. This helper speaks rpc2 directly, so it only issues the
|
|
// RPCs we want, prints nothing, and exits without disturbing the target or the
|
|
// VS Code session.
|
|
//
|
|
// Usage: dlv-restart [addr] (addr defaults to 127.0.0.1:2345)
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
|
|
"github.com/go-delve/delve/service/rpc2"
|
|
)
|
|
|
|
func main() {
|
|
addr := "127.0.0.1:2345"
|
|
if len(os.Args) > 1 {
|
|
addr = os.Args[1]
|
|
}
|
|
|
|
client := rpc2.NewClient(addr)
|
|
|
|
discarded, err := client.RestartFrom(false, "", false, nil, [3]string{}, false)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "dlv-restart: Restart failed: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
for _, d := range discarded {
|
|
fmt.Fprintf(os.Stderr, "discarded %s: %v\n", d.Breakpoint.Name, d.Reason)
|
|
}
|
|
|
|
// The restarted process begins halted, so resume it with Continue, then
|
|
// close the connection. --accept-multiclient keeps the server and target
|
|
// running while our short-lived client disconnects; an attached vscode-go
|
|
// client is undisturbed.
|
|
if err := client.Disconnect(true); err != nil {
|
|
fmt.Fprintf(os.Stderr, "dlv-restart: disconnect failed: %v\n", err)
|
|
}
|
|
}
|