mirror of
https://github.com/juanfont/headscale.git
synced 2026-08-07 07:48:44 +09:00
cmd/headscale: wait for the local socket while the server starts
A CLI command issued right after startup can beat headscale to binding its unix socket. Retry the dial until the CLI timeout, matching the old blocking gRPC dial, instead of failing on a missing socket file.
This commit is contained in:
@@ -84,7 +84,7 @@ func localSocketClient(socketPath string) (*apiv1.Client, error) {
|
||||
httpClient := &http.Client{
|
||||
Transport: &http.Transport{
|
||||
DialContext: func(ctx context.Context, _, _ string) (net.Conn, error) {
|
||||
return (&net.Dialer{}).DialContext(ctx, "unix", socketPath)
|
||||
return dialSocketWaiting(ctx, socketPath)
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -93,6 +93,31 @@ func localSocketClient(socketPath string) (*apiv1.Client, error) {
|
||||
return apiv1.NewClient("http://unix", cliToken("local-socket"), apiv1.WithClient(httpClient))
|
||||
}
|
||||
|
||||
// dialSocketWaiting connects to the local unix socket, retrying while it is
|
||||
// still absent. headscale removes and rebinds the socket during startup, so a
|
||||
// CLI command issued right after "systemctl start" can beat the server to it.
|
||||
// This mirrors the old blocking gRPC dial, which retried until the CLI timeout.
|
||||
func dialSocketWaiting(ctx context.Context, socketPath string) (net.Conn, error) {
|
||||
var dialer net.Dialer
|
||||
|
||||
for {
|
||||
conn, err := dialer.DialContext(ctx, "unix", socketPath)
|
||||
if err == nil {
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
if ctx.Err() != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return nil, err
|
||||
case <-time.After(100 * time.Millisecond):
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func remoteClient(address, apiKey string, insecure bool) (*apiv1.Client, error) {
|
||||
if apiKey == "" {
|
||||
return nil, errAPIKeyNotSet
|
||||
|
||||
Reference in New Issue
Block a user