कैसे स्थापना योग्य में पैकेज स्थापना कार्यों को एकजुट करने के लिए?


68

मैं कई लिनक्स डिस्ट्रोस पर पैकेज स्थापित करने के लिए ansible के साथ शुरुआत कर रहा हूं और दूसरों के बीच इसका उपयोग करूंगा।

मैं डॉक्स कि में देखते हैं 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"

मैं समझता हूं कि दो पैकेज प्रबंधक अलग-अलग हैं, लेकिन उनके पास अभी भी सामान्य बुनियादी उपयोगों का एक सेट है। अन्य ऑर्केस्टर्स ( उदाहरण के लिए नमक ) में एक एकल इंस्टॉलेशन कमांड है।


आपके पास तीन व्यंजन हो सकते हैं: एक जो सामान्य सूची से अधिक है और फिर प्रत्येक ओएस-विशिष्ट सूची के लिए। मैं अभी यह पता लगाने की कोशिश कर रहा हूं कि सामान्य कॉन्फ़िगरेशन आइटम सेट होने के बाद ओएस-विशिष्ट सेवा नाम के साथ एक हैंडलर को कैसे सूचित किया जाए। सौभाग्य!
डेनिमैन

जवाबों:


66

अद्यतन: 2.0 के रूप में, अब एक सामान्य और अमूर्त packageमॉड्यूल है

उपयोग के उदाहरण:

अब जब पैकेज का नाम विभिन्न OS परिवारों में समान है, तो यह उतना ही सरल है:

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

जब पैकेज का नाम OS परिवारों में भिन्न होता है, तो आप इसे वितरण या OS परिवार विशिष्ट 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

फिर, प्रत्येक OS के लिए जिसे आपको अलग-अलग संभालना होगा ... एक var फ़ाइल बनाएं:

---
# 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



EDIT: चूंकि माइकल डेहान (Ansible के निर्माता) ने पैकेज मैनेजर मॉड्यूल को अमूर्त करने के लिए नहीं चुना है, जैसे शेफ करता है,

यदि आप अभी भी Ansible (Ansible <2.0) के पुराने संस्करण का उपयोग कर रहे हैं , तो दुर्भाग्य से आपको अपनी सभी प्लेलिस्ट और भूमिकाओंमें ऐसा करने की आवश्यकता होगी। IMHO यह प्लेबुक और रोल लेखकों पर बहुत सारे अनावश्यक दोहराए जाने वाले काम को आगे बढ़ाता है ... लेकिन यह वर्तमान में ऐसा ही है। ध्यान दें कि मैं यह नहीं कह रहा हूं कि हमें अपने सभी विशिष्ट विकल्पों और आदेशों का समर्थन करने की कोशिश करते हुए पैकेज प्रबंधकों को दूर रखने की कोशिश करनी चाहिए, लेकिन पैकेज मैनेजर एग्नॉस्टिक पैकेज को स्थापित करने का एक आसान तरीका है। मैं यह भी नहीं कह रहा हूं कि हम सभी को स्मार्ट पैकेज मैनेजर पर कूदना चाहिएबैंडवागन, लेकिन यह कि आपके कॉन्फ़िगरेशन प्रबंधन टूल में पैकेज इंस्टॉलेशन एब्स्ट्रक्शन लेयर के कुछ प्रकार क्रॉस-प्लेटफॉर्म प्लेबुक / कुकबुक को सरल बनाने के लिए बहुत उपयोगी हैं। स्मार्ट परियोजना दिलचस्प लग रही है, लेकिन यह अभी भी बहुत ही गोद लेने के बिना विकृत और प्लेटफार्मों पर पैकेज प्रबंधन को एकजुट करने के लिए काफी महत्वाकांक्षी है ... यह देखना दिलचस्प होगा कि क्या यह सफल है। असली मुद्दा सिर्फ इतना है कि पैकेज के नाम कभी-कभी डिस्ट्रोस में भिन्न होते हैं, इसलिए हमें अभी भी 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: 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

यम:

---
# 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

होमब्रू:

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

- homebrew: >
    name=foo
    state=latest

ध्यान दें कि यह भयावह दोहराव है और DRY नहीं है , और हालांकि कुछ चीजें अलग-अलग प्लेटफार्मों पर अलग-अलग हो सकती हैं और उन्हें संभालना होगा, आम तौर पर मुझे लगता है कि शेफ की तुलना में यह क्रिया और अनपेक्षित है:

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

और हाँ, यह तर्क है कि कुछ पैकेज के नाम डिस्ट्रोस में भिन्न हैं। और यद्यपि वर्तमान में आसानी से सुलभ डेटा की कमी है , मैं यह अनुमान लगाने के लिए उद्यम करूंगा कि सबसे लोकप्रिय पैकेज के नाम डिस्ट्रोस में आम हैं और एक अमूर्त पैकेज प्रबंधक मॉड्यूल के माध्यम से स्थापित किया जा सकता है। विशेष मामलों को वैसे भी संभालने की आवश्यकता होगी, और पहले से ही अतिरिक्त काम करने की आवश्यकता होगी, जिससे चीजें कम हो जाती हैं DRY यदि संदेह है, तो pkgs.org की जांच करें ।


