~ubuntu-branches/ubuntu/trusty/puppet/trusty

« back to all changes in this revision

Viewing changes to .pc/2.7.18-CVE-Rollup.patch/lib/puppet/indirector/file_bucket_file/file.rb

  • Committer: Package Import Robot
  • Author(s): Robie Basak
  • Date: 2013-04-08 15:03:25 UTC
  • mfrom: (3.1.46 sid)
  • Revision ID: package-import@ubuntu.com-20130408150325-4o91hljzz2zca5fi
Tags: 2.7.18-4ubuntu1
* Merge from Debian unstable. This merges the vim addon fix in 2.7.18-2
  (LP: #1163927). Remaining changes:
  - debian/puppetmaster-passenger.postinst: Make sure we error if puppet
    config print doesn't work
  - debian/puppetmaster-passenger.postinst: Ensure upgrades from
    <= 2.7.11-1 fixup passenger apache configuration.
  - Drop Build-Depends on ruby-rspec (in universe):
    + debian/control: remove ruby-rspec from Build-Depends
    + debian/patches/no-rspec.patch: make Rakefile work anyway if rspec
      isn't installed so we can use it in debian/rules.
* Drop upstreamed patches:
  - debian/patches/security-mar-2013.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
require 'puppet/indirector/code'
 
2
require 'puppet/file_bucket/file'
 
3
require 'puppet/util/checksums'
 
4
require 'fileutils'
 
5
 
 
6
module Puppet::FileBucketFile
 
7
  class File < Puppet::Indirector::Code
 
8
    include Puppet::Util::Checksums
 
9
 
 
10
    desc "Store files in a directory set based on their checksums."
 
11
 
 
12
    def initialize
 
13
      Puppet.settings.use(:filebucket)
 
14
    end
 
15
 
 
16
    def find( request )
 
17
      checksum, files_original_path = request_to_checksum_and_path( request )
 
18
      dir_path = path_for(request.options[:bucket_path], checksum)
 
19
      file_path = ::File.join(dir_path, 'contents')
 
20
 
 
21
      return nil unless ::File.exists?(file_path)
 
22
      return nil unless path_match(dir_path, files_original_path)
 
23
 
 
24
      if request.options[:diff_with]
 
25
        hash_protocol = sumtype(checksum)
 
26
        file2_path = path_for(request.options[:bucket_path], request.options[:diff_with], 'contents')
 
27
        raise "could not find diff_with #{request.options[:diff_with]}" unless ::File.exists?(file2_path)
 
28
        return `diff #{file_path.inspect} #{file2_path.inspect}`
 
29
      else
 
30
        contents = IO.binread(file_path)
 
31
        Puppet.info "FileBucket read #{checksum}"
 
32
        model.new(contents)
 
33
      end
 
34
    end
 
35
 
 
36
    def head(request)
 
37
      checksum, files_original_path = request_to_checksum_and_path(request)
 
38
      dir_path = path_for(request.options[:bucket_path], checksum)
 
39
 
 
40
      ::File.exists?(::File.join(dir_path, 'contents')) and path_match(dir_path, files_original_path)
 
41
    end
 
42
 
 
43
    def save( request )
 
44
      instance = request.instance
 
45
      checksum, files_original_path = request_to_checksum_and_path(request)
 
46
 
 
47
      save_to_disk(instance, files_original_path)
 
48
      instance.to_s
 
49
    end
 
50
 
 
51
    private
 
52
 
 
53
    def path_match(dir_path, files_original_path)
 
54
      return true unless files_original_path # if no path was provided, it's a match
 
55
      paths_path = ::File.join(dir_path, 'paths')
 
56
      return false unless ::File.exists?(paths_path)
 
57
      ::File.open(paths_path) do |f|
 
58
        f.each_line do |line|
 
59
          return true if line.chomp == files_original_path
 
60
        end
 
61
      end
 
62
      return false
 
63
    end
 
64
 
 
65
    def save_to_disk( bucket_file, files_original_path )
 
66
      filename = path_for(bucket_file.bucket_path, bucket_file.checksum_data, 'contents')
 
67
      dir_path = path_for(bucket_file.bucket_path, bucket_file.checksum_data)
 
68
      paths_path = ::File.join(dir_path, 'paths')
 
69
 
 
70
      # If the file already exists, do nothing.
 
71
      if ::File.exist?(filename)
 
72
        verify_identical_file!(bucket_file)
 
73
      else
 
74
        # Make the directories if necessary.
 
75
        unless ::File.directory?(dir_path)
 
76
          Puppet::Util.withumask(0007) do
 
77
            ::FileUtils.mkdir_p(dir_path)
 
78
          end
 
79
        end
 
80
 
 
81
        Puppet.info "FileBucket adding #{bucket_file.checksum}"
 
82
 
 
83
        # Write the file to disk.
 
84
        Puppet::Util.withumask(0007) do
 
85
          ::File.open(filename, ::File::WRONLY|::File::CREAT, 0440) do |of|
 
86
            of.binmode
 
87
            of.print bucket_file.contents
 
88
          end
 
89
          ::File.open(paths_path, ::File::WRONLY|::File::CREAT, 0640) do |of|
 
90
            # path will be written below
 
91
          end
 
92
        end
 
93
      end
 
94
 
 
95
      unless path_match(dir_path, files_original_path)
 
96
        ::File.open(paths_path, 'a') do |f|
 
97
          f.puts(files_original_path)
 
98
        end
 
99
      end
 
100
    end
 
101
 
 
102
    def request_to_checksum_and_path( request )
 
103
      checksum_type, checksum, path = request.key.split(/\//, 3)
 
104
      if path == '' # Treat "md5/<checksum>/" like "md5/<checksum>"
 
105
        path = nil
 
106
      end
 
107
      raise "Unsupported checksum type #{checksum_type.inspect}" if checksum_type != 'md5'
 
108
      raise "Invalid checksum #{checksum.inspect}" if checksum !~ /^[0-9a-f]{32}$/
 
109
      [checksum, path]
 
110
    end
 
111
 
 
112
    def path_for(bucket_path, digest, subfile = nil)
 
113
      bucket_path ||= Puppet[:bucketdir]
 
114
 
 
115
      dir     = ::File.join(digest[0..7].split(""))
 
116
      basedir = ::File.join(bucket_path, dir, digest)
 
117
 
 
118
      return basedir unless subfile
 
119
      ::File.join(basedir, subfile)
 
120
    end
 
121
 
 
122
    # If conflict_check is enabled, verify that the passed text is
 
123
    # the same as the text in our file.
 
124
    def verify_identical_file!(bucket_file)
 
125
      disk_contents = IO.binread(path_for(bucket_file.bucket_path, bucket_file.checksum_data, 'contents'))
 
126
 
 
127
      # If the contents don't match, then we've found a conflict.
 
128
      # Unlikely, but quite bad.
 
129
      if disk_contents != bucket_file.contents
 
130
        raise Puppet::FileBucket::BucketError, "Got passed new contents for sum #{bucket_file.checksum}"
 
131
      else
 
132
        Puppet.info "FileBucket got a duplicate file #{bucket_file.checksum}"
 
133
      end
 
134
    end
 
135
  end
 
136
end