Modifying LWRP call in library cookbook

Hi,

I’m using the application_ruby cookbook to deploy a rails app. I’m
trying to get zero-downtime restarts working Unicorn and I found a
guide at https://gist.github.com/czarneckid/4639793 which seems to
work, but I need to use a custom runit template.

When I call the application provider in my wrapper cookbook, this
creates a runit service:

My wrapper:

name = ‘myapp’

application name do
(snip)

unicorn do
restart_command do
execute “/etc/init.d/#{name} restart” do
user "root"
end
end
worker_processes 2
listen ({ “#{app_path}/shared/.unicorn.sock” => { :tcp_nodelay =>
true, :backlog => 100 }})
pid "#{app_path}/shared/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
before_exec "ENV[‘BUNDLE_GEMFILE’] = “#{app_path}/current/Gemfile”"
before_fork before_fork
after_fork after_fork
end
end

https://github.com/opscode-cookbooks/application_ruby/blob/master/providers/unicorn.rb:

runit_service new_resource.name do
run_template_name 'unicorn’
log_template_name 'unicorn’
owner new_resource.owner if new_resource.owner
group new_resource.group if new_resource.group

cookbook 'application_ruby'
options(
  :app => new_resource,
  :bundler => new_resource.bundler,
  :bundle_command => new_resource.bundle_command,
  :rails_env => new_resource.environment_name,
  :smells_like_rack =>

::File.exists?(::File.join(new_resource.path, “current”, “config.ru”))
)
end

I’d like to change the ‘cookbook’ line there to use my own cookbook,
so I can write a custom template. I tried changing the template
resource for the runit file:

srv = resources(“template[/etc/sv/myapp/run]”)
srv.cookbook = ‘my_cookbook’

but I get “Cannot find a resource matching template[/etc/sv/myapp/run]
(did you define it first?)”

Is it possible to do this or do I need to fork the application_ruby cookbook?

Thanks

James

It looks like your template probably is not named "/etc/sv/myapp/run".
There's not really enough code there for me to tell what
new_resource.name is in that scope, but that's what you need to search
for. You also might want to try the chef-rewind gem for this... it wraps
up the search and makes these kind of alterations look a little less
ugly... but you still have to have the right name.

Greg

On 09/17/13 11:58, James Wilford wrote:

Hi,

I'm using the application_ruby cookbook to deploy a rails app. I'm
trying to get zero-downtime restarts working Unicorn and I found a
guide at application-notes-zero-downtime-deploys-unicorn-nginx-runit-rvm-chef.md · GitHub which seems to
work, but I need to use a custom runit template.

When I call the application provider in my wrapper cookbook, this
creates a runit service:

My wrapper:

name = 'myapp'

application name do
(snip)

unicorn do
restart_command do
execute "/etc/init.d/#{name} restart" do
user "root"
end
end
worker_processes 2
listen ({ "#{app_path}/shared/.unicorn.sock" => { :tcp_nodelay =>
true, :backlog => 100 }})
pid "#{app_path}/shared/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
before_exec "ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile""
before_fork before_fork
after_fork after_fork
end
end

https://github.com/opscode-cookbooks/application_ruby/blob/master/providers/unicorn.rb:

runit_service new_resource.name do
run_template_name 'unicorn'
log_template_name 'unicorn'
owner new_resource.owner if new_resource.owner
group new_resource.group if new_resource.group

 cookbook 'application_ruby'
 options(
   :app => new_resource,
   :bundler => new_resource.bundler,
   :bundle_command => new_resource.bundle_command,
   :rails_env => new_resource.environment_name,
   :smells_like_rack =>

::File.exists?(::File.join(new_resource.path, "current", "config.ru"))
)
end

I'd like to change the 'cookbook' line there to use my own cookbook,
so I can write a custom template. I tried changing the template
resource for the runit file:

srv = resources("template[/etc/sv/myapp/run]")
srv.cookbook = 'my_cookbook'

but I get "Cannot find a resource matching template[/etc/sv/myapp/run]
(did you define it first?)"

Is it possible to do this or do I need to fork the application_ruby cookbook?

Thanks

James

  • Thanks Greg. I know that new_resource.name is definitely "myapp"
    (actually its something else but changed for the purpose of this
    discussion). And the path of the file I want to change is
    "/etc/sv/myapp/run", so I would expect the template resource to be
    called that. The code of the runit cookbook is very strange though -
    runit/libraries/provider_runit_service.rb at main · chef-cookbooks/runit · GitHub
  • so I can't easily tell from there what the template resource is
    called.

I'm wondering if the problem is simply that the scope of the template
resource isn't visible to my wrapper cookbook, because its in the
runit provider, which in turn is called inside the application
provider?

