From 08095aa9a0d7b9b7636cdf36a5a5b6df2592bc05 Mon Sep 17 00:00:00 2001 From: Sebastien Douheret Date: Thu, 15 Mar 2018 14:50:27 +0100 Subject: [PATCH] Added Target and Terminal events through WS. Signed-off-by: Sebastien Douheret --- lib/xdsserver/apiv1-targets.go | 44 ++++++++++++++++++++++++------- lib/xdsserver/targets.go | 42 ++++++++++++++++++----------- lib/xdsserver/terminal-ssh.go | 2 ++ lib/xdsserver/terminals.go | 53 ++++++++++++++++++++++++++++++++----- lib/xsapiv1/events.go | 60 ++++++++++++++++++++++++++++++++++++++---- 5 files changed, 163 insertions(+), 38 deletions(-) diff --git a/lib/xdsserver/apiv1-targets.go b/lib/xdsserver/apiv1-targets.go index 978dc75..a7048eb 100644 --- a/lib/xdsserver/apiv1-targets.go +++ b/lib/xdsserver/apiv1-targets.go @@ -58,9 +58,16 @@ func (s *APIService) addTarget(c *gin.Context) { return } + // Retrieve session info + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + s.Log.Debugln("Add target config: ", cfgArg) - newTgt, err := s.targets.Add(cfgArg) + newTgt, err := s.targets.Add(cfgArg, sess) if err != nil { common.APIError(c, err.Error()) return @@ -77,9 +84,16 @@ func (s *APIService) delTarget(c *gin.Context) { return } + // Retrieve session info + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + s.Log.Debugln("Delete target id ", id) - delEntry, err := s.targets.Delete(id) + delEntry, err := s.targets.Delete(id, sess) if err != nil { common.APIError(c, err.Error()) return @@ -190,13 +204,8 @@ func (s *APIService) openTgtTerm(c *gin.Context) { common.APIError(c, "Unknown sessions") return } - sock := sess.IOSocket - if sock == nil { - common.APIError(c, "Websocket not established") - return - } - term, err := s.targets.OpenTerminal(id, tid, sock, sess.ID) + term, err := s.targets.OpenTerminal(id, tid, sess) if err != nil { common.APIError(c, err.Error()) return @@ -211,7 +220,15 @@ func (s *APIService) closeTgtTerm(c *gin.Context) { common.APIError(c, err.Error()) return } - term, err := s.targets.CloseTerminal(id, tid) + + // Retrieve session info + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + + term, err := s.targets.CloseTerminal(id, tid, sess) if err != nil { common.APIError(c, err.Error()) return @@ -233,7 +250,14 @@ func (s *APIService) resizeTgtTerm(c *gin.Context) { return } - term, err := s.targets.ResizeTerminal(id, tid, sizeArg.Cols, sizeArg.Rows) + // Retrieve session info + sess := s.sessions.Get(c) + if sess == nil { + common.APIError(c, "Unknown sessions") + return + } + + term, err := s.targets.ResizeTerminal(id, tid, sizeArg.Cols, sizeArg.Rows, sess) if err != nil { common.APIError(c, err.Error()) return diff --git a/lib/xdsserver/targets.go b/lib/xdsserver/targets.go index 663233d..ded3c1b 100644 --- a/lib/xdsserver/targets.go +++ b/lib/xdsserver/targets.go @@ -27,7 +27,6 @@ import ( common "gerrit.automotivelinux.org/gerrit/src/xds/xds-common.git/golib" "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xdsconfig" "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1" - socketio "github.com/googollee/go-socket.io" "github.com/syncthing/syncthing/lib/sync" ) @@ -80,7 +79,7 @@ func (t *Targets) LoadConfig() error { // Update targets t.Log.Infof("Loading initial targets config: %d targets found", len(tgts)) for _, tc := range tgts { - if _, err := t.createUpdate(tc, false, true); err != nil { + if _, err := t.createUpdate(tc, false, true, nil); err != nil { return err } } @@ -149,12 +148,12 @@ func (t *Targets) getConfigArrUnsafe() []xsapiv1.TargetConfig { } // Add adds a new target -func (t *Targets) Add(newT xsapiv1.TargetConfig) (*xsapiv1.TargetConfig, error) { - return t.createUpdate(newT, true, false) +func (t *Targets) Add(newT xsapiv1.TargetConfig, sess *ClientSession) (*xsapiv1.TargetConfig, error) { + return t.createUpdate(newT, true, false, sess) } // CreateUpdate creates or update a target -func (t *Targets) createUpdate(newT xsapiv1.TargetConfig, create bool, initial bool) (*xsapiv1.TargetConfig, error) { +func (t *Targets) createUpdate(newT xsapiv1.TargetConfig, create bool, initial bool, sess *ClientSession) (*xsapiv1.TargetConfig, error) { var err error tcMutex.Lock() @@ -227,6 +226,14 @@ func (t *Targets) createUpdate(newT xsapiv1.TargetConfig, create bool, initial b // Add to folders list t.tgts[newT.ID] = &tgt + // Notify target Add + newTgt := tgt.GetConfig() + if !initial { + if err = t.events.Emit(xsapiv1.EVTTargetAdd, &newTgt, sess.ID); err != nil { + t.Log.Errorf("WS Emit EVTTargetAdd : %v", err) + } + } + // Save config on disk if !initial { if err := t.SaveConfig(); err != nil { @@ -234,12 +241,11 @@ func (t *Targets) createUpdate(newT xsapiv1.TargetConfig, create bool, initial b } } - newTgt := tgt.GetConfig() return &newTgt, nil } // Delete deletes a specific target -func (t *Targets) Delete(id string) (xsapiv1.TargetConfig, error) { +func (t *Targets) Delete(id string, sess *ClientSession) (xsapiv1.TargetConfig, error) { var err error tcMutex.Lock() @@ -262,6 +268,11 @@ func (t *Targets) Delete(id string) (xsapiv1.TargetConfig, error) { // Save config on disk err = t.SaveConfig() + // Notify target remove + if err = t.events.Emit(xsapiv1.EVTTargetRemove, &tgc, sess.ID); err != nil { + t.Log.Errorf("WS Emit EVTTargetRemove : %v", err) + } + return tgc, err } @@ -341,10 +352,8 @@ func (t *Targets) CreateUpdateTerminal(targetID string, tmCfg xsapiv1.TerminalCo } } - term.Status = xsapiv1.StatusTermEnable - - // Save config on disk if !initial { + // Save config on disk if err := t.SaveConfig(); err != nil { return term, err } @@ -374,30 +383,31 @@ func (t *Targets) DeleteTerminal(targetID, termID string) (*xsapiv1.TerminalConf } // OpenTerminal Open a target terminal -func (t *Targets) OpenTerminal(targetID, termID string, sock *socketio.Socket, sessID string) (*xsapiv1.TerminalConfig, error) { +func (t *Targets) OpenTerminal(targetID, termID string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) { terms, exist := t.terminals[targetID] if !exist { return nil, fmt.Errorf("unknown target id") } - return (*terms).Open(termID, sock, sessID) + + return (*terms).Open(termID, sess) } // CloseTerminal Close a target terminal -func (t *Targets) CloseTerminal(targetID, termID string) (*xsapiv1.TerminalConfig, error) { +func (t *Targets) CloseTerminal(targetID, termID string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) { terms, exist := t.terminals[targetID] if !exist { return nil, fmt.Errorf("unknown target id") } - return (*terms).Close(termID) + return (*terms).Close(termID, sess) } // ResizeTerminal Set size (row+col) of a target terminal -func (t *Targets) ResizeTerminal(targetID, termID string, cols, rows uint16) (*xsapiv1.TerminalConfig, error) { +func (t *Targets) ResizeTerminal(targetID, termID string, cols, rows uint16, sess *ClientSession) (*xsapiv1.TerminalConfig, error) { terms, exist := t.terminals[targetID] if !exist { return nil, fmt.Errorf("unknown target id") } - return (*terms).Resize(termID, cols, rows) + return (*terms).Resize(termID, cols, rows, sess) } // SignalTerminal Send a signal to a target terminal diff --git a/lib/xdsserver/terminal-ssh.go b/lib/xdsserver/terminal-ssh.go index 9a9f5fd..c275173 100644 --- a/lib/xdsserver/terminal-ssh.go +++ b/lib/xdsserver/terminal-ssh.go @@ -246,6 +246,8 @@ func (t *TermSSH) Resize(cols, rows uint16) (*xsapiv1.TerminalConfig, error) { t.termCfg.Rows = rows } + t.LogSillyf("Terminal resize id=%v, cols=%v, rows=%v", t.termCfg.ID, cols, rows) + err := t.sshWS.TerminalSetSize(t.termCfg.Rows, t.termCfg.Cols) if err != nil { t.Log.Errorf("Error ssh TerminalSetSize: %v", err) diff --git a/lib/xdsserver/terminals.go b/lib/xdsserver/terminals.go index 36623ab..b52b351 100644 --- a/lib/xdsserver/terminals.go +++ b/lib/xdsserver/terminals.go @@ -21,7 +21,6 @@ import ( "fmt" "gerrit.automotivelinux.org/gerrit/src/xds/xds-server/lib/xsapiv1" - socketio "github.com/googollee/go-socket.io" "github.com/syncthing/syncthing/lib/sync" ) @@ -62,6 +61,13 @@ func (t *Terminals) New(cfg xsapiv1.TerminalConfig, targetID string) (*xsapiv1.T t.terms[termCfg.ID] = &newT + termCfg.Status = xsapiv1.StatusTermEnable + + // Notify terminal add + if err := t.events.Emit(xsapiv1.EVTTargetTerminalAdd, &termCfg, ""); err != nil { + t.Log.Errorf("WS Emit EVTTargetTerminalAdd : %v", err) + } + return &termCfg, nil } @@ -84,6 +90,11 @@ func (t *Terminals) Free(id string) (*xsapiv1.TerminalConfig, error) { delete(t.terms, id) + // Notify terminal state change or add + if err := t.events.Emit(xsapiv1.EVTTargetTerminalRemove, &resTerm, ""); err != nil { + t.Log.Errorf("WS Emit EVTTargetTerminalRemove : %v", err) + } + return &resTerm, nil } @@ -117,25 +128,45 @@ func (t *Terminals) getConfigArrUnsafe() []xsapiv1.TerminalConfig { } // Open adds a new terminal -func (t *Terminals) Open(id string, sock *socketio.Socket, sessID string) (*xsapiv1.TerminalConfig, error) { +func (t *Terminals) Open(id string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) { tc := t.Get(id) if tc == nil { return nil, fmt.Errorf("Unknown id") } - return (*tc).Open(sock, sessID) + + if sess.IOSocket == nil { + return nil, fmt.Errorf("Websocket not established") + } + + term, err := (*tc).Open(sess.IOSocket, sess.ID) + + // Notify term state change + if errEmit := t.events.Emit(xsapiv1.EVTTargetTerminalStateChange, &term, sess.ID); errEmit != nil { + t.Log.Errorf("WS Emit EVTTargetTerminalStateChange : %v", errEmit) + } + + return term, err } // Close a specific terminal -func (t *Terminals) Close(id string) (*xsapiv1.TerminalConfig, error) { +func (t *Terminals) Close(id string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) { tc := t.Get(id) if tc == nil { return nil, fmt.Errorf("Unknown id") } - return (*tc).Close() + + term, err := (*tc).Close() + + // Notify term state change + if errEmit := t.events.Emit(xsapiv1.EVTTargetTerminalStateChange, &term, sess.ID); errEmit != nil { + t.Log.Errorf("WS Emit EVTTargetTerminalStateChange : %v", errEmit) + } + + return term, err } // Resize a specific terminal -func (t *Terminals) Resize(id string, cols, rows uint16) (*xsapiv1.TerminalConfig, error) { +func (t *Terminals) Resize(id string, cols, rows uint16, sess *ClientSession) (*xsapiv1.TerminalConfig, error) { tmMutex.Lock() defer tmMutex.Unlock() @@ -143,7 +174,15 @@ func (t *Terminals) Resize(id string, cols, rows uint16) (*xsapiv1.TerminalConfi if tc == nil { return nil, fmt.Errorf("Unknown id") } - return (*tc).Resize(cols, rows) + + term, err := (*tc).Resize(cols, rows) + + // Notify term state change + if errEmit := t.events.Emit(xsapiv1.EVTTargetTerminalStateChange, &term, sess.ID); errEmit != nil { + t.Log.Errorf("WS Emit EVTTargetTerminalStateChange : %v", errEmit) + } + + return term, err } // Signal Send a Signal a specific terminal diff --git a/lib/xsapiv1/events.go b/lib/xsapiv1/events.go index 84a364c..e42563c 100644 --- a/lib/xsapiv1/events.go +++ b/lib/xsapiv1/events.go @@ -48,13 +48,23 @@ const ( EventTypePrefix = "event:" // following by event type // Supported Events type - EVTAll = EventTypePrefix + "all" + EVTAll = EventTypePrefix + "all" + EVTFolderChange = EventTypePrefix + "folder-change" // type EventMsg with Data type xsapiv1.FolderConfig EVTFolderStateChange = EventTypePrefix + "folder-state-change" // type EventMsg with Data type xsapiv1.FolderConfig - EVTSDKAdd = EventTypePrefix + "sdk-add" // type EventMsg with Data type xsapiv1.SDK - EVTSDKRemove = EventTypePrefix + "sdk-remove" // type EventMsg with Data type xsapiv1.SDK - EVTSDKManagement = EventTypePrefix + "sdk-management" // type EventMsg with Data type xsapiv1.SDKManagementMsg - EVTSDKStateChange = EventTypePrefix + "sdk-state-change" // type EventMsg with Data type xsapiv1.SDK + + EVTSDKAdd = EventTypePrefix + "sdk-add" // type EventMsg with Data type xsapiv1.SDK + EVTSDKRemove = EventTypePrefix + "sdk-remove" // type EventMsg with Data type xsapiv1.SDK + EVTSDKManagement = EventTypePrefix + "sdk-management" // type EventMsg with Data type xsapiv1.SDKManagementMsg + EVTSDKStateChange = EventTypePrefix + "sdk-state-change" // type EventMsg with Data type xsapiv1.SDK + + EVTTargetAdd = EventTypePrefix + "target-add" // type EventMsg with Data type xsapiv1.TargetConfig + EVTTargetRemove = EventTypePrefix + "target-remove" // type EventMsg with Data type xsapiv1.TargetConfig + EVTTargetStateChange = EventTypePrefix + "target-state-change" // type EventMsg with Data type xsapiv1.TargetConfig + + EVTTargetTerminalAdd = EventTypePrefix + "target-terminal-add" // type EventMsg with Data type xsapiv1.TerminalConfig + EVTTargetTerminalRemove = EventTypePrefix + "target-terminal-remove" // type EventMsg with Data type xsapiv1.TerminalConfig + EVTTargetTerminalStateChange = EventTypePrefix + "target-terminal-state-change" // type EventMsg with Data type xsapiv1.TerminalConfig ) // EVTAllList List of all supported events @@ -65,6 +75,12 @@ var EVTAllList = []string{ EVTSDKRemove, EVTSDKManagement, EVTSDKStateChange, + EVTTargetAdd, + EVTTargetRemove, + EVTTargetStateChange, + EVTTargetTerminalAdd, + EVTTargetTerminalRemove, + EVTTargetTerminalStateChange, } // DecodeFolderConfig Helper to decode Data field type FolderConfig @@ -100,3 +116,37 @@ func (e *EventMsg) DecodeSDKEvent() (SDK, error) { } return s, err } + +// DecodeTargetEvent Helper to decode Data field type TargetConfig +func (e *EventMsg) DecodeTargetEvent() (TargetConfig, error) { + var err error + p := TargetConfig{} + switch e.Type { + case EVTTargetAdd, EVTTargetRemove, EVTTargetStateChange: + d := []byte{} + d, err = json.Marshal(e.Data) + if err == nil { + err = json.Unmarshal(d, &p) + } + default: + err = fmt.Errorf("Invalid type") + } + return p, err +} + +// DecodeTerminalEvent Helper to decode Data field type TerminalConfig +func (e *EventMsg) DecodeTerminalEvent() (TerminalConfig, error) { + var err error + p := TerminalConfig{} + switch e.Type { + case EVTTargetTerminalAdd, EVTTargetTerminalRemove, EVTTargetTerminalStateChange: + d := []byte{} + d, err = json.Marshal(e.Data) + if err == nil { + err = json.Unmarshal(d, &p) + } + default: + err = fmt.Errorf("Invalid type") + } + return p, err +} -- 2.16.6