Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Chef guard块ruby代码在运行时未执行_Ruby_Chef Infra_Chef Recipe_Chef Solo - Fatal编程技术网

Chef guard块ruby代码在运行时未执行

Chef guard块ruby代码在运行时未执行,ruby,chef-infra,chef-recipe,chef-solo,Ruby,Chef Infra,Chef Recipe,Chef Solo,根据Chef的双过程模型,ruby块、guard块和lazy中的任何代码都只在运行时执行 我有一个包含三种资源的食谱 在编译阶段赋值的变量 require 'socket' require 'down' require 'net/http' conf = `hostname`.chomp vpn_ip_list = Socket.ip_address_list.select{ |ip| ip.ip_address.match(/^10.12/) } !vpn_ip_list.empty? ?

根据Chef的双过程模型,ruby块、guard块和lazy中的任何代码都只在运行时执行

我有一个包含三种资源的食谱

在编译阶段赋值的变量

require 'socket'
require 'down'
require 'net/http'

conf = `hostname`.chomp
vpn_ip_list = Socket.ip_address_list.select{ |ip| ip.ip_address.match(/^10.12/) }
!vpn_ip_list.empty? ? ip_addr = vpn_ip_list.first.ip_address : ip_addr = ""
第一资源-检查是否使用保护块中的代码分配了所需的VPN IP地址,如果未分配,则下载conf文件并通知第二服务资源重新启动openvpn。保护块内变量的值是在编译阶段获得的

ruby_block 'download_openvpn_conf' do
block do 
    attempt = 2
    begin
        retries ||= 0
        tempfile = Down.download("http://some-url1/#{conf}",max_redirects: 0)
        FileUtils.mv tempfile.path, "#{node['openvpn-conf-path']}/#{tempfile.original_filename}"
        FileUtils.chmod 0644, "#{node['openvpn-conf-path']}/#{tempfile.original_filename}"
    rescue Down::Error => e
        node.run_state['error'] = e.to_s
        puts e
        Chef::Log.warn ("\n \t ***********#{e}***********")
        retry if (retries += 1) < 1
    end 
end
only_if {vpn_ip_list.size.eql?(0) || vpn_ip_list.size >= 2}
action :run
notifies :restart, 'service[openvpn]', :immediately
notifies :delete, "file[#{node['openvpn-conf-path']}/#{conf}]", :before
end
由于上述服务是在converge阶段执行的,因此应根据下载的配置文件分配VPN ip地址

第三个资源-如果在执行第二个资源时未分配VPN IP,则会请求新的VPN配置文件

ruby_block 'manual_vpn' do
block do
    if node.run_state['error'] == "file not found"
        Chef::Log.info ("\n \t ******** VPN IP has not been assigned. File may be corrupted & initiating re-run********")
        uri = URI.parse("http://some-url2=#{host}&action=create")
        Chef::Log.info (uri)
        http = Net::HTTP.new(uri.host,uri.port)
        request = Net::HTTP::Get.new(uri.request_uri)
        response = http.request(request)
        case response.body
        when "error"
            Chef::Log.info ("\n \t Website reported an Error. Config for the given serial number could have already been generated")
        when "Request for vpn successfully added."  
            Chef::Log.warn ("\n \t **** Inside response processing => Request Accepted **")
            Chef::Log.warn ("\n \t *** New vpn config request has been accepted. Waiting for 3 minutes ***")
            sleep 180
        else
            Chef::Log.info ("\n \t Nothing to do - Extra option for future")    
        end 
    else 
        puts "Config file exists and hence not downloading"
    end     
end 
notifies :run, 'ruby_block[re-download-vpn-conf]', :delayed
only_if { Socket.ip_address_list.select{ |ip| ip.ip_address.match(/^10.12/) }.size.eql?(0) }
not_if {node.run_state['error'].eql?("too many redirects")}
end 
分配的VPN IP由保护块
only_if{Socket.IP|u address_列表中的代码检查。选择{IP|IP.IP|u address.match(/^10.12/)}.size.eql?(0)}
,并假定仅在运行时执行。在第二次资源执行结束时,VPN IP已确定分配,但上述防护装置中的代码无法检测到它


我在测试ruby块的配方末尾使用了Pry调试器,以验证在执行第二次服务重启资源后是否分配了IP。想知道为什么Chef的保护块中的代码无法检测到以前资源执行分配的VPN。

