From bf11e7c7aa4ce3337c6697d0b25ee2cdd28ba10c Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Thu, 11 Nov 2010 10:18:04 -0800 Subject: Maint: Move "Local-branch:" info below "---" When running "rake mail_patches", moved the "Local-branch:" info lines below the "---" line in the e-mail, so that if someone applies the patch using "git am", the "Local-branch" notation won't show up in the commit message. --- tasks/rake/git_workflow.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/rake/git_workflow.rake b/tasks/rake/git_workflow.rake index c275bba3f..4c39f98de 100644 --- a/tasks/rake/git_workflow.rake +++ b/tasks/rake/git_workflow.rake @@ -108,7 +108,7 @@ task :mail_patches do files = Dir.glob("00*.patch") files.each do |file| contents = File.read(file) - contents.sub!(/^---$/, "#{additional_info}---") + contents.sub!(/^---\n/, "---\n#{additional_info}") File.open(file, 'w') do |file_handle| file_handle.print contents end -- cgit From 6f1416d7a4cec92ccff64d904d5fe799b8ff9a85 Mon Sep 17 00:00:00 2001 From: Jesse Wolfe Date: Thu, 11 Nov 2010 11:14:02 -0800 Subject: Fix #4904 Mounts shouldn't remount unless they are ensure=>mounted After we fixed issue #2730, it is now possible to manage an fstab entry without asking puppet to try to call mount or unmount on that device. That fix failed to address the "refresh" behavior of mounts. We have changed "refresh" to only remount devices that are set to "mounted", so users can truly manage fstab entries without having puppet try to remount them. Paired-With: Paul Berry --- lib/puppet/type/mount.rb | 2 +- spec/unit/type/mount_spec.rb | 32 +++++++++++++++++++++++++++----- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/lib/puppet/type/mount.rb b/lib/puppet/type/mount.rb index d048c90f1..e8c6b3290 100755 --- a/lib/puppet/type/mount.rb +++ b/lib/puppet/type/mount.rb @@ -210,7 +210,7 @@ module Puppet def refresh # Only remount if we're supposed to be mounted. - provider.remount if self.should(:fstype) != "swap" and provider.mounted? + provider.remount if self.should(:fstype) != "swap" and self.should(:ensure) == :mounted end def value(name) diff --git a/spec/unit/type/mount_spec.rb b/spec/unit/type/mount_spec.rb index ce82cb516..4aa9baf70 100755 --- a/spec/unit/type/mount_spec.rb +++ b/spec/unit/type/mount_spec.rb @@ -203,23 +203,45 @@ describe Puppet::Type.type(:mount)::Ensure do end end - describe Puppet::Type.type(:mount), "when responding to events" do + describe Puppet::Type.type(:mount), "when responding to refresh" do - it "should remount if it is currently mounted" do - @provider.expects(:mounted?).returns(true) + it "should remount if it is supposed to be mounted" do + @mount[:ensure] = "mounted" @provider.expects(:remount) @mount.refresh end - it "should not remount if it is not currently mounted" do - @provider.expects(:mounted?).returns(false) + it "should not remount if it is supposed to be present" do + @mount[:ensure] = "present" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount if it is supposed to be absent" do + @mount[:ensure] = "absent" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount if it is supposed to be defined" do + @mount[:ensure] = "defined" + @provider.expects(:remount).never + + @mount.refresh + end + + it "should not remount if it is supposed to be unmounted" do + @mount[:ensure] = "unmounted" @provider.expects(:remount).never @mount.refresh end it "should not remount swap filesystems" do + @mount[:ensure] = "mounted" @mount[:fstype] = "swap" @provider.expects(:remount).never -- cgit From 2b772f761e151c3c2be41e1688e9af9a22d73dd0 Mon Sep 17 00:00:00 2001 From: Nan Liu Date: Thu, 16 Sep 2010 23:13:31 -0700 Subject: (#3747) Implement upstart provider --- lib/puppet/provider/service/upstart.rb | 76 ++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100755 lib/puppet/provider/service/upstart.rb diff --git a/lib/puppet/provider/service/upstart.rb b/lib/puppet/provider/service/upstart.rb new file mode 100755 index 000000000..915de4c0b --- /dev/null +++ b/lib/puppet/provider/service/upstart.rb @@ -0,0 +1,76 @@ +Puppet::Type.type(:service).provide :upstart, :parent => :init do + desc "Ubuntu service manager upstart. + + This provider manages upstart jobs which have replaced initd. + + See: + * http://upstart.ubuntu.com/ + " + # Note: I did not set default for Ubuntu + # defaultfor :operatingsystem => :ubuntu + + # confine to :ubuntu for now because I haven't tested on other platforms + confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian] + + commands :start => "/sbin/start", + :stop => "/sbin/stop", + :restart => "/sbin/restart", + :status_exec => "/sbin/status", + :initctl => "/sbin/initctl" + + # upstart developer haven't implemented initctl enable/disable yet: + # http://www.linuxplanet.com/linuxplanet/tutorials/7033/2/ + # has_feature :enableable + + def self.instances + instances = [] + execpipe("#{command(:initctl)} list") { |process| + process.each { |line| + # needs special handling of services such as network-interface: + # initctl list: + # network-interface (lo) start/running + # network-interface (eth0) start/running + # network-interface-security start/running + name = \ + if matcher = line.match(/^(network-interface)\s\(([^\)]+)\)/) + "#{matcher[1]} INTERFACE=#{matcher[2]}" + else + line.split.first + end + instances << new(:name => name) #, :path => "/etc/init/#{name}.conf") + } + } + instances + end + + def startcmd + [command(:start), @resource[:name]] + end + + def stopcmd + [command(:stop), @resource[:name]] + end + + def restartcmd + (@resource[:hasrestart] == :true) && [command(:restart), @resource[:name]] + end + + def status + # allows user override of status command + if @resource[:status] + ucommand(:status, false) + if $?.exitstatus == 0 + return :running + else + return :stopped + end + else + output = status_exec(@resource[:name].split) + if (! $?.nil?) && (output =~ /start\//) + return :running + else + return :stopped + end + end + end +end -- cgit From b0acb02b568598ec8dba41aa856f74658b2033dd Mon Sep 17 00:00:00 2001 From: Nick Lewis Date: Thu, 11 Nov 2010 13:47:43 -0800 Subject: (#3747) Add specs for upstart provider Paired-With: Matt Robinson --- lib/puppet/provider/service/upstart.rb | 5 +--- spec/unit/provider/service/upstart.rb | 50 ++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 spec/unit/provider/service/upstart.rb diff --git a/lib/puppet/provider/service/upstart.rb b/lib/puppet/provider/service/upstart.rb index 915de4c0b..54971eeac 100755 --- a/lib/puppet/provider/service/upstart.rb +++ b/lib/puppet/provider/service/upstart.rb @@ -6,9 +6,6 @@ Puppet::Type.type(:service).provide :upstart, :parent => :init do See: * http://upstart.ubuntu.com/ " - # Note: I did not set default for Ubuntu - # defaultfor :operatingsystem => :ubuntu - # confine to :ubuntu for now because I haven't tested on other platforms confine :operatingsystem => :ubuntu #[:ubuntu, :fedora, :debian] @@ -37,7 +34,7 @@ Puppet::Type.type(:service).provide :upstart, :parent => :init do else line.split.first end - instances << new(:name => name) #, :path => "/etc/init/#{name}.conf") + instances << new(:name => name) } } instances diff --git a/spec/unit/provider/service/upstart.rb b/spec/unit/provider/service/upstart.rb new file mode 100644 index 000000000..439fd2c79 --- /dev/null +++ b/spec/unit/provider/service/upstart.rb @@ -0,0 +1,50 @@ +#!/usr/bin/env ruby + +require File.dirname(__FILE__) + '/../../../spec_helper' + +provider_class = Puppet::Type.type(:service).provider(:upstart) + +describe provider_class do + describe "#instances" do + it "should be able to find all instances" do + processes = ["rc stop/waiting", "ssh start/running, process 712"] + provider_class.stubs(:execpipe).yields(processes) + provider_class.instances.map {|provider| provider.name}.should =~ ["rc","ssh"] + end + + it "should attach the interface name for network interfaces" do + processes = ["network-interface (eth0)"] + provider_class.stubs(:execpipe).yields(processes) + provider_class.instances.first.name.should == "network-interface INTERFACE=eth0" + end + end + + describe "#status" do + it "should allow the user to override the status command" do + resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart, :status => "/bin/foo") + provider = provider_class.new(resource) + + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.expects(:ucommand) + provider.status.should == :running + end + + it "should use the default status command if none is specified" do + resource = Puppet::Type.type(:service).new(:name => "foo", :provider => :upstart) + provider = provider_class.new(resource) + + provider.expects(:status_exec).with(["foo"]).returns("foo start/running, process 1000") + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.status.should == :running + end + + it "should properly handle services with 'start' in their name" do + resource = Puppet::Type.type(:service).new(:name => "foostartbar", :provider => :upstart) + provider = provider_class.new(resource) + + provider.expects(:status_exec).with(["foostartbar"]).returns("foostartbar stop/waiting") + Process::Status.any_instance.stubs(:exitstatus).returns(0) + provider.status.should == :stopped + end + end +end -- cgit From c643e98c57e781353bfac55e7edb6690450076e3 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Tue, 16 Nov 2010 11:21:35 -0800 Subject: (#5079) Move methods around to make it clearer whether they're public or private One method was showing up as a private class method, which turns out isn't possible, so it got moved into the public section. This is a rework for diff clarity of a patch submitted by Sandor Szuecs Reviewed-by: Paul Berry --- lib/puppet/provider/mcx/mcxcontent.rb | 99 +++++++++++++++++------------------ 1 file changed, 48 insertions(+), 51 deletions(-) diff --git a/lib/puppet/provider/mcx/mcxcontent.rb b/lib/puppet/provider/mcx/mcxcontent.rb index cb5adc698..b7cc40b87 100644 --- a/lib/puppet/provider/mcx/mcxcontent.rb +++ b/lib/puppet/provider/mcx/mcxcontent.rb @@ -82,10 +82,6 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do mcx_list end - private - - # mcxexport is used by instances, and therefore - # a class method. def self.mcxexport(ds_type, ds_name) ds_t = TypeMap[ds_type] ds_n = ds_name.to_s @@ -93,6 +89,54 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do dscl 'localhost', '-mcxexport', ds_path end + + def create + self.content=(resource[:content]) + end + + def destroy + ds_parms = get_dsparams + ds_t = TypeMap[ds_parms[:ds_type]] + ds_n = ds_parms[:ds_name].to_s + ds_path = "/Local/Default/#{ds_t}/#{ds_n}" + + dscl 'localhost', '-mcxdelete', ds_path + end + + def exists? + # JJM Just re-use the content method and see if it's empty. + begin + mcx = content + rescue Puppet::ExecutionFailure => e + return false + end + has_mcx = ! mcx.empty? + end + + def content + ds_parms = get_dsparams + + mcx = self.class.mcxexport( + ds_parms[:ds_type], + + ds_parms[:ds_name]) + mcx + end + + def content=(value) + # dscl localhost -mcximport + ds_parms = get_dsparams + + mcx = mcximport( + ds_parms[:ds_type], + ds_parms[:ds_name], + + resource[:content]) + mcx + end + + private + def mcximport(ds_type, ds_name, val) ds_t = TypeMap[ds_type] ds_n = ds_name.to_s @@ -155,51 +199,4 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do end - public - - def create - self.content=(resource[:content]) - end - - def destroy - ds_parms = get_dsparams - ds_t = TypeMap[ds_parms[:ds_type]] - ds_n = ds_parms[:ds_name].to_s - ds_path = "/Local/Default/#{ds_t}/#{ds_n}" - - dscl 'localhost', '-mcxdelete', ds_path - end - - def exists? - # JJM Just re-use the content method and see if it's empty. - begin - mcx = content - rescue Puppet::ExecutionFailure => e - return false - end - has_mcx = ! mcx.empty? - end - - def content - ds_parms = get_dsparams - - mcx = self.class.mcxexport( - ds_parms[:ds_type], - - ds_parms[:ds_name]) - mcx - end - - def content=(value) - # dscl localhost -mcximport - ds_parms = get_dsparams - - mcx = mcximport( - ds_parms[:ds_type], - ds_parms[:ds_name], - - resource[:content]) - mcx - end - end -- cgit From 6c7290b4ddff112f97fd6ecf992f901ded953507 Mon Sep 17 00:00:00 2001 From: Matt Robinson Date: Tue, 16 Nov 2010 11:30:38 -0800 Subject: (#5079) Refactor and cleanup mcxcontent provider This is a rework for diff clarity of a patch submitted by Sandor Szuecs Reviewed-by: Paul Berry --- lib/puppet/provider/mcx/mcxcontent.rb | 63 +++++++++++++---------------------- 1 file changed, 23 insertions(+), 40 deletions(-) diff --git a/lib/puppet/provider/mcx/mcxcontent.rb b/lib/puppet/provider/mcx/mcxcontent.rb index b7cc40b87..3ad437b53 100644 --- a/lib/puppet/provider/mcx/mcxcontent.rb +++ b/lib/puppet/provider/mcx/mcxcontent.rb @@ -53,29 +53,25 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do confine :operatingsystem => :darwin defaultfor :operatingsystem => :darwin - # self.instances is all important. - # This is the only class method, it returns - # an array of instances of this class. def self.instances mcx_list = [] - for ds_type in TypeMap.keys + TypeMap.keys.each do |ds_type| ds_path = "/Local/Default/#{TypeMap[ds_type]}" output = dscl 'localhost', '-list', ds_path member_list = output.split - for ds_name in member_list + member_list.each do |ds_name| content = mcxexport(ds_type, ds_name) if content.empty? Puppet.debug "/#{TypeMap[ds_type]}/#{ds_name} has no MCX data." else # This node has MCX data. - rsrc = self.new( - :name => "/#{TypeMap[ds_type]}/#{ds_name}", - :ds_type => ds_type, - :ds_name => ds_name, - - :content => content) - mcx_list << rsrc + mcx_list << self.new( + :name => "/#{TypeMap[ds_type]}/#{ds_name}", + :ds_type => ds_type, + :ds_name => ds_name, + :content => content + ) end end end @@ -104,42 +100,34 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do end def exists? - # JJM Just re-use the content method and see if it's empty. begin - mcx = content + has_mcx? rescue Puppet::ExecutionFailure => e return false end - has_mcx = ! mcx.empty? end def content ds_parms = get_dsparams - mcx = self.class.mcxexport( - ds_parms[:ds_type], - - ds_parms[:ds_name]) - mcx + self.class.mcxexport(ds_parms[:ds_type], ds_parms[:ds_name]) end def content=(value) # dscl localhost -mcximport ds_parms = get_dsparams - mcx = mcximport( - ds_parms[:ds_type], - ds_parms[:ds_name], - - resource[:content]) - mcx + mcximport(ds_parms[:ds_type], ds_parms[:ds_name], resource[:content]) end private + def has_mcx? + !content.empty? + end + def mcximport(ds_type, ds_name, val) ds_t = TypeMap[ds_type] - ds_n = ds_name.to_s ds_path = "/Local/Default/#{ds_t}/#{ds_name}" tmp = Tempfile.new('puppet_mcx') @@ -155,33 +143,31 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do # Given the resource name string, parse ds_type out. def parse_type(name) - tmp = name.split('/')[1] - if ! tmp.is_a? String + ds_type = name.split('/')[1] + unless ds_type raise MCXContentProviderException, "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter." end # De-pluralize and downcase. - tmp = tmp.chop.downcase.to_sym - if not TypeMap.keys.member? tmp + ds_type = ds_type.chop.downcase.to_sym + unless TypeMap.key? ds_type raise MCXContentProviderException, "Coult not parse ds_type from resource name '#{name}'. Specify with ds_type parameter." end - tmp + ds_type end # Given the resource name string, parse ds_name out. def parse_name(name) ds_name = name.split('/')[2] - if ! ds_name.is_a? String + unless ds_name raise MCXContentProviderException, "Could not parse ds_name from resource name '#{name}'. Specify with ds_name parameter." end ds_name end - # Gather ds_type and ds_name from resource or - # parse it out of the name. - # This is a private instance method, not a class method. + # Gather ds_type and ds_name from resource or parse it out of the name. def get_dsparams ds_type = resource[:ds_type] ds_type ||= parse_type(resource[:name]) @@ -190,13 +176,10 @@ Puppet::Type.type(:mcx).provide :mcxcontent, :parent => Puppet::Provider do ds_name = resource[:ds_name] ds_name ||= parse_name(resource[:name]) - rval = { + { :ds_type => ds_type.to_sym, :ds_name => ds_name, } - - return rval - end end -- cgit