[Ansible] CentOS 6 Playbook 中“(libselinux-python) 未安装!”问题的解决方案

大家好,
我是系统解决方案部门的Naka,我偶尔会想吃沾面和意大利面。

错误“(libselinux-python) 未安装!经常会遇到

此错误可能需要手动修复。

但是,当您有大量机器并且想要使用 Ansible 管理它们时,却不得不手动处理每一台机器,很麻烦

于是我想,“如果我们用 Ansible 来解决这个问题岂不是更容易吗?”,然后就写了一个 Playbook。

这次,我们将介绍并解释“解决 CentOS 6 中‘(libselinux-python) 未安装!’问题的 Playbook”。

介绍

  • 我们不建议使用 CentOS 6。这只是
    在您被迫使用 CentOS 6 的情况下的临时解决方案
  • 是一个不受支持的版本。
    仅作为临时解决方案不建议使用。

基本原因

(libselinux-python) 未安装!

当使用会发生变化的模块时,例如文件操作模块,

  • 完全禁用。并未
  • 此外(*1) 未安装 libselinux-python 软件包(*2)

这是当……时发生的错误

*1. 如果禁用 SELinux,则不会出现此错误。
*2. Ansible 运行在 Python 上,因此 Python 需要能够与 SELinux 交互。
* 对于 Python 3,这需要使用“python3-libselinux”,但 CentOS 6 似乎并未普遍提供此库。

手动解答

# sudo yum install libselinux-python

如果在目标端安装“libselinux-python”,这个问题基本上就能得到解决。

* 对于 Python 3,请使用“python3-libselinux”

然而, CentOS 6 已停止维护 (EOL), 如果存储库保留默认设置, 则 yum 很可能无法工作

在这种情况下,您需要使用 wget 和 rpm 从可用的存储库进行本地安装。

因此,跨多个环境进行人工响应是相当困难的。

问:为什么要修改战术手册?

A. 不仅仅是在使用 Ansible 之前需要预先进行手动操作很麻烦;
还很容易产生这样的想法:“既然需要手动操作,那我干脆所有事情都手动做”,这就违背了初衷。

因此,“积极转向使用 Ansible 来可靠地完成任何工作”。我们的立场是

问:它与 CentOS 7 不兼容吗?

A. 我认为更明智的做法是将 Playbook 分开,并在包含/导入阶段进行判断/分支,以处理版本差异。

我当时在想是否要让它兼容,但它已经包含了一个在无法使用“yum”时的分支,这使得情况变得有点复杂。

仓库目录层次结构名称可能会根据操作系统版本而变化,这将进一步增加分支数量。

我们决定不在单个 Playbook 中包含版本分支,因为我们认为这会降低可读性和可维护性。

执行环境

■ Linux 环境
操作系统:AlmaLinux 8.5 版(WSL2 环境)
Shell:Bash
Docker:26.1.0,版本 9714adc

■ Ansible 环境(WSL2 中的 Docker 容器)
操作系统:AlmaLinux 8.9 版
Ansible:Ansible-core 2.12.10

■ Windows 环境
操作系统:Windows 11 专业版(版本:23H2)
语言设置:已更改为日语

■ CentOS 6 环境(Vagrant + VirtualBox)
操作系统:CentOS 6.9 (bento / centos-6.9)
Vagrant:2.4.1
VirtualBox:7.0.18 r162988 (Qt5.15.2)
IP:192.168.33.15

Ansible 2.12 环境构建流程

但兼容的Ansible 版本 (2.12)我们将使用

在上一篇文章中,我们解释了如何构建 Ansible 2.12,请参考这篇文章。

[Ansible 2.12] 在 WSL2 中使用 Docker 为 CentOS 6 构建 Ansible 执行环境

剧本

在 CentOS 6 环境中运行 Playbook,在一开始就包含/导入某些组件,从而防止出现错误确保主动用于旨在

当然,也可以在错误发生后使用此剧本来解决问题。

libselinux-python_wget.yml

此 Playbook 通过 `main.yml` 中的 `import_tasks` 加载。
(这是因为我倾向于按角色分离 Playbook,以提高可重用性、可读性和可维护性。)

