运行 tmux 中的服务器通过 ansible

running server in tmux through ansible

(原谅我乱喷,本来应该调整的,但是感觉自己运行在解决问题的时候又闯了一个新的坎)

我设定了一个目标,运行使用 ansible 构建一个网络服务器:我想我会把它放在一个 tmux 会话中。由于 tmux 掉入它自己的 shell,我很快 运行 进入 ansible play 永远挂起,但在社区的帮助下我已经完成了一半的目标。我 可以 运行 我的服务器,但是在盒子上找不到 tmux 会话。

剧本的任务是这样的:

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

,基本上,如果会话 'api' 不存在,则在会话中启动 gunicorn(从 virtualenv),然后分离。

该剧取得一定的成功:

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 报告没有服务器是 运行ning 错误,这是 has-session 应该做的;然后是 || 的第二个子句开始...至少它 当我 运行 在盒子上手动执行此命令时。但是剧本让我感到惊讶;进程 (gunicorn) 确实启动了(为什么是两个?打败我了!):

> 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

但是 tmux ls 告诉我 no server 运行ning on /tmp/tmux-1001/default

有趣的是,如果我看一下这样的过程:

± |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

,我确实也看到了 tmux(父进程)...但是会话在哪里?如果不是在 tmux 会话中,这匹小马是在什么神奇的 subshell 之类的东西中启动的?或者它可能是某种 tmux 会话,只是我的 tmux 不知道? ¯_(ツ)_/¯

谢谢大家的宝贵时间...

不是真正的答案,而是充实了一些关于 tmux 工作原理的背景知识。

当您 运行 tmux 时,它会尝试连接到(或在必要时创建)特定 Unix 套接字上的服务器 运行ning。默认情况下,该套接字的路径类似于 /tmp/tmux-$USERID/default。您可以使用 -L 选项或 TMUX_TMPDIR 环境变量更改目录。你可以忽略那些使用 -S 来指定你自己的确切路径。

例如,

$ tmux -L ~/foo ...   # Talks to a server via ~/foo/default
$ tmux -S ~/foo/bar   # Talks to a server via ~/foo/bar

您的剧本可能是在与交互式 shell 不同的用户 ID 下执行的,因此 tmux 在这种情况下会尝试与两个不同的服务器通信。我建议在您的剧本中明确说明,以便毫无疑问 Ansible 将 create/talk 连接到哪个服务器。像

- 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

看到 tmux new-session -d 还是 运行ning, as it should have exited immediately after creating the session (or rather, asking the server to create the session). The gunicornprocesses 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` 有点惊讶。

如果您稍后尝试附加到此会话,命令 tmux attach-session -t api 将向服务器发送请求,询问(非常粗略地说)哪个伪终端与当前活动的关联 window 的命名会话。 tmux 客户端随后将与该伪终端通信,提供一种瘦终端仿真。

所以除了 tmux new-session ... 继续在后台 运行 之外,一切看起来都应该如此。