基本上,问题是Chef没有等待系统售后服务资源执行的状态。Chef不关心服务是否启动并运行,它只关心服务的执行

这是一个典型的竞争条件的例子,厨师移动头部来执行下一个资源。为了避免这种情况,我必须在ruby块中引入所需的睡眠时间。另一种方法是添加一个
直到true
条件,但在我的例子中,这不起作用,因为chef中的ruby块被无限地卡住了,尽管服务已经启动并运行

service 'openvpn' do
   supports :status => true, :restart => true, :start => true, :stop => true
   action :nothing
   Chef::Log.info ("\n \t *********Restarting OPEN-VPN*********")
end


ruby_block 'wait for vpn ip' do
    block do
        Chef::Log.warn ("****************** Sleep block starts ********************")
        sleep 30
        Chef::Log.warn ("****************** Sleep block exits ********************")
    end 
    action :run
end

ruby_block 'manual_vpn' do
block do
    if node.run_state['error'] == "file not found"
        Chef::Log.info ("\n \t ******** VPN IP has not been assigned. File may be corrupted & initiating re-run********")
        uri = URI.parse("http://some-url2=#{host}&action=create")
        Chef::Log.info (uri)
        http = Net::HTTP.new(uri.host,uri.port)
        request = Net::HTTP::Get.new(uri.request_uri)
        response = http.request(request)
        case response.body
        when "error"
            Chef::Log.info ("\n \t Website reported an Error. Config for the given serial number could have already been generated")
        when "Request for vpn successfully added."  
            Chef::Log.warn ("\n \t **** Inside response processing => Request Accepted **")
            Chef::Log.warn ("\n \t *** New vpn config request has been accepted. Waiting for 3 minutes ***")
            sleep 180
        else
            Chef::Log.info ("\n \t Nothing to do - Extra option for future")    
        end 
    else 
        puts "Config file exists and hence not downloading"
    end     
end 
notifies :run, 'ruby_block[re-download-vpn-conf]', :delayed
only_if { Socket.ip_address_list.select{ |ip| ip.ip_address.match(/^10.12/) }.size.eql?(0) }
not_if {node.run_state['error'].eql?("too many redirects")}
end  

基本上,问题在于Chef不会等待系统后期服务资源执行的状态。Chef不关心服务是否启动并运行,它只关心服务的执行

这是一个典型的竞争条件的例子,厨师移动头部来执行下一个资源。为了避免这种情况,我必须在ruby块中引入所需的睡眠时间。另一种方法是添加一个
直到true
条件,但在我的例子中,这不起作用,因为chef中的ruby块被无限地卡住了,尽管服务已经启动并运行

service 'openvpn' do
   supports :status => true, :restart => true, :start => true, :stop => true
   action :nothing
   Chef::Log.info ("\n \t *********Restarting OPEN-VPN*********")
end


ruby_block 'wait for vpn ip' do
    block do
        Chef::Log.warn ("****************** Sleep block starts ********************")
        sleep 30
        Chef::Log.warn ("****************** Sleep block exits ********************")
    end 
    action :run
end

ruby_block 'manual_vpn' do
block do
    if node.run_state['error'] == "file not found"
        Chef::Log.info ("\n \t ******** VPN IP has not been assigned. File may be corrupted & initiating re-run********")
        uri = URI.parse("http://some-url2=#{host}&action=create")
        Chef::Log.info (uri)
        http = Net::HTTP.new(uri.host,uri.port)
        request = Net::HTTP::Get.new(uri.request_uri)
        response = http.request(request)
        case response.body
        when "error"
            Chef::Log.info ("\n \t Website reported an Error. Config for the given serial number could have already been generated")
        when "Request for vpn successfully added."  
            Chef::Log.warn ("\n \t **** Inside response processing => Request Accepted **")
            Chef::Log.warn ("\n \t *** New vpn config request has been accepted. Waiting for 3 minutes ***")
            sleep 180
        else
            Chef::Log.info ("\n \t Nothing to do - Extra option for future")    
        end 
    else 
        puts "Config file exists and hence not downloading"
    end     
end 
notifies :run, 'ruby_block[re-download-vpn-conf]', :delayed
only_if { Socket.ip_address_list.select{ |ip| ip.ip_address.match(/^10.12/) }.size.eql?(0) }
not_if {node.run_state['error'].eql?("too many redirects")}
end