diff --git a/db/migrations/000009_screenprimary.down.sql b/db/migrations/000009_screenprimary.down.sql index 1c2aaf96..a4b58677 100644 --- a/db/migrations/000009_screenprimary.down.sql +++ b/db/migrations/000009_screenprimary.down.sql @@ -1,3 +1,3 @@ --- invalid, will throw an error, cannot migrate down past 9 +-- invalid, will throw an error, cannot migrate down SELECT x; diff --git a/db/migrations/000010_removewindowid.down.sql b/db/migrations/000010_removewindowid.down.sql index e69de29b..6332dc5b 100644 --- a/db/migrations/000010_removewindowid.down.sql +++ b/db/migrations/000010_removewindowid.down.sql @@ -0,0 +1,2 @@ +-- invalid, will throw an error, cannot migrate down +SELECT x; diff --git a/db/migrations/000011_cmdscreenid.down.sql b/db/migrations/000011_cmdscreenid.down.sql new file mode 100644 index 00000000..62fbbdf0 --- /dev/null +++ b/db/migrations/000011_cmdscreenid.down.sql @@ -0,0 +1,2 @@ +ALTER TABLE cmd DROP COLUMN screenid; + diff --git a/db/migrations/000011_cmdscreenid.up.sql b/db/migrations/000011_cmdscreenid.up.sql new file mode 100644 index 00000000..13ea21bd --- /dev/null +++ b/db/migrations/000011_cmdscreenid.up.sql @@ -0,0 +1,5 @@ +ALTER TABLE cmd ADD COLUMN screenid varchar(36) NOT NULL DEFAULT ''; + +UPDATE cmd +SET screenid = (SELECT line.screenid FROM line WHERE line.cmdid = cmd.cmdid) +; diff --git a/pkg/cmdrunner/cmdrunner.go b/pkg/cmdrunner/cmdrunner.go index 332c8779..3ab5975d 100644 --- a/pkg/cmdrunner/cmdrunner.go +++ b/pkg/cmdrunner/cmdrunner.go @@ -1164,6 +1164,7 @@ func CrCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up func makeStaticCmd(ctx context.Context, metaCmd string, ids resolvedIds, cmdStr string, cmdOutput []byte) (*sstore.CmdType, error) { cmd := &sstore.CmdType{ SessionId: ids.SessionId, + ScreenId: ids.ScreenId, CmdId: scbase.GenPromptUUID(), CmdStr: cmdStr, Remote: ids.Remote.RemotePtr, @@ -1185,7 +1186,7 @@ func makeStaticCmd(ctx context.Context, metaCmd string, ids resolvedIds, cmdStr return nil, fmt.Errorf("cannot create local ptyout file for %s command: %w", metaCmd, err) } // can ignore ptyupdate - _, err = sstore.AppendToCmdPtyBlob(ctx, cmd.SessionId, cmd.CmdId, cmdOutput, 0) + _, err = sstore.AppendToCmdPtyBlob(ctx, cmd.SessionId, ids.ScreenId, cmd.CmdId, cmdOutput, 0) if err != nil { // TODO tricky error since the command was a success, but we can't show the output return nil, fmt.Errorf("cannot append to local ptyout file for %s command: %v", metaCmd, err) diff --git a/pkg/remote/remote.go b/pkg/remote/remote.go index 23d3d971..1d11c96e 100644 --- a/pkg/remote/remote.go +++ b/pkg/remote/remote.go @@ -1340,6 +1340,7 @@ func RunCommand(ctx context.Context, sessionId string, screenId string, remotePt } cmd := &sstore.CmdType{ SessionId: runPacket.CK.GetSessionId(), + ScreenId: screenId, CmdId: runPacket.CK.GetCmdId(), CmdStr: runPacket.Command, Remote: remotePtr, @@ -1593,7 +1594,8 @@ func (msh *MShellProc) handleDataPacket(dataPk *packet.DataPacketType, dataPosMa var ack *packet.DataAckPacketType if len(realData) > 0 { dataPos := dataPosMap[dataPk.CK] - update, err := sstore.AppendToCmdPtyBlob(context.Background(), dataPk.CK.GetSessionId(), dataPk.CK.GetCmdId(), realData, dataPos) + rcmd := msh.GetRunningCmd(dataPk.CK) + update, err := sstore.AppendToCmdPtyBlob(context.Background(), dataPk.CK.GetSessionId(), rcmd.ScreenId, dataPk.CK.GetCmdId(), realData, dataPos) if err != nil { ack = makeDataAckPacket(dataPk.CK, dataPk.FdNum, 0, err) } else { diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index b61476e3..e7cdfa7e 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -316,7 +316,6 @@ func runHistoryQuery(tx *TxWrap, opts HistoryQueryOpts, realOffset int, itemLimi whereClause += " AND NOT h.ismetacmd" } query := fmt.Sprintf("SELECT %s, ('%s' || CAST((row_number() OVER win) as text)) historynum, l.linenum FROM history h LEFT OUTER JOIN line l ON (h.lineid = l.lineid) %s WINDOW win AS (ORDER BY h.ts, h.historyid) ORDER BY h.ts DESC, h.historyid DESC LIMIT %d OFFSET %d", HistoryCols, hNumStr, whereClause, itemLimit, realOffset) - fmt.Printf("HISTORY QUERY %s\n", query) marr := tx.SelectMaps(query, queryArgs...) rtn := make([]*HistoryItemType, len(marr)) for idx, m := range marr { @@ -420,15 +419,17 @@ func GetAllSessions(ctx context.Context) (*ModelUpdate, error) { func GetScreenLinesById(ctx context.Context, screenId string) (*ScreenLinesType, error) { return WithTxRtn(ctx, func(tx *TxWrap) (*ScreenLinesType, error) { - query := `SELECT sessionid, screenid FROM screen WHERE screenid = ?` + query := `SELECT screenid FROM screen WHERE screenid = ?` screen := GetMappable[*ScreenLinesType](tx, query, screenId) if screen == nil { return nil, nil } + query = `SELECT sessionid FROM screen WHERE screenid = ?` + sessionId := tx.GetString(query, screenId) query = `SELECT * FROM line WHERE sessionid = ? AND screenid = ? ORDER BY linenum` - tx.Select(&screen.Lines, query, screen.SessionId, screen.ScreenId) + tx.Select(&screen.Lines, query, sessionId, screen.ScreenId) query = `SELECT * FROM cmd WHERE cmdid IN (SELECT cmdid FROM line WHERE sessionid = ? AND screenid = ?)` - screen.Cmds = SelectMapsGen[*CmdType](tx, query, screen.SessionId, screen.ScreenId) + screen.Cmds = SelectMapsGen[*CmdType](tx, query, sessionId, screen.ScreenId) return screen, nil }) } @@ -749,6 +750,9 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if line.LineNum != 0 { return fmt.Errorf("line should not hage linenum set") } + if cmd.ScreenId == "" { + return fmt.Errorf("cmd should have screenid set") + } return WithTx(ctx, func(tx *TxWrap) error { query := `SELECT screenid FROM screen WHERE sessionid = ? AND screenid = ?` if !tx.Exists(query, line.SessionId, line.ScreenId) { @@ -766,8 +770,8 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { cmd.OrigTermOpts = cmd.TermOpts cmdMap := cmd.ToMap() query = ` -INSERT INTO cmd ( sessionid, cmdid, remoteownerid, remoteid, remotename, cmdstr, festate, statebasehash, statediffhasharr, termopts, origtermopts, status, startpk, doneinfo, rtnstate, runout, rtnbasehash, rtndiffhasharr) - VALUES (:sessionid,:cmdid,:remoteownerid,:remoteid,:remotename,:cmdstr,:festate,:statebasehash,:statediffhasharr,:termopts,:origtermopts,:status,:startpk,:doneinfo,:rtnstate,:runout,:rtnbasehash,:rtndiffhasharr) +INSERT INTO cmd ( sessionid, screenid, cmdid, remoteownerid, remoteid, remotename, cmdstr, festate, statebasehash, statediffhasharr, termopts, origtermopts, status, startpk, doneinfo, rtnstate, runout, rtnbasehash, rtndiffhasharr) + VALUES (:sessionid,:screenid,:cmdid,:remoteownerid,:remoteid,:remotename,:cmdstr,:festate,:statebasehash,:statediffhasharr,:termopts,:origtermopts,:status,:startpk,:doneinfo,:rtnstate,:runout,:rtnbasehash,:rtndiffhasharr) ` tx.NamedExec(query, cmdMap) } @@ -2358,3 +2362,10 @@ func PurgeHistoryByIds(ctx context.Context, historyIds []string) ([]*HistoryItem return rtn, nil }) } + +func GetScreenIdFromCmd(ctx context.Context, sessionId string, cmdId string) (string, error) { + return WithTxRtn(ctx, func(tx *TxWrap) (string, error) { + query := `SELECT screenid FROM cmd WHERE sessionid = ? AND cmdid = ?` + return tx.GetString(query, sessionId, cmdId), nil + }) +} diff --git a/pkg/sstore/fileops.go b/pkg/sstore/fileops.go index bd654ee6..c27971a2 100644 --- a/pkg/sstore/fileops.go +++ b/pkg/sstore/fileops.go @@ -32,7 +32,10 @@ func StatCmdPtyFile(ctx context.Context, sessionId string, cmdId string) (*cirfi return cirfile.StatCirFile(ctx, ptyOutFileName) } -func AppendToCmdPtyBlob(ctx context.Context, sessionId string, cmdId string, data []byte, pos int64) (*PtyDataUpdate, error) { +func AppendToCmdPtyBlob(ctx context.Context, sessionId string, screenId string, cmdId string, data []byte, pos int64) (*PtyDataUpdate, error) { + if screenId == "" { + return nil, fmt.Errorf("cannot append to PtyBlob, screenid is not set") + } if pos < 0 { return nil, fmt.Errorf("invalid seek pos '%d' in AppendToCmdPtyBlob", pos) } @@ -52,6 +55,7 @@ func AppendToCmdPtyBlob(ctx context.Context, sessionId string, cmdId string, dat data64 := base64.StdEncoding.EncodeToString(data) update := &PtyDataUpdate{ SessionId: sessionId, + ScreenId: screenId, CmdId: cmdId, PtyPos: pos, PtyData64: data64, diff --git a/pkg/sstore/migrate.go b/pkg/sstore/migrate.go index 5e98e3e7..64b52d60 100644 --- a/pkg/sstore/migrate.go +++ b/pkg/sstore/migrate.go @@ -17,7 +17,7 @@ import ( "github.com/golang-migrate/migrate/v4" ) -const MaxMigration = 10 +const MaxMigration = 11 const MigratePrimaryScreenVersion = 9 func MakeMigrate() (*migrate.Migrate, error) { diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index d1978ddc..8a9c7403 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -379,10 +379,9 @@ type ScreenOptsType struct { } type ScreenLinesType struct { - SessionId string `json:"sessionid"` - ScreenId string `json:"screenid"` - Lines []*LineType `json:"lines" dbmap:"-"` - Cmds []*CmdType `json:"cmds" dbmap:"-"` + ScreenId string `json:"screenid"` + Lines []*LineType `json:"lines" dbmap:"-"` + Cmds []*CmdType `json:"cmds" dbmap:"-"` } func (ScreenLinesType) UseDBMap() {} @@ -834,6 +833,7 @@ type CmdDoneInfo struct { type CmdType struct { SessionId string `json:"sessionid"` + ScreenId string `json:"screenid"` CmdId string `json:"cmdid"` Remote RemotePtrType `json:"remote"` CmdStr string `json:"cmdstr"` @@ -894,6 +894,7 @@ func (r *RemoteType) FromMap(m map[string]interface{}) bool { func (cmd *CmdType) ToMap() map[string]interface{} { rtn := make(map[string]interface{}) rtn["sessionid"] = cmd.SessionId + rtn["screenid"] = cmd.ScreenId rtn["cmdid"] = cmd.CmdId rtn["remoteownerid"] = cmd.Remote.OwnerId rtn["remoteid"] = cmd.Remote.RemoteId @@ -916,6 +917,7 @@ func (cmd *CmdType) ToMap() map[string]interface{} { func (cmd *CmdType) FromMap(m map[string]interface{}) bool { quickSetStr(&cmd.SessionId, m, "sessionid") + quickSetStr(&cmd.ScreenId, m, "screenid") quickSetStr(&cmd.CmdId, m, "cmdid") quickSetStr(&cmd.Remote.OwnerId, m, "remoteownerid") quickSetStr(&cmd.Remote.RemoteId, m, "remoteid") diff --git a/pkg/sstore/updatebus.go b/pkg/sstore/updatebus.go index fa1a067e..416b6920 100644 --- a/pkg/sstore/updatebus.go +++ b/pkg/sstore/updatebus.go @@ -18,6 +18,7 @@ type UpdatePacket interface { type PtyDataUpdate struct { SessionId string `json:"sessionid,omitempty"` + ScreenId string `json:"screenid,omitempty"` CmdId string `json:"cmdid,omitempty"` RemoteId string `json:"remoteid,omitempty"` PtyPos int64 `json:"ptypos"`