【问题标题】:Ansible systemd mount dependencyAnsible systemd 挂载依赖
【发布时间】:2021-03-24 08:34:54
【问题描述】:

我使用 Ansible 将 systemd 单元文件部署到房地产中的所有服务器,并使其能够在启动时启动。在其中一些服务器上,单元文件中定义的二进制文件位于不同的文件系统上。这要求单元文件依赖于被挂载的文件系统。例如:

[Unit]
Description = Start the widget
After = network.target usr.mount

[Service]
Type = simple
ExecStart = /usr/bin/widget

[Install]
WantedBy = multi-user.target

目前,Ansible 使用ansible.builtin.copy 模块将单元文件部署为静态文件。如果/usr 是挂载点,有没有办法可以将其转换为模板并将挂载点附加到After =

【问题讨论】:

  • “/usr”会自动转换为“usr.mount”还是有任何映射?例如可能还有“/usr/local/”挂载点。
  • @VladimirBotka 它似乎通过将 / 替换为 - 来翻译。例如。 /usr/local 变成 usr-local.mount。运行systemctl list-units --type=mount 会显示所有内容。

标签: ansible systemd


【解决方案1】:

Ansible fact ansible_mounts 保存了挂载点的列表。让我们使用以下变量进行测试

    widgets:
      - /usr/local/apps/widget
      - /usr/share/apps/widget
      - /scratch/apps/widget
    my_ansible_mounts:
      - mount: /
      - mount: /boot/efi
      - mount: /usr
      - mount: /usr/local
    root:
      - /

创建一个包含小部件和相关挂载点的字典,例如

    - set_fact:
        _mlist: []
    - set_fact:
        _mlist: "{{ _mlist + [{'dict': item.0, 'mount': item.1}] }}"
      with_nested:
        - "{{ widgets }}"
        - "{{ my_ansible_mounts|map(attribute='mount')|difference(root) }}"
      when: item.0|regex_search('^' ~ item.1) != None
    - set_fact:
        _mdict: {}
    - set_fact:
        _mdict: "{{ _mdict|combine({item.0: item.1|
                                            map(attribute='mount')|
                                            map('regex_replace', '/', '-')|
                                            list}) }}"
      loop: "{{ _mlist|groupby('dict') }}"

给予

  _mdict:
    /usr/local/apps/widget:
    - -usr
    - -usr-local
    /usr/share/apps/widget:
    - -usr

那么流程应该是微不足道的,例如

    - debug:
        msg: |-
          {% if _mdict[item]|default([])|length > 0 %}
          [Unit]
          Description = Start the widget
          After = network.target{% for i in _mdict[item] %} {{ i[1:] }}.mount{% endfor %}


          {% endif %}
          [Service]
          Type = simple
          ExecStart = {{ item }}
      loop: "{{ widgets }}"

给予

ok: [localhost] => (item=/usr/local/apps/widget) => 
  msg: |-
    [Unit]
    Description = Start the widget
    After = network.target usr.mount usr-local.mount
  
    [Service]
    Type = simple
    ExecStart = /usr/local/apps/widget
ok: [localhost] => (item=/usr/share/apps/widget) => 
  msg: |-
    [Unit]
    Description = Start the widget
    After = network.target usr.mount
  
    [Service]
    Type = simple
    ExecStart = /usr/share/apps/widget
ok: [localhost] => (item=/scratch/apps/widget) => 
  msg: |-
    [Service]
    Type = simple
    ExecStart = /scratch/apps/widget

要测试真实的东西,在代码中,将 my_ansible_mounts 替换为 ansible_mounts 并适合 widgetshosts 满足您的需求。

【讨论】:

    【解决方案2】:

    只需使用 template 任务,并且在 src 模板任务中有一个条件来根据条件打印所需的块。您可以将变量传递给 template 任务并根据它做出决定,即。您首先检查任务中是否需要该文件系统,然后根据模板任务生成文件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      相关资源
      最近更新 更多