Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add systemd support (in 3.0.0-rewrite) #384

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,4 @@ bin
coverage/
doc/
Gemfile.lock
vendor/
4 changes: 3 additions & 1 deletion .kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ platforms:
# - name: ubuntu-15.04
# - name: centos-5.11
# - name: centos-6.6
# - name: centos-7
- name: centos-7.1
run_list:
- recipe[nginx_service_test::nginx_repo]

suites:
- name: example
Expand Down
5 changes: 0 additions & 5 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,3 @@
AllCops:
Exclude:
- Guardfile
- 'vendor/**/*'

Metrics/LineLength:
Max: 160

Expand Down
2 changes: 2 additions & 0 deletions Berksfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ group :integration do

cookbook 'nginx_service_test', path: 'test/fixtures/cookbooks/nginx_service_test'

cookbook 'yum-epel'

# Or include an entire directory, once we have more test cookbooks:
# Dir["test/fixtures/cookbooks/**/metadata.rb"].each do |metadata|
# cookbook File.basename(File.dirname(metadata)), path: File.dirname(metadata)
Expand Down
15 changes: 15 additions & 0 deletions libraries/helpers.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,20 @@ def nginx_instance_name
def res_name
new_resource.name
end

# @return [String] Name of the user that runs nginx
def user_for_platform(node)
case node['platform']
when 'centos'
'nginx'
when 'ubuntu', 'debian'
'www-data'
else
raise "Unexpected platform '#{node['platform']}'."
end
end
end
end

Chef::Resource.send(:include, NginxCookbook::Helpers)
Chef::Provider.send(:include, NginxCookbook::Helpers)
2 changes: 0 additions & 2 deletions libraries/provider_nginx_service_base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ def whyrun_supported?
true
end

include NginxCookbook::Helpers

action :create do
# Install nginx using system package resource
#
Expand Down
88 changes: 88 additions & 0 deletions libraries/provider_nginx_service_systemd.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
class Chef
class Provider
class NginxService
# Provider actions for platforms using Systemd
#
# @since 3.0.0
# @author Miguel Ferreira <mferreira@schubergphilis.com>
class NginxServiceSystemd < Chef::Provider::NginxServiceBase
provides :nginx_service, os: 'linux' do
Chef::Platform::ServiceHelpers.service_resource_providers.include?(:systemd)
end if defined?(provides)

action :start do
template "#{res_name} :create /etc/systemd/system/#{nginx_instance_name}" do
path "/etc/systemd/system/#{nginx_instance_name}.service"
cookbook 'nginx'
source 'systemd/nginx.erb'
owner 'root'
group 'root'
mode 00744
variables(nginx_instance_name: nginx_instance_name)
action :create
notifies :run, 'execute[systemctl daemon-reload]', :immediately
end

execute 'systemctl daemon-reload' do
action :nothing
end

service "#{nginx_instance_name} :start" do
service_name nginx_instance_name
provider Chef::Provider::Service::Systemd
supports status: true, restart: true
action [:start, :enable]
end
end

action :stop do
service "#{nginx_instance_name} :stop" do
service_name nginx_instance_name
provider Chef::Provider::Service::Systemd
supports status: true, restart: true
action [:stop, :disable]
end
end

action :delete do
file "#{res_name} :delete /etc/systemd/system/#{nginx_instance_name}" do
path "/etc/systemd/system/#{nginx_instance_name}.service"
action :delete
end

service "#{res_name} :delete #{nginx_instance_name}" do
service_name nginx_instance_name
provider Chef::Provider::Service::Systemd
supports status: true
action [:stop, :disable]
notifies :run, 'execute[systemctl daemon-reload]', :immediately
end

execute 'systemctl daemon-reload' do
action :nothing
end
end

action :restart do
# @todo create recipes and tests for this
service "#{res_name} :restart #{nginx_instance_name}" do
service_name nginx_instance_name
supports status: true, restart: true
provider Chef::Provider::Service::Systemd
action :restart
end
end

