feat: Добавлена роль Python 3.12 и восстановлена роль Docker
- Создана универсальная роль Python для установки Python 3.12 на всех ОС - Восстановлена роль Docker из git истории - Исправлены все ошибки линтера - Обновлен deploy.yml с правильным порядком ролей: devops → python → docker - Удалена устаревшая роль ping - Добавлена поддержка альтернативных репозиториев для старых ОС Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
544
roles/python/tasks/main.yml
Normal file
544
roles/python/tasks/main.yml
Normal file
@@ -0,0 +1,544 @@
|
||||
---
|
||||
# Основные задачи для установки Python 3.12
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- name: "Отладочная информация о системе"
|
||||
debug:
|
||||
msg:
|
||||
- "ansible_distribution: '{{ ansible_distribution }}'"
|
||||
- "ansible_os_family: '{{ ansible_os_family }}'"
|
||||
- "ansible_distribution_version: '{{ ansible_distribution_version }}'"
|
||||
when: (python_log_level | default("INFO")) in ["DEBUG", "INFO"]
|
||||
|
||||
- name: "Определение переменных для текущей ОС"
|
||||
set_fact:
|
||||
python_distribution: "{{ ansible_distribution | lower }}"
|
||||
python_os_family: "{{ ansible_os_family | lower }}"
|
||||
python_current_package_manager: "{{ python_package_managers[ansible_distribution | lower] | default('unknown') }}"
|
||||
python_current_packages: "{{ python_packages_by_os[ansible_distribution | lower] | default([]) }}"
|
||||
python_current_build_deps: "{{ python_build_deps_by_os[ansible_distribution | lower] | default([]) }}"
|
||||
python_current_executable: "{{ python_executable_paths[ansible_distribution | lower] | default('/usr/bin/python3.12') }}"
|
||||
python_current_pip: "{{ python_pip_paths[ansible_distribution | lower] | default('/usr/bin/pip3.12') }}"
|
||||
|
||||
- name: "Проверка определенных переменных"
|
||||
debug:
|
||||
msg:
|
||||
- "python_distribution: '{{ python_distribution }}'"
|
||||
- "python_os_family: '{{ python_os_family }}'"
|
||||
- "python_current_package_manager: '{{ python_current_package_manager }}'"
|
||||
- "python_current_packages: {{ python_current_packages }}"
|
||||
- "python_current_build_deps: {{ python_current_build_deps }}"
|
||||
- "python_current_executable: '{{ python_current_executable }}'"
|
||||
- "python_current_pip: '{{ python_current_pip }}'"
|
||||
when: (python_log_level | default("INFO")) in ["DEBUG", "INFO"]
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 1: ДОБАВЛЕНИЕ РЕПОЗИТОРИЕВ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Добавление репозиториев для Ubuntu/Debian"
|
||||
apt_repository:
|
||||
repo: "{{ item.url }}"
|
||||
state: "{{ item.state }}"
|
||||
update_cache: yes
|
||||
loop: "{{ python_repositories[python_distribution] | default([]) }}"
|
||||
when:
|
||||
- python_distribution in ['ubuntu', 'debian']
|
||||
- python_repositories[python_distribution] is defined
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Добавление репозиториев для RHEL-семейства"
|
||||
package:
|
||||
name: "{{ item.name }}"
|
||||
state: "{{ item.state }}"
|
||||
loop: "{{ python_repositories[python_distribution] | default([]) }}"
|
||||
when:
|
||||
- python_distribution in ['redhat', 'centos', 'rhel', 'rocky', 'alma', 'fedora']
|
||||
- python_repositories[python_distribution] is defined
|
||||
- item.name != 'scl'
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Добавление SCL репозиториев для старых RHEL/CentOS"
|
||||
yum_repository:
|
||||
name: "{{ item.name }}"
|
||||
description: "{{ item.name }} repository"
|
||||
baseurl: "{{ item.url }}"
|
||||
gpgcheck: no
|
||||
enabled: yes
|
||||
loop: "{{ python_repositories[python_distribution] | default([]) }}"
|
||||
when:
|
||||
- python_distribution in ['redhat', 'centos', 'rhel']
|
||||
- python_repositories[python_distribution] is defined
|
||||
- item.name == 'scl'
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 2: ОБНОВЛЕНИЕ ПАКЕТОВ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Обновление списка пакетов"
|
||||
package:
|
||||
name: "*"
|
||||
state: present
|
||||
when:
|
||||
- python_current_package_manager in ['apt', 'dnf', 'zypper']
|
||||
- python_current_package_manager != 'unknown'
|
||||
|
||||
- name: "Обновление списка пакетов после добавления репозиториев"
|
||||
package:
|
||||
name: "*"
|
||||
state: present
|
||||
when:
|
||||
- python_repositories[python_distribution] is defined
|
||||
- python_current_package_manager in ['apt', 'dnf']
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 3: УСТАНОВКА СИСТЕМНЫХ ЗАВИСИМОСТЕЙ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Установка системных зависимостей для компиляции"
|
||||
package:
|
||||
name: "{{ python_current_build_deps }}"
|
||||
state: present
|
||||
when:
|
||||
- python_current_build_deps | length > 0
|
||||
- python_current_package_manager != 'unknown'
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 4: ПРОВЕРКА И УСТАНОВКА PYTHON СТАНДАРТНЫМ СПОСОБОМ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Проверка наличия Python {{ python_version }}"
|
||||
command: "{{ python_current_executable }} --version"
|
||||
register: python_version_check
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: python_current_executable is defined and python_current_executable != ""
|
||||
|
||||
- name: "Установка Python из пакетов (основной способ)"
|
||||
package:
|
||||
name: "{{ python_current_packages }}"
|
||||
state: present
|
||||
when:
|
||||
- python_current_packages | length > 0
|
||||
- python_current_package_manager != 'unknown'
|
||||
- python_version_check.rc != 0
|
||||
register: python_package_install
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 5: FALLBACK НА АЛЬТЕРНАТИВНЫЕ СПОСОБЫ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Попытка установки альтернативных пакетов Python"
|
||||
package:
|
||||
name: "{{ python_current_packages | select('match', '.*python3\\.1[12].*') | list }}"
|
||||
state: present
|
||||
when:
|
||||
- python_package_install is defined
|
||||
- python_package_install.failed | default(false)
|
||||
- python_current_package_manager != 'unknown'
|
||||
- python_version_check.rc != 0
|
||||
register: python_alt_install
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Попытка установки SCL пакетов Python"
|
||||
package:
|
||||
name: "{{ python_current_packages | select('match', '.*rh-python.*') | list }}"
|
||||
state: present
|
||||
when:
|
||||
- python_alt_install is defined
|
||||
- python_alt_install.failed | default(false)
|
||||
- python_current_package_manager != 'unknown'
|
||||
- python_version_check.rc != 0
|
||||
- python_distribution in ['redhat', 'centos', 'rhel']
|
||||
register: python_scl_install
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 6: КОМПИЛЯЦИЯ ИЗ ИСХОДНИКОВ (ПОСЛЕДНИЙ СПОСОБ)
|
||||
# =============================================================================
|
||||
|
||||
- name: "Скачивание исходного кода Python {{ python_version }}"
|
||||
get_url:
|
||||
url: "https://www.python.org/ftp/python/{{ python_version }}/Python-{{ python_version }}.tar.xz"
|
||||
dest: "/tmp/Python-{{ python_version }}.tar.xz"
|
||||
mode: '0644'
|
||||
register: download_result
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when:
|
||||
- python_current_packages | length == 0
|
||||
- python_version_check.rc != 0
|
||||
- python_package_install is defined
|
||||
- python_package_install.failed | default(false)
|
||||
- python_alt_install is defined
|
||||
- python_alt_install.failed | default(false)
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Распаковка исходного кода Python"
|
||||
unarchive:
|
||||
src: "/tmp/Python-{{ python_version }}.tar.xz"
|
||||
dest: "/tmp/"
|
||||
remote_src: yes
|
||||
when:
|
||||
- python_current_packages | length == 0
|
||||
- python_version_check.rc != 0
|
||||
- download_result is defined
|
||||
- download_result.status_code == 200
|
||||
|
||||
- name: "Конфигурация Python для компиляции"
|
||||
command: >
|
||||
./configure
|
||||
--prefix={{ python_install_prefix | default('/usr/local') }}
|
||||
--enable-optimizations
|
||||
--enable-shared
|
||||
--with-lto
|
||||
--enable-ipv6
|
||||
--with-system-ffi
|
||||
--with-computed-gotos
|
||||
--enable-loadable-sqlite-extensions
|
||||
args:
|
||||
chdir: "/tmp/Python-{{ python_version }}"
|
||||
changed_when: false
|
||||
when:
|
||||
- python_current_packages | length == 0
|
||||
- python_version_check.rc != 0
|
||||
- download_result is defined
|
||||
- download_result.status_code == 200
|
||||
|
||||
- name: "Компиляция Python"
|
||||
make:
|
||||
chdir: "/tmp/Python-{{ python_version }}"
|
||||
jobs: "{{ ansible_processor_cores | default(1) }}"
|
||||
when:
|
||||
- python_current_packages | length == 0
|
||||
- python_version_check.rc != 0
|
||||
- download_result is defined
|
||||
- download_result.status_code == 200
|
||||
|
||||
- name: "Установка скомпилированного Python"
|
||||
make:
|
||||
chdir: "/tmp/Python-{{ python_version }}"
|
||||
target: install
|
||||
become: true
|
||||
when:
|
||||
- python_current_packages | length == 0
|
||||
- python_version_check.rc != 0
|
||||
- download_result is defined
|
||||
- download_result.status_code == 200
|
||||
|
||||
- name: "Обновление библиотек для скомпилированного Python"
|
||||
command: "ldconfig"
|
||||
become: true
|
||||
changed_when: false
|
||||
when:
|
||||
- python_current_packages | length == 0
|
||||
- python_version_check.rc != 0
|
||||
- download_result is defined
|
||||
- download_result.status_code == 200
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 7: СОЗДАНИЕ СИМВОЛИЧЕСКИХ ССЫЛОК
|
||||
# =============================================================================
|
||||
|
||||
- name: "Создание символических ссылок для Python"
|
||||
file:
|
||||
src: "{{ python_current_executable }}"
|
||||
dest: "/usr/bin/python3"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
|
||||
- name: "Создание символических ссылок для SCL Python"
|
||||
file:
|
||||
src: "/opt/rh/rh-python312/root/usr/bin/python3"
|
||||
dest: "/usr/bin/python3"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
- python_distribution in ['redhat', 'centos', 'rhel']
|
||||
- python_scl_install is defined
|
||||
- python_scl_install.changed | default(false)
|
||||
|
||||
- name: "Создание символических ссылок для pip"
|
||||
file:
|
||||
src: "{{ python_current_pip }}"
|
||||
dest: "/usr/bin/pip3"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
- python_current_pip is defined
|
||||
- python_current_pip != ""
|
||||
|
||||
- name: "Создание символических ссылок для SCL pip"
|
||||
file:
|
||||
src: "/opt/rh/rh-python312/root/usr/bin/pip3"
|
||||
dest: "/usr/bin/pip3"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
- python_distribution in ['redhat', 'centos', 'rhel']
|
||||
- python_scl_install is defined
|
||||
- python_scl_install.changed | default(false)
|
||||
|
||||
- name: "Создание символических ссылок для Python (без версии)"
|
||||
file:
|
||||
src: "{{ python_current_executable }}"
|
||||
dest: "/usr/bin/python"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
|
||||
- name: "Создание символических ссылок для SCL Python (без версии)"
|
||||
file:
|
||||
src: "/opt/rh/rh-python312/root/usr/bin/python"
|
||||
dest: "/usr/bin/python"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
- python_distribution in ['redhat', 'centos', 'rhel']
|
||||
- python_scl_install is defined
|
||||
- python_scl_install.changed | default(false)
|
||||
|
||||
- name: "Создание символических ссылок для pip (без версии)"
|
||||
file:
|
||||
src: "{{ python_current_pip }}"
|
||||
dest: "/usr/bin/pip"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
- python_current_pip is defined
|
||||
- python_current_pip != ""
|
||||
|
||||
- name: "Создание символических ссылок для SCL pip (без версии)"
|
||||
file:
|
||||
src: "/opt/rh/rh-python312/root/usr/bin/pip"
|
||||
dest: "/usr/bin/pip"
|
||||
state: link
|
||||
force: yes
|
||||
when:
|
||||
- (python_create_symlinks | default(true)) | bool
|
||||
- python_version_check.rc != 0
|
||||
- python_distribution in ['redhat', 'centos', 'rhel']
|
||||
- python_scl_install is defined
|
||||
- python_scl_install.changed | default(false)
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 8: НАСТРОЙКА АЛЬТЕРНАТИВ И PIP
|
||||
# =============================================================================
|
||||
|
||||
- name: "Настройка альтернатив для Python"
|
||||
alternatives:
|
||||
name: python3
|
||||
path: "{{ python_current_executable }}"
|
||||
when:
|
||||
- python_current_executable is defined
|
||||
- python_current_executable != ""
|
||||
- ansible_os_family == "RedHat"
|
||||
|
||||
- name: "Установка pip через get-pip.py если не найден"
|
||||
get_url:
|
||||
url: "https://bootstrap.pypa.io/get-pip.py"
|
||||
dest: "/tmp/get-pip.py"
|
||||
mode: '0755'
|
||||
when:
|
||||
- python_version_check.rc == 0
|
||||
- python_current_pip is not defined or python_current_pip == ""
|
||||
|
||||
- name: "Запуск get-pip.py для установки pip"
|
||||
command: "{{ python_current_executable }} /tmp/get-pip.py"
|
||||
changed_when: false
|
||||
when:
|
||||
- python_version_check.rc == 0
|
||||
- python_current_pip is not defined or python_current_pip == ""
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 9: ОБНОВЛЕНИЕ PIP
|
||||
# =============================================================================
|
||||
|
||||
- name: "Получение последней версии pip"
|
||||
uri:
|
||||
url: "https://pypi.org/pypi/pip/json"
|
||||
method: GET
|
||||
register: pip_version_info
|
||||
when: python_version_check.rc == 0
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Извлечение версии pip"
|
||||
set_fact:
|
||||
pip_latest_version: "{{ pip_version_info.json.info.version }}"
|
||||
when:
|
||||
- pip_version_info is defined
|
||||
- pip_version_info.status == 200
|
||||
|
||||
- name: "Проверка текущей версии pip"
|
||||
command: "{{ python_current_pip }} --version"
|
||||
register: pip_current_version
|
||||
changed_when: false
|
||||
when:
|
||||
- python_version_check.rc == 0
|
||||
- python_current_pip is defined
|
||||
- python_current_pip != ""
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Обновление pip до последней версии"
|
||||
command: "{{ python_current_pip }} install --upgrade pip"
|
||||
changed_when: false
|
||||
when:
|
||||
- python_version_check.rc == 0
|
||||
- pip_current_version.rc == 0
|
||||
- pip_latest_version is defined
|
||||
- pip_current_version.stdout is defined
|
||||
- pip_latest_version not in pip_current_version.stdout
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 10: СОЗДАНИЕ ВИРТУАЛЬНОГО ОКРУЖЕНИЯ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Создание виртуального окружения"
|
||||
command: "{{ python_current_executable }} -m venv {{ python_venv_path | default('/opt/python-venv') }}"
|
||||
changed_when: false
|
||||
when:
|
||||
- (python_create_venv | default(false)) | bool
|
||||
- python_version_check.rc == 0
|
||||
ignore_errors: true
|
||||
|
||||
# =============================================================================
|
||||
# ЭТАП 11: ФИНАЛЬНЫЙ ОТЧЕТ
|
||||
# =============================================================================
|
||||
|
||||
- name: "Сбор информации о системе"
|
||||
setup:
|
||||
gather_subset:
|
||||
- "!all"
|
||||
- "distribution"
|
||||
- "os_family"
|
||||
- "architecture"
|
||||
- "kernel"
|
||||
- "python"
|
||||
register: system_facts
|
||||
|
||||
- name: "Проверка установленного Python"
|
||||
command: "{{ python_current_executable }} --version"
|
||||
register: final_python_version
|
||||
changed_when: false
|
||||
when: python_version_check.rc == 0
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Проверка установленного pip"
|
||||
command: "{{ python_current_pip }} --version"
|
||||
register: final_pip_version
|
||||
changed_when: false
|
||||
when:
|
||||
- python_version_check.rc == 0
|
||||
- python_current_pip is defined
|
||||
- python_current_pip != ""
|
||||
ignore_errors: true
|
||||
|
||||
- name: "Проверка символических ссылок"
|
||||
stat:
|
||||
path: "{{ item }}"
|
||||
register: symlink_check
|
||||
loop:
|
||||
- "/usr/bin/python"
|
||||
- "/usr/bin/python3"
|
||||
- "/usr/bin/pip"
|
||||
- "/usr/bin/pip3"
|
||||
|
||||
- name: "Проверка виртуального окружения"
|
||||
stat:
|
||||
path: "{{ python_venv_path | default('/opt/python-venv') }}"
|
||||
register: venv_check
|
||||
when: python_create_venv | bool
|
||||
|
||||
- name: "Сбор информации об установленных пакетах Python"
|
||||
package_facts:
|
||||
manager: "{{ python_current_package_manager }}"
|
||||
when: python_current_package_manager != 'unknown'
|
||||
|
||||
- name: "Финальный отчет об установке"
|
||||
debug:
|
||||
msg: |
|
||||
|
||||
================================================================================
|
||||
🐍 ОТЧЕТ ОБ УСТАНОВКЕ PYTHON {{ python_version | upper }}
|
||||
================================================================================
|
||||
|
||||
📊 ИНФОРМАЦИЯ О СИСТЕМЕ:
|
||||
• Дистрибутив: {{ system_facts.ansible_facts.distribution }} {{ system_facts.ansible_facts.distribution_version }}
|
||||
• Семейство ОС: {{ system_facts.ansible_facts.os_family }}
|
||||
• Архитектура: {{ system_facts.ansible_facts.architecture }}
|
||||
• Ядро: {{ system_facts.ansible_facts.kernel }}
|
||||
|
||||
🐍 PYTHON:
|
||||
• Версия: {{ final_python_version.stdout | default('НЕ УСТАНОВЛЕН') }}
|
||||
• Исполняемый файл: {{ python_current_executable }}
|
||||
• Путь к pip: {{ python_current_pip | default('НЕ НАЙДЕН') }}
|
||||
|
||||
📦 PIP:
|
||||
• Версия: {{ final_pip_version.stdout | default('НЕ УСТАНОВЛЕН') }}
|
||||
|
||||
🔗 СИМВОЛИЧЕСКИЕ ССЫЛКИ:
|
||||
• /usr/bin/python: {{ '✅ СОЗДАНА' if symlink_check.results[0].stat.exists else '❌ НЕ СОЗДАНА' }}
|
||||
• /usr/bin/python3: {{ '✅ СОЗДАНА' if symlink_check.results[1].stat.exists else '❌ НЕ СОЗДАНА' }}
|
||||
• /usr/bin/pip: {{ '✅ СОЗДАНА' if symlink_check.results[2].stat.exists else '❌ НЕ СОЗДАНА' }}
|
||||
• /usr/bin/pip3: {{ '✅ СОЗДАНА' if symlink_check.results[3].stat.exists else '❌ НЕ СОЗДАНА' }}
|
||||
|
||||
🌐 ВИРТУАЛЬНОЕ ОКРУЖЕНИЕ:
|
||||
• Путь: {{ python_venv_path | default('/opt/python-venv') }}
|
||||
• Статус: {{ '✅ СОЗДАНО' if (venv_check is defined and venv_check.stat.exists) else '❌ НЕ СОЗДАНО' }}
|
||||
|
||||
📋 УСТАНОВЛЕННЫЕ ПАКЕТЫ PYTHON:
|
||||
{% if ansible_facts.packages is defined %}
|
||||
{% for package in ansible_facts.packages %}
|
||||
{% if 'python' in package %}
|
||||
• {{ package }}: {{ ansible_facts.packages[package] | map(attribute='version') | list | join(', ') }}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
• Информация недоступна
|
||||
{% endif %}
|
||||
|
||||
🎯 КОМАНДЫ ДЛЯ ПРОВЕРКИ:
|
||||
• python --version
|
||||
• python3 --version
|
||||
• pip --version
|
||||
• pip3 --version
|
||||
• python -m venv test_env
|
||||
|
||||
================================================================================
|
||||
when: python_log_level in ["INFO", "DEBUG"]
|
||||
|
||||
- name: "Уведомление о завершении установки Python"
|
||||
debug:
|
||||
msg: |
|
||||
|
||||
✅ PYTHON {{ python_version | upper }} УСТАНОВЛЕН И НАСТРОЕН!
|
||||
|
||||
🎯 Основные команды:
|
||||
• python --version # Проверить версию Python
|
||||
• python3 --version # Проверить версию Python (с версией)
|
||||
• pip --version # Проверить версию pip
|
||||
• pip3 --version # Проверить версию pip (с версией)
|
||||
• python -m venv env # Создать виртуальное окружение
|
||||
• pip install pkg # Установить пакет
|
||||
|
||||
🚀 Готово к работе!
|
||||
Reference in New Issue
Block a user