(forgive me for spamming, I should have adjusted the original question , but it felt like I ran into a new hurdle when solving the problem)
I set a goal of running a web server with ansible: figured I'd sit it inside a tmux session. I quickly ran into ansible play hanging forever due to tmux dropping into it's own shell, but with community's help got halfway to the goal. I can run my server, but there's no tmux session to be found on the box.
the playbook's task is this:
tasks:
- name: drop into tmux and run gunicorn
shell:
cmd: tmux has-session -t api || tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
chdir: htmshop_parent
, basically, if the session 'api' doesn't exist, launch a gunicorn (from a virtualenv) within a session, and detach.
the play reported certain success:
TASK [drop into tmux and run gunicorn]
*****************************************
changed: [44.197.228.14] => {"changed": true, "cmd": "tmux has-session -t api || tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000", "delta": "0:00:00.012161", "end": "2021-08-25 14:47:14.284544", "rc": 0, "start": "2021-08-25 14:47:14.272383", "stderr": "no server running on /tmp/tmux-0/default", "stderr_lines": ["no server running on /tmp/tmux-0/default"], "stdout": "", "stdout_lines": []}
tmux reporting no server is running error, is what has-session is expected to do; then the second clause of ||kicks in... at least it does when I run this command manually on the box. But playbook surprises me; the process (gunicorn) is indeed launched (why two? beats me:):
> pgrep -a guni
6542 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
6548 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
but tmux ls tells me no server running on /tmp/tmux-1001/default
Interestingly enough, if I take a look at processes like this:
± |staging ?:13 ✗| → ps auxw | grep guni
root 6541 0.0 0.3 7536 3616 ? Ss 15:14 0:00 tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
root 6542 0.0 2.2 30352 22340 pts/2 Ss+ 15:14 0:00 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
root 6548 0.0 4.1 52532 41984 pts/2 S+ 15:14 0:00 /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/python /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
, I do see the tmux (parent process) also... but where's the session? And in what magical subshell-like thing was this pony started, if not in a tmux session? Or perhaps it is a tmux session of some sort, just not one that my tmux knows about? ¯_(ツ)_/¯
Thank y'all for your time...
Not really an answer, but fleshing out some background as to how tmux
works.
When you run tmux
, it tries to connect to (or create if necessary) a server running on a particular Unix socket. By default, the path to that socket is something like /tmp/tmux-$USERID/default
. You can change the directory using the -L
option or the TMUX_TMPDIR
environment variable. You can ignore both those using -S
to specify an exact path your self.
For example,
$ tmux -L ~/foo ... # Talks to a server via ~/foo/default
$ tmux -S ~/foo/bar # Talks to a server via ~/foo/bar
Your playbook is probably executed under a different user ID than your interactive shell, so tmux
is attempting to communicate with two different servers in that case. I would recommend being explicit in your playbook so that there is no doubt about which server Ansible will create/talk to. Something like
- name: Gunicorn in tmux
environment:
TMUX_TMPDIR: /tmp/my/ansible/tmux/session
tasks:
- name: drop into tmux and run gunicorn
shell:
cmd: tmux has-session -t api || tmux new-session -d -s api /home/akarpov/.local/share/virtualenvs/htmshop_parent-NXHiij2E/bin/gunicorn backend.wsgi:application -b 127.0.0.1:4000
chdir: htmshop_parent
I'm somewhat surprised to see that tmux new-session -d
is still running , as it should have exited immediately after creating the session (or rather, asking the server to create the session). The
, as it should have exited immediately after creating the session (or rather, asking the server to create the session). The
gunicorn processes are indeed running in this session. When a session is created, a new window for the session is created as well, and according to your output, this window is associated with the pseudoterminal
/dev/pts/2`.
If you were to later try to attach to this session, the command tmux attach-session -t api
would send a request to the server, asking it (very roughly speaking) which pseudoterminal is associated with the currently active window of the named session. The tmux
client will then communicate with that pseudoterminal, providing a kind of thin terminal emulation.
So aside from tmux new-session...
continuing to run in the background, everything looks like it should.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.