2 * Copyright (C) 2018 "IoT.bzh"
3 * Author Sebastien Douheret <sebastien@iot.bzh>
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
23 "gerrit.automotivelinux.org/gerrit/src/xds/xds-server.git/lib/xsapiv1"
24 "github.com/syncthing/syncthing/lib/sync"
27 // Terminals Represent a XDS terminals
28 type Terminals struct {
30 terms map[string]*ITERMINAL
33 // Mutex to make add/delete atomic
34 var tmMutex = sync.NewMutex()
36 // TerminalsConstructor Create a new instance of Model Terminal
37 func TerminalsConstructor(ctx *Context) *Terminals {
40 terms: make(map[string]*ITERMINAL),
44 // New Create a new terminal
45 func (t *Terminals) New(cfg xsapiv1.TerminalConfig, targetID string) (*xsapiv1.TerminalConfig, error) {
48 defer tmMutex.Unlock()
52 // For now, only SSH term is supported
54 case xsapiv1.TypeTermSSH:
55 newT = NewTermSSH(t.Context, cfg, targetID)
57 return nil, fmt.Errorf("terminal type not set")
60 termCfg := newT.GetConfig()
62 t.terms[termCfg.ID] = &newT
64 termCfg.Status = xsapiv1.StatusTermEnable
66 // Notify terminal add
67 if err := t.events.Emit(xsapiv1.EVTTargetTerminalAdd, &termCfg, ""); err != nil {
68 t.Log.Errorf("WS Emit EVTTargetTerminalAdd : %v", err)
74 // Free a specific terminal
75 func (t *Terminals) Free(id string) (*xsapiv1.TerminalConfig, error) {
78 defer tmMutex.Unlock()
82 return nil, fmt.Errorf("Unknown id")
85 if _, err := (*tc).Close(); err != nil {
89 resTerm := (*tc).GetConfig()
93 // Notify terminal state change or add
94 if err := t.events.Emit(xsapiv1.EVTTargetTerminalRemove, &resTerm, ""); err != nil {
95 t.Log.Errorf("WS Emit EVTTargetTerminalRemove : %v", err)
101 // Get returns the terminal config or nil if not existing
102 func (t *Terminals) Get(id string) *ITERMINAL {
106 tc, exist := t.terms[id]
113 // GetConfigArr returns the config of all terminals as an array
114 func (t *Terminals) GetConfigArr() []xsapiv1.TerminalConfig {
116 defer tmMutex.Unlock()
118 return t.getConfigArrUnsafe()
121 // getConfigArrUnsafe Same as GetConfigArr without mutex protection
122 func (t *Terminals) getConfigArrUnsafe() []xsapiv1.TerminalConfig {
123 conf := []xsapiv1.TerminalConfig{}
124 for _, v := range t.terms {
125 conf = append(conf, (*v).GetConfig())
130 // Open adds a new terminal
131 func (t *Terminals) Open(id string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) {
134 return nil, fmt.Errorf("Unknown id")
137 if sess.IOSocket == nil {
138 return nil, fmt.Errorf("Websocket not established")
141 term, err := (*tc).Open(sess.IOSocket, sess.ID)
143 // Notify term state change
144 if errEmit := t.events.Emit(xsapiv1.EVTTargetTerminalStateChange, &term, sess.ID); errEmit != nil {
145 t.Log.Errorf("WS Emit EVTTargetTerminalStateChange : %v", errEmit)
151 // Close a specific terminal
152 func (t *Terminals) Close(id string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) {
155 return nil, fmt.Errorf("Unknown id")
158 term, err := (*tc).Close()
160 // Notify term state change
161 if errEmit := t.events.Emit(xsapiv1.EVTTargetTerminalStateChange, &term, sess.ID); errEmit != nil {
162 t.Log.Errorf("WS Emit EVTTargetTerminalStateChange : %v", errEmit)
168 // Resize a specific terminal
169 func (t *Terminals) Resize(id string, cols, rows uint16, sess *ClientSession) (*xsapiv1.TerminalConfig, error) {
171 defer tmMutex.Unlock()
175 return nil, fmt.Errorf("Unknown id")
178 term, err := (*tc).Resize(cols, rows)
180 // Notify term state change
181 if errEmit := t.events.Emit(xsapiv1.EVTTargetTerminalStateChange, &term, sess.ID); errEmit != nil {
182 t.Log.Errorf("WS Emit EVTTargetTerminalStateChange : %v", errEmit)
188 // Signal Send a Signal a specific terminal
189 func (t *Terminals) Signal(id, sigName string) error {
191 defer tmMutex.Unlock()
195 return fmt.Errorf("Unknown id")
197 return (*tc).Signal(sigName)