【问题标题】:How does Chef recipe get/retrieve parameters from databag?Chef recipe 如何从数据包中获取/检索参数?
【发布时间】:2015-06-14 00:29:45
【问题描述】:

我一直在尝试学习 Chef,并尝试测试一个可以对 Windows 2008 R2 服务器进行 dcpromo 的小型 Chef 食谱。

我不记得我最初从哪里得到这两个文件,但我能够让它工作。

原来的 dcpromo_unattend.txt.erb 文件是:

[DCINSTALL]
SafeModeAdminPassword=<%= @admin_password %>
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=<%= @domain_name %>
ForestLevel=3
DomainLevel=3
InstallDNS=yes

default.rb 中有这一部分:

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables({
    :admin_password => '',
    :domain_name => ''
  })
end

我不太清楚如何传入 admin_password 和 domain_name 参数,所以我在 dcpromo_unattend.txt.erb 文件中进行了硬编码,经过一些调整后,能够使说明书工作。

现在,我希望能够将 admin_password 和 domain_name 值放入数据包中,所以我尝试添加:

begin
  dcpromote = Chef::DataBagItem.load(:dcpromote, :main)
rescue
  Chef::Log.fatal("Could not find the 'main' item in the 'dcpromote' data bag - Raising fatal error!!")
  raise
end

并将原始模板部分更改为:

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables({
    :admin_password => dcpromote['admin_password'],
    :domain_name => dcpromote['domain_name']
  })
end

我创建了一个名为“dcpromote”的数据包,但这似乎不起作用。

有人可以解释原始模板代码应该如何工作,即,它应该从哪里检索 admin_password 和 domain_name 参数?

另外,谁能告诉我为了从“dcpromote”数据包中读取 admin_password 和 domain_name 所做的更改有什么问题?

谢谢, 吉姆

编辑:我想我已经盯着这个看了几个小时了,实际上,我什至不明白我的所作所为是如何工作的。

我的意思是我拥有的 erb 文件具有硬编码的密码和域:

[DCINSTALL]
SafeModeAdminPassword=xxxxxxxxx
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=WHATEVER.com
ForestLevel=4
DomainLevel=4
InstallDNS=yes

请注意,该文件中没有对 admin_password 或 domain_name 的引用。

那么,recipe/default.rb 的这一部分是如何工作的呢?

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables({
    :admin_password => '',
    :domain_name => ''
  })
end

谁能准确解释这部分配方代码的作用:

  variables({
    :admin_password => '',
    :domain_name => ''
  })

??

谢谢, 吉姆

编辑 2:

在@Draco Ater 建议的更改后添加整个 default.rb:

#
# Cookbook Name:: dcpromote
# Recipe:: default
#
# Copyright (c) 2015 The Authors, All Rights Reserved.
# 


class ServerHelper 
    extend ::Windows::Helper

  class << self
    def dism
      @@dism ||= locate_sysnative_cmd("dism.exe")
    end

    def powershell
      @@powershell ||= locate_sysnative_cmd('WindowsPowershell\v1.0\powershell.exe')
    end

    def feature_installed?(feature)
      cmd = Mixlib::ShellOut.new("#{dism} /online /Get-Features", {:returns => [0,42,127]}).run_command
      !!(cmd.stderr.empty? && (cmd.stdout =~  /^Feature Name : #{feature}.?$\n^State : Enabled.?$/i))
    end
  end
end

windows_reboot 60 do
  action :nothing
end

#
# Following snippet from: https://supermarket.chef.io/cookbooks/ad
# This snippet checks for presence of a databag named "dcpromote" and for presence
# of an item in the databag named "main".  If that item is not present, then
# this snippet logs a fatal error.
begin
  dcpromote = Chef::DataBagItem.load('dcpromote', 'main')
rescue
  Chef::Log.fatal("Could not find the 'main' item in the 'dcpromote' data bag - Raising fatal error!!")
  raise
end




directory Chef::Config[:file_cache_path]
dcpromo_file = File.join(Chef::Config[:file_cache_path], 'dcpromo_unattend.txt')
#cert_script = File.join(Chef::Config[:file_cache_path], 'setupca.vbs')
# Available from e.g. http://blogs.technet.com/b/pki/archive/2009/09/18/automated-ca-installs-using-vb-script-on-windows-server-2008-and-2008r2.aspx

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables(
    :admin_password => dcpromote['admin_password'],
    :domain_name => dcpromote['domain_name']
  )

end

powershell_script "run_dcpromo" do
  code "dcpromo /unattend:#{dcpromo_file}"
  #notifies :request, 'windows_reboot[60]'
  not_if { ServerHelper.feature_installed? 'DirectoryServices-DomainController' }
end

windows_feature 'DirectoryServices-DomainController' do
  action :install
  #notifies :request, 'windows_reboot[60]'
end

这本食谱/食谱仍然无法与数据包一起使用。

澄清一下:当我使用带有硬编码设置的 admin_password 和 domain_name 的早期代码运行它时,它可以工作。

但是,如果我尝试使用数据包的代码,它就不起作用。当我用数据包运行它时:

1) [这很奇怪]:如果我在运行过程中查看“无人值守”的 txt 文件,它看起来像是已填充,但最后密码项设置为空,即无人值守运行期间的文本文件更改。

2) 最后,当 Powershell 运行时,它看起来像错误 32。

