From f2735aa13593f94d50de82d22fd3dfffde3f868a Mon Sep 17 00:00:00 2001 From: Yutong Zhang <90831468+yutongzhang-microsoft@users.noreply.github.com> Date: Wed, 2 Jul 2025 15:45:43 +0800 Subject: [PATCH] Fix shebang to /usr/bin/python in ansible modules for compatibility (#19258) What is the motivation for this PR? We encountered the following issue when trying to upgrade ansible: /bin/sh: 1: /usr/bin/env python3: not found This error occurred when attempting to invoke certain Ansible modules. According to the Module format and documentation, image the recommended shebang is: `#!/usr/bin/python` From the logs, we can observe the following behavior: When the shebang is /usr/bin/env python, Ansible translates it into: 203 1751357337.89274: _low_level_execute_command(): starting 203 1751357337.89277: _low_level_execute_command(): executing: /bin/sh -c ''"'"'/usr/bin/env python'"'"' && sleep 0' In contrast, when using /usr/bin/python, Ansible attempts a full interpreter discovery: 171 1751357179.48738: _low_level_execute_command(): starting 171 1751357179.48741: _low_level_execute_command(): executing: /bin/sh -c 'echo PLATFORM; uname; echo FOUND; command -v '"'"'python3.13'"'"'; command -v '"'"'python3.12'"'"'; command -v '"'"'python3.11'"'"'; command -v '"'"'python3.10'"'"'; command -v '"'"'python3.9'"'"'; command -v '"'"'python3.8'"'"'; command -v '"'"'/usr/bin/python3'"'"'; command -v '"'"'python3'"'"'; echo ENDFOUND && sleep 0' This indicates that Ansible treats /usr/bin/env python literally and does not invoke its interpreter auto-discovery logic, leading to failures on systems without the python symlink. To satisfy the requirements of the latest ansible, we update the shebang lines in all affected modules in advance. How did you do it? To satisfy the requirements of the latest ansible, this PR updates the shebang lines in all affected modules to #!/usr/bin/python. How did you verify/test it? We need to make sure that this change won't affect current test firstly -- test by pipeline itself. And then, we need to make sure that this change works in the new version -- test locally. --- ansible/library/acl_facts.py | 2 +- ansible/library/announce_routes.py | 2 +- ansible/library/config_facts.py | 2 +- ansible/library/conn_graph_facts.py | 2 +- ansible/library/counter_facts.py | 2 +- ansible/library/dut_basic_facts.py | 2 +- ansible/library/exabgp.py | 2 +- ansible/library/fabric_info.py | 2 +- ansible/library/feature_facts.py | 2 +- ansible/library/generate_golden_config_db.py | 2 +- ansible/library/image_facts.py | 2 +- ansible/library/interface_up_down_data_struct_facts.py | 2 +- ansible/library/lldp_facts.py | 2 +- ansible/library/lldpctl_facts.py | 2 +- ansible/library/minigraph_facts.py | 2 +- ansible/library/mux_cable_facts.py | 2 +- ansible/library/port_alias.py | 2 +- ansible/library/ptf_portchannel.py | 2 +- ansible/library/shell_cmds.py | 2 +- ansible/library/test_facts.py | 2 +- ansible/library/topo_facts.py | 2 +- ansible/library/vlan_config.py | 2 +- ansible/library/vlan_facts.py | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ansible/library/acl_facts.py b/ansible/library/acl_facts.py index a2ed3cd1a5..4e3b5c0575 100644 --- a/ansible/library/acl_facts.py +++ b/ansible/library/acl_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for gathering ACL related facts from SONiC device. # # The "sonic-cfggen" tool is used to output all the running config data from db in JSON format. ACL table information diff --git a/ansible/library/announce_routes.py b/ansible/library/announce_routes.py index a3a24b98fc..6ec1febeeb 100644 --- a/ansible/library/announce_routes.py +++ b/ansible/library/announce_routes.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import math import os diff --git a/ansible/library/config_facts.py b/ansible/library/config_facts.py index 8d8fe87f0b..6a5f722c83 100644 --- a/ansible/library/config_facts.py +++ b/ansible/library/config_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import json import traceback diff --git a/ansible/library/conn_graph_facts.py b/ansible/library/conn_graph_facts.py index d327832b56..7130361aeb 100755 --- a/ansible/library/conn_graph_facts.py +++ b/ansible/library/conn_graph_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import csv from ansible.module_utils.basic import AnsibleModule diff --git a/ansible/library/counter_facts.py b/ansible/library/counter_facts.py index 69de5a1d54..1f64aeff50 100755 --- a/ansible/library/counter_facts.py +++ b/ansible/library/counter_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import re diff --git a/ansible/library/dut_basic_facts.py b/ansible/library/dut_basic_facts.py index 7b9cfd7bce..56c73f7f2e 100644 --- a/ansible/library/dut_basic_facts.py +++ b/ansible/library/dut_basic_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for gathering basic facts from DUT of specified testbed. # # Example output: diff --git a/ansible/library/exabgp.py b/ansible/library/exabgp.py index 8159d583db..1dc38b18a0 100644 --- a/ansible/library/exabgp.py +++ b/ansible/library/exabgp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import jinja2 diff --git a/ansible/library/fabric_info.py b/ansible/library/fabric_info.py index e948bf9533..7af5578848 100644 --- a/ansible/library/fabric_info.py +++ b/ansible/library/fabric_info.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import ipaddress diff --git a/ansible/library/feature_facts.py b/ansible/library/feature_facts.py index 2a35ca3521..6ace0babec 100644 --- a/ansible/library/feature_facts.py +++ b/ansible/library/feature_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for gathering feature facts from SONiC device. # diff --git a/ansible/library/generate_golden_config_db.py b/ansible/library/generate_golden_config_db.py index 689d87e237..c6b69d7529 100644 --- a/ansible/library/generate_golden_config_db.py +++ b/ansible/library/generate_golden_config_db.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for generate golden_config_db.json # Currently, only enable dhcp_server feature and generated related configuration in MX device diff --git a/ansible/library/image_facts.py b/ansible/library/image_facts.py index b6bcfb132b..f9e9ed554e 100644 --- a/ansible/library/image_facts.py +++ b/ansible/library/image_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for gathering image facts from SONiC device. # # The "sonic_installer list" command can list the images on SONiC device, including: diff --git a/ansible/library/interface_up_down_data_struct_facts.py b/ansible/library/interface_up_down_data_struct_facts.py index 7e390704b5..93bc6345d0 100644 --- a/ansible/library/interface_up_down_data_struct_facts.py +++ b/ansible/library/interface_up_down_data_struct_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule diff --git a/ansible/library/lldp_facts.py b/ansible/library/lldp_facts.py index 04896e6956..26b73af23e 100644 --- a/ansible/library/lldp_facts.py +++ b/ansible/library/lldp_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import json from collections import defaultdict diff --git a/ansible/library/lldpctl_facts.py b/ansible/library/lldpctl_facts.py index b1c9f8cdd1..7984ef7e79 100644 --- a/ansible/library/lldpctl_facts.py +++ b/ansible/library/lldpctl_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for gathering lldp facts from SONiC device. # It takes two argument # asic_instance_id :- Used to specify LLDP Instance in Multi-asic platforms diff --git a/ansible/library/minigraph_facts.py b/ansible/library/minigraph_facts.py index 83d75818fe..3ac4f057d8 100644 --- a/ansible/library/minigraph_facts.py +++ b/ansible/library/minigraph_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from __future__ import print_function from ansible.module_utils.basic import AnsibleModule import calendar diff --git a/ansible/library/mux_cable_facts.py b/ansible/library/mux_cable_facts.py index bc4045083b..14d3bc9105 100644 --- a/ansible/library/mux_cable_facts.py +++ b/ansible/library/mux_cable_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import os.path import sys import traceback diff --git a/ansible/library/port_alias.py b/ansible/library/port_alias.py index 0535d8e5f4..9685432148 100755 --- a/ansible/library/port_alias.py +++ b/ansible/library/port_alias.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import re diff --git a/ansible/library/ptf_portchannel.py b/ansible/library/ptf_portchannel.py index 50c5e1d0e9..27e52dde8c 100644 --- a/ansible/library/ptf_portchannel.py +++ b/ansible/library/ptf_portchannel.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import jinja2 diff --git a/ansible/library/shell_cmds.py b/ansible/library/shell_cmds.py index 23909e9b04..ba33654f1f 100644 --- a/ansible/library/shell_cmds.py +++ b/ansible/library/shell_cmds.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for running multiple commands by /bin/sh on remote device. # # The ansible builtin module "command" and "shell" can run a single command on the remote device and get its output. diff --git a/ansible/library/test_facts.py b/ansible/library/test_facts.py index 423192d080..43fab52324 100644 --- a/ansible/library/test_facts.py +++ b/ansible/library/test_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import sys import traceback diff --git a/ansible/library/topo_facts.py b/ansible/library/topo_facts.py index b6d8ffb355..bc3652c44d 100644 --- a/ansible/library/topo_facts.py +++ b/ansible/library/topo_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python import os import traceback import ipaddress diff --git a/ansible/library/vlan_config.py b/ansible/library/vlan_config.py index 1b84383507..e3d49b8d5f 100644 --- a/ansible/library/vlan_config.py +++ b/ansible/library/vlan_config.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python from ansible.module_utils.basic import AnsibleModule import traceback diff --git a/ansible/library/vlan_facts.py b/ansible/library/vlan_facts.py index 5be7448fc2..39d133636a 100644 --- a/ansible/library/vlan_facts.py +++ b/ansible/library/vlan_facts.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/python # This ansible module is for gathering VLAN related facts from SONiC device. from ansible.module_utils.basic import AnsibleModule