Packer 无法使用 sudo 执行 shell provisioner

13

我在packer中有一个与用户vagrant连接的shell provisioner

{
  "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“语句|foo”,而是像使用sudo su一样全局切换用户。


请尝试访问此链接:https://www.packer.io/docs/provisioners/shell.html#sudo-example - zx1986
4个回答

12
你应该重写execute_command。示例:
  "provisioners": [
    {
      "execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E sh -eux '{{.Path}}'",
      "scripts": [
        "scripts/foo.sh"
      ],
      "type": "shell"
    }
  ],

但是,当使用您的解决方案时,“virtualbox-ovf: bash: line 1: vagrant: command not found”是输出,以防我想通过“su vagrant”切换回vagrant用户执行其他命令。是否有比我的初始答案更好的切换用户的解决方案? - Georg Heiler
如果您是root用户,只需在要以其他用户身份运行的任何命令前加上sudo -u <user>即可。 - Rickard von Essen

3

有另一种更简单的方法可以同时使用两个提供程序。

Packer的shell提供程序可以使用sudo权限运行bash。首先,您需要使用file提供程序将脚本文件从本地计算机复制到远程计算机,然后使用shell提供程序运行它。

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
# ...

输出

<some_user_other_than_root_with_passwordless_sudo>
root

在配置程序完成其任务后,您可以使用shell配置程序删除文件。

packer.json已更新。

        {
            "type": "shell",
            "inline": ["sudo bash ~/shell.tmp.sh", "rm ~/shell.tmp.sh"]
        }

1

0

假设您正在使用的shell提供程序是bash脚本,您可以将我的技术添加到您的脚本中。

function if_not_root_rerun_as_root(){
    install_self
    if [[ "$(id -u)" -ne 0 ]]; then
        run_as_root_keeping_exports "$0" "$@"
        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 "$@"

这里有一个关于"$@"的相当不错的解释在StackOverflow上


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接