Closed thewyzard44 closed 6 years ago
Hi Sean,
Thanks for taking interest in tty and its components!
I have experience with vagrant, capistrano and other ssh interactive things, however I haven't used kitchen login
. It seems to me that you're wishing to build interactive shell that allows you to 'poke' container via the various apis, which in my mind is slightly different from building a full-blown terminal emulator. I may be wrong here but that's how I interpret your words - please correct me.
The IO piping is stable, and I'm now in a place where I'm enabling the user to connect to the container and getting the visuals to render correctly.
I'm not sure what you mean by visuals here? Would you mind elaborating on this?
On that note, I'm looking at writing a terminal emulator supporting either ANSI and/or VT100, and I wonder if you'd like that as an addition to your TTY ecosystem?
As far as I'm aware VT100
is a standard, though old, terminal which supports variety of ANSI codes. Writing full emulation of it is a large task to say the least, there's a lot of things and tools that it needs to support.
The idea behind tty
gems (see http://piotrmurach.github.io/tty/) is to provide foundations, sort of key components to make it easy to build higher abstractions and more complex tools including terminal emulators.
The scope of what you trying to do feels to me outside of tty ecosystem and very specific to your use case. I have already more than a dozen ideas for tty packages including names such as tty-shell
and tty-console
(developed few years ago). I wish to maintain a benevolent control 👑 of all the current and future tty packages to guarantee "my perceived quality" and hence keep the namespace available for future developments.
It is not to say that I'm not interested in collaborating with you on developing this concept further but similarly I feel I can support your development with the tty
components/primitives I've already have or can add. For example, tty-reader shell example demonstrates a very basic idea of building shell that may respond to commands etc...
What I would suggest is for yourself to further explore your idea in a repository under non tty
namespace that you can share so that I fully understand what you're trying to achieve and see how it works.
you're right ;) I still have a few things to figure out in developing this concept. And that it is probably very specific to this use.
When I say VT100 I was just trying to think of something very old and hopefully simple. Perhaps ANSI will be enough? we'll see...
Kitchen, by default, is just a wrapper around vagrant, with a specific workflow for testing chef recipes (and other things). So by default, when you say kitchen login
, it is the same as vagrant ssh
. And the instances created by kitchen are short lived. Its 'normal' use is with kitchen test
which creates instance(s), installs software, runs a battery of tests and then destroys those instance(s) all in one command. kitchen login is only really used at dev time, or for diagnosing what's wrong with your software and/or tests. As such it doesn't need to be full of bells and whistles.
My software is replacing vagrant in that scenario and creating containers in LXC, instead of VMs in vbox. And most containers don't have sshd installed and running, so I have to use LXDs facilities to gain an interactive session. If I were on the LXD host itself, that's as simple as lxc exec xxxxx -- bash
.
But (and this is where my need for a terminal comes in) if you're remote, then you execute bash via LXD's REST api... LXD wires up a PTY for me and publishes some endpoints that I connect via websockets. I'll be verifying this today, but if I were on a linux workstation I don't think there'd be any issues if I just propagate the TERM env. I could just ruby 'print' whatever I receive and my terminal would understand it. (?? we'll see)
But on windows, i run kitchen login
from powershell and powershell doesn't know what to do with some of those escape sequences that it's receiving. Bash command line editing works well, for whatever reason, but if I launch VIM inside the session, it doesn't render very well at all (This is what I meant by 'getting the visuals to render correctly). The cursor doesn't move right and I get partial escape sequences printing on the screen and all sorts of other artifacts. So I need a piece that sits in between the data I'm getting over the websocket, and translates it into something that powershell can display.
(I do wonder if I need to buffer the output to make sure I don't 'print' partial escape sequences on line 42. My linux testing should flush that out.)
So just like WSL bash + ssh sets TERM=xterm-256color and handles the escape sequences from the host, and like powershell ssh sets TERM=cygwin and handles it. I need to set TERM=ansi (or something) and be able to handle and render whatever I receive.
(Thank you for letting me think out loud. It's difficult to visualize within an unfamiliar solution space)
Now that I've better defined the piece that I need, I can see that yea, this is a total one-off and not very useful to many people. It'll only be useful on windows, and only for parsing random data streams because terminals exist for everything else, already.
But, useful to me lol. So I'll get started on it and I'm sure I'll be leveraging tty as much as possible,
Thank you again!
Thank you for fleshing this out, it is much clearer what you're trying to achieve, though I'm not going to pretend that I fully understand your setup. I would probably need to see it in action.
From my personal experience of building tty-prompt I found a lot of inconsistencies in how ANSI codes are interpreted between vt100 terminal and powershell console. I kind of wonder if you really need to go through such pain? Maybe installing a proper terminal emulator such as cmder or ConEmu is all there needs to be to make things right? The newest Windows comes with full blown Ubuntu terminal as well so your work maybe towards the older spectrum of user base. Just couple of thoughts.
I'm glad I could be your 'yellow rubber duck' :duck:, I get tons of value explaining my reasoning to other people! Please keep in touch as your experience using tty libraries is very important to me!
yea I'm just trying not to 'require' my users to install additional software for such a minimally used edge case, though if it's that minimal maybe it would be 'ok' to tell the user to seperately install such and such terminal software if you're on windows and want 'kitchen login' to work. In which case I wouldn't have to incorporate/coordinate that install when they install my gem. (ugly but viable)
It took more days than I thought to try to run my connection with a nearly pure linux command chain, (I got distracted with another issue) but I was right. I ssh'd into my (linux) metal from my WSL terminal (with TERM=xterm-256color). (The same test worked ssh'ing into that metal from powershell with TERM=cygwin)
I launched a xenial container on that metal, installed the chefdk in that container (which includes test-kitchen), cloned my repo, and emulated 'kitchen login'. Everything worked as expected (given my previously linked code segment - without buffering like I thought I might need). I could launch vim, and it ran full screen as expected, with no artifacts. So yes, it's a pure windows/powershell issue. This confirms that the windows-side 'edge' executables WSL/bash+ssh and powershell+ssh are handling the control codes correctly
i.e. I ran vim perfectly via (WSL/bash->ssh or powershell->ssh)->(lxc exec (bash interactively))->(my code redirecting I/O over websockets while propagating the existing TERM=)->(bash interactively)->vim. The pipes connected end to end and were parsed and displayed correctly.
I've tabled this for future dev due to its edgeness.... but FYI a recent discovery is that (windows 10?) powershell supports tput
, and that although there's no TERM environment set, it also supports tset -
which reports to me that it supports cygwin. (although setting TERM=cygwin doesn't work for this connection, either - so that's probably the weirdness that 'you' report in trying to create 'tty-prompt'. It 'says' cygwin, but isn't parsing correctly per whatever control codes linux/(tput?) is sending back to powershell).
If/when I create this terminal I'm not going to worry about WSL because it 'seems' to start in a good place... I think WSL/bash is doing the work (and not WSL/bash->ssh) but if launched from powershell (because powershell->ssh is not in the middle of my use case - only a simple powershell) I'd like a hash that can read received escape codes and map them into symbols (and we can reduce this to something easy like ansi/vt100). I'd then map those 'generic' symbols into an appropriate powershell/tput command that would (assumedly) give me the right escape code to pass to powershell. If that doesn't work, then eff windows.
i.e. whatever terminal emulation is provided by powershell->ssh, which powershell does not itself handle, is what needs replicated, and since tput is there (supposedly on purpose?) it should be used (per linux semantics) and if that doesn't work I'd toss my hands in the air.
(I'm sorry for all the subtexts/subthoughts - I know it's hard to read - but I'm trying to tie together a dozen threads in my brain - and I'm just talking out loud for posterity, not expecting anything)
/facepalm I just had an idea... a linux dev running on a windows box... what are the odds that they don't have WSL installed? Because of the way kitchen works, I have to shell out (to a ruby script in this case) to execute this use-case... I could exec "bash -c 'lxc-shell blah blah blah'". And then I'd have bash doing the terminal handling. That would also work if run from linux. And then I could auto-detect if bash exists, or otherwise propagate a :disable_wsl option to skip the bash part and just run it in powershell with TERM=dumb and wysiwyg it
I'll put some more thought into that and let you know ;) This would reduce my desire for perfection from excluding a handful of users (running windows) to excluding a trickle of non-serious users (that don't have WSL). I can stomach that. The latter group of people could still run it, but the terminal handling would be 'weak'
@piotrmurach
I tried the aforementioned approach a few days ago... wrapping my ruby script in a bash -c 'ruby myscript.rb'
in order to get WSL/bash to handle the terminal rendering It didn't work, for different reasons, but thought you might be interested in what I found.
The short of it is, through this experiment, I found that while under WSL, executing a windows exe (ruby.exe) resets the environment (to the windows env instead of my bash env) which made my experiment moot so I didn't dig too deep... but...
of note to you, before abandoning the experiment, (superficially - because I was running windows Ruby through WSL) it appeared as though ruby needed to use the linux methods to read the input, but was receiving windows keycodes (maybe?).
reminder of my code block: https://github.com/NexusSW/kitchen-lxd_nexus/blob/master/bin/lxc-shell#L52-L71
I haven't fully explored 'why'... just thought it worth mentioning the following to you to add to your arsenal of knowledge/issues:
env['TTY_TEST'] = true
to force the linux console.... it THEN read and fired that event for each keystroke, but (and now my memory is fuzzy) it was receiving windows keycodes while the linux console class wasn't expecting the windows keycodes. I was also fiddling with https://github.com/NexusSW/kitchen-lxd_nexus/blob/master/bin/lxc-shell#L32 to avoid the keymap and I forget which combos I tried before realizing the environment issue and giving up.Anyways.... if running a windows ruby.exe from WSL/bash is a use case that you would like your gem to cover, I'm set up for various tests and would love to help. Due to the environmental differences between windows and WSL, I'm no longer interested in covering this last gap in my user's environments. But I remain available
P.S. that code 'as-is' runs great from powershell (with a TERM=dumb), and also from a pure linux environment. Thank you for the gem that made my 99% use case easy!! Windows users will just have to suffer a slight loss in functionality... we should be used to that by now xD
I have a particular use-case where I'm connecting to an LXD container via the REST api, and websockets, using a windows client -
kitchen login
if you're familiar with that... much like vagrant - similar to an ssh connection, but more raw (no ssh client providing terminal emulation). The goal being an interactive session where you can inspect your container to see what is 'right' or 'wrong' in order to fine-tune your code and/or your tests. As such, it doesn't need to be 'fancy' or 'fully functional' but it does need to 'just work'.The IO piping is stable, and I'm now in a place where I'm enabling the user to connect to the container and getting the visuals to render correctly.
On that note, I'm looking at writing a terminal emulator supporting either ANSI and/or VT100, and I wonder if you'd like that as an addition to your TTY ecosystem? It could be extended to support additional terminals in the future.
I've only kind of 'glanced' through the functions you currently provide, and I've already used a couple of your TTY gems to translate windows input and detect screen size. But, is there anything that I've overlooked that could do this rendering work for me?
Or if not, would you be adverse to including a 'tty-console' gem to your ecosystem? I've only just begun learning about console handling, but I'm assuming at this point (pending further research/testing) that a linux client would not need this special handling (that I could just directly pipe I/O from the container to the user's terminal in linux) so this 'might' be a windows specific deal.