mirror of
https://github.com/wavetermdev/backup.git
synced 2026-04-22 15:26:58 -07:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d1bffb5a0d | |||
| df94b91e6c | |||
| 1547fc856e | |||
| 37821738d8 | |||
| 8e79eeccca | |||
| 203f1f7505 | |||
| 57a7641f82 | |||
| 03ea444030 |
@@ -50,6 +50,9 @@ import {
|
|||||||
HistoryViewDataType,
|
HistoryViewDataType,
|
||||||
AlertMessageType,
|
AlertMessageType,
|
||||||
HistorySearchParams,
|
HistorySearchParams,
|
||||||
|
UserInputRequest,
|
||||||
|
UserInputResponse,
|
||||||
|
UserInputResponsePacket,
|
||||||
FocusTypeStrs,
|
FocusTypeStrs,
|
||||||
ScreenLinesType,
|
ScreenLinesType,
|
||||||
HistoryTypeStrs,
|
HistoryTypeStrs,
|
||||||
@@ -4110,6 +4113,19 @@ class Model {
|
|||||||
update.screennumrunningcommands.num
|
update.screennumrunningcommands.num
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if ("userinputrequest" in update) {
|
||||||
|
let userInputRequest: UserInputRequest = update.userinputrequest;
|
||||||
|
let userInputResponse: UserInputResponse = {
|
||||||
|
type: "text",
|
||||||
|
text: "what wonderful weather we're having",
|
||||||
|
};
|
||||||
|
let userInputResponsePacket: UserInputResponsePacket = {
|
||||||
|
type: "userinputresp",
|
||||||
|
requestid: userInputRequest.requestid,
|
||||||
|
response: userInputResponse,
|
||||||
|
};
|
||||||
|
this.ws.pushMessage(userInputResponsePacket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateRemotes(remotes: RemoteType[]): void {
|
updateRemotes(remotes: RemoteType[]): void {
|
||||||
|
|||||||
@@ -328,6 +328,7 @@ type ModelUpdateType = {
|
|||||||
alertmessage?: AlertMessageType;
|
alertmessage?: AlertMessageType;
|
||||||
screenstatusindicator?: ScreenStatusIndicatorUpdateType;
|
screenstatusindicator?: ScreenStatusIndicatorUpdateType;
|
||||||
screennumrunningcommands?: ScreenNumRunningCommandsUpdateType;
|
screennumrunningcommands?: ScreenNumRunningCommandsUpdateType;
|
||||||
|
userinputrequest?: UserInputRequest;
|
||||||
};
|
};
|
||||||
|
|
||||||
type HistoryViewDataType = {
|
type HistoryViewDataType = {
|
||||||
@@ -586,6 +587,24 @@ type HistorySearchParams = {
|
|||||||
filterCmds?: boolean;
|
filterCmds?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type UserInputRequest = {
|
||||||
|
requestid: string;
|
||||||
|
querytext: string;
|
||||||
|
responsetype: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
type UserInputResponse = {
|
||||||
|
type: string;
|
||||||
|
text?: string;
|
||||||
|
confirm?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type UserInputResponsePacket = {
|
||||||
|
type: string;
|
||||||
|
requestid: string;
|
||||||
|
response: UserInputResponse;
|
||||||
|
};
|
||||||
|
|
||||||
type RenderModeType = "normal" | "collapsed" | "expanded";
|
type RenderModeType = "normal" | "collapsed" | "expanded";
|
||||||
|
|
||||||
type WebScreen = {
|
type WebScreen = {
|
||||||
@@ -771,6 +790,9 @@ export type {
|
|||||||
RenderModeType,
|
RenderModeType,
|
||||||
AlertMessageType,
|
AlertMessageType,
|
||||||
HistorySearchParams,
|
HistorySearchParams,
|
||||||
|
UserInputRequest,
|
||||||
|
UserInputResponse,
|
||||||
|
UserInputResponsePacket,
|
||||||
ScreenLinesType,
|
ScreenLinesType,
|
||||||
FocusTypeStrs,
|
FocusTypeStrs,
|
||||||
HistoryTypeStrs,
|
HistoryTypeStrs,
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ import (
|
|||||||
"golang.org/x/mod/semver"
|
"golang.org/x/mod/semver"
|
||||||
)
|
)
|
||||||
|
|
||||||
const UseSshLibrary = false
|
const UseSshLibrary = true
|
||||||
|
|
||||||
const RemoteTypeMShell = "mshell"
|
const RemoteTypeMShell = "mshell"
|
||||||
const DefaultTerm = "xterm-256color"
|
const DefaultTerm = "xterm-256color"
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ package remote
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -60,6 +61,14 @@ func ConnectToClient(opts *sstore.SSHOpts) (*ssh.Client, error) {
|
|||||||
identityFile = configIdentity
|
identityFile = configIdentity
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// test code
|
||||||
|
request := &sstore.UserInputRequestType{
|
||||||
|
ResponseType: "text",
|
||||||
|
QueryText: "unused",
|
||||||
|
}
|
||||||
|
response, _ := sstore.MainBus.GetUserInput(request)
|
||||||
|
log.Printf("response: %s\n", response.Text)
|
||||||
|
|
||||||
hostKeyCallback := ssh.InsecureIgnoreHostKey()
|
hostKeyCallback := ssh.InsecureIgnoreHostKey()
|
||||||
var authMethods []ssh.AuthMethod
|
var authMethods []ssh.AuthMethod
|
||||||
publicKeyAuth, err := createPublicKeyAuth(identityFile, opts.SSHPassword)
|
publicKeyAuth, err := createPublicKeyAuth(identityFile, opts.SSHPassword)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ const WatchScreenPacketStr = "watchscreen"
|
|||||||
const FeInputPacketStr = "feinput"
|
const FeInputPacketStr = "feinput"
|
||||||
const RemoteInputPacketStr = "remoteinput"
|
const RemoteInputPacketStr = "remoteinput"
|
||||||
const CmdInputTextPacketStr = "cmdinputtext"
|
const CmdInputTextPacketStr = "cmdinputtext"
|
||||||
|
const UserInputResponsePacketStr = "userinputresp"
|
||||||
|
|
||||||
type FeCommandPacketType struct {
|
type FeCommandPacketType struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
@@ -92,12 +93,19 @@ type CmdInputTextPacketType struct {
|
|||||||
Text utilfn.StrWithPos `json:"text"`
|
Text utilfn.StrWithPos `json:"text"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserInputResponsePacketType struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
RequestId string `json:"requestid"`
|
||||||
|
Response *sstore.UserInputResponseType `json:"response"`
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
packet.RegisterPacketType(FeCommandPacketStr, reflect.TypeOf(FeCommandPacketType{}))
|
packet.RegisterPacketType(FeCommandPacketStr, reflect.TypeOf(FeCommandPacketType{}))
|
||||||
packet.RegisterPacketType(WatchScreenPacketStr, reflect.TypeOf(WatchScreenPacketType{}))
|
packet.RegisterPacketType(WatchScreenPacketStr, reflect.TypeOf(WatchScreenPacketType{}))
|
||||||
packet.RegisterPacketType(FeInputPacketStr, reflect.TypeOf(FeInputPacketType{}))
|
packet.RegisterPacketType(FeInputPacketStr, reflect.TypeOf(FeInputPacketType{}))
|
||||||
packet.RegisterPacketType(RemoteInputPacketStr, reflect.TypeOf(RemoteInputPacketType{}))
|
packet.RegisterPacketType(RemoteInputPacketStr, reflect.TypeOf(RemoteInputPacketType{}))
|
||||||
packet.RegisterPacketType(CmdInputTextPacketStr, reflect.TypeOf(CmdInputTextPacketType{}))
|
packet.RegisterPacketType(CmdInputTextPacketStr, reflect.TypeOf(CmdInputTextPacketType{}))
|
||||||
|
packet.RegisterPacketType(UserInputResponsePacketStr, reflect.TypeOf(UserInputResponsePacketType{}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*CmdInputTextPacketType) GetType() string {
|
func (*CmdInputTextPacketType) GetType() string {
|
||||||
@@ -139,3 +147,7 @@ func MakeRemoteInputPacket() *RemoteInputPacketType {
|
|||||||
func (*RemoteInputPacketType) GetType() string {
|
func (*RemoteInputPacketType) GetType() string {
|
||||||
return RemoteInputPacketStr
|
return RemoteInputPacketStr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*UserInputResponsePacketType) GetType() string {
|
||||||
|
return UserInputResponsePacketStr
|
||||||
|
}
|
||||||
|
|||||||
@@ -278,6 +278,15 @@ func (ws *WSState) processMessage(msgBytes []byte) error {
|
|||||||
sstore.ScreenMemSetCmdInputText(cmdInputPk.ScreenId, cmdInputPk.Text, cmdInputPk.SeqNum)
|
sstore.ScreenMemSetCmdInputText(cmdInputPk.ScreenId, cmdInputPk.Text, cmdInputPk.SeqNum)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
if pk.GetType() == scpacket.UserInputResponsePacketStr {
|
||||||
|
userInputRespPk := pk.(*scpacket.UserInputResponsePacketType)
|
||||||
|
uich, ok := sstore.MainBus.UserInputCh[userInputRespPk.RequestId]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("received User Input Response with invalid Id (%s): %v\n", userInputRespPk.RequestId, err)
|
||||||
|
}
|
||||||
|
uich <- userInputRespPk.Response
|
||||||
|
return nil
|
||||||
|
}
|
||||||
return fmt.Errorf("got ws bad message: %v", pk.GetType())
|
return fmt.Errorf("got ws bad message: %v", pk.GetType())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,10 +4,13 @@
|
|||||||
package sstore
|
package sstore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/wavetermdev/waveterm/waveshell/pkg/packet"
|
"github.com/wavetermdev/waveterm/waveshell/pkg/packet"
|
||||||
"github.com/wavetermdev/waveterm/waveshell/pkg/utilfn"
|
"github.com/wavetermdev/waveterm/waveshell/pkg/utilfn"
|
||||||
)
|
)
|
||||||
@@ -39,32 +42,33 @@ func (*PtyDataUpdate) UpdateType() string {
|
|||||||
func (pdu *PtyDataUpdate) Clean() {}
|
func (pdu *PtyDataUpdate) Clean() {}
|
||||||
|
|
||||||
type ModelUpdate struct {
|
type ModelUpdate struct {
|
||||||
Sessions []*SessionType `json:"sessions,omitempty"`
|
Sessions []*SessionType `json:"sessions,omitempty"`
|
||||||
ActiveSessionId string `json:"activesessionid,omitempty"`
|
ActiveSessionId string `json:"activesessionid,omitempty"`
|
||||||
Screens []*ScreenType `json:"screens,omitempty"`
|
Screens []*ScreenType `json:"screens,omitempty"`
|
||||||
ScreenLines *ScreenLinesType `json:"screenlines,omitempty"`
|
ScreenLines *ScreenLinesType `json:"screenlines,omitempty"`
|
||||||
Line *LineType `json:"line,omitempty"`
|
Line *LineType `json:"line,omitempty"`
|
||||||
Lines []*LineType `json:"lines,omitempty"`
|
Lines []*LineType `json:"lines,omitempty"`
|
||||||
Cmd *CmdType `json:"cmd,omitempty"`
|
Cmd *CmdType `json:"cmd,omitempty"`
|
||||||
CmdLine *utilfn.StrWithPos `json:"cmdline,omitempty"`
|
CmdLine *utilfn.StrWithPos `json:"cmdline,omitempty"`
|
||||||
Info *InfoMsgType `json:"info,omitempty"`
|
Info *InfoMsgType `json:"info,omitempty"`
|
||||||
ClearInfo bool `json:"clearinfo,omitempty"`
|
ClearInfo bool `json:"clearinfo,omitempty"`
|
||||||
Remotes []RemoteRuntimeState `json:"remotes,omitempty"`
|
Remotes []RemoteRuntimeState `json:"remotes,omitempty"`
|
||||||
History *HistoryInfoType `json:"history,omitempty"`
|
History *HistoryInfoType `json:"history,omitempty"`
|
||||||
Interactive bool `json:"interactive"`
|
Interactive bool `json:"interactive"`
|
||||||
Connect bool `json:"connect,omitempty"`
|
Connect bool `json:"connect,omitempty"`
|
||||||
MainView string `json:"mainview,omitempty"`
|
MainView string `json:"mainview,omitempty"`
|
||||||
Bookmarks []*BookmarkType `json:"bookmarks,omitempty"`
|
Bookmarks []*BookmarkType `json:"bookmarks,omitempty"`
|
||||||
SelectedBookmark string `json:"selectedbookmark,omitempty"`
|
SelectedBookmark string `json:"selectedbookmark,omitempty"`
|
||||||
HistoryViewData *HistoryViewData `json:"historyviewdata,omitempty"`
|
HistoryViewData *HistoryViewData `json:"historyviewdata,omitempty"`
|
||||||
ClientData *ClientData `json:"clientdata,omitempty"`
|
ClientData *ClientData `json:"clientdata,omitempty"`
|
||||||
RemoteView *RemoteViewType `json:"remoteview,omitempty"`
|
RemoteView *RemoteViewType `json:"remoteview,omitempty"`
|
||||||
ScreenTombstones []*ScreenTombstoneType `json:"screentombstones,omitempty"`
|
ScreenTombstones []*ScreenTombstoneType `json:"screentombstones,omitempty"`
|
||||||
SessionTombstones []*SessionTombstoneType `json:"sessiontombstones,omitempty"`
|
SessionTombstones []*SessionTombstoneType `json:"sessiontombstones,omitempty"`
|
||||||
OpenAICmdInfoChat []*packet.OpenAICmdInfoChatMessage `json:"openaicmdinfochat,omitempty"`
|
OpenAICmdInfoChat []*packet.OpenAICmdInfoChatMessage `json:"openaicmdinfochat,omitempty"`
|
||||||
AlertMessage *AlertMessageType `json:"alertmessage,omitempty"`
|
AlertMessage *AlertMessageType `json:"alertmessage,omitempty"`
|
||||||
ScreenStatusIndicator *ScreenStatusIndicatorType `json:"screenstatusindicator,omitempty"`
|
ScreenStatusIndicator *ScreenStatusIndicatorType `json:"screenstatusindicator,omitempty"`
|
||||||
ScreenNumRunningCommands *ScreenNumRunningCommandsType `json:"screennumrunningcommands,omitempty"`
|
ScreenNumRunningCommands *ScreenNumRunningCommandsType `json:"screennumrunningcommands,omitempty"`
|
||||||
|
UserInputRequest *UserInputRequestType `json:"userinputrequest,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*ModelUpdate) UpdateType() string {
|
func (*ModelUpdate) UpdateType() string {
|
||||||
@@ -160,6 +164,18 @@ type HistoryInfoType struct {
|
|||||||
Show bool `json:"show"`
|
Show bool `json:"show"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UserInputRequestType struct {
|
||||||
|
RequestId string `json:"requestid"`
|
||||||
|
QueryText string `json:"querytext"`
|
||||||
|
ResponseType string `json:"responsetype"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserInputResponseType struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Text string `json:"text,omitempty"`
|
||||||
|
Confirm bool `json:"confirm,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
type UpdateChannel struct {
|
type UpdateChannel struct {
|
||||||
ScreenId string
|
ScreenId string
|
||||||
ClientId string
|
ClientId string
|
||||||
@@ -174,14 +190,16 @@ func (uch UpdateChannel) Match(screenId string) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UpdateBus struct {
|
type UpdateBus struct {
|
||||||
Lock *sync.Mutex
|
Lock *sync.Mutex
|
||||||
Channels map[string]UpdateChannel
|
Channels map[string]UpdateChannel
|
||||||
|
UserInputCh map[string](chan *UserInputResponseType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeUpdateBus() *UpdateBus {
|
func MakeUpdateBus() *UpdateBus {
|
||||||
return &UpdateBus{
|
return &UpdateBus{
|
||||||
Lock: &sync.Mutex{},
|
Lock: &sync.Mutex{},
|
||||||
Channels: make(map[string]UpdateChannel),
|
Channels: make(map[string]UpdateChannel),
|
||||||
|
UserInputCh: make(map[string](chan *UserInputResponseType)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -273,3 +291,46 @@ type ScreenNumRunningCommandsType struct {
|
|||||||
ScreenId string `json:"screenid"`
|
ScreenId string `json:"screenid"`
|
||||||
Num int `json:"num"`
|
Num int `json:"num"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (bus *UpdateBus) registerUserInputChannel() (string, chan *UserInputResponseType) {
|
||||||
|
bus.Lock.Lock()
|
||||||
|
defer bus.Lock.Unlock()
|
||||||
|
|
||||||
|
id := uuid.New().String()
|
||||||
|
uich := make(chan *UserInputResponseType)
|
||||||
|
|
||||||
|
bus.UserInputCh[id] = uich
|
||||||
|
return id, uich
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bus *UpdateBus) unregisterUserInputChannel(id string) {
|
||||||
|
bus.Lock.Lock()
|
||||||
|
defer bus.Lock.Unlock()
|
||||||
|
|
||||||
|
delete(bus.UserInputCh, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bus *UpdateBus) GetUserInput(userInputRequest *UserInputRequestType) (*UserInputResponseType, error) {
|
||||||
|
// create context for timeout
|
||||||
|
ctx, cancelFn := context.WithTimeout(context.Background(), 1*time.Minute)
|
||||||
|
defer cancelFn()
|
||||||
|
|
||||||
|
id, uich := bus.registerUserInputChannel()
|
||||||
|
|
||||||
|
userInputRequest.RequestId = id
|
||||||
|
update := &ModelUpdate{UserInputRequest: userInputRequest}
|
||||||
|
bus.SendUpdate(update)
|
||||||
|
|
||||||
|
var response *UserInputResponseType
|
||||||
|
var err error
|
||||||
|
// prepare to receive response
|
||||||
|
select {
|
||||||
|
case resp := <-uich:
|
||||||
|
response = resp
|
||||||
|
case <-ctx.Done():
|
||||||
|
err = fmt.Errorf("timed out waiting for user input")
|
||||||
|
}
|
||||||
|
|
||||||
|
bus.unregisterUserInputChannel(id)
|
||||||
|
return response, err
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user