mirror of
https://github.com/cirruslabs/orchard.git
synced 2026-09-29 19:41:15 +02:00
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package socketalias
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
)
|
|
|
|
// baseDirectory is the parent directory for transient socket aliases.
|
|
//
|
|
// To keep the Unix socket path short enough and fit the platform limit,
|
|
// we're specifically requesting "/var/tmp" instead of "/var/folders/.../T/".
|
|
const baseDirectory = "/var/tmp"
|
|
|
|
// Create creates a short Unix socket alias in runtimeDir that points to socketPath.
|
|
//
|
|
// The alias remains valid until runtimeDir is removed.
|
|
func Create(runtimeDir string, socketPath string) (string, error) {
|
|
// Make the symlink target absolute because a relative TART_HOME would
|
|
// otherwise be resolved from runtimeDir, breaking the symlink
|
|
absoluteSocketPath, err := filepath.Abs(socketPath)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
// Place the VM's control socket alias in the runtime directory
|
|
aliasSocketPath := filepath.Join(runtimeDir, "vm.sock")
|
|
if err := os.Symlink(absoluteSocketPath, aliasSocketPath); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return aliasSocketPath, nil
|
|
}
|
|
|
|
// DialContext connects to socketPath through a short transient alias.
|
|
func DialContext(ctx context.Context, socketPath string) (net.Conn, error) {
|
|
// Create a directory where the transient Unix socket alias will live
|
|
runtimeDir, err := os.MkdirTemp(baseDirectory, "orchard-socket-")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Route the socket through the short runtime directory
|
|
aliasSocketPath, err := Create(runtimeDir, socketPath)
|
|
if err != nil {
|
|
return nil, errors.Join(err, os.RemoveAll(runtimeDir))
|
|
}
|
|
|
|
// Connect through the short alias
|
|
var dialer net.Dialer
|
|
conn, err := dialer.DialContext(ctx, "unix", aliasSocketPath)
|
|
|
|
// Remove the transient alias after the connection attempt
|
|
cleanupErr := os.RemoveAll(runtimeDir)
|
|
if err != nil {
|
|
return nil, errors.Join(err, cleanupErr)
|
|
}
|
|
|
|
// Avoid returning a live connection when its alias cannot be removed
|
|
if cleanupErr != nil {
|
|
return nil, errors.Join(cleanupErr, conn.Close())
|
|
}
|
|
|
|
return conn, nil
|
|
}
|