--- ## 变量默认值 # wget_repo | default ("http://ftp.iij.ad.jp/pub/linux/centos-vault") - name: 检查 SELinux ansible.builtin.command: cmd: getenforce register: SELinux_result - ansible.builtin.debug: var: SELinux_result.stdout - name: 检查 libselinux-python ansible.builtin.shell: cmd: rpm -aq | grep libselinux-python register: rpm_result ignore_errors: yes - ansible.builtin.debug: var: rpm_result.stdout # 如果 SELinux 已禁用,Ansible 无需任何附加命令即可运行,因此不会执行此项。 # 此外,如果 libselinux-python 已安装,也不会执行此项。 - name: yum install libselinux-python ansible.builtin.yum: name: libselinux-python state: present register: yum_libselinux_result ignore_errors: yes when: not ( SELinux_result.stdout is search("disabled") ) and not ( rpm_result.stdout is search("libselinux-python*")) # 如果使用 yum 安装失败,则使用 wget 安装 - name: Setup libselinux-python when: yum_libselinux_result is failed and not ( rpm_result.stdout is search("libselinux-python*")) block: # 由于软件包名称会根据版本而变化,因此将软件包列表的 HTML 存储在一个变量中 -name: Get OS_version Packages ansible.builtin.uri: url: "{{ wget_repo | default('http://ftp.iij.ad.jp/pub/linux/centos-vault') }}/{{ ansible_distribution_version }}/os/x86_64/Packages/" method: GET return_content: yes register: packages_content # 从 HTML 获取 "libselinux-python" 的 rpm 名称 - name: Extract rpm_name ansible.builtin.set_fact: rpm_name: "{{ packages_content.content | regex_search('libselinux-python-(.*?)\\.x86_64\\.rpm') }}" - ansible.builtin.debug: var: rpm_name # 使用获取的 rpm 名称下载 - name: Download libselinux-python ansible.builtin.get_url: url: "{{ wget_repo | default('http://ftp.iij.ad.jp/pub/linux/centos-vault') }}/{{ ansible_distribution_version }}/os/x86_64/Packages/{{ rpm_name }}" dest: "/tmp/{{ rpm_name }}" # 在无法使用 yum 的情况下使用 rpm 安装 - name: 安装 libselinux-python ansible.builtin.command: rpm -ivh /tmp/"{{ rpm_name }}"

我已在评论中写明了我的大部分意图,但下面我将解释一下。

# wget_repo: | default ("http://ftp.iij.ad.jp/pub/linux/centos-vault")

如果无法使用 yum,请直接从存储库获取 libselinux-python:

使用变量指定要使用的存储库,但如果未指定变量,则在开头添加注释,明确说明所使用的存储库来自 IIJ。

- name:检查 SELinux
- name:检查 libeselinux-python

在 SELinux 被禁用的环境中,程序无需“libselinux-python”即可运行,因此无需该库。程序
首先检查 SELinux 的状态,然后将状态存储在一个变量中以供后续判断。

此外,考虑到 CentOS 6 可能不支持 yum,我们将通过 Shell 模块检查它是否已使用 rpm 安装。
此结果也会保存到一个变量中以供验证。

- name: yum install libselinux-python

SELinux 状态不是“已禁用”且未安装“libselinux-python”才会执行此命令

尝试使用 yum 模块进行安装,如果显示“已安装”或“已安装”,则说明安装成功。

如果“yum”运行失败,则进程会继续执行“ignore_errors: yes”,但任务失败的情况会记录在一个变量中以供检查,后续任务会尝试直接从存储库中检索数据。

- name:设置 libselinux-python
when:yum_libselinux_result 失败
block:

当通过“yum”安装失败时(满足条件),将执行此任务块。
它会直接从软件仓库检索软件包,并使用rpm进行安装

首先,使用 ansible_facts 中的“ansible_distribution_version”从存储库的目录层次结构中获取与操作系统次版本匹配的“libselinux-python”的官方软件包名称,并将其保存为变量。

然后使用该变量通过 get_uri 模块下载它,并通过 command 模块使用 rpm 在本地安装它。

例子

用于验证环境的库存文件

虽然 CentOS 6 (bento / centos-6.9) 默认使用密码验证,但仍然存在使用密码验证的环境(不建议这样做),因此我们在这种状态下进行了测试。

-- all: vars: ansible_user: vagrant hosts: targetnode: ansible_host: 192.168.33.15 ansible_ssh_pass: vagrant

main.yml

我没有在 main.yml 中编写任务,而是采用了使用 import_tasks 导入 Playbook 的方式。
(这是因为我更喜欢按角色分离 Playbook,以提高代码的重用性、可读性和可维护性。)

- name: libselinux-python hosts: targetnode< become: yes vars: wget_repo: "http://ftp.iij.ad.jp/pub/linux/centos-vault" tasks - name: Include libselinux-python(wget) ansible.builtin.import_tasks: libselinux-python_wget.yml

剧本执行

在本文中,我们将使用较旧版本的 Ansible 在容器中运行它。

[root@author 的容器环境工作]# ansible-playbook -i hosts main.yml

最后

虽然很耗时,但我尝试使用 Ansible 实现一些标准化任务的自动化。
这意味着我可以多次重复使用这些工具,而且就熟悉 Ansible 而言,这也是一次很好的学习经历。

由于 CentOS 6 环境通常缺乏使用“yum”的能力,使得 Ansible 的实现面临很高的门槛,
我希望本文能够为读者探索 Ansible 提供一个起点,并提供一些有用的知识和信息。

感谢您阅读至此!

参考资料

ansible.builtin.yum 模块 – 使用 yum 包管理器管理软件包
https://docs.ansible.com/ansible/9/collections/ansible/builtin/yum_module.html

8.6. SELinux
https://docs.redhat.com/ja/documentation/red_hat_enterprise_linux/8/html/considerations_in_adopting_rhel_8/selinux_security

如果您觉得这篇文章对您有帮助,请点个“赞”!
4
加载中...
4票,平均分:1.00/14
804
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

里面

以中级员工的身份加入 Beyond 公司,
目前在系统解决方案部门工作。
我持有 LPIC-3 304 和 AWS SAA 认证。