components/puppet/patches/puppet-03-zone-provider.patch
branchs11u2-sru
changeset 3460 5c5af6e58474
parent 3457 6358358b4186
child 3461 1240b4c4e38d
equal deleted inserted replaced
3457:6358358b4186 3460:5c5af6e58474
     1 Enhance the zone provider to configure zones using a zonecfg export file format.
       
     2 Enhance the output of puppet resource zone, and fix zone clone functionality.
       
     3 --- puppet-3.4.1/lib/puppet/provider/zone/solaris.rb.orig	2013-07-29 15:48:58.118553584 -0600
       
     4 +++ puppet-3.4.1/lib/puppet/provider/zone/solaris.rb	2013-07-29 15:49:21.053204412 -0600
       
     5 @@ -1,5 +1,5 @@
       
     6  Puppet::Type.type(:zone).provide(:solaris) do
       
     7 -  desc "Provider for Solaris Zones."
       
     8 +  desc "Provider for Solaris zones."
       
     9  
       
    10    commands :adm => "/usr/sbin/zoneadm", :cfg => "/usr/sbin/zonecfg"
       
    11    defaultfor :osfamily => :solaris
       
    12 @@ -8,20 +8,20 @@
       
    13  
       
    14    # Convert the output of a list into a hash
       
    15    def self.line2hash(line)
       
    16 -    fields = [:id, :name, :ensure, :path, :uuid, :brand, :iptype]
       
    17 +    fields = [:id, :name, :ensure, :zonepath, :uuid, :brand, :iptype ]
       
    18      properties = Hash[fields.zip(line.split(':'))]
       
    19  
       
    20 -    del_id = [:brand, :uuid]
       
    21 +    del_id = [:id, :uuid]
       
    22 +
       
    23      # Configured but not installed zones do not have IDs
       
    24      del_id << :id if properties[:id] == "-"
       
    25      del_id.each { |p| properties.delete(p) }
       
    26 -
       
    27      properties[:ensure] = properties[:ensure].intern
       
    28 -    properties[:iptype] = 'exclusive' if properties[:iptype] == 'excl'
       
    29  
       
    30      properties
       
    31    end
       
    32  
       
    33 +
       
    34    def self.instances
       
    35      # LAK:NOTE See http://snurl.com/21zf8  [groups_google_com]
       
    36      x = adm(:list, "-cp").split("\n").collect do |line|
       
    37 @@ -29,109 +29,64 @@
       
    38      end
       
    39    end
       
    40  
       
    41 -  def multi_conf(name, should, &action)
       
    42 -    has = properties[name]
       
    43 -    has = [] if has == :absent
       
    44 -    rms = has - should
       
    45 -    adds = should - has
       
    46 -    (rms.map{|o| action.call(:rm,o)} + adds.map{|o| action.call(:add,o)}).join("\n")
       
    47 -  end
       
    48 -
       
    49 -  def self.def_prop(var, str)
       
    50 -    define_method('%s_conf' % var.to_s) do |v|
       
    51 -      str % v
       
    52 -    end
       
    53 -    define_method('%s=' % var.to_s) do |v|
       
    54 -      setconfig self.send( ('%s_conf'% var).intern, v)
       
    55 -    end
       
    56 -  end
       
    57 +  
       
    58 +  # Read in the zone configuration parameters and properties and
       
    59 +  # perform the zone configuration. Options are cloning the zone,
       
    60 +  # which needs a zonecfg_export file, configuring an archive, which
       
    61 +  # takes optional zonecfg_export and archived_zonename parameters,
       
    62 +  # or performing a zone configuration, which requires a zonecfg_export
       
    63 +  # file or string.
       
    64 +  def configure
       
    65  
       
    66 -  def self.def_multiprop(var, &conf)
       
    67 -    define_method(var.to_s) do |v|
       
    68 -      o = properties[var]
       
    69 -      return '' if o.nil? or o == :absent
       
    70 -      o.join(' ')
       
    71 -    end
       
    72 -    define_method('%s=' % var.to_s) do |v|
       
    73 -      setconfig self.send( ('%s_conf'% var).intern, v)
       
    74 -    end
       
    75 -    define_method('%s_conf' % var.to_s) do |v|
       
    76 -      multi_conf(var, v, &conf)
       
    77 +    if @resource[:archive].nil? && @resource[:zonecfg_export].nil?
       
    78 +      raise Puppet::Error, "No configuration resource is defined."
       
    79      end
       
    80 -  end
       
    81  
       
    82 -  def_prop :iptype, "set ip-type=%s"
       
    83 -  def_prop :autoboot, "set autoboot=%s"
       
    84 -  def_prop :path, "set zonepath=%s"
       
    85 -  def_prop :pool, "set pool=%s"
       
    86 -  def_prop :shares, "add rctl\nset name=zone.cpu-shares\nadd value (priv=privileged,limit=%s,action=none)\nend"
       
    87 -
       
    88 -  def_multiprop :ip do |action, str|
       
    89 -    interface, ip, defrouter = str.split(':')
       
    90 -    case action
       
    91 -    when :add
       
    92 -      cmd = ["add net"]
       
    93 -      cmd << "set physical=#{interface}" if interface
       
    94 -      cmd << "set address=#{ip}" if ip
       
    95 -      cmd << "set defrouter=#{defrouter}" if defrouter
       
    96 -      cmd << "end"
       
    97 -      cmd.join("\n")
       
    98 -    when :rm
       
    99 -      if ip
       
   100 -        "remove net address=#{ip}"
       
   101 -      elsif interface
       
   102 -        "remove net physical=#{interface}"
       
   103 -      else
       
   104 -        raise ArgumentError, "can not remove network based on default router"
       
   105 +    command = String.new
       
   106 +    if @resource[:clone]
       
   107 +      if !@resource[:zonecfg_export]
       
   108 +        raise Puppet::Error, "A zone configuration must be defined to
       
   109 +        clone a zone."
       
   110 +      end
       
   111 +      command = "#{command(:cfg)} -z #{@resource[:name]} -f #{@resource[:zonecfg_export]}"
       
   112 +    else
       
   113 +      unless @resource[:zonecfg_export].nil? || @resource[:zonecfg_export].empty?
       
   114 +        begin
       
   115 +          file = File.open(@resource[:zonecfg_export], "rb")
       
   116 +          str = file.read.gsub(/[\n]\n*\s*/, "; ")
       
   117 +        rescue
       
   118 +          str = @resource[:zonecfg_export].gsub(/[\n]\n*\s*/, "; ")
       
   119 +        ensure
       
   120 +          file.close unless file.nil?
       
   121 +        end
       
   122 +        @property_hash.clear
       
   123        end
       
   124 -    else self.fail action
       
   125 -    end
       
   126 -  end
       
   127  
       
   128 -  def_multiprop :dataset do |action, str|
       
   129 -    case action
       
   130 -    when :add; ['add dataset',"set name=#{str}",'end'].join("\n")
       
   131 -    when :rm; "remove dataset name=#{str}"
       
   132 -    else self.fail action
       
   133 -    end
       
   134 -  end
       
   135 +      unless @resource[:archive].nil? || @resource[:archive].empty?
       
   136 +        if !str.nil?
       
   137 +          command = "#{command(:cfg)} -z #{@resource[:name]} \'create -a #{@resource[:archive]};#{str}\'"
       
   138 +        else
       
   139 +          command = "#{command(:cfg)} -z #{@resource[:name]} create -a #{@resource[:archive]} "
       
   140 +        end
       
   141 +        if @resource[:archived_zonename]
       
   142 +          command << " -z #{@resource[:archived_zonename]}"
       
   143 +        end
       
   144 +      end
       
   145  
       
   146 -  def_multiprop :inherit do |action, str|
       
   147 -    case action
       
   148 -    when :add; ['add inherit-pkg-dir', "set dir=#{str}",'end'].join("\n")
       
   149 -    when :rm; "remove inherit-pkg-dir dir=#{str}"
       
   150 -    else self.fail action
       
   151 +      if !@resource[:zonecfg_export].nil? && @resource[:archive].nil?
       
   152 +        command = "#{command(:cfg)} -z #{@resource[:name]} \'#{str}\'"
       
   153 +      end
       
   154      end
       
   155 -  end
       
   156  
       
   157 -  def my_properties
       
   158 -    [:path, :iptype, :autoboot, :pool, :shares, :ip, :dataset, :inherit]
       
   159 -  end
       
   160 -
       
   161 -  # Perform all of our configuration steps.
       
   162 -  def configure
       
   163 -    self.fail "Path is required" unless @resource[:path]
       
   164 -    arr = ["create -b #{@resource[:create_args]}"]
       
   165 -
       
   166 -    # Then perform all of our configuration steps.  It's annoying
       
   167 -    # that we need this much internal info on the resource.
       
   168 -    self.resource.properties.each do |property|
       
   169 -      next unless my_properties.include? property.name
       
   170 -      method = (property.name.to_s + '_conf').intern
       
   171 -      arr << self.send(method ,@resource[property.name]) unless property.safe_insync?(properties[property.name])
       
   172 +    if command
       
   173 +      r = exec_cmd(:cmd => command)
       
   174      end
       
   175 -    setconfig(arr.join("\n"))
       
   176    end
       
   177  
       
   178    def destroy
       
   179      zonecfg :delete, "-F"
       
   180    end
       
   181  
       
   182 -  def add_cmd(cmd)
       
   183 -    @cmds = [] if @cmds.nil?
       
   184 -    @cmds << cmd
       
   185 -  end
       
   186 -
       
   187    def exists?
       
   188      properties[:ensure] != :absent
       
   189    end
       
   190 @@ -139,31 +94,31 @@
       
   191    # We cannot use the execpipe in util because the pipe is not opened in
       
   192    # read/write mode.
       
   193    def exec_cmd(var)
       
   194 -    # In bash, the exit value of the last command is the exit value of the
       
   195 -    # entire pipeline
       
   196 -    out = execute("echo \"#{var[:input]}\" | #{var[:cmd]}", :failonfail => false, :combine => true)
       
   197 -    st = $?.exitstatus
       
   198 -    {:out => out, :exit => st}
       
   199 -  end
       
   200 -
       
   201 -  # Clear out the cached values.
       
   202 -  def flush
       
   203 -    return if @cmds.nil? || @cmds.empty?
       
   204 -    str = (@cmds << "commit" << "exit").join("\n")
       
   205 -    @cmds = []
       
   206 -    @property_hash.clear
       
   207 -
       
   208 -    command = "#{command(:cfg)} -z #{@resource[:name]} -f -"
       
   209 -    r = exec_cmd(:cmd => command, :input => str)
       
   210 -    if r[:exit] != 0 or r[:out] =~ /not allowed/
       
   211 -      raise ArgumentError, "Failed to apply configuration"
       
   212 +    if var[:input]
       
   213 +    	execute("echo \"#{var[:input]}\" | #{var[:cmd]}", :failonfail => true, :combine => true)
       
   214 +    else
       
   215 +        execute("#{var[:cmd]}", :failonfail => true, :combine => true)
       
   216      end
       
   217    end
       
   218  
       
   219 +
       
   220    def install(dummy_argument=:work_arround_for_ruby_GC_bug)
       
   221 +    if ['5.11', '5.12'].include? Facter.value(:kernelrelease)
       
   222 +       if !@resource[:install_args] and @resource[:config_profile]
       
   223 +         @resource[:install_args] = " -c " + @resource[:config_profile]
       
   224 +       elsif !@resource[:install_args] and @resource[:archive]
       
   225 +         @resource[:install_args] = " -a " + @resource[:archive]
       
   226 +	     if @resource[:archived_zonename]
       
   227 +	       @resource[:install_args] << " -z " + @resource[:archived_zonename]
       
   228 +	     end
       
   229 +       elsif @resource[:config_profile]
       
   230 +	     @resource[:install_args] << " -c " + @resource[:config_profile]
       
   231 +       end
       
   232 +    end
       
   233 +       
       
   234      if @resource[:clone] # TODO: add support for "-s snapshot"
       
   235 -      zoneadm :clone, @resource[:clone]
       
   236 -    elsif @resource[:install_args]
       
   237 +      zoneadm :clone, @resource[:clone] 
       
   238 +    elsif @resource[:install_args] 
       
   239        zoneadm :install, @resource[:install_args].split(" ")
       
   240      else
       
   241        zoneadm :install
       
   242 @@ -183,11 +138,12 @@
       
   243        end
       
   244      end
       
   245      @property_hash.dup
       
   246 +    
       
   247    end
       
   248  
       
   249    # We need a way to test whether a zone is in process.  Our 'ensure'
       
   250    # property models the static states, but we need to handle the temporary ones.
       
   251 -  def processing?
       
   252 +  def processing?  
       
   253      hash = status
       
   254      return false unless hash
       
   255      ["incomplete", "ready", "shutting_down"].include? hash[:ensure]
       
   256 @@ -215,7 +171,6 @@
       
   257    #
       
   258    def getconfig
       
   259      output = zonecfg :info
       
   260 -
       
   261      name = nil
       
   262      current = nil
       
   263      hash = {}
       
   264 @@ -245,14 +200,9 @@
       
   265      hash
       
   266    end
       
   267  
       
   268 -  # Execute a configuration string.  Can't be private because it's called
       
   269 -  # by the properties.
       
   270 -  def setconfig(str)
       
   271 -    add_cmd str
       
   272 -  end
       
   273 -
       
   274    def start
       
   275      # Check the sysidcfg stuff
       
   276 +   if ['5.10'].include? Facter.value(:kernelrelease)
       
   277      if cfg = @resource[:sysidcfg]
       
   278        self.fail "Path is required" unless @resource[:path]
       
   279        zoneetc = File.join(@resource[:path], "root", "etc")
       
   280 @@ -273,7 +223,9 @@
       
   281          end
       
   282        end
       
   283      end
       
   284 +   end
       
   285  
       
   286 +    # Boots the zone
       
   287      zoneadm :boot
       
   288    end
       
   289  
       
   290 @@ -286,64 +238,35 @@
       
   291      end
       
   292  
       
   293      main = self.class.line2hash(output.chomp)
       
   294 -
       
   295 -    # Now add in the configuration information
       
   296 -    config_status.each do |name, value|
       
   297 -      main[name] = value
       
   298 -    end
       
   299 -
       
   300      main
       
   301    end
       
   302  
       
   303    def ready
       
   304 +    # Prepare the zone
       
   305      zoneadm :ready
       
   306    end
       
   307  
       
   308    def stop
       
   309 -    zoneadm :halt
       
   310 +     # Shutdown the zone
       
   311 +     zoneadm :halt
       
   312    end
       
   313 +  
       
   314  
       
   315    def unconfigure
       
   316 +    # Unconfigure and delete the zone
       
   317      zonecfg :delete, "-F"
       
   318    end
       
   319  
       
   320    def uninstall
       
   321 +    # Uninstall the zone
       
   322      zoneadm :uninstall, "-F"
       
   323    end
       
   324  
       
   325    private
       
   326  
       
   327 -  # Turn the results of getconfig into status information.
       
   328 -  def config_status
       
   329 -    config = getconfig
       
   330 -    result = {}
       
   331 -
       
   332 -    result[:autoboot] = config[:autoboot] ? config[:autoboot].intern : :true
       
   333 -    result[:pool] = config[:pool]
       
   334 -    result[:shares] = config[:shares]
       
   335 -    if dir = config["inherit-pkg-dir"]
       
   336 -      result[:inherit] = dir.collect { |dirs| dirs[:dir] }
       
   337 -    end
       
   338 -    if datasets = config["dataset"]
       
   339 -      result[:dataset] = datasets.collect { |dataset| dataset[:name] }
       
   340 -    end
       
   341 -    result[:iptype] = config[:'ip-type'] if config[:'ip-type']
       
   342 -    if net = config["net"]
       
   343 -      result[:ip] = net.collect do |params|
       
   344 -        if params[:defrouter]
       
   345 -          "#{params[:physical]}:#{params[:address]}:#{params[:defrouter]}"
       
   346 -        elsif params[:address]
       
   347 -          "#{params[:physical]}:#{params[:address]}"
       
   348 -        else
       
   349 -          params[:physical]
       
   350 -        end
       
   351 -      end
       
   352 -    end
       
   353 -
       
   354 -    result
       
   355 -  end
       
   356 -
       
   357    def zoneadm(*cmd)
       
   358 +    # Execute the zoneadm command with the arguments
       
   359 +    # provided
       
   360      adm("-z", @resource[:name], *cmd)
       
   361    rescue Puppet::ExecutionFailure => detail
       
   362      self.fail "Could not #{cmd[0]} zone: #{detail}"