zsh reinit fixes (#477)

* reset command now initiates and completes async so there is feedback that something is happening when it takes a long time

* switch from standard rpc to rpciter

* checkpoint on reinit -- stream output, stats packet, logging to cmd pty, new endBytes for EOF

* make generic versions of endbytes scanner and channel output funcs

* update bash to use more modern state parsing (tricks learned from zsh)

* verbose mode, fix stats output message

* add a diff when verbose mode is on
This commit is contained in:
Mike Sawka
2024-03-19 16:38:38 -07:00
committed by GitHub
parent accb74ae0f
commit 5616c9abbb
11 changed files with 427 additions and 170 deletions
+16 -25
View File
@@ -7,7 +7,6 @@ import (
"bytes"
"context"
"encoding/base64"
"errors"
"fmt"
"io"
"os"
@@ -89,13 +88,14 @@ func MakeInstallCommandStr() string {
type MShellBinaryReaderFn func(version string, goos string, goarch string) (io.ReadCloser, error)
type ReturnStateBuf struct {
Lock *sync.Mutex
Buf []byte
Done bool
Err error
Reader *os.File
FdNum int
DoneCh chan bool
Lock *sync.Mutex
Buf []byte
Done bool
Err error
Reader *os.File
FdNum int
EndBytes []byte
DoneCh chan bool
}
func MakeReturnStateBuf() *ReturnStateBuf {
@@ -835,7 +835,8 @@ func RunCommandSimple(pk *packet.RunPacketType, sender *packet.PacketSender, fro
cmd.ReturnState.FdNum = RtnStateFdNum
rtnStateWriter = pw
defer pw.Close()
trapCmdStr := sapi.MakeExitTrap(cmd.ReturnState.FdNum)
trapCmdStr, endBytes := sapi.MakeExitTrap(cmd.ReturnState.FdNum)
cmd.ReturnState.EndBytes = endBytes
rcFileStr += trapCmdStr
}
shellVarMap := shellenv.ShellVarMapFromState(state)
@@ -1021,6 +1022,11 @@ func (rs *ReturnStateBuf) Run() {
}
rs.Lock.Lock()
rs.Buf = append(rs.Buf, buf[0:n]...)
if bytes.HasSuffix(rs.Buf, rs.EndBytes) {
rs.Buf = rs.Buf[:len(rs.Buf)-len(rs.EndBytes)]
rs.Lock.Unlock()
break
}
rs.Lock.Unlock()
}
}
@@ -1127,7 +1133,7 @@ func (c *ShExecType) WaitForCommand() *packet.CmdDonePacketType {
wlog.Logf("debug returnstate file %q\n", base.GetDebugReturnStateFileName())
os.WriteFile(base.GetDebugReturnStateFileName(), c.ReturnState.Buf, 0666)
}
state, _ := c.SAPI.ParseShellStateOutput(c.ReturnState.Buf) // TODO what to do with error?
state, _, _ := c.SAPI.ParseShellStateOutput(c.ReturnState.Buf) // TODO what to do with error?
donePacket.FinalState = state
}
endTs := time.Now()
@@ -1156,21 +1162,6 @@ func MakeInitPacket() *packet.InitPacketType {
return initPacket
}
func MakeShellStatePacket(shellType string) (*packet.ShellStatePacketType, error) {
sapi, err := shellapi.MakeShellApi(shellType)
if err != nil {
return nil, err
}
rtnCh := sapi.GetShellState()
ssOutput := <-rtnCh
if ssOutput.Error != "" {
return nil, errors.New(ssOutput.Error)
}
rtn := packet.MakeShellStatePacket()
rtn.State = ssOutput.ShellState
return rtn, nil
}
func MakeServerInitPacket() (*packet.InitPacketType, error) {
var err error
initPacket := MakeInitPacket()