Repository: ansible-collections/community.general

Issue:
pfexec become plugin does not work on illumos distros
### Summary

Pfexec become plugin does use non existing options and bad quoting, see: https://github.com/ansible/ansible/issues/15642

The old change described in this [patch](https://github.com/OpenIndiana/oi-userland/blob/oi/hipster/components/python/ansible/patches/01-pfexec.patch) still works, I'm ready to open a pull request for.

### Issue Type

Bug Report

### Component Name

community.general.pfexec
`plugins/become/pfexec.py`

### Ansible Version

```console (paste below)
$ ansible --version
ansible [core 2.11.6] 
  config file = None
  configured module search path = ['/home/florian/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.9/site-packages/ansible
  ansible collection location = /home/florian/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/lib/python-exec/python3.9/ansible
  python version = 3.9.7 (default, Oct 17 2021, 02:52:49) [GCC 10.3.0]
  jinja version = 3.0.1
  libyaml = True
```


### Community.general Version

```console (paste below)
$ ansible-galaxy collection list community.general

# /usr/lib/python3.9/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 3.7.0

```


### Configuration

_No response_

### OS / Environment

OmniOS, OpenIndiana, etc.

### Steps to Reproduce

configure host with OmniOS for become method pfexec

### Expected Results

become method pfexec works

### Actual Results

become method pfexec does not work

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* `plugins/modules/packaging/os/pkg5`

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @bcoca @fishman @jasperla @jpdasma @mator @mavit @scathatheworm @troy2914 @xen0l
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
My basic question is, for which OS does the become plugin work as it is today? And if any, should an option switch be added, to allow to choose between old (illumos incompatible) and new (illumos compatible) behavior?
Files identified in the description:
* [`plugins/become/pfexec.py`](https://github.com/ansible-collections/community.general/blob/main/plugins/become/pfexec.py)
* `plugins/modules/packaging/os/pkg5`

If these files are incorrect, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
cc @None
[click here for bot help](https://github.com/ansible/ansibullbot/blob/devel/ISSUE_HELP.md)
<!--- boilerplate: notify --->
!component plugins/modules/packaging/os/pkg5
FYI, when in core this was tested against illumos.

In any case, the patch is not the right fix, the build_success_command function should be overridden instead, shell should not be hardcoded but use the one from the 'shell' variable passed in to allow the user to configure it depending on their context (for example, being restricted to only ksh).
quick look, this might just bee  a quote problem in https://github.com/ansible/ansible/blob/devel/lib/ansible/plugins/become/__init__.py#L74 requiring a shlex.quote wrapping cmd before interpolation
@bcoca  Can you provide a bit more details on this quoting thing? I'm not familiar with ansible coding, but the option problem can be bypassed by host config.  
If you have an experimental change I can test it.
I found a configuration, which makes it work with current ansible version.
```yaml
ansible_become: yes
ansible_become_method: pfexec
ansible_become_flags: ""
ansible_pfexec_wrap_execution: yes
ansible_python_interpreter: /usr/bin/python3.10
```

Maybe someone can verify this.

Resolving patch:
diff --git a/plugins/become/pfexec.py b/plugins/become/pfexec.py
--- a/plugins/become/pfexec.py
+++ b/plugins/become/pfexec.py
@@ -102,4 +102,4 @@ def build_become_command(self, cmd, shell):
 
         flags = self.get_option('become_flags')
         noexe = not self.get_option('wrap_exe')
-        return '%s %s "%s"' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe))
+        return '%s %s %s' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe))


Test patch:
diff --git a/tests/unit/plugins/become/test_pfexec.py b/tests/unit/plugins/become/test_pfexec.py
--- a/tests/unit/plugins/become/test_pfexec.py
+++ b/tests/unit/plugins/become/test_pfexec.py
@@ -32,7 +32,7 @@ def test_pfexec_basic(mocker, parser, reset_cli_args):
     var_options = {}
     cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
     print(cmd)
-    assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
+    assert re.match("""%s %s 'echo %s; %s'""" % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
 
 
 def test_pfexec(mocker, parser, reset_cli_args):
@@ -54,7 +54,7 @@ def test_pfexec(mocker, parser, reset_cli_args):
     var_options = {}
     cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
     print(cmd)
-    assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
+    assert re.match("""%s %s 'echo %s; %s'""" % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
 
 
 def test_pfexec_varoptions(mocker, parser, reset_cli_args):
@@ -79,4 +79,4 @@ def test_pfexec_varoptions(mocker, parser, reset_cli_args):
     }
     cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
     print(cmd)
-    assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
+    assert re.match("""%s %s 'echo %s; %s'""" % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None