diff --git a/lib/ansible/plugins/connection/__init__.py b/lib/ansible/plugins/connection/__init__.py index 82d3854f11..a790138a46 100644 --- a/lib/ansible/plugins/connection/__init__.py +++ b/lib/ansible/plugins/connection/__init__.py @@ -83,7 +83,8 @@ class ConnectionBase(AnsiblePlugin): # we always must have shell if not self._shell: - self._shell = get_shell_plugin(shell_type=getattr(self, '_shell_type', None), executable=self._play_context.executable) + shell_type = play_context.shell if play_context.shell else getattr(self, '_shell_type', None) + self._shell = get_shell_plugin(shell_type=shell_type, executable=self._play_context.executable) self.become = None diff --git a/test/integration/targets/shell/action_plugins/test_shell.py b/test/integration/targets/shell/action_plugins/test_shell.py new file mode 100644 index 0000000000..6e66ed078d --- /dev/null +++ b/test/integration/targets/shell/action_plugins/test_shell.py @@ -0,0 +1,19 @@ +# This file is part of Ansible + +# Copyright (c) 2019 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Make coding more python3-ish +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +from ansible.plugins.action import ActionBase + + +class ActionModule(ActionBase): + + def run(self, tmp=None, task_vars=None): + result = super(ActionModule, self).run(tmp, task_vars) + del tmp # tmp no longer has any effect + result['shell'] = self._connection._shell.SHELL_FAMILY + return result diff --git a/test/integration/targets/shell/aliases b/test/integration/targets/shell/aliases new file mode 100644 index 0000000000..a6dafcf8cd --- /dev/null +++ b/test/integration/targets/shell/aliases @@ -0,0 +1 @@ +shippable/posix/group1 diff --git a/test/integration/targets/shell/connection_plugins/test_connection_default.py b/test/integration/targets/shell/connection_plugins/test_connection_default.py new file mode 100644 index 0000000000..52b027d00a --- /dev/null +++ b/test/integration/targets/shell/connection_plugins/test_connection_default.py @@ -0,0 +1,44 @@ +# Copyright (c) 2019 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' +connection: test_connection_default +short_description: test connection plugin used in tests +description: +- This is a test connection plugin used for shell testing +author: ansible (@core) +version_added: historical +options: +''' + +from ansible.plugins.connection import ConnectionBase + + +class Connection(ConnectionBase): + ''' test connnection ''' + + transport = 'test_connection_default' + + def __init__(self, *args, **kwargs): + super(Connection, self).__init__(*args, **kwargs) + + def transport(self): + pass + + def _connect(self): + pass + + def exec_command(self, cmd, in_data=None, sudoable=True): + pass + + def put_file(self, in_path, out_path): + pass + + def fetch_file(self, in_path, out_path): + pass + + def close(self): + pass diff --git a/test/integration/targets/shell/connection_plugins/test_connection_override.py b/test/integration/targets/shell/connection_plugins/test_connection_override.py new file mode 100644 index 0000000000..56d531c474 --- /dev/null +++ b/test/integration/targets/shell/connection_plugins/test_connection_override.py @@ -0,0 +1,45 @@ +# Copyright (c) 2019 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) +__metaclass__ = type + +DOCUMENTATION = ''' +connection: test_connection_override +short_description: test connection plugin used in tests +description: +- This is a test connection plugin used for shell testing +author: ansible (@core) +version_added: historical +options: +''' + +from ansible.plugins.connection import ConnectionBase + + +class Connection(ConnectionBase): + ''' test connection ''' + + transport = 'test_connection_override' + + def __init__(self, *args, **kwargs): + self._shell_type = 'powershell' # Set a shell type that is not sh + super(Connection, self).__init__(*args, **kwargs) + + def transport(self): + pass + + def _connect(self): + pass + + def exec_command(self, cmd, in_data=None, sudoable=True): + pass + + def put_file(self, in_path, out_path): + pass + + def fetch_file(self, in_path, out_path): + pass + + def close(self): + pass diff --git a/test/integration/targets/shell/tasks/main.yml b/test/integration/targets/shell/tasks/main.yml new file mode 100644 index 0000000000..c38cb02aba --- /dev/null +++ b/test/integration/targets/shell/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: get shell when shell_type is not defined + test_shell: + register: shell_type_default + failed_when: shell_type_default.shell != 'sh' + vars: + ansible_connection: test_connection_default + +- name: get shell when shell_type is not defined but is overridden + test_shell: + register: shell_type_default_override + failed_when: shell_type_default_override.shell != item + vars: + ansible_connection: test_connection_default + ansible_shell_type: '{{ item }}' + with_items: + - csh + - fish + - powershell + - sh + +- name: get shell when shell_type is defined + test_shell: + register: shell_type_defined + failed_when: shell_type_defined.shell != 'powershell' + vars: + ansible_connection: test_connection_override + +- name: get shell when shell_type is defined but is overridden + test_shell: + register: shell_type_defined_override + failed_when: shell_type_defined_override.shell != item + vars: + ansible_connection: test_connection_default + ansible_shell_type: '{{ item }}' + with_items: + - csh + - fish + - powershell + - sh