【问题标题】:Packer can't execute shell provisioner as sudoPacker 无法作为 sudo 执行 shell 配置程序
【发布时间】:2018-07-10 06:26:20
【问题描述】:

我有一个 shell provisioner 在打包器连接到一个用户 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 演示的那样全局切换用户

【问题讨论】:

标签: shell root provisioning packer


【解决方案1】:

还有另一种解决方案,可以更简单地同时使用 2 个配置器。

Packer 的 shell 配置程序可以使用 sudo 权限运行 bash。首先你需要使用fileprovisioner 将你的脚本文件从本地机器复制到远程,然后使用shellprovisioner 运行它。

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完成任务后,你可以用shellprovisioner删除文件。

packer.json 更新

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

【讨论】:

    【解决方案2】:

    假设您使用的 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 "$@"
    

    "$@"here on StackOverflow有一个很好的解释。

    【讨论】:

      【解决方案3】:

      您应该覆盖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` 是输出,以防我想通过@987654323 切换回 vagrant 用户执行其他一些命令@。有没有比我最初的答案更好的切换用户的解决方案?
      • 如果您是root,只需在您想以其他用户身份运行的任何命令前加上sudo -u &lt;user&gt;
      【解决方案4】:

      一个可能的答案似乎是: https://unix.stackexchange.com/questions/70859/why-doesnt-sudo-su-in-a-shell-script-run-the-rest-of-the-script-as-root

      sudo su <<HERE
      ls /root
      whoami
      HERE
      

      也许有更好的答案?

      【讨论】:

        猜你喜欢
        • 2013-03-12
        • 1970-01-01
        • 1970-01-01
        • 2017-02-04
        • 2012-07-05
        • 1970-01-01
        • 2017-12-05
        • 2021-06-01
        相关资源
        最近更新 更多