On Tue, Sep 17, 2013 at 6:13 PM, Greg Symons gsymons@drillinginfo.com wrote:

It looks like your template probably is not named "/etc/sv/myapp/run".
There's not really enough code there for me to tell what new_resource.name
is in that scope, but that's what you need to search for. You also might
want to try the chef-rewind gem for this... it wraps up the search and makes
these kind of alterations look a little less ugly... but you still have to
have the right name.

Greg

On 09/17/13 11:58, James Wilford wrote:

Hi,

I'm using the application_ruby cookbook to deploy a rails app. I'm
trying to get zero-downtime restarts working Unicorn and I found a
guide at application-notes-zero-downtime-deploys-unicorn-nginx-runit-rvm-chef.md · GitHub which seems to
work, but I need to use a custom runit template.

When I call the application provider in my wrapper cookbook, this
creates a runit service:

My wrapper:

name = 'myapp'

application name do
(snip)

unicorn do
restart_command do
execute "/etc/init.d/#{name} restart" do
user "root"
end
end
worker_processes 2
listen ({ "#{app_path}/shared/.unicorn.sock" => { :tcp_nodelay =>
true, :backlog => 100 }})
pid "#{app_path}/shared/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
before_exec "ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile""
before_fork before_fork
after_fork after_fork
end
end

https://github.com/opscode-cookbooks/application_ruby/blob/master/providers/unicorn.rb:

runit_service new_resource.name do
run_template_name 'unicorn'
log_template_name 'unicorn'
owner new_resource.owner if new_resource.owner
group new_resource.group if new_resource.group

 cookbook 'application_ruby'
 options(
   :app => new_resource,
   :bundler => new_resource.bundler,
   :bundle_command => new_resource.bundle_command,
   :rails_env => new_resource.environment_name,
   :smells_like_rack =>

::File.exists?(::File.join(new_resource.path, "current", "config.ru"))
)
end

I'd like to change the 'cookbook' line there to use my own cookbook,
so I can write a custom template. I tried changing the template
resource for the runit file:

srv = resources("template[/etc/sv/myapp/run]")
srv.cookbook = 'my_cookbook'

but I get "Cannot find a resource matching template[/etc/sv/myapp/run]
(did you define it first?)"

Is it possible to do this or do I need to fork the application_ruby
cookbook?

Thanks

James

Actually, if the application or runit cookbooks are using
use_inline_resources in their lwrps, then that's almost certainly
what's happening, since the resources are defined in nested
run_contexts. You probably do need to fork application_ruby and make it
so that the unicorn subresource can take a 'runit_template_cookbook'
parameter with the cookbook name in it or something. At least that might
be something that might be accepted upstream so your fork can be
short-lived.

Greg

On 09/19/13 10:25, James Wilford wrote:

  • Thanks Greg. I know that new_resource.name is definitely "myapp"
    (actually its something else but changed for the purpose of this
    discussion). And the path of the file I want to change is
    "/etc/sv/myapp/run", so I would expect the template resource to be
    called that. The code of the runit cookbook is very strange though -
    runit/libraries/provider_runit_service.rb at main · chef-cookbooks/runit · GitHub
  • so I can't easily tell from there what the template resource is
    called.

I'm wondering if the problem is simply that the scope of the template
resource isn't visible to my wrapper cookbook, because its in the
runit provider, which in turn is called inside the application
provider?

On Tue, Sep 17, 2013 at 6:13 PM, Greg Symons gsymons@drillinginfo.com wrote:

It looks like your template probably is not named "/etc/sv/myapp/run".
There's not really enough code there for me to tell what new_resource.name
is in that scope, but that's what you need to search for. You also might
want to try the chef-rewind gem for this... it wraps up the search and makes
these kind of alterations look a little less ugly... but you still have to
have the right name.

Greg

On 09/17/13 11:58, James Wilford wrote:

Hi,

I'm using the application_ruby cookbook to deploy a rails app. I'm
trying to get zero-downtime restarts working Unicorn and I found a
guide at application-notes-zero-downtime-deploys-unicorn-nginx-runit-rvm-chef.md · GitHub which seems to
work, but I need to use a custom runit template.

When I call the application provider in my wrapper cookbook, this
creates a runit service:

My wrapper:

name = 'myapp'

application name do
(snip)

unicorn do
  restart_command do
    execute "/etc/init.d/#{name} restart" do
      user "root"
    end
  end
  worker_processes 2
  listen ({ "#{app_path}/shared/.unicorn.sock" => { :tcp_nodelay =>

true, :backlog => 100 }})
pid "#{app_path}/shared/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
before_exec "ENV['BUNDLE_GEMFILE'] = "#{app_path}/current/Gemfile""
before_fork before_fork
after_fork after_fork
end
end

