Tampa
Tampa

Reputation: 78422

Chef, how to run a template that creates a init.d script before the service is created

Below is my templete for nginx.

I am facing a catch 22. I need to install a init.d template. So I have a nginx erb template that I place in /etc/init.d/nginx.

I Even tried t place the code on top of the recipe. The recipe is dependent on the init.d file but its not exectued until it is too late and as a result I get this error:

STDERR: update-rc.d: /etc/init.d/nginx: file does not exist
---- End output of "bash"  "/tmp/chef-script20120330-26326-3ologp-0" ----
Ran "bash"  "/tmp/chef-script20120330-26326-3ologp-0" returned 1
[Fri, 30 Mar 2012 06:22:15 +0000] FATAL: Stacktrace dumped to /var/chef/cache/chef-stacktrace.out
[Fri, 30 Mar 2012 06:22:15 +0000] ERROR: Sleeping for 60 seconds before trying again

On the next run of chef client, things work because then the templete was created.

How do I execute a template immediately before I register the service resource for nginx? A quick fix is that I create a recipe that will run the template before nginx to install the template but that seems rather absurd.

This tempate needs to be installed before the service is registed.

template "nginx" do
      path "/etc/init.d/nginx"
      source "nginx.erb"
      owner "root"
      group "root"
      mode "0755"
    end

Then register the server.

service "nginx" do
      supports :restart => true, :start => true, :stop => true, :reload => true
      action [ :enable, :start]
    end







####################################
#Install Nginx
####################################
#http://wiki.nginx.org/HttpLuaModule#Installation
version = node[:nginx][:version]
package "libpcre3" do
  action :install
end
package "libpcre3-dev" do
  action :install
end
package "libpcre++-dev" do
  action :install
end
package "openssl" do
  action :install
end

template "nginx" do
  path "/etc/init.d/nginx"
  source "nginx.erb"
  owner "root"
  group "root"
  mode "0755"
end

#mkdir /var/log/nginx
directory "/var/log/nginx" do
  owner "root"
  group "root"
  mode "0755"
  action :create
  #not_if "test -f /etc/nginx/lock"
end

remote_file "/tmp/nginx-#{version}.tar.gz" do
  source "http://nginx.org/download/nginx-#{version}.tar.gz"
  checksum node[:nginx][:checksum]
  action :create_if_missing
  notifies :run, "bash[install_nginx]", :immediately
end


bash "install_nginx" do
  user "root"
  cwd "/tmp"
  code <<-EOH
    tar -xvf nginx-#{version}.tar.gz
    cd nginx-#{version}
    ./configure --with-http_stub_status_module  
    make -j2
    make install
    ln -s /usr/local/nginx/conf/ /etc/nginx
    /usr/sbin/update-rc.d -f nginx defaults
  EOH
  action :nothing
  creates "/usr/sbin/nginx"
  notifies :restart, "service[nginx]"
  #not_if "test -f /etc/redis/lock"
end


service "nginx" do
  supports :restart => true, :start => true, :stop => true, :reload => true
  action [ :enable, :start]
end

#ln -s /usr/local/nginx/conf/ /etc/nginx
#link "/usr/local/nginx/conf/" do
#  to "/etc/nginx"
#  link_type :hard
#end

link "/usr/local/nginx/logs/access.log" do
  to "/var/log/nginx/access.log"
end

link "/usr/local/nginx/logs/error.log" do
  to "/var/log/nginx/error.log"
end

file "/etc/nginx/lock" do
  owner "root"
  group "root"
  mode "0755"
  action :create_if_missing
end

template "nginx.conf" do
  path "/etc/nginx/nginx.conf"
  source "nginx.conf.erb"
  owner "root"
  group "root"
  mode "0644"
  #notifies :reload, "service[nginx]"
  notifies :reload, resources(:service => "nginx"), :immediately
end

Thanks

Upvotes: 29

Views: 21559

Answers (3)

Evgeniy Shurmin
Evgeniy Shurmin

Reputation: 51

template "nginx" do
    path "/etc/init.d/nginx"
    source "nginx.erb"
    owner "root"
    group "root"
    mode "0755"
end

service "nginx" do
    supports :restart => true, :start => true, :stop => true, :reload => true
    action [ :enable, :start ]
    subscribes :restart, "template[nginx]", :immediately
end 

Upvotes: 5

DV.
DV.

Reputation: 4603

While using notifies is better in this case, in other cases you don't have that luxury. Here's how to instruct Chef to create the template immediately:

tpl = template "nginx" do
  action :nothing
  path "/etc/init.d/nginx"
  source "nginx.erb"
  owner "root"
  group "root"
  mode "0755"
end
tpl.run_action(:create)

Upvotes: -2

turtlebender
turtlebender

Reputation: 1907

You can set the action on the service to :nothing. Then have the template notify the service to enable. That way the template will be processed and then the service will be enabled:

service "nginx" do
  supports :restart => true, :start => true, :stop => true, :reload => true
  action :nothing
end 

template "nginx" do
  path "/etc/init.d/nginx"
  source "nginx.erb"
  owner "root"
  group "root"
  mode "0755"
  notifies :enable, "service[nginx]"
  notifies :start, "service[nginx]"
end

Then the service will wait until the template has processed.

Upvotes: 45

Related Questions