components/ruby/puppet/patches/puppet-03-zone-provider.patch
branchs11-update
changeset 3458 4912663e9858
parent 2928 43b3da52b84a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/ruby/puppet/patches/puppet-03-zone-provider.patch	Fri Nov 07 17:33:48 2014 -0800
@@ -0,0 +1,362 @@
+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.6.2/lib/puppet/provider/zone/solaris.rb.orig	2014-06-18 09:28:43.538680821 -0600
++++ puppet-3.6.2/lib/puppet/provider/zone/solaris.rb	2014-06-16 10:47:24.834849592 -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,129 +8,84 @@
+ 
+   # 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
+     adm(:list, "-cp").split("\n").collect do |line|
+       new(line2hash(line))
+     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
+@@ -138,31 +93,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
+@@ -182,11 +137,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]
+@@ -214,7 +170,6 @@
+   #
+   def getconfig
+     output = zonecfg :info
+-
+     name = nil
+     current = nil
+     hash = {}
+@@ -244,14 +199,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")
+@@ -272,7 +222,9 @@
+         end
+       end
+     end
++   end
+ 
++    # Boots the zone
+     zoneadm :boot
+   end
+ 
+@@ -285,64 +237,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 Puppet::Error, "Could not #{cmd[0]} zone: #{detail}", detail