Skip to content

Commit

Permalink
Ability to bind to TCP
Browse files Browse the repository at this point in the history
  • Loading branch information
DarthSim committed Jul 15, 2020
1 parent 131160b commit 39a405d
Show file tree
Hide file tree
Showing 13 changed files with 99 additions and 74 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,21 @@ $ overmind restart -s path/to/socket sidekiq
$ overmind kill -s path/to/socket
```

#### Using TCP network

Overmind can bind its command center to a TCP address instead of Unix socket. It is useful when you run it on a remote machine.

```bash
$ overmind start -s "0.0.0.0:4321" -S "tcp"
$ OVERMIND_SOCKET="0.0.0.0:4321" OVERMIND_NETWORK="tcp" overmind start
```

You need to pass the same flags to other commands:

```bash
$ overmind connect -s "0.0.0.0:4321" -S "tcp" web
```

## Known issues

### Overmind uses system Ruby/Node/etc instead of custom-defined one
Expand Down
6 changes: 3 additions & 3 deletions cmd_connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package main
import (
"bufio"
"fmt"
"net"
"os"
"os/exec"
"strings"
Expand All @@ -14,8 +13,9 @@ import (
)

type cmdConnectHandler struct {
dialer

ControlMode bool
SocketPath string
}

func (h *cmdConnectHandler) Run(c *cli.Context) error {
Expand All @@ -27,7 +27,7 @@ func (h *cmdConnectHandler) Run(c *cli.Context) error {
utils.Fatal("Specify a single name of process")
}

conn, err := net.Dial("unix", h.SocketPath)
conn, err := h.Dial()
utils.FatalOnErr(err)

fmt.Fprintf(conn, "get-connection %v\n", c.Args().First())
Expand Down
8 changes: 2 additions & 6 deletions cmd_echo.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package main

import (
"fmt"
"net"
"os"
"os/signal"
"syscall"
Expand All @@ -12,17 +11,14 @@ import (
"github.com/urfave/cli"
)

type cmdEchoHandler struct {
ControlMode bool
SocketPath string
}
type cmdEchoHandler struct{ dialer }

func (h *cmdEchoHandler) Run(c *cli.Context) error {
if c.Args().Present() {
utils.Fatal("Echo doesn't accept any arguments")
}

conn, err := net.Dial("unix", h.SocketPath)
conn, err := h.Dial()
utils.FatalOnErr(err)

stop := make(chan os.Signal)
Expand Down
9 changes: 3 additions & 6 deletions cmd_kill.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ package main

import (
"fmt"
"net"

"github.com/DarthSim/overmind/v2/utils"

"github.com/urfave/cli"
)

type cmdKillHandler struct {
SocketPath string
}
type cmdKillHandler struct{ dialer }

func (c *cmdKillHandler) Run(_ *cli.Context) error {
conn, err := net.Dial("unix", c.SocketPath)
func (h *cmdKillHandler) Run(_ *cli.Context) error {
conn, err := h.Dial()
utils.FatalOnErr(err)

fmt.Fprintf(conn, "kill")
Expand Down
9 changes: 3 additions & 6 deletions cmd_quit.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,16 @@ package main

import (
"fmt"
"net"

"github.com/DarthSim/overmind/v2/utils"

"github.com/urfave/cli"
)

type cmdQuitHandler struct {
SocketPath string
}
type cmdQuitHandler struct{ dialer }

func (c *cmdQuitHandler) Run(_ *cli.Context) error {
conn, err := net.Dial("unix", c.SocketPath)
func (h *cmdQuitHandler) Run(_ *cli.Context) error {
conn, err := h.Dial()
utils.FatalOnErr(err)

fmt.Fprintf(conn, "quit")
Expand Down
7 changes: 2 additions & 5 deletions cmd_restart.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ package main

import (
"fmt"
"net"
"strings"

"github.com/DarthSim/overmind/v2/utils"

"github.com/urfave/cli"
)

type cmdRestartHandler struct {
SocketPath string
}
type cmdRestartHandler struct{ dialer }

func (h *cmdRestartHandler) Run(c *cli.Context) error {
conn, err := net.Dial("unix", h.SocketPath)
conn, err := h.Dial()
utils.FatalOnErr(err)

fmt.Fprintf(conn, "restart %v\n", strings.Join(c.Args(), " "))
Expand Down
4 changes: 1 addition & 3 deletions cmd_run.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import (
"github.com/urfave/cli"
)

type cmdRunHandler struct {
SocketPath string
}
type cmdRunHandler struct{}

func (h *cmdRunHandler) Run(c *cli.Context) error {
if !c.Args().Present() {
Expand Down
7 changes: 2 additions & 5 deletions cmd_stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,17 @@ package main

import (
"fmt"
"net"
"strings"

"github.com/DarthSim/overmind/v2/utils"

"github.com/urfave/cli"
)

type cmdStopHandler struct {
SocketPath string
}
type cmdStopHandler struct{ dialer }

func (h *cmdStopHandler) Run(c *cli.Context) error {
conn, err := net.Dial("unix", h.SocketPath)
conn, err := h.Dial()
utils.FatalOnErr(err)

fmt.Fprintf(conn, "stop %v\n", strings.Join(c.Args(), " "))
Expand Down
12 changes: 12 additions & 0 deletions dialer.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package main

import "net"

type dialer struct {
SocketPath string
Network string
}

func (d *dialer) Dial() (net.Conn, error) {
return net.Dial(d.Network, d.SocketPath)
}
85 changes: 49 additions & 36 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,22 @@ import (

const version = "2.1.1"

func socketFlag(s *string) cli.Flag {
return cli.StringFlag{
Name: "socket, s",
EnvVar: "OVERMIND_SOCKET",
Usage: "Path to overmind socket",
Value: "./.overmind.sock",
Destination: s,
func socketFlags(s, n *string) []cli.Flag {
return []cli.Flag{
cli.StringFlag{
Name: "socket, s",
EnvVar: "OVERMIND_SOCKET",
Usage: "Path to overmind socket (in case of using unix socket) or address to bind (in other cases)",
Value: "./.overmind.sock",
Destination: s,
},
cli.StringFlag{
Name: "network, S",
EnvVar: "OVERMIND_NETWORK",
Usage: "Network to use for commands. Can be 'tcp', 'tcp4', 'tcp6' or 'unix'",
Value: "unix",
Destination: n,
},
}
}

Expand All @@ -32,26 +41,28 @@ func setupStartCmd() cli.Command {
Aliases: []string{"s"},
Usage: "Run procfile",
Action: c.Run,
Flags: []cli.Flag{
cli.StringFlag{Name: "title, w", EnvVar: "OVERMIND_TITLE", Usage: "Specify a title of the application", Destination: &c.Title},
cli.StringFlag{Name: "procfile, f", EnvVar: "OVERMIND_PROCFILE", Usage: "Specify a Procfile to load", Value: "./Procfile", Destination: &c.Procfile},
cli.StringFlag{Name: "processes, l", EnvVar: "OVERMIND_PROCESSES", Usage: "Specify process names to launch. Divide names with comma", Destination: &c.ProcNames},
cli.StringFlag{Name: "root, d", Usage: "Specify a working directory of application. Default: directory containing the Procfile", Destination: &c.Root},
cli.IntFlag{Name: "timeout, t", EnvVar: "OVERMIND_TIMEOUT", Usage: "Specify the amount of time (in seconds) processes have to shut down gracefully before being brutally killed", Value: 5, Destination: &c.Timeout},
cli.IntFlag{Name: "port, p", EnvVar: "OVERMIND_PORT,PORT", Usage: "Specify a port to use as the base", Value: 5000, Destination: &c.PortBase},
cli.IntFlag{Name: "port-step, P", EnvVar: "OVERMIND_PORT_STEP", Usage: "Specify a step to increase port number", Value: 100, Destination: &c.PortStep},
cli.BoolFlag{Name: "no-port, N", EnvVar: "OVERMIND_NO_PORT", Usage: "Don't set $PORT variable for processes", Destination: &c.NoPort},
cli.StringFlag{Name: "can-die, c", EnvVar: "OVERMIND_CAN_DIE", Usage: "Specify names of process which can die without interrupting the other processes. Divide names with comma", Destination: &c.CanDie},
cli.StringFlag{Name: "auto-restart, r", EnvVar: "OVERMIND_AUTO_RESTART", Usage: "Specify names of process which will be auto restarted on death. Divide names with comma", Destination: &c.AutoRestart},
cli.StringFlag{Name: "colors, b", EnvVar: "OVERMIND_COLORS", Usage: "Specify the xterm color codes that will be used to colorize process names. Divide codes with comma"},
cli.StringFlag{Name: "formation, m", EnvVar: "OVERMIND_FORMATION", Usage: "Specify the number of each process type to run. The value passed in should be in the format process=num,process=num. Use 'all' as a process name to set value for all processes"},
cli.IntFlag{Name: "formation-port-step", EnvVar: "OVERMIND_FORMATION_PORT_STEP", Usage: "Specify a step to increase port number for the next instance of a process", Value: 10, Destination: &c.FormationPortStep},
cli.StringFlag{Name: "stop-signals, i", EnvVar: "OVERMIND_STOP_SIGNALS", Usage: "Specify a signal that will be sent to each process when Overmind will try to stop them. The value passed in should be in the format process=signal,process=signal. Supported signals are: ABRT, INT, KILL, QUIT, STOP, TERM, USR1, USR2"},
cli.BoolFlag{Name: "daemonize, D", EnvVar: "OVERMIND_DAEMONIZE", Usage: "Launch Overmind as a daemon. Use 'overmind echo' to view logs and 'overmind quit' to gracefully quit daemonized instance", Destination: &c.Daemonize},
cli.StringFlag{Name: "tmux-config, F", EnvVar: "OVERMIND_TMUX_CONFIG", Usage: "Specify an alternative tmux config path to be used by Overmind", Destination: &c.TmuxConfigPath},
cli.StringFlag{Name: "ignored-processes, x", EnvVar: "OVERMIND_IGNORED_PROCESSES", Usage: "Specify process names to prevent from launching. Useful if you want to run all but one or two processes. Divide names with comma. Takes precedence over the 'processes' flag.", Destination: &c.IgnoredProcNames},
socketFlag(&c.SocketPath),
},
Flags: append(
[]cli.Flag{
cli.StringFlag{Name: "title, w", EnvVar: "OVERMIND_TITLE", Usage: "Specify a title of the application", Destination: &c.Title},
cli.StringFlag{Name: "procfile, f", EnvVar: "OVERMIND_PROCFILE", Usage: "Specify a Procfile to load", Value: "./Procfile", Destination: &c.Procfile},
cli.StringFlag{Name: "processes, l", EnvVar: "OVERMIND_PROCESSES", Usage: "Specify process names to launch. Divide names with comma", Destination: &c.ProcNames},
cli.StringFlag{Name: "root, d", Usage: "Specify a working directory of application. Default: directory containing the Procfile", Destination: &c.Root},
cli.IntFlag{Name: "timeout, t", EnvVar: "OVERMIND_TIMEOUT", Usage: "Specify the amount of time (in seconds) processes have to shut down gracefully before being brutally killed", Value: 5, Destination: &c.Timeout},
cli.IntFlag{Name: "port, p", EnvVar: "OVERMIND_PORT,PORT", Usage: "Specify a port to use as the base", Value: 5000, Destination: &c.PortBase},
cli.IntFlag{Name: "port-step, P", EnvVar: "OVERMIND_PORT_STEP", Usage: "Specify a step to increase port number", Value: 100, Destination: &c.PortStep},
cli.BoolFlag{Name: "no-port, N", EnvVar: "OVERMIND_NO_PORT", Usage: "Don't set $PORT variable for processes", Destination: &c.NoPort},
cli.StringFlag{Name: "can-die, c", EnvVar: "OVERMIND_CAN_DIE", Usage: "Specify names of process which can die without interrupting the other processes. Divide names with comma", Destination: &c.CanDie},
cli.StringFlag{Name: "auto-restart, r", EnvVar: "OVERMIND_AUTO_RESTART", Usage: "Specify names of process which will be auto restarted on death. Divide names with comma", Destination: &c.AutoRestart},
cli.StringFlag{Name: "colors, b", EnvVar: "OVERMIND_COLORS", Usage: "Specify the xterm color codes that will be used to colorize process names. Divide codes with comma"},
cli.StringFlag{Name: "formation, m", EnvVar: "OVERMIND_FORMATION", Usage: "Specify the number of each process type to run. The value passed in should be in the format process=num,process=num. Use 'all' as a process name to set value for all processes"},
cli.IntFlag{Name: "formation-port-step", EnvVar: "OVERMIND_FORMATION_PORT_STEP", Usage: "Specify a step to increase port number for the next instance of a process", Value: 10, Destination: &c.FormationPortStep},
cli.StringFlag{Name: "stop-signals, i", EnvVar: "OVERMIND_STOP_SIGNALS", Usage: "Specify a signal that will be sent to each process when Overmind will try to stop them. The value passed in should be in the format process=signal,process=signal. Supported signals are: ABRT, INT, KILL, QUIT, STOP, TERM, USR1, USR2"},
cli.BoolFlag{Name: "daemonize, D", EnvVar: "OVERMIND_DAEMONIZE", Usage: "Launch Overmind as a daemon. Use 'overmind echo' to view logs and 'overmind quit' to gracefully quit daemonized instance", Destination: &c.Daemonize},
cli.StringFlag{Name: "tmux-config, F", EnvVar: "OVERMIND_TMUX_CONFIG", Usage: "Specify an alternative tmux config path to be used by Overmind", Destination: &c.TmuxConfigPath},
cli.StringFlag{Name: "ignored-processes, x", EnvVar: "OVERMIND_IGNORED_PROCESSES", Usage: "Specify process names to prevent from launching. Useful if you want to run all but one or two processes. Divide names with comma. Takes precedence over the 'processes' flag.", Destination: &c.IgnoredProcNames},
},
socketFlags(&c.SocketPath, &c.Network)...,
),
}
}

Expand All @@ -64,7 +75,7 @@ func setupRestartCmd() cli.Command {
Usage: "Restart specified processes",
Action: c.Run,
ArgsUsage: "[process name...]",
Flags: []cli.Flag{socketFlag(&c.SocketPath)},
Flags: socketFlags(&c.SocketPath, &c.Network),
}
}

Expand All @@ -77,7 +88,7 @@ func setupStopCmd() cli.Command {
Usage: "Stop specified processes without quitting Overmind itself",
Action: c.Run,
ArgsUsage: "[process name...]",
Flags: []cli.Flag{socketFlag(&c.SocketPath)},
Flags: socketFlags(&c.SocketPath, &c.Network),
}
}

Expand All @@ -90,10 +101,12 @@ func setupConnectCmd() cli.Command {
Usage: "Connect to the tmux session of the specified process",
Action: c.Run,
ArgsUsage: "[process name]",
Flags: []cli.Flag{
cli.BoolFlag{Name: "control-mode, c", EnvVar: "OVERMIND_CONTROL_MODE", Usage: "Connect to the tmux session in control mode", Destination: &c.ControlMode},
socketFlag(&c.SocketPath),
},
Flags: append(
[]cli.Flag{
cli.BoolFlag{Name: "control-mode, c", EnvVar: "OVERMIND_CONTROL_MODE", Usage: "Connect to the tmux session in control mode", Destination: &c.ControlMode},
},
socketFlags(&c.SocketPath, &c.Network)...,
),
}
}

Expand All @@ -105,7 +118,7 @@ func setupQuitCmd() cli.Command {
Aliases: []string{"q"},
Usage: "Gracefully quits Overmind. Same as sending SIGINT",
Action: c.Run,
Flags: []cli.Flag{socketFlag(&c.SocketPath)},
Flags: socketFlags(&c.SocketPath, &c.Network),
}
}

Expand All @@ -117,7 +130,7 @@ func setupKillCmd() cli.Command {
Aliases: []string{"k"},
Usage: "Kills all processes",
Action: c.Run,
Flags: []cli.Flag{socketFlag(&c.SocketPath)},
Flags: socketFlags(&c.SocketPath, &c.Network),
}
}

Expand All @@ -140,7 +153,7 @@ func setupEchoCmd() cli.Command {
Name: "echo",
Usage: "Echoes output from master Overmind instance",
Action: c.Run,
Flags: []cli.Flag{socketFlag(&c.SocketPath)},
Flags: socketFlags(&c.SocketPath, &c.Network),
}
}

Expand Down
2 changes: 1 addition & 1 deletion start/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ func newCommand(h *Handler) (*command, error) {
}
}

c.cmdCenter = newCommandCenter(&c, h.SocketPath)
c.cmdCenter = newCommandCenter(&c, h.SocketPath, h.Network)

return &c, nil
}
Expand Down
8 changes: 5 additions & 3 deletions start/command_center.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@ type commandCenter struct {
stop bool

SocketPath string
Network string
}

func newCommandCenter(cmd *command, socket string) *commandCenter {
func newCommandCenter(cmd *command, socket, network string) *commandCenter {
return &commandCenter{
cmd: cmd,
SocketPath: socket,
Network: network,
}
}

func (c *commandCenter) Start() (err error) {
if c.listener, err = net.Listen("unix", c.SocketPath); err != nil {
if strings.Contains(err.Error(), "address already in use") {
if c.listener, err = net.Listen(c.Network, c.SocketPath); err != nil {
if c.Network == "unix" && strings.Contains(err.Error(), "address already in use") {
err = fmt.Errorf("it looks like Overmind is already running. If it's not, remove %s and try again", c.SocketPath)
}
return
Expand Down
1 change: 1 addition & 0 deletions start/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ type Handler struct {
ProcNames string
IgnoredProcNames string
SocketPath string
Network string
CanDie string
AutoRestart string
Colors []int
Expand Down

0 comments on commit 39a405d

Please sign in to comment.