puppet 3.4.0 → 3.4.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.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e1040b62e492bc1305e35895aa28cc1f19f5469f
4
- data.tar.gz: ad790a27fffea01c15e15a165d4c73dc93c39c0e
3
+ metadata.gz: 68668528e38b1e5f1736b47b3afcb517372ced94
4
+ data.tar.gz: ff046f6e2a601f59700bbbadf2589be1e6917dcd
5
5
  SHA512:
6
- metadata.gz: 59cecec6476f5427db8e80433d396e2bc4d741f2fdcce76d2c7644b28ce28b9251354441a7941e42d6ea864416286a0c806ff60855a1f7b357b031805cfb8686
7
- data.tar.gz: f57784909b7b81471460e526e61ecc1a9eb18e7370e6b648390239227726d50ad1c6ff66cbe4139fb887769c938b0587cf72c490ba8d49799372e75e77367705
6
+ metadata.gz: 55b1ffdca0b53888d129366a1932874bc5749dbcc429512c75ed647d42e8312bc5a947b817bed4f26db182e972f0d8cf19d578ff7fc5c368936cc163a2226507
7
+ data.tar.gz: c38f970a8be8e4c65d9d1015eae0e5a605bf5d2ed6fbeb07cfd206185b73b282c96836051d96d0115319828f0e76df2fb7a26f946efc9f45b72e3443c2bcb04b
@@ -78,6 +78,12 @@ class Puppet::FileSystem::File
78
78
  Puppet::FileSystem::File.new(@path.dirname)
79
79
  end
80
80
 
81
+ # @return [String] the name of the file
82
+ # @api public
83
+ def basename
84
+ @path.basename.to_s
85
+ end
86
+
81
87
  # @return [Num] The size of this file
82
88
  # @api public
83
89
  def size
@@ -258,4 +264,8 @@ class Puppet::FileSystem::File
258
264
  FileUtils.compare_stream(this, stream)
259
265
  end
260
266
  end
267
+
268
+ def to_s
269
+ @path.to_s
270
+ end
261
271
  end
@@ -713,36 +713,25 @@ Puppet::Type.newtype(:file) do
713
713
  def write(property)
714
714
  remove_existing(:file)
715
715
 
716
- use_temporary_file = write_temporary_file?
717
- if use_temporary_file
718
- path = "#{self[:path]}.puppettmp_#{rand(10000)}"
719
- path = "#{self[:path]}.puppettmp_#{rand(10000)}" while Puppet::FileSystem::File.exist?(path) or Puppet::FileSystem::File.new(path).symlink?
720
- else
721
- path = self[:path]
722
- end
716
+ assumed_default_mode = 0644
723
717
 
724
718
  mode = self.should(:mode) # might be nil
725
- umask = mode ? 000 : 022
726
- mode_int = mode ? symbolic_mode_to_int(mode, 0644) : nil
727
-
728
- content_checksum = Puppet::Util.withumask(umask) { ::File.open(path, 'wb', mode_int ) { |f| write_content(f) } }
729
-
730
- # And put our new file in place
731
- if use_temporary_file # This is only not true when our file is empty.
732
- begin
733
- fail_if_checksum_is_wrong(path, content_checksum) if validate_checksum?
734
- ::File.rename(path, self[:path])
735
- rescue => detail
736
- fail "Could not rename temporary file #{path} to #{self[:path]}: #{detail}"
737
- ensure
738
- # Make sure the created file gets removed
739
- Puppet::FileSystem::File.unlink(path) if Puppet::FileSystem::File.exist?(path)
719
+ mode_int = mode ? symbolic_mode_to_int(mode, assumed_default_mode) : nil
720
+
721
+ if write_temporary_file?
722
+ Puppet::Util.replace_file(self[:path], mode_int) do |file|
723
+ file.binmode
724
+ content_checksum = write_content(file)
725
+ file.flush
726
+ fail_if_checksum_is_wrong(file.path, content_checksum) if validate_checksum?
740
727
  end
728
+ else
729
+ umask = mode ? 000 : 022
730
+ Puppet::Util.withumask(umask) { ::File.open(self[:path], 'wb', mode_int ) { |f| write_content(f) } }
741
731
  end
742
732
 
743
733
  # make sure all of the modes are actually correct
744
734
  property_fix
745
-
746
735
  end
747
736
 
748
737
  private
@@ -378,13 +378,16 @@ module Util
378
378
  def replace_file(file, default_mode, &block)
379
379
  raise Puppet::DevError, "replace_file requires a block" unless block_given?
380
380
 
381
- unless valid_symbolic_mode?(default_mode)
382
- raise Puppet::DevError, "replace_file default_mode: #{default_mode} is invalid"
381
+ if default_mode
382
+ unless valid_symbolic_mode?(default_mode)
383
+ raise Puppet::DevError, "replace_file default_mode: #{default_mode} is invalid"
384
+ end
385
+
386
+ mode = symbolic_mode_to_int(normalize_symbolic_mode(default_mode))
383
387
  end
384
- mode = symbolic_mode_to_int(normalize_symbolic_mode(default_mode))
385
388
 
