mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
redo ptybuffer, move to wshutil to help with stdin processing. change wsh to use cobra
This commit is contained in:
@@ -46,10 +46,8 @@ type BlockController struct {
|
||||
InputCh chan wshutil.BlockCommand
|
||||
Status string
|
||||
CreatedHtmlFile bool
|
||||
|
||||
PtyBuffer *PtyBuffer
|
||||
ShellProc *shellexec.ShellProc
|
||||
ShellInputCh chan *wshutil.BlockInputCommand
|
||||
ShellProc *shellexec.ShellProc
|
||||
ShellInputCh chan *wshutil.BlockInputCommand
|
||||
}
|
||||
|
||||
func (bc *BlockController) WithLock(f func()) {
|
||||
@@ -187,6 +185,17 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts) error {
|
||||
}
|
||||
shellInputCh := make(chan *wshutil.BlockInputCommand)
|
||||
bc.ShellInputCh = shellInputCh
|
||||
commandCh := make(chan wshutil.BlockCommand, 32)
|
||||
ptyBuffer := wshutil.MakePtyBuffer(bc.ShellProc.Pty, commandCh)
|
||||
go func() {
|
||||
for cmd := range commandCh {
|
||||
if strings.HasPrefix(cmd.GetCommand(), "controller:") {
|
||||
bc.InputCh <- cmd
|
||||
} else {
|
||||
ProcessStaticCommand(bc.BlockId, cmd)
|
||||
}
|
||||
}
|
||||
}()
|
||||
go func() {
|
||||
defer func() {
|
||||
// needs synchronization
|
||||
@@ -197,12 +206,11 @@ func (bc *BlockController) DoRunShellCommand(rc *RunShellOpts) error {
|
||||
}()
|
||||
buf := make([]byte, 4096)
|
||||
for {
|
||||
nr, err := bc.ShellProc.Pty.Read(buf)
|
||||
nr, err := ptyBuffer.Read(buf)
|
||||
if nr > 0 {
|
||||
bc.PtyBuffer.AppendData(buf[:nr])
|
||||
if bc.PtyBuffer.Err != nil {
|
||||
log.Printf("error processing pty data: %v\n", bc.PtyBuffer.Err)
|
||||
break
|
||||
err := handleAppendBlockFile(bc.BlockId, BlockFile_Main, buf[:nr])
|
||||
if err != nil {
|
||||
log.Printf("error appending to blockfile: %v\n", err)
|
||||
}
|
||||
}
|
||||
if err == io.EOF {
|
||||
@@ -303,17 +311,6 @@ func StartBlockController(ctx context.Context, blockId string) error {
|
||||
Status: "init",
|
||||
InputCh: make(chan wshutil.BlockCommand),
|
||||
}
|
||||
ptyBuffer := MakePtyBuffer(func(fileName string, data []byte) error {
|
||||
return handleAppendBlockFile(blockId, fileName, data)
|
||||
}, func(cmd wshutil.BlockCommand) error {
|
||||
if strings.HasPrefix(cmd.GetCommand(), "controller:") {
|
||||
bc.InputCh <- cmd
|
||||
} else {
|
||||
ProcessStaticCommand(blockId, cmd)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
bc.PtyBuffer = ptyBuffer
|
||||
blockControllerMap[blockId] = bc
|
||||
go bc.Run(blockData)
|
||||
return nil
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
// Copyright 2024, Command Line Inc.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package blockcontroller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/wavetermdev/thenextwave/pkg/wshutil"
|
||||
)
|
||||
|
||||
const (
|
||||
Mode_Normal = "normal"
|
||||
Mode_Esc = "esc"
|
||||
Mode_WaveEsc = "waveesc"
|
||||
)
|
||||
|
||||
type PtyBuffer struct {
|
||||
Mode string
|
||||
EscSeqBuf []byte
|
||||
DataOutputFn func(string, []byte) error
|
||||
CommandOutputFn func(wshutil.BlockCommand) error
|
||||
Err error
|
||||
}
|
||||
|
||||
func MakePtyBuffer(dataOutputFn func(string, []byte) error, commandOutputFn func(wshutil.BlockCommand) error) *PtyBuffer {
|
||||
return &PtyBuffer{
|
||||
Mode: Mode_Normal,
|
||||
DataOutputFn: dataOutputFn,
|
||||
CommandOutputFn: commandOutputFn,
|
||||
}
|
||||
}
|
||||
|
||||
func (b *PtyBuffer) setErr(err error) {
|
||||
if b.Err == nil {
|
||||
b.Err = err
|
||||
}
|
||||
}
|
||||
|
||||
func (b *PtyBuffer) processWaveEscSeq(escSeq []byte) {
|
||||
jmsg := make(map[string]any)
|
||||
err := json.Unmarshal(escSeq, &jmsg)
|
||||
if err != nil {
|
||||
b.setErr(fmt.Errorf("error unmarshalling Wave OSC sequence data: %w", err))
|
||||
return
|
||||
}
|
||||
cmd, err := wshutil.ParseCmdMap(jmsg)
|
||||
if err != nil {
|
||||
b.setErr(fmt.Errorf("error parsing Wave OSC command: %w", err))
|
||||
return
|
||||
}
|
||||
err = b.CommandOutputFn(cmd)
|
||||
if err != nil {
|
||||
b.setErr(fmt.Errorf("error processing Wave OSC command: %w", err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (b *PtyBuffer) AppendData(data []byte) {
|
||||
outputBuf := make([]byte, 0, len(data))
|
||||
for _, ch := range data {
|
||||
if b.Mode == Mode_WaveEsc {
|
||||
if ch == wshutil.ESC {
|
||||
// terminates the escape sequence (and the rest was invalid)
|
||||
b.Mode = Mode_Normal
|
||||
outputBuf = append(outputBuf, b.EscSeqBuf...)
|
||||
outputBuf = append(outputBuf, ch)
|
||||
b.EscSeqBuf = nil
|
||||
} else if ch == wshutil.BEL || ch == wshutil.ST {
|
||||
// terminates the escpae sequence (is a valid Wave OSC command)
|
||||
b.Mode = Mode_Normal
|
||||
waveEscSeq := b.EscSeqBuf[len(wshutil.WaveOSCPrefix):]
|
||||
b.EscSeqBuf = nil
|
||||
b.processWaveEscSeq(waveEscSeq)
|
||||
} else {
|
||||
b.EscSeqBuf = append(b.EscSeqBuf, ch)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if b.Mode == Mode_Esc {
|
||||
if ch == wshutil.ESC || ch == wshutil.BEL || ch == wshutil.ST {
|
||||
// these all terminate the escape sequence (invalid, not a Wave OSC)
|
||||
b.Mode = Mode_Normal
|
||||
outputBuf = append(outputBuf, b.EscSeqBuf...)
|
||||
outputBuf = append(outputBuf, ch)
|
||||
} else {
|
||||
if ch == wshutil.WaveOSCPrefixBytes[len(b.EscSeqBuf)] {
|
||||
// we're still building what could be a Wave OSC sequence
|
||||
b.EscSeqBuf = append(b.EscSeqBuf, ch)
|
||||
} else {
|
||||
// this is not a Wave OSC sequence, just an escape sequence
|
||||
b.Mode = Mode_Normal
|
||||
outputBuf = append(outputBuf, b.EscSeqBuf...)
|
||||
outputBuf = append(outputBuf, ch)
|
||||
continue
|
||||
}
|
||||
// check to see if we have a full Wave OSC prefix
|
||||
if len(b.EscSeqBuf) == len(wshutil.WaveOSCPrefixBytes) {
|
||||
b.Mode = Mode_WaveEsc
|
||||
}
|
||||
}
|
||||
continue
|
||||
}
|
||||
// Mode_Normal
|
||||
if ch == wshutil.ESC {
|
||||
b.Mode = Mode_Esc
|
||||
b.EscSeqBuf = []byte{ch}
|
||||
continue
|
||||
}
|
||||
outputBuf = append(outputBuf, ch)
|
||||
}
|
||||
if len(outputBuf) > 0 {
|
||||
err := b.DataOutputFn(BlockFile_Main, outputBuf)
|
||||
if err != nil {
|
||||
b.setErr(fmt.Errorf("error processing data output: %w", err))
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user