Commit 299bb9ad authored by Sean OMeara's avatar Sean OMeara
Browse files

Modernizing runit_service provider

- Converting to LWRP DSL
- Increading readability
- Initial ChefSpec
- Debian 7 not works
- RHEL 7 support
parent ea354ac4
......@@ -10,7 +10,7 @@ driver_config:
provisioner:
name: chef_zero
require_chef_omnibus: 12.2.1
require_chef_omnibus: latest
platforms:
- name: centos-5.8
......@@ -33,14 +33,14 @@ platforms:
ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
# - name: centos-7.0
# driver_plugin: digital_ocean
# driver_config:
# size: 2gb
# image: centos-7-0-x64
# region: <%= ENV['DIGITALOCEAN_REGION'] %>
# ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
# ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
- name: centos-7.0
driver_plugin: digital_ocean
driver_config:
size: 2gb
image: centos-7-0-x64
region: <%= ENV['DIGITALOCEAN_REGION'] %>
ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
- name: amazon-2014.09
driver_plugin: ec2
......@@ -49,25 +49,25 @@ platforms:
username: ec2-user
ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %>
# - name: fedora-21
# driver_plugin: digital_ocean
# driver_config:
# size: 2gb
# image: fedora-21-x64
# region: <%= ENV['DIGITALOCEAN_REGION'] %>
# ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
# ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
- name: fedora-21
driver_plugin: digital_ocean
driver_config:
size: 2gb
image: fedora-21-x64
region: <%= ENV['DIGITALOCEAN_REGION'] %>
ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
# - name: debian-7.0
# driver_plugin: digital_ocean
# driver_config:
# size: 2gb
# image: debian-7-0-x64
# region: <%= ENV['DIGITALOCEAN_REGION'] %>
# ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
# ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
# run_list:
# - recipe[apt]
- name: debian-7.0
driver_plugin: digital_ocean
driver_config:
size: 2gb
image: debian-7-0-x64
region: <%= ENV['DIGITALOCEAN_REGION'] %>
ssh_key_ids: <%= ENV['DIGITALOCEAN_SSH_KEYS'] %>
ssh_key: <%= ENV['DIGITALOCEAN_SSH_KEY_PATH'] %>
run_list:
- recipe[apt]
- name: ubuntu-12.04
driver_plugin: digital_ocean
......
AlignParameters:
Enabled: false
Encoding:
Enabled: false
ClassLength:
Enabled: false
MethodLength:
Enabled: false
LineLength:
Max: 200
Enabled: false
# HashSyntax:
# EnforcedStyle: hash_rockets
Documentation:
Enabled: false
HashSyntax:
EnforcedStyle: hash_rockets
PerceivedComplexity:
Enabled: false
CyclomaticComplexity:
Enabled: false
Style/FileName:
Enabled: false
Metrics/AbcSize:
Enabled: false
AllCops:
Exclude:
- 'Guardfile'
Style/GuardClause:
Enabled: false
source 'https://rubygems.org'
gem 'berkshelf', '~> 2.0'
gem 'chefspec', '~> 3.0'
gem 'berkshelf', '~> 3.0'
gem 'chefspec', '~> 4.0'
gem 'foodcritic', '~> 3.0'
gem 'rubocop'
......@@ -15,11 +15,3 @@ group :release do
gem 'emeril'
gem 'rake'
end
group :development do
gem 'growl'
gem 'guard', '~> 2.4'
gem 'guard-rubocop'
gem 'guard-rspec'
gem 'guard-rake'
end
# More info at https://github.com/guard/guard#readme
# guard 'rubocop' do
# watch(/attributes\/.+\.rb$/)
# watch(/providers\/.+\.rb$/)
# watch(/recipes\/.+\.rb$/)
# watch(/resources\/.+\.rb$/)
# watch('metadata.rb')
# end
guard :rspec, :cmd => 'chef exec /opt/chefdk/embedded/bin/rspec', :all_on_start => false, :notification => false do
watch(/^libraries\/(.+)\.rb$/)
watch(/^spec\/(.+)_spec\.rb$/)
watch(/^(recipes)\/(.+)\.rb$/) { |m| "spec/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { 'spec' }
end
# guard :rake, :task => 'spec', :all_on_start => false, :notification => false do
# watch(%r{^libraries\/(.+)\.rb$})
# watch(%r{^spec\/(.+)_spec\.rb$})
# watch(%r{^(recipes)\/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
# watch('spec/spec_helper.rb') { 'spec' }
# end
......@@ -403,9 +403,10 @@ 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.
......
......@@ -6,18 +6,18 @@ require 'rake'
require 'foodcritic'
require 'rspec/core/rake_task'
task :default => [:spec]
task default: [:spec]
RSpec::Core::RakeTask.new(:spec) do |t|
t.pattern = "./test/spec{,/*/**}/*_spec.rb"
t.pattern = './spec{,/*/**}/*_spec.rb'
end
FoodCritic::Rake::LintTask.new do |t|
t.options = {:fail_tags => ['correctness']}
t.options = { fail_tags: ['correctness'] }
end
begin
require 'emeril/rake'
rescue LoadError
puts ">>>>> Emerial gem not loaded, omitting taskes" unless ENV['CI']
puts '>>>>> Emerial gem not loaded, omitting taskes' unless ENV['CI']
end
......@@ -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.
......@@ -20,56 +21,98 @@
module RunitCookbook
module Helpers
# 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}
results.any? { |val| /docker/ =~ val }
end
def runit_installed?
return true if runit_rpm_installed? || (runit_executable? && runit_sv_works?)
def env_dir
"#{sv_dir_name}/env"
end
def runit_executable?
::File.executable?(node['runit']['executable'])
def extra_env_files?
files = []
Dir.glob("#{service_dir_name}/env/*").each do |f|
files << File.basename(f)
end
return true if files.sort != new_resource.env.keys.sort
false
end
def runit_sv_works?
sv = shell_out("#{node['runit']['sv_bin']} --help")
sv.exitstatus == 100 && sv.stderr =~ /usage: sv .* command service/
def zap_extra_env_files
Dir.glob("#{service_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 runit_rpm_installed?
shell_out('rpm -qa | grep -q "^runit"').exitstatus == 0
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("#{sv_bin} --help")
sv.exitstatus == 100 && sv.stderr =~ /usage: sv .* command service/
end
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}")
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("#{new_resource.sv_bin} #{sv_args}status #{service_dir_name}")
cmd = shell_out("#{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 = shell_out("#{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'))
::File.exist?("#{service_dir_name}/run")
end
def log_service_name
::File.join(new_resource.service_name, 'log')
"#{new_resource.service_name}/log"
end
def sv_dir_name
::File.join(new_resource.sv_dir, new_resource.service_name)
"#{parsed_sv_dir}/#{new_resource.service_name}"
end
def sv_args
......@@ -79,12 +122,16 @@ module RunitCookbook
sv_args
end
def sv_bin
parsed_sv_bin
end
def service_dir_name
::File.join(new_resource.service_dir, new_resource.service_name)
"#{new_resource.service_dir}/#{new_resource.service_name}"
end
def log_dir_name
::File.join(new_resource.service_dir, new_resource.service_name, log)
"#{new_resource.service_dir}/#{new_resource.service_name}/log"
end
def template_cookbook
......@@ -92,9 +139,39 @@ module RunitCookbook
end
def default_logger_content
"#!/bin/sh
exec svlogd -tt /var/log/#{new_resource.service_name}"
<<-EOS
#!/bin/sh
exec svlogd -tt /var/log/#{new_resource.service_name}
EOS
end
def disable_service
shell_out("#{new_resource.sv_bin} #{sv_args}down #{service_dir_name}")
FileUtils.rm(service_dir_name)
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
end
end
This diff is collapsed.
......@@ -30,7 +30,7 @@ class Chef
runit_node = runit_attributes_from_node(run_context)
@resource_name = :runit_service
@provider = Chef::Provider::RunitService
@supports = { :restart => true, :reload => true, :status => true }
@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]
......@@ -94,103 +94,103 @@ 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'))
@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
kind_of: [Hash],
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 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 +202,39 @@ 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_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)
......
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.6.1'
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.6.1'