~ubuntu-branches/ubuntu/wily/puppet/wily

« back to all changes in this revision

Viewing changes to lib/puppet/provider/yumrepo/inifile.rb

  • Committer: Package Import Robot
  • Author(s): Stig Sandbeck Mathisen
  • Date: 2014-04-17 14:50:28 UTC
  • mfrom: (3.1.59 sid)
  • Revision ID: package-import@ubuntu.com-20140417145028-j3p3dwvp8ggpzvaf
Tags: 3.5.1-1
ImportedĀ upstreamĀ releaseĀ 3.5.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'puppet/util/inifile'
 
2
 
 
3
Puppet::Type.type(:yumrepo).provide(:inifile) do
 
4
  desc 'Manage yum repos'
 
5
 
 
6
  PROPERTIES = Puppet::Type.type(:yumrepo).validproperties
 
7
 
 
8
  # @return [Array<Puppet::Providers>] Return all the providers built up from
 
9
  #   discovered content on the local node.
 
10
  def self.instances
 
11
    instances = []
 
12
    # Iterate over each section of our virtual file.
 
13
    virtual_inifile.each_section do |section|
 
14
      attributes_hash = {:name => section.name, :ensure => :present, :provider => :yumrepo}
 
15
      # We need to build up a attributes hash
 
16
      section.entries.each do |key, value|
 
17
        key = key.to_sym
 
18
        if valid_property?(key)
 
19
          # We strip the values here to handle cases where distros set values
 
20
          # like enabled = 1 with spaces.
 
21
          attributes_hash[key] = value
 
22
        elsif key == :name
 
23
          attributes_hash[:descr] = value
 
24
        end
 
25
      end
 
26
      instances << new(attributes_hash)
 
27
    end
 
28
  return instances
 
29
  end
 
30
 
 
31
  # @param resources [Array<Puppet::Resource>] Resources to prefetch.
 
32
  # @return [Array<Puppet::Resource>] Resources with providers set.
 
33
  def self.prefetch(resources)
 
34
    repos = instances
 
35
    resources.keys.each do |name|
 
36
      if provider = repos.find { |repo| repo.name == name }
 
37
        resources[name].provider = provider
 
38
      end
 
39
    end
 
40
  end
 
41
 
 
42
  # Return a list of existing directories that could contain repo files.  Fail if none found.
 
43
  # @param conf [String] Configuration file to look for directories in.
 
44
  # @param dirs [Array] Default locations for yum repos.
 
45
  # @return [Array] Directories that were found to exist on the node.
 
46
  def self.reposdir(conf='/etc/yum.conf', dirs=['/etc/yum.repos.d', '/etc/yum/repos.d'])
 
47
    reposdir = find_conf_value('reposdir', conf)
 
48
    dirs << reposdir if reposdir
 
49
 
 
50
    # We can't use the below due to Ruby 1.8.7
 
51
    # dirs.select! { |dir| Puppet::FileSystem.exist?(dir) }
 
52
    dirs.delete_if { |dir| ! Puppet::FileSystem.exist?(dir)  }
 
53
    if dirs.empty?
 
54
      fail('No yum directories were found on the local filesystem')
 
55
    else
 
56
      return dirs
 
57
    end
 
58
  end
 
59
 
 
60
  # Helper method to look up specific values in ini style files.
 
61
  # @todo Migrate this into Puppet::Util::IniConfig.
 
62
  # @param value [String] Value to look for in the configuration file.
 
63
  # @param conf [String] Configuration file to check for value.
 
64
  # @return [String] The value of a looked up key from the configuration file.
 
65
  def self.find_conf_value(value, conf='/etc/yum.conf')
 
66
    if Puppet::FileSystem.exist?(conf)
 
67
      contents = Puppet::FileSystem.read(conf)
 
68
      match = /^#{value}\s*=\s*(.*)/.match(contents)
 
69
    end
 
70
 
 
71
    return match.captures[0] if match
 
72
  end
 
73
 
 
74
  # Build a virtual inifile by reading in numerous .repo
 
75
  # files into a single virtual file to ease manipulation.
 
76
  # @return [Puppet::Util::IniConfig::File] The virtual inifile representing
 
77
  #   multiple real files.
 
78
  def self.virtual_inifile
 
79
    unless @virtual
 
80
      @virtual = Puppet::Util::IniConfig::File.new
 
81
      reposdir.each do |dir|
 
82
        Dir.glob("#{dir}/*.repo").each do |file|
 
83
          @virtual.read(file) if Puppet::FileSystem.file?(file)
 
84
        end
 
85
      end
 
86
    end
 
87
    return @virtual
 
88
  end
 
89
 
 
90
  # @param key [String] The property to look up.
 
91
  # @return [Boolean] Returns true if the property is defined in the type.
 
92
  def self.valid_property?(key)
 
93
    PROPERTIES.include?(key)
 
