diff options
Diffstat (limited to 'lib/xdsserver/terminals.go')
-rw-r--r-- | lib/xdsserver/terminals.go | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/lib/xdsserver/terminals.go b/lib/xdsserver/terminals.go new file mode 100644 index 0000000..36623ab --- /dev/null +++ b/lib/xdsserver/terminals.go @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2018 "IoT.bzh" + * Author Sebastien Douheret <sebastien@iot.bzh> + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package xdsserver + +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" +) + +// Terminals Represent a XDS terminals +type Terminals struct { + *Context + terms map[string]*ITERMINAL +} + +// Mutex to make add/delete atomic +var tmMutex = sync.NewMutex() + +// TerminalsConstructor Create a new instance of Model Terminal +func TerminalsConstructor(ctx *Context) *Terminals { + return &Terminals{ + Context: ctx, + terms: make(map[string]*ITERMINAL), + } +} + +// New Create a new terminal +func (t *Terminals) New(cfg xsapiv1.TerminalConfig, targetID string) (*xsapiv1.TerminalConfig, error) { + + tmMutex.Lock() + defer tmMutex.Unlock() + + var newT ITERMINAL + + // For now, only SSH term is supported + switch cfg.Type { + case xsapiv1.TypeTermSSH: + newT = NewTermSSH(t.Context, cfg, targetID) + default: + return nil, fmt.Errorf("terminal type not set") + } + + termCfg := newT.GetConfig() + + t.terms[termCfg.ID] = &newT + + return &termCfg, nil +} + +// Free a specific terminal +func (t *Terminals) Free(id string) (*xsapiv1.TerminalConfig, error) { + + tmMutex.Lock() + defer tmMutex.Unlock() + + tc := t.Get(id) + if tc == nil { + return nil, fmt.Errorf("Unknown id") + } + + if _, err := (*tc).Close(); err != nil { + return nil, err + } + + resTerm := (*tc).GetConfig() + + delete(t.terms, id) + + return &resTerm, nil +} + +// Get returns the terminal config or nil if not existing +func (t *Terminals) Get(id string) *ITERMINAL { + if id == "" { + return nil + } + tc, exist := t.terms[id] + if !exist { + return nil + } + return tc +} + +// GetConfigArr returns the config of all terminals as an array +func (t *Terminals) GetConfigArr() []xsapiv1.TerminalConfig { + tmMutex.Lock() + defer tmMutex.Unlock() + + return t.getConfigArrUnsafe() +} + +// getConfigArrUnsafe Same as GetConfigArr without mutex protection +func (t *Terminals) getConfigArrUnsafe() []xsapiv1.TerminalConfig { + conf := []xsapiv1.TerminalConfig{} + for _, v := range t.terms { + conf = append(conf, (*v).GetConfig()) + } + return conf +} + +// Open adds a new terminal +func (t *Terminals) Open(id string, sock *socketio.Socket, sessID string) (*xsapiv1.TerminalConfig, error) { + tc := t.Get(id) + if tc == nil { + return nil, fmt.Errorf("Unknown id") + } + return (*tc).Open(sock, sessID) +} + +// Close a specific terminal +func (t *Terminals) Close(id string) (*xsapiv1.TerminalConfig, error) { + tc := t.Get(id) + if tc == nil { + return nil, fmt.Errorf("Unknown id") + } + return (*tc).Close() +} + +// Resize a specific terminal +func (t *Terminals) Resize(id string, cols, rows uint16) (*xsapiv1.TerminalConfig, error) { + tmMutex.Lock() + defer tmMutex.Unlock() + + tc := t.Get(id) + if tc == nil { + return nil, fmt.Errorf("Unknown id") + } + return (*tc).Resize(cols, rows) +} + +// Signal Send a Signal a specific terminal +func (t *Terminals) Signal(id, sigName string) error { + tmMutex.Lock() + defer tmMutex.Unlock() + + tc := t.Get(id) + if tc == nil { + return fmt.Errorf("Unknown id") + } + return (*tc).Signal(sigName) +} |