Class: Puppet::ModuleTool::Applications::Unpacker

Inherits:
Application show all
Defined in:
lib/puppet/module_tool/applications/unpacker.rb

Constant Summary

Constants inherited from Application

Application::DOCPATTERN

Constants included from Util

Util::AbsolutePathPosix, Util::AbsolutePathWindows, Util::DEFAULT_POSIX_MODE, Util::DEFAULT_WINDOWS_MODE, Util::RFC_3986_URI_REGEX

Constants included from Util::SymbolicFileMode

Util::SymbolicFileMode::SetGIDBit, Util::SymbolicFileMode::SetUIDBit, Util::SymbolicFileMode::StickyBit, Util::SymbolicFileMode::SymbolicMode, Util::SymbolicFileMode::SymbolicSpecialToBit

Constants included from Util::POSIX

Util::POSIX::LOCALE_ENV_VARS, Util::POSIX::USER_ENV_VARS

Instance Attribute Summary

Attributes inherited from Application

#command_line, #options

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Application

[], #app_defaults, available_application_names, banner, clear!, clear?, clear_everything_for_tests, #configure_indirector_routes, controlled_run, #deprecate, #deprecated?, environment_mode, exit, find, get_environment_mode, #handle_logdest_arg, #handlearg, #help, #initialize_app_defaults, interrupted?, #log_runtime_environment, #main, #name, option, option_parser_commands, #parse_options, #preinit, restart!, restart_requested?, #run_command, run_mode, #set_log_level, #setup, #setup_logs, stop!, stop_requested?, #summary, try_load_class

Methods included from Util

absolute_path?, benchmark, chuser, clear_environment, default_env, deterministic_rand, deterministic_rand_int, exit_on_fail, get_env, get_environment, logmethods, merge_environment, path_to_uri, pretty_backtrace, replace_file, safe_posix_fork, set_env, symbolizehash, thinmark, uri_encode, uri_query_encode, uri_to_path, which, withenv, withumask

Methods included from Util::SymbolicFileMode

#normalize_symbolic_mode, #symbolic_mode_to_int, #valid_symbolic_mode?

Methods included from Util::POSIX

#get_posix_field, #gid, groups_of, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid

Constructor Details

#initialize(filename, options = {}) ⇒ Unpacker


25
26
27
28
29
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 25

def initialize(filename, options = {})
  @filename = Pathname.new(filename)
  super(options)
  @module_path = Pathname(options[:target_dir])
end

Class Method Details

.harmonize_ownership(source, target) ⇒ Object


16
17
18
19
20
21
22
23
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 16

def self.harmonize_ownership(source, target)
  unless Puppet::Util::Platform.windows?
    source = Pathname.new(source) unless source.respond_to?(:stat)
    target = Pathname.new(target) unless target.respond_to?(:stat)

    FileUtils.chown_R(source.stat.uid, source.stat.gid, target)
  end
end

.unpack(filename, target) ⇒ Object


9
10
11
12
13
14
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 9

def self.unpack(filename, target)
  app = self.new(filename, :target_dir => target)
  app.unpack
  app.sanity_check
  app.move_into(target)
end

Instance Method Details

#module_nameObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


77
78
79
80
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 77

def module_name
   = Puppet::Util::Json.load((root_dir + 'metadata.json').read)
  ['name'][/-(.*)/, 1]
end

#move_into(dir) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


83
84
85
86
87
88
89
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 83

def move_into(dir)
  dir = Pathname.new(dir)
  dir.rmtree if dir.exist?
  FileUtils.mv(root_dir, dir)
ensure
  FileUtils.rmtree(tmpdir)
end

#root_dirObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 63

def root_dir
  return @root_dir if @root_dir

  # Grab the first directory containing a metadata.json file
   = Dir["#{tmpdir}/**/metadata.json"].sort_by(&:length)[0]

  if 
    @root_dir = Pathname.new().dirname
  else
    raise _("No valid metadata.json found!")
  end
end

#runObject


31
32
33
34
35
36
37
38
39
40
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 31

def run
  unpack
  sanity_check
  module_dir = @module_path + module_name
  move_into(module_dir)

  # Return the Pathname object representing the directory where the
  # module release archive was unpacked the to.
  return module_dir
end

#sanity_checkObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Error on symlinks and other junk


44
45
46
47
48
49
50
51
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 44

def sanity_check
  symlinks = Dir.glob("#{tmpdir}/**/*", File::FNM_DOTMATCH).map { |f| Pathname.new(f) }.select {|p| Puppet::FileSystem.symlink? p}
  tmpdirpath = Pathname.new tmpdir

  symlinks.each do |s|
    Puppet.warning _("Symlinks in modules are unsupported. Please investigate symlink %{from}->%{to}.") % { from: s.relative_path_from(tmpdirpath), to: Puppet::FileSystem.readlink(s) }
  end
end

#tmpdirString

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Obtain a suitable temporary path for unpacking tarballs


95
96
97
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 95

def tmpdir
  @dir ||= Dir.mktmpdir('tmp', Puppet::Forge::Cache.base_path)
end

#unpackObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.


54
55
56
57
58
59
60
# File 'lib/puppet/module_tool/applications/unpacker.rb', line 54

def unpack
  begin
    Puppet::ModuleTool::Tar.instance.unpack(@filename.to_s, tmpdir, [@module_path.stat.uid, @module_path.stat.gid].join(':'))
  rescue Puppet::ExecutionFailure => e
    raise RuntimeError, _("Could not extract contents of module archive: %{message}") % { message: e.message }
  end
end