mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
checkpoint
This commit is contained in:
+64
-8
@@ -20,6 +20,7 @@ import (
|
||||
"github.com/scripthaus-dev/mshell/pkg/cmdtail"
|
||||
"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"
|
||||
"github.com/scripthaus-dev/sh2-server/pkg/wsshell"
|
||||
)
|
||||
@@ -256,6 +257,53 @@ func sendCmdInput(pk *packet.InputPacketType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// params: name
|
||||
func GetSession(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
|
||||
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
w.Header().Set("Vary", "Origin")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
qvals := r.URL.Query()
|
||||
name := qvals.Get("name")
|
||||
if name == "" {
|
||||
WriteJsonError(w, fmt.Errorf("must specify a name"))
|
||||
return
|
||||
}
|
||||
session, err := sstore.GetSessionByName(r.Context(), name)
|
||||
if err != nil {
|
||||
WriteJsonError(w, err)
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, session)
|
||||
return
|
||||
}
|
||||
|
||||
// params: sessionid, windowid
|
||||
func GetWindowLines(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
|
||||
w.Header().Set("Access-Control-Allow-Credentials", "true")
|
||||
w.Header().Set("Vary", "Origin")
|
||||
w.Header().Set("Cache-Control", "no-cache")
|
||||
qvals := r.URL.Query()
|
||||
sessionId := qvals.Get("sessionid")
|
||||
windowId := qvals.Get("windowid")
|
||||
if _, err := uuid.Parse(sessionId); err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("invalid sessionid: %w", err))
|
||||
return
|
||||
}
|
||||
if _, err := uuid.Parse(windowId); err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("invalid windowid: %w", err))
|
||||
return
|
||||
}
|
||||
lines, err := sstore.GetWindowLines(r.Context(), sessionId, windowId)
|
||||
if err != nil {
|
||||
WriteJsonError(w, err)
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, lines)
|
||||
return
|
||||
}
|
||||
|
||||
func GetPtyOutFile(sessionId string, cmdId string) string {
|
||||
pathStr := fmt.Sprintf("/Users/mike/scripthaus/.sessions/%s/%s.ptyout", sessionId, cmdId)
|
||||
return pathStr
|
||||
@@ -337,24 +385,24 @@ func HandleRunCommand(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
var params runCommandParams
|
||||
err := decoder.Decode(¶ms)
|
||||
var commandPk scpacket.FeCommandPacketType
|
||||
err := decoder.Decode(&commandPk)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("error decoding json: %w", err))
|
||||
return
|
||||
}
|
||||
if _, err = uuid.Parse(params.SessionId); err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("invalid sessionid '%s': %w", params.SessionId, err))
|
||||
if _, err = uuid.Parse(commandPk.SessionId); err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("invalid sessionid '%s': %w", commandPk.SessionId, err))
|
||||
return
|
||||
}
|
||||
commandStr := strings.TrimSpace(params.Command)
|
||||
commandStr := strings.TrimSpace(commandPk.CmdStr)
|
||||
if commandStr == "" {
|
||||
WriteJsonError(w, fmt.Errorf("invalid emtpty command"))
|
||||
return
|
||||
}
|
||||
if strings.HasPrefix(commandStr, "/comment ") {
|
||||
text := strings.TrimSpace(commandStr[9:])
|
||||
rtnLine := sstore.MakeNewLineText(params.SessionId, params.WindowId, text)
|
||||
rtnLine := sstore.MakeNewLineText(commandPk.SessionId, commandPk.WindowId, text)
|
||||
WriteJsonSuccess(w, &runCommandResponse{Line: rtnLine})
|
||||
return
|
||||
}
|
||||
@@ -370,10 +418,10 @@ func HandleRunCommand(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
return
|
||||
}
|
||||
rtnLine := sstore.MakeNewLineCmd(params.SessionId, params.WindowId)
|
||||
rtnLine := sstore.MakeNewLineCmd(commandPk.SessionId, commandPk.WindowId)
|
||||
// rtnLine.CmdText = commandStr
|
||||
runPacket := packet.MakeRunPacket()
|
||||
runPacket.CK = base.MakeCommandKey(params.SessionId, rtnLine.CmdId)
|
||||
runPacket.CK = base.MakeCommandKey(commandPk.SessionId, rtnLine.CmdId)
|
||||
runPacket.Cwd = ""
|
||||
runPacket.Env = nil
|
||||
runPacket.Command = commandStr
|
||||
@@ -393,6 +441,12 @@ func HandleRunCommand(w http.ResponseWriter, r *http.Request) {
|
||||
// * userid
|
||||
// * sessionid
|
||||
//
|
||||
// /api/get-session
|
||||
// params:
|
||||
// * name
|
||||
// returns:
|
||||
// * session
|
||||
//
|
||||
// /api/ptyout (pos=[position]) - returns contents of ptyout file
|
||||
// params:
|
||||
// * sessionid
|
||||
@@ -515,6 +569,8 @@ func main() {
|
||||
go runWebSocketServer()
|
||||
gr := mux.NewRouter()
|
||||
gr.HandleFunc("/api/ptyout", GetPtyOut)
|
||||
gr.HandleFunc("/api/get-session", GetSession)
|
||||
gr.HandleFunc("/api/get-window-lines", GetWindowLines)
|
||||
gr.HandleFunc("/api/run-command", HandleRunCommand).Methods("GET", "POST", "OPTIONS")
|
||||
server := &http.Server{
|
||||
Addr: MainServerAddr,
|
||||
|
||||
@@ -130,6 +130,20 @@ func GetSessionByName(ctx context.Context, name string) (*SessionType, error) {
|
||||
return rtnSession, nil
|
||||
}
|
||||
|
||||
func GetWindowLines(ctx context.Context, sessionId string, windowId string) ([]*LineType, error) {
|
||||
var lines []*LineType
|
||||
db, err := GetDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
query := `SELECT * FROM line WHERE sessionid = ? AND windowid = ?`
|
||||
err = db.SelectContext(ctx, &lines, query, sessionId, windowId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return lines, nil
|
||||
}
|
||||
|
||||
// also creates window, and sessionremote
|
||||
func InsertSessionWithName(ctx context.Context, sessionName string) error {
|
||||
if sessionName == "" {
|
||||
@@ -168,3 +182,28 @@ func InsertSessionWithName(ctx context.Context, sessionName string) error {
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func InsertLine(ctx context.Context, line *LineType) error {
|
||||
if line == nil {
|
||||
return fmt.Errorf("line cannot be nil")
|
||||
}
|
||||
if line.LineId != 0 {
|
||||
return fmt.Errorf("new line cannot have LineId set")
|
||||
}
|
||||
return WithTx(ctx, func(tx *TxWrap) error {
|
||||
var windowId string
|
||||
query := `SELECT windowid FROM window WHERE sessionid = ? AND windowid = ?`
|
||||
hasWindow := tx.GetWrap(&windowId, query, line.SessionId, line.WindowId)
|
||||
if !hasWindow {
|
||||
return fmt.Errorf("window not found, cannot insert line[%s/%s]", line.SessionId, line.WindowId)
|
||||
}
|
||||
var maxLineId int
|
||||
query = `SELECT max(lineid) FROM line WHERE sessionid = ? AND windowid = ?`
|
||||
tx.GetWrap(&maxLineId, query, line.SessionId, line.WindowId)
|
||||
line.LineId = maxLineId + 1
|
||||
query = `INSERT INTO line ( sessionid, windowid, lineid, ts, userid, linetype, text, cmdid)
|
||||
VALUES (:sessionid,:windowid,:lineid,:ts,:userid,:linetype,:text,:cmdid)`
|
||||
tx.NamedExecWrap(query, line)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -55,13 +55,13 @@ type SessionType struct {
|
||||
}
|
||||
|
||||
type WindowType struct {
|
||||
SessionId string `json:"sessionid"`
|
||||
WindowId string `json:"windowid"`
|
||||
Name string `json:"name"`
|
||||
CurRemote string `json:"curremote"`
|
||||
Remotes []*RemoteType `json:"remotes"`
|
||||
Lines []*LineType `json:"lines"`
|
||||
Version int `json:"version"`
|
||||
SessionId string `json:"sessionid"`
|
||||
WindowId string `json:"windowid"`
|
||||
Name string `json:"name"`
|
||||
CurRemote string `json:"curremote"`
|
||||
Remotes []*SessionRemote `json:"remotes"`
|
||||
Lines []*LineType `json:"lines"`
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
type SessionRemote struct {
|
||||
|
||||
Reference in New Issue
Block a user