0

I have a CHEF recipe for package install on windows hosts. We used to use chef13 client; however we have upgraded to chef16, and we are getting some issues with the cookbook migration.

When I run the existing role as-it-is on a win2k16 chef16 kitchen platform, I get this error,

Chef::Exceptions::ImmutableAttributeModification
------------------------------------------------
Node attributes are read-only when you do not specify which precedence level to set. To set an attribute use code like `node.default["key"] = "value"'

and it points out to this section of the recipe

          67:        guid = guid.gsub(/{/, '').gsub(/}/, '') # remove {}
          68:        log "[#{role}][#{recipe_name}][#{app_name}]: GUID for installer #{app_name} is #{guid}"
          69>>       app_params.store('product_guid', guid) # add GUID to the list of parameters
          70:      end

Hence, what I understand that chef16 dosen't like the hash.store method.

I have tried some other alternate solutions to update the hash, however they do not work.

Using merge method:-

app_params.merge!({ :product_guid => 'guid' })

Using precedence level explicitly:- ( I have used .default, .override as well, however its the same symptom)

node.force_override!['app_params']['product_guid'] = guid
(reff from : https://github.com/chef/chef/issues/6563)

Note that when using the above methods, i do not get any failures, however the hash dosent get updated at all. I have added few log statements to show this:-

log "[#{role}][#{recipe_name}][#{app_name}]: app_params.keys is #{app_params.keys}"
log "[#{role}][#{recipe_name}][#{app_name}]: app_params is #{JSON.pretty_generate(app_params)}"

* log[[my-role][my-recipe][my-pkgName]: app_params.keys is ["app_name", "full_path", "action"]] action write
* log[[my-role][my-recipe][my-pkgName]: app_params is {
   "app_name": "my-pkgName",
   "full_path": "https://myArtifactRepo/.../.../../my-pkgName.msi",
   "action": "install"
}] action write

## ^^ hash keys and hash values (app_params.keys and app_params) BEFORE the force_override method is used 

log "[#{role}][#{recipe_name}][#{app_name}]: app_params.keys is #{app_params.keys}"
log "[#{role}][#{recipe_name}][#{app_name}]: app_params is #{JSON.pretty_generate(app_params)}"

* log[[my-role][my-recipe][my-pkgName]: app_params.keys is ["app_name", "full_path", "action"]] action write
* log[[my-role][my-recipe][my-pkgName]: app_params is {
   "app_name": "my-pkgName",
   "full_path": "https://myArtifactRepo/.../.../../my-pkgName.msi",
   "action": "install"
}] action write

## ^^ hash keys and hash values (app_params.keys and app_params) AFTER the force_override method is used 

Note that the hash and hash key values has not been updated it is still,

["app_name", "full_path", "action"]; 

however we would expect

["app_name", "full_path", "action", "product_guid"] 

and the hash itself like,

"app_name": "my-pkgName",
"full_path": "https://myArtifactRepo/.../.../../my-pkgName.msi",
"action": "install",
"product_guid" : XXXXYYY-0WRR-1234-ABCD-3ERDFR234GRT
maverick
  • 266
  • 4
  • 18
  • 1
    If the hash in question is `app_params`, then its just a variable in the recipe. Its not so clear how it is related to a node attribute. I think you should update the relevant resource in the question. – seshadri_c Oct 06 '21 at 08:30
  • agreed, that app_params is just a local variable in the recipe. In that case ```app_params.merge!({ :product_guid => 'guid' })``` should have worked? any other alternate as how to update the k-v pair to an existing hash? – maverick Oct 06 '21 at 10:37
  • in addition, if i try something like ```app_params[:product_guid] = 'guid'```, it fails with error message ```Chef::Exceptions::ImmutableAttributeModification ------------------------------------------------ Node attributes are read-only when you do not specify which precedence level to set. To set an attribute use code like `node.default["key"] = "value"' ```. So why is it considering it as a node attribute – maverick Oct 06 '21 at 12:01
  • 1
    I suspect you are running into compile/converge sequence as explained in the this [answer](https://stackoverflow.com/a/26000270/13968097). Behaviour of variable assignment will differ depending on where the variable is being modified (in compile or converge phase). – seshadri_c Oct 06 '21 at 12:26
  • 1
    thanks @seshadri_c. Although i tried extracting the node hash, and accordingly assign the k-v pair to the hash, it failed during compile time. Although your suggestion gave me an idea to manipulate the hash at local run time rather than manipulate the node attributes, finally this is what worked, ``` new_app_params = app_params # assign the existing has to a new variable app_params ={} # empty out the existing hash app_params = new_app_params.merge({"product_guid" => guid}) # hydrate the existing old hash to the value of exsting hash + new k-v pair ``` – maverick Oct 06 '21 at 18:47

0 Answers0