chef template variable #node seems to throw error - ruby-on-rails

I'm going through peepcode's Chef tutorial, so far so good. For some reason there is a failure when using template variables. The example is for nginx.
In the nginx/attributes/nginx.rb I have:
default[:nginx][:worker_processes] = 4
In the nginx.conf.erb template I refer to:
worker_processes <%= #node[:nginx][:worker_processes] %>;
Below is the error I get running chef-solo:
Template Context:
-----------------
on line #2
1: user www-data;
2: worker_processes <%= #node[:nginx][:worker_processes] %>;
3:
4: error_log /var/log/nginx/error.log;
5: pid /var/run/nginx.pid;
[2013-07-14T19:46:36+02:00] ERROR: Running exception handlers
[2013-07-14T19:46:36+02:00] ERROR: Exception handlers complete
Chef Client failed. 0 resources updated
[2013-07-14T19:46:36+02:00] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[2013-07-14T19:46:36+02:00] FATAL: Chef::Mixin::Template::TemplateError: undefined method `[]' for nil:NilClass
Other part of the error output:
Starting Chef Client, version 11.4.4
Compiling Cookbooks...
Converging 3 resources
Recipe: nginx::default
* package[nginx] action install (up to date)
* service[nginx] action enable (up to date)
* service[nginx] action start (up to date)
* template[/etc/nginx/nginx.conf] action create
================================================================================
Error executing action `create` on resource 'template[/etc/nginx/nginx.conf]'
================================================================================
Chef::Mixin::Template::TemplateError
------------------------------------
undefined method `[]' for nil:NilClass
Resource Declaration:
---------------------
# In /cookbooks/nginx/recipes/default.rb
8: template "/etc/nginx/nginx.conf" do
9: notifies :reload, "service[nginx]"
10: end
Compiled Resource:
------------------
# Declared in /cookbooks/nginx/recipes/default.rb:8:in `from_file'
template("/etc/nginx/nginx.conf") do
provider Chef::Provider::Template
action "create"
retries 0
retry_delay 2
path "/etc/nginx/nginx.conf"
backup 5
source "nginx.conf.erb"
cookbook_name :nginx
recipe_name "default"
end

