re-align to master

This commit is contained in:
JackDoan
2026-07-14 11:38:43 -05:00
parent 68e3fae870
commit 7cc37323a8
6 changed files with 23 additions and 30 deletions
+2 -3
View File
@@ -98,15 +98,14 @@ func main() {
} }
if !*configTest { if !*configTest {
wait, err := ctrl.Start() if err := ctrl.Start(); err != nil {
if err != nil {
util.LogWithContextIfNeeded("Error while running", err, l) util.LogWithContextIfNeeded("Error while running", err, l)
os.Exit(1) os.Exit(1)
} }
go ctrl.ShutdownBlock() go ctrl.ShutdownBlock()
if err := wait(); err != nil { if err := ctrl.Wait(); err != nil {
l.Error("Nebula stopped due to fatal error", "error", err) l.Error("Nebula stopped due to fatal error", "error", err)
os.Exit(2) os.Exit(2)
} }
+2 -3
View File
@@ -45,14 +45,13 @@ func (p *program) Start(s service.Service) error {
return err return err
} }
wait, err := p.control.Start() if err := p.control.Start(); err != nil {
if err != nil {
return err return err
} }
// Nebula can stop itself on a fatal packet reader error, make sure to log it if it happens. // Nebula can stop itself on a fatal packet reader error, make sure to log it if it happens.
go func() { go func() {
if err := wait(); err != nil { if err := p.control.Wait(); err != nil {
logger.Error(fmt.Sprintf("Nebula stopped due to fatal error: %v", err)) logger.Error(fmt.Sprintf("Nebula stopped due to fatal error: %v", err))
os.Exit(2) os.Exit(2)
} }
+2 -3
View File
@@ -84,8 +84,7 @@ func main() {
} }
if !*configTest { if !*configTest {
wait, err := ctrl.Start() if err := ctrl.Start(); err != nil {
if err != nil {
util.LogWithContextIfNeeded("Error while running", err, l) util.LogWithContextIfNeeded("Error while running", err, l)
os.Exit(1) os.Exit(1)
} }
@@ -93,7 +92,7 @@ func main() {
go ctrl.ShutdownBlock() go ctrl.ShutdownBlock()
notifyReady(l) notifyReady(l)
if err := wait(); err != nil { if err := ctrl.Wait(); err != nil {
l.Error("Nebula stopped due to fatal error", "error", err) l.Error("Nebula stopped due to fatal error", "error", err)
os.Exit(2) os.Exit(2)
} }
+7 -9
View File
@@ -70,21 +70,19 @@ type ControlHostInfo struct {
} }
// Start actually runs nebula, this is a nonblocking call. // Start actually runs nebula, this is a nonblocking call.
// The returned function blocks until nebula has fully stopped and reports the // Use Wait to block until nebula has fully stopped and to learn whether a fatal reader error caused the shutdown.
// fatal reader error (nil on a clean shutdown). Calling it is equivalent to func (c *Control) Start() error {
// calling Wait.
func (c *Control) Start() (func() error, error) {
c.stateLock.Lock() c.stateLock.Lock()
defer c.stateLock.Unlock() defer c.stateLock.Unlock()
switch c.state { switch c.state {
case StateReady: case StateReady:
//yay! //yay!
case StateStopped, StateStopping: case StateStopped, StateStopping:
return nil, ErrAlreadyStopped return ErrAlreadyStopped
case StateStarted: case StateStarted:
return nil, ErrAlreadyStarted return ErrAlreadyStarted
default: default:
return nil, ErrUnknownState return ErrUnknownState
} }
// Activate the interface // Activate the interface
@@ -94,7 +92,7 @@ func (c *Control) Start() (func() error, error) {
c.cancel() c.cancel()
_ = c.f.Close() _ = c.f.Close()
c.state = StateStopped c.state = StateStopped
return nil, err return err
} }
// Call all the delayed funcs that waited patiently for the interface to be created. // Call all the delayed funcs that waited patiently for the interface to be created.
@@ -122,7 +120,7 @@ func (c *Control) Start() (func() error, error) {
// Start reading packets. // Start reading packets.
c.f.run() c.f.run()
c.state = StateStarted c.state = StateStarted
return c.Wait, nil return nil
} }
func (c *Control) State() RunState { func (c *Control) State() RunState {
+8 -10
View File
@@ -109,7 +109,7 @@ func TestControl_StopBeforeStart(t *testing.T) {
require.NoError(t, c.Wait()) require.NoError(t, c.Wait())
// A stopped control can never be started // A stopped control can never be started
_, err := c.Start() err := c.Start()
require.ErrorIs(t, err, ErrAlreadyStopped) require.ErrorIs(t, err, ErrAlreadyStopped)
// A second Stop is a harmless no-op // A second Stop is a harmless no-op
@@ -192,7 +192,7 @@ func TestControl_StartMultiqueueFailureReleases(t *testing.T) {
} }
// The second reader fails to open, everything must be released // The second reader fails to open, everything must be released
_, err := c.Start() err := c.Start()
require.Error(t, err) require.Error(t, err)
assert.Equal(t, StateStopped, c.State()) assert.Equal(t, StateStopped, c.State())
assert.True(t, dev.closed, "the tun device should have been closed") assert.True(t, dev.closed, "the tun device should have been closed")
@@ -250,7 +250,7 @@ func TestControl_ConcurrentStopAndStart(t *testing.T) {
for i := 0; i < 2; i++ { for i := 0; i < 2; i++ {
wg.Go(func() { c.Stop() }) wg.Go(func() { c.Stop() })
} }
wg.Go(func() { _, _ = c.Start() }) wg.Go(func() { _ = c.Start() })
wg.Go(func() { wg.Go(func() {
_ = c.Wait() _ = c.Wait()
// A returned Wait must always observe the final state, no matter how // A returned Wait must always observe the final state, no matter how
@@ -263,18 +263,17 @@ func TestControl_ConcurrentStopAndStart(t *testing.T) {
// panic and Wait must observe the final state // panic and Wait must observe the final state
require.NoError(t, c.Wait()) require.NoError(t, c.Wait())
assert.Equal(t, StateStopped, c.State()) assert.Equal(t, StateStopped, c.State())
_, err := c.Start() err := c.Start()
require.ErrorIs(t, err, ErrAlreadyStopped) require.ErrorIs(t, err, ErrAlreadyStopped)
} }
func TestControl_StartStopLifecycle(t *testing.T) { func TestControl_StartStopLifecycle(t *testing.T) {
c, dev, conn := newReadyControl(t) c, dev, conn := newReadyControl(t)
wait, err := c.Start() err := c.Start()
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, wait, "a successful Start must return a block function")
assert.Equal(t, StateStarted, c.State()) assert.Equal(t, StateStarted, c.State())
_, err = c.Start() err = c.Start()
require.ErrorIs(t, err, ErrAlreadyStarted) require.ErrorIs(t, err, ErrAlreadyStarted)
// Stop must unpark the reader blocked in the device and release everything // Stop must unpark the reader blocked in the device and release everything
@@ -286,7 +285,7 @@ func TestControl_StartStopLifecycle(t *testing.T) {
// The reader drained off a closed device, that is not a fatal error // The reader drained off a closed device, that is not a fatal error
require.NoError(t, c.Wait()) require.NoError(t, c.Wait())
_, err = c.Start() err = c.Start()
require.ErrorIs(t, err, ErrAlreadyStopped) require.ErrorIs(t, err, ErrAlreadyStopped)
} }
@@ -297,9 +296,8 @@ func TestControl_RebindIsGatedByState(t *testing.T) {
c.RebindUDPServer() c.RebindUDPServer()
assert.Equal(t, 0, conn.rebinds, "rebind before start must be a no-op") assert.Equal(t, 0, conn.rebinds, "rebind before start must be a no-op")
wait, err := c.Start() err := c.Start()
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, wait, "a successful Start must return a block function")
c.RebindUDPServer() c.RebindUDPServer()
assert.Equal(t, 1, conn.rebinds, "rebind while started must reach the conn") assert.Equal(t, 1, conn.rebinds, "rebind while started must reach the conn")
+2 -2
View File
@@ -50,7 +50,7 @@ func New(control *nebula.Control) (_ *Service, reterr error) {
return nil, errors.New("must be using user device") return nil, errors.New("must be using user device")
} }
wait, err := control.Start() err := control.Start()
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -155,7 +155,7 @@ func New(control *nebula.Control) (_ *Service, reterr error) {
// Add the nebula wait function to the group so a fatal reader error // Add the nebula wait function to the group so a fatal reader error
// propagates out through errgroup.Wait(). // propagates out through errgroup.Wait().
eg.Go(func() error { eg.Go(func() error {
return wait() return control.Wait()
}) })
return &s, nil return &s, nil