Chef自定义Remote Desktop Apps资源报错:name为必填属性
问题描述
我正在编写Chef食谱,用于在Windows服务器上部署Remote Desktop Services,除了自定义的应用部署资源外,其余功能均正常。该资源结构简单,但在将待部署应用以哈希数组形式传递时遇到诸多问题。
属性文件 attributes\default.rb
default['app']['app_options'] = [ { connection_broker: 'serv-01', options: { collectionname: 'Terminal Services', alias: 'Acrobat', displayname: 'Adobe Acrobat', filepath: 'C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe', filevirtualpath: 'C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe', commandlinesetting: 'DoNotAllow', iconindex: '0', iconpath: '\\\\serv-01\\C$\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe', usergroups: ['domain\\group'], showinwebaccess: '1' } }, { connection_broker: 'serv-01', options: { collectionname: 'Terminal Services', alias: 'Accounts', displayname: 'Accounts', foldername: 'Accounts', filepath: 'D:\\Accounts\\Accounts.bat', filevirtualpath: 'D:\\Accounts\\Accounts.bat', commandlinesetting: 'DoNotAllow', iconindex: '0', iconpath: 'C:\\Windows\\System32\\cmd.exe', usergroups: ['domain\\group'], showinwebaccess: '1' } } ]
食谱文件 recipes\remote_desktop.rb
rdapps = node.read('app', 'app_options') || [] rdapps.each do |app| remote_desktop_apps app['options']['alias'] do action :create connection_broker app['connection_broker'] app_options app['options'] end end
资源文件 resources\remote_desktop_apps.rb
resource_name :remote_desktop_apps property :connection_broker, String, desired_state: false property :app_options, [String, Hash, Array], desired_state: false action :create do app_options.each do |k,v| script << "New-RDRemoteApp -ConnectionBroker "#{connection_broker}" {-#{k.to_s.capitalize} #{v}}.join(' ')}" end end
报错输出
执行kitchen converge后得到以下错误:
================================================================================ Error executing action `create` on resource 'remote_desktop_apps[Acrobat]' ================================================================================ Chef::Exceptions::ValidationFailed ---------------------------------- name is a required property Resource Declaration: --------------------- # In C:/Users/ADMINI~1/AppData/Local/Temp/kitchen/cache/cookbooks/windows_/recipes/remote_desktop.rb 76: remote_desktop_apps app['options']['alias'] do 77: action :create 78: connection_broker app['connection_broker'] 79: app_options app['options'] 80: end 81: end Compiled Resource: ------------------ # Declared in C:/Users/ADMINI~1/AppData/Local/Temp/kitchen/cache/cookbooks/windows_/recipes/remote_desktop.rb:76:in `block in from_file' remote_desktop_apps("Acrobat") do action [:create] default_guard_interpreter :default declared_type :remote_desktop_apps cookbook_name "windows_" recipe_name "remote_desktop" connection_broker "serv-01" app_options {"collectionname"=>"Terminal Services", "alias"=>"Acrobat", "displayname"=>"Adobe Acrobat", "filepath"=>"C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe", "filevirtualpath"=>"C:\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe", "commandlinesetting"=>"DoNotAllow", "iconindex"=>"0", "iconpath"=>"\\\\serv-01\\C$\\Program Files (x86)\\Adobe\\Acrobat 11.0\\Acrobat\\Acrobat.exe", "usergroups"=>["domain\\group"], "showinwebaccess"=>"1"} end
末尾致命错误:
FATAL: Chef::Exceptions::ValidationFailed: remote_desktop_apps[Acrobat] (windows_::remote_desktop line 76) had an error: Chef::Exceptions::ValidationFailed: name is a required property $$$$$$ Exception calling "Read" with "3" argument(s): "Offset and length were out of bounds for the array or count is greater than the number of elements from index to the end of the source collection." At line:100 char:11 $$$$$$ + if ($fs.Read($bytes, 0, $fs.Length) -gt 0) { $$$$$$ + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : ArgumentException
问题原因与解决方法
核心原因
name属性验证失败:自定义Chef资源默认要求name属性存在,当前资源定义未显式声明该属性,导致Chef验证逻辑触发报错。- PowerShell脚本拼接错误:资源
create动作中,命令拼接存在引号嵌套、数组处理不当等问题,生成的无效脚本引发后续临时文件读取异常。
修复步骤
1. 修正自定义资源定义
更新resources\remote_desktop_apps.rb,显式声明name属性并修复PowerShell命令生成逻辑:
resource_name :remote_desktop_apps # 显式声明name作为资源名称属性 property :name, String, name_property: true property :connection_broker, String, desired_state: false property :app_options, Hash, desired_state: false # 限定为Hash类型,匹配传入的参数结构 action :create do # 构建PowerShell参数列表,处理不同类型的值 params = app_options.map do |k, v| value = case v when Array # 数组类型参数(如usergroups)转成单引号包裹的逗号分隔字符串 "'#{v.join("','")}'" else # 含空格的字符串添加双引号包裹 v.to_s.include?(' ') ? "\"#{v}\"" : v.to_s end "-#{k.to_s.capitalize} #{value}" end.join(' ') # 生成完整的PowerShell命令 ps_command = "New-RDRemoteApp -ConnectionBroker \"#{connection_broker}\" #{params}" # 执行PowerShell命令 powershell_script "Create RDS App #{name}" do code ps_command end end
2. 验证食谱调用逻辑
recipes\remote_desktop.rb的调用逻辑无需修改,但需确保app['options']['alias']始终有有效值,避免传递空名称触发新的验证错误。
3. 消除文件读取异常
末尾的文件读取异常是前期脚本错误导致Chef临时文件处理失败,修复资源定义后该异常会自动消失。
内容的提问来源于stack exchange,提问作者lolcomputers
相关产品推荐
相关产品推荐

