Last active
January 4, 2016 00:39
-
-
Save zachfi/8543332 to your computer and use it in GitHub Desktop.
OpenBSD service provider for Puppet
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Puppet::Type.type(:service).provide :openbsd, :parent => :init do | |
desc "Provider for OpenBSD's rc.d daemon control scripts" | |
confine :operatingsystem => :openbsd | |
defaultfor :operatingsystem => :openbsd | |
has_feature :flaggable | |
def self.rcconf() '/etc/rc.conf' end | |
def self.rcconf_local() '/etc/rc.conf.local' end | |
def self.defpath | |
["/etc/rc.d"] | |
end | |
# Fetch the state of all service resources | |
def self.prefetch(resources) | |
services = instances | |
resources.keys.each do |name| | |
if provider = services.find { |svc| svc.name == name } | |
resources[name].provider = provider | |
end | |
end | |
end | |
# Return the list of rc scripts | |
def self.rclist | |
unless @rclist | |
Puppet.debug "Building list of rc scripts" | |
@rclist = [] | |
defpath.each do |p| | |
Dir.glob(p + '/*').each do |item| | |
@rclist << item if File.executable?(item) | |
end | |
end | |
end | |
@rclist | |
end | |
# Return a hash where the keys are the rc script names with flags as values | |
def self.rcflags | |
unless @flag_hash | |
Puppet.debug "Retrieving flags for all discovered services" | |
@flag_hash = {} | |
Puppet.debug "Reading the contents of the rc conf files" | |
if File.exists?(rcconf_local()) | |
rcconf_local_contents = File.open(rcconf_local()).read | |
else | |
rcconf_local_contents = [] | |
end | |
if File.exists?(rcconf()) | |
rcconf_contents = File.open(rcconf()).read | |
else | |
rcconf_contents = [] | |
end | |
rclist().each do |rcitem| | |
rcname = rcitem.split('/').last | |
# Loop over each rc.conf file | |
[rcconf_local_contents, rcconf_contents].flatten.each do |rccontents| | |
if flagline = rccontents.each_line.find {|l| l =~ /#{rcname}_flags/ } | |
# Parse the line and figure out what the flags are | |
flag = flagline.split('=').last.split(/#/).first.strip.gsub(/"/, '') | |
@flag_hash[rcname.to_sym] ||= flag | |
end | |
end | |
@flag_hash[rcname.to_sym] ||= nil | |
end | |
end | |
@flag_hash | |
end | |
# Read the rc.conf* files and determine the value of the flags | |
def self.get_flags(rcname) | |
rcflags() | |
@flag_hash[rcname.to_sym] | |
end | |
def self.instances | |
instances = [] | |
defpath.each do |path| | |
unless FileTest.directory?(path) | |
Puppet.debug "Service path #{path} does not exist" | |
next | |
end | |
rclist().each do |d| | |
instances << new( | |
:name => File.basename(d), | |
:path => path, | |
:flags => get_flags(File.basename(d)), | |
:hasstatus => true | |
) | |
end | |
end | |
instances | |
end | |
def startcmd | |
[self.initscript, "-f", :start] | |
end | |
def restartcmd | |
(@resource[:hasrestart] == :true) && [self.initscript, "-f", :restart] | |
end | |
def statuscmd | |
[self.initscript, :check] | |
end | |
def rcvar_name | |
self.name + '_flags' | |
end | |
def rcvar_value | |
[rcconf,rcconf_local].each do |file| | |
# | |
end | |
end | |
def set_flags(flags) | |
if flags.nil? | |
append = resource[:name] + '_flags=""' | |
else | |
append = resource[:name] + '_flags="' + flags + '"' | |
end | |
# Detect the existense of the tile | |
if File.exists?(self.class.rcconf_local()) | |
s = File.read(self.class.rcconf_local()) | |
else | |
s = '' | |
end | |
# We should detect the presence of the line and proceed accordingly | |
if s.lines.find {|l| /#{resource[:name]}_flags/ =~ l }.nil? | |
# line was not found | |
Puppet.debug "Appending service flags #{append}" | |
File.open(self.class.rcconf_local, File::WRONLY | File::APPEND | File::CREAT, 0644) { |f| | |
f << append + "\n" | |
} | |
else | |
if s.gsub!(/^#{resource[:name]}_flags="(.*)?"(.*)?$/, append) | |
Puppet.debug "Replacing service flags with #{append}" | |
File.open(self.class.rcconf_local(), 'w') { |f| f << s } | |
end | |
end | |
end | |
def remove_flags_line | |
# Detect the existense of the file | |
if File.exists?(self.class.rcconf_local()) | |
s = File.read(self.class.rcconf_local()) | |
if s.lines.find {|l| /#{resource[:name]}_flags/ =~ l } | |
Puppet.debug "Removing service flags for #{self.name}" | |
File.open(self.class.rcconf_local, 'w') { |f| | |
s.split('\n').each {|line| | |
f << line unless line =~ /#{resource[:name]}_flags/ | |
} | |
} | |
end | |
else | |
Puppet.debug "The rc.conf.local file was not found" | |
end | |
end | |
# Determine if the rc script is included in base, or if it exists as a result | |
# of a package installation. | |
def in_base? | |
system("/usr/sbin/pkg_info -qE /etc/rc.d/#{self.name}> /dev/null") | |
$?.exitstatus == 1 | |
end | |
def enabled? | |
if (@property_hash[:flags].nil? or @property_hash[:flags] == 'NO') | |
:false | |
#elsif @property_hash[:flags] != resource[:flags] | |
# # We set false here only so that flush is called to udpate the flags | |
# :false | |
else | |
:true | |
end | |
end | |
def enable | |
self.debug("Enabling #{self.name}") | |
end | |
# We should also check for default state | |
def disable | |
self.debug("Disabling #{self.name}") | |
end | |
def flags | |
@property_hash[:flags] | |
end | |
def flags=(value) | |
@property_hash[:flags] = value | |
end | |
def flush | |
debug "Flusing resource for #{self.name}" | |
if resource[:enable] == :true | |
set_flags(resource[:flags]) | |
elsif resource[:enable] == :false | |
if not in_base? | |
remove_flags_line() | |
else | |
set_flags("NO") | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment