Shell Sessions / Tmux¤
Sessions are a required, when you document (or func test) longer command flows, with shared internal or external (e.g. filesystem) state.
- We do not keep internal state within the docu building process but rely on tmux to keep it.
- This makes state accessible out of band, i.e. you can attach to tmux sessions created by lp. This way you can, in long lasting, complex command flows (e.g. creating clusters in the cloud) fix failing commands manually until they run, add the fix to the failing last block and continue with the next.
- Sessions are not automatically destroyed, except you instruct lp to do so.
Mechanics¤
- We send the statements to evaluate over to tmux as a byte stream, using it's
send-keys
feature. - We capture the output of tmux via it's
tmux capture-pane
feature within a loop, until- the expected output is seen or
- the timeout is reached
Example¤
LP Source:
```bash lp:bash session=docs addsrc
ls -lta /etc/systemd
```
Result:
$ ls -lta /etc/systemd
$ ls -lta /etc/systemd
total 64
drwxr-xr-x 139 root root 12288 Apr 7 10:17 ..
drwxr-xr-x 22 root root 4096 Apr 7 10:17 system
-rw-r--r-- 1 root root 1815 Apr 5 20:22 system.conf
drwxr-xr-x 3 root root 4096 Apr 4 21:40 user
drwxr-xr-x 5 root root 4096 Apr 4 21:39 .
-rw-r--r-- 1 root root 642 Jan 10 04:56 resolved.conf
-rw-r--r-- 1 root root 1042 Apr 22 2020 journald.conf
-rw-r--r-- 1 root root 1042 Apr 22 2020 logind.conf
drwxr-xr-x 2 root root 4096 Apr 22 2020 network
-rw-r--r-- 1 root root 604 Apr 22 2020 timesyncd.conf
-rw-r--r-- 1 root root 1185 Apr 22 2020 user.conf
-rw-r--r-- 1 root root 584 Apr 1 2020 networkd.conf
-rw-r--r-- 1 root root 529 Apr 1 2020 pstore.conf
-rw-r--r-- 1 root root 790 Apr 1 2020 sleep.conf
Note that a --colors=always
is not necessary here - the commands are run as if you would type them
into a tmux window - in fact they are, using tmux send-keys
.
Terminal Output¤
You should see output like this in the terminal, when building:
If the icons are missing then you need a proper font.
Tmux Base Index¤
Reminder tmux:
In order the mechanics to work we need to know the tmux window and pane base indexes of the window we are communicating with, i.e. the number of the first window created within a session.
Problem: Default is 0. But users using tmux configure it normally to 1 (easier window switching via shortcuts).
Since we do not want to fully control the life cycle of tmux sessions, i.e. allow the user to interact with it before, during and after our mkdocs sessions, it would be hard and prbly. not robust to always try find the base index currently in use - there are many things which can go wrong here.
So we decided to either
- work out of the box, when base index is already at 1 (configured by the user) OR
- configure the base index automatically, when there is NOT yet a
~/.tmux.conf
on the system - fail when base index is configured to be 0
Warning
The second option involves a creation of ~/.tmux.conf
(which you can naturally modify to your
liking, except setting the base index to a different value than 1).
Tip
If you absolutely need to have 0 for you normal tmux work: Provide for mkdocs a tmux script, pointing to another config file in the make
file
or the environment ($PATH).
def configure_tmux_base_index_1(session_name):
"""
Seems everybody really using it has 1 (on normal keyboards 0 is far away)
and its a hard to detect or change, especially when the messed with it outside of
our control.
On clean systems it will be just missing or: the user / runner does not care.
=> Lets create it - when it is NOT present, so that we can have automatic CI/CD.
While for a normal user (who is using it) we fail if not configured correctly.
"""
fn = env.get('HOME', '') + '/.tmux.conf'
if exists(fn):
return
lp.app.warning('!!! Writing %s to set base index to 1 !!' % fn)
r = [
'set-option -g base-index 1',
'set-window-option -g pane-base-index 1',
'',
]
write_file(fn, '\n'.join(r))
lp.sprun('tmux source-file "%s"' % fn)
wait(0.5)
tmux_kill_session(session_name)
wait(0.5)
tmux_start(session_name)
wait(0.5)