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

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

当尝试使用 Ansible 更新或更改手动管理的 CentOS 6 环境时,很容易遇到 (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,所需的 libselinux 库是“python3-libselinux”,但该库似乎在 CentOS 6 中并不通用。

手动解答

# sudo yum install libselinux-python

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

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

然而,CentOS 6 已停止维护,如果存储库仍保持默认设置,则 yum 很可能无法使用

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

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

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

A. 这不仅是因为你想使用 Ansible,而且事先手动操作也很麻烦,还因为很容易想,
“如果必须手动操作,那我干脆全部手动完成”,所以这样做是为了防止事态适得其反。

因此,我们的立场是: “对于可以用 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 环境构建流程

我们将使用兼容版本(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”即可运行,因此无需进行此操作。
首先,检查状态,然后将其输入变量以供判断。

此外,考虑到 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
709
X Facebook 哈特纳书签 口袋

写这篇文章的人

关于作者

里面

我在职业生涯中期加入了Beyond,
在系统解决方案部门工作。
我拥有LPIC-3 304和AWS SAA认证。