Update cookbooks and add wordpress cookbook

This commit is contained in:
Greg Karékinian
2016-02-19 18:09:49 +01:00
parent 9ba973e3ac
commit 820b0ab3f8
606 changed files with 22421 additions and 14084 deletions

View File

@@ -2,6 +2,46 @@ runit Cookbook CHANGELOG
========================
This file is used to list changes made in each version of the runit cookbook.
UNRELEASED
----------
v1.7.6
----------
* Ensure `supervise/ok` named pipe is properly removed when disabling a service, so that it can be enabled again (#166, #167, #172)
* Restore `restart_on_update` functionality originally added in [#20](https://github.com/hw-cookbooks/runit/pull/20) and lost in the 1.7.0 refactor.
* Update test cookbooks to fix broken tests revealed by restoring `restart_on_update` functionality. Now using socat instead of netcat.
v1.7.4 (2015-10-13)
----------
* Ensure the service directory exists so that we will succeed when enabling services (#153)
* Fix regression where env directory contents were being deleted when the `env` attribute is empty. (#144, #158)
* Add `log_dir` attribute, used only when `default_logger` is true. (#135)
* Ensure svlogd configuration is linked into correct path (#83, #135)
* Update README and CHANGELOG for v1.7.0 to warn against known regressions (#144, #157)
* Avoid mutating resource options for Chef 12 compatability (#147, #150, #156)
* Fix regression regarding waiting for the service socket before running (#138, #142)
* Reimplement idempotence checks for `runit_service` resources (#137, #141)
* Enhance ChefSpec unit test coverage with specs that step into the LWRP (#139)
* Deduplicate ServerSpec integration test coverage using example groups (#140)
v1.7.2 (2015-06-19)
----------
* Re-add missing runit_service actions start, stop, reload and status
v1.7.0 (2015-06-18)
----------
**NOTE**: With the benefit of hindsight we can say that the changes contained in
this release merit a major version number change. Please be sure to test this
new version for compatibility with your systems before upgrading to version 1.7.
* Modernize runit_service provider by rewriting pure Ruby as LWRP (#107)
* Modernize integration tests by rewriting Minitest suites as ServerSpec (#107)
* Fix regression in support for alternate sv binary on debian platforms (#92, #123)
* Fix regression in default logger's config location (#117)
* Tighten permissions on environment variable config files from 0644 to 0640 (#125)
* Add `start_down` and `delete_downfile` attributes to support configuring services with default state of 'down' (#105)
v1.6.0 (2015-04-06)
--------------------
* Fedora 21 support

View File

@@ -8,15 +8,23 @@ For more information about runit:
- http://smarden.org/runit/
#### A note regarding versions 1.7.0 and 1.7.2
With the benefit of hindsight we can say that the changes contained version 1.7.0 merited a major version number change, and that version 1.7.2 contains some still unresolved regressions compared to 1.6.0. Please be sure to test this new version for compatibility with your systems before upgrading to version 1.7.
See [issue #144](https://github.com/hw-cookbooks/runit/issues/144) for some notes on how these versions behaved unexpectedly in one user's environment.
Requirements
------------
### Platforms
#### Platforms
- Debian/Ubuntu
- Gentoo
- RHEL
### Cookbooks
#### Chef
- Chef 11+
#### Cookbooks
- packagecloud (for RHEL)
Attributes
@@ -109,13 +117,18 @@ Many of these parameters are only used in the `:enable` action.
compatibility with legacy runit service definition. Default is an
empty hash.
- **env** - A hash of environment variables with their values as content
used in the service's `env` directory. Default is an empty hash.
used in the service's `env` directory. Default is an empty hash. When
this hash is non-empty, the contents of the runit service's `env`
directory will be managed by Chef in order to conform to the declared
state.
- **log** - Whether to start the service's logger with svlogd, requires
a template `sv-service_name-log-run.erb` to configure the log's run
script. Default is true.
- **default_logger** - Whether a default `log/run` script should be set
up. If true, the default content of the run script will use
`svlogd` to write logs to `/var/log/service_name`. Default is false.
- **log_dir** - The directory where the `svlogd` log service will run.
Used when `default_logger` is `true`. Default is `/var/log/service_name`
- **log_size** - The maximum size a log file can grow to before it is
automatically rotated. See svlogd(8) for the default value.
- **log_num** - The maximum number of log files that will be retained
@@ -168,6 +181,10 @@ Many of these parameters are only used in the `:enable` action.
- **restart_on_update** - Whether the service should be restarted when
the run script is updated. Defaults to `true`. Set to `false` if
the service shouldn't be restarted when the run script is updated.
- **start_down** - Set the default state of the runit service to 'down' by creating
`<sv_dir>/down` file. Defaults to `false`. Services using `start_down`
will not be notified to restart when their run script is updated.
- **delete_downfile** - Delete previously created `<sv_dir>/down` file
Unlike previous versions of the cookbook using the `runit_service` definition, the `runit_service` resource can be notified. See __Usage__ examples below.
@@ -185,7 +202,7 @@ exec svlogd -tt /var/log/service_name
```
### Examples
These are example use cases of the `runit_service` resource described above. There are others in the `runit_test` cookbook that is included in the [git repository](https://github.com/chef-cookbooks/runit).
These are example use cases of the `runit_service` resource described above. There are others in the `runit_test` cookbook that is included in the [git repository](https://github.com/hw-cookbooks/runit).
**Default Example**
@@ -350,8 +367,8 @@ runit_service "memcached" do
options({
:memory => node[:memcached][:memory],
:port => node[:memcached][:port],
:user => node[:memcached][:user]}.merge(params)
})
:user => node[:memcached][:user]
}.merge(params))
end
```
@@ -396,16 +413,17 @@ end
**More Examples**
For more examples, see the `runit_test` cookbook's `service` recipe in the [git repository](https://github.com/chef-cookbooks/runit).
For more examples, see the `runit_test` cookbook's `service` recipe in the [git repository](https://github.com/hw-cookbooks/runit).
License & Authors
-----------------
- Author:: Adam Jacob <adam@chef.io>
- Author:: Joshua Timberman <joshua@chef.io>
- Author:: Sean OMeara <sean@chef.io>
```text
Copyright:: 2008-2013, Chef Software, Inc
Copyright:: 2008-2016, Chef Software, Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

View File

@@ -2,8 +2,9 @@
# Cookbook:: runit
# Libraries:: helpers
#
# Author: Joshua Timberman <joshua@getchef.com>
# Copyright (c) 2014, Chef Software, Inc. <legal@getchef.com>
# Author: Joshua Timberman <joshua@chef.io>
# Author: Sean OMeara <sean@chef.io>
# Copyright 2008-2015, Chef Software, Inc. <legal@chef.io>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,28 +19,180 @@
# limitations under the License.
#
require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut
module Runit
module RunitCookbook
module Helpers
def runit_installed?
return true if runit_rpm_installed? || (runit_executable? && runit_sv_works?)
# include Chef::Mixin::ShellOut if it is not already included in the calling class
def self.included(klass)
unless klass.ancestors.include?(Chef::Mixin::ShellOut)
klass.class_eval { include Chef::Mixin::ShellOut }
end
end
def runit_executable?
::File.executable?(node['runit']['executable'])
# Default settings for resource properties.
def parsed_sv_bin
return new_resource.sv_bin if new_resource.sv_bin
'/usr/bin/sv'
end
def parsed_sv_dir
return new_resource.sv_dir if new_resource.sv_dir
'/etc/sv'
end
def parsed_service_dir
return new_resource.service_dir if new_resource.service_dir
'/etc/service'
end
def parsed_lsb_init_dir
return new_resource.lsb_init_dir if new_resource.lsb_init_dir
'/etc/init.d'
end
# misc helper functions
def inside_docker?
results = `cat /proc/1/cgroup`.strip.split("\n")
results.any? { |val| /docker/ =~ val }
end
def down_file
"#{sv_dir_name}/down"
end
def env_dir
"#{sv_dir_name}/env"
end
def extra_env_files?
files = []
Dir.glob("#{sv_dir_name}/env/*").each do |f|
files << File.basename(f)
end
return true if files.sort != new_resource.env.keys.sort
false
end
def zap_extra_env_files
Dir.glob("#{sv_dir_name}/env/*").each do |f|
unless new_resource.env.key?(File.basename(f))
File.unlink(f)
Chef::Log.info("removing file #{f}")
end
end
end
def wait_for_service
unless inside_docker?
sleep 1 until ::FileTest.pipe?("#{service_dir_name}/supervise/ok")
if new_resource.log
sleep 1 until ::FileTest.pipe?("#{service_dir_name}/log/supervise/ok")
end
end
end
def runit_sv_works?
sv = shell_out("#{node['runit']['sv_bin']} --help")
sv = shell_out("#{sv_bin} --help")
sv.exitstatus == 100 && sv.stderr =~ /usage: sv .* command service/
end
def runit_rpm_installed?
shell_out('rpm -qa | grep -q "^runit"').exitstatus == 0
def runit_send_signal(signal, friendly_name = nil)
friendly_name ||= signal
converge_by("send #{friendly_name} to #{new_resource}") do
shell_out!("#{sv_bin} #{sv_args}#{signal} #{service_dir_name}")
Chef::Log.info("#{new_resource} sent #{friendly_name}")
end
end
def running?
cmd = shell_out("#{sv_bin} #{sv_args}status #{service_dir_name}")
(cmd.stdout =~ /^run:/ && cmd.exitstatus == 0)
end
def log_running?
cmd = shell_out("#{sv_bin} #{sv_args}status #{service_dir_name}/log")
(cmd.stdout =~ /^run:/ && cmd.exitstatus == 0)
end
def enabled?
::File.exist?("#{service_dir_name}/run")
end
def log_service_name
"#{new_resource.service_name}/log"
end
def sv_dir_name
"#{parsed_sv_dir}/#{new_resource.service_name}"
end
def sv_args
sv_args = ''
sv_args += "-w '#{new_resource.sv_timeout}' " unless new_resource.sv_timeout.nil?
sv_args += '-v ' if new_resource.sv_verbose
sv_args
end
def sv_bin
parsed_sv_bin
end
def service_dir_name
"#{new_resource.service_dir}/#{new_resource.service_name}"
end
def log_dir_name
"#{new_resource.service_dir}/#{new_resource.service_name}/log"
end
def template_cookbook
new_resource.cookbook.nil? ? new_resource.cookbook_name.to_s : new_resource.cookbook
end
def default_logger_content
<<-EOS
#!/bin/sh
exec svlogd -tt #{new_resource.log_dir}
EOS
end
def disable_service
shell_out("#{new_resource.sv_bin} #{sv_args}down #{service_dir_name}")
FileUtils.rm(service_dir_name)
# per the documentation, a service should be removed from supervision
# within 5 seconds of removing the service dir symlink, so we'll sleep for 6.
# otherwise, runit recreates the 'ok' named pipe too quickly
sleep(6)
# runit will recreate the supervise directory and
# pipes when the service is reenabled
FileUtils.rm("#{sv_dir_name}/supervise/ok")
end
def start_service
shell_out!("#{new_resource.sv_bin} #{sv_args}start #{service_dir_name}")
end
def stop_service
shell_out!("#{new_resource.sv_bin} #{sv_args}stop #{service_dir_name}")
end
def restart_service
shell_out!("#{new_resource.sv_bin} #{sv_args}restart #{service_dir_name}")
end
def restart_log_service
shell_out!("#{new_resource.sv_bin} #{sv_args}restart #{service_dir_name}/log")
end
def reload_service
shell_out!("#{new_resource.sv_bin} #{sv_args}force-reload #{service_dir_name}")
end
def reload_log_service
if log_running?
shell_out!("#{new_resource.sv_bin} #{sv_args}force-reload #{service_dir_name}/log")
end
end
end
end
Chef::Recipe.send(:include, Runit::Helpers)
Chef::Resource.send(:include, Runit::Helpers)

View File

@@ -1,5 +1,7 @@
if defined?(ChefSpec)
ChefSpec.define_matcher(:runit_service)
def start_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :start, service)
end

View File

@@ -2,8 +2,9 @@
# Cookbook Name:: runit
# Provider:: service
#
# Copyright 2011, Joshua Timberman
# Copyright 2011, Chef Software, Inc.
# Author:: Joshua Timberman <jtimberman@chef.io>
# Author:: Sean OMeara <sean@chef.io>
# Copyright 2011-2015, Chef Software, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -18,533 +19,330 @@
# limitations under the License.
#
require 'chef/provider/service'
require 'chef/provider/link'
require 'chef/resource/link'
require 'chef/provider/directory'
require 'chef/resource/directory'
require 'chef/provider/template'
require 'chef/resource/template'
require 'chef/provider/file'
require 'chef/resource/file'
require 'chef/mixin/shell_out'
require 'chef/mixin/language'
class Chef
class Provider
class Service
class Runit < Chef::Provider::Service
# refactor this whole thing into a Chef11 LWRP
include Chef::Mixin::ShellOut
class RunitService < Chef::Provider::LWRPBase
unless defined?(VALID_SIGNALS)
# Mapping of valid signals with optional friendly name
VALID_SIGNALS = Mash.new(
:down => nil,
:hup => nil,
:int => nil,
:term => nil,
:kill => nil,
:quit => nil,
:up => nil,
:once => nil,
:cont => nil,
1 => :usr1,
2 => :usr2
)
end
def initialize(*args)
super
new_resource.supports[:status] = true
use_inline_resources if defined?(use_inline_resources)
def whyrun_supported?
true
end
# Mix in helpers from libraries/helpers.rb
include RunitCookbook::Helpers
# actions
action :create do
ruby_block 'restart_service' do
block do
action_enable
restart_service
end
action :nothing
only_if { new_resource.restart_on_update && !new_resource.start_down }
end
def load_current_resource
@current_resource = Chef::Resource::RunitService.new(new_resource.name)
current_resource.service_name(new_resource.service_name)
ruby_block 'restart_log_service' do
block do
action_enable
restart_log_service
end
action :nothing
only_if { new_resource.restart_on_update && !new_resource.start_down }
end
Chef::Log.debug("Checking status of service #{new_resource.service_name}")
# sv_templates
if new_resource.sv_templates
# verify Runit was installed properly
unless ::File.exist?(new_resource.sv_bin) && ::File.executable?(new_resource.sv_bin)
no_runit_message = "Could not locate main runit sv_bin at \"#{new_resource.sv_bin}\". "
no_runit_message << "Did you remember to install runit before declaring a \"runit_service\" resource? "
no_runit_message << "\n\nTry adding the following to the top of your recipe:\n\ninclude_recipe \"runit\""
fail no_runit_message
directory sv_dir_name do
owner new_resource.owner
group new_resource.group
mode '0755'
recursive true
action :create
end
current_resource.running(running?)
current_resource.enabled(enabled?)
current_resource.env(get_current_env)
current_resource
end
#
# Chef::Provider::Service overrides
#
def action_create
configure_service # Do this every run, even if service is already enabled and running
Chef::Log.info("#{new_resource} configured")
end
def action_enable
configure_service # Do this every run, even if service is already enabled and running
Chef::Log.info("#{new_resource} configured")
if current_resource.enabled
Chef::Log.debug("#{new_resource} already enabled - nothing to do")
else
enable_service
Chef::Log.info("#{new_resource} enabled")
template "#{sv_dir_name}/run" do
owner new_resource.owner
group new_resource.group
source "sv-#{new_resource.run_template_name}-run.erb"
cookbook template_cookbook
mode '0755'
variables(options: new_resource.options)
action :create
notifies :run, 'ruby_block[restart_service]', :delayed
end
load_new_resource_state
new_resource.enabled(true)
restart_service if new_resource.restart_on_update && run_script.updated_by_last_action?
restart_log_service if new_resource.restart_on_update && log_run_script.updated_by_last_action?
restart_log_service if new_resource.restart_on_update && log_config_file.updated_by_last_action?
end
def configure_service
if new_resource.sv_templates
Chef::Log.debug("Creating sv_dir for #{new_resource.service_name}")
do_action(sv_dir, :create)
Chef::Log.debug("Creating run_script for #{new_resource.service_name}")
do_action(run_script, :create)
if new_resource.log
Chef::Log.debug("Setting up svlog for #{new_resource.service_name}")
do_action(log_dir, :create)
do_action(log_main_dir, :create)
do_action(default_log_dir, :create) if new_resource.default_logger
do_action(log_run_script, :create)
do_action(log_config_file, :create)
else
Chef::Log.debug("log not specified for #{new_resource.service_name}, continuing")
# log stuff
if new_resource.log
directory "#{sv_dir_name}/log" do
owner new_resource.owner
group new_resource.group
recursive true
action :create
end
unless new_resource.env.empty?
Chef::Log.debug("Setting up environment files for #{new_resource.service_name}")
do_action(env_dir, :create)
env_files.each do |file|
file.action.each { |action| do_action(file, action) }
directory "#{sv_dir_name}/log/main" do
owner new_resource.owner
group new_resource.group
mode '0755'
recursive true
action :create
end
directory new_resource.log_dir do
owner new_resource.owner
group new_resource.group
mode '00755'
recursive true
action :create
end
template "#{sv_dir_name}/log/config" do
owner new_resource.owner
group new_resource.group
mode '00644'
cookbook 'runit'
source 'log-config.erb'
variables(config: new_resource)
notifies :run, 'ruby_block[restart_log_service]', :delayed
action :create
end
link "#{new_resource.log_dir}/config" do
to "#{sv_dir_name}/log/config"
end
if new_resource.default_logger
file "#{sv_dir_name}/log/run" do
content default_logger_content
owner new_resource.owner
group new_resource.group
mode '00755'
action :create
notifies :run, 'ruby_block[restart_log_service]', :delayed
end
else
Chef::Log.debug("Environment not specified for #{new_resource.service_name}, continuing")
end
if new_resource.check
Chef::Log.debug("Creating check script for #{new_resource.service_name}")
do_action(check_script, :create)
else
Chef::Log.debug("Check script not specified for #{new_resource.service_name}, continuing")
end
if new_resource.finish
Chef::Log.debug("Creating finish script for #{new_resource.service_name}")
do_action(finish_script, :create)
else
Chef::Log.debug("Finish script not specified for #{new_resource.service_name}, continuing")
end
unless new_resource.control.empty?
Chef::Log.debug("Creating control signal scripts for #{new_resource.service_name}")
do_action(control_dir, :create)
control_signal_files.each { |file| do_action(file, :create) }
else
Chef::Log.debug("Control signals not specified for #{new_resource.service_name}, continuing")
end
end
Chef::Log.debug("Creating lsb_init compatible interface #{new_resource.service_name}")
do_action(lsb_init, :create)
end
def enable_service
Chef::Log.debug("Creating symlink in service_dir for #{new_resource.service_name}")
do_action(service_link, :create)
unless inside_docker?
Chef::Log.debug("waiting until named pipe #{service_dir_name}/supervise/ok exists.")
until ::FileTest.pipe?("#{service_dir_name}/supervise/ok")
sleep 1
Chef::Log.debug('.')
end
if new_resource.log
Chef::Log.debug("waiting until named pipe #{service_dir_name}/log/supervise/ok exists.")
until ::FileTest.pipe?("#{service_dir_name}/log/supervise/ok")
sleep 1
Chef::Log.debug('.')
template "#{sv_dir_name}/log/run" do
owner new_resource.owner
group new_resource.group
mode '00755'
source "sv-#{new_resource.log_template_name}-log-run.erb"
cookbook template_cookbook
variables(options: new_resource.options)
action :create
notifies :run, 'ruby_block[restart_log_service]', :delayed
end
end
else
Chef::Log.debug("skipping */supervise/ok check inside docker")
end
end
def disable_service
shell_out("#{new_resource.sv_bin} #{sv_args}down #{service_dir_name}")
Chef::Log.debug("#{new_resource} down")
FileUtils.rm(service_dir_name)
Chef::Log.debug("#{new_resource} service symlink removed")
end
# environment stuff
directory "#{sv_dir_name}/env" do
owner new_resource.owner
group new_resource.group
mode '00755'
action :create
end
def start_service
shell_out!("#{new_resource.sv_bin} #{sv_args}start #{service_dir_name}")
end
def stop_service
shell_out!("#{new_resource.sv_bin} #{sv_args}stop #{service_dir_name}")
end
def restart_service
shell_out!("#{new_resource.sv_bin} #{sv_args}restart #{service_dir_name}")
end
def restart_log_service
shell_out!("#{new_resource.sv_bin} #{sv_args}restart #{service_dir_name}/log")
end
def reload_service
shell_out!("#{new_resource.sv_bin} #{sv_args}force-reload #{service_dir_name}")
end
def reload_log_service
shell_out!("#{new_resource.sv_bin} #{sv_args}force-reload #{service_dir_name}/log")
end
#
# Addtional Runit-only actions
#
# only take action if the service is running
[:down, :hup, :int, :term, :kill, :quit].each do |signal|
define_method "action_#{signal}".to_sym do
if current_resource.running
runit_send_signal(signal)
else
Chef::Log.debug("#{new_resource} not running - nothing to do")
new_resource.env.map do |var, value|
file "#{sv_dir_name}/env/#{var}" do
owner new_resource.owner
group new_resource.group
content value
mode 00640
action :create
end
end
end
# only take action if service is *not* running
[:up, :once, :cont].each do |signal|
define_method "action_#{signal}".to_sym do
if current_resource.running
Chef::Log.debug("#{new_resource} already running - nothing to do")
else
runit_send_signal(signal)
ruby_block "zap extra env files for #{new_resource.name} service" do
block { zap_extra_env_files }
only_if { extra_env_files? }
not_if { new_resource.env.empty? }
action :run
end
if new_resource.check
template "#{sv_dir_name}/check" do
owner new_resource.owner
group new_resource.group
mode '00755'
cookbook template_cookbook
source "sv-#{new_resource.check_script_template_name}-check.erb"
variables(options: new_resource.options)
action :create
end
end
end
def action_usr1
runit_send_signal(1, :usr1)
end
def action_usr2
runit_send_signal(2, :usr2)
end
private
def runit_send_signal(signal, friendly_name = nil)
friendly_name ||= signal
converge_by("send #{friendly_name} to #{new_resource}") do
shell_out!("#{new_resource.sv_bin} #{sv_args}#{signal} #{service_dir_name}")
Chef::Log.info("#{new_resource} sent #{friendly_name}")
if new_resource.finish
template "#{sv_dir_name}/finish" do
owner new_resource.owner
group new_resource.group
mode '00755'
source "sv-#{new_resource.finish_script_template_name}-finish.erb"
cookbook template_cookbook
variables(options: new_resource.options) if new_resource.options.respond_to?(:has_key?)
action :create
end
end
end
def running?
cmd = shell_out("#{new_resource.sv_bin} #{sv_args}status #{service_dir_name}")
(cmd.stdout =~ /^run:/ && cmd.exitstatus == 0)
end
directory "#{sv_dir_name}/control" do
owner new_resource.owner
group new_resource.group
mode '00755'
action :create
end
def log_running?
cmd = shell_out("#{new_resource.sv_bin} #{sv_args}status #{service_dir_name}/log")
(cmd.stdout =~ /^run:/ && cmd.exitstatus == 0)
end
def enabled?
::File.exists?(::File.join(service_dir_name, 'run'))
end
def log_service_name
::File.join(new_resource.service_name, 'log')
end
def sv_dir_name
::File.join(new_resource.sv_dir, new_resource.service_name)
end
def sv_args
sv_args = ''
sv_args += "-w '#{new_resource.sv_timeout}' " unless new_resource.sv_timeout.nil?
sv_args += '-v ' if new_resource.sv_verbose
sv_args
end
def service_dir_name
::File.join(new_resource.service_dir, new_resource.service_name)
end
def log_dir_name
::File.join(new_resource.service_dir, new_resource.service_name, log)
end
def template_cookbook
new_resource.cookbook.nil? ? new_resource.cookbook_name.to_s : new_resource.cookbook
end
def default_logger_content
"#!/bin/sh
exec svlogd -tt /var/log/#{new_resource.service_name}"
end
#
# Helper Resources
#
def do_action(resource, action)
resource.run_action(action)
new_resource.updated_by_last_action(true) if resource.updated_by_last_action?
end
def sv_dir
@sv_dir ||=
begin
d = Chef::Resource::Directory.new(sv_dir_name, run_context)
d.recursive(true)
d.owner(new_resource.owner)
d.group(new_resource.group)
d.mode(00755)
d
new_resource.control.map do |signal|
template "#{sv_dir_name}/control/#{signal}" do
owner new_resource.owner
group new_resource.group
mode '0755'
source "sv-#{new_resource.control_template_names[signal]}-#{signal}.erb"
cookbook template_cookbook
variables(options: new_resource.options)
action :create
end
end
end
def run_script
@run_script ||=
begin
t = Chef::Resource::Template.new(::File.join(sv_dir_name, 'run'), run_context)
t.owner(new_resource.owner)
t.group(new_resource.group)
t.source("sv-#{new_resource.run_template_name}-run.erb")
t.cookbook(template_cookbook)
t.mode(00755)
t.variables(:options => new_resource.options) if new_resource.options.respond_to?(:has_key?)
t
# lsb_init
if node['platform'] == 'debian'
ruby_block "unlink #{parsed_lsb_init_dir}/#{new_resource.service_name}" do
block { ::File.unlink("#{parsed_lsb_init_dir}/#{new_resource.service_name}") }
only_if { ::File.symlink?("#{parsed_lsb_init_dir}/#{new_resource.service_name}") }
end
end
def log_dir
@log_dir ||=
begin
d = Chef::Resource::Directory.new(::File.join(sv_dir_name, 'log'), run_context)
d.recursive(true)
d.owner(new_resource.owner)
d.group(new_resource.group)
d.mode(00755)
d
end
end
def log_main_dir
@log_main_dir ||=
begin
d = Chef::Resource::Directory.new(::File.join(sv_dir_name, 'log', 'main'), run_context)
d.recursive(true)
d.owner(new_resource.owner)
d.group(new_resource.group)
d.mode(00755)
d
end
end
def default_log_dir
@default_log_dir ||=
begin
d = Chef::Resource::Directory.new(::File.join("/var/log/#{new_resource.service_name}"), run_context)
d.recursive(true)
d.owner(new_resource.owner)
d.group(new_resource.group)
d.mode(00755)
d
end
end
def log_run_script
@log_run_script ||=
begin
if new_resource.default_logger
f = Chef::Resource::File.new(
::File.join(sv_dir_name, 'log', 'run'),
run_context
)
f.content(default_logger_content)
f.owner(new_resource.owner)
f.group(new_resource.group)
f.mode(00755)
f
else
t = Chef::Resource::Template.new(
::File.join(sv_dir_name, 'log', 'run'),
run_context
)
t.owner(new_resource.owner)
t.group(new_resource.group)
t.mode(00755)
t.source("sv-#{new_resource.log_template_name}-log-run.erb")
t.cookbook(template_cookbook)
t.variables(:options => new_resource.options) if new_resource.options.respond_to?(:has_key?)
t
end
end
end
def log_config_file
@log_config_file ||=
begin
t = Chef::Resource::Template.new(::File.join(sv_dir_name, 'log', 'config'), run_context)
t.owner(new_resource.owner)
t.group(new_resource.group)
t.mode(00644)
t.cookbook('runit')
t.source('log-config.erb')
t.variables(
:size => new_resource.log_size,
:num => new_resource.log_num,
:min => new_resource.log_min,
:timeout => new_resource.log_timeout,
:processor => new_resource.log_processor,
:socket => new_resource.log_socket,
:prefix => new_resource.log_prefix,
:append => new_resource.log_config_append
template "#{parsed_lsb_init_dir}/#{new_resource.service_name}" do
owner 'root'
group 'root'
mode '00755'
cookbook 'runit'
source 'init.d.erb'
variables(
name: new_resource.service_name,
sv_bin: new_resource.sv_bin,
init_dir: ::File.join(parsed_lsb_init_dir, '')
)
t
action :create
end
end
def env_dir
@env_dir ||=
begin
d = Chef::Resource::Directory.new(::File.join(sv_dir_name, 'env'), run_context)
d.owner(new_resource.owner)
d.group(new_resource.group)
d.mode(00755)
d
else
link "#{parsed_lsb_init_dir}/#{new_resource.service_name}" do
to sv_bin
action :create
end
end
def env_files
@env_files ||=
begin
create_files = new_resource.env.map do |var, value|
f = Chef::Resource::File.new(::File.join(sv_dir_name, 'env', var), run_context)
f.owner(new_resource.owner)
f.group(new_resource.group)
f.content(value)
f.action(:create)
f
end
extra_env = current_resource.env.reject { |k,_| new_resource.env.key?(k) }
delete_files = extra_env.map do |k,_|
f = Chef::Resource::File.new(::File.join(sv_dir_name, 'env', k), run_context)
f.action(:delete)
f
end
create_files + delete_files
end
end
def get_current_env
env_dir = ::File.join(sv_dir_name, 'env')
return {} unless ::File.directory? env_dir
files = ::Dir.glob(::File.join(env_dir,'*'))
env = files.reduce({}) do |c,o|
contents = ::IO.read(o).rstrip
c.merge!(::File.basename(o) => contents)
end
env
# Create/Delete service down file
# To prevent unexpected behavior, require users to explicitly set
# delete_downfile to remove any down file that may already exist
df_action = :nothing
if new_resource.start_down
df_action = :create
elsif new_resource.delete_downfile
df_action = :delete
end
file down_file do
mode 00644
backup false
content '# File created and managed by chef!'
action df_action
end
end
end
action :disable do
ruby_block "disable #{new_resource.service_name}" do
block { disable_service }
only_if { enabled? }
end
end
action :enable do
# FIXME: remove action_create in next major version
action_create
directory new_resource.service_dir
link "#{service_dir_name}" do
to sv_dir_name
action :create
end
def check_script
@check_script ||=
begin
t = Chef::Resource::Template.new(::File.join(sv_dir_name, 'check'), run_context)
t.owner(new_resource.owner)
t.group(new_resource.group)
t.source("sv-#{new_resource.check_script_template_name}-check.erb")
t.cookbook(template_cookbook)
t.mode(00755)
t.variables(:options => new_resource.options) if new_resource.options.respond_to?(:has_key?)
t
end
ruby_block "wait for #{new_resource.service_name} service socket" do
block do
wait_for_service
end
action :run
end
end
def finish_script
@finish_script ||=
begin
t = Chef::Resource::Template.new(::File.join(sv_dir_name, 'finish'), run_context)
t.owner(new_resource.owner)
t.group(new_resource.group)
t.mode(00755)
t.source("sv-#{new_resource.finish_script_template_name}-finish.erb")
t.cookbook(template_cookbook)
t.variables(:options => new_resource.options) if new_resource.options.respond_to?(:has_key?)
t
end
# signals
VALID_SIGNALS.each do |signal, signal_name|
action(signal_name || signal) do
if running?
Chef::Log.info "#{new_resource} signalled (#{(signal_name || signal).to_s.upcase})"
runit_send_signal(signal, signal_name)
else
Chef::Log.debug "#{new_resource} not running - nothing to do"
end
end
end
def control_dir
@control_dir ||=
begin
d = Chef::Resource::Directory.new(::File.join(sv_dir_name, 'control'), run_context)
d.owner(new_resource.owner)
d.group(new_resource.group)
d.mode(00755)
d
end
end
action :nothing do
end
def control_signal_files
@control_signal_files ||=
begin
new_resource.control.map do |signal|
t = Chef::Resource::Template.new(
::File.join(sv_dir_name, 'control', signal),
run_context
)
t.owner(new_resource.owner)
t.group(new_resource.group)
t.mode(00755)
t.source("sv-#{new_resource.control_template_names[signal]}-#{signal}.erb")
t.cookbook(template_cookbook)
t.variables(:options => new_resource.options) if new_resource.options.respond_to?(:has_key?)
t
end
end
end
action :restart do
restart_service
end
def lsb_init
@lsb_init ||=
begin
initfile = ::File.join(new_resource.lsb_init_dir, new_resource.service_name)
if node['platform'] == 'debian'
::File.unlink(initfile) if ::File.symlink?(initfile)
t = Chef::Resource::Template.new(initfile, run_context)
t.owner('root')
t.group('root')
t.mode(00755)
t.cookbook('runit')
t.source('init.d.erb')
t.variables(:name => new_resource.service_name)
t
else
l = Chef::Resource::Link.new(initfile, run_context)
l.to(new_resource.sv_bin)
l
end
end
action :start do
if running?
Chef::Log.debug "#{new_resource} already running - nothing to do"
else
start_service
Chef::Log.info "#{new_resource} started"
end
end
def service_link
@service_link ||=
begin
l = Chef::Resource::Link.new(::File.join(service_dir_name), run_context)
l.to(sv_dir_name)
l
end
action :stop do
if running?
stop_service
Chef::Log.info "#{new_resource} stopped"
else
Chef::Log.debug "#{new_resource} already stopped - nothing to do"
end
end
def inside_docker?
results = `cat /proc/1/cgroup`.strip.split("\n")
results.any?{|val| /docker/ =~ val}
action :reload do
if running?
reload_service
Chef::Log.info "#{new_resource} reloaded"
else
Chef::Log.debug "#{new_resource} not running - nothing to do"
end
end
action :status do
running?
end
end
end
end

View File

@@ -29,8 +29,8 @@ class Chef
super
runit_node = runit_attributes_from_node(run_context)
@resource_name = :runit_service
@provider = Chef::Provider::Service::Runit
@supports = { :restart => true, :reload => true, :status => true }
@provider = Chef::Provider::RunitService
@supports = { restart: true, reload: true, status: true }
@action = :enable
@allowed_actions = [:nothing, :start, :stop, :enable, :disable, :restart, :reload, :status, :once, :hup, :cont, :term, :kill, :up, :down, :usr1, :usr2, :create]
@@ -47,6 +47,8 @@ class Chef
@log = true
@cookbook = nil
@check = false
@start_down = false
@delete_downfile = false
@finish = false
@owner = nil
@group = nil
@@ -63,6 +65,7 @@ class Chef
@sv_templates = true
@sv_timeout = nil
@sv_verbose = false
@log_dir = ::File.join('/var/log/', @service_name)
@log_size = nil
@log_num = nil
@log_min = nil
@@ -94,103 +97,114 @@ class Chef
end
def sv_bin(arg = nil)
set_or_return(:sv_bin, arg, :kind_of => [String])
set_or_return(:sv_bin, arg, kind_of: [String])
end
def sv_dir(arg = nil)
set_or_return(:sv_dir, arg, :kind_of => [String, FalseClass])
set_or_return(:sv_dir, arg, kind_of: [String, FalseClass])
end
def sv_timeout(arg = nil)
set_or_return(:sv_timeout, arg, :kind_of => [Fixnum])
set_or_return(:sv_timeout, arg, kind_of: [Fixnum])
end
def sv_verbose(arg = nil)
set_or_return(:sv_verbose, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:sv_verbose, arg, kind_of: [TrueClass, FalseClass])
end
def service_dir(arg = nil)
set_or_return(:service_dir, arg, :kind_of => [String])
set_or_return(:service_dir, arg, kind_of: [String])
end
def lsb_init_dir(arg = nil)
set_or_return(:lsb_init_dir, arg, :kind_of => [String])
set_or_return(:lsb_init_dir, arg, kind_of: [String])
end
def control(arg = nil)
set_or_return(:control, arg, :kind_of => [Array])
set_or_return(:control, arg, kind_of: [Array])
end
def options(arg = nil)
@env.empty? ? opts = @options : opts = @options.merge!(:env_dir => ::File.join(@sv_dir, @service_name, 'env'))
default_opts = @env.empty? ? @options : @options.merge(env_dir: ::File.join(@sv_dir, @service_name, 'env'))
merged_opts = arg.respond_to?(:merge) ? default_opts.merge(arg) : default_opts
set_or_return(
:options,
arg,
:kind_of => [Hash],
:default => opts
merged_opts,
kind_of: [Hash],
default: default_opts
)
end
def env(arg = nil)
set_or_return(:env, arg, :kind_of => [Hash])
set_or_return(:env, arg, kind_of: [Hash])
end
## set log to current instance value if nothing is passed.
def log(arg = @log)
set_or_return(:log, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:log, arg, kind_of: [TrueClass, FalseClass])
end
def cookbook(arg = nil)
set_or_return(:cookbook, arg, :kind_of => [String])
set_or_return(:cookbook, arg, kind_of: [String])
end
def finish(arg = nil)
set_or_return(:finish, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:finish, arg, kind_of: [TrueClass, FalseClass])
end
def check(arg = nil)
set_or_return(:check, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:check, arg, kind_of: [TrueClass, FalseClass])
end
def start_down(arg = nil)
set_or_return(:start_down, arg, kind_of: [TrueClass, FalseClass])
end
def delete_downfile(arg = nil)
set_or_return(:delete_downfile, arg, kind_of: [TrueClass, FalseClass])
end
def owner(arg = nil)
set_or_return(:owner, arg, :regex => [Chef::Config[:user_valid_regex]])
set_or_return(:owner, arg, regex: [Chef::Config[:user_valid_regex]])
end
def group(arg = nil)
set_or_return(:group, arg, :regex => [Chef::Config[:group_valid_regex]])
set_or_return(:group, arg, regex: [Chef::Config[:group_valid_regex]])
end
def default_logger(arg = nil)
set_or_return(:default_logger, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:default_logger, arg, kind_of: [TrueClass, FalseClass])
end
def restart_on_update(arg = nil)
set_or_return(:restart_on_update, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:restart_on_update, arg, kind_of: [TrueClass, FalseClass])
end
def run_template_name(arg = nil)
set_or_return(:run_template_name, arg, :kind_of => [String])
set_or_return(:run_template_name, arg, kind_of: [String])
end
alias_method :template_name, :run_template_name
def log_template_name(arg = nil)
set_or_return(:log_template_name, arg, :kind_of => [String])
set_or_return(:log_template_name, arg, kind_of: [String])
end
def check_script_template_name(arg = nil)
set_or_return(:check_script_template_name, arg, :kind_of => [String])
set_or_return(:check_script_template_name, arg, kind_of: [String])
end
def finish_script_template_name(arg = nil)
set_or_return(:finish_script_template_name, arg, :kind_of => [String])
set_or_return(:finish_script_template_name, arg, kind_of: [String])
end
def control_template_names(arg = nil)
set_or_return(
:control_template_names,
arg,
:kind_of => [Hash],
:default => set_control_template_names
kind_of: [Hash],
default: set_control_template_names
)
end
@@ -202,39 +216,43 @@ class Chef
end
def sv_templates(arg = nil)
set_or_return(:sv_templates, arg, :kind_of => [TrueClass, FalseClass])
set_or_return(:sv_templates, arg, kind_of: [TrueClass, FalseClass])
end
def log_dir(arg = nil)
set_or_return(:log_dir, arg, kind_of: [String])
end
def log_size(arg = nil)
set_or_return(:log_size, arg, :kind_of => [Integer])
set_or_return(:log_size, arg, kind_of: [Integer])
end
def log_num(arg = nil)
set_or_return(:log_num, arg, :kind_of => [Integer])
set_or_return(:log_num, arg, kind_of: [Integer])
end
def log_min(arg = nil)
set_or_return(:log_min, arg, :kind_of => [Integer])
set_or_return(:log_min, arg, kind_of: [Integer])
end
def log_timeout(arg = nil)
set_or_return(:log_timeout, arg, :kind_of => [Integer])
set_or_return(:log_timeout, arg, kind_of: [Integer])
end
def log_processor(arg = nil)
set_or_return(:log_processor, arg, :kind_of => [String])
set_or_return(:log_processor, arg, kind_of: [String])
end
def log_socket(arg = nil)
set_or_return(:log_socket, arg, :kind_of => [String, Hash])
set_or_return(:log_socket, arg, kind_of: [String, Hash])
end
def log_prefix(arg = nil)
set_or_return(:log_prefix, arg, :kind_of => [String])
set_or_return(:log_prefix, arg, kind_of: [String])
end
def log_config_append(arg = nil)
set_or_return(:log_config_append, arg, :kind_of => [String])
set_or_return(:log_config_append, arg, kind_of: [String])
end
def runit_attributes_from_node(run_context)

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,15 @@
name 'runit'
maintainer 'Heavy Water Operations, LLC.'
maintainer_email 'support@hw-ops.com'
license 'Apache 2.0'
description 'Installs runit and provides runit_service definition'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '1.7.6'
recipe 'runit', 'Installs and configures runit'
%w(ubuntu debian gentoo centos redhat amazon scientific oracle enterpriseenterprise).each do |os|
supports os
end
depends 'packagecloud'

View File

@@ -42,6 +42,12 @@ when 'rhel', 'fedora'
packagecloud_repo 'imeyer/runit' unless node['runit']['prefer_local_yum']
package 'runit'
if node['platform_version'].to_i == 7
service 'runsvdir-start' do
action [:start, :enable]
end
end
when 'debian', 'gentoo'
if platform?('gentoo')
@@ -59,7 +65,7 @@ when 'debian', 'gentoo'
action :install
response_file 'runit.seed' if platform?('ubuntu', 'debian')
notifies value_for_platform(
'debian' => { '4.0' => :run, 'default' => :nothing },
'debian' => { '4.0' => :run, 'default' => :nothing },
'ubuntu' => {
'default' => :nothing,
'9.04' => :run,

View File

@@ -13,8 +13,8 @@
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="runit-managed <%= @name %>"
NAME=<%= @name %>
RUNIT=/usr/bin/sv
SCRIPTNAME=/etc/init.d/$NAME
RUNIT=<%= @sv_bin %>
SCRIPTNAME=<%= @init_dir %>$NAME
# Exit if runit is not installed
[ -x $RUNIT ] || exit 0

View File

@@ -1,24 +1,24 @@
<% if @size -%>
s<%= @size %>
<% if @config.log_size -%>
s<%= @config.log_size %>
<% end -%>
<% if @num -%>
n<%= @num %>
<% if @config.log_num -%>
n<%= @config.log_num %>
<% end -%>
<% if @min -%>
N<%= @min %>
<% if @config.log_min -%>
N<%= @config.log_min %>
<% end -%>
<% if @timeout -%>
t<%= @timeout %>
<% if @config.log_timeout -%>
t<%= @config.log_timeout %>
<% end -%>
<% if @processor -%>
!<%= @processor %>
<% if @config.log_processor -%>
!<%= @config.log_processor %>
<% end -%>
<% if @socket -%>
u<%= @socket %>
<% if @config.log_socket -%>
u<%= @config.log_socket %>
<% end -%>
<% if @prefix -%>
p<%= @prefix %>
<% if @config.log_prefix -%>
p<%= @config.log_prefix %>
<% end -%>
<% if @append -%>
<%= @append %>
<% if @config.log_config_append -%>
<%= @config.log_config_append %>
<% end -%>