Module: Puppet::Util::Checksums

Included in:
DataSync, FileBucket::Dipper, FileBucketFile::File, FileServing::Metadata, Resource::Catalog::Compiler
Defined in:
lib/puppet/util/checksums.rb

Overview

A stand-alone module for calculating checksums in a generic way.

Defined Under Namespace

Classes: DigestLite, FakeChecksum

Constant Summary collapse

KNOWN_CHECKSUMS =

If you modify this, update puppet/type/file/checksum.rb too

[
  :sha256, :sha256lite,
  :md5, :md5lite,
  :sha1, :sha1lite,
  :sha512,
  :sha384,
  :sha224,
  :mtime, :ctime, :none,
  :etag
].freeze

Class Method Summary collapse

Class Method Details

.checksum?(string) ⇒ Boolean

Is the provided string a checksum?

Returns:

  • (Boolean)


43
44
45
46
# File 'lib/puppet/util/checksums.rb', line 43

def checksum?(string)
  # 'sha256lite'.length == 10
  string =~ /^\{(\w{3,10})\}\S+/
end

.checksum_file(digest, filename, lite = false) ⇒ Object

Perform an incremental checksum on a file.



384
385
386
387
388
389
390
391
392
393
394
# File 'lib/puppet/util/checksums.rb', line 384

def checksum_file(digest, filename, lite = false)
  buffer = lite ? 512 : 4096
  File.open(filename, 'rb') do |file|
    while content = file.read(buffer) # rubocop:disable Lint/AssignmentInCondition
      digest << content
      break if lite
    end
  end

  digest.hexdigest
end

.checksum_stream(digest, block, lite = false) ⇒ Object



396
397
398
399
# File 'lib/puppet/util/checksums.rb', line 396

def checksum_stream(digest, block, lite = false)
  block.call(DigestLite.new(digest, lite))
  digest.hexdigest
end

.ctime(content) ⇒ Object



303
304
305
# File 'lib/puppet/util/checksums.rb', line 303

def ctime(content)
  ""
end

.ctime?(string) ⇒ Boolean

Returns:

  • (Boolean)


307
308
309
310
311
312
313
# File 'lib/puppet/util/checksums.rb', line 307

def ctime?(string)
  return true if string.is_a? Time

  !!DateTime.parse(string)
rescue
  false
end

.ctime_file(filename) ⇒ Object

Return the :ctime of a file.



316
317
318
# File 'lib/puppet/util/checksums.rb', line 316

def ctime_file(filename)
  Puppet::FileSystem.stat(filename).ctime
end

.ctime_stream(&block) ⇒ Object



320
321
322
# File 'lib/puppet/util/checksums.rb', line 320

def ctime_stream(&block)
  mtime_stream(&block)
end

.etag(content) ⇒ Object

ETag-based checksum delegates to md5 for local file computation. The actual algorithm is determined at runtime by HttpMetadata#collect based on the ETag header length.



346
347
348
# File 'lib/puppet/util/checksums.rb', line 346

def etag(content)
  md5(content)
end

.etag?(string) ⇒ Boolean

Returns:

  • (Boolean)


350
351
352
# File 'lib/puppet/util/checksums.rb', line 350

def etag?(string)
  string =~ /^\h{32,64}$/
end

.etag_file(filename, lite = false) ⇒ Object



354
355
356
# File 'lib/puppet/util/checksums.rb', line 354

def etag_file(filename, lite = false)
  md5_file(filename, lite)
end

.etag_stream(lite = false, &block) ⇒ Object



358
359
360
# File 'lib/puppet/util/checksums.rb', line 358

def etag_stream(lite = false, &block)
  md5_stream(lite, &block)
end

.known_checksum_typesObject

It’s not a good idea to use some of these in some contexts: for example, I wouldn’t try bucketing a file using the :none checksum type.



26
27
28
# File 'lib/puppet/util/checksums.rb', line 26

def known_checksum_types
  KNOWN_CHECKSUMS
end

.md5(content) ⇒ Object

Calculate a checksum using Digest::MD5.



187
188
189
# File 'lib/puppet/util/checksums.rb', line 187

def md5(content)
  Digest::MD5.hexdigest(content)
end

.md5?(string) ⇒ Boolean

Returns:

  • (Boolean)


191
192
193
# File 'lib/puppet/util/checksums.rb', line 191