这是控制台输出:

PS C:\Users\Administrator> chef-client -o dcpromote_usedatabag
Starting Chef Client, version 12.3.0
[2015-06-14T07:24:47-07:00] INFO: *** Chef 12.3.0 ***
[2015-06-14T07:24:47-07:00] INFO: Chef-client pid: 260
[2015-06-14T07:25:04-07:00] WARN: Run List override has been provided.
[2015-06-14T07:25:04-07:00] WARN: Original Run List: []
[2015-06-14T07:25:04-07:00] WARN: Overridden Run List: [recipe[dcpromote_usedatabag]]
[2015-06-14T07:25:04-07:00] INFO: Run List is [recipe[dcpromote_usedatabag]]
[2015-06-14T07:25:04-07:00] INFO: Run List expands to [dcpromote_usedatabag]
[2015-06-14T07:25:04-07:00] INFO: Starting Chef Run for node8
[2015-06-14T07:25:04-07:00] INFO: Running start handlers
[2015-06-14T07:25:04-07:00] INFO: Start handlers complete.
[2015-06-14T07:25:04-07:00] INFO: HTTP Request Returned 404 Not Found:
resolving cookbooks for run list: ["dcpromote_usedatabag"]
[2015-06-14T07:25:04-07:00] INFO: Loading cookbooks [dcpromote_usedatabag@0.1.1, windows@1.37.0, che
[2015-06-14T07:25:04-07:00] INFO: Skipping removal of obsoleted cookbooks from the cache
Synchronizing Cookbooks:
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/recipes/default.rb
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/templates/default/d
erb in the cache.
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/Berksfile in the ca
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/.kitchen.yml in the
  - windows
  - chef_handler
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/chefignore in the c
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/metadata.rb in the
[2015-06-14T07:25:04-07:00] INFO: Storing updated cookbooks/dcpromote_usedatabag/README.md in the ca
  - dcpromote_usedatabag
Compiling Cookbooks...
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  HI ++++++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  HI ++++++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  In template +++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: +++++++++++++++++++++++++++  In template +++++++++++++++++++++++++
[2015-06-14T07:25:04-07:00] INFO: ++++ xoutput = [123]
Converging 5 resources
Recipe: dcpromote_usedatabag::default
  * windows_reboot[60] action nothing[2015-06-14T07:25:04-07:00] INFO: Processing windows_reboot[60]
romote_usedatabag::default line 28)
 (skipped due to action :nothing)
  * directory[c:/chef/cache] action create[2015-06-14T07:25:04-07:00] INFO: Processing directory[c:/
reate (dcpromote_usedatabag::default line 47)
 (up to date)
  * template[c:/chef/cache/dcpromo_unattend.txt] action create[2015-06-14T07:25:04-07:00] INFO: Proc
hef/cache/dcpromo_unattend.txt] action create (dcpromote_usedatabag::default line 52)
[2015-06-14T07:25:04-07:00] INFO: template[c:/chef/cache/dcpromo_unattend.txt] created file c:/chef/
nd.txt

    - create new file c:/chef/cache/dcpromo_unattend.txt[2015-06-14T07:25:04-07:00] INFO: template[c
_unattend.txt] updated file contents c:/chef/cache/dcpromo_unattend.txt

    - update content in file c:/chef/cache/dcpromo_unattend.txt from none to 798057
    --- c:/chef/cache/dcpromo_unattend.txt      2015-06-14 07:25:04.000000000 -0700
    +++ C:/Users/ADMINI~1/AppData/Local/Temp/chef-rendered-template20150614-260-1cvaiw  2015-06-14 0
