puppet 4.8.0 → 4.8.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of puppet might be problematic. Click here for more details.

data/Gemfile CHANGED
@@ -53,6 +53,9 @@ group(:development, :test) do
53
53
 
54
54
  gem 'rdoc', "~> 4.1", :platforms => [:ruby]
55
55
 
56
+ # webmock requires addressable as as of 2.5.0 addressable started
57
+ # requiring the public_suffix gem which requires Ruby 2
58
+ gem 'addressable', '< 2.5.0'
56
59
  gem 'webmock', '~> 1.24'
57
60
  gem 'vcr', '~> 2.9'
58
61
  end
@@ -9,11 +9,6 @@
9
9
  "email": "henrik.lindberg@puppet.com",
10
10
  "name": "Henrik Lindberg"
11
11
  },
12
- {
13
- "github": "kylog",
14
- "email": "kylo@puppet.com",
15
- "name": "Kylo Ginsberg"
16
- },
17
12
  {
18
13
  "github": "joshcooper",
19
14
  "email": "josh@puppet.com",
data/Rakefile CHANGED
@@ -84,7 +84,7 @@ task(:commits) do
84
84
  # falls back to `master..HEAD` as a next best bet as `master` is unlikely to
85
85
  # ever be absent.
86
86
  commit_range = ENV['TRAVIS_COMMIT_RANGE'].nil? ? 'master..HEAD' : ENV['TRAVIS_COMMIT_RANGE']
87
- puts "Checking commits..."
87
+ puts "Checking commits #{commit_range}"
88
88
  %x{git log --no-merges --pretty=%s #{commit_range}}.each_line do |commit_summary|
89
89
  # This regex tests for the currently supported commit summary tokens: maint, doc, packaging, or pup-<number>.
90
90
  # The exception tries to explain it in more full.
@@ -108,7 +108,7 @@ Puppet::Face.define(:config, '0.0.1') do
108
108
  when_invoked do |name, value, options|
109
109
  path = Puppet::FileSystem.pathname(Puppet.settings.which_configuration_file)
110
110
  Puppet::FileSystem.touch(path)
111
- Puppet::FileSystem.open(path, nil, 'r+') do |file|
111
+ Puppet::FileSystem.open(path, nil, 'r+:UTF-8') do |file|
112
112
  Puppet::Settings::IniFile.update(file) do |config|
113
113
  config.set(options[:section], name, value)
114
114
  end
@@ -209,20 +209,14 @@ Puppet::Type.type(:mount).provide(
209
209
 
210
210
  # Update fstab entries that are mounted
211
211
  providers.each do |prov|
212
- mounts.delete_if do |mount|
213
- if mount[:name] == prov.get(:name) && mount[:mounted] == :yes
214
- prov.set(:ensure => :mounted)
215
- prov.set(:live_options => mount[:live_options])
216
- true
217
- else
218
- false
219
- end
212
+ if mounts.delete({:name => prov.get(:name), :mounted => :yes}) then
213
+ prov.set(:ensure => :mounted)
220
214
  end
221
215
  end
222
216
 
223
217
  # Add mounts that are not in fstab but mounted
224
218
  mounts.each do |mount|
225
- providers << new(:ensure => :ghost, :name => mount[:name], :live_options => mount[:live_options])
219
+ providers << new(:ensure => :ghost, :name => mount[:name])
226
220
  end
227
221
  providers
228
222
  end
@@ -238,7 +232,6 @@ Puppet::Type.type(:mount).provide(
238
232
  # to fstab we need to know if the device was mounted before)
239
233
  mountinstances.each do |hash|
240
234
  if mount = resources[hash[:name]]
241
- mount.provider.set(:live_options => hash[:live_options])
242
235
  case mount.provider.get(:ensure)
243
236
  when :absent # Mount not in fstab
244
237
  mount.provider.set(:ensure => :ghost)
@@ -261,7 +254,6 @@ Puppet::Type.type(:mount).provide(
261
254
  else
262
255
  / on (\S*)/
263
256
  end
264
-
265
257
  instances = []
266
258
  mount_output = mountcmd.split("\n")
267
259
  if mount_output.length >= 2 and mount_output[1] =~ /^[- \t]*$/
@@ -272,13 +264,7 @@ Puppet::Type.type(:mount).provide(
272
264
  end
273
265
  mount_output.each do |line|
274
266
  if match = regex.match(line) and name = match.captures.first
275
- live_options_platforms = ["Linux", "Darwin"]
276
- if live_options_platforms.include? Facter.value(:kernel)
277
- options = line[/\(.*\)/].tr('()', '')
278
- instances << {:name => name, :mounted => :yes, :live_options => options}
279
- else
280
- instances << {:name => name, :mounted => :yes}
281
- end
267
+ instances << {:name => name, :mounted => :yes} # Only :name is important here
282
268
  else
283
269
  raise Puppet::Error, "Could not understand line #{line} from mount output"
284
270
  end
@@ -13,9 +13,9 @@ class Puppet::Settings::IniFile
13
13
  config = new([DefaultSection.new])
14
14
  config_fh.each_line do |line|
15
15
  case line
16
- when /^(\s*)\[(\w+)\](\s*)$/
16
+ when /^(\s*)\[([[:word:]]+)\](\s*)$/
17
17
  config.append(SectionLine.new($1, $2, $3))
18
- when /^(\s*)(\w+)(\s*=\s*)(.*?)(\s*)$/
18
+ when /^(\s*)([[:word:]]+)(\s*=\s*)(.*?)(\s*)$/
19
19
  config.append(SettingLine.new($1, $2, $3, $4, $5))
20
20
  else
21
21
  config.append(Line.new(line))
@@ -176,50 +176,6 @@ module Puppet
176
176
  appear in fstab. For many platforms this is a comma delimited string.
177
177
  Consult the fstab(5) man page for system-specific details."
178
178
 
179
- def insync?(is)
180
-
181
- if @resource[:ensure] == :mounted && !provider.property_hash[:live_options].nil?
182
-
183
- # The mount options according to /etc/fstab. It is possible for puppet to
184
- # update this file to reflect new options even if the remount to update
185
- # the options has actually failed
186
- fstab_options = provider.property_hash[:options] || ''
187
- # The mount options according to the output of the 'mount' command. These will
188
- # always reflect the options of the actual mounted device
189
- mount_options = provider.property_hash[:live_options] || ''
190
- # The desired mount options that have been specified in the puppet manifest
191
- resource_options = @resource[:options] || ''
192
-
193
- mount_list = mount_options.split(',')
194
- resource_list = resource_options.split(',')
195
- # Remove the string 'defaults' from the list of resources, because when
196
- # we are comparing against the mount command output 'defaults' will be
197
- # expanded into the full list of default options for the OS and file system
198
- resource_list.delete('defaults')
199
-
200
- # Do the options in fstab match the options that the user has defined?
201
- if fstab_options != resource_options
202
- return false
203
- end
204
-
205
- # Do the options provided by the 'mount' command match the options that
206
- # the user has defined? We have to check this too because fstab could provide
207
- # a false positive if a remount has failed
208
- #
209
- # We want to see if the mount command options contain the list of user
210
- # specified options from the manifest. The reason we cannot do a 1:1
211
- # comparison is because the expanded list of default options may be included
212
- # in the mount output. These vary between OS and file system so since we don't
213
- # have a good way to find out what they are, just check for the specific options
214
- # the user has specified
215
- if !(resource_list - mount_list).empty?
216
- return false
217
- end
218
- end
219
-
220
- super
221
- end
222
-
223
179
  validate do |value|
224
180
  raise Puppet::Error, "options must not contain whitespace: #{value}" if value =~ /\s/
225
181
  raise Puppet::Error, "options must not be an empty string" if value.empty?
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '4.8.0'
10
+ PUPPETVERSION = '4.8.1'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -0,0 +1,80 @@
1
+ #! /usr/bin/env ruby
2
+ require 'spec_helper'
3
+ require 'puppet/face'
4
+
5
+ describe Puppet::Face[:config, '0.0.1'] do
6
+ include PuppetSpec::Files
7
+
8
+ # different UTF-8 widths
9
+ # 1-byte A
10
+ # 2-byte ۿ - http://www.fileformat.info/info/unicode/char/06ff/index.htm - 0xDB 0xBF / 219 191
11
+ # 3-byte ᚠ - http://www.fileformat.info/info/unicode/char/16A0/index.htm - 0xE1 0x9A 0xA0 / 225 154 160
12
+ # 4-byte 𠜎 - http://www.fileformat.info/info/unicode/char/2070E/index.htm - 0xF0 0xA0 0x9C 0x8E / 240 160 156 142
13
+ MIXED_UTF8 = "A\u06FF\u16A0\u{2070E}" # Aۿᚠ𠜎
14
+ let (:tmp_environment_path) { tmpdir('envpath') }
15
+ let (:tmp_config) { tmpfile('puppet.conf') }
16
+
17
+ def load_settings(path)
18
+ test_settings = Puppet::Settings.new
19
+
20
+ test_settings.define_settings(:main,
21
+ :config => {
22
+ :type => :file,
23
+ :default => path,
24
+ :desc => '',
25
+ },
26
+ :environmentpath => {
27
+ :default => tmp_environment_path,
28
+ :desc => '',
29
+ },
30
+ :basemodulepath => {
31
+ :default => '',
32
+ :desc => '',
33
+ },
34
+ # definition required to use the value
35
+ :rando_key => {
36
+ :default => '',
37
+ :desc => ''
38
+ },
39
+ MIXED_UTF8.to_sym => {
40
+ :default => '',
41
+ :desc => ''
42
+ },
43
+ )
44
+
45
+ test_settings.initialize_global_settings
46
+ test_settings
47
+ end
48
+
49
+ before :each do
50
+ File.open(tmp_config, 'w', :encoding => 'UTF-8') do |file|
51
+ file.puts <<-EOF
52
+ [main]
53
+ rando_key=foobar
54
+ #{MIXED_UTF8}=foobar
55
+ EOF
56
+ end
57
+ end
58
+
59
+ context 'when getting / setting UTF8 values' do
60
+ # key must be a defined setting
61
+ ['rando_key', MIXED_UTF8].each do |key|
62
+ it "can change '#{key}' keyed ASCII value to a UTF-8 value and read it back" do
63
+ key = "rando_key"
64
+ value = "value#{MIXED_UTF8.reverse}value"
65
+
66
+ # needed for the subject.set to write to correct file
67
+ Puppet.settings.stubs(:which_configuration_file).returns(tmp_config)
68
+ subject.set(key, value)
69
+
70
+ # make sure subject.print looks at the newly modified settings
71
+ test_settings = load_settings(tmp_config)
72
+ # instead of the default Puppet.settings (implementation detail)
73
+ Puppet.stubs(:settings).returns(test_settings)
74
+
75
+ expect { subject.print() }.to have_printed("#{key} = #{value}")
76
+ expect { subject.print(key, :section => 'main') }.to have_printed("#{value}")
77
+ end
78
+ end
79
+ end
80
+ end
@@ -149,10 +149,9 @@ describe "mount provider (integration)", :unless => Puppet.features.microsoft_wi
149
149
  pending "Due to bug 6309"
150
150
  @mounted = true
151
151
  @current_device = "/dev/disk2s2"
152
- @current_options = "local"
153
152
  create_fake_fstab(true)
154
153
  @desired_options = "local"
155
- run_in_catalog(:ensure=>:mounted, :options=>'msdos,local')
154
+ run_in_catalog(:ensure=>:mounted, :options=>'local')
156
155
  expect(@current_device).to eq("/dev/disk1s1")
157
156
  expect(@mounted).to eq(true)
158
157
  expect(@current_options).to eq('local')
@@ -8,7 +8,7 @@ describe Puppet::Util::Windows::SID::Principal, :if => Puppet.features.microsoft
8
8
  let (:system_bytes) { [1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0] }
9
9
  let (:null_sid_bytes) { bytes = [1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] }
10
10
  let (:administrator_bytes) { [1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2, 0, 0] }
11
- let (:computer_sid) { Puppet::Util::Windows::SID.name_to_sid_object(Socket.gethostname) }
11
+ let (:computer_sid) { Puppet::Util::Windows::SID.name_to_sid_object(Puppet::Util::Windows::ADSI.computer_name) }
12
12
  # BUILTIN is localized on German Windows, but not French
13
13
  # looking this up like this dilutes the values of the tests as we're comparing two mechanisms
14
14
  # for returning the same values, rather than to a known good
@@ -64,7 +64,7 @@ describe Puppet::Util::Windows::SID::Principal, :if => Puppet.features.microsoft
64
64
  # otherwise running in AppVeyor there is no Administrator and a the current local user can be used
65
65
  skip if (running_as_system && !user_exists)
66
66
 
67
- hostname = Socket.gethostname
67
+ hostname = Puppet::Util::Windows::ADSI.computer_name
68
68
 
69
69
  principal = Puppet::Util::Windows::SID::Principal.lookup_account_name("#{hostname}\\#{username}")
70
70
  expect(principal.account).to match(/^#{Regexp.quote(username)}$/i)
@@ -44,6 +44,53 @@ syslogfacility = file
44
44
  subject.print('all')
45
45
  end
46
46
 
47
+ context "when setting config values" do
48
+ let(:config_file) { '/foo/puppet.conf' }
49
+ let(:path) { Pathname.new(config_file).expand_path }
50
+ before(:each) do
51
+ Puppet[:config] = config_file
52
+ Puppet::FileSystem.stubs(:pathname).with(path.to_s).returns(path)
53
+ Puppet::FileSystem.stubs(:touch)
54
+ end
55
+
56
+ it "writes to the correct puppet config file" do
57
+ Puppet::FileSystem.expects(:open).with(path, anything, anything)
58
+ subject.set('foo', 'bar')
59
+ end
60
+
61
+ it "creates a config file if one does not exist" do
62
+ Puppet::FileSystem.stubs(:open).with(path, anything, anything).yields(StringIO.new)
63
+ Puppet::FileSystem.expects(:touch).with(path)
64
+ subject.set('foo', 'bar')
65
+ end
66
+
67
+ it "sets the supplied config/value in the default section (main)" do
68
+ Puppet::FileSystem.stubs(:open).with(path, anything, anything).yields(StringIO.new)
69
+ config = Puppet::Settings::IniFile.new([Puppet::Settings::IniFile::DefaultSection.new])
70
+ manipulator = Puppet::Settings::IniFile::Manipulator.new(config)
71
+ Puppet::Settings::IniFile::Manipulator.stubs(:new).returns(manipulator)
72
+
73
+ manipulator.expects(:set).with("main", "foo", "bar")
74
+ subject.set('foo', 'bar')
75
+ end
76
+
77
+ it "sets the value in the supplied section" do
78
+ Puppet::FileSystem.stubs(:open).with(path, anything, anything).yields(StringIO.new)
79
+ config = Puppet::Settings::IniFile.new([Puppet::Settings::IniFile::DefaultSection.new])
80
+ manipulator = Puppet::Settings::IniFile::Manipulator.new(config)
81
+ Puppet::Settings::IniFile::Manipulator.stubs(:new).returns(manipulator)
82
+
83
+ manipulator.expects(:set).with("baz", "foo", "bar")
84
+ subject.set('foo', 'bar', {:section => "baz"})
85
+
86
+ end
87
+
88
+ it "opens the file with UTF-8 encoding" do
89
+ Puppet::FileSystem.expects(:open).with(path, nil, 'r+:UTF-8')
90
+ subject.set('foo', 'bar')
91
+ end
92
+ end
93
+
47
94
  shared_examples_for :config_printing_a_section do |section|
48
95
 
49
96
  def add_section_option(args, section)
@@ -115,7 +115,6 @@ FSTAB
115
115
  describe "mountinstances" do
116
116
  it "should get name from mountoutput found on Solaris" do
117
117
  Facter.stubs(:value).with(:osfamily).returns 'Solaris'
118
- Facter.stubs(:value).with(:kernel).returns 'SunOS'
119
118
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('solaris.mount')))
120
119
  mounts = described_class.mountinstances
121
120
  expect(mounts.size).to eq(6)
@@ -129,7 +128,6 @@ FSTAB
129
128
 
130
129
  it "should get name from mountoutput found on HP-UX" do
131
130
  Facter.stubs(:value).with(:osfamily).returns 'HP-UX'
132
- Facter.stubs(:value).with(:kernel).returns 'HP-UX'
133
131
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('hpux.mount')))
134
132
  mounts = described_class.mountinstances
135
133
  expect(mounts.size).to eq(17)
@@ -152,35 +150,32 @@ FSTAB
152
150
  expect(mounts[16]).to eq({ :name => '/ghost', :mounted => :yes })
153
151
  end
154
152
 
155
- it "should get name and mount options from mountoutput found on Darwin" do
153
+ it "should get name from mountoutput found on Darwin" do
156
154
  Facter.stubs(:value).with(:osfamily).returns 'Darwin'
157
- Facter.stubs(:value).with(:kernel).returns 'Darwin'
158
155
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('darwin.mount')))
159
156
  mounts = described_class.mountinstances
160
157
  expect(mounts.size).to eq(6)
161
- expect(mounts[0]).to eq({ :name => '/', :mounted => :yes, :live_options=>"hfs, local, journaled"})
162
- expect(mounts[1]).to eq({ :name => '/dev', :mounted => :yes, :live_options=>"devfs, local, nobrowse"})
163
- expect(mounts[2]).to eq({ :name => '/net', :mounted => :yes, :live_options=>"autofs, nosuid, automounted, nobrowse"})
164
- expect(mounts[3]).to eq({ :name => '/home', :mounted => :yes, :mounted=>:yes, :live_options=>"autofs, automounted, nobrowse"})
165
- expect(mounts[4]).to eq({ :name => '/usr', :mounted => :yes, :mounted=>:yes, :live_options=>"hfs, local, journaled"})
166
- expect(mounts[5]).to eq({ :name => '/ghost', :mounted => :yes, :live_options => "hfs, local, journaled"})
158
+ expect(mounts[0]).to eq({ :name => '/', :mounted => :yes })
159
+ expect(mounts[1]).to eq({ :name => '/dev', :mounted => :yes })
160
+ expect(mounts[2]).to eq({ :name => '/net', :mounted => :yes })
161
+ expect(mounts[3]).to eq({ :name => '/home', :mounted => :yes })
162
+ expect(mounts[4]).to eq({ :name => '/usr', :mounted => :yes })
163
+ expect(mounts[5]).to eq({ :name => '/ghost', :mounted => :yes })
167
164
  end
168
165
 
169
- it "should get name and mount options from mountoutput found on Linux" do
166
+ it "should get name from mountoutput found on Linux" do
170
167
  Facter.stubs(:value).with(:osfamily).returns 'Gentoo'
171
- Facter.stubs(:value).with(:kernel).returns 'Linux'
172
168
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('linux.mount')))
173
169
  mounts = described_class.mountinstances
