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