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
32 def pack(sourcedir, destfile)
33   Zlib::GzipWriter.open(destfile) do |writer|
34     Archive::Tar::Minitar.pack(sourcedir, writer) do |step, name, stats|
35       # TODO smcclellan 2017-10-31 Set permissions here when this yield block
36       # executes before the header is written. As it stands, the `stats`
37       # argument isn't mutable in a way that will effect the desired mode for
38       # the file.
39     end
40   end
41 end
unpack(sourcefile, destdir, _) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
 2 def unpack(sourcefile, destdir, _)
 3   Zlib::GzipReader.open(sourcefile) do |reader|
 4     # puppet doesn't have a hard dependency on minitar, so we
 5     # can't be certain which version is installed. If it's 0.9
 6     # or above then we can prevent minitar from fsync'ing each
 7     # extracted file and directory, otherwise fallback to the
 8     # old behavior
 9     args = [reader, destdir, find_valid_files(reader)]
10     spec = Gem::Specification.find_by_name('minitar')
11     if spec && spec.version >= Gem::Version.new('0.9')
12       args << {:fsync => false}
13     end
14     Archive::Tar::Minitar.unpack(*args) do |action, name, stats|
15       case action
16       when :dir
17         validate_entry(destdir, name)
18         set_dir_mode!(stats)
19         Puppet.debug("Extracting: #{destdir}/#{name}")
20       when :file_start
21         # Octal string of the old file mode.
22         validate_entry(destdir, name)
23         set_file_mode!(stats)
24         Puppet.debug("Extracting: #{destdir}/#{name}")
25       end
26       set_default_user_and_group!(stats)
27       stats
28     end
29   end
30 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
 93 def find_valid_files(tarfile)
 94   Archive::Tar::Minitar.open(tarfile).collect do |entry|
 95     flag = entry.typeflag
 96     if flag.nil? || flag =~ /[[:digit:]]/ && (0..7).cover?(flag.to_i)
 97       entry.full_name
 98     else
 99       Puppet.debug "Invalid tar flag '#{flag}' will not be extracted: #{entry.name}"
100       next
101     end
102   end
103 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
63 def sanitized_mode(old_mode)
64   old_mode & USER_EXECUTE != 0 ? EXECUTABLE : NOT_EXECUTABLE
65 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
82 def set_default_user_and_group!(stats)
83   stats[:uid] = 0
84   stats[:gid] = 0
85 end
set_dir_mode!(stats) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
49 def set_dir_mode!(stats)
50   if stats.key?(:mode)
51     # This is only the case for `pack`, so this code will not run.
52     stats[:mode] = EXECUTABLE
53   elsif stats.key?(:entry)
54     old_mode = stats[:entry].instance_variable_get(:@mode)
55     if old_mode.is_a?(Integer)
56       stats[:entry].instance_variable_set(:@mode, EXECUTABLE)
57     end
58   end
59 end
set_file_mode!(stats) click to toggle source
   # File lib/puppet/module_tool/tar/mini.rb
67 def set_file_mode!(stats)
68   if stats.key?(:mode)
69     # This is only the case for `pack`, so this code will not run.
70     stats[:mode] = sanitized_mode(stats[:mode])
71   elsif stats.key?(:entry)
72     old_mode = stats[:entry].instance_variable_get(:@mode)
73     # If the user can execute the file, set 0755, otherwise 0644.
74     if old_mode.is_a?(Integer)
75       new_mode = sanitized_mode(old_mode)
76       stats[:entry].instance_variable_set(:@mode, new_mode)
77     end
78   end
79 end
validate_entry(destdir, path) click to toggle source
    # File lib/puppet/module_tool/tar/mini.rb
105 def validate_entry(destdir, path)
106   if Pathname.new(path).absolute?
107     raise Puppet::ModuleTool::Errors::InvalidPathInPackageError, :entry_path => path, :directory => destdir
108   end
109 
110   path = Pathname.new(File.join(destdir, path)).cleanpath.to_path
111 
112   if path !~ /\A#{Regexp.escape destdir}/
113     raise Puppet::ModuleTool::Errors::InvalidPathInPackageError, :entry_path => path, :directory => destdir
114   end
115 end