174
- expect(mounts[0]).to eq({ :name => '/', :mounted => :yes, :live_options=>"rw,noatime"})
175
- expect(mounts[1]).to eq({ :name => '/lib64/rc/init.d', :mounted => :yes, :live_options => "rw,nosuid,nodev,noexec,relatime,size=1024k,mode=755" })
176
- expect(mounts[2]).to eq({ :name => '/sys', :mounted => :yes, :live_options => "rw,nosuid,nodev,noexec,relatime"})
177
- expect(mounts[3]).to eq({ :name => '/usr/portage', :mounted => :yes, :live_options => "rw" })
178
- expect(mounts[4]).to eq({ :name => '/ghost', :mounted => :yes, :live_options => "rw" })
170
+ expect(mounts[0]).to eq({ :name => '/', :mounted => :yes })
171
+ expect(mounts[1]).to eq({ :name => '/lib64/rc/init.d', :mounted => :yes })
172
+ expect(mounts[2]).to eq({ :name => '/sys', :mounted => :yes })
173
+ expect(mounts[3]).to eq({ :name => '/usr/portage', :mounted => :yes })
174
+ expect(mounts[4]).to eq({ :name => '/ghost', :mounted => :yes })
179
175
  end
180
176
 
181
177
  it "should get name from mountoutput found on AIX" do
