由于我们的基础设施使用 Amazon EC2,因此我正在为一些服务器开发自动引导程序。
我所做的是:运行一个 Fabric 脚本,该脚本连接到 EC2 并初始化一个新实例,将 cloud-init 脚本放入用户数据中。此脚本签出一个包含 Fabric 任务的 Mercurial 项目,然后在签出后,脚本将找出它在哪种类型的服务器中运行并执行特定的本地 Fabric 任务。
我的问题是某些任务需要运行 sudo 命令,由于脚本是从 cloud-init 初始化的,因此 sudo 警告需要通过 tty 运行,我尝试修改它以运行su --session-command="my commands to restart services" root
但它根本不起作用(而且似乎不应该起作用)。
那么,如何在这个启动脚本中运行 sudo 命令?
一些代码:
cloud_init_script:
#!/bin/sh
su --session-command="\
source /etc/profile; \
cd /home/my_user; \
hg clone ssh://fabric_tasks_repo fabric; \
/usr/local/bin/fab -f /home/my_user/fabric/fabfile.py \`ec2-describe-tags --filter \"resource-type=instance\" --filter \"resource-id=$(ec2-metadata -i | cut -d ' ' -f2)\" --filter \"key=type\" | cut -f5\` > /home/my_user/fabric.log 2>&1" my_user &
该行中的技巧/usr/local/bin/fab
是它将运行一些 ec2 脚本来检查服务器处于哪个标签键“类型”。
答案1
sudo: Sorry, you must have a tty to run sudo
运行visudo
并添加以下行以为requiretty
您的用户禁用:
Defaults:username !requiretty
答案2
最好的选择(也可能是最可靠的)是授予用户正确的 sudo 访问权限以访问所需的命令,并使用 NOPASSWD 标志
例如,如果运行脚本的用户是 bob,则要通过 sudo 重新加载 nginx 而无需密码,/etc/sudoers 的语法将是:
bob ALL= NOPASSWD: /etc/init.d/nginx reload
上面的脚本实际上应该改为:
sudo -u my_user hg clone ssh://fabric_tasks_repo /home/my_user/fabric
sudo -u my_user /usr/local/bin/fab -f /home/my_user/fabric/fabfile.py `ec2-describe-tags --filter "resource-type=instance" --filter "resource-id=$(ec2-metadata -i | cut -d ' ' -f2)" --filter "key=type" | cut -f5` > /home/my_user/fabric.log 2>&1 &
您可能需要也可能不需要转义您的引号,但为了清晰起见,我删除了它们
因此,您的 sudoers 文件具有您以之运行脚本的用户,但它可以以用户 my_user 的身份运行这些命令