class PoiseArchive::ArchiveProviders::Tar
The `tar` provider class for `poise_archive` to install from tar archives.
@see PoiseArchive::Resources::PoiseArchive::Resource
@provides poise_archive
Constants
- TAR_LONGLINK
Hack that GNU tar uses for paths over 100 bytes.
@api private @see
unpack_tar
Private Instance Methods
chown_entries()
click to toggle source
# File lib/poise_archive/archive_providers/tar.rb, line 144 def chown_entries paths = @tar_entry_paths notifying_block do paths.each do |type, path| send(type, path) do group new_resource.group owner new_resource.user end end end end
close_file!()
click to toggle source
Close all the various file handles.
@return [void]
# File lib/poise_archive/archive_providers/tar.rb, line 129 def close_file! if @tar_reader @tar_reader.close @tar_reader = nil end if @file @file.close @file = nil end if @raw_file @raw_file.close unless @raw_file.closed? @raw_file = nil end end
open_file!()
click to toggle source
Open a file handle of the correct flavor.
@return [void]
# File lib/poise_archive/archive_providers/tar.rb, line 110 def open_file! @raw_file = ::File.open(new_resource.absolute_path, 'rb') @file = case new_resource.absolute_path when /\.tar$/ nil # So it uses @raw_file instead. when /\.t?gz/ Zlib::GzipReader.wrap(@raw_file) when /\.t?bz/ # This can't take a block, hence the gross non-block forms for everything. PoiseArchive::Bzip2::Decompressor.new(@raw_file) else raise RuntimeError.new("Unknown or unsupported file extension for #{new_resource.path}") end @tar_reader = Gem::Package::TarReader.new(@file || @raw_file) end
tar_each(&block)
click to toggle source
Sequence the opening, iteration, and closing.
@param block [Proc] Block to process each tar entry. @return [void]
# File lib/poise_archive/archive_providers/tar.rb, line 98 def tar_each(&block) # In case of extreme weirdness where this happens twice. close_file! open_file! @tar_reader.each(&block) ensure close_file! end
tar_each_with_longlink(&block)
click to toggle source
# File lib/poise_archive/archive_providers/tar.rb, line 75 def tar_each_with_longlink(&block) entry_name = nil tar_each do |entry| if entry.full_name == TAR_LONGLINK # Stash the longlink name so it will be used for the next entry. entry_name = entry.read.strip # And then skip forward because this isn't a real block. next end # For entries not preceded by a longlink block, use the normal name. entry_name ||= entry.full_name # Make the entry return the correct name. entry.define_singleton_method(:full_name) { entry_name } block.call(entry) # Reset entry_name for the next entry. entry_name = nil end end
unpack_archive()
click to toggle source
# File lib/poise_archive/archive_providers/tar.rb, line 41 def unpack_archive unpack_tar chown_entries if new_resource.user || new_resource.group end
unpack_tar()
click to toggle source
Unpack the archive.
@return [void]
# File lib/poise_archive/archive_providers/tar.rb, line 49 def unpack_tar @tar_entry_paths = [] tar_each_with_longlink do |entry| entry_name = entry.full_name.split(/\//).drop(new_resource.strip_components).join('/') # If strip_components wiped out the name, don't process this entry. next if entry_name.empty? dest = ::File.join(new_resource.destination, entry_name) if entry.directory? Dir.mkdir(dest, entry.header.mode) @tar_entry_paths << [:directory, dest] elsif entry.file? ::File.open(dest, 'wb', entry.header.mode) do |dest_f| while buf = entry.read(4096) dest_f.write(buf) end end @tar_entry_paths << [:file, dest] elsif entry.header.typeflag == '2' # symlink? is new in Ruby 2.0, apparently. ::File.symlink(entry.header.linkname, dest) @tar_entry_paths << [:link, dest] else raise RuntimeError.new("Unknown tar entry type #{entry.header.typeflag.inspect} in #{new_resource.path}") end end end