class Puppet::ModuleTool::Tar::Mini

Constants

EXECUTABLE
NOT_EXECUTABLE
USER_EXECUTE

Public Instance Methods

pack(sourcedir, destfile) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
33 def pack(sourcedir, destfile)
34   Zlib::GzipWriter.open(destfile) do |writer|
35     Archive::Tar::Minitar.pack(sourcedir, writer) do |step, name, stats|
36       # TODO smcclellan 2017-10-31 Set permissions here when this yield block
37       # executes before the header is written. As it stands, the `stats`
38       # argument isn't mutable in a way that will effect the desired mode for
39       # the file.
40     end
41   end
42 end
unpack(sourcefile, destdir, _) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
 3 def unpack(sourcefile, destdir, _)
 4   Zlib::GzipReader.open(sourcefile) do |reader|
 5     # puppet doesn't have a hard dependency on minitar, so we
 6     # can't be certain which version is installed. If it's 0.9
 7     # or above then we can prevent minitar from fsync'ing each
 8     # extracted file and directory, otherwise fallback to the
 9     # old behavior
10     args = [reader, destdir, find_valid_files(reader)]
11     spec = Gem::Specification.find_by_name('minitar')
12     if spec && spec.version >= Gem::Version.new('0.9')
13       args << {:fsync => false}
14     end
15     Archive::Tar::Minitar.unpack(*args) do |action, name, stats|
16       case action
17       when :dir
18         validate_entry(destdir, name)
19         set_dir_mode!(stats)
20         Puppet.debug("Extracting: #{destdir}/#{name}")
21       when :file_start
22         # Octal string of the old file mode.
23         validate_entry(destdir, name)
24         set_file_mode!(stats)
25         Puppet.debug("Extracting: #{destdir}/#{name}")
26       end
27       set_default_user_and_group!(stats)
28       stats
29     end
30   end
31 end

Private Instance Methods

find_valid_files(tarfile) click to toggle source

Find all the valid files in tarfile.

This check was mainly added to ignore ā€˜x’ and ā€˜g’ flags from the PAX standard but will also ignore any other non-standard tar flags. tar format info: pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa500%2Ftaf.htm pax format info: pic.dhe.ibm.com/infocenter/zos/v1r13/index.jsp?topic=%2Fcom.ibm.zos.r13.bpxa500%2Fpxarchfm.htm

    # File lib/puppet/module_tool/tar/mini.rb
 94 def find_valid_files(tarfile)
 95   Archive::Tar::Minitar.open(tarfile).collect do |entry|
 96     flag = entry.typeflag
 97     if flag.nil? || flag =~ /[[:digit:]]/ && (0..7).cover?(flag.to_i)
 98       entry.full_name
 99     else
100       Puppet.debug "Invalid tar flag '#{flag}' will not be extracted: #{entry.name}"
101       next
102     end
103   end
104 end
sanitized_mode(old_mode) click to toggle source

Sets a file mode to 0755 if the file is executable by the user. Sets a file mode to 0644 if the file mode is set (non-Windows).

   # File lib/puppet/module_tool/tar/mini.rb
64 def sanitized_mode(old_mode)
65   old_mode & USER_EXECUTE != 0 ? EXECUTABLE : NOT_EXECUTABLE
66 end
set_default_user_and_group!(stats) click to toggle source

Sets UID and GID to 0 for standardization.

   # File lib/puppet/module_tool/tar/mini.rb
83 def set_default_user_and_group!(stats)
84   stats[:uid] = 0
85   stats[:gid] = 0
86 end
set_dir_mode!(stats) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
50 def set_dir_mode!(stats)
51   if stats.key?(:mode)
52     # This is only the case for `pack`, so this code will not run.
53     stats[:mode] = EXECUTABLE
54   elsif stats.key?(:entry)
55     old_mode = stats[:entry].instance_variable_get(:@mode)
56     if old_mode.is_a?(Integer)
57       stats[:entry].instance_variable_set(:@mode, EXECUTABLE)
58     end
59   end
60 end
set_file_mode!(stats) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
68 def set_file_mode!(stats)
69   if stats.key?(:mode)
70     # This is only the case for `pack`, so this code will not run.
71     stats[:mode] = sanitized_mode(stats[:mode])
72   elsif stats.key?(:entry)
73     old_mode = stats[:entry].instance_variable_get(:@mode)
74     # If the user can execute the file, set 0755, otherwise 0644.
75     if old_mode.is_a?(Integer)
76       new_mode = sanitized_mode(old_mode)
77       stats[:entry].instance_variable_set(:@mode, new_mode)
78     end
79   end
80 end
validate_entry(destdir, path) click to toggle source
    # File lib/puppet/module_tool/tar/mini.rb
106 def validate_entry(destdir, path)
107   if Pathname.new(path).absolute?
108     raise Puppet::ModuleTool::Errors::InvalidPathInPackageError, :entry_path => path, :directory => destdir
109   end
110 
111   path = Pathname.new(File.join(destdir, path)).cleanpath.to_path
112 
113   if path !~ /\A#{Regexp.escape destdir}/
114     raise Puppet::ModuleTool::Errors::InvalidPathInPackageError, :entry_path => path, :directory => destdir
115   end
116 end