Ansible 2 के साथ आप पैकेज मॉड्यूल का उपयोग इस सभी डॉक्स के
Guido

@ GuidoGarcía: बहुत अच्छा! Ansible 2.0 के लिए इस बारे में एक नोट जोड़ना
TrinitronX

शायद यह भी ध्यान देने योग्य है कि आप अल्पविराम से अलग की गई सूची या केवल संकुल की सूची निर्दिष्ट कर सकते हैं।
वेस टर्नर

13

आप तथ्यों के माध्यम से पैकेज प्रबंधकों को सार कर सकते हैं

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

बस आपको कुछ तर्क चाहिए जो सेट ansible_pkg_mgrकरते हैं aptया yumआदि।

Ansible भी क्या आप भविष्य मॉड्यूल में चाहते कर रही पर काम कर रहे हैं


1
ansible_pkg_mgrकिसी भी पैकर के बारे में यह खुद ही तय करता है। आपके लिए कुछ भी करना आवश्यक नहीं है। मैं हर जगह इस विशेष निर्माण का उपयोग करता हूं।
माइकल हैम्पटन

सिंटैक्स अभी भी उन लोगों के लिए काफी उपयोगी है जो अपनी प्लेबुक के रन का अनुकूलन करना चाहते हैं। सामान्य पैकेज मॉड्यूल अभी तक with_items के लिए अनुकूलन प्रदान नहीं करता है, इसलिए जब यह एक साथ कई पैकेज स्थापित करने के लिए उपयोग किया जाता है तो यह बहुत धीमा होता है।
डैनिला वर्शिन

@DanielV। ध्यान दें कि github समस्या इसके लिए समाधान प्रदान करती है।
माइकल हैम्पटन

6

Ansible 2.0 से नया Package-मॉडल है।

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

फिर आप इसे अपने प्रस्ताव की तरह उपयोग कर सकते हैं:

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

आपको अभी भी नाम के अंतर पर विचार करना है।


3

सशर्त आयात पर Ansible के दस्तावेज देखें ।

एक कार्य यह सुनिश्चित करने के लिए कि अपाचे चल रहे हैं भले ही सेवा नाम प्रत्येक ओएस पर अलग हो।

---
- 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

2

आप ऐसा नहीं करना चाहते क्योंकि कुछ संकुल नाम डिस्ट्रोस के बीच भिन्न होते हैं। उदाहरण के लिए आरएचईएल-संबंधित डिस्ट्रोस पर लोकप्रिय वेब सर्वर पैकेज का नाम दिया गया है httpd, जहां डेबियन-संबंधित डिस्ट्रोस का नाम दिया गया है apache2। इसी तरह अन्य प्रणाली और सहायक पुस्तकालयों की एक विशाल सूची के साथ।

आम बुनियादी मापदंडों का एक सेट हो सकता है, लेकिन फिर कई उन्नत पैरामीटर भी हैं जो पैकेज प्रबंधकों के बीच भिन्न हैं। और आप एक अस्पष्ट स्थिति में नहीं रहना चाहते हैं जहां कुछ आदेशों के लिए आप एक वाक्यविन्यास का उपयोग करते हैं और अन्य आदेशों के लिए आप एक अन्य वाक्यविन्यास का उपयोग करते हैं।


यह कम या ज्यादा है जो मैं उम्मीद कर रहा था (दुर्भाग्य से :)) तो मुझे आश्चर्य है कि saltदोनों पैकेज प्रबंधकों को कैसे एकजुट किया जाए। फिर भी, मैं एक डबल कॉन्फ़िगरेशन का सहारा लूंगा।
WoJ

या एक डिस्ट्रो चिड़ियाघर का प्रबंधन न करें ;-) एक-डिस्ट्रो इन्फ्रास्ट्रक्चर में प्रवास करें और एक खुशहाल जीवन जीएं।
एमएक्स

चिड़ियाघर सौभाग्य से केवल दो जानवर हैं लेकिन यह सबसे कम संख्या है जो मैं जा सकता हूं :)
WoJ

1
@ एमएक्स यह एक sysadmin के लिए ठीक तर्क है लेकिन एक सॉफ्टवेयर विक्रेता या सलाहकार के बारे में जो कई प्लेटफार्मों का समर्थन करता है?
डेविड एच। बेनेट

@ डेविड, इसके बाद डिस्ट्रो वेंडर्स के साथ जुड़ने की जरूरत है, क्योंकि उनके पास यूनिफाइड पैकेज के नाम हैं और टूल्स इंस्टॉल करने हैं। वास्तविक रूप से कोई तरीका नहीं है कि सभी संस्करणों के सभी समर्थित डिस्ट्रो से सभी पैकेजों की एक एकीकृत मैपिंग हो सकती है।
एमएक्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.