AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 587727
Accepted
WoJ
WoJ
Asked: 2014-04-10 03:45:02 +0800 CST2014-04-10 03:45:02 +0800 CST 2014-04-10 03:45:02 +0800 CST

ansible中如何统一包安装任务?

  • 772

我从ansible开始,并将使用它在几个 Linux 发行版上安装软件包。

我在文档中看到yumandapt命令是分开的 - 统一它们并使用如下内容的最简单方法是什么:

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

我知道这两个包管理器是不同的,但它们仍然有一组共同的基本用法。其他编排器(例如 salt)只有一个安装命令。

package-management
  • 6 6 个回答
  • 54807 Views

6 个回答

  • Voted
  1. Best Answer
    TrinitronX
    2014-12-05T19:14:03+08:002014-12-05T19:14:03+08:00

    更新:从 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
    



    编辑: 由于 Michael DeHaan(Ansible 的创建者)选择不像Chef那样抽象出包管理器模块,

    如果您仍在使用旧版本的 Ansible (Ansible < 2.0),不幸的是,您需要在所有剧本和角色中处理此操作。 恕我直言,这将许多不必要的重复工作推给了剧本和角色作者……但这就是目前的情况。请注意,我并不是说我们应该尝试抽象包管理器,同时仍然尝试支持它们的所有特定选项和命令,但只是有一种简单的方法来安装与包管理器无关的包。我也不是说我们都应该使用智能包管理器潮流,但是配置管理工具中的某种包安装抽象层对于简化跨平台的剧本/食谱非常有用。Smart 项目看起来很有趣,但是在没有太多采用的情况下统一跨发行版和平台的包管理是相当雄心勃勃的……看看它是否成功将会很有趣。真正的问题是不同发行版的包名称有时会有所不同,因此我们仍然需要使用案例语句或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
    

    百胜:

    ---
    # 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,尽管有些事情在不同的平台上可能会有所不同并且必须处理,但通常我认为与 Chef 相比,这是冗长且笨拙的:

    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。

    • 81
  2. xddsg
    2015-06-10T10:08:31+08:002015-06-10T10:08:31+08:00

    您可以通过事实抽象出包管理器

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

    您所需要的只是一些设置ansible_pkg_mgr为apt或yum等的逻辑。

    Ansible也在努力在未来的模块中做你想做的事情。

    • 14
  3. Tvartom
    2015-11-16T03:52:02+08:002015-11-16T03:52:02+08:00

    从 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
  4. David Vasandani
    2015-03-18T08:19:58+08:002015-03-18T08:19:58+08:00

    查看 Ansible 关于Conditional Imports的文档。

    即使每个操作系统的服务名称不同,一项任务也能确保 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
  5. Mxx
    2014-04-11T04:00:16+08:002014-04-11T04:00:16+08:00

    您不想这样做,因为发行版之间的某些包名称不同。例如,在与 RHEL 相关的发行版中,流行的 Web 服务器包被命名为httpd,而在 Debian 相关的发行版中,它被命名为apache2。同样,还有大量其他系统和支持库。

    可能有一组通用的基本参数,但还有一些更高级的参数,它们在包管理器之间是不同的。并且您不希望处于模棱两可的情况下,对于某些命令您使用一种语法,而对于其他命令您使用另一种语法。

    • 2
  6. Zach Smith
    2020-10-28T21:48:25+08:002020-10-28T21:48:25+08:00

    最重要的答案似乎都链接到损坏的页面。这看起来像正确的 URL:https ://docs.ansible.com/ansible/latest/collections/ansible/builtin/package_module.html

    • 0

相关问题

  • 如何使程序从源代码保持最新?

  • Firefox 打包以包含用于网络安装的插件

  • 使用 YUM 将属于已安装 RPM 的文件替换为不同的 RPM

  • 如何及时了解有关 UNIX 软件补丁和升级的最新信息?

  • 从零开始 Linux 上的包管理

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve