Meet "uninitialized constant #<Class:0x8d78f18>::Chef::Resource::CookbookFile" when running chef-client - ruby

I am using Chef 11.10.0.
I implement a new resource called MyCookbookFile which inherits Chef::Resource::CookbookFile.
And, I am not going to change the provider this moment (So Chef::Provider::CookbookFile will be used).
require 'chef/resource/cookbook_file'
require 'chef/mixin/securable'
class Chef
class Resource
class MyCookbookFile < Chef::Resource::CookbookFile
include Chef::Mixin::Securable
provides :my_cookbook_file, :on_platforms => :all
# more codes here...
end
end
end
I met the following error:
================================================================================
Recipe Compile Error in /var/chef/cache/cookbooks/my-cookbook/resources/my_cookbook_file.rb
================================================================================
NameError
---------
uninitialized constant #<Class:0x8d78f18>::Chef::Resource::CookbookFile
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/my-cookbook/resources/my_cookbook_file.rb:6:in `<class:Resource>'
/var/chef/cache/cookbooks/my-cookbook/resources/my_cookbook_file.rb:5:in `<class:Chef>'
/var/chef/cache/cookbooks/my-cookbook/resources/my_cookbook_file.rb:4:in `class_from_file'
Relevant File Content:
----------------------
/var/chef/cache/cookbooks/my-cookbook/resources/my_cookbook_file.rb:
1: require 'chef/resource/cookbook_file'
2: require 'chef/mixin/securable'
3:
4: class Chef
5: class Resource
6>> class MyCookbookFile < Chef::Resource::CookbookFile
Running handlers:
[2014-02-17T08:16:26+00:00] ERROR: Running exception handlers
Running handlers complete
[2014-02-17T08:16:26+00:00] ERROR: Exception handlers complete
[2014-02-17T08:16:26+00:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
Chef Client failed. 0 resources updated in 1.189243344 seconds
[2014-02-17T08:16:26+00:00] ERROR: uninitialized constant #<Class:0x8d78f18>::Chef::Resource::CookbookFile
[2014-02-17T08:16:26+00:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
I tried to print and check the LOAD_PATH in my cookbook. It includes:
/opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.10.0/bin/../lib
And the library should be in place:
[root#localhost /]$ ll /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.10.0/lib/chef/resource/cookbook_file.rb
-rw-r--r-- 1 root root 1598 Feb 6 17:22 /opt/chef/embedded/lib/ruby/gems/1.9.1/gems/chef-11.10.0/lib/chef/resource/cookbook_file.rb

You should add :: before Chef::Resource::CookbookFile.
class MyCookbookFile < ::Chef::Resource::CookbookFile
And move your my_cookbook_file.rb to libraries folder of the cookbook, since you use pure Ruby and not LWRP syntax.

Change:
class MyCookbookFile < Chef::Resource::CookbookFile
to:
class MyCookbookFile < ::Chef::Resource::CookbookFile

Related

inspec resources not identified

i am using inspec test framework with ruby for infrastructure testing. I have written a test in the controls
Here is my test:
require 'aws-sdk'
credentials = Aws::AssumeRoleCredentials.new(
role_arn: 'some_value',
role_session_name: 'pipeline')
client_params = {
region: 'ap-southeast-2',
credentials: credentials
}
ec2_client = Aws::EC2::Resource.new(client_params)
instance = ec2_client.instances(filters: [{name:'tag:component', values: ['api', 'fxsnet', 'admin']}])
puts "ec2 Client is : #{ec2_client}"
puts "list of instances based on tag is: #{instance}"
instance.each do |i|
puts 'ID: ' + i.id
puts 'State: ' + i.state.name
#for each of the instance check if tmp file exist
describe file('/tmp') do # The actual test
it { should exist }
end
end
but on execution, i get below error
An error occurred while loading ./inspec-infra-tests/controls/apiInstances.rb.
Failure/Error:
describe file('/tmp') do # The actual test
it { should exist }
end
NoMethodError:
undefined method `file' for main:Object
Did you mean? fail
# ./inspec-infra-tests/controls/apiInstances.rb:46:in `block in <top (required)>'
# ./inspec-infra-tests/controls/apiInstances.rb:35:in `<top (required)>'
No examples found.
0 examples, 0 failures, 0 passed
file InSpec audit resource to test all system file types, including files, directories, symbolic links, named pipes, sockets etc..
#InspecWithRuby #inspec #inspecResourcesNotIdentified #InspecResourcesNotFound
It looks to me like you are attempting to run an inspec test by executing with ruby rather then running with inspec exec. I can reproduce locally by pasting your test in a file:
inspec_example.rb
describe file('/tmp') do # The actual test
it { should exist }
end
Executing with ruby directly
ruby inspec_example.rb gives:
Traceback (most recent call last):
inspec_example.rb:1:in `<main>': undefined method `file' for main:Object (NoMethodError)
Did you mean? fail
Executing with inspec exec works as expected:
inspec exec inspec_example.rb gives:
Profile: tests from inspec_example.rb (tests from inspec_example.rb)
Version: (not specified)
Target: local://
File /tmp
✔ should exist
I'm not familiar with the AWS SDK, but it you want to test for a set of files using InSpec, you can do so like this:
myfiles = %w(temp.err temp.out)
control 'tmp-files-1' do
title 'Test for a set of temp files.'
myfiles.each do |myfile|
describe file('/tmp/' + myfile) do
it { should exist }
end
end
end
If you execute this control, it will return the following (assuming that these files actually exist in your /tmp folder:
✔ tmp-files-1: Test for a set of temp files.
✔ File /tmp/temp.err should exist
✔ File /tmp/temp.out should exist
I'm hoping you can take this example and adapt it to your AWS needs.

Unable to add cookbook dependency in metadata.rb chef

I am trying to include my abc-cookbook which has a ruby service installed in metadata.rb of another cookbook (say xyz-cookbook) which i have to launch.
But while deploying the instance in opswork my setup is failing with an error as :
STDERR: Unable to satisfy constraints on package abc-cookbook, which does not exist, due to solution constraint (xyz-cookbook = 0.1.0). Solution constraints that may result in a constraint on abc-cookbook: [(xyz-cookbook = 0.1.0) -> (abc-cookbook >= 0.0.0)]
Missing artifacts: abac-cookbook
Demand that cannot be met: (xyz-cookbook = 0.1.0)
Unable to find a solution for demands: activemq (1.3.3), apacheds (0.1.0), apt (
---- End output of /opt/aws/opsworks/local/bin/berks vendor /opt/aws/opsworks/current/berkshelf-cookbooks ----
Ran /opt/aws/opsworks/local/bin/berks vendor /opt/aws/opsworks/current/berkshelf-cookbooks returned 106
Cookbook Trace:
---------------
/var/lib/aws/opsworks/cache.stage1/cookbooks/opsworks_commons/libraries/shellout.rb:9:in `shellout'
/var/lib/aws/opsworks/cache.stage1/cookbooks/opsworks_berkshelf/providers/runner.rb:13:in `block (3 levels) in class_from_file'
Resource Declaration:
---------------------
# In /var/lib/aws/opsworks/cache.stage1/cookbooks/opsworks_berkshelf/providers/runner.rb
11: ruby_block 'Install the cookbooks specified in the Berksfile and their dependencies' do
12: block do
13: Chef::Log.info OpsWorks::ShellOut.shellout(
14: berks_install_command,
15: :cwd => ::File.dirname(OpsWorks::Berkshelf.berksfile),
16: :environment => {
17: "BERKSHELF_PATH" => Opsworks::InstanceAgent::Environment.berkshelf_cache_path,
18: "LC_ALL" => "en_US.UTF-8"
19: }
20: )
21:
22: ::FileUtils.rm_rf Opsworks::InstanceAgent::Environment.berkshelf_cache_path
23: end
24:
25: only_if do
26: OpsWorks::Berkshelf.berkshelf_installed? && OpsWorks::Berkshelf.berksfile_available?
27: end
28: end
29: end
Compiled Resource:
------------------
# Declared in /var/lib/aws/opsworks/cache.stage1/cookbooks/opsworks_berkshelf/providers/runner.rb:11:in `block in class_from_file'
ruby_block("Install the cookbooks specified in the Berksfile and their dependencies") do
action "run"
retries 0
retry_delay 2
block_name "Install the cookbooks specified in the Berksfile and their dependencies"
cookbook_name "opsworks_berkshelf"
block #<Proc:0x0055813e8bcb70#/var/lib/aws/opsworks/cache.stage1/cookbooks/opsworks_berkshelf/providers/runner.rb:12>
only_if { #code block }
end
[2016-01-08T12:33:45+00:00] INFO: Running queued delayed notifications before re-raising exception
[2016-01-08T12:33:45+00:00] ERROR: Running exception handlers
[2016-01-08T12:33:45+00:00] ERROR: Exception handlers complete
[2016-01-08T12:33:45+00:00] FATAL: Stacktrace dumped to /var/lib/aws/opsworks/cache.stage1/chef-stacktrace.out
[2016-01-08T12:33:45+00:00] ERROR: ruby_block[Install the cookbooks specified in the Berksfile and their dependencies] (/var/lib/aws/opsworks/cache.stage1/cookbooks/opsworks_berkshelf/providers/runner.rb line 11) had an error: Mixlib::ShellOut::ShellCommandFailed
Also I have added the dependency in xyz-cookbook metadata.rb as :
name 'xyz-cookbook'
maintainer ''
maintainer_email ''
license 'All rights reserved'
description 'Installs/Configures create'
long_description 'Installs/Configures create'
version '0.1.0'
depends 'abc-cookbook'
What am I missing and what is the error actually..
I did resolve this by adding dependency in my root Berksfile, which i missed even though i included my cookbook in another custom cookbook.
This helped me :
Important
Do not declare cookbooks by including a metadata line in your
Berksfile and declaring the cookbook dependencies in metadata.rb. For
this to work correctly, both files must be in the same directory. With
AWS OpsWorks, the Berksfile must be in the repository's root
directory, but metadata.rb files must be in their respective cookbook
directories. You should instead explicitly declare external cookbooks
in the Berksfile

Why is my test double not expecting the command I allowed?

I have some code which makes shellout calls to the Linux OS, which will run distro-specific commands. I'm trying to ensure the tests can be run on any system, so am using a test double for the Mixlib::ShellOut call. Here's a simplified version that replicates my issue:
require 'mixlib/shellout'
class SelinuxCommand
def run
runner = Mixlib::ShellOut.new('getenforce')
runner.run_command
end
end
My test stubs Mixlib:ShellOut.new returning a test double, and then says that :run_command should return the string 'Enforcing':
require 'rspec'
require_relative 'selinuxcommand'
describe SelinuxCommand do
it 'gets the Selinux enforcing level' do
command = SelinuxCommand.new
Mixlib::ShellOut.stub(:new).and_return(double)
allow(double).to receive(:run_command).and_return('Enforcing')
expect command.run.to eql 'Enforcing'
end
end
However, when I run the test I see:
$ rspec -fd selinuxcommand_spec.rb
SelinuxCommand gets the Selinux enforcing level (FAILED - 1)
Failures:
1) SelinuxCommand gets the Selinux enforcing level
Failure/Error: expect command.run.to eql 'Enforcing'
Double received unexpected message :run_command with (no args)
# ./selinuxcommand.rb:5:in `run'
# ./selinuxcommand_spec.rb:9:in `block (2 levels) in <top (required)>'
Finished in 0.00197 seconds 1 example, 1 failure
Failed examples:
rspec ./selinuxcommand_spec.rb:5 # SelinuxCommand gets the Selinux enforcing level
I don't understand why the double doesn't expect :run_command when I explicitly set it up to expect that. What have I missed?
It is just because every time you call double you get a different object, so the object allowed to receive the run_command method is not the same object returned by the stubbed new. You can fix it like this:
it 'Gets the Selinux enforcing level' do
runner = double
Mixlib::ShellOut.stub(:new).and_return(runner)
expect(runner).to receive(:run_command).and_return('Enforcing')
expect(subject.run).to eq('Enforcing')
end
Can't check now but it seems to me that you need stub :initialize method - not :new.
Try this variant:
Mixlib::ShellOut.stub(:initialize).and_return(double)

Build extension spree e-commerce

I'm with one problem when executed the step 5.7. In my extension not metting the path:
#lib/spree/flag_promotion_configuration.rb.
I must create the directory 'spree' and after create the file 'flag_promotion_configuration.rb' ?
If I write this in the file, as the tutorial required:
#lib/spree_flag_promotions/engine.rb
module Spree::ActiveShipping; end
....
module SpreeFlagPromotions
class Engine < Rails::Engine
initializer "spree.flag_promotions.preferences", :after => "spree.environment" do |app|
Spree::FlagPromotions::Config = Spree::FlagPromotionConfiguration.new
end
....
end
end
And I executed:
$ rake db:migrate
Return this error:
rake aborted!
uninitialized constant Spree::FlagPromotions
Tasks: TOP => db:migrate => environment
(See full trace by running task with --trace)
I believe it has anything to do with:
#lib/spree/flag_promotion_configuration.rb.
Because they do not know where to create this file is or where.

how to troubleshoot Object.const_get failing in rake but not in console?

I have these lines of code that I use as a Factory to create objects:
class ServiceProcessor
def self.create(service, logger)
classified_name = service.name.to_s.split('_').collect! { |w| w }.join << "Processor"
logger.warn "Creating service proc, classified name: #{classified_name}"
service_proc = Object.const_get(classified_name).new
... check respond_to etc.
return service_proc
The first line might be odd, it needs to be refactored. I can use these lines to create various Processors:
class AlphaProcessor < ServiceProcessor
class BetaProcessor < ServiceProcessor
etc...
So these processors can be created in my specs and via the console. They can be created in rake as well -- but only some of them. Two of them are failing:
WARN 2012-01-27 08:54:18 -0800 (25626) Creating service proc,
classified name: AlphaProcessor
ERROR 2012-01-27 08:54:18 -0800 (25626)
Failed for service #<Service _id: 4f203c171d41c83b3b000003, _type: nil,
deleted_at: nil, name: "Alpha", enabled: true>
ERROR 2012-01-27 08:54:18
-0800 (25626) Exception: uninitialized constant AlphaProcessor ERROR
2012-01-27 08:54:18 -0800 (25626) Backtrace:
["/mnt/hgfs/kodiak/lib/service_processors/_service_processor.rb:33:in
`const_get'",
"/mnt/hgfs/kodiak/lib/service_processors/_service_processor.rb:33:in
`create'", "/mnt/hgfs/kodiak/lib/update_engine.rb:28:in `block in
update_all'",
So the question is, how should I go about figuring out why these two (out of 9) would fail, but only in Rake? I can see that Rake and the Console are loading the same environment (a few puts in the environment.rb), so I doubt that's it. I'm stumped on what could be causing this or where to look.
Have you tried adding a Kernel#require to the top of your rake file to load the proper classes? Also, how are you defining the rake task? I've been able to do this for pulling in my class constants:
task :my_task => :environment do
...
end
Also, check your filenames. Make sure that a class named "AlphaBravoTangoProcessor" is in a file named 'alpha_bravo_tango_processor.rb', not a file named 'alphabravotango_processor.rb'.

Resources