Documentation
¶
Overview ¶
Package portforwarddaemon implements the detached daemon backing `rune port-forward -d`, plus the CLI-side RPC client and subcommands for `list` / `stop` / `logs`. See RUNE-123.
Index ¶
- Constants
- Variables
- func DialDaemon(socketPath string) (net.Conn, error)
- func EnsureRunning(stateDir string, daemonArgs []string) (string, error)
- func ForwardPath(dir, id string) string
- func IsAlive(stateDir string) bool
- func LogPath(dir string) string
- func PidPath(dir string) string
- func ReadJSONLine(r *bufio.Reader, v interface{}) error
- func RemoveForward(dir, id string) error
- func SocketPath(dir string) string
- func StateDir() (string, error)
- func WriteForward(dir string, fwd *Forward) error
- func WriteJSONLine(w io.Writer, v interface{}) error
- type ClientFactory
- type Daemon
- type Forward
- type ForwardStatus
- type PortMapping
- type Request
- type Response
- type TargetKind
Constants ¶
const ( CmdPing = "ping" CmdAdd = "add" CmdList = "list" CmdStop = "stop" CmdStopAll = "stop_all" CmdLogs = "logs" )
Request types accepted by the daemon over its unix socket.
Variables ¶
var IdleShutdownAfter = 60 * time.Second
IdleShutdownAfter is how long the daemon waits with zero forwards before exiting. Tunable for tests.
Functions ¶
func DialDaemon ¶
DialDaemon opens a connection to the daemon socket. Returns a net.Conn the caller must Close.
func EnsureRunning ¶
EnsureRunning returns the path to the daemon socket, spawning the daemon if it isn't already running. If the daemon is up, this is a fast no-op (one ping round-trip).
`daemonArgs` is the argv to pass to the spawned process; the caller supplies the path to the current binary plus the hidden subcommand (e.g. "__port-forward-daemon").
func ForwardPath ¶
ForwardPath returns the JSON file path for a given forward id.
func IsAlive ¶
IsAlive returns true if the pid in `daemon.pid` corresponds to a running process. Used by `list` for a quick "is the daemon up?" probe without opening a socket connection.
func ReadJSONLine ¶
ReadJSONLine reads one newline-terminated JSON object from r into v.
func RemoveForward ¶
RemoveForward removes the JSON descriptor for the given id (no-op if already gone).
func SocketPath ¶
func StateDir ¶
StateDir returns the directory holding daemon state for the current user, creating it with 0700 if needed.
func WriteForward ¶
WriteForward persists a forward's descriptor. Atomic via tmpfile + rename so a partial write never leaves a corrupt state file behind.
func WriteJSONLine ¶
WriteJSONLine writes one length-prefixed JSON object to w. We use a trailing newline as the framing terminator — every Request / Response fits comfortably in well under a megabyte and pretty printers / debugging is trivial.
Types ¶
type ClientFactory ¶
ClientFactory builds an API client for the daemon's outbound gRPC calls. Injectable for tests; production wires it to the same createAPIClient the CLI uses.
type Daemon ¶
type Daemon struct {
// contains filtered or unexported fields
}
Daemon owns the unix socket listener, the active set of forwards, and the idle-shutdown timer.
type Forward ¶
type Forward struct {
ID string `json:"id"`
Namespace string `json:"namespace"`
TargetKind TargetKind `json:"target_kind"`
Target string `json:"target"`
InstancePin string `json:"instance_pin,omitempty"`
Mappings []PortMapping `json:"mappings"`
Context string `json:"context,omitempty"`
CreatedAt time.Time `json:"created_at"`
Status ForwardStatus `json:"status"`
LastError string `json:"last_error,omitempty"`
}
Forward is the persisted descriptor for one daemonized forward. In-memory state on the daemon is authoritative; this struct is what is written to ~/.rune/forwards/<id>.json and reported via `list`.
func LoadForwards ¶
LoadForwards walks the state directory and returns every persisted descriptor, sorted by CreatedAt. Used by the daemon at startup (recovery) and as a fallback for `list` if the daemon is down.
type ForwardStatus ¶
type ForwardStatus string
ForwardStatus mirrors the lifecycle column shown by `list`.
const ( StatusActive ForwardStatus = "active" StatusReconnecting ForwardStatus = "reconnecting" StatusFailed ForwardStatus = "failed" StatusUnauthenticated ForwardStatus = "unauthenticated" )
type PortMapping ¶
type PortMapping struct {
Local string `json:"local"` // bind addr, e.g. "127.0.0.1:27017"
Remote uint32 `json:"remote"` // remote port on the container
}
PortMapping is one [LOCAL:]REMOTE pair persisted in a forward's state file.
type Request ¶
type Request struct {
Cmd string `json:"cmd"`
Forward *Forward `json:"forward,omitempty"` // for Add
ID string `json:"id,omitempty"` // for Stop, Logs
Tail int `json:"tail,omitempty"` // for Logs
}
Request is one CLI → daemon RPC. Exactly one of the typed fields is populated based on Cmd.
type Response ¶
type Response struct {
OK bool `json:"ok"`
Error string `json:"error,omitempty"`
Version string `json:"version,omitempty"` // Ping
Forward *Forward `json:"forward,omitempty"` // Add
Forwards []*Forward `json:"forwards,omitempty"` // List
Stopped int `json:"stopped,omitempty"` // StopAll
Lines []string `json:"lines,omitempty"` // Logs
}
Response is one daemon → CLI reply. OK is the only field guaranteed to be set; the rest are command-specific.
type TargetKind ¶
type TargetKind string
TargetKind says whether the forward is bound to a service or a specific instance.
const ( TargetService TargetKind = "service" TargetInstance TargetKind = "instance" )