mirror of
https://github.com/wavetermdev/backup.git
synced 2026-08-05 13:57:07 -07:00
working on multiple sessions/windows
This commit is contained in:
+75
-9
@@ -270,19 +270,19 @@ func sendCmdInput(pk *packet.InputPacketType) error {
|
||||
return msh.SendInput(pk)
|
||||
}
|
||||
|
||||
// params: name
|
||||
// params: sessionid
|
||||
func HandleGetSession(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"))
|
||||
sessionId := qvals.Get("sessionid")
|
||||
if sessionId == "" {
|
||||
WriteJsonError(w, fmt.Errorf("must specify a sessionid"))
|
||||
return
|
||||
}
|
||||
session, err := sstore.GetSessionByName(r.Context(), name)
|
||||
session, err := sstore.GetSessionById(r.Context(), sessionId)
|
||||
if err != nil {
|
||||
WriteJsonError(w, err)
|
||||
return
|
||||
@@ -291,6 +291,69 @@ func HandleGetSession(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
func HandleGetAllSessions(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")
|
||||
list, err := sstore.GetAllSessions(r.Context())
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("cannot get all sessions: %w", err))
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, list)
|
||||
return
|
||||
}
|
||||
|
||||
// params: name
|
||||
func HandleCreateSession(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")
|
||||
sessionId, err := sstore.InsertSessionWithName(r.Context(), name)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("inserting session: %w", err))
|
||||
return
|
||||
}
|
||||
session, err := sstore.GetSessionById(r.Context(), sessionId)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("getting new session: %w", err))
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, session)
|
||||
return
|
||||
}
|
||||
|
||||
// params: sessionid, name
|
||||
func HandleCreateWindow(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")
|
||||
if _, err := uuid.Parse(sessionId); err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("invalid sessionid: %w", err))
|
||||
return
|
||||
}
|
||||
name := qvals.Get("name")
|
||||
windowId, err := sstore.InsertWindow(r.Context(), sessionId, name)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("inserting new window: %w", err))
|
||||
return
|
||||
}
|
||||
window, err := sstore.GetWindowById(r.Context(), sessionId, windowId)
|
||||
if err != nil {
|
||||
WriteJsonError(w, fmt.Errorf("getting new window: %w", err))
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, window)
|
||||
return
|
||||
}
|
||||
|
||||
// params: [none]
|
||||
func HandleGetRemotes(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin"))
|
||||
@@ -303,7 +366,7 @@ func HandleGetRemotes(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// params: sessionid, windowid
|
||||
func HandleGetWindowLines(w http.ResponseWriter, r *http.Request) {
|
||||
func HandleGetWindow(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")
|
||||
@@ -319,12 +382,12 @@ func HandleGetWindowLines(w http.ResponseWriter, r *http.Request) {
|
||||
WriteJsonError(w, fmt.Errorf("invalid windowid: %w", err))
|
||||
return
|
||||
}
|
||||
lines, err := sstore.GetWindowLines(r.Context(), sessionId, windowId)
|
||||
window, err := sstore.GetWindowById(r.Context(), sessionId, windowId)
|
||||
if err != nil {
|
||||
WriteJsonError(w, err)
|
||||
return
|
||||
}
|
||||
WriteJsonSuccess(w, lines)
|
||||
WriteJsonSuccess(w, window)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -623,9 +686,12 @@ func main() {
|
||||
go runWebSocketServer()
|
||||
gr := mux.NewRouter()
|
||||
gr.HandleFunc("/api/ptyout", HandleGetPtyOut)
|
||||
gr.HandleFunc("/api/get-all-sessions", HandleGetAllSessions)
|
||||
gr.HandleFunc("/api/create-session", HandleCreateSession)
|
||||
gr.HandleFunc("/api/get-session", HandleGetSession)
|
||||
gr.HandleFunc("/api/get-window-lines", HandleGetWindowLines)
|
||||
gr.HandleFunc("/api/get-window", HandleGetWindow)
|
||||
gr.HandleFunc("/api/get-remotes", HandleGetRemotes)
|
||||
gr.HandleFunc("/api/create-window", HandleCreateWindow)
|
||||
gr.HandleFunc("/api/run-command", HandleRunCommand).Methods("GET", "POST", "OPTIONS")
|
||||
server := &http.Server{
|
||||
Addr: MainServerAddr,
|
||||
|
||||
+115
-25
@@ -84,6 +84,20 @@ func InsertRemote(ctx context.Context, remote *RemoteType) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetAllSessions(ctx context.Context) ([]*SessionType, error) {
|
||||
db, err := GetDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var rtn []*SessionType
|
||||
query := `SELECT * FROM session`
|
||||
err = db.SelectContext(ctx, &rtn, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rtn, nil
|
||||
}
|
||||
|
||||
func GetSessionById(ctx context.Context, id string) (*SessionType, error) {
|
||||
var rtnSession *SessionType
|
||||
err := WithTx(ctx, func(tx *TxWrap) error {
|
||||
@@ -128,35 +142,56 @@ func GetSessionByName(ctx context.Context, name string) (*SessionType, error) {
|
||||
return GetSessionById(ctx, sessionId)
|
||||
}
|
||||
|
||||
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
|
||||
func GetWindowById(ctx context.Context, sessionId string, windowId string) (*WindowType, error) {
|
||||
var rtnWindow *WindowType
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
var window WindowType
|
||||
query := `SELECT * FROM window WHERE sessionid = ? AND windowid = ?`
|
||||
found := tx.GetWrap(&window, query, sessionId, windowId)
|
||||
if !found {
|
||||
return nil
|
||||
}
|
||||
rtnWindow = &window
|
||||
query = `SELECT * FROM line WHERE sessionid = ? AND windowid = ?`
|
||||
tx.SelectWrap(&window.Lines, query, sessionId, windowId)
|
||||
return nil
|
||||
})
|
||||
return rtnWindow, txErr
|
||||
}
|
||||
|
||||
// also creates window
|
||||
func InsertSessionWithName(ctx context.Context, sessionName string) error {
|
||||
if sessionName == "" {
|
||||
return fmt.Errorf("invalid session name '%s'", sessionName)
|
||||
}
|
||||
session := &SessionType{
|
||||
SessionId: uuid.New().String(),
|
||||
Name: sessionName,
|
||||
}
|
||||
return WithTx(ctx, func(tx *TxWrap) error {
|
||||
// also creates default window, returns sessionId
|
||||
// if sessionName == "", it will be generated
|
||||
func InsertSessionWithName(ctx context.Context, sessionName string) (string, error) {
|
||||
newSessionId := uuid.New().String()
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
if sessionName == "" {
|
||||
var names []string
|
||||
query := `SELECT name FROM session`
|
||||
tx.GetWrap(&names, query)
|
||||
snum := len(names) + 1
|
||||
for {
|
||||
sessionName = fmt.Sprintf("session-%d", snum)
|
||||
if !containsStr(names, sessionName) {
|
||||
break
|
||||
}
|
||||
snum++
|
||||
}
|
||||
} else {
|
||||
var dupSessionId string
|
||||
query := `SELECT sessionid FROM session WHERE name = ?`
|
||||
tx.GetWrap(&dupSessionId, query, sessionName)
|
||||
if dupSessionId != "" {
|
||||
return fmt.Errorf("cannot create session with duplicate name")
|
||||
}
|
||||
}
|
||||
newSession := &SessionType{
|
||||
SessionId: newSessionId,
|
||||
Name: sessionName,
|
||||
}
|
||||
query := `INSERT INTO session (sessionid, name) VALUES (:sessionid, :name)`
|
||||
tx.NamedExecWrap(query, session)
|
||||
|
||||
tx.NamedExecWrap(query, newSession)
|
||||
window := &WindowType{
|
||||
SessionId: session.SessionId,
|
||||
SessionId: newSessionId,
|
||||
WindowId: uuid.New().String(),
|
||||
Name: DefaultWindowName,
|
||||
CurRemote: LocalRemoteName,
|
||||
@@ -165,6 +200,61 @@ func InsertSessionWithName(ctx context.Context, sessionName string) error {
|
||||
tx.NamedExecWrap(query, window)
|
||||
return nil
|
||||
})
|
||||
return newSessionId, txErr
|
||||
}
|
||||
|
||||
func containsStr(strs []string, testStr string) bool {
|
||||
for _, s := range strs {
|
||||
if s == testStr {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// if windowName == "", it will be generated
|
||||
// returns (windowid, err)
|
||||
func InsertWindow(ctx context.Context, sessionId string, windowName string) (string, error) {
|
||||
var newWindowId string
|
||||
txErr := WithTx(ctx, func(tx *TxWrap) error {
|
||||
var testSessionId string
|
||||
query := `SELECT sesssionid FROM session WHERE sessionid = ?`
|
||||
sessionExists := tx.GetWrap(&testSessionId, query, sessionId)
|
||||
if !sessionExists {
|
||||
return fmt.Errorf("cannot insert window, session does not exist")
|
||||
}
|
||||
if windowName == "" {
|
||||
var names []string
|
||||
query = `SELECT name FROM window WHERE sessionid = ?`
|
||||
tx.GetWrap(&names, query, sessionId)
|
||||
wnum := len(names) + 1
|
||||
for {
|
||||
windowName = fmt.Sprintf("w%d", wnum)
|
||||
if !containsStr(names, windowName) {
|
||||
break
|
||||
}
|
||||
wnum++
|
||||
}
|
||||
} else {
|
||||
var testWindowId string
|
||||
query = `SELECT windowid FROM window WHERE sessionid = ? AND name = ?`
|
||||
windowExists := tx.GetWrap(&testWindowId, query, sessionId, windowName)
|
||||
if windowExists {
|
||||
return fmt.Errorf("cannot insert window, name already exists in session")
|
||||
}
|
||||
}
|
||||
newWindowId = uuid.New().String()
|
||||
window := &WindowType{
|
||||
SessionId: sessionId,
|
||||
WindowId: newWindowId,
|
||||
Name: windowName,
|
||||
CurRemote: LocalRemoteName,
|
||||
}
|
||||
query = `INSERT INTO window (sessionid, windowid, name, curremote, version) VALUES (:sessionid, :windowid, :name, :curremote, :version)`
|
||||
tx.NamedExecWrap(query, window)
|
||||
return nil
|
||||
})
|
||||
return newWindowId, txErr
|
||||
}
|
||||
|
||||
func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error {
|
||||
|
||||
@@ -16,6 +16,7 @@ func AppendToCmdPtyBlob(ctx context.Context, sessionId string, cmdId string, dat
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer fd.Close()
|
||||
if len(data) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ func EnsureDefaultSession(ctx context.Context) (*SessionType, error) {
|
||||
if session != nil {
|
||||
return session, nil
|
||||
}
|
||||
err = InsertSessionWithName(ctx, DefaultSessionName)
|
||||
_, err = InsertSessionWithName(ctx, DefaultSessionName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user