diff --git a/Makefile b/Makefile index da3b593..ebab51d 100644 --- a/Makefile +++ b/Makefile @@ -2,15 +2,26 @@ default: init +PROTOBUF_INSTALL_CMD = brew install protobuf + +ifeq ($(OS),Windows_NT) + PROTOBUF_INSTALL_CMD = choco install protoc +endif + +windows: + go mod tidy + go build -o main.exe cmd/main.go + init: - brew install protobuf + $(PROTOBUF_INSTALL_CMD) go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.62.0 go install golang.org/x/tools/go/analysis/passes/fieldalignment/cmd/fieldalignment@v0.27.0 go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.35.2 go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@v1.5.1 proto: - protoc --go_out=. --go-grpc_out=. */*.proto + protoc --go_out=. --go-grpc_out=. agent/agent.proto api/api.proto cluster/cluster.proto multipass/multipass.proto + linter: go mod tidy diff --git a/api/client.go b/api/client.go index 8e84a7f..b1cf523 100644 --- a/api/client.go +++ b/api/client.go @@ -7,8 +7,9 @@ import ( "log" "multiverse/common" "os" - "os/signal" - "syscall" + osSignal "os/signal" + + "github.com/moby/sys/signal" "golang.org/x/term" "google.golang.org/grpc" @@ -37,6 +38,7 @@ func (c *client) List(ctx context.Context) (*ListReply, error) { type shellRequestWriter struct { stream grpc.BidiStreamingClient[ShellRequest, ShellReply] + closed chan struct{} width int height int } @@ -50,25 +52,33 @@ func (s *shellRequestWriter) Write(p []byte) (n int, err error) { return len(p), nil } +func (s *shellRequestWriter) Clean() { + close(s.closed) +} + func NewShellRequestWriter( stream grpc.BidiStreamingClient[ShellRequest, ShellReply], width int, height int, stdOutFd int, -) (io.Writer, error) { - writer := &shellRequestWriter{width: width, height: height, stream: stream} - +) (*shellRequestWriter, error) { + writer := &shellRequestWriter{width: width, height: height, stream: stream, closed: make(chan struct{}, 1)} go func(writer *shellRequestWriter) { ch := make(chan os.Signal, 1) - signal.Notify(ch, syscall.SIGWINCH) - - for range ch { - if newWidth, newHeight, err := term.GetSize(stdOutFd); err == nil { - writer.width = newWidth - writer.height = newHeight - _, _ = writer.Write([]byte{}) + osSignal.Notify(ch, signal.SIGWINCH) + loop: + for { + select { + case <-ch: + if newWidth, newHeight, err := term.GetSize(stdOutFd); err == nil { + writer.width = newWidth + writer.height = newHeight + _, _ = writer.Write([]byte{}) + } + case <-writer.closed: + osSignal.Stop(ch) + break loop } } }(writer) - return writer, nil } @@ -106,6 +116,7 @@ func (c *client) Shell(ctx context.Context, nodeName string, instanceName string }(stdInFd, state) stdin, err := NewShellRequestWriter(stream, width, height, stdOutFd) + defer stdin.Clean() if err != nil { return err } diff --git a/go.mod b/go.mod index fffc3e0..08d0361 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ go 1.23 require ( github.com/google/uuid v1.6.0 github.com/jedib0t/go-pretty/v6 v6.6.2 + github.com/moby/sys/signal v0.7.1 golang.org/x/crypto v0.29.0 golang.org/x/term v0.26.0 google.golang.org/grpc v1.68.0 diff --git a/go.sum b/go.sum index 7c92c39..6d3192b 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/jedib0t/go-pretty/v6 v6.6.2 h1:27bLj3nRODzaiA7tPIxy9UVWHoPspFfME9Xxgw github.com/jedib0t/go-pretty/v6 v6.6.2/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E= github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/moby/sys/signal v0.7.1 h1:PrQxdvxcGijdo6UXXo/lU/TvHUWyPhj7UOpSo8tuvk0= +github.com/moby/sys/signal v0.7.1/go.mod h1:Se1VGehYokAkrSQwL4tDzHvETwUZlnY7S5XtQ50mQp8= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=