Chef不同资源块间传值问题:Redis端口检测后启动逻辑运行报错咨询
问题根因
- 你在第一个bash资源的Shell脚本中定义的
portval_#{port}变量仅存在于当前bash资源运行的独立子Shell进程中,资源执行完成后子Shell销毁,变量直接失效,无法传递给后续资源使用 - 第二个bash资源的
only_if "portval_#{port}"写法会被Chef解析为「执行名为portval_54321的系统命令,根据返回值判断是否执行当前资源」,系统中不存在这个命令,自然会抛出No such file or directory的错误
正确实现方式
你完全不需要单独定义检查用的bash资源,直接把进程检查逻辑放到启动资源的守卫语句中即可,优化后代码如下:
ports.each do |port| bash "Starting_redis_after_crash_for_port - #{port}" do # 仅当对应端口的redis进程不存在时才执行启动逻辑 only_if <<-EOH pidval=$(ps -ef | grep /opt/redis/src/redis-server | grep ":#{port}" | grep -vc grep) [ $pidval -eq 0 ] EOH code <<-EOH rm -f #{port}.pid sudo service redis@#{port} start EOH end end
如果确实需要在多个资源之间共享运行状态,也可以用Chef提供的临时存储node.run_state实现值传递,示例逻辑如下:
ports.each do |port| ruby_block "Check_port_running_#{port}" do block do pidval = shell_out("ps -ef | grep /opt/redis/src/redis-server | grep :#{port} | grep -vc grep").stdout.to_i node.run_state["redis_port_#{port}_alive"] = pidval > 0 end end bash "Starting_redis_after_crash_for_port - #{port}" do only_if { node.run_state["redis_port_#{port}_alive"] == false } code <<-EOH rm -f #{port}.pid sudo service redis@#{port} start EOH end end
内容的提问来源于stack exchange,提问作者Dabang
相关产品推荐
相关产品推荐

