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 +4 -4
- data/lib/puppet/file_system/file.rb +10 -0
- data/lib/puppet/type/file.rb +12 -23
- data/lib/puppet/util.rb +33 -49
- data/lib/puppet/util/windows/access_control_list.rb +7 -0
- data/lib/puppet/version.rb +1 -1
- data/spec/integration/type/file_spec.rb +0 -14
- data/spec/integration/util_spec.rb +47 -0
- data/spec/unit/type/file_spec.rb +0 -29
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 68668528e38b1e5f1736b47b3afcb517372ced94
|
4
|
+
data.tar.gz: ff046f6e2a601f59700bbbadf2589be1e6917dcd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
data/lib/puppet/type/file.rb
CHANGED
@@ -713,36 +713,25 @@ Puppet::Type.newtype(:file) do
|
|
713
713
|
def write(property)
|
714
714
|
remove_existing(:file)
|
715
715
|
|
716
|
-
|
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
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
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
|
data/lib/puppet/util.rb
CHANGED
@@ -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
|
-
|
382
|
-
|
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 =
|
387
|
-
tempfile = Tempfile.new(file.basename
|
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
|
-
|
400
|
+
if !Puppet.features.microsoft_windows?
|
398
401
|
# Grab the current file mode, and fall back to the defaults.
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
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
|
-
#
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
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
|
|
data/lib/puppet/version.rb
CHANGED
@@ -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
|
data/spec/unit/type/file_spec.rb
CHANGED
@@ -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.
|
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-
|
11
|
+
date: 2013-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: facter
|