How to combine a different provider with the Chef deploy resource? - ruby

I am trying to create a recipe to deploy an application.
I would like to combine the Chef deploy resource with the Chef Mercurial provider. The readme of this provider suggest that it is easy to use with deploy resource. However, I'm not sure how to do this.
The mercurial resource is working as expected:
mercurial deploy[:deploy_to] do
repository deploy[:scm][:repository]
ssh_key "/home/vagrant/.ssh/authorized_keys"
ssh_ignore true
branch true
revision deploy[:scm][:revision]
user deploy[:user]
group deploy[:group]
action :sync
end
However I'm having trouble with the provider
deploy deploy[:deploy_to] do
repository deploy[:scm][:repository]
user deploy[:user]
group deploy[:group]
revision deploy[:scm][:revision]
environment deploy[:environment].to_hash
scm_provider Chef::Provider::Mercurial
action :deploy
end
The error I'm getting is NoMethodError: undefined method 'ssh_key' for Chef::Resource::Deploy. This is probably due to the fact that the resource requires the ssh_key attribute. I don't know how to pass this attribute through when using the deploy resource.
How can I make this work?
Does anyone have an example of how to use the Chef deploy resource with the Chef Mercurial provider?

Related

List all the declared packages in chef

I'm working on a infrastructure where some servers don't have access to the internet, so I have to push the packages to the local repo before declaring them to be installed on Chef.
However we've been on a situation where Chef failed to install a package since the package wasn't there on some boxes and it has been successful on some other boxes.
What I want to do is to run a Ruby/RSpec test before applying Chef config on the nodes to make sure the packages declared on the recipes do actually exist on the repo.
In order to do that I need to be able to list all the packages exists in the our recipes.
My question is: Is there anyway to list all the declared packages in Chef? I had a quick look at Chef::Platform and ChefSpec but unfortunately couldn't find anything useful to my problem.
Do you have any idea where is the best place to look at?
If you use ChefSpec you can find all the packages by calling chef_run.find_resources(:package) inside some test. See the source code. Like this:
require 'chefspec'
describe 'example::default' do
let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) }
it 'does something' do
chef_run.find_resources(:package)...
end
end
You could install one or more of the community ohai plugins. For example the following will return information about installed sofware:
debian
Redhat
windows
Once the plugins are enabled they will add additional node attributes that will be searchable from chef-server.

Unable to use application_ruby cookbook with Chef 11.8.0, Cannot find a resource for bundle_options

