Вопрос: Как унифицировать задачи установки пакета?


Я начинаю с анзибль и будет использовать его, в частности, для установки пакетов на нескольких дистрибутивах Linux.

В документах я вижу, что yum а также apt команды разделены - что было бы самым простым способом их унификации и использовать что-то вроде этого:

- name: install the latest version of Apache
  unified_install: name=httpd state=latest

вместо

- name: install the latest version of Apache on CentOS
  yum: name=httpd state=latest
  when: ansible_os_family == "RedHat"

- name: install the latest version of Apache on Debian
  apt: pkg=httpd state=latest 
  when: ansible_os_family == "Debian"

Я понимаю, что два менеджера пакетов отличаются друг от друга, но у них все еще есть набор общих основных обычаев. Другие оркестры (соль, например) имеют одну команду установки.


58
2018-04-09 11:45


Источник


У вас может быть три рецепта: один, который выполняет итерацию по общему списку, а затем по одному для списков конкретных ОС. То, что я пытаюсь понять прямо сейчас, - это как уведомить обработчик с именем службы, специфичным для ОС, после того, как установлен общий элемент конфигурации. удачи! - dannyman
возможный дубликат Параметрическая управляющая команда, основанная на фактах, как это сделать? - xddsg


Ответы:


Обновление: по сравнению с Ansible 2.0, теперь есть общий и абстрактный package модуль

Примеры использования:

Теперь, когда имя пакета одинаково для разных семейств ОС, это так же просто, как:

---
- name: Install foo
  package: name=foo state=latest

Когда имя пакета отличается по семействам ОС, вы можете обрабатывать его с помощью файлов Vars для дистрибутива или ОС:

---
# roles/apache/apache.yml: Tasks entry point for 'apache' role. Called by main.yml
# Load a variable file based on the OS type, or a default if not found.
- include_vars: "{{ item }}"
  with_first_found:
    - "../vars/{{ ansible_distribution }}-{{ ansible_distribution_major_version | int}}.yml"
    - "../vars/{{ ansible_distribution }}.yml"
    - "../vars/{{ ansible_os_family }}.yml"
    - "../vars/default.yml"
  when: apache_package_name is not defined or apache_service_name is not defined

- name: Install Apache
  package: >
    name={{ apache_package_name }}
    state=latest

- name: Enable apache service
  service: >
    name={{ apache_service_name }}
    state=started
    enabled=yes
  tags: packages

Затем для каждой ОС, которую вы должны обрабатывать по-разному ... создайте файл vars:

---
# roles/apache/vars/default.yml
apache_package_name: apache2
apache_service_name: apache2

---
# roles/apache/vars/RedHat.yml
apache_package_name: httpd
apache_service_name: httpd

---
# roles/apache/vars/SLES.yml
apache_package_name: apache2
apache_service_name: apache2

---
# roles/apache/vars/Debian.yml
apache_package_name: apache2
apache_service_name: apache2

---
# roles/apache/vars/Archlinux.yml
apache_package_name: apache
apache_service_name: httpd



РЕДАКТИРОВАТЬ:  Поскольку Майкл ДеХаан (создатель Ansible) выбрал не абстрагировать модули диспетчера пакетов как шеф-повар делает, 

Если вы все еще используете более старую версию Ansible (Ansible <2.0), к сожалению, вам нужно будет справиться с этим в все ваших плейбуков и ролей. ИМХО это подталкивает много ненужной повторяющейся работы к авторам пьес и роли ... но так оно и есть. Обратите внимание, что я не говорю, что мы должны попытаться отвлечь менеджеров пакетов, все еще пытаясь поддержать все их конкретные параметры и команды, но просто иметь простой способ установить пакет, который является агностиком менеджера пакетов. Я также не говорю, что мы все должны Менеджер интеллектуальных пакетов но что-то вроде уровня абстракции установки пакета в вашем инструменте управления конфигурацией очень полезно для упрощения кросс-платформенных плейбуков / кулинарных книг. Смарт-проект выглядит интересным, но довольно амбициозно унифицировать управление пакетами через дистрибутивы и платформы без значительного принятия ... интересно будет ли это успешно. Реальная проблема заключается только в том, что имена пакетов иногда имеют разные различия между дистрибутивами, поэтому нам все равно приходится делать заявления о случаях или when: для обработки различий.

То, как я имел дело с этим, - это следовать этому tasks структура каталога в учебнике или роли:

roles/foo
└── tasks
    ├── apt_package.yml
    ├── foo.yml
    ├── homebrew_package.yml
    ├── main.yml
    └── yum_package.yml

И тогда у меня это в моем main.yml:

---
# foo: entry point for tasks
#                 Generally only include other file(s) and add tags here.

- include: foo.yml tags=foo

Это в foo.yml (для пакета 'foo'):

---
# foo: Tasks entry point. Called by main.yml
- include: apt_package.yml
  when: ansible_pkg_mgr == 'apt'
- include: yum_package.yml
  when: ansible_pkg_mgr == 'yum'
- include: homebrew_package.yml
  when: ansible_os_family == 'Darwin'

- name: Enable foo service
  service: >
    name=foo
    state=started
    enabled=yes
  tags: packages
  when: ansible_os_family != 'Darwin'

Затем для разных менеджеров пакетов:

Апт:

---
# tasks file for installing foo on apt based distros

- name: Install foo package via apt
  apt: >
    name=foo{% if foo_version is defined %}={{ foo_version }}{% endif %}
    state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
  tags: packages

Yum:

---
# tasks file for installing foo on yum based distros
- name: Install EPEL 6.8 repos (...because it's RedHat and foo is in EPEL for example purposes...)
  yum: >
    name={{ docker_yum_repo_url }}
    state=present
  tags: packages
  when: ansible_os_family == "RedHat" and ansible_distribution_major_version|int == 6

- name: Install foo package via yum
  yum: >
    name=foo{% if foo_version is defined %}-{{ foo_version }}{% endif %}
    state={% if foo_install_latest is defined and foo_version is not defined %}latest{% else %}present{% endif %}
  tags: packages

- name: Install RedHat/yum-based distro specific stuff...
  yum: >
    name=some-other-custom-dependency-on-redhat
    state=latest
  when: ansible_os_family == "RedHat"
  tags: packages

Homebrew:

---
- name: Tap homebrew foobar/foo
  homebrew_tap: >
    name=foobar/foo
    state=present

- homebrew: >
    name=foo
    state=latest

Обратите внимание, что это ужасно повторяется, а не D.R.Y., и хотя некоторые вещи мог бы быть разными на разных платформах, и их придется обрабатывать, как правило, я думаю, что это многословное и громоздкое по сравнению с поваром шеф-повара:

package 'foo' do
  version node['foo']['version']
end

case node["platform"]
when "debian", "ubuntu"
  # do debian/ubuntu things
when "redhat", "centos", "fedora"
  # do redhat/centos/fedora things
end

И да, есть аргумент, что некоторые имена пакетов различаются между дистрибутивами. И хотя в настоящее время существует отсутствие легкодоступных данных, Я бы рискнул догадаться, что большинство популярные имена пакетов являются общими для дистрибутивов и могут быть установлены через абстрактный модуль диспетчера пакетов. В любом случае необходимо будет обрабатывать особые случаи, и уже потребует дополнительной работы, делающей вещи менее D.R.Y. Если есть сомнения, проверьте pkgs.org,


56
2017-12-05 03:14



С помощью Ansible 2 вы можете использовать модуль пакета для абстрагирования всего этого docs.ansible.com/ansible/package_module.html - Guido García
@ GuidoGarcía: Очень приятно! Добавление примечания об этом для Ansible 2.0 - TrinitronX


Вы можете абстрагировать менеджеров пакетов через факты

- name: Install packages
  with_items: package_list
  action: "{{ ansible_pkg_mgr }} state=installed name={{ item }}"

Все, что вам нужно, это некоторая логика, которая устанавливает ansible_pkg_mgr в apt или yum и т.п.

анзибль также работают над тем, чтобы делать то, что вы хотите в будущем модуле,


13
2018-06-09 18:08



Несложные множества ansible_pkg_mgr сам для любого упаковщика, о котором он знает. Вам не нужно ничего делать. Я использую эту конкретную конструкцию всюду. - Michael Hampton♦
Синтаксис по-прежнему весьма полезен для тех, кто хочет оптимизировать запуск своих плейбуков. Общий пакетный модуль еще не обеспечивает оптимизацию для with_items поэтому он намного медленнее, когда он используется для установки сразу нескольких пакетов. - Daniel V.
@DanielV. Обратите внимание, что проблема github обеспечивает обходной путь для этого. - Michael Hampton♦


От Ansible 2.0 появился новый Package-modul.

http://docs.ansible.com/ansible/package_module.html

Затем вы можете использовать его, как и ваше предложение:

- name: install the latest version of Apache
  package: name=httpd state=latest

Вам все равно придется учитывать различия в именах.


6
2017-11-15 11:52





Ознакомьтесь с документацией Ansible по Условный импорт,

Одна задача убедиться, что apache работает, даже если имена служб различаются для каждой ОС.

---
- hosts: all
  remote_user: root
  vars_files:
    - "vars/common.yml"
    - [ "vars/{{ ansible_os_family }}.yml", "vars/os_defaults.yml" ]
  tasks:
  - name: make sure apache is running
    service: name={{ apache }} state=running

3
2018-03-17 16:19





Вы не хотите этого делать, потому что определенные имена пакетов различаются между дистрибутивами. Например, в дистрибутивах, связанных с RHEL, популярный пакет веб-сервера называется httpd, где, как и в дистрибутивах, связанных с Debian, он называется apache2, Аналогично с огромным списком других систем и поддерживающих библиотек.

Может существовать набор общих базовых параметров, но тогда также существует ряд более сложных параметров, которые отличаются между менеджерами пакетов. И вы не хотите находиться в неоднозначной ситуации, когда для некоторых команд вы используете один синтаксис, а для других команд используется другой синтаксис.


2
2018-04-10 12:00



Это более или менее то, что я ожидал (к сожалению :)), поэтому мне интересно, как salt удается объединить обоих менеджеров пакетов. В любом случае, я прибегну к двойной конфигурации. - WoJ
Или не управляйте дистрибуторским зоопарком ;-) мигрируйте в инфраструктуру с одним дистрибутивом и живете счастливее. - Mxx
Зоопарк, к счастью, только два больших животных, но это самое низкое число, на которое я могу пойти :) - WoJ
@Mxx это прекрасная логика для sysadmin, но как насчет поставщика программного обеспечения или консультанта, который поддерживает несколько платформ? - David H. Bennett
@David, тогда это необходимо обсудить с поставщиками дистрибутивов, чтобы они имели унифицированные имена пакетов и инструменты для установки. Реально не существует способа, которым Ansible может иметь унифицированное отображение ВСЕХ пакетов из всех поддерживаемых дистрибутивов всех версий. - Mxx