700
    @@ -1 +1,10 @@
    +[DCINSTALL]
    +SafeModeAdminPassword=P@ssw0rd$123
    +RebootOnCompletion=Yes
    +ReplicaOrNewDomain=domain
    +NewDomain=forest
    +NewDomainDNSName=whateverisforever123.com
    +ForestLevel=4
    +DomainLevel=4
    +InstallDNS=yes
  * powershell_script[run_dcpromo] action run[2015-06-14T07:25:04-07:00] INFO: Processing powershell
 action run (dcpromote_usedatabag::default line 68)


    ================================================================================
    Error executing action `run` on resource 'powershell_script[run_dcpromo]'
    ================================================================================

    Mixlib::ShellOut::ShellCommandFailed
    ------------------------------------
    Expected process to exit with [0], but received '32'
    ---- Begin output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrest
None -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
    STDOUT:
    STDERR:
    ---- End output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestri
ne -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
    Ran "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted -InputForm
ers/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" returned 32

    Resource Declaration:
    ---------------------
    # In c:/chef/cache/cookbooks/dcpromote_usedatabag/recipes/default.rb

     68: powershell_script "run_dcpromo" do
     69:   code "dcpromo /unattend:#{dcpromo_file}"
     70:   #notifies :request, 'windows_reboot[60]'
     71:   not_if { ServerHelper.feature_installed? 'DirectoryServices-DomainController' }
     72: end
     73:

    Compiled Resource:
    ------------------
    # Declared in c:/chef/cache/cookbooks/dcpromote_usedatabag/recipes/default.rb:68:in `from_file'

    powershell_script("run_dcpromo") do
      action "run"
      retries 0
      retry_delay 2
      default_guard_interpreter :powershell_script
      command "run_dcpromo"
      backup 5
      returns 0
      code "dcpromo /unattend:c:/chef/cache/dcpromo_unattend.txt"
      interpreter "powershell.exe"
      declared_type :powershell_script
      cookbook_name "dcpromote_usedatabag"
      recipe_name "default"
      not_if { #code block }
    end

[2015-06-14T07:26:22-07:00] INFO: Running queued delayed notifications before re-raising exception

Running handlers:
[2015-06-14T07:26:22-07:00] ERROR: Running exception handlers
Running handlers complete
[2015-06-14T07:26:22-07:00] ERROR: Exception handlers complete
[2015-06-14T07:26:22-07:00] FATAL: Stacktrace dumped to c:/chef/cache/chef-stacktrace.out
Chef Client failed. 1 resources updated in 98.15625 seconds
[2015-06-14T07:26:22-07:00] FATAL: Mixlib::ShellOut::ShellCommandFailed: powershell_script[run_dcpro
tabag::default line 68) had an error: Mixlib::ShellOut::ShellCommandFailed: Expected process to exit
ved '32'
---- Begin output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestrict
 -File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
STDOUT:
STDERR:
---- End output of "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted
File "C:/Users/ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" ----
Ran "powershell.exe" -NoLogo -NonInteractive -NoProfile -ExecutionPolicy Unrestricted -InputFormat N
ADMINI~1/AppData/Local/Temp/chef-script20150614-260-dfo5yi.ps1" returned 32
PS C:\Users\Administrator>

最后是无人看管的 txt 文件:

[DCINSTALL]
SafeModeAdminPassword=
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
NewDomainDNSName=whateverisforever123.com
ForestLevel=4
DomainLevel=4
InstallDNS=yes

为什么无人值守的txt文件在运行过程中会发生两次变化(为什么密码值消失了)?

谢谢, 吉姆

编辑 3:

作为记录,我可以通过在模板文件中添加一个额外的参数来设置 netbios 名称来实现这一点:

[DCINSTALL]
RebootOnCompletion=Yes
ReplicaOrNewDomain=domain
NewDomain=forest
SafeModeAdminPassword=<%= @admin_password %>
NewDomainDNSName=<%= @domain_name %>
ForestLevel=4
DomainLevel=4
InstallDNS=yes
DomainNetbiosName=<%= @domain_netbios_name %>

然后修改default.rb来设置那个参数:

template dcpromo_file do
  source "dcpromo_unattend.txt.erb"
  variables(
    :admin_password => dcpromote['admin_password'],
    :domain_netbios_name => dcpromote['domain_netbios_name'],
    :domain_name => dcpromote['domain_name']
  )

吉姆

【问题讨论】:

    标签: ruby chef-infra chef-recipe


    【解决方案1】:

    让我们从模板文件本身开始。

    [DCINSTALL]
    SafeModeAdminPassword=<%= @admin_password %>
    RebootOnCompletion=Yes
    ReplicaOrNewDomain=domain
    NewDomain=forest
    NewDomainDNSName=<%= @domain_name %>
    ForestLevel=3
    DomainLevel=3
    InstallDNS=yes
    

    &lt;% %&gt; 中的代码是 ruby​​ 代码。 &lt;% %&gt; 中以 @ 开头的东西是变量。 = 是打印值的简写。所以模板使用 2 个变量来设置值,只需将它们打印出来。

    变量从何而来?正是来自配方中的这段代码({} 在这里不需要):

     variables(
        :admin_password => '',
        :domain_name => ''
     )
    

    目前它们是由空字符串初始化的,但是如果你在配方中放了其他东西,它也会在模板中改变。它不会中断,如果你传递一些模板中没有使用的变量,它只是冗余代码。

    现在你可以像这样把你的密码和域名放在那里并让它工作(在目标机器上生成正确的配置文件)

    variables(
        :admin_password => 'my_pass',
        :domain_name => 'localhost'
    )
    

    现在我们要将值移动到数据包中。使用“main”数据包项创建一个“dcpromote”数据包。

    knife data bag create dcpromote main
    

    并编辑 json 文件。最后你应该有这样的东西:

    {
      "id": "main", # <= data bag item name
      "admin_password": "my_pass",
      "domain_name": "localhost"
    }
    

    然后在配方中将数据包读入变量(尝试使用字符串而不是符号作为数据包和项目名称):

    begin
      dcpromote = Chef::DataBagItem.load( 'dcpromote', 'main' )
    rescue
      Chef::Log.fatal("Could not find the 'main' item in the 'dcpromote' data bag - Raising fatal error!!")
      raise
    end
    

    并在创建配置文件时使用:

    variables(
      :admin_password => dcpromote['admin_password'],
      :domain_name => dcpromote['domain_name']
    )
    

    【讨论】:

    • 感谢您的解释和 cmets - 我按照您的建议使用附加信息编辑了我的原始帖子,解释了我做出这些更改后发生的情况。
    • 更多测试:(a) 如果我在 default.rb 中注释 powershell_script 和之后的资源,无人值守的 txt 文件最终正常,即填充了密码参数,并且(b) 我尝试更改模板erb文件中的参数顺序,但密码项仍然为空。
    • 我认为在无人参与的文件中以空密码参数结束是一个红鲱鱼。查看此页面:support.microsoft.com/en-us/kb/947034 它说“为了保护,安装 AD DS 后,密码将从答案文件中删除。”,这可能是密码参数为空的原因。所以,底线仍然是为什么 dcpromo 得到“错误 32”??
    • 我不知道为什么,但据此:technet.microsoft.com/en-us/library/cc754937(v=ws.10).aspx,“错误 32”是“ExitBadNetbiosDomainName”,“NetBIOS 名称无效。”
    • 这里我帮不了你。这已经是另一个问题了——根本不涉及模板或厨师。单独问更好。
    猜你喜欢
    • 2016-05-01
    • 2016-11-16
    • 1970-01-01
    • 2021-12-28
    • 1970-01-01
    • 2016-09-02
    • 2011-08-25
    • 2020-08-02
    • 1970-01-01
    相关资源
    最近更新 更多