简体   繁体   中英

running server in tmux through ansible

(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM