你说得对!为了让 ota_manager.py
(以 cat
用户身份运行)能够启动和停止 ota_http_server.service
(以及其他 ROS 服务),我们需要在 sudoers
配置中明确授予 cat
用户执行这些特定 systemctl
命令的权限,并且是无需密码 (NOPASSWD) 的。
使用 visudo
编辑 sudoers 配置(推荐且安全的方式):
-
打开
visudo
编辑器:bashsudo visudo
这会使用系统默认的文本编辑器(通常是 nano 或 vim)打开一个临时文件进行编辑。
visudo
会在保存时检查语法,防止你搞坏sudo
。 -
添加权限规则: 在文件的末尾(或者用户权限规则部分),添加以下行。注意: 每一行对应一个允许的操作。你需要为每个服务添加
start
和stop
的权限。sudoers# Allow cat user to start/stop specific services without a password for OTA management cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start ota_http_server.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop ota_http_server.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start camera_processor_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop camera_processor_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start ot_agent_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop ot_agent_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start ogger_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop ogger_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start le_reader_launch.service cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop le_reader_launch.service
cat
: 指定哪个用户。ALL=
: 表示允许从任何主机执行。(ALL)
: 表示允许以任何用户身份运行命令(通常是 root)。NOPASSWD:
: 表示执行后面的命令时不需要输入密码。/usr/bin/systemctl start <service_name>
: 明确指定允许执行的命令及其参数。使用systemctl
的绝对路径 (/usr/bin/systemctl
或which systemctl
的输出) 很重要!
-
保存并退出:
- Nano 编辑器: 按
Ctrl+X
,然后按Y
确认保存,再按Enter
确认文件名。 - Vim 编辑器: 按
Esc
,然后输入:wq
,再按Enter
。
visudo
会在你保存时检查语法。如果有错误,它会提示你,不允许你保存错误的配置。 - Nano 编辑器: 按
替代方案:使用 /etc/sudoers.d/
目录(更推荐,更易管理)
创建一个单独的文件来存放你的 OTA 相关权限规则,这样更容易管理,并且不容易影响主 /etc/sudoers
文件。
bash
# (需要 root 权限)
# 1. 创建并编辑新文件 (文件名不重要,但最好有意义)
sudo visudo -f /etc/sudoers.d/ota_manager_permissions
# 2. 在打开的编辑器中,粘贴以下内容:
# Allow cat user to start/stop specific services without password for OTA management
cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start http_server.service
cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop _server.service
cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start amera_processor_launch.service
cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl stop camera_processor_launch.service
cat ALL=(ALL) NOPASSWD: /usr/bin/systemctl start bot_agent_launch.service
# 3. 保存并退出编辑器。
# 4. (重要)设置正确的文件权限,否则 sudo 会忽略它!
sudo chmod 440 /etc/sudoers.d/ota_manager_permissions
echo "Sudoers rule created in /etc/sudoers.d/ota_manager_permissions"
完成以上配置后:
-
重启
ota_manager.service
:bashsudo systemctl restart ota_manager.service
-
检查日志: 查看
journalctl -u ota_manager.service
或~/ota_workspace/logs/ota_manager.log
。这次run_systemctl
函数调用sudo systemctl ...
时应该不会再有 PAM 认证失败的错误了,服务应该能被成功启动和停止。 -
测试 HTTP 服务自启动:
bash# (确保 manager 服务正在运行) sudo systemctl stop ota_http_server.service # 手动停止 HTTP 服务 sleep 2 sudo systemctl restart ota_manager.service # 重启 Manager sleep 5 # 等待 manager 启动并检查 sudo systemctl status ota_http_server.service --no-pager # 确认 HTTP 服务被 Manager 重新启动了 sudo netstat -tulnp | grep ':5000' # 确认端口监听
这样配置后,ota_manager.py
(以 cat
用户运行)就获得了控制这些特定服务的必要权限,并且整个流程都运行在更低的用户权限下,更加安全。