182
178
  Facter.stubs(:value).with(:osfamily).returns 'AIX'
183
- Facter.stubs(:value).with(:kernel).returns 'AIX'
184
179
  described_class.stubs(:mountcmd).returns(File.read(my_fixture('aix.mount')))
185
180
  mounts = described_class.mountinstances
186
181
  expect(mounts[0]).to eq({ :name => '/', :mounted => :yes })
@@ -229,42 +224,29 @@ FSTAB
229
224
  platform != 'solaris' or
230
225
  skip "We need to stub the operatingsystem fact at load time, but can't"
231
226
  end
227
+
228
+ # Stub the mount output to our fixture.
229
+ begin
230
+ mount = my_fixture(platform + '.mount')
231
+ described_class.stubs(:mountcmd).returns File.read(mount)
232
+ rescue
233
+ skip "is #{platform}.mount missing at this point?"
234
+ end
235
+
236
+ # Note: we have to stub default_target before creating resources
237
+ # because it is used by Puppet::Type::Mount.new to populate the
238
+ # :target property.
239
+ described_class.stubs(:default_target).returns fstab
240
+ @retrieve = described_class.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}}
232
241
  end
233
242
 
234
243
  # Following mountpoint are present in all fstabs/mountoutputs
235
244
  describe "on other platforms than Solaris", :if => Facter.value(:osfamily) != 'Solaris' do
