0

我在试图理解发生了什么时遇到了麻烦,为什么尽管代码放在最后,但为什么要先执行纯 ruby​​ 代码,这是操作 :install 包含的内容的一部分:

action :install do

    ...

    windows_package "#{installation_name}" do
        source "#{Chef::Config[:file_cache_path]}\\#{installer_filename}"
        options "INSTALLDIR=\"#{installation_path}\""
        action :install
        not_if {::Dir.exists?("#{installation_path}\\bin")}
    end

    env "MYSQL_PATH" do
        value "#{installation_path}"
    end

    windows_path "#{installation_path}\\bin" do
        action :add
    end

    windows_batch "Installing Service" do
        code <<-EOH
            set MYSQL_PATH="#{installation_path}"
            call %MYSQL_PATH%\\bin\\mysqld-nt.exe --install MySQL
        EOH
    end

    service "MySQL" do
        action :start
    end

    service "MySQL" do
        action :enable
    end

    change_pass_str = "call \"#{installation_path}\\bin\\mysql.exe\" -u root --execute \"UPDATE mysql.user SET Password=PASSWORD('#{root_password}') WHERE User='root';FLUSH PRIVILEGES;\""
    puts change_pass_str

    password_set_result = system(change_pass_str)
    log !password_set_result ? "Password wasn't changed since root already have a password defined. Maybe there's still data from a previous installation." : "Password has been set!"

end

请忽略我没有放置变量定义的事实,并且知道它们定义明确。问题是当这部分 lwrp 被执行时

change_pass_str = "call \"#{installation_path}\\bin\\mysql.exe\" -u root --execute \"UPDATE mysql.user SET Password=PASSWORD('#{root_password}') WHERE User='root';FLUSH PRIVILEGES;\""
puts change_pass_str
password_set_result = system(change_pass_str)

它无法找到#{installation_path}\\bin\\mysql.exe,因为它尚未安装,尽管该块在动作结束时。

谁能指出我的错误是什么?为什么其他(在这种情况下已在 Windows LWRP 中定义)资源在最后而不是开始时执行?我该如何解决?

4

2 回答 2

1

厨师有一个两通系统看这个

  • 首先通过“编译”食谱并将资源添加到集合中
  • 第二遍“收敛”并检查每个资源是否需要更新并采取相应措施。

在您的 lwrp 中,其中的 ruby​​ 在处理后立即运行,将您的代码包含到ruby_block资源 ( DOC ) 中,以便在收敛时执行。

于 2014-09-30T09:19:29.843 回答
1

LWRP 在执行顺序方面与配方没有什么不同。因此,就像在配方中一样,任何不在资源中的 ruby​​ 代码都将在“资源收集”阶段执行。在您的情况下,您需要将代码包装在一个ruby_blockexecute这样的资源中:

ruby_block 'change the password' do
  block {
    change_pass_str = "call \"#{installation_path}\\bin\\mysql.exe\" -u root --execute \"UPDATE mysql.user SET Password=PASSWORD('#{root_password}') WHERE User='root';FLUSH PRIVILEGES;\""
    puts change_pass_str
    password_set_result = system(change_pass_str)
  end
end

或者

execute'change the password' do
  command "call \"#{installation_path}\\bin\\mysql.exe\" -u root --execute \"UPDATE mysql.user SET Password=PASSWORD('#{root_password}') WHERE User='root';FLUSH PRIVILEGES;\""
end    

这将导致此代码在运行时进行评估。您还需要添加一个only_if, not_if, 或action :nothingruby_block确保它仅在需要时运行。基本上,一个not_iforonly_if会运行 SQL 代码来检查是否设置了密码,如果该块返回 false,那么密码更改将不会运行。

或者,您可以使用action :nothing将资源设置为不运行,然后使用通知或订阅来触发资源仅在安装 mysql 后运行。

于 2014-09-30T13:51:18.410 回答