def md5?(string)
  string =~ /^\h{32}$/
end

.md5_file(filename, lite = false) ⇒ Object

Calculate a checksum of a file’s content using Digest::MD5.



196
197
198
199
# File 'lib/puppet/util/checksums.rb', line 196

def md5_file(filename, lite = false)
  digest = Digest::MD5.new
  checksum_file(digest, filename, lite)
end

.md5_hex_lengthObject



206
207
208
# File 'lib/puppet/util/checksums.rb', line 206

def md5_hex_length
  32
end

.md5_stream(lite = false, &block) ⇒ Object



201
202
203
204
# File 'lib/puppet/util/checksums.rb', line 201

def md5_stream(lite = false, &block)
  digest = Digest::MD5.new
  checksum_stream(digest, block, lite)
end

.md5lite(content) ⇒ Object

Calculate a checksum of the first 500 chars of the content using Digest::MD5.



211
212
213
# File 'lib/puppet/util/checksums.rb', line 211

def md5lite(content)
  md5(content[0..511])
end

.md5lite?(string) ⇒ Boolean

Returns:

  • (Boolean)


215
216
217
# File 'lib/puppet/util/checksums.rb', line 215

def md5lite?(string)
  md5?(string)
end

.md5lite_file(filename) ⇒ Object

Calculate a checksum of the first 500 chars of a file’s content using Digest::MD5.



220
221
222
# File 'lib/puppet/util/checksums.rb', line 220

def md5lite_file(filename)
  md5_file(filename, true)
end

.md5lite_hex_lengthObject



228
229
230
# File 'lib/puppet/util/checksums.rb', line 228

def md5lite_hex_length
  md5_hex_length
end

.md5lite_stream(&block) ⇒ Object



224
225
226
# File 'lib/puppet/util/checksums.rb', line 224

def md5lite_stream(&block)
  md5_stream(true, &block)
end

.mtime(content) ⇒ Object



232
233
234
# File 'lib/puppet/util/checksums.rb', line 232

def mtime(content)
  ""
end

.mtime?(string) ⇒ Boolean

Returns:

  • (Boolean)


236
237
238
239
240
241
242
# File 'lib/puppet/util/checksums.rb', line 236

def mtime?(string)
  return true if string.is_a? Time

  !!DateTime.parse(string)
rescue
  false
end

.mtime_file(filename) ⇒ Object

Return the :mtime timestamp of a file.



245
246
247
# File 'lib/puppet/util/checksums.rb', line 245

def mtime_file(filename)
  Puppet::FileSystem.stat(filename).mtime
end

.mtime_stream {|noop_digest| ... } ⇒ Object

by definition this doesn’t exist but we still need to execute the block given

Yields:

  • (noop_digest)


251
252
253
254
255
# File 'lib/puppet/util/checksums.rb', line 251

def mtime_stream(&block)
  noop_digest = FakeChecksum.new
  yield noop_digest
  nil
end

.none(content) ⇒ Object



324
325
326
# File 'lib/puppet/util/checksums.rb', line 324

def none(content)
  ""
end

.none?(string) ⇒ Boolean

Returns:

  • (Boolean)


328
329
330
# File 'lib/puppet/util/checksums.rb', line 328

def none?(string)
  string.empty?
end

.none_file(filename) ⇒ Object

Return a “no checksum”



333
334
335
# File 'lib/puppet/util/checksums.rb', line 333

def none_file(filename)
  ""
end

.none_stream {|noop_digest| ... } ⇒ Object

Yields:

  • (noop_digest)


337
338
339
340
341
# File 'lib/puppet/util/checksums.rb', line 337

def none_stream
  noop_digest = FakeChecksum.new
  yield noop_digest
  ""
end

.sha1(content) ⇒ Object

Calculate a checksum using Digest::SHA1.



258
259
260
# File 'lib/puppet/util/checksums.rb', line 258

def sha1(content)
  Digest::SHA1.hexdigest(content)
end

.sha1?(string) ⇒ Boolean

Returns:

  • (Boolean)


262
263
264
# File 'lib/puppet/util/checksums.rb', line 262

def sha1?(string)
  string =~ /^\h{40}$/
end

.sha1_file(filename, lite = false) ⇒ Object

Calculate a checksum of a file’s content using Digest::SHA1.