386
- file = Pathname(file)
387
- tempfile = Tempfile.new(file.basename.to_s, file.dirname.to_s)
389
+ file = Puppet::FileSystem::File.new(file)
390
+ tempfile = Tempfile.new(file.basename, file.dir.to_s)
388
391
 
389
392
  # Set properties of the temporary file before we write the content, because
390
393
  # Tempfile doesn't promise to be safe from reading by other people, just
@@ -394,16 +397,21 @@ module Util
394
397
  # and specifically handle the platform, which has all sorts of magic.
395
398
  # So, unlike Unix, we don't pre-prep security; we use the default "quite
396
399
  # secure" tempfile permissions instead. Magic happens later.
397
- unless Puppet.features.microsoft_windows?
400
+ if !Puppet.features.microsoft_windows?
398
401
  # Grab the current file mode, and fall back to the defaults.
399
- stat = file.lstat rescue OpenStruct.new(:mode => mode,
400
- :uid => Process.euid,
401
- :gid => Process.egid)
402
-
403
- # We only care about the bottom four slots, which make the real mode,
404
- # and not the rest of the platform stat call fluff and stuff.
405
- tempfile.chmod(stat.mode & 07777)
406
- tempfile.chown(stat.uid, stat.gid)
402
+ if file.exist?
403
+ stat = file.path.lstat
404
+ tempfile.chown(stat.uid, stat.gid)
405
+ effective_mode = stat.mode
406
+ else
407
+ effective_mode = mode
408
+ end
409
+
410
+ if effective_mode
411
+ # We only care about the bottom four slots, which make the real mode,
412
+ # and not the rest of the platform stat call fluff and stuff.
413
+ tempfile.chmod(effective_mode & 07777)
414
+ end
407
415
  end
408
416
 
409
417
  # OK, now allow the caller to write the content of the file.
@@ -426,50 +434,26 @@ module Util
426
434
  tempfile.close
427
435
 
428
436
  if Puppet.features.microsoft_windows?
429
- # This will appropriately clone the file, but only if the file we are
430
- # replacing exists. Which is kind of annoying; thanks Microsoft.
431
- #
432
- # So, to avoid getting into an infinite loop we will retry once if the
433
- # file doesn't exist, but only the once...
434
- have_retried = false
435
-
436
- begin
437
- # Yes, the arguments are reversed compared to the rename in the rest
438
- # of the world.
439
- Puppet::Util::Windows::File.replace_file(file, tempfile.path)
440
- rescue Puppet::Util::Windows::Error
441
- # This might race, but there are enough possible cases that there
442
- # isn't a good, solid "better" way to do this, and the next call
443
- # should fail in the same way anyhow.
444
- raise if have_retried or Puppet::FileSystem::File.exist?(file)
445
- have_retried = true
446
-
447
- # OK, so, we can't replace a file that doesn't exist, so let us put
448
- # one in place and set the permissions. Then we can retry and the
449
- # magic makes this all work.
450
- #
451
- # This is the least-worst option for handling Windows, as far as we
452
- # can determine.
453
- File.open(file, 'a') do |fh|
454
- # this space deliberately left empty for auto-close behaviour,
455
- # append mode, and not actually changing any of the content.
437
+ # Windows ReplaceFile needs a file to exist, so touch handles this
438
+ if !file.exist?
439
+ file.touch
440
+ if mode
441
+ Puppet::Util::Windows::Security.set_mode(mode, file.path.to_s)
456
442
  end
457
-
458
- # Set the permissions to what we want.
459
- Puppet::Util::Windows::Security.set_mode(mode, file.to_s)
460
-
461
- # ...and finally retry the operation.
462
- retry
463
443
  end
444
+ # Yes, the arguments are reversed compared to the rename in the rest
445
+ # of the world.
446
+ Puppet::Util::Windows::File.replace_file(file.path, tempfile.path)
447
+
464
448
  else
465
- File.rename(tempfile.path, file.to_s)
449
+ File.rename(tempfile.path, file.path.to_s)
466
450
  end
467
451
 
468
452
  # Ideally, we would now fsync the directory as well, but Ruby doesn't
469
453
  # have support for that, and it doesn't matter /that/ much...
470
454
 
471
455
  # Return something true, and possibly useful.
472
- file
456
+ file.path
473
457
  end
474
458
  module_function :replace_file
475
459
 
@@ -103,4 +103,11 @@ class Puppet::Util::Windows::AccessControlList
103
103
  end
104
104
  str
105
105
  end
106
+
107
+ def ==(other)
108
+ self.class == other.class &&
109
+ self.to_a == other.to_a
110
+ end
111
+
112
+ alias eql? ==
106
113
  end
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '3.4.0'
10
+ PUPPETVERSION = '3.4.1'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -506,20 +506,6 @@ describe Puppet::Type.type(:file) do
506
506
  bucket.bucket.getfile(foomd5).should == "fooyay"
507
507
  bucket.bucket.getfile(barmd5).should == "baryay"
508
508
  end
