Packer 无法以 sudo 身份执行 shell provisioner
Packer can't execute shell provisioner as sudo
我有一个 shell provisioner
in packer 连接到用户 vagrant
的盒子
{
"environment_vars": [
"HOME_DIR=/home/vagrant"
],
"expect_disconnect": true,
"scripts": [
"scripts/foo.sh"
],
"type": "shell"
}
其中脚本内容为:
whoami
sudo su
whoami
奇怪的是输出仍然是:
==> virtualbox-ovf: Provisioning with shell script: scripts/configureProxies.sh
virtualbox-ovf: vagrant
virtualbox-ovf: vagrant
为什么我不能切换到root用户?
如何以 root 身份执行语句?
请注意,我不想引用 sudo "statement |foo"
之类的所有语句,而是像 sudo su
演示的那样全局切换用户
sudo su <<HERE
ls /root
whoami
HERE
也许有更好的答案?
您应该覆盖 execute_command。示例:
"provisioners": [
{
"execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'",
"scripts": [
"scripts/foo.sh"
],
"type": "shell"
}
],
假设您使用的 shell provisioner 是一个 bash 脚本,您可以将我的技术添加到您的脚本中。
function if_not_root_rerun_as_root(){
install_self
if [[ "$(id -u)" -ne 0 ]]; then
run_as_root_keeping_exports "[=10=]" "$@"
exit $?
fi
}
function run_as_root_keeping_exports(){
eval sudo $(for x in $_EXPORTS; do printf '%s=%q ' "$x" "${!x}"; done;) "$@"
}
export EXPORTS="PACKER_BUILDER_TYPE PACKER_BUILD_NAME"
if_not_root_rerun_as_root "$@"
"$@"
here on Whosebug 有很好的解释。
还有另一种解决方案,可以更简单地一起使用 2 个配置器。
Packer 的 shell 供应商可以 运行 bash
和 sudo
权限。首先,您需要使用 file
provisioner 将脚本文件从本地机器复制到远程,然后使用 shell
provisioner 运行 复制它。
packer.json
{
"vars": [...],
"builders": [
{
# ...
"ssh_username": "<some_user_other_than_root_with_passwordless_sudo>",
}
],
"provisioners": [
{
"type": "file",
"source": "scripts/foo.sh",
"destination": "~/shell.tmp.sh"
},
{
"type": "shell",
"inline": ["sudo bash ~/shell.tmp.sh"]
}
]
}
foo.sh
# ...
whoami
sudo su root
whoami
# ...
output
<some_user_other_than_root_with_passwordless_sudo>
root
provisioner 完成任务后,您可以使用 shell provisioner 删除文件。
packer.json
已更新
{
"type": "shell",
"inline": ["sudo bash ~/shell.tmp.sh", "rm ~/shell.tmp.sh"]
}
我有一个 shell provisioner
in packer 连接到用户 vagrant
{
"environment_vars": [
"HOME_DIR=/home/vagrant"
],
"expect_disconnect": true,
"scripts": [
"scripts/foo.sh"
],
"type": "shell"
}
其中脚本内容为:
whoami
sudo su
whoami
奇怪的是输出仍然是:
==> virtualbox-ovf: Provisioning with shell script: scripts/configureProxies.sh
virtualbox-ovf: vagrant
virtualbox-ovf: vagrant
为什么我不能切换到root用户?
如何以 root 身份执行语句?
请注意,我不想引用 sudo "statement |foo"
之类的所有语句,而是像 sudo su
sudo su <<HERE
ls /root
whoami
HERE
也许有更好的答案?
您应该覆盖 execute_command。示例:
"provisioners": [
{
"execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'",
"scripts": [
"scripts/foo.sh"
],
"type": "shell"
}
],
假设您使用的 shell provisioner 是一个 bash 脚本,您可以将我的技术添加到您的脚本中。
function if_not_root_rerun_as_root(){
install_self
if [[ "$(id -u)" -ne 0 ]]; then
run_as_root_keeping_exports "[=10=]" "$@"
exit $?
fi
}
function run_as_root_keeping_exports(){
eval sudo $(for x in $_EXPORTS; do printf '%s=%q ' "$x" "${!x}"; done;) "$@"
}
export EXPORTS="PACKER_BUILDER_TYPE PACKER_BUILD_NAME"
if_not_root_rerun_as_root "$@"
"$@"
here on Whosebug 有很好的解释。
还有另一种解决方案,可以更简单地一起使用 2 个配置器。
Packer 的 shell 供应商可以 运行 bash
和 sudo
权限。首先,您需要使用 file
provisioner 将脚本文件从本地机器复制到远程,然后使用 shell
provisioner 运行 复制它。
packer.json
{
"vars": [...],
"builders": [
{
# ...
"ssh_username": "<some_user_other_than_root_with_passwordless_sudo>",
}
],
"provisioners": [
{
"type": "file",
"source": "scripts/foo.sh",
"destination": "~/shell.tmp.sh"
},
{
"type": "shell",
"inline": ["sudo bash ~/shell.tmp.sh"]
}
]
}
foo.sh
# ...
whoami
sudo su root
whoami
# ...
output
<some_user_other_than_root_with_passwordless_sudo>
root
provisioner 完成任务后,您可以使用 shell provisioner 删除文件。
packer.json
已更新
{
"type": "shell",
"inline": ["sudo bash ~/shell.tmp.sh", "rm ~/shell.tmp.sh"]
}