https://github.com/opscode-cookbooks/application_ruby/blob/master/providers/unicorn.rb:

runit_service new_resource.name do
  run_template_name 'unicorn'
  log_template_name 'unicorn'
  owner new_resource.owner if new_resource.owner
  group new_resource.group if new_resource.group

  cookbook 'application_ruby'
  options(
    :app => new_resource,
    :bundler => new_resource.bundler,
    :bundle_command => new_resource.bundle_command,
    :rails_env => new_resource.environment_name,
    :smells_like_rack =>

::File.exists?(::File.join(new_resource.path, "current", "config.ru"))
)
end

I'd like to change the 'cookbook' line there to use my own cookbook,
so I can write a custom template. I tried changing the template
resource for the runit file:

srv = resources("template[/etc/sv/myapp/run]")
srv.cookbook = 'my_cookbook'

but I get "Cannot find a resource matching template[/etc/sv/myapp/run]
(did you define it first?)"

Is it possible to do this or do I need to fork the application_ruby
cookbook?

Thanks

James

@James, I'd also been in this situation earlier and couldn't do it.
Then I fallback to the deploy_revision and adding my own unicorn template.
But, I'd definitely like to use the application_ruby cookbook. Do post the
solution/thoughts if you come or overcome across this.

@millisami
~Sachin Sagar Rai
Ruby on Rails Developer
http://tfm.com.np
http://nepalonrails.com

On Sat, Sep 21, 2013 at 6:39 AM, Greg Symons gsymons@drillinginfo.comwrote:

Actually, if the application or runit cookbooks are using
use_inline_resources in their lwrps, then that's almost certainly what's
happening, since the resources are defined in nested run_contexts. You
probably do need to fork application_ruby and make it so that the unicorn
subresource can take a 'runit_template_cookbook' parameter with the
cookbook name in it or something. At least that might be something that
might be accepted upstream so your fork can be short-lived.

Greg

On 09/19/13 10:25, James Wilford wrote:

I'm wondering if the problem is simply that the scope of the template
resource isn't visible to my wrapper cookbook, because its in the
runit provider, which in turn is called inside the application
provider?

On Tue, Sep 17, 2013 at 6:13 PM, Greg Symons gsymons@drillinginfo.com
wrote:

It looks like your template probably is not named "/etc/sv/myapp/run".
There's not really enough code there for me to tell what
new_resource.name
is in that scope, but that's what you need to search for. You also might
want to try the chef-rewind gem for this... it wraps up the search and
makes
these kind of alterations look a little less ugly... but you still have
to
have the right name.

Greg

On 09/17/13 11:58, James Wilford wrote:

Hi,

I'm using the application_ruby cookbook to deploy a rails app. I'm
trying to get zero-downtime restarts working Unicorn and I found a
guide at https://gist.github.com/**czarneckid/4639793https://gist.github.com/czarneckid/4639793which seems to
work, but I need to use a custom runit template.

When I call the application provider in my wrapper cookbook, this
creates a runit service:

My wrapper:

name = 'myapp'

application name do
(snip)

unicorn do
  restart_command do
    execute "/etc/init.d/#{name} restart" do
      user "root"
    end
  end
  worker_processes 2
  listen ({ "#{app_path}/shared/.unicorn.**sock" => { :tcp_nodelay

=>
true, :backlog => 100 }})
pid "#{app_path}/shared/pids/**unicorn.pid"
stderr_path "#{app_path}/shared/log/**unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/**unicorn.stdout.log"
before_exec "ENV['BUNDLE_GEMFILE'] =
"#{app_path}/current/Gemfile**""
before_fork before_fork
after_fork after_fork
end
end

https://github.com/opscode-**cookbooks/application_ruby/**
blob/master/providers/unicorn.**rbhttps://github.com/opscode-cookbooks/application_ruby/blob/master/providers/unicorn.rb
:

runit_service new_resource.name do
  run_template_name 'unicorn'
  log_template_name 'unicorn'
  owner new_resource.owner if new_resource.owner
  group new_resource.group if new_resource.group

  cookbook 'application_ruby'
  options(
    :app => new_resource,
    :bundler => new_resource.bundler,
    :bundle_command => new_resource.bundle_command,
    :rails_env => new_resource.environment_name,
    :smells_like_rack =>

::File.exists?(::File.join(**new_resource.path, "current", "config.ru
"))
)
end

I'd like to change the 'cookbook' line there to use my own cookbook,
so I can write a custom template. I tried changing the template
resource for the runit file:

srv = resources("template[/etc/sv/**myapp/run]")
srv.cookbook = 'my_cookbook'

but I get "Cannot find a resource matching template[/etc/sv/myapp/run]
(did you define it first?)"

Is it possible to do this or do I need to fork the application_ruby
cookbook?

Thanks

James