working on autoconnect

This commit is contained in:
sawka 2022-12-28 13:56:19 -08:00
parent 43689ac3f8
commit 16b808bb21
6 changed files with 50 additions and 13 deletions

View File

@ -35,8 +35,10 @@ const HttpWriteTimeout = 21 * time.Second
const HttpMaxHeaderBytes = 60000 const HttpMaxHeaderBytes = 60000
const HttpTimeoutDuration = 21 * time.Second const HttpTimeoutDuration = 21 * time.Second
const WebSocketServerAddr = "localhost:8081"
const MainServerAddr = "localhost:8080" const MainServerAddr = "localhost:8080"
const WebSocketServerAddr = "localhost:8081"
const MainServerDevAddr = "localhost:8090"
const WebSocketServerDevAddr = "localhost:8091"
const WSStateReconnectTime = 30 * time.Second const WSStateReconnectTime = 30 * time.Second
const WSStatePacketChSize = 20 const WSStatePacketChSize = 20

View File

@ -270,10 +270,16 @@ func resolveUiIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype i
} }
if rtype&R_RemoteConnected > 0 { if rtype&R_RemoteConnected > 0 {
if !rtn.Remote.RState.IsConnected() { if !rtn.Remote.RState.IsConnected() {
return rtn, fmt.Errorf("remote '%s' is not connected", rtn.Remote.DisplayName) err = rtn.Remote.MShell.TryAutoConnect()
if err != nil {
return rtn, fmt.Errorf("error trying to auto-connect remote %q", rtn.Remote.DisplayName)
}
}
if !rtn.Remote.RState.IsConnected() {
return rtn, fmt.Errorf("remote %q is not connected", rtn.Remote.DisplayName)
} }
if rtn.Remote.StatePtr == nil || rtn.Remote.FeState == nil { if rtn.Remote.StatePtr == nil || rtn.Remote.FeState == nil {
return rtn, fmt.Errorf("remote '%s' state is not available", rtn.Remote.DisplayName) return rtn, fmt.Errorf("remote %q state is not available", rtn.Remote.DisplayName)
} }
} }
return rtn, nil return rtn, nil

View File

@ -93,6 +93,7 @@ type MShellProc struct {
MakeClientCancelFn context.CancelFunc MakeClientCancelFn context.CancelFunc
StateMap map[string]*packet.ShellState // sha1->state StateMap map[string]*packet.ShellState // sha1->state
CurrentState string // sha1 CurrentState string // sha1
NumTryConnect int
// install // install
InstallStatus string InstallStatus string
@ -247,7 +248,7 @@ func LoadRemoteById(ctx context.Context, remoteId string) error {
defer GlobalStore.Lock.Unlock() defer GlobalStore.Lock.Unlock()
existingRemote := GlobalStore.Map[remoteId] existingRemote := GlobalStore.Map[remoteId]
if existingRemote != nil { if existingRemote != nil {
return fmt.Errorf("cannot add remote %d, already in global map", remoteId) return fmt.Errorf("cannot add remote %s, already in global map", remoteId)
} }
GlobalStore.Map[r.RemoteId] = msh GlobalStore.Map[r.RemoteId] = msh
if r.ConnectMode == sstore.ConnectModeStartup { if r.ConnectMode == sstore.ConnectModeStartup {
@ -1234,7 +1235,7 @@ func RunCommand(ctx context.Context, sessionId string, windowId string, remotePt
return nil, nil, fmt.Errorf("cannot run command while a stateful command is still running: %v", err) return nil, nil, fmt.Errorf("cannot run command while a stateful command is still running: %v", err)
} }
if line == nil { if line == nil {
return nil, nil, fmt.Errorf("cannot run command while a stateful command is still running %s", *existingPSC, windowId) return nil, nil, fmt.Errorf("cannot run command while a stateful command is still running %s", *existingPSC)
} }
return nil, nil, fmt.Errorf("cannot run command while a stateful command (linenum=%d) is still running", line.LineNum) return nil, nil, fmt.Errorf("cannot run command while a stateful command (linenum=%d) is still running", line.LineNum)
} }
@ -1821,3 +1822,26 @@ func (msh *MShellProc) getFeStateFromDiff(stateDiff *packet.ShellStateDiff) (*ss
return sstore.FeStateFromShellState(&newState), nil return sstore.FeStateFromShellState(&newState), nil
} }
} }
func (msh *MShellProc) TryAutoConnect() error {
if msh.IsConnected() {
return nil
}
rcopy := msh.GetRemoteCopy()
if !rcopy.AutoInstall {
return nil
}
var err error
msh.WithLock(func() {
if msh.NumTryConnect > 5 {
err = fmt.Errorf("cannot auto-connect remote %q (too many unsuccessful tries)", msh.Remote.GetName())
return
}
msh.NumTryConnect++
})
if err != nil {
return err
}
msh.Launch()
return nil
}

View File

