class R10K::Tarball
Attributes
@!attribute [rw] checksum
@return [String] The tarball's expected sha256 digest
@!attribute [rw] name
@return [String] The tarball's name
@!attribute [rw] source
@return [String] The tarball's source
Public Class Methods
@param name [String] The name of the tarball content @param source [String] The source for the tarball content @param checksum [String] The sha256 digest of the tarball content
# File lib/r10k/tarball.rb, line 38 def initialize(name, source, checksum: nil) @name = name @source = source @checksum = checksum # At this time, the only checksum type supported is sha256. In the future, # we may decide to support other algorithms if a use case arises. TBD. checksum_algorithm = :SHA256 end
Public Instance Methods
@return [String] The basename of the tarball cache file.
# File lib/r10k/tarball.rb, line 64 def cache_basename if checksum.nil? sanitized_dirname(source) + '.tar.gz' else checksum + '.tar.gz' end end
# File lib/r10k/tarball.rb, line 166 def cache_checksum raise R10K::Error, _("Cache not present at %{path}") % {path: cache_path} unless File.exist?(cache_path) file_digest(cache_path) end
@return [String] Directory. Where the cache_basename file will be created.
# File lib/r10k/tarball.rb, line 49 def cache_dirname File.join(settings[:cache_root], 'tarball') end
The final cache_path should match one of the templates:
- {cachedir}/{checksum}.tar.gz
- {cachedir}/{source}.tar.gz
@return [String] File. The full file path the tarball will be cached to.
# File lib/r10k/tarball.rb, line 59 def cache_path File.join(cache_dirname, cache_basename) end
Checks the cached tarball's digest against the expected checksum. Returns false if no cached file is present. If the tarball has no expected checksum, any cached file is assumed to be valid.
@return [Boolean]
# File lib/r10k/tarball.rb, line 150 def cache_valid? return false unless File.exist?(cache_path) return true if checksum.nil? checksum == file_digest(cache_path) end
Download the tarball from @source to @cache_path
# File lib/r10k/tarball.rb, line 112 def get Tempfile.open(cache_basename) do |tempfile| tempfile.binmode src_uri = URI.parse(source) temp_digest = case src_uri.scheme when 'file', nil copy(src_uri.path, tempfile) when %r{^[a-z]$} # Windows drive letter copy(src_uri.to_s, tempfile) when %r{^https?$} download(src_uri, tempfile) else raise "Unexpected source scheme #{src_uri.scheme}" end # Verify the download unless (checksum == temp_digest) || checksum.nil? raise 'Downloaded file does not match checksum' end # Move the download to cache_path FileUtils::mkdir_p(cache_dirname) begin FileUtils.mv(tempfile.path, cache_path) rescue Errno::EACCES # It may be the case that permissions don't permit moving the file # into place, but do permit overwriting an existing in-place file. FileUtils.cp(tempfile.path, cache_path) end end end
@param target_dir [String] The directory to check if is in sync with the
tarball content
@param ignore_untracked_files [Boolean] If true, consider the target
dir to be in sync as long as all tracked content matches.
@return [Boolean]
# File lib/r10k/tarball.rb, line 91 def insync?(target_dir, ignore_untracked_files: false) target_tree_entries = Find.find(target_dir).map(&:to_s) - [target_dir] each_tarball_entry do |entry| found = target_tree_entries.delete(File.join(target_dir, entry.full_name.chomp('/'))) return false if found.nil? next if entry.directory? return false unless file_digest(found) == reader_digest(entry) end if ignore_untracked_files # We wouldn't have gotten this far if there were discrepancies in # tracked content true else # If there are still files in target_tree_entries, then there is # untracked content present in the target tree. If not, we're in sync. target_tree_entries.empty? end end
List all of the files contained in the tarball and their paths. This is useful for implementing R10K::Purgable
@return [Array] A normalized list of file paths contained in the archive
# File lib/r10k/tarball.rb, line 160 def paths names = Array.new each_tarball_entry { |entry| names << Pathname.new(entry).cleanpath.to_s } names - ['.'] end
Extract the cached tarball to the target directory.
@param target_dir [String] Where to unpack the tarball
# File lib/r10k/tarball.rb, line 75 def unpack(target_dir) file = File.open(cache_path, 'rb') reader = Zlib::GzipReader.new(file) begin Minitar.unpack(reader, target_dir) ensure reader.close end end
Private Instance Methods
# File lib/r10k/tarball.rb, line 173 def each_tarball_entry(&block) File.open(cache_path, 'rb') do |file| Zlib::GzipReader.wrap(file) do |reader| Archive::Tar::Minitar::Input.each_entry(reader) do |entry| yield entry end end end end