mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-22 21:42:49 +01:00
working with new static commands
This commit is contained in:
parent
fdc5a289a9
commit
e55f7fb4fe
@ -247,43 +247,12 @@ func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.U
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
rtnLine, err := sstore.AddCmdLine(ctx, ids.SessionId, ids.WindowId, DefaultUserId, cmd)
|
update, err := addLineForCmd(ctx, "/run", true, ids, cmd)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
sw, err := sstore.GetScreenWindowByIds(ctx, ids.SessionId, ids.ScreenId, ids.WindowId)
|
update.Interactive = pk.Interactive
|
||||||
if err != nil {
|
|
||||||
// ignore error here, because the command has already run (nothing to do)
|
|
||||||
fmt.Printf("/run error getting screen-window: %v\n", err)
|
|
||||||
}
|
|
||||||
if sw != nil {
|
|
||||||
updateMap := make(map[string]interface{})
|
|
||||||
updateMap[sstore.SWField_SelectedLine] = rtnLine.LineNum
|
|
||||||
updateMap[sstore.SWField_Focus] = sstore.SWFocusCmdFg
|
|
||||||
sw, err = sstore.UpdateScreenWindow(ctx, ids.SessionId, ids.ScreenId, ids.WindowId, updateMap)
|
|
||||||
if err != nil {
|
|
||||||
// ignore error again (nothing to do)
|
|
||||||
fmt.Printf("/run error updating screen-window selected line: %v\n", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update := sstore.ModelUpdate{
|
|
||||||
Line: rtnLine,
|
|
||||||
Cmd: cmd,
|
|
||||||
ScreenWindows: []*sstore.ScreenWindowType{sw},
|
|
||||||
Interactive: pk.Interactive,
|
|
||||||
}
|
|
||||||
sstore.MainBus.SendUpdate(ids.SessionId, update)
|
sstore.MainBus.SendUpdate(ids.SessionId, update)
|
||||||
ctxVal := ctx.Value(historyContextKey)
|
|
||||||
if ctxVal != nil {
|
|
||||||
hctx := ctxVal.(*historyContextType)
|
|
||||||
if rtnLine != nil {
|
|
||||||
hctx.LineId = rtnLine.LineId
|
|
||||||
}
|
|
||||||
if cmd != nil {
|
|
||||||
hctx.CmdId = cmd.CmdId
|
|
||||||
hctx.RemotePtr = &cmd.Remote
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,19 +489,27 @@ func UnSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore
|
|||||||
delete(envMap, argStr)
|
delete(envMap, argStr)
|
||||||
unsetVars[argStr] = true
|
unsetVars[argStr] = true
|
||||||
}
|
}
|
||||||
|
if len(unsetVars) == 0 {
|
||||||
|
return nil, fmt.Errorf("no variables provided to unset")
|
||||||
|
}
|
||||||
state := *ids.Remote.RemoteState
|
state := *ids.Remote.RemoteState
|
||||||
state.Env0 = shexec.MakeEnv0(envMap)
|
state.Env0 = shexec.MakeEnv0(envMap)
|
||||||
remote, err := sstore.UpdateRemoteState(ctx, ids.SessionId, ids.WindowId, ids.Remote.RemotePtr, state)
|
remoteInst, err := sstore.UpdateRemoteState(ctx, ids.SessionId, ids.WindowId, ids.Remote.RemotePtr, state)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
update := sstore.ModelUpdate{
|
var cmdOutput bytes.Buffer
|
||||||
Sessions: sstore.MakeSessionsUpdateForRemote(ids.SessionId, remote),
|
for varName, _ := range unsetVars {
|
||||||
Info: &sstore.InfoMsgType{
|
cmdOutput.WriteString(fmt.Sprintf("unset %s\r\n", shellescape.Quote(varName)))
|
||||||
InfoMsg: fmt.Sprintf("[%s] unset vars: %s", ids.Remote.DisplayName, formatStrs(mapToStrs(unsetVars), "and", false)),
|
|
||||||
TimeoutMs: 2000,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
cmd, err := makeStaticCmd(ctx, "unset", ids, pk.GetRawStr(), cmdOutput.Bytes())
|
||||||
|
update, err := addLineForCmd(ctx, "/unset", false, ids, cmd)
|
||||||
|
if err != nil {
|
||||||
|
// TODO tricky error since the command was a success, but we can't show the output
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
update.Interactive = pk.Interactive
|
||||||
|
update.Sessions = sstore.MakeSessionsUpdateForRemote(ids.SessionId, remoteInst)
|
||||||
return update, nil
|
return update, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1043,16 +1020,101 @@ func CdCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
update := sstore.ModelUpdate{
|
cmdOutput := fmt.Sprintf("cwd = %s", shellescape.Quote(newDir))
|
||||||
Sessions: sstore.MakeSessionsUpdateForRemote(ids.SessionId, remoteInst),
|
cmd, err := makeStaticCmd(ctx, "cd", ids, pk.GetRawStr(), []byte(cmdOutput))
|
||||||
Info: &sstore.InfoMsgType{
|
if err != nil {
|
||||||
InfoMsg: fmt.Sprintf("[%s] current directory = %s", ids.Remote.DisplayName, newDir),
|
// TODO tricky error since the command was a success, but we can't show the output
|
||||||
TimeoutMs: 2000,
|
return nil, err
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
update, err := addLineForCmd(ctx, "/cd", false, ids, cmd)
|
||||||
|
if err != nil {
|
||||||
|
// TODO tricky error since the command was a success, but we can't show the output
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
update.Interactive = pk.Interactive
|
||||||
|
update.Sessions = sstore.MakeSessionsUpdateForRemote(ids.SessionId, remoteInst)
|
||||||
|
//update.Info = &sstore.InfoMsgType{
|
||||||
|
// InfoMsg: fmt.Sprintf("[%s] current directory = %s", ids.Remote.DisplayName, newDir),
|
||||||
|
// TimeoutMs: 2000,
|
||||||
|
//}
|
||||||
return update, nil
|
return update, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeStaticCmd(ctx context.Context, metaCmd string, ids resolvedIds, cmdStr string, cmdOutput []byte) (*sstore.CmdType, error) {
|
||||||
|
cmd := &sstore.CmdType{
|
||||||
|
SessionId: ids.SessionId,
|
||||||
|
CmdId: scbase.GenSCUUID(),
|
||||||
|
CmdStr: cmdStr,
|
||||||
|
Remote: ids.Remote.RemotePtr,
|
||||||
|
TermOpts: sstore.TermOpts{Rows: shexec.DefaultTermRows, Cols: shexec.DefaultTermCols, FlexRows: true, MaxPtySize: remote.DefaultMaxPtySize},
|
||||||
|
Status: sstore.CmdStatusDone,
|
||||||
|
StartPk: nil,
|
||||||
|
DonePk: nil,
|
||||||
|
RunOut: nil,
|
||||||
|
}
|
||||||
|
if ids.Remote.RemoteState != nil {
|
||||||
|
cmd.RemoteState = *ids.Remote.RemoteState
|
||||||
|
}
|
||||||
|
err := sstore.CreateCmdPtyFile(ctx, cmd.SessionId, cmd.CmdId, cmd.TermOpts.MaxPtySize)
|
||||||
|
if err != nil {
|
||||||
|
// TODO tricky error since the command was a success, but we can't show the output
|
||||||
|
return nil, fmt.Errorf("cannot create local ptyout file for %s command: %w", metaCmd, err)
|
||||||
|
}
|
||||||
|
// can ignore ptyupdate
|
||||||
|
_, err = sstore.AppendToCmdPtyBlob(ctx, cmd.SessionId, cmd.CmdId, cmdOutput, 0)
|
||||||
|
if err != nil {
|
||||||
|
// TODO tricky error since the command was a success, but we can't show the output
|
||||||
|
return nil, fmt.Errorf("cannot append to local ptyout file for %s command: %v", metaCmd, err)
|
||||||
|
}
|
||||||
|
return cmd, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func addLineForCmd(ctx context.Context, metaCmd string, shouldFocus bool, ids resolvedIds, cmd *sstore.CmdType) (*sstore.ModelUpdate, error) {
|
||||||
|
rtnLine, err := sstore.AddCmdLine(ctx, ids.SessionId, ids.WindowId, DefaultUserId, cmd)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sw, err := sstore.GetScreenWindowByIds(ctx, ids.SessionId, ids.ScreenId, ids.WindowId)
|
||||||
|
if err != nil {
|
||||||
|
// ignore error here, because the command has already run (nothing to do)
|
||||||
|
fmt.Printf("%s error getting screen-window: %v\n", metaCmd, err)
|
||||||
|
}
|
||||||
|
if sw != nil {
|
||||||
|
updateMap := make(map[string]interface{})
|
||||||
|
updateMap[sstore.SWField_SelectedLine] = rtnLine.LineNum
|
||||||
|
if shouldFocus {
|
||||||
|
updateMap[sstore.SWField_Focus] = sstore.SWFocusCmdFg
|
||||||
|
}
|
||||||
|
sw, err = sstore.UpdateScreenWindow(ctx, ids.SessionId, ids.ScreenId, ids.WindowId, updateMap)
|
||||||
|
if err != nil {
|
||||||
|
// ignore error again (nothing to do)
|
||||||
|
fmt.Printf("%s error updating screen-window selected line: %v\n", metaCmd, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update := &sstore.ModelUpdate{
|
||||||
|
Line: rtnLine,
|
||||||
|
Cmd: cmd,
|
||||||
|
ScreenWindows: []*sstore.ScreenWindowType{sw},
|
||||||
|
}
|
||||||
|
updateHistoryContext(ctx, rtnLine, cmd)
|
||||||
|
return update, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateHistoryContext(ctx context.Context, line *sstore.LineType, cmd *sstore.CmdType) {
|
||||||
|
ctxVal := ctx.Value(historyContextKey)
|
||||||
|
if ctxVal == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
hctx := ctxVal.(*historyContextType)
|
||||||
|
if line != nil {
|
||||||
|
hctx.LineId = line.LineId
|
||||||
|
}
|
||||||
|
if cmd != nil {
|
||||||
|
hctx.CmdId = cmd.CmdId
|
||||||
|
hctx.RemotePtr = &cmd.Remote
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getStrArr(v interface{}, field string) []string {
|
func getStrArr(v interface{}, field string) []string {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return nil
|
return nil
|
||||||
|
@ -164,6 +164,7 @@ func EvalMetaCommand(ctx context.Context, origPk *scpacket.FeCommandPacketType)
|
|||||||
rtnPk.MetaSubCmd = metaSubCmd
|
rtnPk.MetaSubCmd = metaSubCmd
|
||||||
rtnPk.Kwargs = make(map[string]string)
|
rtnPk.Kwargs = make(map[string]string)
|
||||||
rtnPk.UIContext = origPk.UIContext
|
rtnPk.UIContext = origPk.UIContext
|
||||||
|
rtnPk.RawStr = origPk.RawStr
|
||||||
for key, val := range origPk.Kwargs {
|
for key, val := range origPk.Kwargs {
|
||||||
rtnPk.Kwargs[key] = val
|
rtnPk.Kwargs[key] = val
|
||||||
}
|
}
|
||||||
|
@ -927,14 +927,14 @@ func (msh *MShellProc) Launch() {
|
|||||||
msh.MakeClientCancelFn = makeClientCancelFn
|
msh.MakeClientCancelFn = makeClientCancelFn
|
||||||
go msh.NotifyRemoteUpdate()
|
go msh.NotifyRemoteUpdate()
|
||||||
})
|
})
|
||||||
cproc, uname, err := shexec.MakeClientProc(makeClientCtx, ecmd)
|
cproc, initPk, err := shexec.MakeClientProc(makeClientCtx, ecmd)
|
||||||
var mshellVersion string
|
var mshellVersion string
|
||||||
msh.WithLock(func() {
|
msh.WithLock(func() {
|
||||||
msh.UName = uname
|
|
||||||
msh.MakeClientCancelFn = nil
|
msh.MakeClientCancelFn = nil
|
||||||
if cproc != nil && cproc.InitPk != nil {
|
if initPk != nil {
|
||||||
msh.Remote.InitPk = cproc.InitPk
|
msh.Remote.InitPk = initPk
|
||||||
mshellVersion = cproc.InitPk.Version
|
msh.UName = initPk.UName
|
||||||
|
mshellVersion = initPk.Version
|
||||||
if semver.Compare(mshellVersion, MShellVersion) < 0 {
|
if semver.Compare(mshellVersion, MShellVersion) < 0 {
|
||||||
// only set NeedsMShellUpgrade if we got an InitPk
|
// only set NeedsMShellUpgrade if we got an InitPk
|
||||||
msh.NeedsMShellUpgrade = true
|
msh.NeedsMShellUpgrade = true
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package scpacket
|
package scpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/alessio/shellescape"
|
||||||
"github.com/scripthaus-dev/mshell/pkg/base"
|
"github.com/scripthaus-dev/mshell/pkg/base"
|
||||||
"github.com/scripthaus-dev/mshell/pkg/packet"
|
"github.com/scripthaus-dev/mshell/pkg/packet"
|
||||||
"github.com/scripthaus-dev/sh2-server/pkg/sstore"
|
"github.com/scripthaus-dev/sh2-server/pkg/sstore"
|
||||||
@ -19,10 +22,33 @@ type FeCommandPacketType struct {
|
|||||||
MetaSubCmd string `json:"metasubcmd,omitempty"`
|
MetaSubCmd string `json:"metasubcmd,omitempty"`
|
||||||
Args []string `json:"args,omitempty"`
|
Args []string `json:"args,omitempty"`
|
||||||
Kwargs map[string]string `json:"kwargs,omitempty"`
|
Kwargs map[string]string `json:"kwargs,omitempty"`
|
||||||
|
RawStr string `json:"rawstr,omitempty"`
|
||||||
UIContext *UIContextType `json:"uicontext,omitempty"`
|
UIContext *UIContextType `json:"uicontext,omitempty"`
|
||||||
Interactive bool `json:"interactive"`
|
Interactive bool `json:"interactive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (pk *FeCommandPacketType) GetRawStr() string {
|
||||||
|
if pk.RawStr != "" {
|
||||||
|
return pk.RawStr
|
||||||
|
}
|
||||||
|
cmd := "/" + pk.MetaCmd
|
||||||
|
if pk.MetaSubCmd != "" {
|
||||||
|
cmd = cmd + ":" + pk.MetaSubCmd
|
||||||
|
}
|
||||||
|
var args []string
|
||||||
|
for k, v := range pk.Kwargs {
|
||||||
|
argStr := fmt.Sprintf("%s=%s", shellescape.Quote(k), shellescape.Quote(v))
|
||||||
|
args = append(args, argStr)
|
||||||
|
}
|
||||||
|
for _, arg := range pk.Args {
|
||||||
|
args = append(args, shellescape.Quote(arg))
|
||||||
|
}
|
||||||
|
if len(args) == 0 {
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
return cmd + " " + strings.Join(args, " ")
|
||||||
|
}
|
||||||
|
|
||||||
type UIContextType struct {
|
type UIContextType struct {
|
||||||
SessionId string `json:"sessionid"`
|
SessionId string `json:"sessionid"`
|
||||||
ScreenId string `json:"screenid"`
|
ScreenId string `json:"screenid"`
|
||||||
|
Loading…
Reference in New Issue
Block a user