You can access object variables (the ones that start with #) in templates, only if you passed them through variables method of template like that:
template("/etc/nginx/nginx.conf") do
[...]
variables( :my_var => node )
[...]
end
Then you will have #my_var available in template. But you don't have to pass the node, because it is already available in templates. You just have to access it not as an object variable. The following code in template should work.
<%= node[:nginx][:worker_processes] %>
Just remove the # from the front of node.

The node object is not accessible via an instance variable (the thing starting with an # sign). Instead, it is a method in the current context.
Change:
<%= #node[:nginx][:worker_processes] %>
to
<%= node[:nginx][:worker_processes] %>
Notice the removal of the #-sign? You only need the #-sign when passing in variables to the template via the variables parameter.

Related

STORYBLOK, RUBY: undefined method `[]' for nil:NilClass (NoMethodError)

I don't know that much about RUBY, just thought that you guys might help me with this. I'm using Storyblok as my headless CMS and JEKYLL when I'm building serve it this is the error that I got;
33: from C:/project/test/_plugins/storyblok_generator.rb:8:in `generate'
32: from C:/project/test/_plugins/storyblok_cms/generator.rb:12:in `generate!'
C:/project/test/vendor/cache/ruby/2.7.0/gems/storyblok-3.0.1/lib/storyblok/client.rb:354:in `block (2 levels) in find_and_fill_links': undefined method `[]' for nil:NilClass (NoMethodError)
the code below is from _plugins/storyblok_cms/generator.rb
def generate!
timestamp = Time.now.to_i
links = client.links(cv: timestamp)['data']['links']
stories = client.stories(per_page: 100, page: 1, cv: timestamp)['data']['stories'] #line 12
stories.each do |story|
# create all pages except global (header,footer,etc.)
content_type = story['content']['component']
if content_type != 'shared'
site.pages << create_page(site, story, links)
end
rescue UnknownContentTypeError => e
# for production, raise unknown content type error;
# for preview and other environments, issue an warning only since the content_type might be available
# but the code handling that content type might be in a different branch.
Jekyll.env == 'production' ? raise : Jekyll.logger.warn(e.message)
end
site.data['stories'] = stories
site.data['articles'] = stories.select { |story| story['full_slug'].start_with?('articles') }
site.data['shared'] = stories.select { |story| story['full_slug'].start_with?('shared') }
end
the code below is from _plugins/storyblok_generator.rb
require "storyblok"
module Jekyll
class StoryblokGenerator < Jekyll::Generator
safe true
def generate(site)
StoryblokCms::Generator.new(site).generate! #line 8
end
end
end
Additional Info:
ruby version: ruby 2.7.4p191 (2021-07-07 revision a21a3b7d23) [x64-mingw32]
jekyll version: jekyll 4.2.1
OS: Windows 10
I've actually found the solution to this, So this error occurs because I have created a page template in Block Library in Storyblok and then firing bundle exec jekyll serve command in terminal without creating the page template source/file in my project directory.
So I have an about_us block (content-type) in Block Library created and then when I fire bundle exec jekyll serve without creating an about_us.html first in _layouts folder, It would trigger the error.
Solution;
Make sure to create the source/file first in the _layouts folder if you have created a block (content-type) in block library.

LoadError Unable to autoload constant ( Rails Engine )

Whenever i hit the endpoints (example: greet ) exposed by rails engine i receive this error.
Error:
"LoadError(Unable to autoload constant TestingController,
expected /local_path/app/controllers/testing_controller.rb to define it):
/Users/xxxxx/.rvm/gems/ruby-2.5.1/gems/activesupport-5.2.1/lib/active_support/
dependencies.rb:507:in `load_missing_constant'"
Engine:
I have an engine with action method greet defined as below
# type: class
# path: app/controllers/testing_controller.rb
# file name: testing_controller.rb
module Parent
module Child
class TestingController < ApplicationController
def initialize
#name = 'BOB'
end
def greet
render json: {'hi': 'hi', 'name': #name}
end
end
end
end
routes defined as
# type: route
# path: app/config/routes.rb
# file name: routes.rb
Parent::Child::Engine.routes.draw do
get 'greet', to: 'testing#greet', as: :greet
end
Details:
This engine has been mounted to a gem ABC which is then used in the rails app called Example. When i hit the greet route in the app via
http://localhost:3000/greet for the first time i receive LoadError.
However if i refresh the page it renders the
json as expected. {"hi":"hi","name":"BOB"}.
we have development.rb (app/config/env/) has cache and eager load defined as below
config.cache_classes = false
config.eager_load = false
Ruby: 2.5.1
Rails: 5.2.1
Thanks for your help, much appreciated.
The message seems to be coming from the expectation that in the root level of the file testing_controller.rb has a definition of a TestingController class whilst you have that class defined nested within Parent::Child:: modules.
I guess that if you put your testing_controller.rb file in the following path: app/controllers/parent/child/testing_controller.rb the error will disappear.

Rails.application.assets_manifest.find_sources("#{params[:controller]}.js").any? crashes on Heroku

in my application_layout.html.rb of my rails application I'm loading controller specific javascript:
<%= javascript_include_tag params[:controller] if Rails.application.assets_manifest.find_sources("#{params[:controller]}.js").any? %>
Which is working correctly until I deploy to Heroku. Than I get this error:
ActionView::Template::Error (undefined method `find_asset' for nil:NilClass)
The same error I get when I try to call any method on the object returned from #find_sources.
EDIT:
<%= Rails.application.assets_manifest.find_sources("#{params[:controller]}.js") %>
returns #<Enumerator:0x007fda655a17b0>
Any idea?
Thanks
It does not work because there is a static manifest file in production and no in development (usually, it depends on environment config). You can create a helper method to do the check differently based on current environment configuration:
def asset_exist?(path)
if Rails.configuration.assets.compile
Rails.application.precompiled_assets.include? path
else
Rails.application.assets_manifest.assets[path].present?
end
end
Please check this issue for more details.

Additional html.erb file in View not Working in ruby on rails

I have a database I created in ruby on rails which automatically created some of the needed files but when I manually added an additional file in the views folder and try to access it in my browser .
This error appears
Routing Error
No route matches [GET] "/second/count"
Try running rake routes for more information on available routes.
I tried to correct this by putting a number sign in the routes.rb
Community::Application.routes.draw do
#resources :seconds
match ':controller(/:action(/:id))', :via => :get
The file I just created worked but then the files automatically created won't.
This error appears
NameError in Seconds#index
Showing c:/Sites/Community/app/views/seconds/index.html.erb where line #25 raised:
undefined local variable or method `new_second_path' for #<#<Class:0x456ee80>:0x37b9a98>
Extracted source (around line #25):
22:
23: <br />
24:
25: <%= link_to 'New Second', new_second_path %>
Rails.root: c:/Sites/Community
Application Trace | Framework Trace | Full Trace
app/views/seconds/index.html.erb:25:in `_app_views_seconds_index_html_erb__742794588_29296056'
app/controllers/seconds_controller.rb:7:in `index'
Request
Parameters:
None
Show session dump
Show env dump
Response
Headers:
None
For the helper new_second_path to work, you have to uncomment the line resources :seconds in the routes.
Unless you know what you are doing, I would comment the line match ... which is a catch-all.
Also: a path /second/count will not work, it should be /seconds/count. To explain this:
/second/count: with your match it will look for SecondController (singular!!) and action count
But the clean way to handle is to write:
resources :seconds do
collection do
get :count
end
end
This will allow you to write count_seconds_path in your view, which will render the correct link (/seconds/count).

Undefined method `checksum' for Chef::Resource::Directory

While running a recipe for Pyramid, the following is failing in chef-solo:
================================================================================
Error executing action `create` on resource 'directory[/etc/service/pyramid/supervise/status]'
================================================================================
NoMethodError
-------------
undefined method `checksum' for Chef::Resource::Directory
Resource Declaration:
---------------------
# In /var/chef-solo/cookbooks/project/recipes/pyramid.rb
22: directory "#{node['runit']['service_dir']}/pyramid#{dir}/supervise/#{f}" do
23: owner login
24: group login
25: end
26: end
Compiled Resource:
------------------
# Declared in /var/chef-solo/cookbooks/project/recipes/pyramid.rb:22:in `block (2 levels) in from_file'
directory("/etc/service/pyramid/supervise/status") do
provider Chef::Provider::Directory
action :create
retries 0
retry_delay 2
path "/etc/service/pyramid/supervise/status"
cookbook_name :project
recipe_name "pyramid"
owner "myusername"
group "myusername"
mode 420
end
Why is this getting "undefined method checksum" and what can I do about it?
This error doesn't appear to be consistent. Sometimes the chef run appears to hang. Other times, after multiple runs, chef is able to pass this point.
I'm running on a vanilla Ubuntu server 12.04LTS with chef installed with a deploy script:
sudo apt-get install -y ruby1.9.1 ruby1.9.1-dev make &&
sudo gem1.9.1 install chef ohai --no-rdoc --no-ri
This is the full Pyramid recipe:
login = node["user"]["login"]
home = node["user"]["home"]
app_root = node["user"]["app_root"]
runit_service "pyramid" do #, :template_name => "site" do
template_name "pyramid"
owner login
group login
options({
:login => login,
:app_root => app_root,
:home => home,
:config => "#{app_root}/config/gunicorn.conf.py"
})
end
["", "/log"].each do |dir|
directory "#{node['runit']['service_dir']}/pyramid#{dir}/supervise" do
mode "0755"
end
%w(ok control status).each do |f|
directory "#{node['runit']['service_dir']}/pyramid#{dir}/supervise/#{f}" do
owner login
group login
end
end
end
This was my solution - found after some hacking around plus the tip from #Draco-ater...
Where the recipe referenced directory("/etc/service/pyramid/supervise/status"), the status 'directory' is a file that already exists which was causing issues.
In addition, the script also tried to update the control and ok pipes as directories - which was also failing. I solved this by using bash and chmod:
bash "give_perms_pyramid" do
user "chef"
cwd "#{node['runit']['service_dir']}/pyramid#{dir}/supervise"
code <<-EOH
sudo chown myuser:root control
sudo chmod g+rw control
EOH
Maybe that will help someone.

Resources