Open o0-o opened 2 years ago
Ansible runs on Python3 for both control node and managed nodes. If not set by default, it can be configured via ansible.cfg.
The circular dependency to which you refer has always existed. This role is mainly intended for configuring machines other than the control node (if run on the control node, nothing new should happen since command line tools should already be installed).
It is certainly possible that this role needs a refactor in light of major OS updates, but I don't think it'll be for the reason you described.
My mistake. I was under the impression that Python 3 was completely missing from macOS but I see that I do have it at /usr/bin/python3
. I think I was conflating it with BASH which only ships as version 3 for licensing reasons on macOS.
Please disregard and thank you for your time responding.
Hey @elliotweiser. According to this, Ansible doesn't do anything special to validate the Python is usable, it just checks that it is present. When a playbook is run against a fresh-out-of-the-box macOS 12.3+ target, interpreter discovery returns /usr/bin/python3, which is not a valid interpreter. It is only a shim that launches an installer that itself won't complete without GUI button-clicking.
This effectively creates a circular dependency if one wants to install the Xcode CLT first thing on a fresh-out-of-the-box macOS 12.3+.
Do you have any suggestions how we should go about this?
It would need to be refactored to only use raw
, script
modules to configure the host until a legitimate Python interpreter is available.
@EiyuuZack @o0-o I think I need a more detailed description of your use-case.
This role has never been intended for "same node" operation. To run Ansible against the local machine, Python must be installed and useable. On MacOS, that depends on the command-line tools being installed (thus, the circular dependency).
This role has only ever been intended to configure a machine that is NOT also the control node (virtual machine on same host, remote host over SSH, etc.). The remote Python used to dispatch Ansible commands has historically been Python 2.7 (I'm not sure if/when that might have changed). Nevertheless, it was always possible to reconfigure the remote executable to a Python 3 installation via the ansible.cfg
, which should work because the entire Ansible codebase is Python 3 compatible. If the Python 3 installation that's provided on the remote machine is not even usable, then that's a different story and using raw
to my recollection is the only way around it. I'd be happy to look into it if this is the only way forward, or alternatively, I'll accept pull-requests.
I'm curious to hear more about your respective use-cases.
Come to think of it, as @EiyuuZack indicates, if simply attempting to use /usr/bin/python3
is enough to spawn GUI actions and effectively block the execution of the rest of the role, then yes, this'll have to be fixed in order to support OS 12.3+.
@elliotweiser apologies if I wasn't clear enough.
Starting with macOS 12.3, the only Python bundled with the OS is /usr/bin/python3
, which only spawns a GUI to install CLT in order for Python 3 to be actually usable.
My use case is having a remote farm of Mac mini machines. After formatting a given host, I bootstrap it using Ansible via SSH. In my playbook, one of the first tasks is to install the CLT. That tasks now fails on macOS 12.3+ because there is no longer any usable remote Python executable until the CLT are installed, which is what I am attempting to do in the first place.
Hope this clears it for you.
@elliotweiser I can work on this if you're open to a pull request.
I have written playbooks that relied on raw
to bootstrap BSD/Linux hosts with Python before. The tasks file becomes significantly longer, but you can achieve effectively the same functionality. There are 2 approaches. I can either use a series of block
/rescue
s or rely entirely on when
. The first approach is much less noisy when run against a host that is already configured, but the 2nd might be easier to read.
@EiyuuZack Definitely clears it up, thank you.
@o0-o Absolutely. Please feel free to submit a PR. This will free me up to look into setting up GH Actions for this project, which is long overdue.
In case anyone needs a workaround for this, set gather_facts: false
and use ansible.builtin.script
with
#!/bin/bash
if ! pkgutil --pkg-info=com.apple.pkg.CLTools_Executables; then
touch /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
clt_label=$(softwareupdate -l | grep -B 1 -E 'Command Line Tools' | awk -F'*' '/^\*/ {print $2}' | sed 's/^ Label: //' | grep -iE '[0-9|.]' | sort | tail -n1)
softwareupdate -i "$clt_label"
rm /tmp/.com.apple.dt.CommandLineTools.installondemand.in-progress
fi
Apple is deprecating Python 2.7 in macOS 12.3.
https://developer.apple.com/documentation/macos-release-notes/macos-12_3-release-notes
I believe this means that no version of Python will be included with stock macOS going forward. Python 3 can be installed via Xcode or Homebrew (which of course itself depends on Xcode's CLI tools), but this creates a circular dependency in this Ansible role. Since it requires Python to be available and Python now requires CLI tools.
Afaik, the only way to address this is to refactor the entire role using the
raw
and/orscript
modules and avoid relying on any data fromgather_facts
/setup
.Do you have any desire to undertake this? I'm afraid the role will have no feasible use beyond macOS 12.3 otherwise (please correct me if I'm missing something here).