This commit fixes race conditions in the tsh session player by using
a condition variable to detect state changes rather than unsafely
polling a variable that is written by a separate goroutine.
In addition, fix an off by one error when resuming playback
after pausing. The player's position variable has always stored
the index of the last succesfully played event, so when we resume
playback we should start at position+1 to not re-play the previous
event twice.
Fixes#11479
* Add support for `tsh ssh` on Windows
This adds Windows session support to tsh, taking advantage of ANSI
terminal support and VT emulation added in recent versions Windows
10. On supported Windows versions (Windows 10 1607+), `tsh ssh`
should work as expected in `cmd.exe`, PowerShell, and the new
Windows Terminal app.
* Address a few review comments
* Remove significant chunks of unnecessary tncon code.
Removes the global buffer, `GetVTSeqFromKeyStroke`, and several
ancillary headers and functions that aren't needed for our (current)
use-case. Also removes mouse and focus events.
* Refactor OS-specific terminal handling
This significantly simplifies OS-specific terminal behavior:
* Move OS specific terminal code into a new `terminal` package
* Remove `session_windows.go` in favor of an OS-independent
`session.go`, defer to terminal package for OS specific
functionality.
* Remove ConPTY since it's not needed.
* Always wait for the terminal and ssh session to fully close before
quitting.
* Refactor tncon; ensure the raw reader can be closed and reopened,
remove lots of unnecessary C code.
* Revert dependency changes
* Use WindowsOS constant.
* Fix `tsh play` on Windows
This fixes `tsh play` on Windows by using the new `terminal` module to
initialize the terminal for raw input in a cross-platform way.
Additionally, this simplifies `terminal.New()` since in practice we never
want interactive mode at init time, and fixes a broken unit test.
* Use correct log library
* Fix `tsh play` player controls on Windows
This fixes the console player controls on Windows as well as the timestamp
writer.
* Clean up lints
* Add missing license header
* Fix broken unit test
* Fix cross-compile builds on Linux/Docker
We need windows.h, which is not capitalized in the mingw packages
(and is case insensitive on Windows).
* Address code review feedback
- Rename `Terminal.InitInteractive` to `Terminal.InitRaw`
- Ensure goroutines terminate on close
- Fix outdated godoc comments
- Ensure Terminal event subscribers are cleared (and their channels
are closed)
- Ensure terminal output mode is reset on error in initTerminal
- Bubble up errors in Terminal.Close()
- Add author notice to tncon.c re: our changes
- Add go-ansiterm as a direct dependency
- Run `make update-vendor`
* Add constants and a small player.go TODO.
* Clear linter warning
List of fixed items:
```
integration/helpers.go:1279:2 gosimple S1000: should use for range instead of for { select {} }
integration/integration_test.go:144:5 gosimple S1009: should omit nil check; len() for nil slices is defined as zero
integration/integration_test.go:173:5 gosimple S1009: should omit nil check; len() for nil slices is defined as zero
integration/integration_test.go:296:28 gosimple S1019: should use make(chan error) instead
integration/integration_test.go:570:41 gosimple S1019: should use make(chan interface{}) instead
integration/integration_test.go:685:40 gosimple S1019: should use make(chan interface{}) instead
integration/integration_test.go:759:33 gosimple S1019: should use make(chan string) instead
lib/auth/init_test.go:62:2 gosimple S1021: should merge variable declaration with assignment on next line
lib/auth/tls_test.go:1658:22 gosimple S1024: should use time.Until instead of t.Sub(time.Now())
lib/backend/dynamo/dynamodbbk.go:420:5 gosimple S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/dynamo/dynamodbbk.go:656:12 gosimple S1039: unnecessary use of fmt.Sprintf
lib/backend/etcdbk/etcd.go:458:5 gosimple S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/firestore/firestorebk.go:407:5 gosimple S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/lite/lite.go:317:5 gosimple S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/lite/lite.go:336:6 gosimple S1004: should use !bytes.Equal(value, expected.Value) instead
lib/backend/memory/memory.go:365:5 gosimple S1004: should use !bytes.Equal(expected.Key, replaceWith.Key) instead
lib/backend/memory/memory.go:376:5 gosimple S1004: should use !bytes.Equal(existingItem.Value, expected.Value) instead
lib/backend/test/suite.go:327:10 gosimple S1024: should use time.Until instead of t.Sub(time.Now())
lib/client/api.go:1410:9 gosimple S1003: should use strings.ContainsRune(name, ':') instead
lib/client/api.go:2355:32 gosimple S1019: should use make([]ForwardedPort, len(spec)) instead
lib/client/keyagent_test.go:85:2 gosimple S1021: should merge variable declaration with assignment on next line
lib/client/player.go:54:33 gosimple S1019: should use make(chan int) instead
lib/config/configuration.go:1024:52 gosimple S1019: should use make(services.CommandLabels) instead
lib/config/configuration.go:1025:44 gosimple S1019: should use make(map[string]string) instead
lib/config/configuration.go:930:21 gosimple S1003: should use strings.Contains(clf.Roles, defaults.RoleNode) instead
lib/config/configuration.go:931:22 gosimple S1003: should use strings.Contains(clf.Roles, defaults.RoleAuthService) instead
lib/config/configuration.go:932:23 gosimple S1003: should use strings.Contains(clf.Roles, defaults.RoleProxy) instead
lib/service/supervisor.go:387:2 gosimple S1001: should use copy() instead of a loop
lib/tlsca/parsegen.go:140:9 gosimple S1034: assigning the result of this type assertion to a variable (switch generalKey := generalKey.(type)) could eliminate type assertions in switch cases
lib/utils/certs.go:140:9 gosimple S1034: assigning the result of this type assertion to a variable (switch generalKey := generalKey.(type)) could eliminate type assertions in switch cases
lib/utils/certs.go:167:40 gosimple S1010: should omit second index in slice, s[a:len(s)] is identical to s[a:]
lib/utils/certs.go:204:5 gosimple S1004: should use !bytes.Equal(certificateChain[0].SubjectKeyId, certificateChain[0].AuthorityKeyId) instead
lib/utils/parse/parse.go:116:45 gosimple S1003: should use strings.Contains(variable, "}}") instead
lib/utils/parse/parse.go:116:6 gosimple S1003: should use strings.Contains(variable, "{{") instead
lib/utils/socks/socks.go:192:10 gosimple S1025: should use String() instead of fmt.Sprintf
lib/utils/socks/socks.go:199:10 gosimple S1025: should use String() instead of fmt.Sprintf
lib/web/apiserver.go:1054:18 gosimple S1024: should use time.Until instead of t.Sub(time.Now())
lib/web/apiserver.go:1954:9 gosimple S1039: unnecessary use of fmt.Sprintf
tool/tsh/tsh.go:1193:14 gosimple S1024: should use time.Until instead of t.Sub(time.Now())
```
* Changed import path from github.com/moby/moby to canonical path of
github.com/docker/docker.
* Updated dependency for github.com/docker/docker/pkg/term.
* Updated dependency for github.com/Azure/go-ansiterm.
- replay now works in both web and CLI
- fixed two nasty connection bugs in web sessions
- removed verbose logging/diagnostics
- refactoring of web code by Alexey