diff --git a/lxc/console.go b/lxc/console.go index 9e9b70f0524b..f46bdd3fbb8d 100644 --- a/lxc/console.go +++ b/lxc/console.go @@ -1,15 +1,18 @@ package main import ( + "context" "errors" "fmt" "io" "net" "os" "os/exec" + "os/signal" "runtime" "strconv" "sync" + "syscall" "github.com/gorilla/websocket" "github.com/spf13/cobra" @@ -237,6 +240,12 @@ func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error { var err error conf := c.global.conf + // Create a context that is canceled on signal reception. + // This is used to enable the function to execute any cleanup defer statements + // before exiting. + ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP) + defer stop() + // We currently use the control websocket just to abort in case of errors. controlDone := make(chan struct{}, 1) handler := func(control *websocket.Conn) { @@ -284,7 +293,8 @@ func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error { } // Listen on the socket. - listener, err = net.Listen("unix", path.Name()) + lc := net.ListenConfig{} + listener, err = lc.Listen(ctx, "unix", path.Name()) if err != nil { return err } @@ -320,6 +330,12 @@ func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error { return err } + // Cancel the operation if the context is canceled. + go func() { + <-ctx.Done() + _ = op.Cancel() + }() + // Handle connections to the socket. wgConnections := sync.WaitGroup{} chConnected := make(chan struct{}) @@ -405,4 +421,4 @@ func (c *cmdConsole) vga(d lxd.InstanceServer, name string) error { } return nil -} +} \ No newline at end of file