Вопрос или проблема
- name: Установленные пакеты.
ansible.builtin.shell:
cmd: apt list --installed | cut -d"https://serverfault.com/" -f1 | uniq
register: установленные_пакеты
- name: Установить пакеты.
ansible.builtin.apt:
name: "{{ item }}"
state: present
when: 'item not in установленные_пакеты.stdout.splitlines()'
loop:
- 7zip
- acl
У меня есть вышеуказанная задача. Работает отлично, ЗА ИСКЛЮЧЕНИЕМ того, что ‘string’ соответствует частичным именам пакетов. То есть, если я хочу установить пакет ‘acl’, он пропускается, потому что ‘libacl1’ уже установлен. Мне нужно, чтобы соответствие происходило по полному имени пакета и ТОЛЬКО по полному имени пакета.
Есть ли способ сделать это?
Ответ или решение
Для решения проблемы с установкой пакетов в Ansible и предотвращения пропуска требуемых пакетов из-за неполного совпадения названий, необходимо изменить условие проверки. В текущем коде используется конструкция when: 'item | string not in installed_packages.stdout'
, которая действительно позволяет осуществлять частичное совпадение имен пакетов, что приводит к проблеме при установке, например, пакета ‘acl’, когда установлен ‘libacl1’.
Чтобы обеспечить полное совпадение имен пакетов, вы можете воспользоваться фильтрацией списка установленных пакетов и проверкой с помощью регулярного выражения. Ниже представлен обновленный вариант вашего кода, который учитывает только полные совпадения имен пакетов:
- name: Получить список установленных пакетов.
ansible.builtin.shell:
cmd: apt list --installed | cut -d"/" -f1 | uniq
register: installed_packages
- name: Установить пакеты.
ansible.builtin.apt:
name: "{{ item }}"
state: present
when: "'{{ item }}' not in installed_packages.stdout.splitlines() | map('trim') | list"
loop:
- 7zip
- acl
Объяснение изменений:
-
Получение списка установленных пакетов: Команда
apt list --installed
возвращает полный список установленных пакетов на системе. В скрипте используетсяcut -d"/" -f1
для получения только имен пакетов (игнорируя информацию о версии), аuniq
убирает дубликаты. -
Проверка на полное совпадение: Ошибка, связанная с частичными совпадениями, исправляется с помощью
when: "'{{ item }}' not in installed_packages.stdout.splitlines() | map('trim') | list"
. Этот подход разбиваетstdout
на строки с помощью методаsplitlines()
, затем применяет фильтрmap('trim')
, чтобы удалить лишние пробелы. Это позволяет делать корректную проверку наличия полного имени пакета в списке установленных пакетов. -
Использование
loop
: Через циклloop
задаются пакеты для установки, как в исходном варианте. Если пакет уже установлен (полное совпадение), он не будет установлен повторно.
Рекомендации по улучшению:
- Логи: Рекомендуется добавить задачу логирования, чтобы отслеживать, какие пакеты были установлены или пропущены. Это поможет в диагностике и обеспечит прозрачность выполнения playbook.
- Тестирование: Перед запуском в производственной среде протестируйте новый код в безопасной среде, чтобы удостовериться, что все работает согласно ожиданиям.
- Версия Ansible: Убедитесь, что используете актуальную версию Ansible, так как новые релизы могут содержать улучшения и исправления, касающиеся выполнения задач.
Приведенное решение должно полностью устранить проблему с частичным совпадением имен пакетов и обеспечить корректное поведение вашего Ansible playbook.