509
-
510
- it "should propagate failures encountered when renaming the temporary file" do
511
- file = described_class.new :path => path, :content => "foo"
512
- file.stubs(:perform_backup).returns(true)
513
-
514
- catalog.add_resource file
515
-
516
- File.open(path, "w") { |f| f.print "bar" }
517
-
518
- File.expects(:rename).raises ArgumentError
519
-
520
- expect { file.write(:content) }.to raise_error(Puppet::Error, /Could not rename temporary file/)
521
- File.read(path).should == "bar"
522
- end
523
509
  end
524
510
 
525
511
  describe "when recursing" do
@@ -3,6 +3,8 @@
3
3
  require 'spec_helper'
4
4
 
5
5
  describe Puppet::Util do
6
+ include PuppetSpec::Files
7
+
6
8
  describe "#execute" do
7
9
  it "should properly allow stdout and stderr to share a file" do
8
10
  command = "ruby -e '(1..10).each {|i| (i%2==0) ? $stdout.puts(i) : $stderr.puts(i)}'"
@@ -25,5 +27,50 @@ describe Puppet::Util do
25
27
  expect { Puppet::Util::Execution.execute(command) }.to raise_error(Puppet::ExecutionFailure, /Execution of '#{command}' returned 43: /)
26
28
  $CHILD_STATUS.exitstatus.should == 43
27
29
  end
30
+
31
+ it "replace_file should preserve original ACEs from existing replaced file on Windows",
32
+ :if => Puppet.features.microsoft_windows? do
33
+
34
+ file = tmpfile("somefile")
35
+ FileUtils.touch(file)
36
+
37
+ admins = 'S-1-5-32-544'
38
+ dacl = Puppet::Util::Windows::AccessControlList.new
39
+ dacl.allow(admins, Windows::File::FILE_ALL_ACCESS)
40
+ protect = true
41
+ expected_sd = Puppet::Util::Windows::SecurityDescriptor.new(admins, admins, dacl, protect)
42
+ Puppet::Util::Windows::Security.set_security_descriptor(file, expected_sd)
43
+
44
+ ignored_mode = 0644
45
+ Puppet::Util.replace_file(file, ignored_mode) do |temp_file|
46
+ ignored_sd = Puppet::Util::Windows::Security.get_security_descriptor(temp_file.path)
47
+ users = 'S-1-5-11'
48
+ ignored_sd.dacl.allow(users, Windows::File::FILE_GENERIC_READ)
49
+ Puppet::Util::Windows::Security.set_security_descriptor(temp_file.path, ignored_sd)
50
+ end
51
+
52
+ replaced_sd = Puppet::Util::Windows::Security.get_security_descriptor(file)
53
+
54
+ replaced_sd.dacl.should == expected_sd.dacl
55
+ end
56
+
57
+ it "replace_file should use reasonable default ACEs on a new file on Windows",
58
+ :if => Puppet.features.microsoft_windows? do
59
+
60
+ dir = tmpdir('DACL_playground')
61
+ sibling_path = File.join(dir, 'sibling_file')
62
+ FileUtils.touch(sibling_path)
63
+
64
+ expected_sd = Puppet::Util::Windows::Security.get_security_descriptor(sibling_path)
65
+
66
+ new_file_path = File.join(dir, 'new_file')
67
+
68
+ ignored_mode = nil
69
+ Puppet::Util.replace_file(new_file_path, ignored_mode) { |tmp_file| }
70
+
71
+ new_sd = Puppet::Util::Windows::Security.get_security_descriptor(new_file_path)
72
+
73
+ new_sd.dacl.should == expected_sd.dacl
74
+ end
28
75
  end
29
76
  end
@@ -1066,35 +1066,6 @@ describe Puppet::Type.type(:file) do
1066
1066
  end
1067
1067
 
1068
1068
  describe "#write" do
1069
- it "should propagate failures encountered when renaming the temporary file" do
1070
- File.stubs(:open)
1071
- File.expects(:rename).raises ArgumentError
1072
-
1073
- file[:backup] = 'puppet'
1074
-
1075
- file.stubs(:validate_checksum?).returns(false)
1076
-
1077
- property = stub('content_property', :actual_content => "something", :length => "something".length)
1078
- file.stubs(:property).with(:content).returns(property)
1079
-
1080
- expect { file.write(:content) }.to raise_error(Puppet::Error)
1081
- end
1082
-
1083
- it "should delegate writing to the content property" do
1084
- filehandle = stub_everything 'fh'
1085
- File.stubs(:open).yields(filehandle)
1086
- File.stubs(:rename)
1087
- property = stub('content_property', :actual_content => "something", :length => "something".length)
1088
- file[:backup] = 'puppet'
1089
-
1090
- file.stubs(:validate_checksum?).returns(false)
1091
- file.stubs(:property).with(:content).returns(property)
1092
-
1093
- property.expects(:write).with(filehandle)
1094
-
1095
- file.write(:content)
1096
- end
1097
-
1098
1069
  describe "when validating the checksum" do
1099
1070
  before { file.stubs(:validate_checksum?).returns(true) }
1100
1071
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.4.0
4
+ version: 3.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Puppet Labs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-12-19 00:00:00.000000000 Z
11
+ date: 2013-12-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: facter