267
268
269
270
# File 'lib/puppet/util/checksums.rb', line 267

def sha1_file(filename, lite = false)
  digest = Digest::SHA1.new
  checksum_file(digest, filename, lite)
end

.sha1_hex_lengthObject



277
278
279
# File 'lib/puppet/util/checksums.rb', line 277

def sha1_hex_length
  40
end

.sha1_stream(lite = false, &block) ⇒ Object



272
273
274
275
# File 'lib/puppet/util/checksums.rb', line 272

def sha1_stream(lite = false, &block)
  digest = Digest::SHA1.new
  checksum_stream(digest, block, lite)
end

.sha1lite(content) ⇒ Object

Calculate a checksum of the first 500 chars of the content using Digest::SHA1.



282
283
284
# File 'lib/puppet/util/checksums.rb', line 282

def sha1lite(content)
  sha1(content[0..511])
end

.sha1lite?(string) ⇒ Boolean

Returns:

  • (Boolean)


286
287
288
# File 'lib/puppet/util/checksums.rb', line 286

def sha1lite?(string)
  sha1?(string)
end

.sha1lite_file(filename) ⇒ Object

Calculate a checksum of the first 500 chars of a file’s content using Digest::SHA1.



291
292
293
# File 'lib/puppet/util/checksums.rb', line 291

def sha1lite_file(filename)
  sha1_file(filename, true)
end

.sha1lite_hex_lengthObject



299
300
301
# File 'lib/puppet/util/checksums.rb', line 299

def sha1lite_hex_length
  sha1_hex_length
end

.sha1lite_stream(&block) ⇒ Object



295
296
297
# File 'lib/puppet/util/checksums.rb', line 295

def sha1lite_stream(&block)
  sha1_stream(true, &block)
end

.sha224(content) ⇒ Object

Calculate a checksum using Digest::SHA224.



160
161
162
163
# File 'lib/puppet/util/checksums.rb', line 160

def sha224(content)
  require_relative '../../puppet/ssl/openssl_loader'
  OpenSSL::Digest.new('SHA224').hexdigest(content)
end

.sha224?(string) ⇒ Boolean

Returns:

  • (Boolean)


165
166
167
# File 'lib/puppet/util/checksums.rb', line 165

def sha224?(string)
  string =~ /^\h{56}$/
end

.sha224_file(filename, lite = false) ⇒ Object



169
170
171
172
173
174
# File 'lib/puppet/util/checksums.rb', line 169

def sha224_file(filename, lite = false)
  require_relative '../../puppet/ssl/openssl_loader'

  digest = OpenSSL::Digest.new('SHA224')
  checksum_file(digest, filename, lite)
end

.sha224_hex_lengthObject



182
183
184
# File 'lib/puppet/util/checksums.rb', line 182

def sha224_hex_length
  56
end

.sha224_stream(lite = false, &block) ⇒ Object



176
177
178
179
180
# File 'lib/puppet/util/checksums.rb', line 176

def sha224_stream(lite = false, &block)
  require_relative '../../puppet/ssl/openssl_loader'
  digest = OpenSSL::Digest.new('SHA224')
  checksum_stream(digest, block, lite)
end

.sha256(content) ⇒ Object

Calculate a checksum using Digest::SHA256.



59
60
61
62
# File 'lib/puppet/util/checksums.rb', line 59

def sha256(content)
  require 'digest/sha2'
  Digest::SHA256.hexdigest(content)
end

.sha256?(string) ⇒ Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/puppet/util/checksums.rb', line 64

def sha256?(string)
  string =~ /^\h{64}$/
end

.sha256_file(filename, lite = false) ⇒ Object



68
69
70
71
72
73
# File 'lib/puppet/util/checksums.rb', line 68

def sha256_file(filename, lite = false)
  require 'digest/sha2'

  digest = Digest::SHA256.new
  checksum_file(digest, filename, lite)
end

.sha256_hex_lengthObject



81
82
83
# File 'lib/puppet/util/checksums.rb', line 81

def sha256_hex_length
  64
end

.sha256_stream(lite = false, &block) ⇒ Object



75
76
77
78
79
# File 'lib/puppet/util/checksums.rb', line 75

def sha256_stream(lite = false, &block)
  require 'digest/sha2'
  digest = Digest::SHA256.new
  checksum_stream(digest, block, lite)
