16453463 Update Puppet's offerings on Solaris
16979551 Update Puppet to 3.2.2
17242868 Need to set the start method for the Puppet service to default to disabled.
17243548 The puppet.xml template entry needs updating
17257851 nameservice resource types need to stop calling svccfg refresh so much
17263808 Unable to initialize LDAP configuration using profile name
17263843 LDAP parameters do not match expected parameters
17270555 NIS provider returns an error when attempting to set securenets parameter
17271383 NIS provider is not updating domainname property
17277145 nsswitch provider object error and missing parameter
17284016 nis, ldap, and dns refreshed on every Puppet run
17284583 puppet service needs dependency on identity:node
17307127 LDAP provider has an invalid parameter.
17307412 clobber/clean can fail in puppet/ext
17318366 Update Puppet to 3.2.4
17318398 problem in UTILITY/PUPPET
Enhance the zone provider to configure zones using a zonecfg export file format.
Enhance the output of puppet resource zone, and fix zone clone functionality.
--- puppet-3.2.4/lib/puppet/provider/zone/solaris.rb.orig 2013-07-29 15:48:58.118553584 -0600
+++ puppet-3.2.4/lib/puppet/provider/zone/solaris.rb 2013-07-29 15:49:21.053204412 -0600
@@ -1,5 +1,5 @@
Puppet::Type.type(:zone).provide(:solaris) do
- desc "Provider for Solaris Zones."
+ desc "Provider for Solaris zones."
commands :adm => "/usr/sbin/zoneadm", :cfg => "/usr/sbin/zonecfg"
defaultfor :osfamily => :solaris
@@ -8,20 +8,20 @@
# Convert the output of a list into a hash
def self.line2hash(line)
- fields = [:id, :name, :ensure, :path, :uuid, :brand, :iptype]
+ fields = [:id, :name, :ensure, :zonepath, :uuid, :brand, :iptype ]
properties = Hash[fields.zip(line.split(':'))]
- del_id = [:brand, :uuid]
+ del_id = [:id, :uuid]
+
# Configured but not installed zones do not have IDs
del_id << :id if properties[:id] == "-"
del_id.each { |p| properties.delete(p) }
-
properties[:ensure] = properties[:ensure].intern
- properties[:iptype] = 'exclusive' if properties[:iptype] == 'excl'
properties
end
+
def self.instances
# LAK:NOTE See http://snurl.com/21zf8 [groups_google_com]
x = adm(:list, "-cp").split("\n").collect do |line|
@@ -29,109 +29,64 @@
end
end
- def multi_conf(name, should, &action)
- has = properties[name]
- has = [] if has == :absent
- rms = has - should
- adds = should - has
- (rms.map{|o| action.call(:rm,o)} + adds.map{|o| action.call(:add,o)}).join("\n")
- end
-
- def self.def_prop(var, str)
- define_method('%s_conf' % var.to_s) do |v|
- str % v
- end
- define_method('%s=' % var.to_s) do |v|
- setconfig self.send( ('%s_conf'% var).intern, v)
- end
- end
+
+ # Read in the zone configuration parameters and properties and
+ # perform the zone configuration. Options are cloning the zone,
+ # which needs a zonecfg_export file, configuring an archive, which
+ # takes optional zonecfg_export and archived_zonename parameters,
+ # or performing a zone configuration, which requires a zonecfg_export
+ # file or string.
+ def configure
- def self.def_multiprop(var, &conf)
- define_method(var.to_s) do |v|
- o = properties[var]
- return '' if o.nil? or o == :absent
- o.join(' ')
- end
- define_method('%s=' % var.to_s) do |v|
- setconfig self.send( ('%s_conf'% var).intern, v)
- end
- define_method('%s_conf' % var.to_s) do |v|
- multi_conf(var, v, &conf)
+ if @resource[:archive].nil? && @resource[:zonecfg_export].nil?
+ raise Puppet::Error, "No configuration resource is defined."
end
- end
- def_prop :iptype, "set ip-type=%s"
- def_prop :autoboot, "set autoboot=%s"
- def_prop :path, "set zonepath=%s"
- def_prop :pool, "set pool=%s"
- def_prop :shares, "add rctl\nset name=zone.cpu-shares\nadd value (priv=privileged,limit=%s,action=none)\nend"
-
- def_multiprop :ip do |action, str|
- interface, ip, defrouter = str.split(':')
- case action
- when :add
- cmd = ["add net"]
- cmd << "set physical=#{interface}" if interface
- cmd << "set address=#{ip}" if ip
- cmd << "set defrouter=#{defrouter}" if defrouter
- cmd << "end"
- cmd.join("\n")
- when :rm
- if ip
- "remove net address=#{ip}"
- elsif interface
- "remove net physical=#{interface}"
- else
- raise ArgumentError, "can not remove network based on default router"
+ command = String.new
+ if @resource[:clone]
+ if !@resource[:zonecfg_export]
+ raise Puppet::Error, "A zone configuration must be defined to
+ clone a zone."
+ end
+ command = "#{command(:cfg)} -z #{@resource[:name]} -f #{@resource[:zonecfg_export]}"
+ else
+ unless @resource[:zonecfg_export].nil? || @resource[:zonecfg_export].empty?
+ begin
+ file = File.open(@resource[:zonecfg_export], "rb")
+ str = file.read.gsub(/[\n]\n*\s*/, "; ")
+ rescue
+ str = @resource[:zonecfg_export].gsub(/[\n]\n*\s*/, "; ")
+ ensure
+ file.close unless file.nil?
+ end
+ @property_hash.clear
end
- else self.fail action
- end
- end
- def_multiprop :dataset do |action, str|
- case action
- when :add; ['add dataset',"set name=#{str}",'end'].join("\n")
- when :rm; "remove dataset name=#{str}"
- else self.fail action
- end
- end
+ unless @resource[:archive].nil? || @resource[:archive].empty?
+ if !str.nil?
+ command = "#{command(:cfg)} -z #{@resource[:name]} \'create -a #{@resource[:archive]};#{str}\'"
+ else
+ command = "#{command(:cfg)} -z #{@resource[:name]} create -a #{@resource[:archive]} "
+ end
+ if @resource[:archived_zonename]
+ command << " -z #{@resource[:archived_zonename]}"
+ end
+ end
- def_multiprop :inherit do |action, str|
- case action
- when :add; ['add inherit-pkg-dir', "set dir=#{str}",'end'].join("\n")
- when :rm; "remove inherit-pkg-dir dir=#{str}"
- else self.fail action
+ if !@resource[:zonecfg_export].nil? && @resource[:archive].nil?
+ command = "#{command(:cfg)} -z #{@resource[:name]} \'#{str}\'"
+ end
end
- end
- def my_properties
- [:path, :iptype, :autoboot, :pool, :shares, :ip, :dataset, :inherit]
- end
-
- # Perform all of our configuration steps.
- def configure
- self.fail "Path is required" unless @resource[:path]
- arr = ["create -b #{@resource[:create_args]}"]
-
- # Then perform all of our configuration steps. It's annoying
- # that we need this much internal info on the resource.
- self.resource.properties.each do |property|
- next unless my_properties.include? property.name
- method = (property.name.to_s + '_conf').intern
- arr << self.send(method ,@resource[property.name]) unless property.safe_insync?(properties[property.name])
+ if command
+ r = exec_cmd(:cmd => command)
end
- setconfig(arr.join("\n"))
end
def destroy
zonecfg :delete, "-F"
end
- def add_cmd(cmd)
- @cmds = [] if @cmds.nil?
- @cmds << cmd
- end
-
def exists?
properties[:ensure] != :absent
end
@@ -139,31 +94,31 @@
# We cannot use the execpipe in util because the pipe is not opened in
# read/write mode.
def exec_cmd(var)
- # In bash, the exit value of the last command is the exit value of the
- # entire pipeline
- out = execute("echo \"#{var[:input]}\" | #{var[:cmd]}", :failonfail => false, :combine => true)
- st = $?.exitstatus
- {:out => out, :exit => st}
- end
-
- # Clear out the cached values.
- def flush
- return if @cmds.nil? || @cmds.empty?
- str = (@cmds << "commit" << "exit").join("\n")
- @cmds = []
- @property_hash.clear
-
- command = "#{command(:cfg)} -z #{@resource[:name]} -f -"
- r = exec_cmd(:cmd => command, :input => str)
- if r[:exit] != 0 or r[:out] =~ /not allowed/
- raise ArgumentError, "Failed to apply configuration"
+ if var[:input]
+ execute("echo \"#{var[:input]}\" | #{var[:cmd]}", :failonfail => true, :combine => true)
+ else
+ execute("#{var[:cmd]}", :failonfail => true, :combine => true)
end
end
+
def install(dummy_argument=:work_arround_for_ruby_GC_bug)
+ if ['5.11', '5.12'].include? Facter.value(:kernelrelease)
+ if !@resource[:install_args] and @resource[:config_profile]
+ @resource[:install_args] = " -c " + @resource[:config_profile]
+ elsif !@resource[:install_args] and @resource[:archive]
+ @resource[:install_args] = " -a " + @resource[:archive]
+ if @resource[:archived_zonename]
+ @resource[:install_args] << " -z " + @resource[:archived_zonename]
+ end
+ elsif @resource[:config_profile]
+ @resource[:install_args] << " -c " + @resource[:config_profile]
+ end
+ end
+
if @resource[:clone] # TODO: add support for "-s snapshot"
- zoneadm :clone, @resource[:clone]
- elsif @resource[:install_args]
+ zoneadm :clone, @resource[:clone]
+ elsif @resource[:install_args]
zoneadm :install, @resource[:install_args].split(" ")
else
zoneadm :install
@@ -183,11 +138,12 @@
end
end
@property_hash.dup
+
end
# We need a way to test whether a zone is in process. Our 'ensure'
# property models the static states, but we need to handle the temporary ones.
- def processing?
+ def processing?
hash = status
return false unless hash
["incomplete", "ready", "shutting_down"].include? hash[:ensure]
@@ -215,7 +171,6 @@
#
def getconfig
output = zonecfg :info
-
name = nil
current = nil
hash = {}
@@ -245,14 +200,9 @@
hash
end
- # Execute a configuration string. Can't be private because it's called
- # by the properties.
- def setconfig(str)
- add_cmd str
- end
-
def start
# Check the sysidcfg stuff
+ if ['5.10'].include? Facter.value(:kernelrelease)
if cfg = @resource[:sysidcfg]
self.fail "Path is required" unless @resource[:path]
zoneetc = File.join(@resource[:path], "root", "etc")
@@ -273,7 +223,9 @@
end
end
end
+ end
+ # Boots the zone
zoneadm :boot
end
@@ -286,64 +238,35 @@
end
main = self.class.line2hash(output.chomp)
-
- # Now add in the configuration information
- config_status.each do |name, value|
- main[name] = value
- end
-
main
end
def ready
+ # Prepare the zone
zoneadm :ready
end
def stop
- zoneadm :halt
+ # Shutdown the zone
+ zoneadm :halt
end
+
def unconfigure
+ # Unconfigure and delete the zone
zonecfg :delete, "-F"
end
def uninstall
+ # Uninstall the zone
zoneadm :uninstall, "-F"
end
private
- # Turn the results of getconfig into status information.
- def config_status
- config = getconfig
- result = {}
-
- result[:autoboot] = config[:autoboot] ? config[:autoboot].intern : :true
- result[:pool] = config[:pool]
- result[:shares] = config[:shares]
- if dir = config["inherit-pkg-dir"]
- result[:inherit] = dir.collect { |dirs| dirs[:dir] }
- end
- if datasets = config["dataset"]
- result[:dataset] = datasets.collect { |dataset| dataset[:name] }
- end
- result[:iptype] = config[:'ip-type'] if config[:'ip-type']
- if net = config["net"]
- result[:ip] = net.collect do |params|
- if params[:defrouter]
- "#{params[:physical]}:#{params[:address]}:#{params[:defrouter]}"
- elsif params[:address]
- "#{params[:physical]}:#{params[:address]}"
- else
- params[:physical]
- end
- end
- end
-
- result
- end
-
def zoneadm(*cmd)
+ # Execute the zoneadm command with the arguments
+ # provided
adm("-z", @resource[:name], *cmd)
rescue Puppet::ExecutionFailure => detail
self.fail "Could not #{cmd[0]} zone: #{detail}"