Initial Chef repository

This commit is contained in:
Greg Karékinian
2015-07-21 19:45:23 +02:00
parent 7e5401fc71
commit ee4079fa85
1151 changed files with 185163 additions and 0 deletions

View File

@@ -0,0 +1,192 @@
runit Cookbook CHANGELOG
========================
This file is used to list changes made in each version of the runit cookbook.
v1.6.0 (2015-04-06)
--------------------
* Fedora 21 support
* Kitchen platform updates
* use imeyers packagecloud repo for RHEL
* fix converge_by usage
* do_action helper to set updated_by_last_action
* style fixes to provider
v1.5.18 (2015-03-13)
--------------------
* Add helper methods to detect installation presence
v1.5.16 (2015-02-11)
--------------------
* Allow removal of env files(nhuff)
v1.5.14 (2015-01-15)
--------------------
* Provide create action(clako)
v1.5.12 (2014-12-15)
--------------------
* prevent infinite loop inside docker container
* runit service failing inside docker container
* move to librarian-chef for kitchen dependency resolution
* update tests
* updates to chefspec matchers
v1.5.10 (2014-03-07)
--------------------
PR #53- Fix runit RPM file location for Chef provisionless Centos 5.9 Box Image
v1.5.9
------
Fix runit RPM file location for Chef provisionless Centos 5.9 Box Image
v1.5.8
------
Fixing string interpolation bug
v1.5.3
------
Fixing assignment/compare error
v1.5.1
------
### Bug
- **[COOK-3950](https://tickets.chef.io/browse/COOK-3950)** - runit cookbook should use full service path when checking running status
v1.5.0
------
### Improvement
- **[COOK-3267] - Improve testing suite in runit cookbook
- Updating test-kitchen harness
- Cleaning up style for rubocop
v1.4.4
------
fixing metadata version error. locking to < 3.0
v1.4.2
------
Locking yum dependency to '< 3'
v1.4.0
------
[COOK-3560] Allow the user to configure runit's timeout (-w) and verbose (-v) settings
v1.3.0
------
### Improvement
- **[COOK-3663](https://tickets.chef.io/browse/COOK-3663)** - Add ./check scripts support
### Bug
- **[COOK-3271](https://tickets.chef.io/browse/COOK-3271)** - Fix an issue where runit fails to install rpm package on rehl systems
v1.2.0
------
### New Feature
- **[COOK-3243](https://tickets.chef.io/browse/COOK-3243)** - Expose LSB init directory as a configurable
### Bug
- **[COOK-3182](https://tickets.chef.io/browse/COOK-3182)** - Do not hardcode rpmbuild location
### Improvement
- **[COOK-3175](https://tickets.chef.io/browse/COOK-3175)** - Add svlogd config file support
- **[COOK-3115](https://tickets.chef.io/browse/COOK-3115)** - Add ability to install 'runit' package from Yum
v1.1.6
------
### Bug
- [COOK-2353]: Runit does not update run template if the service is already enabled
- [COOK-3013]: Runit install fails on rhel if converge is only partially successful
v1.1.4
------
### Bug
- [COOK-2549]: cannot enable_service (lwrp) on Gentoo
- [COOK-2567]: Runit doesn't start at boot in Gentoo
- [COOK-2629]: runit tests have ruby 1.9 method chaning syntax
- [COOK-2867]: On debian, runit recipe will follow symlinks from /etc/init.d, overwrite /usr/bin/sv
v1.1.2
------
- [COOK-2477] - runit cookbook should enable EPEL repo for CentOS 5
- [COOK-2545] - Runit cookbook fails on Amazon Linux
- [COOK-2322] - runit init template is broken on debian
v1.1.0
------
- [COOK-2353] - Runit does not update run template if the service is already enabled
- [COOK-2497] - add :nothing to allowed actions
v1.0.6
------
- [COOK-2404] - allow sending sigquit
- [COOK-2431] - gentoo - it should create the runit-start template before calling it
v1.0.4
------
- [COOK-2351] - add `run_template_name` to allow alternate run script template
v1.0.2
------
- [COOK-2299] - runit_service resource does not properly start a non-running service
v1.0.0
------
- [COOK-2254] - (formerly CHEF-154) Convert `runit_service` definition to a service resource named `runit_service`.
This version has some backwards incompatible changes (hence the major
version bump). It is recommended that users pin the cookbook to the
previous version where it is a dependency until this version has been
tested in a non-production environment (use version 0.16.2):
depends "runit", "<= 0.16.2"
If you use Chef environments, pin the version in the appropriate
environment(s).
**Changes of note**
1. The "runit" recipe must be included before the runit_service resource
can be used.
2. The `runit_service` definition created a separate `service`
resource for notification purposes. This is still available, but the
only actions that can be notified are `:start`, `:stop`, and `:restart`.
3. The `:enable` action blocks waiting for supervise/ok after the
service symlink is created.
4. User-controlled services should be created per the runit
documentation; see README.md for an example.
5. Some parameters in the definition have changed names in the
resource. See below.
The following parameters in the definition are renamed in the resource
to clarify their intent.
- directory -> sv_dir
- active_directory -> service_dir
- template_name -> use service_name (name attribute)
- nolog -> set "log" to false
- start_command -> unused (was previously in the "service" resource)
- stop_command -> unused (was previously in the "service" resource)
- restart_command -> unused (was previously in the "service" resource)
v0.16.2
-------
- [COOK-1576] - Do not symlink /etc/init.d/servicename to /usr/bin/sv on debian
- [COOK-1960] - default_logger still looks for sv-service-log-run template
- [COOK-2035] - runit README change
v0.16.0
-------
- [COOK-794] default logger and `no_log` for `runit_service` definition
- [COOK-1165] - restart functionality does not work right on Gentoo due to the wrong directory in the attributes
- [COOK-1440] - Delegate service control to normal user
v0.15.0
-------
- [COOK-1008] - Added parameters for names of different templates in runit

421
cookbooks/runit/README.md Normal file
View File

@@ -0,0 +1,421 @@
runit Cookbook
==============
Installs runit and provides the `runit_service` service resource for managing processes (services) under runit.
This cookbook does not use runit to replace system init, nor are ther plans to do so.
For more information about runit:
- http://smarden.org/runit/
Requirements
------------
### Platforms
- Debian/Ubuntu
- Gentoo
- RHEL
### Cookbooks
- packagecloud (for RHEL)
Attributes
----------
See `attributes/default.rb` for defaults generated per platform.
- `node['runit']['sv_bin']` - Full path to the `sv` binary.
- `node['runit']['chpst_bin']` - Full path to the `chpst` binary.
- `node['runit']['service_dir']` - Full path to the default "services" directory where enabled services are linked.
- `node['runit']['sv_dir']` - Full path to the directory where service lives, which gets linked to `service_dir`.
- `node['runit']['lsb_init_dir']` - Full path to the directory where the LSB-compliant init script interface will be created.
- `node['runit']['start']` - Command to start the runsvdir service
- `node['runit']['stop]` - Command to stop the runsvdir service
- `node['runit']['reload']` - Command to reload the runsvdir service
### Optional Attributes for RHEL systems
- `node['runit']['prefer_local_yum']` - If `true`, assumes that a `runit` package is available on an already configured local yum repository. By default, the recipe installs the `runit` package from a Package Cloud repository (see below). This is set to the value of `node['runit']['use_package_from_yum']` for backwards compatibility, but otherwise defaults to `false`.
Recipes
-------
### default
The default recipe installs runit and starts `runsvdir` to supervise the services in runit's service directory (e.g., `/etc/service`).
On RHEL-family systems, it will install the runit RPM using [Ian Meyer's Package Cloud repository](https://packagecloud.io/imeyer/runit) for runit. This replaces the previous functionality where the RPM was build using his [runit RPM SPEC](https://github.com/imeyer/runit-rpm). However, if the attribute `node['runit']['prefer_local_yum']` is set to `true`, the packagecloud repository creation will be skipped and it is assumed that a `runit` package is available on an otherwise configured (outside this cookbook) local repository.
On Debian family systems, the runit packages are maintained by the runit author, Gerrit Pape, and the recipe will use that for installation.
On Gentoo, the runit ebuild package is installed.
Resource/Provider
-----------------
This cookbook has a resource, `runit_service`, for managing services under runit. This service subclasses the Chef `service` resource.
**This resource replaces the runit_service definition. See the CHANGELOG.md file in this cookbook for breaking change information and any actions you may need to take to update cookbooks using runit_service.**
### Actions
- **enable** - enables the service, creating the required run scripts and symlinks. This is the default action.
- **start** - starts the service with `sv start`
- **stop** - stops the service with `sv stop`
- **disable** - stops the service with `sv down` and removes the service symlink
- **create** - create the service directory, but don't enable the service with symlink
- **restart** - restarts the service with `sv restart`
- **reload** - reloads the service with `sv force-reload`
- **once** - starts the service with `sv once`.
- **hup** - sends the `HUP` signal to the service with `sv hup`
- **cont** - sends the `CONT` signal to the service
- **term** - sends the `TERM` signal to the service
- **kill** - sends the `KILL` signal to the service
- **up** - starts the service with `sv up`
- **down** - downs the service with `sv down`
- **usr1** - sends the `USR1` signal to the service with `sv 1`
- **usr2** - sends the `USR2` signal to the service with `sv 2`
Service management actions are taken with runit's "`sv`" program.
Read the `sv(8)` [man page](http://smarden.org/runit/sv.8.html) for more information on the `sv` program.
### Parameter Attributes
The first three parameters, `sv_dir`, `service_dir`, and `sv_bin` will attempt to use the corresponding node attributes, and fall back to hardcoded default values that match the settings used on Debian platform systems.
Many of these parameters are only used in the `:enable` action.
- **sv_dir** - The base "service directory" for the services managed by
the resource. By default, this will attempt to use the
`node['runit']['sv_dir']` attribute, and falls back to `/etc/sv`.
- **service_dir** - The directory where services are symlinked to be
supervised by `runsvdir`. By default, this will attempt to use the
`node['runit']['service_dir']` attribute, and falls back to
`/etc/service`.
- **lsb_init_dir** - The directory where an LSB-compliant init script
interface will be created. By default, this will attempt to use the
`node['runit']['lsb_init_dir']` attribute, and falls back to
`/etc/init.d`.
- **sv_bin** - The path to the `sv` program binary. This will attempt
to use the `node['runit']['sv_bin']` attribute, and falls back to
`/usr/bin/sv`.
- **service_name** - *Name attribute*. The name of the service. This
will be used in the directory of the managed service in the
`sv_dir` and `service_dir`.
- **sv_timeout** - Override the default `sv` timeout of 7 seconds.
- **sv_verbose** - Whether to enable `sv` verbose mode. Default is
`false`.
- **sv_templates** - If true, the `:enable` action will create the
service directory with the appropriate templates. Default is
`true`. Set this to `false` if the service has a package that
provides its own service directory. See __Usage__ examples.
- **options** - Options passed as variables to templates, for
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.
- **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_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
after rotation. See svlogd(8) for the default value.
- **log_min** - The minimum number of log files that will be retained
after rotation (if svlogd cannot create a new file and the minimum
has not been reached, it will block). Default is no minimum.
- **log_timeout** - The maximum age a log file can get to before it is
automatically rotated, whether it has reached `log_size` or not.
Default is no timeout.
- **log_processor** - A string containing a path to a program that
rotated log files will be fed through. See the **PROCESSOR** section
of svlogd(8) for details. Default is no processor.
- **log_socket** - An string containing an IP:port pair identifying a UDP
socket that log lines will be copied to. Default is none.
- **log_prefix** - A string that will be prepended to each line as it
is logged. Default is no prefix.
- **log_config_append** - A string containing optional additional lines to add
to the log service configuration. See svlogd(8) for more details.
- **cookbook** - A cookbook where templates are located instead of
where the resource is used. Applies for all the templates in the
`enable` action.
- **check** - whether the service has a check script, requires a
template `sv-service_name-check.erb`
- **finish** - whether the service has a finish script, requires a
template `sv-service_name-finish.erb`
- **control** - An array of signals to customize control of the service,
see [runsv man page](http://smarden.org/runit/runsv.8.html) on how
to use this. This requires that each template be created with the
name `sv-service_name-signal.erb`.
- **owner** - user that should own the templates created to enable the
service
- **group** - group that should own the templates created to enable the
service
- **run_template_name** - alternate filename of the run run script to
use replacing `service_name`.
- **log_template_name** - alternate filename of the log run script to
use replacing `service_name`.
- **check_script_template_name** - alternate filename of the check
script to use, replacing `service_name`.
- **finish_script_template_name** - alternate filename of the finish
script to use, replacing `service_name`.
- **control_template_names** - a hash of control signals (see *control*
above) and their alternate template name(s) replacing
`service_name`.
- **status_command** - The command used to check the status of the
service to see if it is enabled/running (if it's running, it's
enabled). This hardcodes the location of the sv program to
`/usr/bin/sv` due to the aforementioned cookbook load order.
- **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.
Unlike previous versions of the cookbook using the `runit_service` definition, the `runit_service` resource can be notified. See __Usage__ examples below.
Usage
-----
To get runit installed on supported platforms, use `recipe[runit]`. Once it is installed, use the `runit_service` resource to set up services to be managed by runit.
In order to use the `runit_service` resource in your cookbook(s), each service managed will also need to have `sv-service_name-run.erb` and `sv-service_name-log-run.erb` templates created. If the `log` parameter is false, the log run script isn't created. If the `log` parameter is true, and `default_logger` is also true, the log run
script will be created with the default content:
```bash
#!/bin/sh
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).
**Default Example**
This example uses all the defaults in the `:enable` action to set up the service.
We'll set up `chef-client` to run as a service under runit, such as is done in the `chef-client` cookbook. This example will be more simple than in that cookbook. First, create the required run template, `chef-client/templates/default/sv-chef-client-run.erb`.
```bash
#!/bin/sh
exec 2>&1
exec /usr/bin/env chef-client -i 1800 -s 30
```
Then create the required log/run template, `chef-client/templates/default/sv-chef-client-log-run.erb`.
```bash
#!/bin/sh
exec svlogd -tt ./main
```
__Note__ This will cause output of the running process to go to `/etc/sv/chef-client/log/main/current`. Some people may not like this, see the following example. This is preserved for compatibility reasons.
Finally, set up the service in the recipe with:
```ruby
runit_service "chef-client"
```
**Default Logger Example**
To use a default logger with svlogd which will log to `/var/log/chef-client/current`, instead, use the `default_logger` option.
```ruby
runit_service "chef-client" do
default_logger true
end
```
**No Log Service**
If there isn't an appendant log service, set `log` to false, and the log/run script won't be created.
```ruby
runit_service "no-svlog" do
log false
end
```
**Check Script**
To create a service that has a check script in its service directory, set the `check` parameter to `true`, and create a `sv-checker-check.erb` template.
```ruby
runit_service "checker" do
check true
end
```
This will create `/etc/sv/checker/check`.
**Finish Script**
To create a service that has a finish script in its service directory, set the `finish` parameter to `true`, and create a `sv-finisher-finish.erb` template.
```ruby
runit_service "finisher" do
finish true
end
```
This will create `/etc/sv/finisher/finish`.
**Alternate service directory**
If the service directory for the managed service isn't the `sv_dir` (`/etc/sv`), then specify it:
```ruby
runit_service "custom_service" do
sv_dir "/etc/custom_service/runit"
end
```
**No Service Directory**
If the service to manage has a package that provides its service directory, such as `git-daemon` on Debian systems, set `sv_templates` to false.
```ruby
package "git-daemon-run"
runit_service "git-daemon" do
sv_templates false
end
```
This will create the service symlink in `/etc/service`, but it will not manage any templates in the service directory.
**User Controlled Services**
To set up services controlled by a non-privileged user, we follow the recommended configuration in the [runit documentation](http://smarden.org/runit/faq.html#user) (Is it possible to allow a user other than root to control a service?).
Suppose the user's name is floyd, and floyd wants to run floyds-app. Assuming that the floyd user and group are already managed with Chef, create a `runsvdir-floyd` runit_service.
```ruby
runit_service "runsvdir-floyd"
```
Create the `sv-runsvdir-floyd-log-run.erb` template, or add `log false`. Also create the `sv-runsvdir-floyd-run.erb` with the following content:
```bash
#!/bin/sh
exec 2>&1
exec chpst -ufloyd runsvdir /home/floyd/service
```
Next, create the `runit_service` resource for floyd's app:
```ruby
runit_service "floyds-app" do
sv_dir "/home/floyd/sv"
service_dir "/home/floyd/service"
owner "floyd"
group "floyd"
end
```
And now floyd can manage the service with sv:
```text
$ id
uid=1000(floyd) gid=1001(floyd) groups=1001(floyd)
$ sv stop /home/floyd/service/floyds-app/
ok: down: /home/floyd/service/floyds-app/: 0s, normally up
$ sv start /home/floyd/service/floyds-app/
ok: run: /home/floyd/service/floyds-app/: (pid 5287) 0s
$ sv status /home/floyd/service/floyds-app/
run: /home/floyd/service/floyds-app/: (pid 5287) 13s; run: log: (pid 4691) 726s
```
**Options**
Next, let's set up memcached under runit with some additional options using the `options` parameter. First, the `memcached/templates/default/sv-memcached-run.erb` template:
```bash
#!/bin/sh
exec 2>&1
exec chpst -u <%= @options[:user] %> /usr/bin/memcached -v -m <%= @options[:memory] %> -p <%= @options[:port] %>
```
Note that the script uses `chpst` (which comes with runit) to set the user option, then starts memcached on the specified memory and port (see below).
The log/run template, `memcached/templates/default/sv-memcached-log-run.erb`:
```bash
#!/bin/sh
exec svlogd -tt ./main
```
Finally, the `runit_service` in our recipe:
```ruby
runit_service "memcached" do
options({
:memory => node[:memcached][:memory],
:port => node[:memcached][:port],
:user => node[:memcached][:user]}.merge(params)
})
end
```
This is where the user, port and memory options used in the run template are used.
**Notifying Runit Services**
In previous versions of this cookbook where the definition was used, it created a `service` resource that could be notified. With the `runit_service` resource, recipes need to use the full resource name.
For example:
```ruby
runit_service "my-service"
template "/etc/my-service.conf" do
notifies :restart, "runit_service[my-service]"
end
```
Because the resource implements actions for various commands that `sv` can send to the service, any of those actions could be used for notification. For example, `chef-client` supports triggering a Chef run with a USR1 signal.
```ruby
template "/tmp/chef-notifier" do
notifies :usr1, "runit_service[chef-client]"
end
```
For older implementations of services that used `runit_service` as a definition, but may support alternate service styles, use a conditional, such as based on an attribute:
```ruby
service_to_notify = case node['nginx']['init_style']
when "runit"
"runit_service[nginx]"
else
"service[nginx]"
end
template "/etc/nginx/nginx.conf" do
notifies :restart, service_to_notify
end
```
**More Examples**
For more examples, see the `runit_test` cookbook's `service` recipe in the [git repository](https://github.com/chef-cookbooks/runit).
License & Authors
-----------------
- Author:: Adam Jacob <adam@chef.io>
- Author:: Joshua Timberman <joshua@chef.io>
```text
Copyright:: 2008-2013, 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.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
```

View File

@@ -0,0 +1,62 @@
#
# Cookbook Name:: runit
# Attribute File:: sv_bin
#
# Copyright 2008-2009, 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.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
case node['platform_family']
when 'debian'
default['runit']['sv_bin'] = '/usr/bin/sv'
default['runit']['chpst_bin'] = '/usr/bin/chpst'
default['runit']['service_dir'] = '/etc/service'
default['runit']['sv_dir'] = '/etc/sv'
default['runit']['lsb_init_dir'] = '/etc/init.d'
default['runit']['executable'] = '/sbin/runit'
if node['platform'] == 'debian'
default['runit']['start'] = 'runsvdir-start'
default['runit']['stop'] = ''
default['runit']['reload'] = ''
elsif node['platform'] == 'ubuntu'
default['runit']['start'] = 'start runsvdir'
default['runit']['stop'] = 'stop runsvdir'
default['runit']['reload'] = 'reload runsvdir'
end
when 'rhel', 'fedora'
default['runit']['sv_bin'] = '/sbin/sv'
default['runit']['chpst_bin'] = '/sbin/chpst'
default['runit']['service_dir'] = '/etc/service'
default['runit']['sv_dir'] = '/etc/sv'
default['runit']['lsb_init_dir'] = '/etc/init.d'
default['runit']['executable'] = '/sbin/runit'
default['runit']['prefer_local_yum'] = node['runit']['use_package_from_yum'] || false
default['runit']['start'] = '/etc/init.d/runit-start start'
default['runit']['stop'] = '/etc/init.d/runit-start stop'
default['runit']['reload'] = '/etc/init.d/runit-start reload'
when 'gentoo'
default['runit']['sv_bin'] = '/usr/bin/sv'
default['runit']['chpst_bin'] = '/usr/bin/chpst'
default['runit']['service_dir'] = '/var/service'
default['runit']['sv_dir'] = '/etc/sv'
default['runit']['lsb_init_dir'] = '/etc/init.d'
default['runit']['executable'] = '/sbin/runit'
default['runit']['start'] = '/etc/init.d/runit-start start'
default['runit']['stop'] = '/etc/init.d/runit-start stop'
default['runit']['reload'] = '/etc/init.d/runit-start reload'
end

View File

@@ -0,0 +1 @@
runit runit/signalinit boolean true

View File

View File

@@ -0,0 +1,6 @@
start on runlevel-2
start on runlevel-3
start on runlevel-4
start on runlevel-5
stop on shutdown
respawn /usr/sbin/runsvdir-start

View File

@@ -0,0 +1,7 @@
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn
exec /usr/sbin/runsvdir-start

View File

@@ -0,0 +1,7 @@
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn
exec /usr/sbin/runsvdir-start

View File

@@ -0,0 +1,7 @@
start on runlevel 2
start on runlevel 3
start on runlevel 4
start on runlevel 5
stop on shutdown
respawn
exec /usr/sbin/runsvdir-start

View File

View File

@@ -0,0 +1,45 @@
#
# Cookbook:: runit
# Libraries:: helpers
#
# Author: Joshua Timberman <joshua@getchef.com>
# Copyright (c) 2014, Chef Software, Inc. <legal@getchef.com>
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/mixin/shell_out'
include Chef::Mixin::ShellOut
module Runit
module Helpers
def runit_installed?
return true if runit_rpm_installed? || (runit_executable? && runit_sv_works?)
end
def runit_executable?
::File.executable?(node['runit']['executable'])
end
def runit_sv_works?
sv = shell_out("#{node['runit']['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
end
end
end
Chef::Recipe.send(:include, Runit::Helpers)
Chef::Resource.send(:include, Runit::Helpers)

View File

@@ -0,0 +1,67 @@
if defined?(ChefSpec)
def start_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :start, service)
end
def stop_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :stop, service)
end
def enable_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :enable, service)
end
def disable_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :disable, service)
end
def restart_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :restart, service)
end
def reload_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :reload, service)
end
def status_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :status, service)
end
def once_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :once, service)
end
def hup_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :hup, service)
end
def cont_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :cont, service)
end
def term_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :term, service)
end
def kill_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :kill, service)
end
def up_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :up, service)
end
def down_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :down, service)
end
def usr1_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :usr1, service)
end
def usr2_runit_service(service)
ChefSpec::Matchers::ResourceMatcher.new(:runit_service, :usr2, service)
end
end

View File

@@ -0,0 +1,550 @@
#
# Cookbook Name:: runit
# Provider:: service
#
# Copyright 2011, Joshua Timberman
# Copyright 2011, 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.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# 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
def initialize(*args)
super
new_resource.supports[:status] = true
end
def load_current_resource
@current_resource = Chef::Resource::RunitService.new(new_resource.name)
current_resource.service_name(new_resource.service_name)
Chef::Log.debug("Checking status of service #{new_resource.service_name}")
# 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
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")
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")
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) }
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('.')
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
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")
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)
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}")
end
end
def running?
cmd = shell_out("#{new_resource.sv_bin} #{sv_args}status #{service_dir_name}")
(cmd.stdout =~ /^run:/ && cmd.exitstatus == 0)
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
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
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
)
t
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
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
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
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
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
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
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
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
end
def inside_docker?
results = `cat /proc/1/cgroup`.strip.split("\n")
results.any?{|val| /docker/ =~ val}
end
end
end
end
end

View File

@@ -0,0 +1,249 @@
#
# Cookbook Name:: runit
# Provider:: service
#
# Copyright 2011, Joshua Timberman
# Copyright 2011, 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.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require 'chef/resource'
require 'chef/resource/service'
class Chef
class Resource
# Missing top-level class documentation comment
class RunitService < Chef::Resource::Service
def initialize(name, run_context = nil)
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 }
@action = :enable
@allowed_actions = [:nothing, :start, :stop, :enable, :disable, :restart, :reload, :status, :once, :hup, :cont, :term, :kill, :up, :down, :usr1, :usr2, :create]
# sv_bin, sv_dir, service_dir and lsb_init_dir may have been set in the
# node attributes
@sv_bin = runit_node[:sv_bin] || '/usr/bin/sv'
@sv_dir = runit_node[:sv_dir] || '/etc/sv'
@service_dir = runit_node[:service_dir] || '/etc/service'
@lsb_init_dir = runit_node[:lsb_init_dir] || '/etc/init.d'
@control = []
@options = {}
@env = {}
@log = true
@cookbook = nil
@check = false
@finish = false
@owner = nil
@group = nil
@enabled = false
@running = false
@default_logger = false
@restart_on_update = true
@run_template_name = @service_name
@log_template_name = @service_name
@check_script_template_name = @service_name
@finish_script_template_name = @service_name
@control_template_names = {}
@status_command = "#{@sv_bin} status #{@service_dir}"
@sv_templates = true
@sv_timeout = nil
@sv_verbose = false
@log_size = nil
@log_num = nil
@log_min = nil
@log_timeout = nil
@log_processor = nil
@log_socket = nil
@log_prefix = nil
@log_config_append = nil
#
# Backward Compat Hack
#
# This ensures a 'service' resource exists for all 'runit_service' resources.
# This should allow all recipes using the previous 'runit_service' definition to
# continue operating.
#
unless run_context.nil?
service_dir_name = ::File.join(@service_dir, @name)
@service_mirror = Chef::Resource::Service.new(name, run_context)
@service_mirror.provider(Chef::Provider::Service::Simple)
@service_mirror.supports(@supports)
@service_mirror.start_command("#{@sv_bin} start #{service_dir_name}")
@service_mirror.stop_command("#{@sv_bin} stop #{service_dir_name}")
@service_mirror.restart_command("#{@sv_bin} restart #{service_dir_name}")
@service_mirror.status_command("#{@sv_bin} status #{service_dir_name}")
@service_mirror.action(:nothing)
run_context.resource_collection.insert(@service_mirror)
end
end
def sv_bin(arg = nil)
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])
end
def sv_timeout(arg = nil)
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])
end
def service_dir(arg = nil)
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])
end
def control(arg = nil)
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'))
set_or_return(
:options,
arg,
:kind_of => [Hash],
:default => opts
)
end
def env(arg = nil)
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])
end
def cookbook(arg = nil)
set_or_return(:cookbook, arg, :kind_of => [String])
end
def finish(arg = nil)
set_or_return(:finish, arg, :kind_of => [TrueClass, FalseClass])
end
def check(arg = nil)
set_or_return(:check, arg, :kind_of => [TrueClass, FalseClass])
end
def owner(arg = nil)
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]])
end
def default_logger(arg = nil)
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])
end
def run_template_name(arg = nil)
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])
end
def check_script_template_name(arg = nil)
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])
end
def control_template_names(arg = nil)
set_or_return(
:control_template_names,
arg,
:kind_of => [Hash],
:default => set_control_template_names
)
end
def set_control_template_names
@control.each do |signal|
@control_template_names[signal] ||= @service_name
end
@control_template_names
end
def sv_templates(arg = nil)
set_or_return(:sv_templates, arg, :kind_of => [TrueClass, FalseClass])
end
def log_size(arg = nil)
set_or_return(:log_size, arg, :kind_of => [Integer])
end
def log_num(arg = nil)
set_or_return(:log_num, arg, :kind_of => [Integer])
end
def log_min(arg = nil)
set_or_return(:log_min, arg, :kind_of => [Integer])
end
def log_timeout(arg = nil)
set_or_return(:log_timeout, arg, :kind_of => [Integer])
end
def log_processor(arg = nil)
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])
end
def log_prefix(arg = nil)
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])
end
def runit_attributes_from_node(run_context)
if run_context && run_context.node && run_context.node[:runit]
run_context.node[:runit]
else
{}
end
end
end
end
end

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,85 @@
#
# Cookbook Name:: runit
# Recipe:: default
#
# Copyright 2008-2010, 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.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
service 'runit' do
action :nothing
end
execute 'start-runsvdir' do
command value_for_platform(
'debian' => { 'default' => 'runsvdir-start' },
'ubuntu' => { 'default' => 'start runsvdir' },
'gentoo' => { 'default' => '/etc/init.d/runit-start start' }
)
action :nothing
end
execute 'runit-hup-init' do
command 'telinit q'
only_if 'grep ^SV /etc/inittab'
action :nothing
end
case node['platform_family']
when 'rhel', 'fedora'
packagecloud_repo 'imeyer/runit' unless node['runit']['prefer_local_yum']
package 'runit'
when 'debian', 'gentoo'
if platform?('gentoo')
template '/etc/init.d/runit-start' do
source 'runit-start.sh.erb'
mode 0755
end
service 'runit-start' do
action :nothing
end
end
package 'runit' do
action :install
response_file 'runit.seed' if platform?('ubuntu', 'debian')
notifies value_for_platform(
'debian' => { '4.0' => :run, 'default' => :nothing },
'ubuntu' => {
'default' => :nothing,
'9.04' => :run,
'8.10' => :run,
'8.04' => :run },
'gentoo' => { 'default' => :run }
), 'execute[start-runsvdir]', :immediately
notifies value_for_platform(
'debian' => { 'squeeze/sid' => :run, 'default' => :nothing },
'default' => :nothing
), 'execute[runit-hup-init]', :immediately
notifies :enable, 'service[runit-start]' if platform?('gentoo')
end
if node['platform'] =~ /ubuntu/i && node['platform_version'].to_f <= 8.04
cookbook_file '/etc/event.d/runsvdir' do
source 'runsvdir'
mode 0644
notifies :run, 'execute[start-runsvdir]', :immediately
only_if { ::File.directory?('/etc/event.d') }
end
end
end

View File

@@ -0,0 +1,66 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: <%= @name %>
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:
# Short-Description: initscript for runit-managed <%= @name %> service
### END INIT INFO
# Author: Chef Software, Inc. <cookbooks@chef.io>
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="runit-managed <%= @name %>"
NAME=<%= @name %>
RUNIT=/usr/bin/sv
SCRIPTNAME=/etc/init.d/$NAME
# Exit if runit is not installed
[ -x $RUNIT ] || exit 0
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC " "$NAME"
$RUNIT start $NAME
[ "$VERBOSE" != no ] && log_end_msg $?
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
$RUNIT stop $NAME
[ "$VERBOSE" != no ] && log_end_msg $?
;;
status)
$RUNIT status $NAME && exit 0 || exit $?
;;
reload)
[ "$VERBOSE" != no ] && log_daemon_msg "Reloading $DESC" "$NAME"
$RUNIT reload $NAME
[ "$VERBOSE" != no ] && log_end_msg $?
;;
force-reload)
[ "$VERBOSE" != no ] && log_daemon_msg "Force reloading $DESC" "$NAME"
$RUNIT force-reload $NAME
[ "$VERBOSE" != no ] && log_end_msg $?
;;
restart)
[ "$VERBOSE" != no ] && log_daemon_msg "Restarting $DESC" "$NAME"
$RUNIT restart $NAME
[ "$VERBOSE" != no ] && log_end_msg $?
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|reload|force-reload|restart}" >&2
exit 3
;;
esac
:

View File

@@ -0,0 +1,24 @@
<% if @size -%>
s<%= @size %>
<% end -%>
<% if @num -%>
n<%= @num %>
<% end -%>
<% if @min -%>
N<%= @min %>
<% end -%>
<% if @timeout -%>
t<%= @timeout %>
<% end -%>
<% if @processor -%>
!<%= @processor %>
<% end -%>
<% if @socket -%>
u<%= @socket %>
<% end -%>
<% if @prefix -%>
p<%= @prefix %>
<% end -%>
<% if @append -%>
<%= @append %>
<% end -%>

View File

@@ -0,0 +1,32 @@
#!/sbin/runscript
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# $Header: $
depend() {
after net
}
start() {
ebegin "Starting runsvdir"
start-stop-daemon --start --exec /usr/bin/runsvdir \
--background --make-pidfile \
--pidfile /var/run/runsvdir.pid -- <%= node.runit.sv_dir %>
eend $?
}
stop() {
local ret1 ret2
ebegin "Stopping runsvdir"
start-stop-daemon --stop --oknodo --pidfile /var/run/runsvdir.pid
ret1=$?
eend ${ret1}
ebegin "Stopping services and logging"
sv shutdown -w 10 <%= node.runit.sv_dir %>/*
ret2=$?
eend ${ret2}
return $((ret1+ret2))
}