Chef custom resource action properties not working - ruby

I'm having an issue with a custom resource I created in a new cookbook i'm working on. When I do a kitchen converge on the following setup I get the following error:
error: NoMethodError: undefined method `repository_url' for PoiseApplicationGit::Resource
Info about my development machine:
Chef Development Kit Version: 2.1.11
chef-client version: 13.2.20
delivery version: master (73ebb72a6c42b3d2ff5370c476be800fee7e5427)
berks version: 6.3.0
kitchen version: 1.17.0
inspec version: 1.33.1
Here's my custom resource under resources/deploy.rb:
resource_name :opsworks_deploy
property :app_path, String, name_property: true
property :app_name, String, required: true
property :repository_url, String, required: true
property :repository_key, String, required: true
property :short_name, String, required: true
property :app_type, String, required: true
property :app, Object, required: true
property :permission, String, required: true
action :deploy do
apt_update 'update'
# Install NGinx
package 'nginx' do
not_if { ::File.exist?("/etc/init.d/nginx") }
end
# Setup the app directory
directory my_app_path do
owner 'www-data'
group 'www-data'
mode '0755'
recursive true
end
slack_notify "notify_deployment_end" do
message "App #{app_name} deployed successfully"
action :nothing
end
slack_notify "notify_nginx_reload" do
message "Nginx has reloaded"
action :nothing
end
slack_notify "notify_nginx_config" do
message "Nginx site config has been updated for #{app_name}"
action :nothing
end
slack_notify "notify_git_deploy" do
message "App #{app_name} has been checkout out from git"
action :nothing
end
slack_notify "notify_file_permissions" do
message "App #{app_name} has been given proper file permissions"
action :nothing
end
# Deploy git repo from opsworks app
application app_path do
owner 'www-data'
group 'www-data'
git do
user 'root'
group 'root'
repository my_repo_url
deploy_key my_repo_key
notifies :notify, "slack_notify[notify_git_deploy]", :immediately
end
execute "chown-data-www" do
command "chown -R www-data:www-data #{my_app_path}"
user "root"
action :run
notifies :notify, "slack_notify[notify_file_permissions]", :immediately
end
# Setup the nginx config file for the site
template "/etc/nginx/sites-enabled/#{my_short_name}" do
source "#{my_app_type}.erb"
owner "root"
group "root"
mode 0644
variables( :app => my_app )
notifies :notify, "slack_notify[notify_nginx_config]", :immediately
end
# Reload nginx
service "nginx" do
supports :status => true, :restart => true, :reload => true, :stop => true, :start => true
action :reload
notifies :notify, "slack_notify[notify_nginx_reload]", :immediately
end
end
end
Here's my recipe under recipes/default.rb (all variables are set properly and to the proper types, i'm using test data bags and they are correctly passing):
command = search(:aws_opsworks_command).first
deploy_app = command[:args][:app_ids].first
app = search(:aws_opsworks_app, "app_id:#{deploy_app}").first
app_path = "/var/www/" + app[:shortname]
opsworks_deploy app_path do
app_name app[:name]
app_type app[:environment][:APP_TYPE]
repository_url app[:app_source][:url]
repository_key app[:app_source][:ssh_key]
short_name app[:shortname]
app app
permission '0755'
end
The only way I can get it working is if I add this at the top of the action declaration and update the properties within to match:
action :deploy do
my_repo_url = repository_url.dup
my_repo_key = repository_key.dup
my_app_path = app_path.dup
my_app_type = app_type.dup
my_short_name = short_name.dup
my_app = app.dup
...
Any reason why this is the case? Should I have to redeclare them like that in the action?

Use new_resource.repository_url and similar. The magic aliasing doesn't work correctly in a lot of circumstances and we've formally deprecated it as of 13.1 (though it's been not recommended for a while).

Related

Sidekiq - Sinatra - Can't read from my ActiveRecord Objects

For some reason, my sidekiq worker can't read from my ActiveRecord models. Here is my worker class. It fails on line where its trying to read from my User object: name = User.find_by(id: user_id).first_name.
require 'gcm'
module Socio
class RequestNotificationWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(target_token, key)
begin
gcm = GCM.new(key)
registration_ids= [target_token]
options = {notification: {title: "Connection request!", body: "You have a new Socio request.",
sound: "default", badge: 1, type: "1"},
collapse_key: "New Connections", content_available: true, priority: "high"}
gcm.send(registration_ids, options)
{success: true}
rescue => e
{success: false, error: e.to_s}
end
end
end
class ConfirmNotificationWorker
include Sidekiq::Worker
sidekiq_options retry: false
def perform(target_token, key)
begin
gcm = GCM.new(key)
name = User.find_by(id: #user_id).first_name
registration_ids= [target_token]
options = {notification: {title: "Connection Confirmed!", body: "#{name} has accepted your Socio request.",
sound: "default", badge: 1, type: "2"},
collapse_key: "New Connections", content_available: true, priority: "high"}
gcm.send(registration_ids, options)
{success: true}.to_json
rescue => e
{success: false, error: e.to_s}
end
end
end
end
Also here is my procfile:
web: bundle exec thin start -p $PORT
worker: bundle exec sidekiq -c 5 -v -r ./app/sidekiq.rb
And here is the error message:
Failed uninitialized constant Socio::ConfirmNotificationWorker::User
I tried different require and include commands, but couldn't get it to work.
Somewhere inside app/sidekiq.rb you need to require activerecord and user.rb. If you show us your sidekiq.rb it will help.
This is because app/sidekiq is not initializing your application - you have probably all relevant require statements in the main application file (app.rb). Compare app/sidekiq.rb with app.rb file (and possible other files in the tree) and add relevant require instructions in the first one.
You can also start the console session (for example using Pry: pry -r ./app/sidekiq.rb or built-in irb: irb -r ./app/sidekiq.rb) with app/sidekiq and check if all needed classes are there or even better: write specs to check if it works fine.

How can you access Chef LWRP attributes in a recipe

With some of the default chef resources, it is possible to access some of their attributes after they have been called
# recipes/default.rb
f = file "/tmp/file_resource" do
owner "root"
group "root"
mode "0755"
action :create
end
log "Path to my file is #{f.path}" # outputs "/tmp/file_resource"
How can this be achieved in a custom LWRP (here is an example)
# resources/default.rb
actions :create
default_action :create
attribute :relative_path, :kind_of => String, :name_attribute => true
attribute :full_path, :kind_of => String
In this provider, I am trying to update the property of new_resource.full_path to be equal to the path of the file resource
# providers/default.rb
action :create do
f = file "/path/to/my/resource/#{new_resource.relative_path}" do
owner "root"
group "root"
mode "0755"
action :create
end
new_resource.full_path(f.path)
new_resource.updated_by_last_action(f.updated_by_last_action?)
end
However when I try to access resource.full_path in the recipe, it is nil rather than the expected /path/to/my/resource/relative/path
# recipes/default.rb
resource = my_awesome_lwrp "relative/path" do
action :create
end
log "Full path for my resource: #{resource.full_path}" # outputs "Full path for my resource:"
This example is rather contrived I know, the real world application/reason for this can be seen in the default resource/provider here https://github.com/peterjmit/chef-ssl-cert

Chef : Pass parameters to a ruby_block in Chef

How do you pass parameters to a ruby_block in chef.
If I have
notifies :create, "ruby_block[createErb]", :immediately
and I want pass a parameter (fileToConvert) to this ruby_block (createErb) at the time that I notify.
ruby_block "createErb" do
block do
ErbCreator.new(fileToConvert)
end
action :nothing
end
How would I do this?
Short answer - you can't.
RubyBlock is a Chef resource, so it does not accept arbitrary parameters. In your example, I would recommend creating a Chef Extension (LWRP or HWRP):
In your resource:
# resources/erb_create.rb
actions :create
default_action :create
attribute :filename, name_attribute: true
# more attributes
And in your provider:
# providers/erb_create.rb
action(:create) do
ErbCreator.new(new_resource.filename)
# ... etc
end
Then in a recipe:
# recipes/default.rb
cookbook_erb_create 'filename'
You can read more about LWRPs on the Chef Docs.

heroku: ActionController::RoutingError (No route matches [GET] "/newrelic")

ERROR
ActionController::RoutingError (No route matches [GET] "/newrelic")
# and I am getting error page for both staging and production heroku servers
Documentation
https://devcenter.heroku.com/articles/newrelic
GEM
https://github.com/newrelic/rpm
# ruby 2.1.0p0
# rails 4.0.1
Both environment variables NEW_RELIC_LICENSE_KEY and NEW_RELIC_APP_NAME are set to heroku config variable
Gemfile
gem "newrelic_rpm", "~> 3.5.7.59"
config/newrelic.yml
common: &default_settings
license_key: <%= ENV['NEW_RELIC_LICENSE_KEY'] %>
app_name: <%= ENV["NEW_RELIC_APP_NAME"] %>
monitor_mode: true
developer_mode: false
log_level: info
browser_monitoring:
auto_instrument: true
audit_log:
enabled: false
capture_params: false
transaction_tracer:
enabled: true
transaction_threshold: apdex_f
record_sql: obfuscated
stack_trace_threshold: 0.500
error_collector:
enabled: true
capture_source: true
ignore_errors: "ActionController::RoutingError,Sinatra::NotFound"
development:
<<: *default_settings
monitor_mode: true
developer_mode: true
test:
<<: *default_settings
monitor_mode: false
production:
<<: *default_settings
monitor_mode: true
staging:
<<: *default_settings
monitor_mode: true
app_name: <%= ENV["NEW_RELIC_APP_NAME"] %> (Staging)
[NOTE: I have two application hosted to heroku:]
(staging).herokuapp.com
(production).herokuapp.com
And I want to configure new-relic for both environments/servers.
Also, Note that this configuration is working fine in development(localhost) environmet.
EDITED
config/routes.rb
Demo::Application.routes.draw do
root :to => "home#index"
devise_for :users,:controllers => {:sessions => "sessions",:omniauth_callbacks => "omniauth_callbacks" }
post '/tinymce_assets' => 'tinymce_assets#create'
resources :home
namespace :admin do
resources :dashboards
resources :users do
member do
get :reset
put :reset_pw
put :delete_record
put :restore_user
end
end
end
resources :drives do
member do
put :destroy_drive
post :add_consolidation
put :delete_consolidation
post :add_driveorganizer
put :delete_drive_organizer
put :restore_drirve
end
collection do
get :recalculate_consolidation
end
resources :drive_details do
resources :images
end
end
resources :products do
member do
post :add_category
put :destroy_pc
put :delete_product
put :restore_products
end
end
resources :stores do
member do
put :delete_store
end
end
resources :store_products do
member do
put :delete_storeproduct
post :add_package_items
put :delete_package_item
put :restore_store_product
get :get_product_price
end
collection do
get :autocomplete_others
end
end
resources :orders do
member do
put :delete_order
put :restore_order
get :charge_stripe
end
resources :order_items do
collection do
post :display_price
end
member do
put :delete_record
end
end
end
resources :categories do
member do
put :delete_category
put :restore_category
end
collection do
get :move
end
end
namespace :user do
resources :campaigns do
member do
get :single_campaign
end
resources :stores
resources :carts do
collection do
post :carts_update
get :checkout_final
get :payment
post :payment
get :update_payment
get :update_payment_and_redirect
get :confirmation
post :confirmation
get :finish
post :confirmation_update
put :empty_cart
post :shelter_survey
end
member do
put :destroy_oi
put :checkout
end
end
end
end
# The priority is based upon order of creation: first created -> highest priority.
# See how all your routes lay out with "rake routes".
# You can have the root of your site routed with "root"
# root 'welcome#index'
# Example of regular route:
# get 'products/:id' => 'catalog#view'
# Example of named route that can be invoked with purchase_url(id: product.id)
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
# Example resource route (maps HTTP verbs to controller actions automatically):
# resources :products
# Example resource route with options:
# resources :products do
# member do
# get 'short'
# post 'toggle'
# end
#
# collection do
# get 'sold'
# end
# end
# Example resource route with sub-resources:
# resources :products do
# resources :comments, :sales
# resource :seller
# end
# Example resource route with more complex sub-resources:
# resources :products do
# resources :comments
# resources :sales do
# get 'recent', on: :collection
# end
# end
# Example resource route with concerns:
# concern :toggleable do
# post 'toggle'
# end
# resources :posts, concerns: :toggleable
# resources :photos, concerns: :toggleable
# Example resource route within a namespace:
# namespace :admin do
# # Directs /admin/products/* to Admin::ProductsController
# # (app/controllers/admin/products_controller.rb)
# resources :products
# end
end
Thanks
Based on the error you're getting, it looks like you're trying to access the route to the New Relic Ruby agent's developer mode in your staging and production environments. Developer mode installs a middleware in your app that responds to any URL prepended with /newrelic. Because you've enabled Developer mode in your development (localhost) environment (the developer_mode key is set to true in your newrelic.yml under development), accessing this route succeeds there, but it fails in staging and production because you don't have developer mode enabled in those environments.
Your current configuration is usually desirable, since Developer mode introduces a large amount of overhead that is generally unacceptable in production. Rather than attempt to access the route in staging or production, use it during development only.
You may also want to consider upgrading the version of the agent you are using, since version 3.5.7 does not fully support Ruby 2.0 or Rails 4. More information on releases can be found at https://docs.newrelic.com/docs/releases/ruby.

Thin throws error: undefined method "call"

I'm having trouble getting thin to run my webapp. It starts up just fine, but whenever I make a request thin craps out and I get the following popping up in the log:
>> Listening on 0.0.0.0:3000, CTRL+C to stop
!! Unexpected error while processing request: undefined method `call'
for #<Rack::Request:0x7f104facb640>
This configuration worked just fine on my Debian server; I'm running Gentoo now.
This is my rackup file:
require 'toto'
# Rack config
use Rack::Static, :urls => ['/css', '/js', '/images', '/favicon.ico', '/pubkey.asc'], :root => 'public'
use Rack::Request
use Rack::CommonLogger
if ENV['RACK_ENV'] == 'development'
use Rack::ShowExceptions
end
#
# Create and configure a toto instance
#
toto = Toto::Server.new do
#
# Add your settings here
# set [:setting], [value]
#
set :author, "jibcage" # blog author
set :title, "Going to Grass" # site title
set :root, "index" # page to load on /
# set :date, lambda {|now| now.strftime("%d/%m/%Y") } # date format for articles
set :markdown, :smart
Delete the line
use Rack::Request

Resources