I have been attempting to setup a chef recipe which installs ruby using RVM and then uses the application_ruby cookbook to configure the application, however I keep running into the error
NameError: Cannot find a resource for bundle_options on ubuntu version 12.04
I am using the following code
application "application setup" do
owner "ubuntu"
group "ubuntu"
repository "https://github.com/me/myapplication.git" // Real address removed
path rails_app_path
revision "master"
rails do
bundler true
precompile_assets true
bundler_deployment true
end
end
I noticed that the bundle_options was recently added, https://github.com/opscode-cookbooks/application_ruby/commit/e7719170a661a957796e8e5d58ba8f4ecd937487 however I am unable to track down if this is causing the issue. I have included
depends "application"
depends "application_ruby"
in my metadata.rb and made sure all my dependencies are installed so I am unsure what I am doing wrong at this point.
According to documentation bundle_options is an attribute of the rails resource, not a resource itself.
The only correct way of using it is INSIDE the "rails" block, so you got the message because you either used it as :
an attribute of the application resource (but outside of the "rails" block)
standalone resource (outside of any resource).
Message you mentioned is being displayed when nonexistent resource is being referenced. e.g. if you had tried to execute following code on your system:
nonexistent_resource "failure gonna happen" do
some_attribute "whatever_value"
end
you would've got a message
NameError: Cannot find a resource for nonexistent_resource on Ubuntu version 12.04
I ran into this problem today as well. It appears the problem is that commit e771917 forgot to add the necessary getter for the bundle_option. Someone filed a PR to fix it (https://github.com/poise/application_ruby/pull/44), but it has not yet been merged. I can confirm that when I made that change locally, this error went away. The forked branch in the PR is located at https://github.com/mauriciosilva/application_ruby/tree/bundle_options_fix.

Chef Solo - Role Data in Ruby DSL or JSON?

I am playing with Roles with Chef Solo (11.4.4 and 11.6.0). A bit Confused.
For Chef Solo runs, should roles be written in Ruby or JSON?
As per the official docs: About Roles, Roles can be stored as domain-specific Ruby (DSL) files or JSON data.
NOTE: chef-client uses Ruby for Roles, when these files are uploaded to Chef Server, they are converted to JSON. Whenever chef-repo is refreshed, the contents of all domain-specific Ruby files are re-compiled to JSON and re-uploaded to the server.
My question is, if the requirement is to run Chef in solo mode without a server and roles are needed, should the roles be written in Ruby or JSON (we don't have a server to convert Ruby to JSON)?
My guess is the latter. Does anyone know the correct answer?
BTW: I've seen people mixing Ruby and JSON in role files...
What is the Ruby DSL equivalent for rbenv.rb below?
Example, run rbenv + ruby-build cookbooks to install rbenv on Ubuntu.
rbenv.json
{
"run_list": ["role[rbenv]"]
}
roles/rbenv.rb
name "rbenv"
description "rbenv + ruby-build"
run_list(
"recipe[rbenv]",
"recipe[ruby_build]"
)
override_attributes(
:rbenv => {
:git_repository => "https://github.com/sstephenson/rbenv.git"
},
:ruby_build => {
:git_repository => "https://github.com/sstephenson/ruby-build.git"
}
)
Chef Solo run chef-solo -c solo.rb -j rbenv.json -l debug works as expected. This is to achieve cloning via HTTPS because it easier behind the firewall.
However, using a Ruby DSL version of role rbenv.rb like below
name "rbenv"
description "rbenv + ruby-build"
run_list "recipe[rbenv]", "recipe[ruby_build]"
# default_attributes ":rbenv" => {":install_prefix" => "/opt"}
override_attributes ":rbenv" => {":git_repository" => "https://github.com/sstephenson/rbenv.git"}, ":ruby_build" => {":git_repository" => "https://github.com/sstephenson/ruby-build.git"}
It didn't seem to work because it still used the default attributes (clone via git URL instead of HTTPS).
I am new to Ruby so most likely I made some mistakes in the DSL code, please help;-)
* git[/opt/rbenv] action sync[2013-09-03T03:44:53+00:00] INFO: Processing git[/opt/rbenv] action sync (rbenv::default line 91)
[2013-09-03T03:44:53+00:00] DEBUG: git[/opt/rbenv] finding current git revision
[2013-09-03T03:44:53+00:00] DEBUG: git[/opt/rbenv] resolving remote reference
================================================================================
Error executing action `sync` on resource 'git[/opt/rbenv]'
================================================================================
Mixlib::ShellOut::ShellCommandFailed
------------------------------------
Expected process to exit with [0], but received '128'
---- Begin output of git ls-remote "git://github.com/sstephenson/rbenv.git" master* ----
STDOUT:
STDERR: fatal: unable to connect to github.com:
github.com[0: 192.30.252.128]: errno=Connection timed out
---- End output of git ls-remote "git://github.com/sstephenson/rbenv.git" master* ----
Ran git ls-remote "git://github.com/sstephenson/rbenv.git" master* returned 128
I prefer to use JSON format wherever possible for one simple reason - it's easy to parse and validate with a script. Here are three things that you can do if all your Chef data is in JSON format:
Easily perform a syntax check in a git pre-commit hook, something that's much harder to do when the file is in the Ruby DSL format.
Validate the keys and values in a data bag entry. This can be useful to check that you are not going to deploy invalid or nonsensical data bag entries to production.
Compare (with a little extra work - key ordering in a dictionary needs to be taken into account) the value of an object on a server with what's in git. The --format json argument is useful here.

Deploy java app in Chef cookbook

I am already using application cookbook to deploy and install my java application. I tried it on my own.
application "saymetrix" do
path "/usr/local"
owner "chef"
group "chef"
end
And for the above code i get following error.
Error executing action `deploy` on resource 'application[saymetrix]'
================================================================================
NameError
---------
Cannot find a resource for saymetrix on ubuntu version 12.04
Cookbook Trace:
---------------
/var/chef/cache/cookbooks/application/providers/default.rb:82:in `before_deploy'
/var/chef/cache/cookbooks/application/providers/default.rb:27:in `block in class_from_file'
I don't get how to resolve this?
Refer to the application_java cookbook.
you need to add these in the metadata.rb of your saymatrix cookbook:
depends 'application'
depends 'application_java'
And add necessary details at least including repository and deployment target like tomcat. You can find the section Usage of the example here: application_java

Chef passing revision variable to deploy resource

I'm trying to pass the git branch that I want to deploy to the Chef deploy resource but it isn't working, I'm guessing it's because the resources are compiled separately and then just executed? But I might be wrong as my understanding of Ruby is limited.
So I'm trying to do this:
ruby_block 'revision' do
block do
# Some code determines the branch to be deployed
branch = 'master'
node.run_state['branch'] = branch
end
end
deploy "#{node['path']['web']}" do
action :deploy
repository "#{node['git']['repository']}"
revision "#{node.run_state['branch']}"
end
However the deploy resource doesn't get passed that variable.
Is this the correct way to go about this? Is there a better or other way?
Thanks in advance!
At the moment chef compiles your deploy resource ruby_block resource is not run yet, so node.run_state['branch'] is not set. You have to move your deploy resource into ruby_block and define it dynamically.
ruby_block 'revision' do
block do
# Some code determines the branch to be deployed
branch = 'master'
node.run_state['branch'] = branch
depl = Chef::Resource::Deploy.new node['path']['web'], run_context
depl.repository node['git']['repository']
depl.revision node.run_state['branch']
depl.run_action :deploy
end
end

Resources