diff --git a/ansible/roles/fanout/tasks/fanout_sonic.yml b/ansible/roles/fanout/tasks/fanout_sonic.yml index 04a92835dc..85fccb5243 100644 --- a/ansible/roles/fanout/tasks/fanout_sonic.yml +++ b/ansible/roles/fanout/tasks/fanout_sonic.yml @@ -11,13 +11,15 @@ dest=/etc/sonic/vlan.json become: yes +- include_tasks: add_container_to_inventory.yml + vars: + container_name: swss + - name: disable all copp rules copy: content='[]' dest=/etc/swss/config.d/00-copp.config.json become: yes - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i swss python + delegate_to: "{{ ansible_host }}_swss" - name: generate config_db.json shell: sonic-cfggen -H -j /etc/sonic/vlan.json -j /etc/sonic/init_cfg.json --print-data > /etc/sonic/config_db.json diff --git a/ansible/roles/sonic-common/tasks/lldp.yml b/ansible/roles/sonic-common/tasks/lldp.yml index 6b690cab3e..4384bea123 100644 --- a/ansible/roles/sonic-common/tasks/lldp.yml +++ b/ansible/roles/sonic-common/tasks/lldp.yml @@ -23,6 +23,10 @@ docker_volumes: - /etc/sonic/:/etc/sonic/:ro +- include_tasks: add_container_to_inventory.yml + vars: + container_name: lldp + - block: - name: Setup LLDPD Daemon Config File become: true @@ -43,9 +47,7 @@ # Force handler flush to trigger daemon restarts - meta: flush_handlers - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: Copy lldpctl helper script become: true diff --git a/ansible/roles/sonic-common/tasks/sensors_check.yml b/ansible/roles/sonic-common/tasks/sensors_check.yml index 1a915d9e38..067686367d 100644 --- a/ansible/roles/sonic-common/tasks/sensors_check.yml +++ b/ansible/roles/sonic-common/tasks/sensors_check.yml @@ -6,16 +6,13 @@ shell: show platform summary | grep Platform | awk '{print $2}' register: platform -- set_fact: - ansible_python_interpreter: "docker exec -i {{ pmon_ps.stdout }} python" +- include_tasks: add_container_to_inventory.yml + vars: + container_name: "{{ pmon_ps.stdout }}" - name: Gather sensors sensors_facts: checks={{ sensors_checks[platform.stdout] }} - vars: - ansible_shell_type: docker - -- set_fact: - ansible_python_interpreter: "/usr/bin/python" + delegate_to: "{{ ansible_host }}_{{ pmon_ps.stdout }}" - name: Output of sensors information debug: var=vars['sensors'] diff --git a/ansible/roles/sonic-common/tasks/snmp.yml b/ansible/roles/sonic-common/tasks/snmp.yml index f328a64a21..ad4f195490 100644 --- a/ansible/roles/sonic-common/tasks/snmp.yml +++ b/ansible/roles/sonic-common/tasks/snmp.yml @@ -63,6 +63,10 @@ delegate_to: localhost register: snmp_remap +- include_tasks: add_container_to_inventory.yml + vars: + container_name: snmp + - block: - name: Check version of snmpd shell: dpkg-query -W --showformat='${Version}' snmpd @@ -108,6 +112,4 @@ # Force handler flush to trigger daemon restarts - meta: flush_handlers - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i snmp python + delegate_to: "{{ ansible_host }}_snmp" diff --git a/ansible/roles/sonicv2/tasks/quagga.yml b/ansible/roles/sonicv2/tasks/quagga.yml index 290cb8a835..e63f82e234 100644 --- a/ansible/roles/sonicv2/tasks/quagga.yml +++ b/ansible/roles/sonicv2/tasks/quagga.yml @@ -26,6 +26,10 @@ docker_volumes_from: - database +- include_tasks: add_container_to_inventory.yml + vars: + container_name: bgp + - block: - name: Copy Device Specific Quagga Zebra Configuration File. become: true @@ -78,9 +82,7 @@ - isolate - unisolate - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i bgp python + delegate_to: "{{ ansible_host }}_bgp" - name: Copy vtysh helper script become: true diff --git a/ansible/roles/sonicv2/tasks/teamd_interface.yml b/ansible/roles/sonicv2/tasks/teamd_interface.yml index feeda01322..4e7f941e4d 100644 --- a/ansible/roles/sonicv2/tasks/teamd_interface.yml +++ b/ansible/roles/sonicv2/tasks/teamd_interface.yml @@ -1,19 +1,21 @@ +- include_tasks: add_container_to_inventory.yml + vars: + container_name: teamd + - block: - - name: Ensure /etc/teamd folder exists - become: true - file: path=/etc/teamd - state=directory + - name: Ensure /etc/teamd folder exists + become: true + file: path=/etc/teamd + state=directory - - debug: msg={{ item }} + - debug: msg={{ item }} - - name: Copy teamd configuration file - become: true - template: src=teamd.j2 - dest=/etc/teamd/{{ item['name'] }}.conf - owner=root - group=root - mode=644 + - name: Copy teamd configuration file + become: true + template: src=teamd.j2 + dest=/etc/teamd/{{ item['name'] }}.conf + owner=root + group=root + mode=644 - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i teamd python + delegate_to: "{{ ansible_host }}_teamd" diff --git a/ansible/roles/test/tasks/acltb_ranges_test.yml b/ansible/roles/test/tasks/acltb_ranges_test.yml index 14773cc679..b303bc5101 100644 --- a/ansible/roles/test/tasks/acltb_ranges_test.yml +++ b/ansible/roles/test/tasks/acltb_ranges_test.yml @@ -52,6 +52,11 @@ # Outer block to execute laganalizer in always block - block: # Perform the test: generate and apply acl jsons + + - include_tasks: add_container_to_inventory.yml + vars: + container_name: swss + - block: - name: Copy JSON configs into docker filesystem template: src={{ item }}.j2 dest=/tmp/{{ item }}.json @@ -77,9 +82,7 @@ with_items: - "{{ acltb_configs[::-1] }}" - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i swss python + delegate_to: "{{ ansible_host }}_swss" always: - include_tasks: roles/test/files/tools/loganalyzer/loganalyzer_analyze.yml diff --git a/ansible/roles/test/tasks/add_container_to_inventory.yml b/ansible/roles/test/tasks/add_container_to_inventory.yml new file mode 100644 index 0000000000..32d2f60519 --- /dev/null +++ b/ansible/roles/test/tasks/add_container_to_inventory.yml @@ -0,0 +1,26 @@ +- name: Add/update the public key in the "{{ lookup('env','HOME') + '/.ssh/known_hosts' }}" + delegate_to: localhost + known_hosts: + name: "{{ ansible_host }}" + key: "{{ lookup('pipe', 'ssh-keyscan ' + ansible_host) }}" + state: "present" + +- name: Generate an OpenSSH keypair + delegate_to: localhost + openssh_keypair: + path: "{{ lookup('env','HOME') + '/.ssh/id_rsa' }}" + register: out + +- name: Set authorized key + authorized_key: + user: "{{ ansible_ssh_user }}" + state: present + key: "{{ out.public_key }}" + +- name: Add {{ container_name }} container to inventory + add_host: + name: "{{ ansible_host }}_{{ container_name }}" + ansible_connection: docker + ansible_host: "{{ container_name }}" + ansible_docker_extra_args: "-H=ssh://{{ ansible_ssh_user }}@{{ ansible_host }}" + ansible_user: root diff --git a/ansible/roles/test/tasks/bgp_entry_flap.yml b/ansible/roles/test/tasks/bgp_entry_flap.yml index 16e19c28ad..1ce23bc056 100644 --- a/ansible/roles/test/tasks/bgp_entry_flap.yml +++ b/ansible/roles/test/tasks/bgp_entry_flap.yml @@ -10,12 +10,14 @@ hwsku: "{{ acs_devices[name]['hwsku'] }}" cred: "{{ switch_login[acs_devices[name]['hwsku']] }}" +- include_tasks: add_container_to_inventory.yml + vars: + container_name: sswsyncd + - name: Get ASIC tables switch_tables: asic="{{asic}}" nexthop=yes nexthopgroup=yes become: yes - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i sswsyncd python + delegate_to: "{{ ansible_host }}_sswsyncd" - block: - name: Assert the particular entry is in nexthopgroup table @@ -44,9 +46,7 @@ - name: Update list of current nexthop group(s) switch_tables: asic="{{asic}}" nexthop=yes nexthopgroup=yes become: yes - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i sswsyncd python + delegate_to: "{{ ansible_host }}_sswsyncd" - name: Poll for updated tables until peer is not in nexthop groups switch_tables: asic="{{asic}}" nexthop=yes nexthopgroup=yes @@ -56,9 +56,7 @@ retries: 6 delay: 10 with_items: "{{ nexthopgroup }}" - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i sswsyncd python + delegate_to: "{{ ansible_host }}_sswsyncd" - name: Restart BGP session from neighbor action: cisco template=bgp_neighbor_noshut.j2 @@ -73,9 +71,7 @@ - name: Update list of current nexthop group(s) switch_tables: asic="{{asic}}" nexthop=yes nexthopgroup=yes become: yes - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i sswsyncd python + delegate_to: "{{ ansible_host }}_sswsyncd" - name: Poll for updated tables until peer is in nexthop groups switch_tables: asic="{{asic}}" nexthop=yes nexthopgroup=yes @@ -85,8 +81,6 @@ retries: 6 delay: 10 with_items: "{{ nexthopgroup }}" - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i sswsyncd python + delegate_to: "{{ ansible_host }}_sswsyncd" when: "'T2' in name" diff --git a/ansible/roles/test/tasks/bgp_gr_helper/get_vm_info.yml b/ansible/roles/test/tasks/bgp_gr_helper/get_vm_info.yml index 58e3bd6d57..f2b40cdb51 100644 --- a/ansible/roles/test/tasks/bgp_gr_helper/get_vm_info.yml +++ b/ansible/roles/test/tasks/bgp_gr_helper/get_vm_info.yml @@ -30,11 +30,13 @@ with_items: "{{ minigraph_bgp }}" when: "item.name == vm_name and item.addr|ipv6" +- include_tasks: add_container_to_inventory.yml + vars: + container_name: lldp + - name: Gather information from LLDP lldp: - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: Get VM IP address. set_fact: diff --git a/ansible/roles/test/tasks/copp.yml b/ansible/roles/test/tasks/copp.yml index a4902ffa1a..6c6038cdd4 100644 --- a/ansible/roles/test/tasks/copp.yml +++ b/ansible/roles/test/tasks/copp.yml @@ -1,3 +1,10 @@ +- include_tasks: add_container_to_inventory.yml + vars: + container_name: "{{ item }}" + with_items: + - "lldp" + - "syncd" + - block: - fail: msg="Please set ptf_host variable" when: ptf_host is not defined @@ -5,9 +12,7 @@ - name: Ensure LLDP Daemon stopped become: yes supervisorctl: state=stopped name={{ item }} - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" with_items: - lldp-syncd - lldpd @@ -38,15 +43,11 @@ - name: Update ptf_nn_agent configuration inside dut template: src=ptf_nn_agent.conf.dut.j2 dest=/etc/supervisor/conf.d/ptf_nn_agent.conf - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i syncd python + delegate_to: "{{ ansible_host }}_syncd" - name: Restart ptf_nn_agent inside dut supervisorctl: state=restarted name=ptf_nn_agent - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i syncd python + delegate_to: "{{ ansible_host }}_syncd" - name: copy the test to ptf container copy: src=roles/test/files/ptftests dest=/root @@ -96,22 +97,16 @@ - name: Update ptf_nn_agent configuration inside dut template: src=ptf_nn_agent.conf.dut.j2 dest=/etc/supervisor/conf.d/ptf_nn_agent.conf - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i syncd python + delegate_to: "{{ ansible_host }}_syncd" - name: Restart ptf_nn_agent inside dut supervisorctl: state=restarted name=ptf_nn_agent - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i syncd python + delegate_to: "{{ ansible_host }}_syncd" - name: Restore LLDP Daemon become: yes supervisorctl: state=started name={{ item }} - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" with_items: - lldpd - lldp-syncd diff --git a/ansible/roles/test/tasks/dip_sip.yml b/ansible/roles/test/tasks/dip_sip.yml index 90090d985f..d064187be3 100644 --- a/ansible/roles/test/tasks/dip_sip.yml +++ b/ansible/roles/test/tasks/dip_sip.yml @@ -20,11 +20,13 @@ script: roles/test/files/helpers/change_mac.sh delegate_to: "{{ ptf_host }}" +- include_tasks: add_container_to_inventory.yml + vars: + container_name: lldp + - name: "Gather information from LLDP" lldp: - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: "Copy tests to PTF" copy: src=roles/test/files/ptftests dest=/root diff --git a/ansible/roles/test/tasks/ecn_wred.yml b/ansible/roles/test/tasks/ecn_wred.yml index c7e1cdaf68..3a2645db55 100644 --- a/ansible/roles/test/tasks/ecn_wred.yml +++ b/ansible/roles/test/tasks/ecn_wred.yml @@ -20,14 +20,15 @@ - set_fact: red_min_threshold={{ wred_value.stdout }} -- block: - - name: Copy test files to DUT - copy: src={{ item }} dest={{ tmp_dir }} - with_fileglob: - - "{{ test_files_dir }}/*" +- include_tasks: add_container_to_inventory.yml vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i database python + container_name: database + +- name: Copy test files to DUT database + copy: src={{ item }} dest={{ tmp_dir }} + delegate_to: "{{ ansible_host }}_database" + with_fileglob: + - "{{ test_files_dir }}/*" - block: # Test case #3(MA): Check configuration applied @@ -45,4 +46,4 @@ shell: ecnconfig -p AZURE_LOSSLESS -rmin {{ red_min_threshold }} become: yes register: ecn_restore - failed_when: ecn_restore.rc != 0 \ No newline at end of file + failed_when: ecn_restore.rc != 0 diff --git a/ansible/roles/test/tasks/interface_up_down.yml b/ansible/roles/test/tasks/interface_up_down.yml index 685bc6f8a9..b415e46615 100644 --- a/ansible/roles/test/tasks/interface_up_down.yml +++ b/ansible/roles/test/tasks/interface_up_down.yml @@ -1,5 +1,9 @@ # This playbook tests neighbor interface flap and ACS interface status work properly # +- include_tasks: add_container_to_inventory.yml + vars: + container_name: lldp + - name: Gathering minigraph facts about the device minigraph_facts: host={{ inventory_hostname }} @@ -8,15 +12,11 @@ service: name=lldpd state=started enabled=yes - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: Gather information from lldp lldp: - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: If underlay exists, use underlay to replace it. set_fact: @@ -47,9 +47,7 @@ - name: Gather information from lldp again after ports are enabled lldp: - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: rearrange lldp received data structure for interface up down test interface_up_down_data_struct_facts: data="{{ lldp }}" diff --git a/ansible/roles/test/tasks/lag_2.yml b/ansible/roles/test/tasks/lag_2.yml index 65c0da1a60..7b1eca5c45 100644 --- a/ansible/roles/test/tasks/lag_2.yml +++ b/ansible/roles/test/tasks/lag_2.yml @@ -23,11 +23,13 @@ - set_fact: test_rate=true when: test_rate is not defined +- include_tasks: add_container_to_inventory.yml + vars: + container_name: lldp + - name: Gathering peer VM information from lldp lldp: - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - name: gathering minigraph of the device configuration minigraph_facts: host={{ inventory_hostname }} diff --git a/ansible/roles/test/tasks/lagall.yml b/ansible/roles/test/tasks/lagall.yml index f8de92b51c..e1cf48ab73 100644 --- a/ansible/roles/test/tasks/lagall.yml +++ b/ansible/roles/test/tasks/lagall.yml @@ -42,11 +42,13 @@ dut_lag_members: "{{ dut_lag_members }} + [ '{{ item.1['members'][0] }}' ] + [ '{{ item.1['members'][1] }}' ]" with_indexed_items: "{{ minigraph_portchannel_interfaces }}" +- include_tasks: add_container_to_inventory.yml + vars: + container_name: lldp + - name: Gather information from LLDP. lldp: - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" - debug: msg: "{{ dut_lag_members }}" diff --git a/ansible/roles/test/tasks/qos_sai.yml b/ansible/roles/test/tasks/qos_sai.yml index cf10f9c57f..4250127484 100644 --- a/ansible/roles/test/tasks/qos_sai.yml +++ b/ansible/roles/test/tasks/qos_sai.yml @@ -6,6 +6,14 @@ - include_vars: vars/qos.yml +- include_tasks: add_container_to_inventory.yml + vars: + container_name: "{{ item }}" + with_items: + - "lldp" + - "bgp" + - "syncd" + - block: - name: Getting minigraph facts minigraph_facts: host={{inventory_hostname}} @@ -21,9 +29,7 @@ - name: Ensure LLDP Daemon stopped become: yes supervisorctl: state=stopped name={{item}} - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" with_items: - lldpd - lldp-syncd @@ -35,9 +41,7 @@ line='bgpd=no' notify: - Restart Quagga Daemon - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i bgp python + delegate_to: "{{ ansible_host }}_bgp" - meta: flush_handlers @@ -47,9 +51,7 @@ - name: Disable Mellanox packet aging shell: python /root/packets_aging.py disable - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i syncd python + delegate_to: "{{ ansible_host }}_syncd" when: minigraph_hwsku is defined and minigraph_hwsku in mellanox_hwskus - name: copy ptf tests @@ -68,7 +70,7 @@ ['Arista-7050-QX-32S', 'Arista-7060CX-32S-C32', 'Celestica-DX010-C32', 'Arista-7260CX3-D108C8', 'Force10-S6100', 'Arista-7260CX3-Q64']) - name: Init PTF base test parameters - set_fact: + set_fact: ptf_base_params: - router_mac={% if testbed_type not in ['t0', 't0-64', 't0-116'] %}'{{ansible_Ethernet0['macaddress']}}'{% else %}''{% endif %} - server='{{ansible_host}}' @@ -564,9 +566,7 @@ - name: Restore LLDP Daemon become: yes supervisorctl: state=started name={{item}} - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i lldp python + delegate_to: "{{ ansible_host }}_lldp" with_items: - lldpd - lldp-syncd @@ -578,9 +578,7 @@ line='bgpd=yes' notify: - Restart Quagga Daemon - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i bgp python + delegate_to: "{{ ansible_host }}_bgp" - name: Restore original watermark polling status shell: counterpoll watermark {{watermark_status.stdout}} @@ -594,9 +592,7 @@ - name: Enable Mellanox packet aging shell: python /root/packets_aging.py enable - vars: - ansible_shell_type: docker - ansible_python_interpreter: docker exec -i syncd python + delegate_to: "{{ ansible_host }}_syncd" when: minigraph_hwsku is defined and minigraph_hwsku in mellanox_hwskus - meta: flush_handlers diff --git a/ansible/shell_plugins/docker.py b/ansible/shell_plugins/docker.py deleted file mode 100644 index 022eed32c3..0000000000 --- a/ansible/shell_plugins/docker.py +++ /dev/null @@ -1,116 +0,0 @@ -from __future__ import (absolute_import, division) -__metaclass__ = type - -DOCUMENTATION = ''' -name: docker -plugin_type: shell -short_description: "docker shell plugin" -version_added: historical -description: - - This module allows you to execute commands directly in docker on the remote host -extends_documentation_fragment: - - shell_common -''' - -import os -import re -import pipes -import ansible.constants as C -import time -import random -import shlex -import getopt -from ansible.module_utils.six import text_type -from ansible.plugins.shell.sh import ShellModule as sh -from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound - -class ShellModule(sh): - - def __init__(self, *args, **kwargs): - super(ShellModule, self).__init__(*args, **kwargs) - self.dtemps = [] - - def join_path(self, *args): - ## HACK! HACK! HACK! - ## We observe the interactions between ShellModule and ActionModule, and - ## find the temporary directories Ansible created on remote machine. So we - ## collect them and copied to docker container in build_module_command - if len(args) >= 2 and (args[0].startswith('/home/') or args[0].startswith('/root/')) and args[1] == '': - self.dtemps.append(args[0]) - - return super(ShellModule, self).join_path(*args) - - def remove(self, path, recurse=False): - argv = self.get_option('ansible_python_interpreter').split() - assert(argv[0] == 'docker') - assert(argv[1] == 'exec') - opts, args = getopt.getopt(argv[2:], 'i') - self.container_name = args[0] - - remove_files_on_host_cmd = super(ShellModule, self).remove(path, recurse) - - cmd = remove_files_on_host_cmd + "; docker exec -i " - cmd += self.container_name + " rm -f " - if recurse: - cmd += '-r ' - cmd += " ".join(self.dtemps) - - return cmd - - def build_module_command(self, env_string, shebang, cmd, arg_path=None): - # assert(self.container_name) - argv = shlex.split(shebang.replace("#!", "")) - assert(argv[0] == 'docker') - assert(argv[1] == 'exec') - opts, args = getopt.getopt(argv[2:], 'i') - self.container_name = args[0] - - # Inject environment variable before python in the shebang string - assert(args[1].endswith('python')) - args[1] = 'env {0} {1}'.format(env_string, args[1]) - argv_env = argv[0:2] + [o for opt in opts for o in opt] + args - shebang_env = ' '.join(argv_env) - - ## Note: Docker cp behavior - ## DEST_PATH exists and is a directory - ## SRC_PATH does end with /. - ## the content of the source directory is copied into this directory - ## Ref: https://docs.docker.com/engine/reference/commandline/cp/ - pre = ''.join('docker exec {1} mkdir -p {0}; docker cp {0}/. {1}:{0}; ' - .format(dtemp, self.container_name) for dtemp in self.dtemps) - - return pre + super(ShellModule, self).build_module_command('', shebang_env, cmd, arg_path) - - def checksum(self, path, python_interp): - """ - Return the command to calculate the checksum for the file in ansible controlled machine - Arguments: - path: - the file path - python_interp: - the path for the python interpreter - Example: - path: - /zebra.conf - python_interp: - docker exec -i debian python - cmd: - rc=flag; [ -r /zebra.conf ] || rc=2; [ -f /zebra.conf ] || rc=1; [ -d /zebra.conf ] && rc=3; python -V 2>/dev/null || rc=4; [ x"$rc" != "xflag" ] && echo "${rc} "/zebra.conf && exit 0; (python -c '...' 2>/dev/null) || (echo '0 '/zebra.conf) - returns: - docker exec -i debian sh -c "rc=flag; [ -r /zebra.conf ] || rc=2; [ -f /zebra.conf ] || rc=1; [ -d /zebra.conf ] && rc=3; python -V 2>/dev/null || rc=4; [ x\"\$rc\" != \"xflag\" ] && echo \"\${rc} \"/zebra.conf && exit 0; (python -c '...' 2>/dev/null) || (echo '0 '/zebra.conf)" - """ - ## Super class implements this function by sh commands and python scripts - ## If python_interp is modified to 'docker CONTAINER python', it will only influence the python - ## script part in super class. Instead we should influence both - simple_interp = 'python' - assert(python_interp.startswith('docker exec ')) - assert(python_interp.endswith(' ' + simple_interp)) - - docker_prefix = re.sub(simple_interp, '', python_interp) - cmd = super(ShellModule, self).checksum(path, simple_interp) - ## Escape the cmd: - ## " --> \" - cmd_escaped = cmd.replace('"', '\\"') - ## $ --> \$ - cmd_escaped = cmd_escaped.replace('$', '\\$') - return '%s sh -c "%s"' % (docker_prefix, cmd_escaped)