Files
podman/pkg/machine/sockets/sockets.go
Matt Heon 34166fc004 Bump Go version to v6
Tremendous amount of changes in here, but all should amount to
the same thing: changing Go import paths from v5 to v6.

Also bumped go.mod to github.com/containers/podman/v6 and updated
version to v6.0.0-dev.

Signed-off-by: Matt Heon <mheon@redhat.com>
2025-10-23 11:00:15 -04:00

112 lines
2.8 KiB
Go

package sockets
import (
"bufio"
"bytes"
"fmt"
"net"
"net/url"
"path/filepath"
"time"
"github.com/containers/podman/v6/pkg/machine/define"
"github.com/sirupsen/logrus"
"go.podman.io/storage/pkg/fileutils"
)
// ListenAndWaitOnSocket waits for a new connection to the listener and sends
// any error back through the channel. ListenAndWaitOnSocket is intended to be
// used as a goroutine
func ListenAndWaitOnSocket(errChan chan<- error, listener net.Listener) {
conn, err := listener.Accept()
if err != nil {
logrus.Debug("failed to connect to ready socket")
errChan <- err
return
}
_, err = bufio.NewReader(conn).ReadString('\n')
logrus.Debug("ready ack received")
if closeErr := conn.Close(); closeErr != nil {
errChan <- closeErr
return
}
errChan <- err
}
// DialSocketWithBackoffs attempts to connect to the socket in maxBackoffs attempts
func DialSocketWithBackoffs(maxBackoffs int, backoff time.Duration, socketPath string) (conn net.Conn, err error) {
for i := range maxBackoffs {
if i > 0 {
time.Sleep(backoff)
backoff *= 2
}
conn, err = net.Dial("unix", socketPath)
if err == nil {
return conn, nil
}
}
return nil, err
}
// DialSocketWithBackoffsAndProcCheck attempts to connect to the socket in
// maxBackoffs attempts. After every failure to connect, it makes sure the
// specified process is alive
func DialSocketWithBackoffsAndProcCheck(
maxBackoffs int,
backoff time.Duration,
socketPath string,
checkProccessStatus func(string, int, *bytes.Buffer) error,
procHint string,
procPid int,
errBuf *bytes.Buffer,
) (conn net.Conn, err error) {
for i := range maxBackoffs {
if i > 0 {
time.Sleep(backoff)
backoff *= 2
}
conn, err = net.Dial("unix", socketPath)
if err == nil {
return conn, nil
}
// check to make sure process denoted by procHint is alive
err = checkProccessStatus(procHint, procPid, errBuf)
if err != nil {
return nil, err
}
}
return nil, err
}
// WaitForSocketWithBackoffs attempts to discover listening socket in maxBackoffs attempts
func WaitForSocketWithBackoffs(maxBackoffs int, backoff time.Duration, socketPath string, name string) error {
backoffWait := backoff
logrus.Debugf("checking that %q socket is ready", name)
for range maxBackoffs {
err := fileutils.Exists(socketPath)
if err == nil {
return nil
}
time.Sleep(backoffWait)
backoffWait *= 2
}
return fmt.Errorf("unable to connect to %q socket at %q", name, socketPath)
}
// ToUnixURL converts `socketLoc` into URL representation
func ToUnixURL(socketLoc *define.VMFile) (*url.URL, error) {
p := socketLoc.GetPath()
if !filepath.IsAbs(p) {
return nil, fmt.Errorf("socket path must be absolute %q", p)
}
s, err := url.Parse("unix:///")
if err != nil {
return nil, err
}
s = s.JoinPath(filepath.ToSlash(p))
return s, nil
}