Use go module as dependency tool instead of glide
[src/xds/xds-server.git] / lib / xdsserver / terminals.go
1 /*
2  * Copyright (C) 2018 "IoT.bzh"
3  * Author Sebastien Douheret <sebastien@iot.bzh>
4  *
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
8  *
9  *   http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 package xdsserver
19
20 import (
21         "fmt"
22
23         "gerrit.automotivelinux.org/gerrit/src/xds/xds-server.git/lib/xsapiv1"
24         "github.com/syncthing/syncthing/lib/sync"
25 )
26
27 // Terminals Represent a XDS terminals
28 type Terminals struct {
29         *Context
30         terms map[string]*ITERMINAL
31 }
32
33 // Mutex to make add/delete atomic
34 var tmMutex = sync.NewMutex()
35
36 // TerminalsConstructor Create a new instance of Model Terminal
37 func TerminalsConstructor(ctx *Context) *Terminals {
38         return &Terminals{
39                 Context: ctx,
40                 terms:   make(map[string]*ITERMINAL),
41         }
42 }
43
44 // New Create a new terminal
45 func (t *Terminals) New(cfg xsapiv1.TerminalConfig, targetID string) (*xsapiv1.TerminalConfig, error) {
46
47         tmMutex.Lock()
48         defer tmMutex.Unlock()
49
50         var newT ITERMINAL
51
52         // For now, only SSH term is supported
53         switch cfg.Type {
54         case xsapiv1.TypeTermSSH:
55                 newT = NewTermSSH(t.Context, cfg, targetID)
56         default:
57                 return nil, fmt.Errorf("terminal type not set")
58         }
59
60         termCfg := newT.GetConfig()
61
62         t.terms[termCfg.ID] = &newT
63
64         termCfg.Status = xsapiv1.StatusTermEnable
65
66         // Notify terminal add
67         if err := t.events.Emit(xsapiv1.EVTTargetTerminalAdd, &termCfg, ""); err != nil {
68                 t.Log.Errorf("WS Emit EVTTargetTerminalAdd : %v", err)
69         }
70
71         return &termCfg, nil
72 }
73
74 // Free a specific terminal
75 func (t *Terminals) Free(id string) (*xsapiv1.TerminalConfig, error) {
76
77         tmMutex.Lock()
78         defer tmMutex.Unlock()
79
80         tc := t.Get(id)
81         if tc == nil {
82                 return nil, fmt.Errorf("Unknown id")
83         }
84
85         if _, err := (*tc).Close(); err != nil {
86                 return nil, err
87         }
88
89         resTerm := (*tc).GetConfig()
90
91         delete(t.terms, id)
92
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)
96         }
97
98         return &resTerm, nil
99 }
100
101 // Get returns the terminal config or nil if not existing
102 func (t *Terminals) Get(id string) *ITERMINAL {
103         if id == "" {
104                 return nil
105         }
106         tc, exist := t.terms[id]
107         if !exist {
108                 return nil
109         }
110         return tc
111 }
112
113 // GetConfigArr returns the config of all terminals as an array
114 func (t *Terminals) GetConfigArr() []xsapiv1.TerminalConfig {
115         tmMutex.Lock()
116         defer tmMutex.Unlock()
117
118         return t.getConfigArrUnsafe()
119 }
120
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())
126         }
127         return conf
128 }
129
130 // Open adds a new terminal
131 func (t *Terminals) Open(id string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) {
132         tc := t.Get(id)
133         if tc == nil {
134                 return nil, fmt.Errorf("Unknown id")
135         }
136
137         if sess.IOSocket == nil {
138                 return nil, fmt.Errorf("Websocket not established")
139         }
140
141         term, err := (*tc).Open(sess.IOSocket, sess.ID)
142
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)
146         }
147
148         return term, err
149 }
150
151 // Close a specific terminal
152 func (t *Terminals) Close(id string, sess *ClientSession) (*xsapiv1.TerminalConfig, error) {
153         tc := t.Get(id)
154         if tc == nil {
155                 return nil, fmt.Errorf("Unknown id")
156         }
157
158         term, err := (*tc).Close()
159
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)
163         }
164
165         return term, err
166 }
167
168 // Resize a specific terminal
169 func (t *Terminals) Resize(id string, cols, rows uint16, sess *ClientSession) (*xsapiv1.TerminalConfig, error) {
170         tmMutex.Lock()
171         defer tmMutex.Unlock()
172
173         tc := t.Get(id)
174         if tc == nil {
175                 return nil, fmt.Errorf("Unknown id")
176         }
177
178         term, err := (*tc).Resize(cols, rows)
179
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)
183         }
184
185         return term, err
186 }
187
188 // Signal Send a Signal a specific terminal
189 func (t *Terminals) Signal(id, sigName string) error {
190         tmMutex.Lock()
191         defer tmMutex.Unlock()
192
193         tc := t.Get(id)
194         if tc == nil {
195                 return fmt.Errorf("Unknown id")
196         }
197         return (*tc).Signal(sigName)
198 }