I'm currently a bit stuck in the "works-for-me-don't-need-any-tests"-state.
But I hope I will find some time soon to write the tests ... ;-)
Anselm
On Monday 15 March 2010 22:37:38 James Turnbull wrote:
>
> Anselm
>
> Thanks for this. Can you mail your code as a unified diff to the
> list for comment? Did you make any progress on tests?
>
> Thanks
>
> James Turnbull
>
--
You received this message because you are subscribed to the Google Groups
"Puppet Developers" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/puppet-dev?hl=en.
diff --git a/lib/puppet/provider/service/bsd.rb b/lib/puppet/provider/service/bsd.rb
new file mode 100644
index 0000000..fed6559
--- /dev/null
+++ b/lib/puppet/provider/service/bsd.rb
@@ -0,0 +1,54 @@
+# Manage FreeBSD services.
+Puppet::Type.type(:service).provide :bsd, :parent => :init do
+ desc "FreeBSD's (and probably NetBSD?) form of ``init``-style service management.
+
+ Uses ``rc.conf.d`` for service enabling and disabling.
+
+"
+
+ confine :operatingsystem => [:freebsd, :netbsd, :openbsd]
+
+ @@rcconf_dir = '/etc/rc.conf.d'
+
+ def self.defpath
+ superclass.defpath
+ end
+
+ # remove service file from rc.conf.d to disable it
+ def disable
+ rcfile = File.join(@@rcconf_dir, @model[:name])
+ if File.exists?(rcfile)
+ File.delete(rcfile)
+ end
+ end
+
+ # if the service file exists in rc.conf.d then it's already enabled
+ def enabled?
+ rcfile = File.join(@@rcconf_dir, @model[:name])
+ if File.exists?(rcfile)
+ return :true
+ end
+
+ return :false
+ end
+
+ # enable service by creating a service file under rc.conf.d with the
+ # proper contents
+ def enable
+ if not File.exists?(@@rcconf_dir)
+ Dir.mkdir(@@rcconf_dir)
+ end
+ rcfile = File.join(@@rcconf_dir, @model[:name])
+ open(rcfile, 'w') { |f| f << "%s_enable=\"YES\"\n" % @model[:name] }
+ end
+
+ # Override stop/start commands to use one<cmd>'s and the avoid race condition
+ # where provider trys to stop/start the service before it is enabled
+ def startcmd
+ [self.initscript, :onestart]
+ end
+
+ def stopcmd
+ [self.initscript, :onestop]
+ end
+end
diff --git a/lib/puppet/provider/service/freebsd.rb b/lib/puppet/provider/service/freebsd.rb
index baf5e5a..27f3715 100644
--- a/lib/puppet/provider/service/freebsd.rb
+++ b/lib/puppet/provider/service/freebsd.rb
@@ -1,56 +1,139 @@
-# Manage FreeBSD services.
Puppet::Type.type(:service).provide :freebsd, :parent => :init do
- desc "FreeBSD's (and probably NetBSD?) form of ``init``-style service management.
- Uses ``rc.conf.d`` for service enabling and disabling.
+ desc "Provider for FreeBSD. Makes use of rcvar argument of init scripts and parses/edits rc files."
-"
+ confine :operatingsystem => [:freebsd]
+ defaultfor :operatingsystem => [:freebsd]
- confine :operatingsystem => [:freebsd, :netbsd, :openbsd]
+ @@rcconf = '/etc/rc.conf'
+ @@rcconf_local = '/etc/rc.conf.local'
+ @@rcconf_dir = '/etc/rc.conf.d'
- defaultfor :operatingsystem => :freebsd
+ def self.defpath
+ superclass.defpath
+ end
- @@rcconf_dir = '/etc/rc.conf.d'
+ # Executing an init script with the 'rcvar' argument returns
+ # the service name, rcvar name and whether it's enabled/disabled
+ def rcvar
+ rcvar = execute([self.initscript, :rcvar], :failonfail => true, :squelch => false)
+ rcvar = rcvar.split("\n")
+ return rcvar
+ end
- def self.defpath
- superclass.defpath
- end
+ # Extract service name
+ def service_name
+ name = self.rcvar[0]
+ self.error("No service name found in rcvar") if name.nil?
+ name = name.gsub!(/# (.*)/, '\1')
+ self.error("Service name is empty") if name.nil?
+ self.debug("Service name is #{name}")
+ return name
+ end
- # remove service file from rc.conf.d to disable it
- def disable
- rcfile = File.join(@@rcconf_dir, @model[:name])
- if File.exists?(rcfile)
- File.delete(rcfile)
- end
- end
+ # Extract rcvar name
+ def rcvar_name
+ name = self.rcvar[1]
+ self.error("No rcvar name found in rcvar") if name.nil?
+ name = name.gsub!(/(.*)_enable=(.*)/, '\1')
+ self.error("rcvar name is empty") if name.nil?
+ self.debug("rcvar name is #{name}")
+ return name
+ end
- # if the service file exists in rc.conf.d then it's already enabled
- def enabled?
- rcfile = File.join(@@rcconf_dir, @model[:name])
- if File.exists?(rcfile)
- return :true
- end
+ # Extract rcvar value
+ def rcvar_value
+ value = self.rcvar[1]
+ self.error("No rcvar value found in rcvar") if value.nil?
+ value = value.gsub!(/(.*)_enable=\"?(.*)\"?/, '\2')
+ self.error("rcvar value is empty") if value.nil?
+ self.debug("rcvar value is #{value}")
+ return value
+ end
- return :false
+ # Edit rc files and set the service to yes/no
+ def rc_edit(yesno)
+ service = self.service_name
+ rcvar = self.rcvar_name
+ self.debug("Editing rc files: setting #{rcvar} to #{yesno} for #{service}")
+ if not self.rc_replace(service, rcvar, yesno)
+ self.rc_add(service, rcvar, yesno)
end
+ end
- # enable service by creating a service file under rc.conf.d with the
- # proper contents
- def enable
- if not File.exists?(@@rcconf_dir)
- Dir.mkdir(@@rcconf_dir)
+ # Try to find an existing setting in the rc files
+ # and replace the value
+ def rc_replace(service, rcvar, yesno)
+ success = false
+ # Replace in all files, not just in the first found with a match
+ [@@rcconf, @@rcconf_local, @@rcconf_dir + "/#{service}"].each do |filename|
+ if File.exists?(filename)
+ s = File.read(filename)
+ if s.gsub!(/(#{rcvar}_enable)=\"?(YES|NO)\"?/, "\\1=\"#{yesno}\"")
+ File.open(filename, File::WRONLY) { |f| f << s }
+ self.debug("Replaced in #{filename}")
+ success = true
end
- rcfile = File.join(@@rcconf_dir, @model[:name])
- open(rcfile, 'w') { |f| f << "%s_enable=\"YES\"\n" % @model[:name] }
+ end
end
+ return success
+ end
- # Override stop/start commands to use one<cmd>'s and the avoid race condition
- # where provider trys to stop/start the service before it is enabled
- def startcmd
- [self.initscript, :onestart]
+ # Add a new setting to the rc files
+ def rc_add(service, rcvar, yesno)
+ append = "\n\# Added by Puppet\n#{rcvar}_enable=\"#{yesno}\""
+ # First, try the one-file-per-service style
+ if File.exists?(@@rcconf_dir)
+ File.open(@@rcconf_dir + "/#{service}", File::WRONLY | File::APPEND | File::CREAT, 0644) {
+ |f| f << append
+ self.debug("Appended to #{f.path}")
+ }
+ else
+ # Else, check the local rc file first, but don't create it
+ if File.exists?(@@rcconf_local)
+ File.open(@@rcconf_local, File::WRONLY | File::APPEND) {
+ |f| f << append
+ self.debug("Appended to #{f.path}")
+ }
+ else
+ # At last use the standard rc.conf file
+ File.open(@@rcconf, File::WRONLY | File::APPEND | File::CREAT, 0644) {
+ |f| f << append
+ self.debug("Appended to #{f.path}")
+ }
+ end
end
+ end
- def stopcmd
- [self.initscript, :onestop]
+ def enabled?
+ if /YES$/ =~ self.rcvar_value then
+ self.debug("Is enabled")
+ return :true
end
+ self.debug("Is disabled")
+ return :false
+ end
+
+ def enable
+ self.debug("Enabling")
+ self.rc_edit("YES")
+ end
+
+ def disable
+ self.debug("Disabling")
+ self.rc_edit("NO")
+ end
+
+ def startcmd
+ [self.initscript, :onestart]
+ end
+
+ def stopcmd
+ [self.initscript, :onestop]
+ end
+
+ def statuscmd
+ [self.initscript, :onestatus]
+ end
+
end