end

.sha256lite(content) ⇒ Object



85
86
87
# File 'lib/puppet/util/checksums.rb', line 85

def sha256lite(content)
  sha256(content[0..511])
end

.sha256lite?(string) ⇒ Boolean

Returns:

  • (Boolean)


89
90
91
# File 'lib/puppet/util/checksums.rb', line 89

def sha256lite?(string)
  sha256?(string)
end

.sha256lite_file(filename) ⇒ Object



93
94
95
# File 'lib/puppet/util/checksums.rb', line 93

def sha256lite_file(filename)
  sha256_file(filename, true)
end

.sha256lite_hex_lengthObject



101
102
103
# File 'lib/puppet/util/checksums.rb', line 101

def sha256lite_hex_length
  sha256_hex_length
end

.sha256lite_stream(&block) ⇒ Object



97
98
99
# File 'lib/puppet/util/checksums.rb', line 97

def sha256lite_stream(&block)
  sha256_stream(true, &block)
end

.sha384(content) ⇒ Object

Calculate a checksum using Digest::SHA384.



106
107
108
109
# File 'lib/puppet/util/checksums.rb', line 106

def sha384(content)
  require 'digest/sha2'
  Digest::SHA384.hexdigest(content)
end

.sha384?(string) ⇒ Boolean

Returns:

  • (Boolean)


111
112
113
# File 'lib/puppet/util/checksums.rb', line 111

def sha384?(string)
  string =~ /^\h{96}$/
end

.sha384_file(filename, lite = false) ⇒ Object



115
116
117
118
119
120
# File 'lib/puppet/util/checksums.rb', line 115

def sha384_file(filename, lite = false)
  require 'digest/sha2'

  digest = Digest::SHA384.new
  checksum_file(digest, filename, lite)
end

.sha384_hex_lengthObject



128
129
130
# File 'lib/puppet/util/checksums.rb', line 128

def sha384_hex_length
  96
end

.sha384_stream(lite = false, &block) ⇒ Object



122
123
124
125
126
# File 'lib/puppet/util/checksums.rb', line 122

def sha384_stream(lite = false, &block)
  require 'digest/sha2'
  digest = Digest::SHA384.new
  checksum_stream(digest, block, lite)
end

.sha512(content) ⇒ Object

Calculate a checksum using Digest::SHA512.



133
134
135
136
# File 'lib/puppet/util/checksums.rb', line 133

def sha512(content)
  require 'digest/sha2'
  Digest::SHA512.hexdigest(content)
end

.sha512?(string) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/puppet/util/checksums.rb', line 138

def sha512?(string)
  string =~ /^\h{128}$/
end

.sha512_file(filename, lite = false) ⇒ Object



142
143
144
145
146
147
# File 'lib/puppet/util/checksums.rb', line 142

def sha512_file(filename, lite = false)
  require 'digest/sha2'

  digest = Digest::SHA512.new
  checksum_file(digest, filename, lite)
end

.sha512_hex_lengthObject



155
156
157
# File 'lib/puppet/util/checksums.rb', line 155

def sha512_hex_length
  128
end

.sha512_stream(lite = false, &block) ⇒ Object



149
150
151
152
153
# File 'lib/puppet/util/checksums.rb', line 149

def sha512_stream(lite = false, &block)
  require 'digest/sha2'
  digest = Digest::SHA512.new
  checksum_stream(digest, block, lite)
end

.sumdata(checksum) ⇒ Object

Strip the checksum type from an existing checksum



49
50
51
# File 'lib/puppet/util/checksums.rb', line 49

def sumdata(checksum)
  checksum =~ /^\{(\w+)\}(.+)/ ? ::Regexp.last_match(2) : nil
end

.sumtype(checksum) ⇒ Object

Strip the checksum type from an existing checksum



54
55
56
# File 'lib/puppet/util/checksums.rb', line 54

def sumtype(checksum)
  checksum =~ /^\{(\w+)\}/ ? ::Regexp.last_match(1) : nil
end

.valid_checksum?(type, value) ⇒ Boolean

Returns:

  • (Boolean)


30
31
32
33
34
# File 'lib/puppet/util/checksums.rb', line 30

def valid_checksum?(type, value)
  !!send("#{type}?", value)
rescue NoMethodError
  false
end