mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
use packet.ShellState, send aliases and functions as part of state
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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"`
|
||||
|
||||
Reference in New Issue
Block a user