如何授予 www-data 用户访问 python salt 模块的权限?

how to grant www-data user access to python salt module?

我正在维护一个小型遗留 php5 应用程序(基于 CodeIgniter),它充当盐网 UI,允许我 运行 盐命令和安排重复作业。 Web 应用程序 运行s python 脚本调用盐 api 来执行命令。

我面临的问题是 python 在我尝试遍历结果时抛出 UnboundLocalError。有趣的是,此问题仅在我 运行 使用 www-data 用户的 python 脚本时发生。如果我使用我的管理员帐户,脚本可以正常工作。

这失败了:

sudo su - www-data -s /bin/bash -c '/usr/bin/python /home/system/update-manager/check_reboot_status.py'

Traceback (most recent call last):
  File "/home/system/update-manager/check_reboot_status.py", line 43, in <module>
    main()
  File "/home/system/update-manager/check_reboot_status.py", line 34, in main
    for r in returns:
  File "/usr/lib/python2.7/dist-packages/salt/client/__init__.py", line 563, in cmd_batch
    salt.utils.versions.warn_until(
UnboundLocalError: local variable 'salt' referenced before assignment

这很好用:

sudo /usr/bin/python /home/system/update-manager/check_reboot_status.py
2019-02-21 12:12:04,456 INFO Started the check reboot status script...
2019-02-21 12:12:22,144 INFO Updated the 'Reboot Status' of 92 minions.
2019-02-21 12:12:22,144 INFO End of the check reboot status script.

最初,我认为这是由于权限不足,但是我的 visudo 文件将 www-data 权限授予 运行 该命令:

www-data ALL = NOPASSWD: /usr/bin/python /home/system/update-manager/check_reboot_status.py

我很困惑错误是围绕一个变量 'salt',因为我确定安装了 python 模块;毕竟我的管理员帐户可以毫无错误地执行脚本。不知道是不是和脚本执行的shell环境有关。我在 php doc.

中找不到相关信息

我遗漏了什么要尝试或调查的?我复制了下面的 python 和 php 代码以供参考。

php 脚本:

$script = '/home/system/update-manager/check_reboot_status.py';

shell_exec('sudo /usr/bin/python ' . $script . '> /home/system/update-manager/logs/check_reboot_status.log 2>&1 &');

python代码

import salt.client
local = salt.client.LocalClient()

linux = 'G@os:Ubuntu'    

# Linux minions
cmd = '[ -f /var/run/reboot-required ] && echo 1 || echo 0'
returns = local.cmd_batch(linux, 'cmd.run', [cmd], bat='1', expr_form='compound')

for r in returns:
    count += 1
    for minion, reboot_required in r.iteritems():
        umb.change_reboot_status(minion, reboot_required)

tl;dr:对错误信息的误解。使用命令 with/without sudo 导致两个不同的 python salt 模块。根据 API 文档,只有在 salt-master 上启动 salt 的用户可以 运行 命令,在本例中为:root。原始问题与描述的情况不符,因为 python 从来没有访问过该模块,否则会抛出 "ImportError: No module named salt" 之类的错误。

存在隐藏实际问题的权限问题。

首先我发现 运行ning python 这两个命令使用了两个不同的文件来加载:

$ sudo python
>>> import salt.client
>>> salt.client
<module 'salt.client' from' /home/support/.local/lib/python2.7/site-packages/salt/client/__init__.pyc'>

 sudo runuser -l www-data -s /bin/bash -c '/usr/bin/python
>>> import salt.client
>>> salt.client
<module 'salt.client' from '/usr/lib/python2.7/dist-packages/salt/client/__init__.pyc'>

堆栈跟踪显示错误来自以下块:"salt.utils.versions.warn_until()" 抛出问题中显示的 salt 错误,即使该包是在文件开头导入的。

#/usr/lib/python2.7/dist-packages/salt/client/__init__.py
if 'expr_form' in kwargs:
            #import salt.utils.versions
--->        salt.utils.versions.warn_until(
                'Fluorine',
                'The target type should be passed using the \'tgt_type\' '
                'argument instead of \'expr_form\'. Support for using '
                '\'expr_form\' will be removed in Salt Fluorine.'
            )
            tgt_type = kwargs.pop('expr_form')

        import salt.cli.batc

通过添加导入行(在评论中显示)错误得到解决,但是,另一个替代了它:

salt.exceptions.SaltClientError: Authentication error occurred.

documentation 所述 "Importing and using LocalClient must be done on the same machine as the Salt Master and it must be done using the same user that the Salt Master is running as. [...])."。 这是我意识到命令只能是 运行 与 root 用户的地方。