236
- before :each do
237
- # Stub the mount output to our fixture.
238
- begin
239
- mount = my_fixture(platform + '.mount')
240
- described_class.stubs(:mountcmd).returns File.read(mount)
241
- rescue
242
- skip "is #{platform}.mount missing at this point?"
243
- end
244
-
245
- # Note: we have to stub default_target before creating resources
246
- # because it is used by Puppet::Type::Mount.new to populate the
247
- # :target property.
248
- described_class.stubs(:default_target).returns fstab
249
-
250
- platforms = {
251
- 'linux' => ['Gentoo', 'Linux'],
252
- 'freebsd' => ['BSD', 'BSD'],
253
- 'openbsd' => ['BSD', 'BSD'],
254
- 'netbsd' => ['BSd', 'BSD']
255
- }
256
- Facter.stubs(:value).with(:osfamily).returns(platforms[platform][0])
257
- Facter.stubs(:value).with(:kernel).returns(platforms[platform][1])
258
-
259
- @retrieve = described_class.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}}
260
- end
261
-
262
- it "should include mounted resources" do
245
+ it "should include unmounted resources" do
263
246
  expect(@retrieve).to include(:name => '/', :ensure => :mounted)
264
247
  end
265
248
 
266
- it "should include unmounted resources" do
267
- @retrieve = described_class.instances.collect { |prov| {:name => prov.get(:name), :ensure => prov.get(:ensure)}}
249
+ it "should include mounted resources" do
268
250
  expect(@retrieve).to include(:name => '/boot', :ensure => :unmounted)
269
251
  end
270
252