Ruby Uninitialized Constant Error when Inheriting in Chef - ruby

In my LWRP extending a supermarket cookbook, I got the following working.
module PIWebsphereCookBook
class WebsphereJbdc < WebsphereCookBook::WebsphereBase
Whereas when I introduced my own class in between these 2, I am getting the 'Unitialized Constant Error'
require_relative './pi_websphere_base'
module PIWebsphereCookBook
class WebsphereJbdc < PIWebsphereBase
The base class I am trying to extend is as shown below:
module PIWebsphereCookBook
class PIWebsphereBase < WebsphereCookbook::WebsphereBase
I see from the logs that the referenced class/file is being loaded
[2017-06-23T18:37:28-04:00] DEBUG: Loading cookbook pi_websphere's resources from /var/chef/cache/cookbooks/pi_websphere/resources/pi_websphere_base.rb
[2017-06-23T18:37:28-04:00] DEBUG: Loaded contents of /var/chef/cache/cookbooks/pi_websphere/resources/pi_websphere_base.rb into resource pi_websphere_pi_websphere_base (Custom resource pi_websphere_pi_websphere_base from cookbook pi_websphere)
[2017-06-23T18:37:28-04:00] DEBUG: Loading cookbook pi_websphere's resources from /var/chef/cache/cookbooks/pi_websphere/resources/websphere_j2c.rb
[2017-06-23T18:37:28-04:00] DEBUG: Loaded contents of /var/chef/cache/cookbooks/pi_websphere/resources/websphere_j2c.rb into resource pi_websphere_websphere_j2c (Custom resource pi_websphere_websphere_j2c from cookbook pi_websphere)
[2017-06-23T18:37:28-04:00] DEBUG: Loading cookbook pi_websphere's resources from /var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb
[2017-06-23T18:37:28-04:00] DEBUG: Filtered backtrace of compile error: /var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:3:in `<module:PIWebsphereCookBook>',/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:2:in `class_from_file'
[2017-06-23T18:37:28-04:00] DEBUG: Backtrace entry for compile error: '/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:3:in `<module:PIWebsphereCookBook>''
[2017-06-23T18:37:28-04:00] DEBUG: Line number of compile error: '3'
Recipe Compile Error in
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb
NameError
---------
uninitialized constant #
<Class:0x000000052796d8>::PIWebsphereCookBook::PIWebsphereBase
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:3:in ` <module:PIWebsphereCookBook>'
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:2:in ` class_from_file'
Relevant File Content:
----------------------
/var/chef/cache/cookbooks/pi_websphere/resources/websphere_jdbc.rb:
1: require_relative './pi_websphere_base'
2: module PIWebsphereCookBook
3>> class WebsphereJbdc < PIWebsphereBase
4: require_relative 'helper'
5:
The folder structure is given below
[root#localhost pi_websphere]# tree
.
├── attributes
│   └── default.rb
├── Gemfile
├── jaas_auth.py
├── libraries
│   ├── abc.rb
│   ├── artifactory_helper.rb
│    ├── pi_websphere_base.rb
│   └── websphere_base.rb
├── metadata.rb
├── README.md
├── resources
│   ├── artifactory_client.rb
│   ├── helper.rb
│   ├── websphere_j2c.rb
│   ├── websphere_jdbc.rb

You need to make sure the file containing PIWebsphereBase is loaded first. Normally cookbook library files are loaded in ASCII-betical order, but you can force things a little more with the require_relative you have there but is commented out. You probably want require_relative './pi_websphere_base' or something like that, or tweak the filenames.

Related

Automatic Ansible custom modules installation with Ansible Galaxy

Is there any nice way to use Ansible Galaxy order to install and enable Ansible (2.7.9) custom modules?
My requirement allows Ansible Galaxy to download the right Ansible role which embeds my custom module. Once ansible-galaxy install --roles-path ansible/roles/ -r roles/requirements.yml, I get the following structure (non-exhaustive):
├── ansible
│   ├── roles
│   │   ├── mymodule (being imported by Galaxy)
│   │   │   ├── library
│   │   │   │   └── mymodule.py
By looking this part of the documentation, it seems like my module is at the right place and does not require any further configuration: https://docs.ansible.com/ansible/latest/user_guide/playbooks_best_practices.html?highlight=library#directory-layout
But when I found this part of the documentation I got confused. Is ANSIBLE_LIBRARY related to the custom modules?
DEFAULT_MODULE_PATH
Description: Colon separated paths in which Ansible will search for Modules.
Type: pathspec
Default: ~/.ansible/plugins/modules:/usr/share/ansible/plugins/modules
Ini Section: defaults
Ini Key: library
Environment: ANSIBLE_LIBRARY
https://docs.ansible.com/ansible/latest/reference_appendices/config.html#default-module-path
When calling my module,
- name: Test of my Module
mymodule:
I get the following error:
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
I expected not to have to configure the ANSIBLE_LIBRARY and the module being automatically callable. Am I understanding correctly or should I also trick this var?
If your custom module is in a role, you need to include the role in your playbook, so at the very least:
---
- hosts: myhosts
roles:
- role: mymodule
tasks:
- name: Test of my Module
mymodule:

Trouble with chef-solo "Missing Cookbooks"

I am trying to run chef-solo, and I have the following configuration
/var/chef
├── cookbooks
│   ├── cc_db
│   │   ├── Berksfile
│   │   ├── Berksfile.lock
│   │   ├── chefignore
│   │   ├── metadata.rb
│   │   ├── recipes
│   │   │   └── default.rb
├── node.json
└── solo.rb
node.json
{
"run_list": [ "recipe[cc_db]" ]
}
solo.rb
file_cache_path "/var/chef"
cookbook_path "/var/chef/cookbooks"
json_attribs "/var/chef/node.json"
metadata.rb
depends 'database', '~> 5.1.2'
depends 'mysql2_chef_gem', '~> 1.0'
I've gotten this to work in a kitchen-test environment, but I'm trying it now on a different server using chef-solo.
Whenever I run:
chef-solo -c solo.rb
I get:
resolving cookbooks for run list: ["cc_db"]
================================================================================
Error Resolving Cookbooks for Run List:
================================================================================
Missing Cookbooks:
------------------
No such cookbook: database
Expanded Run List:
------------------
* cc_db
Platform:
---------
x86_64-linux
Running handlers:
[2016-09-20T15:34:05-04:00] ERROR: Running exception handlers
Running handlers complete
[2016-09-20T15:34:05-04:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated in 02 seconds
[2016-09-20T15:34:05-04:00] FATAL: Stacktrace dumped to /var/chef/chef-stacktrace.out
[2016-09-20T15:34:05-04:00] FATAL: Please provide the contents of the stacktrace.out file if you file a bug report
[2016-09-20T15:34:05-04:00] ERROR: 412 "Precondition Failed"
[2016-09-20T15:34:05-04:00] FATAL: Chef::Exceptions::ChildConvergeError: Chef run process exited unsuccessfully (exit code 1)
I'm confused because the database cookbook seem to be installed with berks, but chef isn't picking it up.
any help would be greatly appreciated.
thanks.
myles.
Chef doesn't directly integrate with Berkshelf, so chef-solo knows nothing about that. Normally you would use something like knife-solo which ties them together, but you could also do it manually. Run berks vendor /path/to/a/folder and then set that folder as the cookbook_path.
I ended up just going around the problem.
I set up a chef-server on a virtual host, and do some final level testing on that. I created nodes, bootstrapped them, then ran chef-client on the node.
I also don't have a very large server configuration, so I just uploaded the cookbooks and dependent cookbooks by hands. Which I'm pretty sure is why chef-zero was failing. At some point in the future I will get Berkshelf working in conjunction with everything to help ease the cookbook dependency process.

Compiling and Routing files under bower_component folder in Nanoc

I want to take and put some of the files under bower_components folder. In my web site, bower_components folder tree is as follows:
├── bower_components
│   └── angular
│   ├── README.md
│   ├── angular-csp.css
│   ├── angular.js
│   ├── angular.min.js
│   ├── angular.min.js.gzip
│   ├── angular.min.js.map
│   └── bower.json
I just want to copy the angular.min.js file to the output/bower_components/angular/angular.min.js folder.
For this purpose, I modified the Rules file as below:
compile "/bower_components/*.min.js" do
#item.identifier.chop + '.' + item[:extension]
end
route "/bower_components/*.min.js" do
item.identifier.chop + '.' + item[:extension]
end
When I compile my website, I have the following error:
RuntimeError: Found 4 content files for content/bower_components/angular/angular; expected 0 or 1
Compilation stack:
(empty)
Stack trace:
0. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/data_sources/filesystem.rb:164:in `block in all_split_files_in'
1. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/data_sources/filesystem.rb:154:in `each_pair'
2. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/data_sources/filesystem.rb:154:in `all_split_files_in'
3. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/data_sources/filesystem.rb:78:in `load_objects'
4. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/data_sources/filesystem.rb:37:in `items'
5. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/base/source_data/site.rb:325:in `block in load_items'
6. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/base/source_data/site.rb:324:in `each'
7. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/base/source_data/site.rb:324:in `load_items'
8. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/base/source_data/site.rb:243:in `load'
9. /Users/neva/.rvm/gems/ruby-1.9.3-p448#global/gems/nanoc-3.6.7/lib/nanoc/base/source_data/site.rb:127:in `layouts'
... 27 more lines omitted. See full crash log for details.
What shall be the problem?
Do you have any idea?
Because of the way it maps input filenames onto output paths, Nanoc requires the base name (i.e., the filename less extension) of each file under content to be unique. From Nanoc's perspective you are giving it four files that share the base name angular and thus cannot have unique output paths, so it gives you this error.
Since what you really want is to have Nanoc copy over this portion of your site verbatim, you ought to set up a static data source from which to load it. Then Nanoc will simply copy the files over as-is without attempting to process or rename them. The "Troubleshooting" page on the Nanoc website has instructions on how to do this; see "Solution #2" under "Error: “Found 3 content files for X; expected 0 or 1”.

Simple pattern to export rake tasks defined in gem to the outside world upon installation

This question follows the "Make rake task from gem available everywhere?" for which I'm not fully satisfied with the Railties approach since it induces a dependency on Rails3 which seems to me overkilling compared to what I want.
Also, I dislike the idea to create an extra binary as suggested in this question
So, assuming I have the below layout:
.
├── CHANGELOG.md
├── Gemfile
├── Gemfile.lock
├── LICENCE.md
├── README.md
├── Rakefile
├── my_gem.gemspec
├── lib
│   ├── my_gem
│   │   ├── common.rb
│   │   ├── loader.rb
│   │   ├── tasks
│   │   │   └── sometasks.rake
│   │   └── version.rb
│   └── my_gem.rb
where lib/my_gem/tasks/sometasks.rake has some nested rake tasks definition:
#.....................
namespace :n1 do
#.....................
namespace :n2 do
desc "Tasks n1:n2:t1"
task :t1 do |t|
puts "Task 1"
end
desc "Tasks n1:n2:t2"
task :t2 do |t|
puts "Task 2"
end
end # namespace n1:n2
end # namespace n1
How can I easily share these tasks in another external Rakefile with a simple syntax such as require "my_gem/sometasks" once the gem is installed?
I tested the following configuration in a separate directory with success yet I still think it's a complicated syntax. Any help to simplify the load / include/ require would be welcome:
add a GemFile containing
gem 'my_gem', :path => '~/path/to/my_gem'
add a Rakefile with the following content:
require "my_gem"
load "my_gem/tasks/sometasks.rake"
desk "Test my_gem"
task :toto do |t|
puts "task toto"
end
In the above configuration, it works:
$> bundle exec rake -T
rake n1:n2:t1 # Task n1:n2:t1
rake n1:n2:t1 # Task n1:n2:t2
rake toto # Test my_gem
Yet if I get rid of .rake extension in the Rakefile, I have a load error
rake aborted!
LoadError: cannot load such file -- my_gem/tasks/sometasks
Any hint?
I found a way, inspired from Bundler to offer a simplified interface (and [gem_tasks.rb](https://github.com/bundler/bundler/blob/master/lib/bundler/gem_tasks.rb):
create a file lib/my_gem/sometasks_tasks.rb with an install_tasks method
require 'rake'
module MyGem
class SomeTasks
include Rake::DSL if defined? Rake::DSL
def install_tasks
load 'my_gem/tasks/sometasks.rake'
end
end
end
MyGem::SomeTasks.new.install_tasks
In the application’s Rakefile, it is now enough to add require 'my_gem/sometasks_tasks'

Classes defined in CoffeeScript not found by Jasmine specs

I am building a backbone.js app on a Rails 3.1 back-end. I'm using CoffeeScript to write the backbone classes, and Jasmine (via jasmine-headless-webkit) for testing.
Given the following (partial) tree:
.
├── app
│   ├── assets
│   │   ├── javascripts
│   │   │   └── views
│   │   │   ├── avia_view.js.coffee
├── spec
│   ├── javascripts
│   │   └── views
│   │   └── avia_view_spec.js.coffee
... I would expect avia_view_spec.js.coffee to know about Avia.AviaView, which is defined in avia_view.js.coffee.
However, I get the following output from running bundle exec jasmine-headless-webkit:
Running Jasmine specs...
F
Avia.AviaView render creates a new MatricesView . (/home/duncan/avia/spec/javascripts/views/avia_view_spec.js.coffee:10)
ReferenceError: Can't find variable: Avia in /home/duncan/avia/spec/javascripts/views/avia_view_spec.js.coffee (line ~5)
ReferenceError: Can't find variable: Avia in /home/duncan/avia/spec/javascripts/views/avia_view_spec.js.coffee (line ~10)
My jasmine.yml contains the following:
src_files:
- public/javascripts/prototype.js
- public/javascripts/effects.js
- public/javascripts/controls.js
- public/javascripts/dragdrop.js
- public/javascripts/application.js
- public/javascripts/**/*.js
I think I need to tell Jasmine to load the contents of avia_view.js.coffee but I'm not entirely sure how. Adding an explicit reference in the src_files section in jasmine.yml doesn't seem to make a difference ...
Could someone please tell me what I'm doing wrong here? I suspect it's something simple ...
Without having seen to much of your code, I'd suspect it beacuse of CoffeeScript's function wrapping (docs). You need to ensure that all the symbols you want to use are exported to somewhere you can get at them (here is a thorough discussion about that).
Edit: here's another longish and theoretical but good documentation on this topic.
Try adding this to your avia_view.js.coffee
(exports ? this).Avia = Avia
See this for a detailed explanation.
Alternatively try this;
window.Avia = Avia
We encountered the same problem; I highly recommend JasmineRice

Resources