├── .ansible-lint-ignore ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── README.md ├── ansible.cfg ├── ansible.yml ├── defaults └── main │ ├── base.yml │ ├── python.yml │ └── venv.yml ├── meta └── main.yml └── tasks ├── deps.yml ├── main.yml ├── misc.yml ├── python24.yml ├── python26.yml ├── python2x.yml ├── python3x.yml ├── python_generic.yml ├── venv.yml ├── venv27.yml └── venvs.yml /.ansible-lint-ignore: -------------------------------------------------------------------------------- 1 | # This file contains ignores rule violations for ansible-lint 2 | tasks/python_generic.yml name[template] 3 | tasks/venv.yml name[template] 4 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | push: 5 | branches: 6 | - master 7 | - main 8 | 9 | jobs: 10 | 11 | yaml: 12 | name: YAML syntax Lint 13 | runs-on: ubuntu-latest 14 | steps: 15 | - name: Check out the codebase. 16 | uses: actions/checkout@v4 17 | 18 | - name: Set up Python 3. 19 | uses: actions/setup-python@v5 20 | with: 21 | python-version: '3.x' 22 | 23 | - name: Install test dependencies. 24 | run: pip3 install yamllint 25 | 26 | - name: Lint code. 27 | run: | 28 | yamllint */*.yml 29 | 30 | playbook: 31 | name: ansible-playbook lint 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: Check out the codebase. 35 | uses: actions/checkout@v4 36 | 37 | - name: Set up Python 3. 38 | uses: actions/setup-python@v5 39 | with: 40 | python-version: '3.x' 41 | 42 | - name: Install test dependencies. 43 | run: pip3 install ansible 44 | 45 | - name: Lint code. 46 | run: | 47 | ansible-playbook --syntax-check ansible.yml 48 | 49 | ansible-lint: 50 | name: ansible-lint 51 | runs-on: ubuntu-latest 52 | steps: 53 | - name: Check out the codebase. 54 | uses: actions/checkout@v4 55 | 56 | - name: Set up Python 3. 57 | uses: actions/setup-python@v5 58 | with: 59 | python-version: '3.x' 60 | 61 | - name: Install test dependencies. 62 | run: pip3 install ansible-lint 63 | 64 | - name: Lint code. 65 | run: | 66 | ansible-lint . 67 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # added by GitSavvy 3 | /inventory.cfg 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Compile python 2 | 3 | Usually you don't want to mess with system packages, 4 | specially if the package in question is python. 5 | 6 | Distributions usually patch python 7 | in a way that may not work together with your app. 8 | 9 | On those occasions 10 | rather than replacing the version provided by your distribution 11 | is usually better to compile your own. 12 | 13 | _And that's what this ansible playbook is for!_ 14 | 15 | Installs all necessary tools to build and install Python and then installs 16 | any given version of Python. 17 | 18 | So far Python 2.4, 2.6, 2.7 and 3.1 to 3.12 are supported, 19 | plus installing system dependencies to install (not done in this role): 20 | 21 | - pillow 22 | - lxml 23 | 24 | If other versions are wanted, 25 | pull requests welcome. 26 | 27 | For ease of usage an easy to remember symlinks are provided for each python version, 28 | i.e. `/srv/python27`, `/srv/python36` and so on. 29 | 30 | ## Requirements 31 | 32 | None 33 | 34 | ## Role Variables 35 | 36 | - python_24: `true/false` (defaults to **false**) 37 | - python_26: `true/false` (defaults to **false**) 38 | - python_27: `true/false` (defaults to **false**) 39 | - python_31: `true/false` (defaults to **false**) 40 | - python_32: `true/false` (defaults to **false**) 41 | - python_33: `true/false` (defaults to **false**) 42 | - python_34: `true/false` (defaults to **false**) 43 | - python_35: `true/false` (defaults to **false**) 44 | - python_36: `true/false` (defaults to **false**) 45 | - python_37: `true/false` (defaults to **false**) 46 | - python_38: `true/false` (defaults to **false**) 47 | - python_39: `true/false` (defaults to **false**) 48 | - python_310: `true/false` (defaults to **false**) 49 | - python_311: `true/false` (defaults to **false**) 50 | - python_312: `true/false` (defaults to **true**) 51 | - pillow: `true/false` (defaults to **false**) 52 | - lxml: `true/false` (defaults to **false**) 53 | 54 | ## Dependencies 55 | 56 | Ubuntu 23.04 (jammy) 57 | 58 | ## Example Playbook 59 | 60 | ```yml 61 | - hosts: servers 62 | roles: 63 | - gforcada.compile-python 64 | vars: 65 | - python_26: true 66 | - python_27: true 67 | - python_36: true 68 | ``` 69 | 70 | ## License 71 | 72 | BSD 73 | 74 | ## Author Information 75 | 76 | Gil Forcada Codinachs 77 | 78 | ## Contribute 79 | 80 | Code can be found at: https://github.com/gforcada/ansible-compile-python 81 | 82 | Please report issues at: https://github.com/gforcada/ansible-compile-python/issues 83 | -------------------------------------------------------------------------------- /ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | roles_path = .. 3 | -------------------------------------------------------------------------------- /ansible.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | roles: 4 | - ansible-compile-python 5 | vars: 6 | python_24: true 7 | python_26: true 8 | pillow: true 9 | lxml: true 10 | -------------------------------------------------------------------------------- /defaults/main/base.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ## 3 | # role main options 4 | ## 5 | 6 | python_24: false 7 | python_26: false 8 | python_27: false 9 | python_31: false 10 | python_32: false 11 | python_33: false 12 | python_34: false 13 | python_35: false 14 | python_36: false 15 | python_37: false 16 | python_38: false 17 | python_39: false 18 | python_310: false 19 | python_311: false 20 | python_312: true 21 | python_313: false 22 | 23 | pillow: false 24 | lxml: false 25 | 26 | # fine grained settings 27 | base_install_folder: "/srv" 28 | -------------------------------------------------------------------------------- /defaults/main/python.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ## 3 | # Pythons configuration 4 | ## 5 | 6 | ftp_url: "https://www.python.org/ftp/python" 7 | 8 | versions: 9 | py24: "2.4.6" 10 | py26: "2.6.9" 11 | py27: "2.7.18" 12 | py31: "3.1.5" 13 | py32: "3.2.6" 14 | py33: "3.3.7" 15 | py34: "3.4.10" 16 | py35: "3.5.10" 17 | py36: "3.6.15" 18 | py37: "3.7.17" 19 | py38: "3.8.20" 20 | py39: "3.9.21" 21 | py310: "3.10.16" 22 | py311: "3.11.11" 23 | py312: "3.12.9" 24 | py313: "3.13.2" 25 | 26 | hashes: 27 | py24: "76083277f6c7e4d78992f36d7ad9018d" 28 | py26: "933a811f11e3db3d73ae492f6c3a7a76" 29 | py27: "fd6cc8ec0a78c44036f825e739f36e5a" 30 | py31: "20dd2b7f801dc97db948dd168df4dd52" 31 | py32: "e0ba4360dfcb4aec735e666cc0ae7b0e" 32 | py33: "84e2f12f044ca53b577f6224c53f82ac" 33 | py34: "f88a98bce17a03c43a6a5f8a66ab2e62" 34 | py35: "75c9c268703654aa6f6f2ae67303dde4" 35 | py36: "bc04aa6c2a1a172a35012abd668538cd" 36 | py37: "dd94cab4541b57b88cf3dab32d6336e3" 37 | py38: "745478c81d6382cf46b5e7ad89e56008" 38 | py39: "e8ab0f9a295f12428310f409abd79e9c" 39 | py310: "97b3ee1740f32a92905dd0a99dcb04d5" 40 | py311: "3e497037b170fe4be5f462c4964596f2" 41 | py312: "880942124f7d5c01e7b65cbad62dc873" 42 | py313: "4c2d9202ab4db02c9d0999b14655dfe5" 43 | 44 | ## 45 | # Specific python version details, based on the variables above 46 | ## 47 | 48 | py24: 49 | version: "{{ versions.py24 }}" 50 | major_version: "2.4" 51 | url: "{{ ftp_url }}/{{ versions.py24 }}/Python-{{ versions.py24 }}.tar.bz2" 52 | md5: "{{ hashes.py24 }}" 53 | tar_file: "/tmp/py{{ versions.py24 }}.tar.bz2" 54 | sources: "/tmp/Python-{{ versions.py24 }}" 55 | install: "{{ base_install_folder }}/python{{ versions.py24 }}" 56 | bin: "{{ base_install_folder }}/python{{ versions.py24 }}/bin/python2.4" 57 | 58 | py26: 59 | version: "{{ versions.py26 }}" 60 | major_version: "2.6" 61 | url: "{{ ftp_url }}/{{ versions.py26 }}/Python-{{ versions.py26 }}.tar.xz" 62 | md5: "{{ hashes.py26 }}" 63 | tar_file: "/tmp/py{{ versions.py26 }}.tar.xz" 64 | sources: "/tmp/Python-{{ versions.py26 }}" 65 | install: "{{ base_install_folder }}/python{{ versions.py26 }}" 66 | bin: "{{ base_install_folder }}/python{{ versions.py26 }}/bin/python2.6" 67 | 68 | py27: 69 | version: "{{ versions.py27 }}" 70 | major_version: "2.7" 71 | url: "{{ ftp_url }}/{{ versions.py27 }}/Python-{{ versions.py27 }}.tar.xz" 72 | md5: "{{ hashes.py27 }}" 73 | tar_file: "/tmp/py{{ versions.py27 }}.tar.xz" 74 | sources: "/tmp/Python-{{ versions.py27 }}" 75 | install: "{{ base_install_folder }}/python{{ versions.py27 }}" 76 | bin: "{{ base_install_folder }}/python{{ versions.py27 }}/bin/python2.7" 77 | 78 | py31: 79 | version: "{{ versions.py31 }}" 80 | major_version: "3.1" 81 | url: "{{ ftp_url }}/{{ versions.py31 }}/Python-{{ versions.py31 }}.tar.xz" 82 | md5: "{{ hashes.py31 }}" 83 | tar_file: "/tmp/py{{ versions.py31 }}.tar.xz" 84 | sources: "/tmp/Python-{{ versions.py31 }}" 85 | install: "{{ base_install_folder }}/python{{ versions.py31 }}" 86 | bin: "{{ base_install_folder }}/python{{ versions.py31 }}/bin/python3.1" 87 | 88 | py32: 89 | version: "{{ versions.py32 }}" 90 | major_version: "3.2" 91 | url: "{{ ftp_url }}/{{ versions.py32 }}/Python-{{ versions.py32 }}.tar.xz" 92 | md5: "{{ hashes.py32 }}" 93 | tar_file: "/tmp/py{{ versions.py32 }}.tar.xz" 94 | sources: "/tmp/Python-{{ versions.py32 }}" 95 | install: "{{ base_install_folder }}/python{{ versions.py32 }}" 96 | bin: "{{ base_install_folder }}/python{{ versions.py32 }}/bin/python3.4" 97 | 98 | py33: 99 | version: "{{ versions.py33 }}" 100 | major_version: "3.3" 101 | url: "{{ ftp_url }}/{{ versions.py33 }}/Python-{{ versions.py33 }}.tar.xz" 102 | md5: "{{ hashes.py33 }}" 103 | tar_file: "/tmp/py{{ versions.py33 }}.tar.xz" 104 | sources: "/tmp/Python-{{ versions.py33 }}" 105 | install: "{{ base_install_folder }}/python{{ versions.py33 }}" 106 | bin: "{{ base_install_folder }}/python{{ versions.py33 }}/bin/python3.3" 107 | 108 | py34: 109 | version: "{{ versions.py34 }}" 110 | major_version: "3.4" 111 | url: "{{ ftp_url }}/{{ versions.py34 }}/Python-{{ versions.py34 }}.tar.xz" 112 | md5: "{{ hashes.py34 }}" 113 | tar_file: "/tmp/py{{ versions.py34 }}.tar.xz" 114 | sources: "/tmp/Python-{{ versions.py34 }}" 115 | install: "{{ base_install_folder }}/python{{ versions.py34 }}" 116 | bin: "{{ base_install_folder }}/python{{ versions.py34 }}/bin/python3.4" 117 | 118 | py35: 119 | version: "{{ versions.py35 }}" 120 | major_version: "3.5" 121 | url: "{{ ftp_url }}/{{ versions.py35 }}/Python-{{ versions.py35 }}.tar.xz" 122 | md5: "{{ hashes.py35 }}" 123 | tar_file: "/tmp/py{{ versions.py35 }}.tar.xz" 124 | sources: "/tmp/Python-{{ versions.py35 }}" 125 | install: "{{ base_install_folder }}/python{{ versions.py35 }}" 126 | bin: "{{ base_install_folder }}/python{{ versions.py35 }}/bin/python3.5" 127 | 128 | py36: 129 | version: "{{ versions.py36 }}" 130 | major_version: "3.6" 131 | url: "{{ ftp_url }}/{{ versions.py36 }}/Python-{{ versions.py36 }}.tar.xz" 132 | md5: "{{ hashes.py36 }}" 133 | tar_file: "/tmp/py{{ versions.py36 }}.tar.xz" 134 | sources: "/tmp/Python-{{ versions.py36 }}" 135 | install: "{{ base_install_folder }}/python{{ versions.py36 }}" 136 | bin: "{{ base_install_folder }}/python{{ versions.py36 }}/bin/python3.6" 137 | 138 | py37: 139 | version: "{{ versions.py37 }}" 140 | major_version: "3.7" 141 | url: "{{ ftp_url }}/{{ versions.py37 }}/Python-{{ versions.py37 }}.tar.xz" 142 | md5: "{{ hashes.py37 }}" 143 | tar_file: "/tmp/py{{ versions.py37 }}.tar.xz" 144 | sources: "/tmp/Python-{{ versions.py37 }}" 145 | install: "{{ base_install_folder }}/python{{ versions.py37 }}" 146 | bin: "{{ base_install_folder }}/python{{ versions.py37 }}/bin/python3.7" 147 | 148 | py38: 149 | version: "{{ versions.py38 }}" 150 | major_version: "3.8" 151 | url: "{{ ftp_url }}/{{ versions.py38 }}/Python-{{ versions.py38 }}.tar.xz" 152 | md5: "{{ hashes.py38 }}" 153 | tar_file: "/tmp/py{{ versions.py38 }}.tar.xz" 154 | sources: "/tmp/Python-{{ versions.py38 }}" 155 | install: "{{ base_install_folder }}/python{{ versions.py38 }}" 156 | bin: "{{ base_install_folder }}/python{{ versions.py38 }}/bin/python3.8" 157 | 158 | py39: 159 | version: "{{ versions.py39 }}" 160 | major_version: "3.9" 161 | url: "{{ ftp_url }}/{{ versions.py39 }}/Python-{{ versions.py39 }}.tar.xz" 162 | md5: "{{ hashes.py39 }}" 163 | tar_file: "/tmp/py{{ versions.py39 }}.tar.xz" 164 | sources: "/tmp/Python-{{ versions.py39 }}" 165 | install: "{{ base_install_folder }}/python{{ versions.py39 }}" 166 | bin: "{{ base_install_folder }}/python{{ versions.py39 }}/bin/python3.9" 167 | 168 | py310: 169 | version: "{{ versions.py310 }}" 170 | major_version: "3.10" 171 | url: "{{ ftp_url }}/{{ versions.py310 }}/Python-{{ versions.py310 }}.tar.xz" 172 | md5: "{{ hashes.py310 }}" 173 | tar_file: "/tmp/py{{ versions.py310 }}.tar.xz" 174 | sources: "/tmp/Python-{{ versions.py310 }}" 175 | install: "{{ base_install_folder }}/python{{ versions.py310 }}" 176 | bin: "{{ base_install_folder }}/python{{ versions.py310 }}/bin/python3.10" 177 | 178 | py311: 179 | version: "{{ versions.py311 }}" 180 | major_version: "3.11" 181 | url: "{{ ftp_url }}/{{ versions.py311 }}/Python-{{ versions.py311 }}.tar.xz" 182 | md5: "{{ hashes.py311 }}" 183 | tar_file: "/tmp/py{{ versions.py311 }}.tar.xz" 184 | sources: "/tmp/Python-{{ versions.py311 }}" 185 | install: "{{ base_install_folder }}/python{{ versions.py311 }}" 186 | bin: "{{ base_install_folder }}/python{{ versions.py311 }}/bin/python3.11" 187 | 188 | py312: 189 | version: "{{ versions.py312 }}" 190 | major_version: "3.12" 191 | url: "{{ ftp_url }}/{{ versions.py312 }}/Python-{{ versions.py312 }}.tar.xz" 192 | md5: "{{ hashes.py312 }}" 193 | tar_file: "/tmp/py{{ versions.py312 }}.tar.xz" 194 | sources: "/tmp/Python-{{ versions.py312 }}" 195 | install: "{{ base_install_folder }}/python{{ versions.py312 }}" 196 | bin: "{{ base_install_folder }}/python{{ versions.py312 }}/bin/python3.12" 197 | 198 | py313: 199 | version: "{{ versions.py313 }}" 200 | major_version: "3.13" 201 | url: "{{ ftp_url }}/{{ versions.py313 }}/Python-{{ versions.py313 }}.tar.xz" 202 | md5: "{{ hashes.py313 }}" 203 | tar_file: "/tmp/py{{ versions.py313 }}.tar.xz" 204 | sources: "/tmp/Python-{{ versions.py313 }}" 205 | install: "{{ base_install_folder }}/python{{ versions.py313 }}" 206 | bin: "{{ base_install_folder }}/python{{ versions.py313 }}/bin/python3.13" 207 | -------------------------------------------------------------------------------- /defaults/main/venv.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ## 3 | # Virtual environment related configuration 4 | # 5 | # !! Note that Python 2.7 is installed slightly different 6 | ## 7 | 8 | pkg_url: "https://files.pythonhosted.org/packages" 9 | 10 | venv_versions: 11 | py24: "1.7.2" 12 | py26: "1.10" 13 | py27: "20.15.1" 14 | 15 | venv_url_hashes: 16 | py24: "7b88d35d0a353ec70e42aa37fd8b0bd1c643419c80f022ffaafa4d6449f0" 17 | py26: "f425e456e017af4801bb08920e30c149a44ac0c194f2225bdb712e77701c" 18 | py27: "df7c7b1b7a5ac4e41fac24c3682c1cc32f2c1d683d308bba2500338d1e3e" 19 | 20 | venv_file_hashes: 21 | py24: "b5d63b05373a4344ae099a68875aae78" 22 | py26: "9745c28256c70c76d36adb3767a00212" 23 | py27: "e9a76a95dc28cf9b55cfc87bd4eef20c" 24 | 25 | venv27_wheel_name: "virtualenv-{{ venv_versions.py27 }}-py2.py3-none-any.whl" 26 | 27 | ## 28 | # main venvs configuration, based on the variables above 29 | ## 30 | 31 | venv24: 32 | version: "{{ venv_versions.py24 }}" 33 | url: "{{ pkg_url }}/16/86/{{ venv_url_hashes.py24 }}/virtualenv-1.7.2.tar.gz" 34 | md5: "{{ venv_file_hashes.py24 }}" 35 | tar_file: "/tmp/virtualenv-{{ venv_versions.py24 }}.tar.gz" 36 | sources: "/tmp/virtualenv-{{ venv_versions.py24 }}" 37 | 38 | venv26: 39 | version: "{{ venv_versions.py26 }}" 40 | url: "{{ pkg_url }}/d5/5b/{{ venv_url_hashes.py26 }}/virtualenv-1.10.tar.gz" 41 | md5: "{{ venv_file_hashes.py26 }}" 42 | tar_file: "/tmp/virtualenv-{{ venv_versions.py26 }}.tar.gz" 43 | sources: "/tmp/virtualenv-{{ venv_versions.py26 }}" 44 | 45 | venv27: 46 | version: "{{ venv_versions.py27 }}" 47 | url: "{{ pkg_url }}/6f/43/{{ venv_url_hashes.py27 }}/{{ venv27_wheel_name }}" 48 | md5: "{{ venv_file_hashes.py27 }}" 49 | wheel_file: "/tmp/{{ venv27_wheel_name }}" 50 | -------------------------------------------------------------------------------- /meta/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | dependencies: [] 4 | 5 | galaxy_info: 6 | author: Gil Forcada Codinachs 7 | description: Install all dependencies and compile any version of Python 8 | role_name: compile_python 9 | namespace: gforcada 10 | license: BSD-3-Clause 11 | min_ansible_version: '2.2' 12 | platforms: 13 | - name: Ubuntu 14 | versions: 15 | - jammy 16 | galaxy_tags: 17 | - python 18 | - compile 19 | -------------------------------------------------------------------------------- /tasks/deps.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Update APT sources 4 | become: true 5 | ansible.builtin.apt: 6 | update_cache: true 7 | 8 | - name: Dependencies Python | Install compile time depdendencies 9 | become: true 10 | ansible.builtin.apt: 11 | state: present 12 | name: 13 | - autotools-dev 14 | - blt-dev 15 | - bzip2 16 | - dpkg-dev 17 | - g++-multilib 18 | - gcc-multilib 19 | - libbluetooth-dev 20 | - libbz2-dev 21 | - libexpat1-dev 22 | - libffi-dev 23 | - libgdbm-dev 24 | - libgpm2 25 | - libncursesw5-dev 26 | - libreadline-dev 27 | - libsqlite3-dev 28 | - libssl-dev 29 | - libtinfo-dev 30 | - net-tools 31 | - netbase 32 | - quilt 33 | - tk-dev 34 | - zlib1g-dev 35 | 36 | - name: Dependencies Python 3.6 | Install compile time dependencies 37 | become: true 38 | ansible.builtin.apt: 39 | state: present 40 | name: 41 | - liblzma-dev 42 | when: python_36 43 | 44 | ## 45 | # Pillow 46 | ## 47 | 48 | - name: Dependencies Pillow | Install compile time depdendencies 49 | become: true 50 | ansible.builtin.apt: 51 | state: present 52 | name: 53 | - cmake 54 | - libfreetype6-dev 55 | - libjpeg8-dev 56 | - liblcms2-dev 57 | - libtiff5-dev 58 | - libwebp-dev 59 | - tcl8.6-dev 60 | - tk8.6-dev 61 | when: pillow 62 | 63 | ## 64 | # lxml 65 | ## 66 | 67 | - name: Dependencies lxml | Install compile time dependencies 68 | become: true 69 | ansible.builtin.apt: 70 | state: present 71 | name: 72 | - libxml2 73 | - libxml2-dev 74 | - libxslt1.1 75 | - libxslt1-dev 76 | when: lxml 77 | -------------------------------------------------------------------------------- /tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install dependencies 4 | ansible.builtin.import_tasks: deps.yml 5 | 6 | - name: Install Python 2.x 7 | ansible.builtin.import_tasks: python2x.yml 8 | 9 | - name: Install Python 3.x 10 | ansible.builtin.import_tasks: python3x.yml 11 | 12 | - name: Install virtualenvs 13 | ansible.builtin.import_tasks: venvs.yml 14 | 15 | - name: Miscellaneous 16 | ansible.builtin.import_tasks: misc.yml 17 | -------------------------------------------------------------------------------- /tasks/misc.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Create a symlink to easily create python 2.7 virtualenvs 4 | become: true 5 | ansible.builtin.file: 6 | src: /srv/python2.7/bin/virtualenv 7 | dest: /usr/local/bin/virtualenv 8 | state: link 9 | when: python_27 10 | -------------------------------------------------------------------------------- /tasks/python24.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Python 2.4 | Check that py24 is still not installed 4 | become: true 5 | ansible.builtin.stat: 6 | path: "{{ py24.bin }}" 7 | register: py24_already_installed 8 | ignore_errors: true 9 | 10 | - name: Python 2.4 | Download 11 | ansible.builtin.get_url: 12 | url: "{{ py24.url }}" 13 | dest: "{{ py24.tar_file }}" 14 | checksum: "md5:{{ py24.md5 }}" 15 | mode: "0440" 16 | when: python_24 and not py24_already_installed.stat.exists 17 | 18 | - name: Python 2.4 | Uncompress 19 | ansible.builtin.unarchive: 20 | src: "{{ py24.tar_file }}" 21 | dest: /tmp 22 | copy: false 23 | creates: "{{ py24.sources }}" 24 | when: python_24 and not py24_already_installed.stat.exists 25 | 26 | - name: Python 2.4 | Configure sources 27 | become: true 28 | ansible.builtin.command: "./configure --prefix {{ py24.install }}" 29 | args: 30 | chdir: "{{ py24.sources }}" 31 | when: python_24 and not py24_already_installed.stat.exists 32 | register: output 33 | changed_when: output.rc != 0 34 | 35 | - name: Python 2.4 | Tweak sources 36 | become: true 37 | ansible.builtin.lineinfile: 38 | dest: "{{ py24.sources }}/Modules/Setup" 39 | regexp: ^#zlib(.*) 40 | line: zlib\1 41 | backrefs: true 42 | when: python_24 and not py24_already_installed.stat.exists 43 | 44 | - name: Python 2.4 | Compile and install 45 | become: true 46 | ansible.builtin.command: "{{ item }}" 47 | args: 48 | chdir: "{{ py24.sources }}" 49 | with_items: 50 | - make 51 | - make install 52 | when: python_24 and not py24_already_installed.stat.exists 53 | register: output 54 | changed_when: output.rc != 0 55 | 56 | - name: Python 2.4 | Create python_major_version symlink 57 | become: true 58 | ansible.builtin.file: 59 | src: "{{ py24.install }}" 60 | dest: "{{ base_install_folder }}/python{{ py24.major_version }}" 61 | state: link 62 | when: python_24 and not py24_already_installed.stat.exists 63 | -------------------------------------------------------------------------------- /tasks/python26.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Python 2.6 | Check that py26 is still not installed 4 | become: true 5 | ansible.builtin.stat: 6 | path: "{{ py26.bin }}" 7 | register: py26_already_installed 8 | ignore_errors: true 9 | 10 | - name: Python 2.6 | Download 11 | ansible.builtin.get_url: 12 | url: "{{ py26.url }}" 13 | dest: "{{ py26.tar_file }}" 14 | checksum: "md5:{{ py26.md5 }}" 15 | mode: "0440" 16 | when: python_26 and not py26_already_installed.stat.exists 17 | 18 | - name: Python 2.6 | Uncompress 19 | ansible.builtin.unarchive: 20 | src: "{{ py26.tar_file }}" 21 | dest: /tmp 22 | copy: false 23 | creates: "{{ py26.sources }}" 24 | when: python_26 and not py26_already_installed.stat.exists 25 | 26 | - name: Python 2.6 | Configure sources 27 | become: true 28 | ansible.builtin.command: "./configure --prefix {{ py26.install }}" 29 | args: 30 | chdir: "{{ py26.sources }}" 31 | when: python_26 and not py26_already_installed.stat.exists 32 | register: output 33 | changed_when: output.rc != 0 34 | 35 | - name: Python 2.6 | Tweak sources 36 | become: true 37 | ansible.builtin.lineinfile: 38 | dest: "{{ py26.sources }}/Modules/Setup" 39 | regexp: ^#zlib(.*) 40 | line: zlib\1 41 | backrefs: true 42 | when: python_26 and not py26_already_installed.stat.exists 43 | 44 | - name: Python 2.6 | Tweak sources 45 | become: true 46 | ansible.builtin.lineinfile: 47 | dest: "{{ py26.sources }}/Modules/Setup" 48 | regexp: ^#_sha256(.*) 49 | line: _sha256\1 50 | backrefs: true 51 | when: python_26 and not py26_already_installed.stat.exists 52 | 53 | - name: Python 2.6 | Tweak sources 54 | become: true 55 | ansible.builtin.lineinfile: 56 | dest: "{{ py26.sources }}/Modules/Setup" 57 | regexp: ^#_sha512(.*) 58 | line: _sha512\1 59 | backrefs: true 60 | when: python_26 and not py26_already_installed.stat.exists 61 | 62 | - name: Python 2.6 | Compile and install 63 | become: true 64 | ansible.builtin.command: "{{ item }}" 65 | args: 66 | chdir: "{{ py26.sources }}" 67 | with_items: 68 | - make 69 | - make install 70 | when: python_26 and not py26_already_installed.stat.exists 71 | register: output 72 | changed_when: output.rc != 0 73 | 74 | - name: Python 2.6 | Create python_major_version symlink 75 | become: true 76 | ansible.builtin.file: 77 | src: "{{ py26.install }}" 78 | dest: "{{ base_install_folder }}/python{{ py26.major_version }}" 79 | state: link 80 | when: python_26 and not py26_already_installed.stat.exists 81 | -------------------------------------------------------------------------------- /tasks/python2x.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install Python 2.4 4 | ansible.builtin.import_tasks: python24.yml 5 | 6 | - name: Install Python 2.6 7 | ansible.builtin.import_tasks: python26.yml 8 | 9 | - name: Install Python 2.7 10 | ansible.builtin.include_tasks: 11 | file: python_generic.yml 12 | vars: 13 | py_data: "{{ py27 }}" 14 | when: python_27 15 | -------------------------------------------------------------------------------- /tasks/python3x.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install Python 3.1 4 | ansible.builtin.include_tasks: 5 | file: python_generic.yml 6 | vars: 7 | py_data: "{{ py31 }}" 8 | when: python_31 9 | 10 | - name: Install Python 3.2 11 | ansible.builtin.include_tasks: 12 | file: python_generic.yml 13 | vars: 14 | py_data: "{{ py32 }}" 15 | when: python_32 16 | 17 | - name: Install Python 3.3 18 | ansible.builtin.include_tasks: 19 | file: python_generic.yml 20 | vars: 21 | py_data: "{{ py33 }}" 22 | when: python_33 23 | 24 | - name: Install Python 3.4 25 | ansible.builtin.include_tasks: 26 | file: python_generic.yml 27 | vars: 28 | py_data: "{{ py34 }}" 29 | when: python_34 30 | 31 | - name: Install Python 3.5 32 | ansible.builtin.include_tasks: 33 | file: python_generic.yml 34 | vars: 35 | py_data: "{{ py35 }}" 36 | when: python_35 37 | 38 | - name: Install Python 3.6 39 | ansible.builtin.include_tasks: 40 | file: python_generic.yml 41 | vars: 42 | py_data: "{{ py36 }}" 43 | when: python_36 44 | 45 | - name: Install Python 3.7 46 | ansible.builtin.include_tasks: 47 | file: python_generic.yml 48 | vars: 49 | py_data: "{{ py37 }}" 50 | when: python_37 51 | 52 | - name: Install Python 3.8 53 | ansible.builtin.include_tasks: 54 | file: python_generic.yml 55 | vars: 56 | py_data: "{{ py38 }}" 57 | when: python_38 58 | 59 | - name: Install Python 3.9 60 | ansible.builtin.include_tasks: 61 | file: python_generic.yml 62 | vars: 63 | py_data: "{{ py39 }}" 64 | when: python_39 65 | 66 | - name: Install Python 3.10 67 | ansible.builtin.include_tasks: 68 | file: python_generic.yml 69 | vars: 70 | py_data: "{{ py310 }}" 71 | when: python_310 72 | 73 | - name: Install Python 3.11 74 | ansible.builtin.include_tasks: 75 | file: python_generic.yml 76 | vars: 77 | py_data: "{{ py311 }}" 78 | when: python_311 79 | 80 | - name: Install Python 3.12 81 | ansible.builtin.include_tasks: 82 | file: python_generic.yml 83 | vars: 84 | py_data: "{{ py312 }}" 85 | when: python_312 86 | 87 | - name: Install Python 3.13 88 | ansible.builtin.include_tasks: 89 | file: python_generic.yml 90 | vars: 91 | py_data: "{{ py313 }}" 92 | when: python_313 93 | -------------------------------------------------------------------------------- /tasks/python_generic.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "Python | Check that it is still not installed | {{ py_data.version }}" 4 | become: true 5 | ansible.builtin.stat: 6 | path: "{{ py_data.bin }}" 7 | register: already_installed 8 | ignore_errors: true 9 | 10 | - name: "Python | Download | {{ py_data.version }}" 11 | ansible.builtin.get_url: 12 | url: "{{ py_data.url }}" 13 | dest: "{{ py_data.tar_file }}" 14 | checksum: "md5:{{ py_data.md5 }}" 15 | mode: "0440" 16 | when: not already_installed.stat.exists 17 | 18 | - name: "Python | Uncompress | {{ py_data.version }}" 19 | ansible.builtin.unarchive: 20 | src: "{{ py_data.tar_file }}" 21 | dest: /tmp 22 | copy: false 23 | creates: "{{ py_data.sources }}" 24 | when: not already_installed.stat.exists 25 | 26 | - name: "Python | Compile and install | {{ py_data.version }}" 27 | become: true 28 | ansible.builtin.command: "{{ item }}" 29 | args: 30 | chdir: "{{ py_data.sources }}" 31 | with_items: 32 | - "./configure --enable-optimizations --prefix {{ py_data.install }}" 33 | - make 34 | - make install 35 | when: not already_installed.stat.exists 36 | register: output 37 | changed_when: output.rc != 0 38 | 39 | - name: "Python | Create symlink | {{ py_data.version }}" 40 | become: true 41 | ansible.builtin.file: 42 | src: "{{ py_data.install }}" 43 | dest: "{{ base_install_folder }}/python{{ py_data.major_version }}" 44 | state: link 45 | when: not already_installed.stat.exists 46 | -------------------------------------------------------------------------------- /tasks/venv.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "Virtualenv | Check if it is already installed | {{ py_data.version }}" 4 | become: true 5 | ansible.builtin.stat: 6 | path: "{{ py_data.install }}/bin/virtualenv" 7 | register: already_installed 8 | ignore_errors: true 9 | 10 | - name: "Virtualenv | Download | {{ py_data.version }}" 11 | ansible.builtin.get_url: 12 | url: "{{ venv_data.url }}" 13 | dest: "{{ venv_data.tar_file }}" 14 | checksum: "md5:{{ venv_data.md5 }}" 15 | mode: "0440" 16 | when: not already_installed.stat.exists 17 | 18 | - name: "Virtualenv | Uncompress | {{ py_data.version }}" 19 | ansible.builtin.unarchive: 20 | src: "{{ venv_data.tar_file }}" 21 | dest: /tmp 22 | copy: false 23 | when: not already_installed.stat.exists 24 | 25 | - name: " Virtualenv | Install | {{ py_data.version }}" 26 | become: true 27 | ansible.builtin.command: "{{ item }}" 28 | args: 29 | chdir: "{{ venv_data.sources }}" 30 | creates: "{{ py_data.install }}/bin/virtualenv" 31 | with_items: 32 | - "{{ py_data.bin }} setup.py install" 33 | when: not already_installed.stat.exists 34 | -------------------------------------------------------------------------------- /tasks/venv27.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: "Virtualenv | Check if it is already installed | {{ py_data.version }}" 4 | become: true 5 | ansible.builtin.stat: 6 | path: "{{ py_data.install }}/bin/virtualenv" 7 | register: already_installed 8 | ignore_errors: true 9 | 10 | - name: "Virtualenv | Download | {{ py_data.version }}" 11 | ansible.builtin.get_url: 12 | url: "{{ venv_data.url }}" 13 | dest: "{{ venv_data.wheel_file }}" 14 | checksum: "md5:{{ venv_data.md5 }}" 15 | mode: "0440" 16 | when: not already_installed.stat.exists 17 | 18 | - name: "Virtualenv | Download | pip" 19 | ansible.builtin.get_url: 20 | url: "https://bootstrap.pypa.io/pip/2.7/get-pip.py" 21 | dest: "/tmp/get-pip.py" 22 | checksum: "md5:60e8267eb1b7bc71dc4843eb7bd294d3" 23 | mode: "0440" 24 | when: not already_installed.stat.exists 25 | 26 | - name: "Virtualenv | Install | pip" 27 | ansible.builtin.command: "{{ item }}" 28 | args: 29 | creates: "{{ py_data.install }}/bin/pip" 30 | with_items: 31 | - "{{ py_data.install }}/bin/python /tmp/get-pip.py" 32 | when: not already_installed.stat.exists 33 | 34 | - name: " Virtualenv | Install | {{ py_data.version }}" 35 | become: true 36 | ansible.builtin.command: "{{ item }}" 37 | args: 38 | creates: "{{ py_data.install }}/bin/virtualenv" 39 | with_items: 40 | - "{{ py_data.install }}/bin/pip install {{ venv_data.wheel_file }}" 41 | when: not already_installed.stat.exists 42 | -------------------------------------------------------------------------------- /tasks/venvs.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | - name: Install Virtualenv for Python 2.4 4 | ansible.builtin.include_tasks: 5 | file: venv.yml 6 | vars: 7 | py_data: "{{ py24 }}" 8 | venv_data: "{{ venv24 }}" 9 | when: python_24 10 | 11 | - name: Install Virtualenv for Python 2.6 12 | ansible.builtin.include_tasks: 13 | file: venv.yml 14 | vars: 15 | py_data: "{{ py26 }}" 16 | venv_data: "{{ venv26 }}" 17 | when: python_26 18 | 19 | - name: Install Virtualenv for Python 2.7 20 | ansible.builtin.include_tasks: 21 | file: venv27.yml 22 | vars: 23 | py_data: "{{ py27 }}" 24 | venv_data: "{{ venv27 }}" 25 | when: python_27 26 | --------------------------------------------------------------------------------