You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chef食谱编译错误:undefined method 'cwd' for cookbook 求助

问题诊断与修正方案

核心问题分析

  1. 编译错误undefined method 'cwd' for cookbook
    该错误通常由以下原因导致:

    • Chef客户端版本过低(建议使用Chef 12+版本,早期版本对execute资源的cwd属性支持不完善);
    • 食谱代码缩进不规范,导致execute资源块语法非法;
    • 角色未正确应用到节点,导致节点属性未加载。
  2. 脚本无法运行的关键原因
    你设置的devops_dir是本地工作站的cookbook路径,但Chef客户端在目标EC2节点运行时,cookbook会被下载到节点的缓存目录(默认路径为/var/chef/cache/cookbooks/),而非你指定的本地路径,导致cwd指向的目录不存在,脚本无法被找到。

  3. 节点变量迭代有效性
    节点变量完全可以在数组迭代中生效,你对employees数组的遍历逻辑本身是正确的。


修正后的食谱方案

方案一:标准做法(推荐)

使用cookbook_file将脚本同步到目标节点,避免路径依赖:

  1. 在hello-chef cookbook中创建files/default/scripts目录,将shell.sh放入该目录;
  2. 修改multi-module.rb食谱:
node['employees'].each do |employee|
  # 同步脚本到节点指定目录
  cookbook_file "/tmp/scripts/shell.sh" do
    source "scripts/shell.sh"
    owner node['user']
    group node['group']
    mode '0755'
    action :create
    not_if { ::File.exist?("/tmp/scripts/shell.sh") }
  end

  execute "test-multi-#{employee['name']}" do
    cwd "/tmp/scripts"
    user node['user']
    group node['group']
    # 使用数组形式避免命令注入风险
    command ["bash", "shell.sh", employee['name'], employee['email']]
  end
end

方案二:使用节点缓存路径(不推荐)

若需直接使用cookbook中的脚本,可通过Chef内置变量获取节点上的缓存路径:

node['employees'].each do |employee|
  execute "test-multi-#{employee['name']}" do
    cwd "#{Chef::Config[:file_cache_path]}/cookbooks/#{cookbook_name}/recipes/scripts"
    user node['user']
    group node['group']
    command ["bash", "shell.sh", employee['name'], employee['email']]
  end
end

验证步骤

  1. 确认角色已应用到节点:运行knife node show <节点名称> -r,检查run_list是否包含recipe[multi-module];
  2. 上传更新后的cookbook:knife cookbook upload hello-chef;
  3. 在节点执行Chef客户端:sudo chef-client;
  4. 查看执行日志:/var/log/chef/client.log,确认脚本执行状态。

内容的提问来源于stack exchange,提问作者Shyam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:55:27