无法在 WSL Ubuntu 20.04.3 LTS(焦点)中使用 Localhost 上的 Ansible 模块服务启动 Apache2

Failed to start Apache2 using Ansible Module Service on Localhost in WSL Ubuntu 20.04.3 LTS (focal)

我尝试使用 'sudo service' 命令启动 Apache2 服务并且它有效,但是当我尝试使用 ansible 服务模块启动 apache2 时,我收到错误消息“服务处于未知状态”。

我确实升级了我的ansible到最新版本。我在 WSL Ubuntu 20.04.3LTS 工作。而且我确实已经正确设置了 SSH,这样我就可以 运行 使用诸如 apt、命令和 shell 等模块的其他 ansible ad-hoc 命令

任何问题可能出在哪里的线索?

进一步挖掘后,我发现 ansible 在 service_mgr.py 中的方法 'is_systemd_managed_offline(module) 中似乎有一个错误,这使得 ansible 认为服务管理器是系统的,而它实际上是服务(或 sysv init):

if module.get_bin_path('systemctl'):
            # check if /sbin/init is a symlink to systemd
            # on SUSE, /sbin/init may be missing if systemd-sysvinit package is not installed.
            if os.path.islink('/sbin/init') and os.path.basename(os.readlink('/sbin/init')) == 'systemd':
                return True
        return False

这是因为在我的WSLUbuntu20.04 LTS上,确实有一个link从/sbin/init到systemd,如图:

/sbin/init -> /lib/systemd/systemd*

然而,服务管理器实际上应该设置为 sysv init,如果一切正常,它将设置在 service_mgr.py 代码的 elif 部分的末尾:

        elif collected_facts.get('ansible_system') == 'Linux':
            # FIXME: mv is_systemd_managed
            if self.is_systemd_managed(module=module):
                service_mgr_name = 'systemd'
            elif module.get_bin_path('initctl') and os.path.exists("/etc/init/"):
                service_mgr_name = 'upstart'
            elif os.path.exists('/sbin/openrc'):
                service_mgr_name = 'openrc'
            elif self.is_systemd_managed_offline(module=module):
                service_mgr_name = 'systemd'
            elif os.path.exists('/etc/init.d/'):
                service_mgr_name = 'sysvinit'

        if not service_mgr_name:
            # if we cannot detect, fallback to generic 'service'
            service_mgr_name = 'service'

但是,由于上面显示的link,ansible会停在is_system_managed_offline的elif行,不会继续到elif系列的末尾。

如下所示,服务管理器显示为 init (sysv init):

$ ps -p 1 -o comm=
init

知道如何解决这个问题吗?

//////////已解决////////////////// 通过检查 ansible 文档网站上服务模块的文档,并使用参数 'use' 强制 ansible 使用 'service' 而不是 'systemd' 作为服务管理器(尽管来自 ansible setup 模块,ansible 仍然错误地认为 systemd 是我的 WSL Ubuntu 20.04.3 LTS 的服务管理器,因为代码错误如上所示。

希望在未来版本的Ansible中,上面的代码错误(用于检查Linux机器上可用的服务管理器的elif)可以得到解决,特别是通过WSL Ubuntu和其他考虑到 WSL 变体。

一个快速的解决方法是重新排列 elif 顺序,将 'is_systemd_managed_offline' 变体放在 elif 列表的末尾,并将 os.path.exists('/etc/init.d') 移到更高的位置在列表中,如图:

    elif collected_facts.get('ansible_system') == 'Linux':
            # FIXME: mv is_systemd_managed
            if self.is_systemd_managed(module=module):
                service_mgr_name = 'systemd'
            elif module.get_bin_path('initctl') and os.path.exists("/etc/init/"):
                service_mgr_name = 'upstart'
            elif os.path.exists('/sbin/openrc'):
                service_mgr_name = 'openrc'
            *elif os.path.exists('/etc/init.d/'):
                service_mgr_name = 'sysvinit'
            elif self.is_systemd_managed_offline(module=module):
                service_mgr_name = 'systemd'*

我想你可以强制你的服务模块使用“service”而不是 systemctl:

ansible  localhost -m service -a "use=service name=apache2 state=stopped"

Service use reference