mirror of
https://github.com/wavetermdev/waveterm.git
synced 2024-12-22 16:48:23 +01:00
remote archiving, bug fixes
This commit is contained in:
parent
cde8bed381
commit
6f71866663
@ -43,6 +43,16 @@ var genericNameRe = regexp.MustCompile("^[a-zA-Z][a-zA-Z0-9_ .()<>,/\"'\\[\\]{}=
|
||||
var positionRe = regexp.MustCompile("^((\\+|-)?[0-9]+|(\\+|-))$")
|
||||
var wsRe = regexp.MustCompile("\\s+")
|
||||
|
||||
type contextType string
|
||||
|
||||
var historyContextKey = contextType("history")
|
||||
|
||||
type historyContextType struct {
|
||||
LineId string
|
||||
CmdId string
|
||||
RemotePtr *sstore.RemotePtrType
|
||||
}
|
||||
|
||||
type MetaCmdFnType = func(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error)
|
||||
type MetaCmdEntryType struct {
|
||||
IsAlias bool
|
||||
@ -66,6 +76,7 @@ func init() {
|
||||
registerCmdFn("session:open", SessionOpenCommand)
|
||||
registerCmdAlias("session:new", SessionOpenCommand)
|
||||
registerCmdFn("session:set", SessionSetCommand)
|
||||
registerCmdFn("session:delete", SessionDeleteCommand)
|
||||
|
||||
registerCmdFn("screen", ScreenCommand)
|
||||
registerCmdFn("screen:close", ScreenCloseCommand)
|
||||
@ -77,11 +88,16 @@ func init() {
|
||||
registerCmdFn("remote:show", RemoteShowCommand)
|
||||
registerCmdFn("remote:showall", RemoteShowAllCommand)
|
||||
registerCmdFn("remote:new", RemoteNewCommand)
|
||||
registerCmdFn("remote:archive", RemoteArchiveCommand)
|
||||
registerCmdFn("remote:set", RemoteSetCommand)
|
||||
registerCmdFn("remote:disconnect", RemoteDisconnectCommand)
|
||||
registerCmdFn("remote:connect", RemoteConnectCommand)
|
||||
|
||||
registerCmdFn("window:resize", WindowResizeCommand)
|
||||
|
||||
registerCmdFn("line", LineCommand)
|
||||
registerCmdFn("line:show", LineShowCommand)
|
||||
|
||||
registerCmdFn("history", HistoryCommand)
|
||||
}
|
||||
|
||||
@ -195,16 +211,26 @@ func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.U
|
||||
}
|
||||
update := sstore.ModelUpdate{Line: rtnLine, Cmd: cmd, Interactive: pk.Interactive}
|
||||
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
|
||||
}
|
||||
|
||||
func addToHistory(ctx context.Context, pk *scpacket.FeCommandPacketType, update sstore.UpdatePacket, isMetaCmd bool, hadError bool) error {
|
||||
func addToHistory(ctx context.Context, pk *scpacket.FeCommandPacketType, historyContext historyContextType, isMetaCmd bool, hadError bool) error {
|
||||
cmdStr := firstArg(pk)
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lineId, cmdId, rptr := sstore.ReadHistoryDataFromUpdate(update)
|
||||
hitem := &sstore.HistoryItemType{
|
||||
HistoryId: uuid.New().String(),
|
||||
Ts: time.Now().UnixMilli(),
|
||||
@ -212,14 +238,14 @@ func addToHistory(ctx context.Context, pk *scpacket.FeCommandPacketType, update
|
||||
SessionId: ids.SessionId,
|
||||
ScreenId: ids.ScreenId,
|
||||
WindowId: ids.WindowId,
|
||||
LineId: lineId,
|
||||
LineId: historyContext.LineId,
|
||||
HadError: hadError,
|
||||
CmdId: cmdId,
|
||||
CmdId: historyContext.CmdId,
|
||||
CmdStr: cmdStr,
|
||||
IsMetaCmd: isMetaCmd,
|
||||
}
|
||||
if !isMetaCmd && rptr != nil {
|
||||
hitem.Remote = ids.Remote.RemotePtr
|
||||
if !isMetaCmd && historyContext.RemotePtr != nil {
|
||||
hitem.Remote = *historyContext.RemotePtr
|
||||
}
|
||||
err = sstore.InsertHistoryItem(ctx, hitem)
|
||||
if err != nil {
|
||||
@ -232,13 +258,15 @@ func EvalCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.
|
||||
if len(pk.Args) == 0 {
|
||||
return nil, fmt.Errorf("usage: /eval [command], no command passed to eval")
|
||||
}
|
||||
var historyContext historyContextType
|
||||
ctxWithHistory := context.WithValue(ctx, historyContextKey, &historyContext)
|
||||
var update sstore.UpdatePacket
|
||||
newPk, rtnErr := EvalMetaCommand(ctx, pk)
|
||||
newPk, rtnErr := EvalMetaCommand(ctxWithHistory, pk)
|
||||
if rtnErr == nil {
|
||||
update, rtnErr = HandleCommand(ctx, newPk)
|
||||
update, rtnErr = HandleCommand(ctxWithHistory, newPk)
|
||||
}
|
||||
if !resolveBool(pk.Kwargs["nohist"], false) {
|
||||
err := addToHistory(ctx, pk, update, (newPk.MetaCmd != "run"), (rtnErr != nil))
|
||||
err := addToHistory(ctx, pk, historyContext, (newPk.MetaCmd != "run"), (rtnErr != nil))
|
||||
if err != nil {
|
||||
fmt.Printf("[error] adding to history: %v\n", err)
|
||||
// continue...
|
||||
@ -343,7 +371,7 @@ func ScreenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstor
|
||||
if firstArg == "" {
|
||||
return nil, fmt.Errorf("usage /screen [screen-name|screen-index|screen-id], no param specified")
|
||||
}
|
||||
ritem, err := resolveSessionScreen(ctx, ids.SessionId, firstArg, pk.Kwargs["screen"])
|
||||
ritem, err := resolveSessionScreen(ctx, ids.SessionId, firstArg, ids.ScreenId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -505,6 +533,15 @@ func RemoteNewCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ss
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func RemoteSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window|R_Remote)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Printf("ids: %v\n", ids)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func RemoteShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Window|R_Remote)
|
||||
if err != nil {
|
||||
@ -524,7 +561,7 @@ func RemoteShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (s
|
||||
}
|
||||
return sstore.ModelUpdate{
|
||||
Info: &sstore.InfoMsgType{
|
||||
InfoTitle: fmt.Sprintf("show remote '%s' info", ids.Remote.DisplayName),
|
||||
InfoTitle: fmt.Sprintf("show remote [%s] info", ids.Remote.DisplayName),
|
||||
InfoLines: splitLinesForInfo(buf.String()),
|
||||
},
|
||||
}, nil
|
||||
@ -550,6 +587,15 @@ func RemoteShowAllCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
}, nil
|
||||
}
|
||||
|
||||
func RemoteArchiveCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Window|R_Remote)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
update := sstore.InfoMsgUpdate("remote [%s] archived", ids.Remote.DisplayName)
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func RemoteCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
return nil, fmt.Errorf("/remote requires a subcommand: %s", formatStrs([]string{"show"}, "or", false))
|
||||
}
|
||||
@ -568,7 +614,7 @@ func SetEnvCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstor
|
||||
}
|
||||
update := sstore.ModelUpdate{
|
||||
Info: &sstore.InfoMsgType{
|
||||
InfoTitle: fmt.Sprintf("environment for [%s] remote", ids.Remote.DisplayName),
|
||||
InfoTitle: fmt.Sprintf("environment for remote [%s]", ids.Remote.DisplayName),
|
||||
InfoLines: infoLines,
|
||||
},
|
||||
}
|
||||
@ -615,7 +661,7 @@ func CrCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up
|
||||
return nil, err
|
||||
}
|
||||
if rptr == nil {
|
||||
return nil, fmt.Errorf("/cr error: remote '%s' not found", newRemote)
|
||||
return nil, fmt.Errorf("/cr error: remote [%s] not found", newRemote)
|
||||
}
|
||||
err = sstore.UpdateCurRemote(ctx, ids.SessionId, ids.WindowId, *rptr)
|
||||
if err != nil {
|
||||
@ -991,6 +1037,26 @@ func SessionOpenCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func SessionDeleteCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = sstore.DeleteSession(ctx, ids.SessionId)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot delete session: %v", err)
|
||||
}
|
||||
sessionIds, _ := sstore.GetAllSessionIds(ctx) // ignore error, session is already deleted so that's the main return value
|
||||
delSession := &sstore.SessionType{SessionId: ids.SessionId, Remove: true}
|
||||
update := sstore.ModelUpdate{
|
||||
Sessions: []*sstore.SessionType{delSession},
|
||||
}
|
||||
if len(sessionIds) > 0 {
|
||||
update.ActiveSessionId = sessionIds[0]
|
||||
}
|
||||
return update, nil
|
||||
}
|
||||
|
||||
func SessionSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session)
|
||||
if err != nil {
|
||||
@ -1027,6 +1093,10 @@ func SessionSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (s
|
||||
}
|
||||
|
||||
func SessionCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
firstArg := firstArg(pk)
|
||||
if firstArg == "" {
|
||||
return nil, fmt.Errorf("usage /session [name|id|pos], no param specified")
|
||||
@ -1036,7 +1106,7 @@ func SessionCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (ssto
|
||||
return nil, err
|
||||
}
|
||||
ritems := sessionsToResolveItems(bareSessions)
|
||||
ritem, err := genericResolve(firstArg, pk.Kwargs["session"], ritems, "session")
|
||||
ritem, err := genericResolve(firstArg, ids.SessionId, ritems, "session")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -1179,3 +1249,16 @@ func WindowResizeCommand(ctx context.Context, pk *scpacket.FeCommandPacketType)
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func LineCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
return nil, fmt.Errorf("/line requires a subcommand: %s", formatStrs([]string{"show"}, "or", false))
|
||||
}
|
||||
|
||||
func LineShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.UpdatePacket, error) {
|
||||
ids, err := resolveUiIds(ctx, pk, R_Session|R_Screen|R_Window)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fmt.Printf("/line:show ids %v\n", ids)
|
||||
return nil, nil
|
||||
}
|
||||
|
@ -413,6 +413,10 @@ func (msh *MShellProc) GetRemoteName() string {
|
||||
|
||||
func (msh *MShellProc) Launch() {
|
||||
remoteCopy := msh.getRemoteCopy()
|
||||
if remoteCopy.ConnectMode == sstore.ConnectModeArchive {
|
||||
logf(&remoteCopy, "cannot launch archived remote")
|
||||
return
|
||||
}
|
||||
logf(&remoteCopy, "starting launch")
|
||||
ecmd := convertSSHOpts(remoteCopy.SSHOpts).MakeSSHExecCmd(MShellServerCommand)
|
||||
cmdPty, err := msh.addControllingTty(ecmd)
|
||||
|
@ -43,10 +43,6 @@ func removeFirstCmdWaitFn(ck base.CommandKey) func() {
|
||||
delete(GlobalStore.CmdWaitMap, ck)
|
||||
return nil
|
||||
}
|
||||
if len(fns) == 1 {
|
||||
delete(GlobalStore.CmdWaitMap, ck)
|
||||
return fns[0]
|
||||
}
|
||||
fn := fns[0]
|
||||
GlobalStore.CmdWaitMap[ck] = fns[1:]
|
||||
return fn
|
||||
|
@ -122,6 +122,19 @@ func InsertRemote(ctx context.Context, remote *RemoteType) error {
|
||||
return txErr
|
||||
}
|
||||
|
||||
func ArchiveRemote(ctx context.Context, remoteId string) error {
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
query := `SELECT remoteid FROM remote WHERE remoteid = ?`
|
||||
if !tx.Exists(query, remoteId) {
|
||||
return fmt.Errorf("cannot archive, remote does not exist")
|
||||
}
|
||||
query = `UPDATE remote SET connectmode = ?, physicalid = '', remotetype = '', remotealias = '', initpk = '', sshopts = '', remoteopts = '', lastconnectts = 0 WHERE remoteid = ?`
|
||||
tx.ExecWrap(query, ConnectModeArchive, remoteId)
|
||||
return nil
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
||||
func InsertHistoryItem(ctx context.Context, hitem *HistoryItemType) error {
|
||||
if hitem == nil {
|
||||
return fmt.Errorf("cannot insert nil history item")
|
||||
@ -910,3 +923,7 @@ func UpdateCmdTermOpts(ctx context.Context, sessionId string, cmdId string, term
|
||||
})
|
||||
return txErr
|
||||
}
|
||||
|
||||
func DeleteSession(ctx context.Context, sessionId string) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -55,6 +55,7 @@ const (
|
||||
ConnectModeStartup = "startup"
|
||||
ConnectModeAuto = "auto"
|
||||
ConnectModeManual = "manual"
|
||||
ConnectModeArchive = "archive"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -71,7 +72,7 @@ func GetSessionDBName() string {
|
||||
}
|
||||
|
||||
func IsValidConnectMode(mode string) bool {
|
||||
return mode == ConnectModeStartup || mode == ConnectModeAuto || mode == ConnectModeManual
|
||||
return mode == ConnectModeStartup || mode == ConnectModeAuto || mode == ConnectModeManual || mode == ConnectModeArchive
|
||||
}
|
||||
|
||||
func GetDB(ctx context.Context) (*sqlx.DB, error) {
|
||||
|
Loading…
Reference in New Issue
Block a user