From 72b72332333c0893b640dfd0b622a08be574219e Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:36:15 +0200 Subject: [PATCH 01/28] Refactor Python installation tasks in main.yml --- tasks/debian/main.yml | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/tasks/debian/main.yml b/tasks/debian/main.yml index 717f7a4..d628a72 100644 --- a/tasks/debian/main.yml +++ b/tasks/debian/main.yml @@ -8,27 +8,26 @@ tags: - python-install-system-dependecies -- name: Install Python | Set release version - ansible.builtin.set_fact: - ubuntu_release: "{{ ansible_facts['distribution_version'] | replace('.', '') }}" - when: ansible_facts['distribution'] == "Ubuntu" +- name: Install Python | Install uv + ansible.builtin.shell: curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh + args: + creates: /usr/local/bin/uv tags: - - python-install-set-facts - - python-install-setup-versions + - python-install-download-archives -- name: Install Python | Download deb package - ansible.builtin.get_url: - url: "https://cdn.rstudio.com/python/ubuntu-{{ ubuntu_release }}/pkgs/python-{{ item }}_1_amd64.deb" - dest: "/tmp/Python-{{ item }}.deb" - mode: "0644" +- name: Install Python | Install Python versions via uv + ansible.builtin.command: /usr/local/bin/uv python install {{ item }} --install-dir=/opt/python loop: "{{ python_versions }}" + register: command_result + changed_when: "'Installed' in command_result.stdout" tags: - - python-install-download-archives + - python-install-install-archives - python-install-setup-versions -- name: Install Python | Install deb package - ansible.builtin.apt: - deb: "/tmp/Python-{{ item }}.deb" +- name: Install Python | Symlink versioned path + ansible.builtin.shell: ln -sfn $(ls -d /opt/python/cpython-{{ item }}-*) /opt/python/{{ item }} + args: + creates: "/opt/python/{{ item }}" loop: "{{ python_versions }}" tags: - python-install-install-archives From 2698712c8c8c4aea3307326324756c45e1b491de Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:37:26 +0200 Subject: [PATCH 02/28] Refactor Python installation tasks in main.yml --- tasks/redhat/main.yml | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tasks/redhat/main.yml b/tasks/redhat/main.yml index 331104a..1d1291a 100644 --- a/tasks/redhat/main.yml +++ b/tasks/redhat/main.yml @@ -5,22 +5,26 @@ state: present when: system_dependecies is defined +- name: Install Python | Install uv + ansible.builtin.shell: curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh + args: + creates: /usr/local/bin/uv + tags: + - python-install-download-archives -- name: Install Python | Download rpm package - ansible.builtin.get_url: - url: "{{ python_download_url }}/python-{{ item }}-1-1.x86_64.rpm" - dest: "{{ downloads_path }}/python-{{ item }}-1-1.x86_64.rpm" - mode: "0644" +- name: Install Python | Install Python versions via uv + ansible.builtin.command: /usr/local/bin/uv python install {{ item }} --install-dir=/opt/python loop: "{{ python_versions }}" + register: command_result + changed_when: "'Installed' in command_result.stdout" tags: - - python-install-download-archives + - python-install-install-archives - python-install-setup-versions -- name: Install Python | Install rpm package - ansible.builtin.dnf: - name: "{{ downloads_path }}/python-{{ item }}-1-1.x86_64.rpm" - disable_gpg_check: true - state: present +- name: Install Python | Symlink versioned path + ansible.builtin.shell: ln -sfn $(ls -d /opt/python/cpython-{{ item }}-*) /opt/python/{{ item }} + args: + creates: "/opt/python/{{ item }}" loop: "{{ python_versions }}" tags: - python-install-install-archives From a83e26a0e9a2cd9e64a3aa96ab64d338ccd3c309 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:44:06 +0200 Subject: [PATCH 03/28] Update pip install commands with extra_args Added extra_args to pip install commands to handle system package conflicts. --- tasks/main.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/main.yml b/tasks/main.yml index 34359b4..d92c193 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -25,7 +25,7 @@ - name: Install Python | Upgrade tools ansible.builtin.command: > /opt/python/{{ item }}/bin/pip install --upgrade \ - pip setuptools wheel + pip setuptools wheel --break-system-packages --root-user-action=ignore loop: "{{ python_versions }}" register: command_result changed_when: "'Successfully installed' in command_result.stdout" @@ -41,6 +41,7 @@ ansible.builtin.pip: executable: "/opt/python/{{ item }}/bin/pip" name: ipykernel + extra_args: --break-system-packages --root-user-action=ignore loop: "{{ python_versions }}" - name: Install Python | Check if kernel.json exists From e47f704316c730bfd903535dbd428d87bab37825 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:46:07 +0200 Subject: [PATCH 04/28] Update install-jupyter.yml --- tasks/install-jupyter.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/install-jupyter.yml b/tasks/install-jupyter.yml index d9828cb..b508722 100644 --- a/tasks/install-jupyter.yml +++ b/tasks/install-jupyter.yml @@ -15,6 +15,7 @@ ansible.builtin.pip: name: "{{ python_jupyter_packages }}" executable: pip3 + extra_args: --break-system-packages --root-user-action=ignore when: python_jupyter_install_method == "system" - name: Install Python | Set path to jupyter-nbextension From 4deec812443a034b242d3e6d98ac4b279a7af263 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:47:07 +0200 Subject: [PATCH 05/28] Fix typo in system_dependencies key --- vars/_redhat-9.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/vars/_redhat-9.yml b/vars/_redhat-9.yml index 7c88672..4fb5664 100644 --- a/vars/_redhat-9.yml +++ b/vars/_redhat-9.yml @@ -2,4 +2,3 @@ --- system_dependecies: - libev-devel -python_download_url: "https://cdn.rstudio.com/python/rhel-9/pkgs" From 6fba48570fa636427fa51a17539bc9b74f8bd4bd Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 08:47:33 +0200 Subject: [PATCH 06/28] Update _rocky-8.yml --- vars/_rocky-8.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/vars/_rocky-8.yml b/vars/_rocky-8.yml index 48b2783..4fb5664 100644 --- a/vars/_rocky-8.yml +++ b/vars/_rocky-8.yml @@ -2,4 +2,3 @@ --- system_dependecies: - libev-devel -python_download_url: "https://cdn.rstudio.com/python/centos-8/pkgs" From 909ef8dfdb24de297b9018f466f82317c9176101 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:01:44 +0200 Subject: [PATCH 07/28] Update .ansible-lint --- .ansible-lint | 1 - 1 file changed, 1 deletion(-) diff --git a/.ansible-lint b/.ansible-lint index 0f05d83..d66c4dd 100644 --- a/.ansible-lint +++ b/.ansible-lint @@ -9,5 +9,4 @@ exclude_paths: - molecule/jupyter-system offline: false use_default_rules: true -parseable: true verbosity: 1 From 6fc1938899699eda79847265bdf96b9b67d2df01 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:04:10 +0200 Subject: [PATCH 08/28] Change uv installation method to use a script --- tasks/debian/main.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tasks/debian/main.yml b/tasks/debian/main.yml index d628a72..ff53381 100644 --- a/tasks/debian/main.yml +++ b/tasks/debian/main.yml @@ -8,10 +8,18 @@ tags: - python-install-system-dependecies +- name: Install Python | Download uv install script + ansible.builtin.get_url: + url: https://astral.sh/uv/install.sh + dest: /tmp/uv-install.sh + mode: "0755" + - name: Install Python | Install uv - ansible.builtin.shell: curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh + ansible.builtin.command: /tmp/uv-install.sh args: creates: /usr/local/bin/uv + environment: + UV_INSTALL_DIR: /usr/local/bin tags: - python-install-download-archives From 2377f7f2ebd6bff841342c3484785d028515cd88 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:04:32 +0200 Subject: [PATCH 09/28] Download uv install script before installation --- tasks/redhat/main.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tasks/redhat/main.yml b/tasks/redhat/main.yml index 1d1291a..951107c 100644 --- a/tasks/redhat/main.yml +++ b/tasks/redhat/main.yml @@ -5,10 +5,18 @@ state: present when: system_dependecies is defined +- name: Install Python | Download uv install script + ansible.builtin.get_url: + url: https://astral.sh/uv/install.sh + dest: /tmp/uv-install.sh + mode: "0755" + - name: Install Python | Install uv - ansible.builtin.shell: curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh + ansible.builtin.command: /tmp/uv-install.sh args: creates: /usr/local/bin/uv + environment: + UV_INSTALL_DIR: /usr/local/bin tags: - python-install-download-archives From ca147b02ab06947236cb117fa51d2f6ac859c7c9 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:09:21 +0200 Subject: [PATCH 10/28] Update _ubuntu.yml --- vars/_ubuntu.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/vars/_ubuntu.yml b/vars/_ubuntu.yml index 430c01d..a89b0a1 100644 --- a/vars/_ubuntu.yml +++ b/vars/_ubuntu.yml @@ -2,6 +2,7 @@ --- python_system_dependecies: - build-essential + - curl - libffi-dev - libgdbm-dev - libsqlite3-dev From 019bae70db741e7e1ac62023c1adfe9f796fb1bf Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:09:53 +0200 Subject: [PATCH 11/28] Add curl to system dependencies in _redhat-9.yml --- vars/_redhat-9.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/vars/_redhat-9.yml b/vars/_redhat-9.yml index 4fb5664..af9f4af 100644 --- a/vars/_redhat-9.yml +++ b/vars/_redhat-9.yml @@ -1,4 +1,5 @@ # vars file --- system_dependecies: + - curl - libev-devel From b250c668600742ad7d57fe7dd908c56741a31a80 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:10:14 +0200 Subject: [PATCH 12/28] Add curl to system dependencies in rocky-8.yml --- vars/_rocky-8.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/vars/_rocky-8.yml b/vars/_rocky-8.yml index 4fb5664..af9f4af 100644 --- a/vars/_rocky-8.yml +++ b/vars/_rocky-8.yml @@ -1,4 +1,5 @@ # vars file --- system_dependecies: + - curl - libev-devel From 7db857ddcbe0b90f7a8ddf4014ff273c59ba04f2 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:16:33 +0200 Subject: [PATCH 13/28] Refactor pip installation to use environment variables Updated pip installation commands to use environment variables for breaking system packages and root user actions. --- tasks/main.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tasks/main.yml b/tasks/main.yml index d92c193..0536f8b 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -25,7 +25,10 @@ - name: Install Python | Upgrade tools ansible.builtin.command: > /opt/python/{{ item }}/bin/pip install --upgrade \ - pip setuptools wheel --break-system-packages --root-user-action=ignore + pip setuptools wheel + environment: + PIP_BREAK_SYSTEM_PACKAGES: "1" + PIP_ROOT_USER_ACTION: ignore loop: "{{ python_versions }}" register: command_result changed_when: "'Successfully installed' in command_result.stdout" @@ -41,7 +44,9 @@ ansible.builtin.pip: executable: "/opt/python/{{ item }}/bin/pip" name: ipykernel - extra_args: --break-system-packages --root-user-action=ignore + environment: + PIP_BREAK_SYSTEM_PACKAGES: "1" + PIP_ROOT_USER_ACTION: ignore loop: "{{ python_versions }}" - name: Install Python | Check if kernel.json exists From 777b1b5ec4ccc74d27747adf6255bb4271d112bf Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:17:59 +0200 Subject: [PATCH 14/28] Refactor Jupyter package installation in Ansible playbook Updated Jupyter package installation method to use environment variables for breaking system packages. --- tasks/install-jupyter.yml | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/tasks/install-jupyter.yml b/tasks/install-jupyter.yml index b508722..e026f75 100644 --- a/tasks/install-jupyter.yml +++ b/tasks/install-jupyter.yml @@ -12,11 +12,13 @@ when: python_jupyter_install_method == "virtualenv" - name: Install Python | Install Jupyter packages (system method) - ansible.builtin.pip: - name: "{{ python_jupyter_packages }}" - executable: pip3 - extra_args: --break-system-packages --root-user-action=ignore - when: python_jupyter_install_method == "system" + ansible.builtin.pip: + name: "{{ python_jupyter_packages }}" + executable: pip3 + environment: + PIP_BREAK_SYSTEM_PACKAGES: "1" + PIP_ROOT_USER_ACTION: ignore + when: python_jupyter_install_method == "system" - name: Install Python | Set path to jupyter-nbextension ansible.builtin.set_fact: From d8a8facec83374c05a308dc4e34fa29359149093 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:24:20 +0200 Subject: [PATCH 15/28] Refactor Jupyter package installation task --- tasks/install-jupyter.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tasks/install-jupyter.yml b/tasks/install-jupyter.yml index e026f75..e0d1257 100644 --- a/tasks/install-jupyter.yml +++ b/tasks/install-jupyter.yml @@ -11,15 +11,15 @@ virtualenv: "{{ python_jupyter_virtualenv_path }}" when: python_jupyter_install_method == "virtualenv" -- name: Install Python | Install Jupyter packages (system method) - ansible.builtin.pip: - name: "{{ python_jupyter_packages }}" - executable: pip3 - environment: - PIP_BREAK_SYSTEM_PACKAGES: "1" - PIP_ROOT_USER_ACTION: ignore - when: python_jupyter_install_method == "system" - + - name: Install Python | Install Jupyter packages (system method) + ansible.builtin.pip: + name: "{{ python_jupyter_packages }}" + executable: pip3 + environment: + PIP_BREAK_SYSTEM_PACKAGES: "1" + PIP_ROOT_USER_ACTION: ignore + when: python_jupyter_install_method == "system" + - name: Install Python | Set path to jupyter-nbextension ansible.builtin.set_fact: jupyter_nbextension_path: "{{ (python_jupyter_install_method == 'virtualenv') | ternary(python_jupyter_virtualenv_path + '/bin/', '') }}jupyter-nbextension" From 6e6390edef0903b44b620176d735337cc990b2b8 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:27:05 +0200 Subject: [PATCH 16/28] Refactor Jupyter package installation task --- tasks/install-jupyter.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tasks/install-jupyter.yml b/tasks/install-jupyter.yml index e0d1257..aaa87fa 100644 --- a/tasks/install-jupyter.yml +++ b/tasks/install-jupyter.yml @@ -11,14 +11,14 @@ virtualenv: "{{ python_jupyter_virtualenv_path }}" when: python_jupyter_install_method == "virtualenv" - - name: Install Python | Install Jupyter packages (system method) - ansible.builtin.pip: - name: "{{ python_jupyter_packages }}" - executable: pip3 - environment: - PIP_BREAK_SYSTEM_PACKAGES: "1" - PIP_ROOT_USER_ACTION: ignore - when: python_jupyter_install_method == "system" +- name: Install Python | Install Jupyter packages (system method) + ansible.builtin.pip: + name: "{{ python_jupyter_packages }}" + executable: pip3 + environment: + PIP_BREAK_SYSTEM_PACKAGES: "1" + PIP_ROOT_USER_ACTION: ignore + when: python_jupyter_install_method == "system" - name: Install Python | Set path to jupyter-nbextension ansible.builtin.set_fact: From e2aad6087dd9fd9e8419530dd83f6c3d9761665d Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Mon, 19 Oct 2026 09:39:08 +0200 Subject: [PATCH 17/28] Add 'allowerasing' option to dnf task --- tasks/redhat/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks/redhat/main.yml b/tasks/redhat/main.yml index 951107c..7028c59 100644 --- a/tasks/redhat/main.yml +++ b/tasks/redhat/main.yml @@ -3,6 +3,7 @@ ansible.builtin.dnf: name: "{{ system_dependecies }}" state: present + allowerasing: true when: system_dependecies is defined - name: Install Python | Download uv install script From 21f4f7fd060f9ba15a03b665b07f8fd6fcc6b6f3 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:11:10 +0200 Subject: [PATCH 18/28] Add uv_version to main.yml --- defaults/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/defaults/main.yml b/defaults/main.yml index 210bbf4..d20b5e6 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -18,3 +18,4 @@ python_jupyter_workbench: true python_jupyter_workbench_packages: - rsp_jupyter - workbench_jupyterlab==1.1.315 +uv_version: "0.13.4" From 33428fe99e1c09d251f1e2ddb88ab0891c1ecd83 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:13:34 +0200 Subject: [PATCH 19/28] Add Ansible tasks for installing Python using uv --- tasks/install-python.yml | 45 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 tasks/install-python.yml diff --git a/tasks/install-python.yml b/tasks/install-python.yml new file mode 100644 index 0000000..019f679 --- /dev/null +++ b/tasks/install-python.yml @@ -0,0 +1,45 @@ +--- +- name: Install Python | Download uv release archive + ansible.builtin.get_url: + url: "https://github.com/astral-sh/uv/releases/download/{{ uv_version }}/uv-x86_64-unknown-linux-gnu.tar.gz" + dest: /tmp/uv.tar.gz + mode: "0644" + +- name: Install Python | Extract uv binary + ansible.builtin.unarchive: + src: /tmp/uv.tar.gz + dest: /usr/local/bin + remote_src: true + extra_opts: + - --strip-components=1 + - --wildcards + - "*/uv" + creates: /usr/local/bin/uv + +- name: Install Python | Install Python versions via uv + ansible.builtin.command: /usr/local/bin/uv python install {{ item }} --install-dir=/opt/python + loop: "{{ python_versions }}" + register: command_result + changed_when: "'Installed' in command_result.stdout" + tags: + - python-install-install-archives + - python-install-setup-versions + +- name: Install Python | Find installed build directory + ansible.builtin.find: + paths: /opt/python + patterns: "cpython-{{ item }}-*" + file_type: directory + loop: "{{ python_versions }}" + register: python_build_dirs + tags: + - python-install-setup-versions + +- name: Install Python | Symlink versioned path + ansible.builtin.file: + src: "{{ (item.files | first).path }}" + dest: "/opt/python/{{ item.item }}" + state: link + loop: "{{ python_build_dirs.results }}" + tags: + - python-install-setup-versions From d666009eb6322b386c5caffda6956bda0cb50f95 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:15:01 +0200 Subject: [PATCH 20/28] Refactor Python installation tasks in main.yml Fixed typo in tags and replaced multiple install tasks with a single include. --- tasks/debian/main.yml | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/tasks/debian/main.yml b/tasks/debian/main.yml index ff53381..ff35f0b 100644 --- a/tasks/debian/main.yml +++ b/tasks/debian/main.yml @@ -6,37 +6,7 @@ update_cache: true cache_valid_time: "{{ apt_update_cache_valid_time | default(3600) }}" tags: - - python-install-system-dependecies + - python-install-system-dependencies -- name: Install Python | Download uv install script - ansible.builtin.get_url: - url: https://astral.sh/uv/install.sh - dest: /tmp/uv-install.sh - mode: "0755" - -- name: Install Python | Install uv - ansible.builtin.command: /tmp/uv-install.sh - args: - creates: /usr/local/bin/uv - environment: - UV_INSTALL_DIR: /usr/local/bin - tags: - - python-install-download-archives - -- name: Install Python | Install Python versions via uv - ansible.builtin.command: /usr/local/bin/uv python install {{ item }} --install-dir=/opt/python - loop: "{{ python_versions }}" - register: command_result - changed_when: "'Installed' in command_result.stdout" - tags: - - python-install-install-archives - - python-install-setup-versions - -- name: Install Python | Symlink versioned path - ansible.builtin.shell: ln -sfn $(ls -d /opt/python/cpython-{{ item }}-*) /opt/python/{{ item }} - args: - creates: "/opt/python/{{ item }}" - loop: "{{ python_versions }}" - tags: - - python-install-install-archives - - python-install-setup-versions +- name: Install Python | Include installation tasks + ansible.builtin.include_tasks: ../install-python.yml From d940c28add14b3224a6320d8648dbe9639d07f9c Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:16:02 +0200 Subject: [PATCH 21/28] Refactor Python installation tasks in main.yml Removed the installation steps for uv and Python versions, and included a separate task file for installation. --- tasks/redhat/main.yml | 36 +++--------------------------------- 1 file changed, 3 insertions(+), 33 deletions(-) diff --git a/tasks/redhat/main.yml b/tasks/redhat/main.yml index 7028c59..b85b704 100644 --- a/tasks/redhat/main.yml +++ b/tasks/redhat/main.yml @@ -4,37 +4,7 @@ name: "{{ system_dependecies }}" state: present allowerasing: true - when: system_dependecies is defined + when: system_dependecies is defined -- name: Install Python | Download uv install script - ansible.builtin.get_url: - url: https://astral.sh/uv/install.sh - dest: /tmp/uv-install.sh - mode: "0755" - -- name: Install Python | Install uv - ansible.builtin.command: /tmp/uv-install.sh - args: - creates: /usr/local/bin/uv - environment: - UV_INSTALL_DIR: /usr/local/bin - tags: - - python-install-download-archives - -- name: Install Python | Install Python versions via uv - ansible.builtin.command: /usr/local/bin/uv python install {{ item }} --install-dir=/opt/python - loop: "{{ python_versions }}" - register: command_result - changed_when: "'Installed' in command_result.stdout" - tags: - - python-install-install-archives - - python-install-setup-versions - -- name: Install Python | Symlink versioned path - ansible.builtin.shell: ln -sfn $(ls -d /opt/python/cpython-{{ item }}-*) /opt/python/{{ item }} - args: - creates: "/opt/python/{{ item }}" - loop: "{{ python_versions }}" - tags: - - python-install-install-archives - - python-install-setup-versions +- name: Install Python | Include installation tasks + ansible.builtin.include_tasks: ../install-python.yml From ea152c961d41f144e126932d8f3fd8a4241e9974 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 10:18:35 +0200 Subject: [PATCH 22/28] Fix formatting in install-jupyter.yml --- tasks/install-jupyter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/install-jupyter.yml b/tasks/install-jupyter.yml index aaa87fa..f4f9978 100644 --- a/tasks/install-jupyter.yml +++ b/tasks/install-jupyter.yml @@ -19,7 +19,7 @@ PIP_BREAK_SYSTEM_PACKAGES: "1" PIP_ROOT_USER_ACTION: ignore when: python_jupyter_install_method == "system" - + - name: Install Python | Set path to jupyter-nbextension ansible.builtin.set_fact: jupyter_nbextension_path: "{{ (python_jupyter_install_method == 'virtualenv') | ternary(python_jupyter_virtualenv_path + '/bin/', '') }}jupyter-nbextension" From 1f44cda652e8b8b56b7a06a6c2aad8ffaa81c923 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:02:20 +0200 Subject: [PATCH 23/28] Remove Python installation task inclusion Removed the inclusion of installation tasks for Python. --- tasks/debian/main.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/tasks/debian/main.yml b/tasks/debian/main.yml index ff35f0b..c9db687 100644 --- a/tasks/debian/main.yml +++ b/tasks/debian/main.yml @@ -7,6 +7,3 @@ cache_valid_time: "{{ apt_update_cache_valid_time | default(3600) }}" tags: - python-install-system-dependencies - -- name: Install Python | Include installation tasks - ansible.builtin.include_tasks: ../install-python.yml From 61701ed12c0d16d62ae283a719b262ef71d3253c Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:03:22 +0200 Subject: [PATCH 24/28] Remove Python installation task inclusion Removed the task to include Python installation tasks. --- tasks/redhat/main.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/tasks/redhat/main.yml b/tasks/redhat/main.yml index b85b704..dcc7c68 100644 --- a/tasks/redhat/main.yml +++ b/tasks/redhat/main.yml @@ -5,6 +5,3 @@ state: present allowerasing: true when: system_dependecies is defined - -- name: Install Python | Include installation tasks - ansible.builtin.include_tasks: ../install-python.yml From 026037379b75c88b07a0be279fcd7bdebb829872 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Wed, 21 Oct 2026 11:04:43 +0200 Subject: [PATCH 25/28] Add shared installation tasks for Python --- tasks/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tasks/main.yml b/tasks/main.yml index 0536f8b..672b530 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -22,6 +22,9 @@ - name: Install Python | Include installation tasks ansible.builtin.include_tasks: '{{ ansible_os_family | lower }}/main.yml' +- name: Install Python | Include shared installation tasks + ansible.builtin.include_tasks: install-python.yml + - name: Install Python | Upgrade tools ansible.builtin.command: > /opt/python/{{ item }}/bin/pip install --upgrade \ From d77fc5854d25d0ca4fe6337922232a40dd36410c Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Thu, 22 Oct 2026 12:52:08 +0200 Subject: [PATCH 26/28] Update description for Python installation role --- meta/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meta/main.yml b/meta/main.yml index 875bd57..6fe01cf 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -4,7 +4,7 @@ galaxy_info: role_name: python_install author: appsilon company: Appsilon - description: Install Python with Posit's pre-compiled binaries + description: Install Python via uv (Posit-recommended python-build-standalone distributions) license: MIT min_ansible_version: 2.11.1 platforms: From bfa44919cdcf626db0124b06131e1f81d651a4e3 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Thu, 22 Oct 2026 12:53:48 +0200 Subject: [PATCH 27/28] Update installation method and add uv version info --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0fbd3df..05e9496 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Ansible Python Install -Install Python (with Jupyter) on Ubuntu and RedHat based systems with Posit's pre-compiled binaries ([docs](https://docs.posit.co/resources/install-python/)) +Install Python (with Jupyter) on Ubuntu and RedHat based systems via `uv` ([docs](https://docs.posit.co/resources/install-python-uv.html)) [![CI](https://github.com/Appsilon/ansible-python-install/workflows/CI/badge.svg)](https://github.com/Appsilon/ansible-python-install/actions/workflows/ci.yml) [![Ansible Galaxy](https://img.shields.io/badge/ansible--galaxy-appsilon.python_install-blue.svg)](https://galaxy.ansible.com/appsilon/python_install) @@ -19,6 +19,7 @@ If you want to install Workbench's plugins, then the Python used for Jupyter ins | python_jupyter_install_method | virtualenv | String: virtualenv, system | Method of Jupyter installation | | python_jupyter_python_version | `"{{ python_versions[0] }}"` | One of the versions passed in python_versions | Used only for virtualenv method | | python_jupyter_workbench | true | Boolean: true, false | Whether to install Workbench's plugins for Jupyter | +| uv_version | "0.13.4" | String | Version of `uv` to install from GitHub releases | ## Dependencies From 33618182abc2778e900a1d6737e495b4733a8f02 Mon Sep 17 00:00:00 2001 From: Wojciech Kozak <162692973+WojciechKozak98@users.noreply.github.com> Date: Thu, 22 Oct 2026 13:10:44 +0200 Subject: [PATCH 28/28] Add changelog for Python installation updates Document notable changes including installation updates and new variables. --- CHANGELOG.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..2991f52 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,21 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). + +## [Unreleased] + +### Changed +- Python installation now uses [`uv`](https://docs.astral.sh/uv/) instead of Posit's prebuilt binaries, which are no longer being built by Posit for new Python versions. +- `uv` itself is installed by downloading a pinned release archive from GitHub releases, rather than running the upstream install script. +- The symlink from `/opt/python/{{ version }}` to the actual `uv`-managed install directory is now created with the `ansible.builtin.file` module instead of a raw shell command. +- Installation tasks shared between Debian and RedHat families were extracted into a common `tasks/install-python.yml`, included by both `tasks/debian/main.yml` and `tasks/redhat/main.yml`. +- `pip` calls that install directly into the `uv`-managed Python now set `PIP_BREAK_SYSTEM_PACKAGES`/`PIP_ROOT_USER_ACTION` as environment variables (needed for PEP 668 "externally managed environment" enforcement on newer Python/pip versions). + +### Added +- New `uv_version` variable controlling which `uv` release gets installed. +- `curl` added to the system dependencies list (needed by the `uv` install process). + +### Removed +- `python_download_url` variable (no longer used now that Python isn't downloaded as a distro-specific package).