【问题标题】:Using a script that requires user input with chef cookbook with vagrant使用需要用户输入的脚本和带有流浪汉的厨师食谱
【发布时间】:2025-12-17 07:45:01
【问题描述】:

我正在编写一个自定义的 Asterisk 厨师食谱,我需要在其中运行此脚本

bash 'create asterisk keys' do
  user 'root'
  cwd File.dirname(source_path)
  code <<-EOH
    cd asterisk-#{node.version}*
    ./contrib/scripts/ast_tls_cert -C #{node.host} -O "#{node.box_name}" -d #{node.keys_dir}
  EOH
  action :nothing
end

这个ast_tls_cert 脚本会要求输入几个密码,但是当我通过 vagrant 运行它时,由于永远不会输入密码,因此永远不会生成密钥。有没有办法告诉厨师如果脚本需要用户输入才能使用一些 ENV 变量作为值?我真的不需要它停下来向用户询问输入。实际上,我宁愿它不这样做。我只想指定一些值并告诉它使用该值。

【问题讨论】:

  • 诚然that script 只是一个方便的openssl 包装器。您可以直接调用 openssl 命令(这将启用 -passin 和 -passout 命令行选项)。或者你甚至可以在一个 ruby​​_block 中使用 ruby​​ 和 OpenSSL Module

标签: vagrant chef-infra asterisk cookbook


【解决方案1】:

通常,您需要假设 Chef 是在无人值守的情况下运行的。您可以使用 expect 或 pexpect(python 版本)之类的工具来驱动绝对需要交互式输入的脚本,但请检查您是否可以通过环境变量或类似方式提供密码。

【讨论】:

  • 必须有一些厨师方法来做到这一点。我知道 ruby​​ 有 PTY 模块。 ast_tls_cert 脚本无法将密码作为选项传递。
  • 我的意思是你可以在 Ruby 中编写一个简单的 expect 克隆(实际上,Google shows at least one exists),但这不是 Chef 所做或关心的事情。
【解决方案2】:

有一个名为 ruby_expect 的 gem 可以添加到食谱中来处理这个问题。

在您的食谱default.rb 文件的顶部,您需要添加chef_gem 'ruby_expect'。接下来我创建了一个 ruby​​_block 来处理这个问题。

ruby_block 'create asterisk keys' do
  block do
    require 'ruby_expect'
    Dir.chdir(File.join(File.dirname(tarball_path), "asterisk-#{node.version}"))
    exp = RubyExpect::Expect.spawn(%{./contrib/scripts/ast_tls_cert -C #{node.host} -O "#{node.box_name}" -d #{node.keys_dir}}, debug: true)
    exp.procedure do
      each do
        expect %r{Enter pass phrase for /etc/asterisk/keys/ca.key:} do
          send 'somepassword'
        end
      end
    end
  end
  action :nothing
end

tarball_path 是您下载星号 tar 的位置。

【讨论】:

    最近更新 更多