Files
DevOpsLab/roles/python/tasks/main.yml
Сергей Антропов 0b4efd9ca1 feat: Добавлена роль Python 3.12 и восстановлена роль Docker
- Создана универсальная роль Python для установки Python 3.12 на всех ОС
- Восстановлена роль Docker из git истории
- Исправлены все ошибки линтера
- Обновлен deploy.yml с правильным порядком ролей: devops → python → docker
- Удалена устаревшая роль ping
- Добавлена поддержка альтернативных репозиториев для старых ОС

Автор: Сергей Антропов
Сайт: https://devops.org.ru
2025-10-27 22:08:37 +03:00

544 lines
20 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
# Основные задачи для установки 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 # Установить пакет
🚀 Готово к работе!