HewlettPackard / oneview-chef

This project is no longer being developed and has limited support. In the near future this repository will be fully deprecated. Please consider using other OneView projects, such as Terraform and Ansible Collection
https://supermarket.chef.io/cookbooks/oneview
Apache License 2.0
17 stars 15 forks source link

Chef-client 13.2.20 does not allow modification of property :save_resource_info #243

Closed vranystepan closed 7 years ago

vranystepan commented 7 years ago

Scenario/Intent

Chef client version 13.2.20 raises following error:

RuntimeError
------------
can't modify frozen Chef::Node::ImmutableArray

Cookbook Trace:
---------------
  <path>/.chef/local-mode-cache/cache/cookbooks/oneview/libraries/oneview_resource_base.rb:20:in `load'
  <path>/.chef/local-mode-cache/cache/cookbooks/oneview/resources/datacenter.rb:12:in `class_from_file'

Relevant File Content:
----------------------
<path>/.chef/local-mode-cache/cache/cookbooks/oneview/libraries/oneview_resource_base.rb:

 13:    # Define default properties for all resources
 14:    module ResourceBaseProperties
 15:      # Loads the default properties for all resources
 16:      def self.load(context)
 17:        context.property :client
 18:        context.property :name, [String, Symbol], required: true
 19:        context.property :data, Hash, default: {}
 20>>       context.property :save_resource_info, [TrueClass, FalseClass, Array], default: context.node['oneview']['save_resource_info']
 21:        context.property :api_version, Integer, default: context.node['oneview']['api_version']
 22:        context.property :api_variant, [String, Symbol], default: context.node['oneview']['api_variant']
 23:        context.property :api_header_version, Integer    # Overrides X-API-Version headers in API requests
 24:        context.property :operation, String              # To be used with :patch action
 25:        context.property :path, String                   # To be used with :patch action
 26:        context.property :value, [String, Array]         # To be used with :patch action
 27:      end
 28:    end
 29:  end

Environment Details

Steps to Reproduce

Upgrade chef-client to the latest version and try to use arbitrary resource. It happens only when you have for example default['oneview']['save_resource_info'] = ['uri', 'status', 'created'] specified in you attributes file. With trueand false everything works fine.

Fix / Workaround

I was able to eliminate this behaviour with following edit in OneviewCookbook::ResourceBaseProperties.load:

 context.property :save_resource_info, [TrueClass, FalseClass, Array], default: context.node['oneview']['save_resource_info'].dup

However TrueClassor FalseClasscan't be dup-ed so there must be some condition i.e.

module OneviewCookbook
  # Define default properties for all resources
  module ResourceBaseProperties
    # Loads the default properties for all resources
    def self.load(context)
      save_res_info_default =
        if context.node['oneview']['save_resource_info'].is_a?(Array)
          context.node['oneview']['save_resource_info'].dup
        else
          context.node['oneview']['save_resource_info']
        end
      context.property :client
      context.property :name, [String, Symbol], required: true
      context.property :data, Hash, default: {}
      context.property :save_resource_info, [TrueClass, FalseClass, Array], default: save_res_info_default
      context.property :api_version, Integer, default: context.node['oneview']['api_version']
      context.property :api_variant, [String, Symbol], default: context.node['oneview']['api_variant']
      context.property :api_header_version, Integer    # Overrides X-API-Version headers in API requests
      context.property :operation, String              # To be used with :patch action
      context.property :path, String                   # To be used with :patch action
      context.property :value, [String, Array]         # To be used with :patch action
    end
  end
end
vranystepan commented 7 years ago

Or something like this:

def safe_dup(e)
  e.dup
rescue TypeError
  e
end

I can see such method here but I don't know whether we can use it ...

jsmartt commented 7 years ago

@ricardogpsf or @tmiotto , do either of you have some time to look into fixing this?