How to access the shell or shell-based applications via the internet?
In HackerEarth at the start of 2020, we were trying to create new problem types named fullstack and DevOps. In these 2 problem types, the candidate would need shell access to the ECS(Fargate) container in which their code is running…
Providing access to an EC2 machine is always possible. It can be done with the help of SSH/SSM. But in our case, we were using ECS(Fargate) which made it impossible directly. To solve this, we planned to create a lightweight web application that works the same as SSM manager but for our ECS(Fargate) containers. From here the new project webpty started :)
Development
To make development faster nowadays everyone uses web frameworks. For us the application needs to be lightweight also it should support both WebSocket and HTTP together, so I decided to use tornado here.
The above snippet creates a simple web server in the tornado that listens in port 8080.
The above WebSocket handler function handles all the WebSocket request that comes to the terminal from UI. This is responsible for creating a forked process on opening a connection if not already forked. Once forked it stored the process_id and file_descriptor of that process.
On every new message, it gets the data from the message and writes it to file_descriptor of the forked process using os.write()
Writing to the file_descriptor is done by the handler, but reading from the file descriptor and sending the output needs to be done in an async fashion. After some testing, I decided to use the gen.coroutine module available in the tornado.
The above read_and_update_web_terminal function is triggered on open of a connection instance. The instance here refers to the WebSocket handler instance. This watches the file_descriptor if any output is generated. If generated, with the help of os.read() it reads and writes it as a message with the handler instance.
The final server.py file looked like this,
And finally to show up that beautiful terminal in the web browser I used xterm.js.
For everyone to enjoy using this, I have published this as a pip package. Follow the simple instructions below to set this up.
Installation
Use python package manager pip to install this package.
$ pip install webpty
Usage
$ webpty --cmd=$SHELL
This $SHELL can be any shell or shell-based application that is present in your system.
Example: Python Shell Sharing :)
$ webpty --cmd=python
Once the web application started head over to http://localhost:8000/ on your browser and use your python shell from the browser.
Other applications
There are some cool features in the pipeline. To get an update on the latest releases refer to GitHub.