Search code examples
ansiblejinja2ansible-inventoryansible-template

Rendering a template to the remote end and the rendered result should only contain information about the node on which the task is running


Here is the background information for this question: I have a inventory which contains the information about remote nodes. I also have a template file. I'm trying to render this template to remote end and the rendered result should only contain the information about its target. For example, when I render my template to ops1, the result should only contain the information which defined in my Inventory file([ceph_osd] - ops1 - rules

This is my Inventory file:

[cluster]
ops1 ansible_host=192.168.15.80
ops2 ansible_host=192.168.15.81
ops3 ansible_host=192.168.15.82

[ceph_osd]
ops1 rules="{'rule1':{'bcache': '/dev/nvme1n1p7', 'disks': ['/dev/sdb']},'rule2':{'bcache': '/dev/nvme1n1p8', 'disks': ['/dev/sdc']}}"
ops2 rules="{'rule1':{'bcache': '/dev/nvme1n1p7', 'disks': ['/dev/sdb']},'rule2':{'bcache': '/dev/nvme1n1p8', 'disks': ['/dev/sdd']}}"
ops3 rules="{'rule1':{'bcache': '/dev/nvme1n1p7', 'disks': ['/dev/sdc']},'rule2':{'bcache': '/dev/nvme1n1p8', 'disks': ['/dev/sdf']}}"

This is my jinja2 template file:

# clean_bcache.sh.j2
#!/bin/sh

{% for host in groups['ceph_osd'] %}
{% for rule in hostvars[host].rules.values() %}
{% if rule.bcache != 'none' %}
    bcache_name=$(lsblk -o KNAME {{ rule.bcache }} | grep bcache)
    cset.uuid=$(bcache-super-show {{ rule.bcache }} | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
{% for backing_dev in rule.disks %}
    echo 1 > /sys/block/{{backing_dev}}/bcache/stop
    
{% endfor %}
{% endif %}
{% endfor %}
{% endfor %}

My ansible task is as follows:

- hosts: cluster
  name: start bcache deployment
  gather_facts: False
  tasks:
  - name: template
    template: src=./clean_bcache.sh.j2 dest=/opt/clean_bcache.sh

After executing this task, all of the rendered files have the same content, which as shown below.

# clean_bcache.sh
#!/bin/sh
    #########################
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p9 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p9 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdg/bcache/stop
    
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p8 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p8 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdc/bcache/stop
    
    #########################
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p9 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p9 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdc/bcache/stop
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p8 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p8 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdd/bcache/stop
  
    #########################
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p9 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p9 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdg/bcache/stop
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p8 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p8 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdf/bcache/stop
   

What I want to do is to render this file into three different files located on different nodes. The goal I want to achieve is as follows:

The clean_bcache.sh on the remote ops1 should look like follow. As you can see, it only contains the information related to ops1 in the foregoing Inventory

#!/bin/sh
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p9 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p9 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdg/bcache/stop
    
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p8 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p8 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdc/bcache/stop

This is the clean_bcache.sh on ops2.

#!/bin/sh
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p9 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p9 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdc/bcache/stop
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p8 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p8 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdd/bcache/stop

This is the clean_bcache.sh on ops3

#!/bin/sh
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p9 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p9 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdg/bcache/stop
    bcache_name=$(lsblk -o KNAME /dev/nvme1n1p8 | grep bcache)
    cset.uuid=$(bcache-super-show /dev/nvme1n1p8 | grep cset.uuid | awk -F' ' '{print $2}')
    echo ${cset.uuid} > /sys/block/$bcache_name/bcache/detach
    sleep 1
    echo 1 >/sys/fs/bcache/${cset.uuid}/unregister 
    sleep 1
    echo 1 > /sys/block//dev/sdf/bcache/stop

I have googled a lot, but none of them worked.

Any ideas? Thanks in advance!!


Solution

  • To solve this problem, you only need to add a if statement if host == inventory_hostname in your template file.

    #!/bin/sh
    
    {% for host in groups['ceph_osd'] %}
    {% if host == inventory_hostname %}
    {% for rule in hostvars[host].rules.values() %}
    {% if rule.bcache != 'none' %}
        bcache_name=$(lsblk -o KNAME {{ rule.disks | first }} | grep bcache)
        cset_uuid=$(bcache-super-show {{ rule.bcache }} | grep cset.uuid | awk -F' ' '{print $2}')
        echo $cset_uuid > /sys/block/$bcache_name/bcache/detach
        sleep 1
        echo 1 >/sys/fs/bcache/$cset_uuid/unregister 
        sleep 1
    {% for backing_dev in rule.disks %}
        echo 1 > /sys/block/{{backing_dev.split("/") | last}}/bcache/stop
    {% endfor %}
    {% endif %}
    {% endfor %}
    {% endif %}
    {% endfor %}