action :reload do
# @todo create recipes and tests for this
service "#{res_name} :reload #{nginx_instance_name}" do
service_name nginx_instance_name
provider Chef::Provider::Service::Systemd
supports status: true, reload: true
action :reload
end
end
end
end
end
end
2 changes: 1 addition & 1 deletion libraries/resource_nginx_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class NginxService < Chef::Resource::LWRPBase
attribute :error_log_level, kind_of: String, default: 'warn'
attribute :run_group, kind_of: String, default: nil
# @todo Determine what user is correct per-platform
attribute :run_user, kind_of: String, default: 'www-data'
attribute :run_user, kind_of: String, default: lazy { user_for_platform(node) }
attribute :worker_connections, kind_of: Integer, default: 1024
attribute :worker_processes, kind_of: Integer, default: 1

Expand Down
49 changes: 36 additions & 13 deletions spec/libraries_specs/helpers_spec.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
# require_relative '../../libraries/helpers'
# require_relative '../../libraries/resource_nginx_service'
#
# describe NginxCookbook::Helpers do
# class DummyClass
# end
#
# before(:all) do
# @dummy = DummyClass.new
# @dummy.extend NginxCookbook::Helpers
# end
#
require_relative '../../libraries/helpers'
require_relative '../../libraries/resource_nginx_service'

describe NginxCookbook::Helpers do
class DummyClass
attr_accessor :node

def initialize
@node = {}
end
end

before(:all) do
@dummy = DummyClass.new
@dummy.extend NginxCookbook::Helpers
end

it 'returns www-data for debian platform' do
@dummy.node['platform'] = 'debian'

expect(@dummy.user_for_platform(@dummy.node)).to be == 'www-data'
end

it 'returns www-data for ubuntu platform' do
@dummy.node['platform'] = 'ubuntu'

expect(@dummy.user_for_platform(@dummy.node)).to be == 'www-data'
end

it 'returns nginx for centos platform' do
@dummy.node['platform'] = 'centos'

expect(@dummy.user_for_platform(@dummy.node)).to be == 'nginx'
end

# # let(:klass) { Class.new { extend NginxCookbook::Helpers } }
#
# # let(:klass) do
Expand Down Expand Up @@ -103,4 +126,4 @@
# end
# end
# end
# end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe 'resource_nginx_service :create on centos 7' do
before do
allow(Chef::Platform::ServiceHelpers).to receive(:service_resource_providers).and_return([:systemd])
end

cached(:chef_run) do
ChefSpec::SoloRunner.new(
step_into: 'nginx_service',
platform: 'centos',
version: '7.0'
).converge('nginx::example')
end

it_behaves_like 'create a named nginx_service', 'example'

it_behaves_like 'nginx_service :create', 'example', 'platform' => 'centos'
it_behaves_like 'nginx_service :start', 'example'
it_behaves_like 'nginx_service #systemd', 'example'

it_behaves_like 'nginx_config :create', 'example'
end
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

it_behaves_like 'create a named nginx_service', 'example'

it_behaves_like 'nginx_service :create', 'example'
it_behaves_like 'nginx_service :create', 'example', 'platform' => 'debian'
it_behaves_like 'nginx_service :start', 'example'
it_behaves_like 'nginx_service #upstart', 'example'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

it_behaves_like 'create a named nginx_service', 'example'

it_behaves_like 'nginx_service :create', 'example'
it_behaves_like 'nginx_service :create', 'example', 'platform' => 'ubuntu'
it_behaves_like 'nginx_service :start', 'example'
it_behaves_like 'nginx_service #sysvinit', 'example'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

it_behaves_like 'create a named nginx_service', 'example'

it_behaves_like 'nginx_service :create', 'example'
it_behaves_like 'nginx_service :create', 'example', 'platform' => 'ubuntu'
it_behaves_like 'nginx_service :start', 'example'
it_behaves_like 'nginx_service #upstart', 'example'

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
describe 'resource_nginx_service :delete on centos 7' do
cached(:chef_run) do
ChefSpec::SoloRunner.new(
step_into: 'nginx_service',
platform: 'centos',
version: '7.0'
).converge('nginx_service_test::single', 'nginx_service_test::delete')
end

it_behaves_like 'create a named nginx_service', 'single'

