- Создана универсальная роль Python для установки Python 3.12 на всех ОС - Восстановлена роль Docker из git истории - Исправлены все ошибки линтера - Обновлен deploy.yml с правильным порядком ролей: devops → python → docker - Удалена устаревшая роль ping - Добавлена поддержка альтернативных репозиториев для старых ОС Автор: Сергей Антропов Сайт: https://devops.org.ru
544 lines
20 KiB
YAML
544 lines
20 KiB
YAML
---
|
||
# Основные задачи для установки 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 # Установить пакет
|
||
|
||
🚀 Готово к работе! |