ownport/portable-ansible

ansible-pull failed with permission denied

Opened this issue · 2 comments

tftm commented

Hi!
For ansible portable version 0.5 for python 3 when I run ansibe-pull like:
/usr/bin/python /opt/ent/bin/ansiblePortable/py3/ansible-pull --url https://git_repo --inventory /path_to_inv.py
i get error:
Traceback (most recent call last):
File "/opt/bin/ansiblePortable/py3/ansible-pull/main.py", line 139, in
exit_code = cli.run()
File "/opt/bin/ansiblePortable/py3/ansible/ansible/cli/pull.py", line 241, in run
rc, b_out, b_err = run_cmd(cmd, live=True)
File "/opt/bin/ansiblePortable/py3/ansible/ansible/utils/cmd_functions.py", line 44, in run_cmd
p = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
File "/usr/lib64/python3.8/subprocess.py", line 854, in init
self._execute_child(args, executable, preexec_fn, close_fds,
File "/usr/lib64/python3.8/subprocess.py", line 1702, in _execute_child
raise child_exception_type(errno_num, err_msg, err_filename)
PermissionError: [Errno 13] Permission denied: b'/opt/bin/ansiblePortable/py3/ansible'

I can fix it by adding "cmd = 'python ' + cmd" string in def_run function in ansible/utils/cmd_functions.py like

def run_cmd(cmd, live=False, readsize=10):

    # readsize = 10
    cmd = 'python ' + cmd                                     # <<< THIS STRING
    # On python2, shlex needs byte strings
    if PY2:
         cmd = to_bytes(cmd, errors='surrogate_or_strict')
    cmdargs = shlex.split(cmd)
 
    # subprocess should be passed byte strings.  (on python2.6 it must be
    # passed byte strtings)
    cmdargs = [to_bytes(a, errors='surrogate_or_strict') for a in cmdargs]
 
    p = subprocess.Popen(cmdargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

but I think it's need to fix by more proper way.

FBnil commented

Able to reproduce. Tried ansible 2.10.15 (by modifying conf/requirements to higher ansible-base>=2.10.15,<2.11 and rebuilding), but the error is still there.
I understand the problem, but don't have an elegant solution other than using sys.executable just in case python points to python2. And test if the first thing is a binary or a directory (if it's a directory, then portable-ansible, then pre-pend the sys.executable

Can you try with:

    # readsize = 10

    # On python2, shlex needs byte strings
    if PY2:
        cmd = to_bytes(cmd, errors='surrogate_or_strict')
    cmdargs = shlex.split(cmd)

    isDirectory = os.path.isdir(cmdargs[0])
    if isDirectory:
        cmdargs.insert(0,sys.executable)

It's still a hack, because we are now touching the original binaries from Ansible.

FBnil commented

I've learned a bit more about python and the elegant solution to force python3 is to use venv, (but that solves one of the 2 issues)