wilas / vbkick

Tool for building and maintaining VirtualBox VMs described as a code in a single definition file.
Other
8 stars 5 forks source link

Add more convenient command-line utility that types strings into a VM. #36

Open cniswander opened 10 years ago

cniswander commented 10 years ago

(This is one of multiple issues that describe functionality I've implemented offline that I'd like to bring into the official github repository.)

A command-line utility that accepts strings and types them into a VM.

I know that README.md shows how to use convert_2_scancode.py like this:

$ VBoxManage controlvm VM_NAME keyboardputscancode $(printf "Hello VM" | convert_2_scancode.py)

However, my command line utility has advantages: 1) Less typing required 2) Automatically insert small delay between each character to prevent overflowing keyboard buffer. 3) support for <Wait> pseudo-keystroke (sleeps/delays 1 second.)

I realize this could be done by changing convert_2_scancode.py. However, as I make more complicated functionality for this, I like the idea of separating the module now.

wilas commented 10 years ago
$ VBoxManage controlvm VM_NAME keyboardputscancode $(printf "Hello VM" | convert_2_scancode.py)

is far from perfection, special if you try send something like this: "<Multiply(20,Hello)>" so at the moment vbkick is responsible for delays between each character and interpretation of expression.

The weaknes of this solution is that vbkick types something to the VM only during "build" action, so there is a gap for a people which want type a text to existing VM.

I agree that utility which fill the gap is needed, but I think this could be done as a part of convert_2_scancode.py Reasons:

What about this as a finall solution:

# prints to the VM_NAME
$ printf "Hello VM" | convert_2_scancode.py -o "VM_NAME"
# or (prefered)
$ printf "Hello VM" | convert_2_scancode.py "VM_NAME"
# or (VM as a device where you write to)
$ printf "Hello VM" | convert_2_scancode.py "/dev/VM_NAME"
# and following prints scancodes to the stdout
$ printf "Hello VM" | convert_2_scancode.py
cniswander commented 10 years ago

I have two thoughts re Wilas' comment:

  1. I think Wilas' design goals for a command line utility are rather different from my design goals for the utility I wrote for my own use. For example, Wilas isn't complaining about having to type the name of the VM when using the utility 'manually' from the command line. But as I look at his usage examples, I see that he cares about many use cases and options that I don't care about for my own use.
  2. I suggest that the vbkick project might call a command-line utility something like vbtyper.py or vbtype.py. It's short and in keeping with a vb* naming theme.
wilas commented 10 years ago

re.1. A few bits from my and @cniswander email conversation:

"Here's a session in which, using a guest's Unity graphical shell in Ubuntu 12, I close the Firefox browser, open the default terminal, and create a new terminal window and new terminal tab. Note that an empty line sends an , because I thought that was a convenient feature for me."

$ python stringtyper.py
"RubberTree.1 Ubuntu" {21a2ff09-a3bc-43d2-bc4f-02e219311fba}

0 --> RubberTree.1 Ubuntu
Please enter the VM name: 0
st: <AltSpacebar>c
st: <Win><Wait>terminal
st: <400>
st:
st: <CtrlN>
st: <CtrlShiftt>
st:
$
(I terminated session by typing CTRL-D and pressing ENTER KEY, or CTRL-C.) 

A session feature is a something new in this issue thread - I thought that @cniswander only wants send a string to the VM using e.g. printf "Hello VM" | convert_2_scancode.py "VM_NAME" (more about this in one of the above comments), but as you can see from the example his work flow is a bit different.

He creates something cool and I believe useful for others. I would like to add that feature to the convert_2_scancode.py.

I think this could be done by adding extra option for existing convert_2_scancode.py command line utility, e.g:

convert_2_scancode.py -s "VM_NAME"
convert_2_scancode.py --session "VM_NAME"

or creating a new file. I would prefer extend convert_2_scancode.py functionality.

This of course has impact on how things are implemented in convert_2_scancode.py . convert_2_scancode.py needs to work as a both:

My proposition for code organization is to create 2 classes: Typer and Scancodes:

class Typer:
def __init__...
def print_to_stdout...
def print_to_vm()...
def start_session()...raise("Not implemented")

class Scancodes:
"""almost everything what is now in convert_2_scancode"""
def __init__...
def translate_chars...
def get...

You may ask why single file and classes, here is my answer: " I was thinking about classes in a context of code organization rather than OOP - "class" as a collection of functions. It's not rare, e.g: /usr/lib/python2.7/httplib.py or /usr/lib/python2.7/collections.py I'm not afraid of large python file as well - 1200+ LOC is not surprise in python land.

'Basically, if most users of A also need B and vice versa, A and B should probably be in the same module; but if many users will only need one of them and not the other, then they should probably be in distinct modules (perhaps in the same package, i.e., directory with an init.py file in it).' src: https://stackoverflow.com/questions/1801878/the-pythonic-way-of-organizing-modules-and-packages

'A module is a distinct thing that may have one or two dozen closely-related classes. The trick is that a module is something you'll import, and you need that import to be perfectly sensible to people who will read, maintain and extend your software.' src: https://stackoverflow.com/questions/106896/how-many-python-classes-should-i-put-in-one-file

Goal is it to type something to the VM so typer and scancode should live together in the same module. "

re.2. I like vbtyper.py name. +1 for keeping with a vb* naming theme. There is as well another benefit using that name - nice name for python module - underscores are not welcome in python modules name.

@cniswander if I missed something from our conversation please comment here :)