ruby - Chef Recipe 如何从数据包中获取/检索参数?

标签 ruby chef-infra chef-recipe

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

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

原始的 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

有人能准确解释这部分 Recipe 代码在做什么吗:

  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

这本 Recipe/Recipe 仍然不适用于数据包。

澄清一下:当我使用带有 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']
  )

吉姆

最佳答案

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

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

里面的代码<% %>是 ruby 代码。以@开头的东西在<% %>里面是变量。 =是打印值的简写。因此,模板使用 2 个变量来设置值,只需将它们打印出来即可。

变量从何而来?完全来自 Recipe 中的这段代码(此处不需要 {}):

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

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

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

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

现在我们要将值移动到数据包中。使用“主要”数据包项创建“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']
)

关于ruby - Chef Recipe 如何从数据包中获取/检索参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30824900/

相关文章:

ruby-on-rails - 如何在 Rails 中为我的整个应用捕获 ArgumentError?

ruby - 是否有与 car、cdr 和 cons 等效的 ruby​​?

elasticsearch - 覆盖Elasticsearch Recipe 中的属性

chef-infra - Chef : How to rollback a run of cookbook?

amazon-web-services - 如何修改 aws opsworks 上 Tomcat 的 context.xml?

Ruby 看不到 NLS_LANG 环境变量

ruby-on-rails - rails : what's wrong with this multiple join with conditions on the associations?

amazon-web-services - 使用 Chef 以编程方式查找 AWS 公共(public) DNS

java - 使用 Vagrant 时为 Chef 预缓存下载

docker - 厨房-Docker 和 Systemd