use packet.ShellState, send aliases and functions as part of state

This commit is contained in:
sawka
2022-10-16 23:51:04 -07:00
parent c940c7b85b
commit fdc5a289a9
5 changed files with 87 additions and 75 deletions
+2 -3
View File
@@ -226,9 +226,8 @@ func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.U
runPacket := packet.MakeRunPacket()
runPacket.ReqId = uuid.New().String()
runPacket.CK = base.MakeCommandKey(ids.SessionId, cmdId)
runPacket.Cwd = ids.Remote.RemoteState.Cwd
runPacket.Env0 = ids.Remote.RemoteState.Env0
runPacket.EnvComplete = true
runPacket.State = ids.Remote.RemoteState
runPacket.StateComplete = true
runPacket.UsePty = true
runPacket.TermOpts = &packet.TermOpts{Rows: shexec.DefaultTermRows, Cols: shexec.DefaultTermCols, Term: remote.DefaultTerm, MaxPtySize: shexec.DefaultMaxPtySize}
if pk.UIContext != nil && pk.UIContext.TermOpts != nil {
+3 -2
View File
@@ -8,6 +8,7 @@ import (
"strings"
"github.com/google/uuid"
"github.com/scripthaus-dev/mshell/pkg/packet"
"github.com/scripthaus-dev/sh2-server/pkg/remote"
"github.com/scripthaus-dev/sh2-server/pkg/scpacket"
"github.com/scripthaus-dev/sh2-server/pkg/sstore"
@@ -33,7 +34,7 @@ type ResolvedRemote struct {
RemotePtr sstore.RemotePtrType
MShell *remote.MShellProc
RState remote.RemoteRuntimeState
RemoteState *sstore.RemoteState
RemoteState *packet.ShellState
RemoteCopy *sstore.RemoteType
}
@@ -471,7 +472,7 @@ func resolveRemoteFromPtr(ctx context.Context, rptr *sstore.RemotePtrType, sessi
}
// returns (remoteDisplayName, remoteptr, state, rstate, err)
func resolveRemote(ctx context.Context, fullRemoteRef string, sessionId string, windowId string) (string, *sstore.RemotePtrType, *sstore.RemoteState, *remote.RemoteRuntimeState, error) {
func resolveRemote(ctx context.Context, fullRemoteRef string, sessionId string, windowId string) (string, *sstore.RemotePtrType, *packet.ShellState, *remote.RemoteRuntimeState, error) {
if fullRemoteRef == "" {
return "", nil, nil, nil, nil
}
+29 -32
View File
@@ -36,8 +36,8 @@ const RemoteTermRows = 8
const RemoteTermCols = 80
const PtyReadBufSize = 100
const MShellVersion = "v0.1.0"
const MShellVersionConstraint = "^0.1"
const MShellVersion = "v0.2.0"
const MShellVersionConstraint = "^0.2"
const MShellServerCommandFmt = `
PATH=$PATH:~/.mshell;
@@ -98,26 +98,26 @@ type MShellProc struct {
}
type RemoteRuntimeState struct {
RemoteType string `json:"remotetype"`
RemoteId string `json:"remoteid"`
PhysicalId string `json:"physicalremoteid"`
RemoteAlias string `json:"remotealias,omitempty"`
RemoteCanonicalName string `json:"remotecanonicalname"`
RemoteVars map[string]string `json:"remotevars"`
Status string `json:"status"`
ErrorStr string `json:"errorstr,omitempty"`
InstallStatus string `json:"installstatus"`
InstallErrorStr string `json:"installerrorstr,omitempty"`
NeedsMShellUpgrade bool `json:"needsmshellupgrade,omitempty"`
DefaultState *sstore.RemoteState `json:"defaultstate"`
ConnectMode string `json:"connectmode"`
AutoInstall bool `json:"autoinstall"`
Archived bool `json:"archived,omitempty"`
RemoteIdx int64 `json:"remoteidx"`
UName string `json:"uname"`
MShellVersion string `json:"mshellversion"`
WaitingForPassword bool `json:"waitingforpassword,omitempty"`
Local bool `json:"local,omitempty"`
RemoteType string `json:"remotetype"`
RemoteId string `json:"remoteid"`
PhysicalId string `json:"physicalremoteid"`
RemoteAlias string `json:"remotealias,omitempty"`
RemoteCanonicalName string `json:"remotecanonicalname"`
RemoteVars map[string]string `json:"remotevars"`
Status string `json:"status"`
ErrorStr string `json:"errorstr,omitempty"`
InstallStatus string `json:"installstatus"`
InstallErrorStr string `json:"installerrorstr,omitempty"`
NeedsMShellUpgrade bool `json:"needsmshellupgrade,omitempty"`
DefaultState *packet.ShellState `json:"defaultstate"`
ConnectMode string `json:"connectmode"`
AutoInstall bool `json:"autoinstall"`
Archived bool `json:"archived,omitempty"`
RemoteIdx int64 `json:"remoteidx"`
UName string `json:"uname"`
MShellVersion string `json:"mshellversion"`
WaitingForPassword bool `json:"waitingforpassword,omitempty"`
Local bool `json:"local,omitempty"`
}
func (state RemoteRuntimeState) IsConnected() bool {
@@ -465,10 +465,7 @@ func (msh *MShellProc) GetRemoteRuntimeState() RemoteRuntimeState {
vars["color"] = msh.Remote.RemoteOpts.Color
}
if msh.ServerProc != nil && msh.ServerProc.InitPk != nil {
state.DefaultState = &sstore.RemoteState{
Cwd: msh.ServerProc.InitPk.Cwd,
Env0: msh.ServerProc.InitPk.Env0,
}
state.DefaultState = msh.ServerProc.InitPk.State
state.MShellVersion = msh.ServerProc.InitPk.Version
vars["home"] = msh.ServerProc.InitPk.HomeDir
vars["remoteuser"] = msh.ServerProc.InitPk.User
@@ -512,7 +509,7 @@ func GetAllRemoteRuntimeState() []RemoteRuntimeState {
return rtn
}
func GetDefaultRemoteStateById(remoteId string) (*sstore.RemoteState, error) {
func GetDefaultRemoteStateById(remoteId string) (*packet.ShellState, error) {
remote := GetRemoteById(remoteId)
if remote == nil {
return nil, fmt.Errorf("remote not found")
@@ -988,13 +985,13 @@ func (msh *MShellProc) IsConnected() bool {
return msh.Status == StatusConnected
}
func (msh *MShellProc) GetDefaultState() *sstore.RemoteState {
func (msh *MShellProc) GetDefaultState() *packet.ShellState {
msh.Lock.Lock()
defer msh.Lock.Unlock()
if msh.ServerProc == nil || msh.ServerProc.InitPk == nil {
return nil
}
return &sstore.RemoteState{Cwd: msh.ServerProc.InitPk.HomeDir, Env0: msh.ServerProc.InitPk.Env0}
return msh.ServerProc.InitPk.State
}
func replaceHomePath(pathStr string, homeDir string) string {
@@ -1060,7 +1057,7 @@ func makeTermOpts(runPk *packet.RunPacketType) sstore.TermOpts {
}
// returns (cmdtype, allow-updates-callback, err)
func RunCommand(ctx context.Context, cmdId string, remotePtr sstore.RemotePtrType, remoteState *sstore.RemoteState, runPacket *packet.RunPacketType) (*sstore.CmdType, func(), error) {
func RunCommand(ctx context.Context, cmdId string, remotePtr sstore.RemotePtrType, remoteState *packet.ShellState, runPacket *packet.RunPacketType) (*sstore.CmdType, func(), error) {
if remotePtr.OwnerId != "" {
return nil, nil, fmt.Errorf("cannot run command against another user's remote '%s'", remotePtr.MakeFullRemoteRef())
}
@@ -1332,7 +1329,7 @@ func isDigit(r rune) bool {
return r >= '0' && r <= '9' // just check ascii digits (not unicode)
}
func EvalPrompt(promptFmt string, vars map[string]string, state *sstore.RemoteState) string {
func EvalPrompt(promptFmt string, vars map[string]string, state *packet.ShellState) string {
var buf bytes.Buffer
promptRunes := []rune(promptFmt)
for i := 0; i < len(promptRunes); i++ {
@@ -1373,7 +1370,7 @@ func EvalPrompt(promptFmt string, vars map[string]string, state *sstore.RemoteSt
return buf.String()
}
func evalPromptEsc(escCode string, vars map[string]string, state *sstore.RemoteState) string {
func evalPromptEsc(escCode string, vars map[string]string, state *packet.ShellState) string {
if strings.HasPrefix(escCode, "x{") && strings.HasSuffix(escCode, "}") {
varName := escCode[2 : len(escCode)-1]
return vars[varName]
+18 -17
View File
@@ -300,9 +300,9 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) {
screen.Windows = append(screen.Windows, sw)
}
query = `SELECT * FROM remote_instance`
var ris []*RemoteInstance
tx.SelectWrap(&ris, query)
for _, ri := range ris {
riMaps := tx.SelectMaps(query)
for _, m := range riMaps {
ri := RIFromMap(m)
s := sessionMap[ri.SessionId]
if s != nil {
s.Remotes = append(s.Remotes, ri)
@@ -776,13 +776,13 @@ func DeleteScreen(ctx context.Context, sessionId string, screenId string) (Updat
return update, nil
}
func GetRemoteState(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType) (*RemoteState, error) {
var remoteState *RemoteState
func GetRemoteState(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType) (*packet.ShellState, error) {
var remoteState *packet.ShellState
txErr := WithTx(ctx, func(tx *TxWrap) error {
var ri RemoteInstance
query := `SELECT * FROM remote_instance WHERE sessionid = ? AND windowid = ? AND remoteownerid = ? AND remoteid = ? AND name = ?`
found := tx.GetWrap(&ri, query, sessionId, windowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name)
if found {
m := tx.GetMap(query, sessionId, windowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name)
ri := RIFromMap(m)
if ri != nil {
remoteState = &ri.State
return nil
}
@@ -807,20 +807,21 @@ func validateSessionWindow(tx *TxWrap, sessionId string, windowId string) error
}
}
func UpdateRemoteState(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType, state RemoteState) (*RemoteInstance, error) {
func UpdateRemoteState(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType, state packet.ShellState) (*RemoteInstance, error) {
if remotePtr.IsSessionScope() {
windowId = ""
}
var ri RemoteInstance
var ri *RemoteInstance
txErr := WithTx(ctx, func(tx *TxWrap) error {
err := validateSessionWindow(tx, sessionId, windowId)
if err != nil {
return fmt.Errorf("cannot update remote instance cwd: %w", err)
}
query := `SELECT * FROM remote_instance WHERE sessionid = ? AND windowid = ? AND remoteownerid = ? AND remoteid = ? AND name = ?`
found := tx.GetWrap(&ri, query, sessionId, windowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name)
if !found {
ri = RemoteInstance{
m := tx.GetMap(query, sessionId, windowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name)
ri = RIFromMap(m)
if ri == nil {
ri = &RemoteInstance{
RIId: scbase.GenSCUUID(),
Name: remotePtr.Name,
SessionId: sessionId,
@@ -831,15 +832,15 @@ func UpdateRemoteState(ctx context.Context, sessionId string, windowId string, r
}
query = `INSERT INTO remote_instance ( riid, name, sessionid, windowid, remoteownerid, remoteid, state)
VALUES (:riid,:name,:sessionid,:windowid,:remoteownerid,:remoteid,:state)`
tx.NamedExecWrap(query, ri)
tx.NamedExecWrap(query, ri.ToMap())
return nil
}
query = `UPDATE remote_instance SET state = ? WHERE sessionid = ? AND windowid = ? AND remoteownerid = ? AND remoteid = ? AND name = ?`
query = `UPDATE remote_instance SET state = ? WHERE riid = ?`
ri.State = state
tx.ExecWrap(query, ri.State, ri.SessionId, ri.WindowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name)
tx.ExecWrap(query, quickJson(ri.State), ri.RIId)
return nil
})
return &ri, txErr
return ri, txErr
}
func UpdateCurRemote(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType) error {
+35 -21
View File
@@ -440,19 +440,6 @@ type HistoryQueryOpts struct {
FromTs int64
}
type RemoteState struct {
Cwd string `json:"cwd"`
Env0 []byte `json:"env0"` // "env -0" format
}
func (s *RemoteState) Scan(val interface{}) error {
return quickScanJson(s, val)
}
func (s RemoteState) Value() (driver.Value, error) {
return quickValueJson(s)
}
type TermOpts struct {
Rows int64 `json:"rows"`
Cols int64 `json:"cols"`
@@ -469,18 +456,45 @@ func (opts TermOpts) Value() (driver.Value, error) {
}
type RemoteInstance struct {
RIId string `json:"riid"`
Name string `json:"name"`
SessionId string `json:"sessionid"`
WindowId string `json:"windowid"`
RemoteOwnerId string `json:"remoteownerid"`
RemoteId string `json:"remoteid"`
State RemoteState `json:"state"`
RIId string `json:"riid"`
Name string `json:"name"`
SessionId string `json:"sessionid"`
WindowId string `json:"windowid"`
RemoteOwnerId string `json:"remoteownerid"`
RemoteId string `json:"remoteid"`
State packet.ShellState `json:"state"`
// only for updates
Remove bool `json:"remove,omitempty"`
}
func (ri *RemoteInstance) ToMap() map[string]interface{} {
rtn := make(map[string]interface{})
rtn["riid"] = ri.RIId
rtn["name"] = ri.Name
rtn["sessionid"] = ri.SessionId
rtn["windowid"] = ri.WindowId
rtn["remoteownerid"] = ri.RemoteOwnerId
rtn["remoteid"] = ri.RemoteId
rtn["state"] = quickJson(ri.State)
return rtn
}
func RIFromMap(m map[string]interface{}) *RemoteInstance {
if len(m) == 0 {
return nil
}
var ri RemoteInstance
quickSetStr(&ri.RIId, m, "riid")
quickSetStr(&ri.Name, m, "name")
quickSetStr(&ri.SessionId, m, "sessionid")
quickSetStr(&ri.WindowId, m, "windowid")
quickSetStr(&ri.RemoteOwnerId, m, "remoteownerid")
quickSetStr(&ri.RemoteId, m, "remoteid")
quickSetJson(&ri.State, m, "state")
return &ri
}
type LineType struct {
SessionId string `json:"sessionid"`
WindowId string `json:"windowid"`
@@ -557,7 +571,7 @@ type CmdType struct {
CmdId string `json:"cmdid"`
Remote RemotePtrType `json:"remote"`
CmdStr string `json:"cmdstr"`
RemoteState RemoteState `json:"remotestate"`
RemoteState packet.ShellState `json:"remotestate"`
TermOpts TermOpts `json:"termopts"`
OrigTermOpts TermOpts `json:"origtermopts"`
Status string `json:"status"`