简体   繁体   English

Ansible systemd挂载依赖

[英]Ansible systemd mount dependency

I use Ansible to deploy a systemd unit file to all the servers in an estate and enable it to start on boot.我使用 Ansible 将 systemd 单元文件部署到房地产中的所有服务器并使其能够在启动时启动。 On some of those servers, the binary defined in the unit file is on a different filesystem.在其中一些服务器上,单元文件中定义的二进制文件位于不同的文件系统上。 This requires the unit file to have a dependency on that filesystem being mounted.这要求单元文件依赖于被挂载的文件系统。 Eg:例如:

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

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

[Install]
WantedBy = multi-user.target

Currently the unit file is deployed by Ansible as a static file, using the ansible.builtin.copy module.目前,单元文件由 Ansible 部署为 static 文件,使用ansible.builtin.copy模块。 Is there a way I can convert this to a template and append the mountpoint to After = if /usr is a mountpoint?有没有办法可以将它转换为模板和 append 挂载点到After =如果/usr是挂载点?

Ansible fact ansible_mounts keeps the list of the mount points. Ansible 事实上ansible_mounts保存挂载点列表。 Let's use the following vars for testing让我们使用以下变量进行测试

    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:
      - /

Create a dictionary of widgets and related mount points, eg创建小部件和相关安装点的字典,例如

    - 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') }}"

gives

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

Then the flow should be trivial, eg那么流程应该是微不足道的,例如

    - 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 }}"

gives

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

To test the real stuff, in the code, replace my_ansible_mounts with ansible_mounts and fit the widgets and hosts to your needs.要测试真实的东西,在代码中,将my_ansible_mounts替换为ansible_mounts并根据您的需要调整小部件主机

Just use template task and in src template task have a condition to print required block based on a condition.只需使用模板任务,并且在src模板任务中有条件根据条件打印所需的块。 You can pass a varible to template task and make a decision based on it, ie.您可以将变量传递给模板任务并根据它做出决定,即。 you first check if that filesystem is needed in a task, then generate file based on the template task.您首先检查任务中是否需要该文件系统,然后根据模板任务生成文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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