mirror of https://github.com/hashicorp/consul
agent/proxy: check if process is alive
parent
0e8c0b7b48
commit
13ff115436
|
@ -342,9 +342,11 @@ func (p *Daemon) UnmarshalSnapshot(m map[string]interface{}) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mitchellh): we should check if proc refers to a process that
|
// FindProcess on many systems returns no error even if the process
|
||||||
// is currently alive. If not, we should return here and not manage the
|
// is now dead. We perform an extra check that the process is alive.
|
||||||
// process.
|
if err := processAlive(proc); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// "Start it"
|
// "Start it"
|
||||||
stopCh := make(chan struct{})
|
stopCh := make(chan struct{})
|
||||||
|
|
|
@ -372,6 +372,7 @@ func TestDaemonUnmarshalSnapshot(t *testing.T) {
|
||||||
ProxyToken: uuid,
|
ProxyToken: uuid,
|
||||||
Logger: testLogger,
|
Logger: testLogger,
|
||||||
}
|
}
|
||||||
|
defer d.Stop()
|
||||||
require.NoError(d.Start())
|
require.NoError(d.Start())
|
||||||
|
|
||||||
// Wait for the file to exist
|
// Wait for the file to exist
|
||||||
|
@ -408,3 +409,43 @@ func TestDaemonUnmarshalSnapshot(t *testing.T) {
|
||||||
r.Fatalf("should not exist: %s", err)
|
r.Fatalf("should not exist: %s", err)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDaemonUnmarshalSnapshot_notRunning(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
require := require.New(t)
|
||||||
|
td, closer := testTempDir(t)
|
||||||
|
defer closer()
|
||||||
|
|
||||||
|
path := filepath.Join(td, "file")
|
||||||
|
uuid, err := uuid.GenerateUUID()
|
||||||
|
require.NoError(err)
|
||||||
|
|
||||||
|
d := &Daemon{
|
||||||
|
Command: helperProcess("start-stop", path),
|
||||||
|
ProxyToken: uuid,
|
||||||
|
Logger: testLogger,
|
||||||
|
}
|
||||||
|
defer d.Stop()
|
||||||
|
require.NoError(d.Start())
|
||||||
|
|
||||||
|
// Wait for the file to exist
|
||||||
|
retry.Run(t, func(r *retry.R) {
|
||||||
|
_, err := os.Stat(path)
|
||||||
|
if err == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
r.Fatalf("error: %s", err)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Snapshot
|
||||||
|
snap := d.MarshalSnapshot()
|
||||||
|
|
||||||
|
// Stop the original daemon
|
||||||
|
require.NoError(d.Stop())
|
||||||
|
|
||||||
|
// Restore the second daemon
|
||||||
|
d2 := &Daemon{Logger: testLogger}
|
||||||
|
require.Error(d2.UnmarshalSnapshot(snap))
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
// +build !windows
|
||||||
|
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"syscall"
|
||||||
|
)
|
||||||
|
|
||||||
|
// processAlive for non-Windows. Note that this very likely doesn't
|
||||||
|
// work for all non-Windows platforms Go supports and we should expand
|
||||||
|
// support as we experience it.
|
||||||
|
func processAlive(p *os.Process) error {
|
||||||
|
// On Unix-like systems, we can verify a process is alive by sending
|
||||||
|
// a 0 signal. This will do nothing to the process but will still
|
||||||
|
// return errors if the process is gone.
|
||||||
|
err := p.Signal(syscall.Signal(0))
|
||||||
|
if err == nil || err == syscall.EPERM {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
// +build windows
|
||||||
|
|
||||||
|
package proxy
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func processAlive(p *os.Process) error {
|
||||||
|
// On Windows, os.FindProcess will error if the process is not alive,
|
||||||
|
// so we don't have to do any further checking. The nature of it being
|
||||||
|
// non-nil means it seems to be healthy.
|
||||||
|
if p == nil {
|
||||||
|
return fmt.Errof("process no longer alive")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
Loading…
Reference in New Issue