@ -19,9 +19,11 @@ import (
const HomeVarName = "HOME" const HomeVarName = "HOME"
const PromptHomeVarName = "PROMPT_HOME" const PromptHomeVarName = "PROMPT_HOME"
const PromptDevVarName = "PROMPT_DEV"
const SessionsDirBaseName = "sessions" const SessionsDirBaseName = "sessions"
const PromptLockFile = "prompt.lock" const PromptLockFile = "prompt.lock"
const PromptDirName = "prompt" const PromptDirName = "prompt"
const PromptDevDirName = "prompt-dev"
const PromptAppPathVarName = "PROMPT_APP_PATH" const PromptAppPathVarName = "PROMPT_APP_PATH"
const PromptVersion = "v0.1.0" const PromptVersion = "v0.1.0"
const PromptAuthKeyFileName = "prompt.authkey" const PromptAuthKeyFileName = "prompt.authkey"
@ -37,7 +39,13 @@ func GetPromptHomeDir() string {
if homeVar == "" { if homeVar == "" {
homeVar = "/" homeVar = "/"
} }
scHome = path.Join(homeVar, PromptDirName) pdev := os.Getenv(PromptDevVarName)
if pdev != "" {
scHome = path.Join(homeVar, PromptDevDirName)
} else {
scHome = path.Join(homeVar, PromptDirName)
}
} }
return scHome return scHome
} }

View File

@ -208,7 +208,7 @@ func (ws *WSState) RunWSRead() {
err := ws.handleWatchScreen(wsPk) err := ws.handleWatchScreen(wsPk)
if err != nil { if err != nil {
// TODO send errors back to client, likely unrecoverable // TODO send errors back to client, likely unrecoverable
log.Printf("[ws %s] error %v\n", err) log.Printf("[ws %s] error %v\n", ws.ClientId, err)
} }
continue continue
} }
@ -264,7 +264,7 @@ func sendCmdInput(pk *scpacket.FeInputPacketType) error {
} }
msh := remote.GetRemoteById(pk.Remote.RemoteId) msh := remote.GetRemoteById(pk.Remote.RemoteId)
if msh == nil { if msh == nil {
return fmt.Errorf("remote %d not found", pk.Remote.RemoteId) return fmt.Errorf("remote %s not found", pk.Remote.RemoteId)
} }
if len(pk.InputData64) > 0 { if len(pk.InputData64) > 0 {
inputLen := packet.B64DecodedLen(pk.InputData64) inputLen := packet.B64DecodedLen(pk.InputData64)

View File

@ -886,7 +886,6 @@ func CleanWindows(sessionId string) {
} }
func ArchiveScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) { func ArchiveScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
var newActiveScreenId string
txErr := WithTx(ctx, func(tx *TxWrap) error { txErr := WithTx(ctx, func(tx *TxWrap) error {
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?` query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?`
if !tx.Exists(query, sessionId, screenId) { if !tx.Exists(query, sessionId, screenId) {
@ -909,7 +908,6 @@ func ArchiveScreen(ctx context.Context, sessionId string, screenId string) (Upda
screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT archived ORDER BY screenidx`, sessionId) screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT archived ORDER BY screenidx`, sessionId)
nextId := getNextId(screenIds, screenId) nextId := getNextId(screenIds, screenId)
tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId)
newActiveScreenId = nextId
} }
return nil return nil
}) })
@ -943,7 +941,6 @@ func UnArchiveScreen(ctx context.Context, sessionId string, screenId string) err
} }
func DeleteScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) { func DeleteScreen(ctx context.Context, sessionId string, screenId string) (UpdatePacket, error) {
var newActiveScreenId string
txErr := WithTx(ctx, func(tx *TxWrap) error { txErr := WithTx(ctx, func(tx *TxWrap) error {
query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?` query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?`
if !tx.Exists(query, sessionId, screenId) { if !tx.Exists(query, sessionId, screenId) {
@ -959,7 +956,6 @@ func DeleteScreen(ctx context.Context, sessionId string, screenId string) (Updat
screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT archived ORDER BY screenidx`, sessionId) screenIds := tx.SelectStrings(`SELECT screenid FROM screen WHERE sessionid = ? AND NOT archived ORDER BY screenidx`, sessionId)
nextId := getNextId(screenIds, screenId) nextId := getNextId(screenIds, screenId)
tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId) tx.ExecWrap(`UPDATE session SET activescreenid = ? WHERE sessionid = ?`, nextId, sessionId)
newActiveScreenId = nextId
} }
query = `DELETE FROM screen_window WHERE sessionid = ? AND screenid = ?` query = `DELETE FROM screen_window WHERE sessionid = ? AND screenid = ?`
tx.ExecWrap(query, sessionId, screenId) tx.ExecWrap(query, sessionId, screenId)
@ -976,7 +972,8 @@ func DeleteScreen(ctx context.Context, sessionId string, screenId string) (Updat
return nil, err return nil, err
} }
bareSession.Screens = append(bareSession.Screens, &ScreenType{SessionId: sessionId, ScreenId: screenId, Remove: true}) bareSession.Screens = append(bareSession.Screens, &ScreenType{SessionId: sessionId, ScreenId: screenId, Remove: true})
return ModelUpdate{Sessions: []*SessionType{bareSession}}, nil update := ModelUpdate{Sessions: []*SessionType{bareSession}}
return update, nil
} }
func GetRemoteState(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType) (*packet.ShellState, *ShellStatePtr, error) { func GetRemoteState(ctx context.Context, sessionId string, windowId string, remotePtr RemotePtrType) (*packet.ShellState, *ShellStatePtr, error) {