Python Remote Terminal App

Overview

PyPi module N/A
git repository https://bitbucket.org/arrizza-public/remote-terminal
git command git clone git@bitbucket.org:arrizza-public/remote-terminal.git
Verification Report https://arrizza.com/web-ver/python-remote-terminal-report.html
Version Info
  • Ubuntu 22.04 jammy, Python 3.10

Summary

I do a fair amount of cross-platform projects. The same app/module that runs on Ubuntu needs to run correctly on macOS and Windows (via MSYS2). Normally I write the code on Ubuntu, push it to the git repo and then go to the other PC (mac or win), do a git pull and try the same command to see if it works there. If it fails, then fix it on the mac/win and reverse all that back to Ubuntu and check it there. All with logging in again and again because the screen goes black.

That's cumbersome. This app is an attempt to make that easier.

The new process is:

  • Initial setup (only done once per project):
    • set up a remote-terminal server on the macOS (still be ported to windows/msys2!)
    • start the client GUI on Ubuntu
    • setup the GUI widgets to point to the matching project on the Mac
  • make a code change on Ubuntu. remote-terminal will use rsync to copy those file changes over to the Mac.
  • run a command on Ubuntu. Enter the same command in remote-terminal and click Send. That executes the same command on the Mac and sends the output back to the GUI.
  • Repeat until done.

Warnings

The rsync will delete any files/directories in the destination (e.g. Mac) that are not on the source (e.g. Ubuntu). This means that if the directories are the same project, the files on the Mac will be deleted!

It can be worse. If you name the home directory on the destination PC (e.g. Mac), then it will delete EVERYTHING in your home directory.

To mitigate: check the full directory path shown on the GUI to ensure it matches the correct path to the actual directory on the destination PC (e.g. Mac)

To Use

1) Open cfg.py and adjust these values as you need:

  • max_cmds set the maximum number of commands/directories in the Combobox lists in the GUI. (default: 20)
  • ip_address set this to the IP address where the server runs (default: 10.0.0.7)
  • ip_port set this to the IP port for the server (default: 5002)
  • status_dir the GUI saves various content to a json file so on restart it behaves the same way. Set status_dir to the directory where app_status.json can be saved. (default: "out" directory)
  • ignore_paths these are directories or subdirectories that should be ignored by rsync. Typically, these are temp directories or a ones that should/must be different between the two platforms.
  • dst_rootdir the root of the destination directory used by rsync

2) On the destination PC (e.g. Mac):

3) On the client PC (e.g. Ubuntu):

  • do a ./do_install in this directory too.
  • start remote-terminal using doit.
  • The GUI should start.

Check the "Sync Paused. " shows the correct directory and ssh info for using rsync to your destination PC (e.g. Mac)

4) The server window should show that a ping-pong successfully occurred between the client and server:

 --  tx: ping
 --  rx: pong

5) Enter "pwd" as the command to send. Click Send.

The server should respond with the correct directory on the destination (e.g. Mac).

 --  tx: packet: {"cmd": "pwd", "working_dir": "~/projects/web/remote-terminal"}
 --  cmd_client  : start cmd output -->
 --  rx: [  1] /Users/arrizza/projects/web/remote-terminal
 --  rx: cmd rc=0
 --  rx: ack
 --  cmd_client  : end of command output

Try other commands for example ls or ls -al.

6) double-check(!!) the directory on the destination PC (e.g. Mac). If it is correct, then click "Start Sync".

From this moment on, any changes you make on your client PC (e.g. Ubuntu) will be automatically copied over to the destination PC (e.g. Mac)

7) If you have some additional files or directories you'd like the rsync to ignore, see lib/watcher/watcher_rsync.py _run_rsync() function.

8) Move the GUI window to where you want it. Close the window. Restart the GUI.

  • the window should be back where you left it
  • the last command you used should be there
  • the last execution directory you entered should be there
  • the Sync directory should still be there
  • The Sync should still be active (assuming you left it running). The button should be a sunken "Stop Sync".

That's it!

Stand-alone GUI executable

Once you have this working as you need it, you can create a GUI executable via PyInstaller.

./do_build
==== do_build: starting...
<snip>
     do_build: overall rc=0

# the executable is in the dist directory:
$ ls -al dist
total 10476
drwxrwxr-x  2 arrizza arrizza     4096 Jul  5 20:27 .
drwxrwxr-x 12 arrizza arrizza     4096 Jul  5 20:27 ..
-rwxr-xr-x  1 arrizza arrizza 10715472 Jul  5 20:27 rem-term

If you copy the executable to a directory in your PATH then you can invoke the GUI anywhere:

cp dist/rem-term ~/bin

cd ../some-other-project

rem-term
# gui starts here

Note you will have to re-enter the directory info etc. in the GUI or copy the relevant content of the out/app_status. py file:

{
    "cmd_list": [
        "./do_ut",
        "pwd",
        "echo hi there",
        "./do_lint",
        "./do_doc"
    ],
    "loc_list": [
        "~/projects/web/remote-terminal",
        "~/projects/remoteterminal",
        "."
    ],
    "rsync_dirs": [
        "projects/web/remote-terminal",
        "projects/remoteterminal",
        "."
    ],
    "rsync_state": false,   <=== make sure this is initially false!
    "window": [
        1920,
        177
    ]
}

WARNING: strongly recommend you start with rsync_state: false to ensure the rsync data is correct.

Enhancements

  • There are probably some code or configuration that is specific to my PC setup. These will need to be made configurable via a config file of some sort. See cfg.py for most of these values.

  • currently the server only has been tested on Ubuntu and macOS. Needs testing/tweaking on a Windows/MSYS2.

  • get the GUI to work with both a Mac and Windows connection at the same time. Show the logs and cmd execution from both platforms. It may be very convenient to run the same command on both machines at the same time as well (but could be difficult to implement correctly).

- John Arrizza