it_behaves_like 'nginx_service :create', 'single', 'platform' => 'centos'
it_behaves_like 'nginx_service :start', 'single'

xit 'stops the service' do
expect(chef_run).to stop_service('nginx-single')
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

it_behaves_like 'create a named nginx_service', 'single'

it_behaves_like 'nginx_service :create', 'single'
it_behaves_like 'nginx_service :create', 'single', 'platform' => 'debian'
it_behaves_like 'nginx_service :start', 'single'

xit 'stops the service' do
Expand Down
14 changes: 12 additions & 2 deletions spec/shared_examples/service.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
require_relative '../../libraries/helpers.rb'
include NginxCookbook::Helpers

RSpec.configure do
shared_examples_for 'create a named nginx_service' do |servicename|
it "creates nginx_service[#{servicename}]" do
expect(chef_run).to create_nginx_service(servicename)
end
end

shared_examples_for 'nginx_service :create' do |servicename|
shared_examples_for 'nginx_service :create' do |servicename, node|
it 'installs the nginx package' do
expect(chef_run).to install_package("#{servicename} :create nginx")
.with(package_name: 'nginx')
Expand All @@ -18,7 +21,7 @@

it 'creates new directories for the named instance' do
expect(chef_run).to create_directory("/var/log/nginx-#{servicename}")
.with(user: 'www-data', group: 'adm', mode: 00755)
.with(user: user_for_platform(node), group: 'adm', mode: 00755)

%W(
/etc/nginx-#{servicename}
Expand Down Expand Up @@ -60,4 +63,11 @@
.with(user: 'root', group: 'root', mode: 00744)
end
end

shared_examples_for 'nginx_service #systemd' do |servicename|
it 'templates instance-specific files' do
expect(chef_run).to create_template("/etc/nginx-#{servicename}/nginx.conf")
.with(user: 'root', group: 'root', mode: 00644)
end
end
end
19 changes: 19 additions & 0 deletions templates/default/systemd/nginx.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Dynamically generated by Chef - local modifications will be overwritten

[Unit]
Description=The nginx HTTP and reverse proxy server for <%= @nginx_instance_name %>
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/<%= @nginx_instance_name %>.pid
ExecStartPre=/usr/sbin/nginx -t -c /etc/<%= @nginx_instance_name %>/nginx.conf
ExecStart=/usr/sbin/nginx -c /etc/<%= @nginx_instance_name %>/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=process
KillSignal=SIGQUIT
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target
1 change: 1 addition & 0 deletions test/fixtures/cookbooks/nginx_service_test/metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@
version '0.1.0'

depends 'apt'
depends 'yum-epel'
depends 'nginx'
23 changes: 17 additions & 6 deletions test/fixtures/cookbooks/nginx_service_test/recipes/nginx_repo.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@
# distribution node['lsb']['codename']
# end

apt_repository 'nginx.org' do
uri "http://nginx.org/packages/#{node['platform']}"
distribution node['lsb']['codename']
components ['nginx']
key 'http://nginx.org/keys/nginx_signing.key'
only_if { node['platform_family'] == 'debian' }
case node['platform']
when 'ubuntu', 'debian'
apt_repository 'nginx.org' do
uri "http://nginx.org/packages/#{node['platform']}"
distribution node['lsb']['codename']
components ['nginx']
key 'http://nginx.org/keys/nginx_signing.key'
only_if { node['platform_family'] == 'debian' }
end
when 'centos'
yum_repository 'nginx repo' do
description 'Official Red Hat/CentOS packages'
mirrorlist 'http://nginx.org/packages/centos/$releasever/$basearch/'
gpgcheck false
enabled true
action :create
end
end
2 changes: 1 addition & 1 deletion test/integration/example/serverspec/example_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
nginx_example_conf = file '/etc/nginx-example/nginx.conf'

expect(nginx_example_conf).to be_a_file
expect(nginx_example_conf.content).to match(/user www-data;/)
expect(nginx_example_conf.content).to match(/user (www-data|nginx);/)
end

it 'starts & enables the example nginx service' do
Expand Down