94
  end
 
95
 
 
96
  # We need to return a valid section from the larger virtual inifile here,
 
97
  # which we do by first looking it up and then creating a new section for
 
98
  # the appropriate name if none was found.
 
99
  # @param name [String] Section name to lookup in the virtual inifile.
 
100
  # @return [Puppet::Util::IniConfig] The IniConfig section
 
101
  def self.section(name)
 
102
    result = self.virtual_inifile[name]
 
103
    # Create a new section if not found.
 
104
    unless result
 
105
      # Previously we did an .each on reposdir with the effect that we
 
106
      # constantly created and overwrote result until the last entry of
 
107
      # the array.  This was done because the ordering is
 
108
      # [defaults, custom] for reposdir and we want to use the custom if
 
109
      # we have it and the defaults if not.
 
110
      path = ::File.join(reposdir.last, "#{name}.repo")
 
111
      Puppet.info("create new repo #{name} in file #{path}")
 
112
      result = self.virtual_inifile.add_section(name, path)
 
113
    end
 
114
    result
 
115
  end
 
116
 
 
117
  # Here we store all modifications to disk, forcing the output file to 0644 if it differs.
 
118
  # @return [void]
 
119
  def self.store
 
120
    inifile = self.virtual_inifile
 
121
    inifile.store
 
122
 
 
123
    target_mode = 0644
 
124
    inifile.each_file do |file|
 
125
      current_mode = Puppet::FileSystem.stat(file).mode & 0777
 
126
      unless current_mode == target_mode
 
127
        Puppet.info "changing mode of #{file} from %03o to %03o" % [current_mode, target_mode]
 
128
        Puppet::FileSystem.chmod(target_mode, file)
 
129
      end
 
130
    end
 
131
  end
 
132
 
 
133
  # @return [void]
 
134
  def create
 
135
    @property_hash[:ensure] = :present
 
136
 
 
137
    new_section = current_section
 
138
 
 
139
    # We fetch a list of properties from the type, then iterate
 
140
    # over them, avoiding ensure.  We're relying on .should to
 
141
    # check if the property has been set and should be modified,
 
142
    # and if so we set it in the virtual inifile.
 
143
    PROPERTIES.each do |property|
 
144
      next if property == :ensure
 
145
 
 
146
 
 
147
      if value = @resource.should(property)
 
148
        self.send("#{property}=", value)
 
149
      end
 
150
    end
 
151
  end
 
152
 
 
153
  # @return [Boolean] Returns true if ensure => present.
 
154
  def exists?
 
155
    @property_hash[:ensure] == :present
 
156
  end
 
157
 
 
158
  # We don't actually destroy the file here, merely mark it for
 
159
  # destruction in the section.
 
160
  # @return [void]
 
161
  def destroy
 
162
    # Flag file for deletion on flush.
 
163
    current_section.destroy=(true)
 
164
 
 
165
    @property_hash.clear
 
166
  end
 
167
 
 
168
  # @return [void]
 
169
  def flush
 
170
    self.class.store
 
171
  end
 
172
 
 
173
  # Generate setters and getters for our INI properties.
 
174
  PROPERTIES.each do |property|
 
175
    # The ensure property uses #create, #exists, and #destroy we can't generate
 
176
    # meaningful setters and getters for this
 
177
    next if property == :ensure
 
178
 
 
179
    define_method(property) do
 
180
      get_property(property)
 
181
    end
 
182
 
 
183
    define_method("#{property}=") do |value|
 
184
      set_property(property, value)
 
185
    end
 
186
  end
 
187
 
 
188
  # Map the yumrepo 'descr' type property to the 'name' INI property.
 
189
  def descr
 
190
    if ! @property_hash.has_key?(:descr)
 
191
      @property_hash[:descr] = current_section['name']
 
192
    end
 
193
    value = @property_hash[:descr]
 
194
    value.nil? ? :absent : value
 
195
  end
 
196
 
 
197
  def descr=(value)
 
198
    value = (value == :absent ? nil : value)
 
199
    current_section['name'] = value
 
200
    @property_hash[:descr] = value
 
201
  end
 
202
 
 
203
  private
 
204
 
 
205
  def get_property(property)
 
206
    if ! @property_hash.has_key?(property)
 
207
      @property_hash[property] = current_section[property.to_s]
 
208
    end
 
209
    value = @property_hash[property]
 
210
    value.nil? ? :absent : value
 
211
  end
 
212
 
 
213
  def set_property(property, value)
 
214
    value = (value == :absent ? nil : value)
 
215
    current_section[property.to_s] = value
 
216
    @property_hash[property] = value
 
217
  end
 
218
 
 
219
  # @return [void]
 
220
  def section(name)
 
221
    self.class.section(name)
 
222
  end
 
223
 
 
224
  def current_section
 
225
    self.class.section(self.name)
 
226
  end
 
227
end