February 20, 2019

Rebranding a tmux tool

Several years ago I had a succession of what you would probably call “dev ops” jobs. I found myself writing lots of elaborate scripts, documenting and automating heretofore manual processes. In hindsight I look back on most of these efforts as futile attempts to fully automate what could not be (one cannot automate away the decisions we people that are a part of ’the process’ need to make!).

One tool that came out of that was something I dubbed ‘sshmux’. I didn’t think to google the name. Not only does sshmux sound a lot like “schmucks”, but there turn out to be quite a few other people that thought sshmux would be a great name for a tool. I’m sure that these are only a subset:

See any recurring themes? SSH. MUX. TMUX. Yep!

The other week I had the flu. Amidst marathon sessions of sweaty snoozing under layers of blankets on the couch, reading Agatha Christy and binge watching Mr Robot, I had a few moments of lucidity.

It was probably Mr Robot that got me thinking about sshmux. I still use sshmux every now and then when I need to execute the same commands on multiple servers (or monitor the same processes, or tail the same logs). But I realized that nowadays I find myself connecting more frequently to docker hosts on my laptop either by themselves, or via docker-compose. After my fever broke, I decided to add some features.

And with features, why not rebrand?

And so I give you an equally improbably but unused name: intmux! You know: “In tmux”. As in “Lets see whats in the syslog for staging, in tmux”. Or “Lets watch pstree while I deploy some fraught feature in tmux”. Or, more Mr Robot like perhaps, “Monitor HTTP traffic with tcpdump on all the webservers in tmux”.

If you don’t get the idea, maybe a video will help:

Here I’ve spun up a few temporary AWS servers to tail the system logs. I was lazy and didn’t want to copy/paste the IP addresses for all these servers, so I’ve just uhm…looked them up with the AWS CLI tools and extracted them from the JSON output (in hindsight that might not have been easier than copying and pasting 4 IP addresses!):

aws ec2 describe-instances | jq '.Reservations[1]|.Instances|.[]|.PublicIpAddress'

But you get the idea: more often than not the information about the servers you want to access are in some other system. With intmux, you can pipe that information straight in.

The servers I started up have one ec2-user that I can login as, which is definitely not my laptop’s user account, so I need to pass along the remote username as an ssh option:

# How do I use this thing?
intmux ssh --help
usage: intmux ssh [-h] [--ssh-options SSH_OPTIONS] [hosts [hosts ...]]

Connect to the provided hosts.

positional arguments:
  hosts                 SSH hosts to connect to.

optional arguments:
  -h, --help            show this help message and exit
  --ssh-options SSH_OPTIONS, -so SSH_OPTIONS
                        Options to pass to SSH connection.

aws ec2 describe-instances | jq '.Reservations[1]|.Instances|.[]|.PublicIpAddress' | intmux ssh --ssh-options "-o User=ec2-user"

# or...do it the straightforward way!
intmux ssh ec2-user@ ec2-user@ ec2-user@ ec2-user@

# or
intmux ssh -so "-o User=ec2-user"

And with that I have simultaneous control over my four servers.

At any rate, during my feverish flu time I decided that I wanted to extend this functionality to work with docker. You can now:

  • intmux docker: connect to local docker containers. Or narrow down the list: intmux docker container1 container2 (the equivalent of creating a new tmux session and creating new panes with docker exec -it container1 bash in each pane). You can control the docker command. For instance, to tail the logs: intmux docker --docker-command 'logs -f' container1 container2.
  • intmux compose: connect to local docker containers associated with the docker-compose.yml in your current directory.
  • intmux ssh-docker: connect to remote docker containers (ie, SSH to remote servers, and connect to the docker containers there).

Head on over to the github intmux to learn more.

© Dane Summers 2023