mirror of https://github.com/status-im/consul.git
Make daemoinze an option on test binary without hacks. Misc fixes for racey or broken tests. Still failing on several though.
This commit is contained in:
parent
2b377dc624
commit
ba0fb58a72
|
@ -1691,7 +1691,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
require := require.New(t)
|
require := require.New(t)
|
||||||
assert := assert.New(t)
|
assert := assert.New(t)
|
||||||
|
|
||||||
_, err := state.AddProxy(&p1, "fake-token")
|
_, err := state.AddProxy(&p1, "fake-token", "")
|
||||||
require.Error(err, "should fail as the target service isn't registered")
|
require.Error(err, "should fail as the target service isn't registered")
|
||||||
|
|
||||||
// Sanity check done, lets add a couple of target services to the state
|
// Sanity check done, lets add a couple of target services to the state
|
||||||
|
@ -1710,7 +1710,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
|
||||||
// Should work now
|
// Should work now
|
||||||
pstate, err := state.AddProxy(&p1, "fake-token")
|
pstate, err := state.AddProxy(&p1, "fake-token", "")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
|
|
||||||
svc := pstate.Proxy.ProxyService
|
svc := pstate.Proxy.ProxyService
|
||||||
|
@ -1724,8 +1724,9 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
|
|
||||||
{
|
{
|
||||||
// Re-registering same proxy again should not pick a random port but re-use
|
// Re-registering same proxy again should not pick a random port but re-use
|
||||||
// the assigned one.
|
// the assigned one. It should also keep the same proxy token since we don't
|
||||||
pstateDup, err := state.AddProxy(&p1, "fake-token")
|
// want to force restart for config change.
|
||||||
|
pstateDup, err := state.AddProxy(&p1, "fake-token", "")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
svcDup := pstateDup.Proxy.ProxyService
|
svcDup := pstateDup.Proxy.ProxyService
|
||||||
|
|
||||||
|
@ -1736,6 +1737,8 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
assert.Equal("", svcDup.Address, "should have empty address by default")
|
assert.Equal("", svcDup.Address, "should have empty address by default")
|
||||||
// Port must be same as before
|
// Port must be same as before
|
||||||
assert.Equal(svc.Port, svcDup.Port)
|
assert.Equal(svc.Port, svcDup.Port)
|
||||||
|
// Same ProxyToken
|
||||||
|
assert.Equal(pstate.ProxyToken, pstateDup.ProxyToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Let's register a notifier now
|
// Let's register a notifier now
|
||||||
|
@ -1748,7 +1751,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
// Second proxy should claim other port
|
// Second proxy should claim other port
|
||||||
p2 := p1
|
p2 := p1
|
||||||
p2.TargetServiceID = "cache"
|
p2.TargetServiceID = "cache"
|
||||||
pstate2, err := state.AddProxy(&p2, "fake-token")
|
pstate2, err := state.AddProxy(&p2, "fake-token", "")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
svc2 := pstate2.Proxy.ProxyService
|
svc2 := pstate2.Proxy.ProxyService
|
||||||
assert.Contains([]int{20000, 20001}, svc2.Port)
|
assert.Contains([]int{20000, 20001}, svc2.Port)
|
||||||
|
@ -1764,7 +1767,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
// Third proxy should fail as all ports are used
|
// Third proxy should fail as all ports are used
|
||||||
p3 := p1
|
p3 := p1
|
||||||
p3.TargetServiceID = "db"
|
p3.TargetServiceID = "db"
|
||||||
_, err = state.AddProxy(&p3, "fake-token")
|
_, err = state.AddProxy(&p3, "fake-token", "")
|
||||||
require.Error(err)
|
require.Error(err)
|
||||||
|
|
||||||
// Should have a notification but we'll do nothing so that the next
|
// Should have a notification but we'll do nothing so that the next
|
||||||
|
@ -1775,7 +1778,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
"bind_port": 1234,
|
"bind_port": 1234,
|
||||||
"bind_address": "0.0.0.0",
|
"bind_address": "0.0.0.0",
|
||||||
}
|
}
|
||||||
pstate3, err := state.AddProxy(&p3, "fake-token")
|
pstate3, err := state.AddProxy(&p3, "fake-token", "")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
svc3 := pstate3.Proxy.ProxyService
|
svc3 := pstate3.Proxy.ProxyService
|
||||||
require.Equal("0.0.0.0", svc3.Address)
|
require.Equal("0.0.0.0", svc3.Address)
|
||||||
|
@ -1793,7 +1796,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
require.NotNil(gotP3)
|
require.NotNil(gotP3)
|
||||||
var ws memdb.WatchSet
|
var ws memdb.WatchSet
|
||||||
ws.Add(gotP3.WatchCh)
|
ws.Add(gotP3.WatchCh)
|
||||||
pstate3, err = state.AddProxy(&p3updated, "fake-token")
|
pstate3, err = state.AddProxy(&p3updated, "fake-token", "")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
svc3 = pstate3.Proxy.ProxyService
|
svc3 = pstate3.Proxy.ProxyService
|
||||||
require.Equal("0.0.0.0", svc3.Address)
|
require.Equal("0.0.0.0", svc3.Address)
|
||||||
|
@ -1817,7 +1820,7 @@ func TestStateProxyManagement(t *testing.T) {
|
||||||
// Should be able to create a new proxy for that service with the port (it
|
// Should be able to create a new proxy for that service with the port (it
|
||||||
// should have been "freed").
|
// should have been "freed").
|
||||||
p4 := p2
|
p4 := p2
|
||||||
pstate4, err := state.AddProxy(&p4, "fake-token")
|
pstate4, err := state.AddProxy(&p4, "fake-token", "")
|
||||||
require.NoError(err)
|
require.NoError(err)
|
||||||
svc4 := pstate4.Proxy.ProxyService
|
svc4 := pstate4.Proxy.ProxyService
|
||||||
assert.Contains([]int{20000, 20001}, svc2.Port)
|
assert.Contains([]int{20000, 20001}, svc2.Port)
|
||||||
|
@ -1865,3 +1868,65 @@ func drainCh(ch chan struct{}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests the logic for retaining tokens and ports through restore (i.e.
|
||||||
|
// proxy-service already restored and token passed in externally)
|
||||||
|
func TestStateProxyRestore(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
state := local.NewState(local.Config{
|
||||||
|
// Wide random range to make it very unlikely to pass by chance
|
||||||
|
ProxyBindMinPort: 10000,
|
||||||
|
ProxyBindMaxPort: 20000,
|
||||||
|
}, log.New(os.Stderr, "", log.LstdFlags), &token.Store{})
|
||||||
|
|
||||||
|
// Stub state syncing
|
||||||
|
state.TriggerSyncChanges = func() {}
|
||||||
|
|
||||||
|
webSvc := structs.NodeService{
|
||||||
|
Service: "web",
|
||||||
|
}
|
||||||
|
|
||||||
|
p1 := structs.ConnectManagedProxy{
|
||||||
|
ExecMode: structs.ProxyExecModeDaemon,
|
||||||
|
Command: []string{"consul", "connect", "proxy"},
|
||||||
|
TargetServiceID: "web",
|
||||||
|
}
|
||||||
|
|
||||||
|
p2 := p1
|
||||||
|
|
||||||
|
require := require.New(t)
|
||||||
|
assert := assert.New(t)
|
||||||
|
|
||||||
|
// Add a target service
|
||||||
|
require.NoError(state.AddService(&webSvc, "fake-token-web"))
|
||||||
|
|
||||||
|
// Add the proxy for first time to get the proper service definition to
|
||||||
|
// register
|
||||||
|
pstate, err := state.AddProxy(&p1, "fake-token", "")
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
// Now start again with a brand new state
|
||||||
|
state2 := local.NewState(local.Config{
|
||||||
|
// Wide random range to make it very unlikely to pass by chance
|
||||||
|
ProxyBindMinPort: 10000,
|
||||||
|
ProxyBindMaxPort: 20000,
|
||||||
|
}, log.New(os.Stderr, "", log.LstdFlags), &token.Store{})
|
||||||
|
|
||||||
|
// Stub state syncing
|
||||||
|
state2.TriggerSyncChanges = func() {}
|
||||||
|
|
||||||
|
// Register the target service
|
||||||
|
require.NoError(state2.AddService(&webSvc, "fake-token-web"))
|
||||||
|
|
||||||
|
// "Restore" the proxy service
|
||||||
|
require.NoError(state.AddService(p1.ProxyService, "fake-token-web"))
|
||||||
|
|
||||||
|
// Now we can AddProxy with the "restored" token
|
||||||
|
pstate2, err := state.AddProxy(&p2, "fake-token", pstate.ProxyToken)
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
// Check it still has the same port and token as before
|
||||||
|
assert.Equal(pstate.ProxyToken, pstate2.ProxyToken)
|
||||||
|
assert.Equal(p1.ProxyService.Port, p2.ProxyService.Port)
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"path"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -75,11 +76,9 @@ type Daemon struct {
|
||||||
// second.
|
// second.
|
||||||
pollInterval time.Duration
|
pollInterval time.Duration
|
||||||
|
|
||||||
// daemonizePath is set only in tests to control the path to the daemonize
|
// daemonizeCmd is set only in tests to control the path and args to the
|
||||||
// command. The test executable itself will not respond to the consul command
|
// daemonize command.
|
||||||
// arguments we need to make this work so we rely on the current source being
|
daemonizeCmd []string
|
||||||
// built and installed here to run the tests.
|
|
||||||
daemonizePath string
|
|
||||||
|
|
||||||
// process is the started process
|
// process is the started process
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
|
@ -112,6 +111,18 @@ func (p *Daemon) Start() error {
|
||||||
p.stopCh = stopCh
|
p.stopCh = stopCh
|
||||||
p.exitedCh = exitedCh
|
p.exitedCh = exitedCh
|
||||||
|
|
||||||
|
// Ensure log dirs exist
|
||||||
|
if p.StdoutPath != "" {
|
||||||
|
if err := os.MkdirAll(path.Dir(p.StdoutPath), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.StderrPath != "" {
|
||||||
|
if err := os.MkdirAll(path.Dir(p.StderrPath), 0755); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start the loop.
|
// Start the loop.
|
||||||
go p.keepAlive(stopCh, exitedCh)
|
go p.keepAlive(stopCh, exitedCh)
|
||||||
|
|
||||||
|
@ -270,19 +281,21 @@ func (p *Daemon) start() (*os.Process, error) {
|
||||||
daemonCmd.Path = dCmd[0]
|
daemonCmd.Path = dCmd[0]
|
||||||
// First arguments are for the stdout, stderr
|
// First arguments are for the stdout, stderr
|
||||||
daemonCmd.Args = append(dCmd, p.StdoutPath)
|
daemonCmd.Args = append(dCmd, p.StdoutPath)
|
||||||
daemonCmd.Args = append(daemonCmd.Args, p.StdoutPath)
|
daemonCmd.Args = append(daemonCmd.Args, p.StderrPath)
|
||||||
daemonCmd.Args = append(daemonCmd.Args, p.Args...)
|
daemonCmd.Args = append(daemonCmd.Args, p.Args...)
|
||||||
daemonCmd.Env = env
|
daemonCmd.Env = env
|
||||||
|
|
||||||
// setup stdout so we can read the PID
|
// setup stdout so we can read the PID
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
daemonCmd.Stdout = &out
|
daemonCmd.Stdout = &out
|
||||||
|
daemonCmd.Stderr = &out
|
||||||
|
|
||||||
// Run it to completion - it should exit immediately (this calls wait to
|
// Run it to completion - it should exit immediately (this calls wait to
|
||||||
// ensure we don't leave the daemonize command as a zombie)
|
// ensure we don't leave the daemonize command as a zombie)
|
||||||
p.Logger.Printf("[DEBUG] agent/proxy: starting proxy: %q %#v", daemonCmd.Path,
|
p.Logger.Printf("[DEBUG] agent/proxy: starting proxy: %q %#v", daemonCmd.Path,
|
||||||
daemonCmd.Args[1:])
|
daemonCmd.Args[1:])
|
||||||
if err := daemonCmd.Run(); err != nil {
|
if err := daemonCmd.Run(); err != nil {
|
||||||
|
p.Logger.Printf("[DEBUG] agent/proxy: daemonize output: %s", out.String())
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -313,15 +326,16 @@ func (p *Daemon) start() (*os.Process, error) {
|
||||||
|
|
||||||
// daemonizeCommand returns the daemonize command.
|
// daemonizeCommand returns the daemonize command.
|
||||||
func (p *Daemon) daemonizeCommand() ([]string, error) {
|
func (p *Daemon) daemonizeCommand() ([]string, error) {
|
||||||
|
// test override
|
||||||
|
if p.daemonizeCmd != nil {
|
||||||
|
return p.daemonizeCmd, nil
|
||||||
|
}
|
||||||
// Get the path to the current executable. This is cached once by the
|
// Get the path to the current executable. This is cached once by the
|
||||||
// library so this is effectively just a variable read.
|
// library so this is effectively just a variable read.
|
||||||
execPath, err := os.Executable()
|
execPath, err := os.Executable()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if p.daemonizePath != "" {
|
|
||||||
execPath = p.daemonizePath
|
|
||||||
}
|
|
||||||
return []string{execPath, "connect", "daemonize"}, nil
|
return []string{execPath, "connect", "daemonize"}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -102,6 +102,10 @@ type Manager struct {
|
||||||
// proxies (unlikely scenario).
|
// proxies (unlikely scenario).
|
||||||
lastSnapshot *snapshot
|
lastSnapshot *snapshot
|
||||||
|
|
||||||
|
// daemonizeCmd is set only in tests to control the path and args to the
|
||||||
|
// daemonize command.
|
||||||
|
daemonizeCmd []string
|
||||||
|
|
||||||
proxies map[string]Proxy
|
proxies map[string]Proxy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,6 +409,7 @@ func (m *Manager) newProxy(mp *local.ManagedProxy) (Proxy, error) {
|
||||||
proxy.Args = command // idx 0 is path but preserved since it should be
|
proxy.Args = command // idx 0 is path but preserved since it should be
|
||||||
proxy.ProxyId = id
|
proxy.ProxyId = id
|
||||||
proxy.ProxyToken = mp.ProxyToken
|
proxy.ProxyToken = mp.ProxyToken
|
||||||
|
proxy.daemonizeCmd = m.daemonizeCmd
|
||||||
return proxy, nil
|
return proxy, nil
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -361,6 +361,10 @@ func testManager(t *testing.T) (*Manager, func()) {
|
||||||
td, closer := testTempDir(t)
|
td, closer := testTempDir(t)
|
||||||
m.DataDir = td
|
m.DataDir = td
|
||||||
|
|
||||||
|
// Override daemonize command to use the built-in test binary. Note that Args
|
||||||
|
// includes the binary path as first arg.
|
||||||
|
m.daemonizeCmd = helperProcess("daemonize").Args
|
||||||
|
|
||||||
return m, func() { closer() }
|
return m, func() { closer() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -368,8 +372,9 @@ func testManager(t *testing.T) (*Manager, func()) {
|
||||||
// (expected to be from the helperProcess function call). It returns the
|
// (expected to be from the helperProcess function call). It returns the
|
||||||
// ID for deregistration.
|
// ID for deregistration.
|
||||||
func testStateProxy(t *testing.T, state *local.State, service string, cmd *exec.Cmd) string {
|
func testStateProxy(t *testing.T, state *local.State, service string, cmd *exec.Cmd) string {
|
||||||
command := []string{cmd.Path}
|
// Note that exec.Command already ensures the command name is the first
|
||||||
command = append(command, cmd.Args...)
|
// argument in the list so no need to append again
|
||||||
|
command := cmd.Args
|
||||||
|
|
||||||
require.NoError(t, state.AddService(&structs.NodeService{
|
require.NoError(t, state.AddService(&structs.NodeService{
|
||||||
Service: service,
|
Service: service,
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
package proxy
|
package proxy
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
// isProcessAlreadyFinishedErr does a janky comparison with an error string
|
// isProcessAlreadyFinishedErr does a janky comparison with an error string
|
||||||
// defined in os/exec_unix.go and os/exec_windows.go which we encounter due to races.
|
// defined in os/exec_unix.go and os/exec_windows.go which we encounter due to
|
||||||
// These case tests to fail since Stop returns an error sometimes so we should
|
// races with polling the external process. These case tests to fail since Stop
|
||||||
// notice if this string stops matching the error in a future go version.
|
// returns an error sometimes so we should notice if this string stops matching
|
||||||
|
// the error in a future go version.
|
||||||
func isProcessAlreadyFinishedErr(err error) bool {
|
func isProcessAlreadyFinishedErr(err error) bool {
|
||||||
return strings.Contains(err.Error(), "os: process already finished")
|
return strings.Contains(err.Error(), "os: process already finished")
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,6 @@ func externalWait(pid int, pollInterval time.Duration) (<-chan struct{}, func())
|
||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
log.Printf("checking pid %d", pid)
|
|
||||||
if _, err := findProcess(pid); err != nil {
|
if _, err := findProcess(pid); err != nil {
|
||||||
close(ch)
|
close(ch)
|
||||||
return
|
return
|
||||||
|
|
|
@ -10,6 +10,9 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/hashicorp/consul/command/connect/daemonize"
|
||||||
|
"github.com/mitchellh/cli"
|
||||||
)
|
)
|
||||||
|
|
||||||
// testLogger is a logger that can be used by tests that require a
|
// testLogger is a logger that can be used by tests that require a
|
||||||
|
@ -55,29 +58,17 @@ func helperProcess(s ...string) *exec.Cmd {
|
||||||
// interactions. The Daemon has it's Path, Args and stdio paths populated but
|
// interactions. The Daemon has it's Path, Args and stdio paths populated but
|
||||||
// other fields might need to be set depending on test requirements.
|
// other fields might need to be set depending on test requirements.
|
||||||
//
|
//
|
||||||
// NOTE: this relies on a sufficiently recent version on consul being installed
|
// This relies on the TestMainInterceptDaemonize hack being active.
|
||||||
// in your path so that the daemonize command can be used. That's gross but hard
|
|
||||||
// to see how we can do better given that tests are separate binaries and we
|
|
||||||
// need consul's daemonize mode to work correctly. I considered hacks around
|
|
||||||
// building the local tree and getting the absolute path to the resulting binary
|
|
||||||
// but that seems gross in a different way. This is the same or weaker
|
|
||||||
// assumption our `api` test suit makes already...
|
|
||||||
func helperProcessDaemon(s ...string) *Daemon {
|
func helperProcessDaemon(s ...string) *Daemon {
|
||||||
cs := []string{os.Args[0], "-test.run=TestHelperProcess", "--", helperProcessSentinel}
|
cs := []string{os.Args[0], "-test.run=TestHelperProcess", "--", helperProcessSentinel}
|
||||||
cs = append(cs, s...)
|
cs = append(cs, s...)
|
||||||
|
|
||||||
path, err := exec.LookPath("consul")
|
|
||||||
if err != nil || path == "" {
|
|
||||||
panic("consul not found on $PATH - download and install " +
|
|
||||||
"consul or skip this test")
|
|
||||||
}
|
|
||||||
|
|
||||||
return &Daemon{
|
return &Daemon{
|
||||||
Path: os.Args[0],
|
Path: os.Args[0],
|
||||||
Args: cs,
|
Args: cs,
|
||||||
StdoutPath: "_", // dev null them for now
|
StdoutPath: "_", // dev null them for now
|
||||||
StderrPath: "_",
|
StderrPath: "_",
|
||||||
daemonizePath: path,
|
daemonizeCmd: helperProcess("daemonize").Args,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -214,6 +205,24 @@ func TestHelperProcess(t *testing.T) {
|
||||||
time.Sleep(time.Hour)
|
time.Sleep(time.Hour)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case "daemonize":
|
||||||
|
// Run daemonize!
|
||||||
|
ui := &cli.BasicUi{Writer: os.Stdout, ErrorWriter: os.Stderr}
|
||||||
|
cli := &cli.CLI{
|
||||||
|
Args: append([]string{"daemonize"}, args...),
|
||||||
|
Commands: map[string]cli.CommandFactory{
|
||||||
|
"daemonize": func() (cli.Command, error) {
|
||||||
|
return daemonize.New(ui), nil
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
exitCode, err := cli.Run()
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERR] running hijacked daemonize command: %s", err)
|
||||||
|
}
|
||||||
|
os.Exit(exitCode)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
fmt.Fprintf(os.Stderr, "Unknown command: %q\n", cmd)
|
fmt.Fprintf(os.Stderr, "Unknown command: %q\n", cmd)
|
||||||
os.Exit(2)
|
os.Exit(2)
|
||||||
|
|
|
@ -1140,7 +1140,7 @@ func TestAPI_AgentConnectProxyConfig(t *testing.T) {
|
||||||
Port: 8000,
|
Port: 8000,
|
||||||
Connect: &AgentServiceConnect{
|
Connect: &AgentServiceConnect{
|
||||||
Proxy: &AgentServiceConnectProxy{
|
Proxy: &AgentServiceConnectProxy{
|
||||||
Command: []string{"consul connect proxy"},
|
Command: []string{"consul", "connect", "proxy"},
|
||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
"foo": "bar",
|
"foo": "bar",
|
||||||
},
|
},
|
||||||
|
@ -1157,7 +1157,7 @@ func TestAPI_AgentConnectProxyConfig(t *testing.T) {
|
||||||
ProxyServiceID: "foo-proxy",
|
ProxyServiceID: "foo-proxy",
|
||||||
TargetServiceID: "foo",
|
TargetServiceID: "foo",
|
||||||
TargetServiceName: "foo",
|
TargetServiceName: "foo",
|
||||||
ContentHash: "93baee1d838888ae",
|
ContentHash: "2a29f8237db69d0e",
|
||||||
ExecMode: "daemon",
|
ExecMode: "daemon",
|
||||||
Command: []string{"consul", "connect", "proxy"},
|
Command: []string{"consul", "connect", "proxy"},
|
||||||
Config: map[string]interface{}{
|
Config: map[string]interface{}{
|
||||||
|
|
|
@ -23,17 +23,15 @@ type cmd struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cmd) Run(args []string) int {
|
func (c *cmd) Run(args []string) int {
|
||||||
// Ignore initial `consul connect daemonize`
|
numArgs := len(args)
|
||||||
offset := 3
|
if numArgs < 3 {
|
||||||
numArgs := len(os.Args) - offset
|
|
||||||
if numArgs < 4 {
|
|
||||||
c.UI.Error("Need at least 3 arguments; stdoutPath, stdinPath, " +
|
c.UI.Error("Need at least 3 arguments; stdoutPath, stdinPath, " +
|
||||||
"executablePath [arguments...]")
|
"executablePath [arguments...]")
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.stdoutPath, c.stderrPath = os.Args[offset], os.Args[offset+1]
|
c.stdoutPath, c.stderrPath = args[0], args[1]
|
||||||
c.cmdArgs = os.Args[offset+2:] // includes the executable as arg 0 as expected
|
c.cmdArgs = args[2:] // includes the executable as arg 0 as expected
|
||||||
|
|
||||||
// Open log files if specified
|
// Open log files if specified
|
||||||
var stdoutF, stderrF *os.File
|
var stdoutF, stderrF *os.File
|
||||||
|
|
Loading…
Reference in New Issue