Question

I'm writing a chef recipe which simply creates a database config file, but I'm stumped simply access the attributes. I have a few PHP applications being deployed to each instance, and OpsWorks uses the same recipes for everyone, so I have a few different settings in the attributes file.

attributes/database-settings.rb

# API
default[:api][:path]      = 'app/config/database.php';
default[:api][:host]      = 'test';
default[:api][:database]  = 'test';
default[:api][:username]  = 'test';
default[:api][:password]  = 'test';

recipes/database-settings.rb

Chef::Log.info("Database settings!");

node[:deploy].each do |application, deploy|

    if node.has_key?(application)
        Chef::Log.info("Application: #{application}");

        path = node["api"]["path"]; # ERROR HAPPENING HERE
        Chef::Log.info("Path: #{path}");

        template path do
            source "database.erb"
            mode 0440
            variables({
               :host     => node["api"]["host"],
               :database => node["api"]["database"],
               :username => node["api"]["username"],
               :password => node["api"]["password"]
            })
        end

    end

end

The error I'm getting is no implicit conversion of String into Integer. I've tried creating and accessing the settings in every way I can think of, such as...

node[:api][:path] # no implicit conversion of Symbol into Integer
node['api']['path'] # no implicit conversion of String into Integer
node[:api].path # undefined method `path' for #<Chef::Node::ImmutableArray:0x007fa4a71086e8>
node[application][:path] # no implicit conversion of Symbol into Integer

I'm sure there's something very obvious I'm doing wrong here, but I've tried everything I can think of an I just can't seem to find any way of getting this to work?! Ideally I'd like to use a variable where I can "api", but using an if/else wouldn't be too terrible for 3 apps...

Was it helpful?

Solution 2

Ok so the problem wasn't really that I was accessing the config wrongly, it was that the different attribute files were all being merged into a single config and I didn't realise this. I had these config files...

attributes/database_settings.rb

default[:api][:path] = 'app/config/database.php';
default[:api][:username] = 'example';

attributes/writable_directories.rb

default[:api] = ['public/uploads', 'storage/cache'];

When I tried to access default[:api][:path] I was actually accessing the array of directories when seemed to override the database settings attributes. Moving these into default[:directories][:api] and default[:database][:api][:path] etc fixed this.

OTHER TIPS

That is a common error seen when you try to access an object thinking it is a hash, but is actually an array. In fact, from one of your errors, it can be read that node["api"] is a Chef::Node::ImmutableArray.

Note that you will also get this error if you accidentally enter a space between "node" and the items indexing it:

node[:foo][:bar]

will work, while

node [:foo][:bar]

will throw this exception. It can be hard to spot.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top