Added target and terminal support.
[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/lib/xsapiv1"
24         socketio "github.com/googollee/go-socket.io"
25         "github.com/syncthing/syncthing/lib/sync"
26 )
27
28 // Terminals Represent a XDS terminals
29 type Terminals struct {
30         *Context
31         terms map[string]*ITERMINAL
32 }
33
34 // Mutex to make add/delete atomic
35 var tmMutex = sync.NewMutex()
36
37 // TerminalsConstructor Create a new instance of Model Terminal
38 func TerminalsConstructor(ctx *Context) *Terminals {
39         return &Terminals{
40                 Context: ctx,
41                 terms:   make(map[string]*ITERMINAL),
42         }
43 }
44
45 // New Create a new terminal
46 func (t *Terminals) New(cfg xsapiv1.TerminalConfig, targetID string) (*xsapiv1.TerminalConfig, error) {
47
48         tmMutex.Lock()
49         defer tmMutex.Unlock()
50
51         var newT ITERMINAL
52
53         // For now, only SSH term is supported
54         switch cfg.Type {
55         case xsapiv1.TypeTermSSH:
56                 newT = NewTermSSH(t.Context, cfg, targetID)
57         default:
58                 return nil, fmt.Errorf("terminal type not set")
59         }
60
61         termCfg := newT.GetConfig()
62
63         t.terms[termCfg.ID] = &newT
64
65         return &termCfg, nil
66 }
67
68 // Free a specific terminal
69 func (t *Terminals) Free(id string) (*xsapiv1.TerminalConfig, error) {
70
71         tmMutex.Lock()
72         defer tmMutex.Unlock()
73
74         tc := t.Get(id)
75         if tc == nil {
76                 return nil, fmt.Errorf("Unknown id")
77         }
78
79         if _, err := (*tc).Close(); err != nil {
80                 return nil, err
81         }
82
83         resTerm := (*tc).GetConfig()
84
85         delete(t.terms, id)
86
87         return &resTerm, nil
88 }
89
90 // Get returns the terminal config or nil if not existing
91 func (t *Terminals) Get(id string) *ITERMINAL {
92         if id == "" {
93                 return nil
94         }
95         tc, exist := t.terms[id]
96         if !exist {
97                 return nil
98         }
99         return tc
100 }
101
102 // GetConfigArr returns the config of all terminals as an array
103 func (t *Terminals) GetConfigArr() []xsapiv1.TerminalConfig {
104         tmMutex.Lock()
105         defer tmMutex.Unlock()
106
107         return t.getConfigArrUnsafe()
108 }
109
110 // getConfigArrUnsafe Same as GetConfigArr without mutex protection
111 func (t *Terminals) getConfigArrUnsafe() []xsapiv1.TerminalConfig {
112         conf := []xsapiv1.TerminalConfig{}
113         for _, v := range t.terms {
114                 conf = append(conf, (*v).GetConfig())
115         }
116         return conf
117 }
118
119 // Open adds a new terminal
120 func (t *Terminals) Open(id string, sock *socketio.Socket, sessID string) (*xsapiv1.TerminalConfig, error) {
121         tc := t.Get(id)
122         if tc == nil {
123                 return nil, fmt.Errorf("Unknown id")
124         }
125         return (*tc).Open(sock, sessID)
126 }
127
128 // Close a specific terminal
129 func (t *Terminals) Close(id string) (*xsapiv1.TerminalConfig, error) {
130         tc := t.Get(id)
131         if tc == nil {
132                 return nil, fmt.Errorf("Unknown id")
133         }
134         return (*tc).Close()
135 }
136
137 // Resize a specific terminal
138 func (t *Terminals) Resize(id string, cols, rows uint16) (*xsapiv1.TerminalConfig, error) {
139         tmMutex.Lock()
140         defer tmMutex.Unlock()
141
142         tc := t.Get(id)
143         if tc == nil {
144                 return nil, fmt.Errorf("Unknown id")
145         }
146         return (*tc).Resize(cols, rows)
147 }
148
149 // Signal Send a Signal a specific terminal
150 func (t *Terminals) Signal(id, sigName string) error {
151         tmMutex.Lock()
152         defer tmMutex.Unlock()
153
154         tc := t.Get(id)
155         if tc == nil {
156                 return fmt.Errorf("Unknown id")
157         }
158         return (*tc).Signal(sigName)
159 }