module Puppet::ModuleTool::Shared
Public Instance Methods
add_module_name_constraints_to_graph(graph)
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 169 def add_module_name_constraints_to_graph(graph) 170 # Puppet modules are installed by "module name", but resolved by 171 # "full name" (including namespace). So that we don't run into 172 # problems at install time, we should reject any solution that 173 # depends on multiple nodes with the same "module name". 174 graph.add_graph_constraint('PMT') do |nodes| 175 names = nodes.map { |x| x.dependency_names + [ x.name ] }.flatten 176 names = names.map { |x| x.tr('/', '-') }.uniq 177 names = names.map { |x| x[/-(.*)/, 1] } 178 names.length == names.uniq.length 179 end 180 end
annotated_version(mod, versions)
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 59 def annotated_version(mod, versions) 60 if versions.empty? 61 return implicit_version(mod) 62 else 63 return "#{implicit_version(mod)}: #{versions.last}" 64 end 65 end
download_tarballs(graph, default_path, forge)
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 146 def download_tarballs(graph, default_path, forge) 147 graph.map do |release| 148 begin 149 if release[:tarball] 150 cache_path = Pathname(release[:tarball]) 151 else 152 cache_path = forge.retrieve(release[:file]) 153 end 154 rescue OpenURI::HTTPError => e 155 raise RuntimeError, _("Could not download module: %{message}") % { message: e.message }, e.backtrace 156 end 157 158 [ 159 { (release[:path] ||= default_path) => cache_path}, 160 *download_tarballs(release[:dependencies], default_path, forge) 161 ] 162 end.flatten 163 end
forced?()
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 165 def forced? 166 options[:force] 167 end
get_local_constraints()
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 5 def get_local_constraints 6 @local = Hash.new { |h,k| h[k] = { } } 7 @conditions = Hash.new { |h,k| h[k] = [] } 8 @installed = Hash.new { |h,k| h[k] = [] } 9 10 @environment.modules_by_path.values.flatten.each do |mod| 11 mod_name = (mod.forge_name || mod.name).tr('/', '-') 12 @installed[mod_name] << mod 13 d = @local["#{mod_name}@#{mod.version}"] 14 (mod.dependencies || []).each do |hash| 15 name, conditions = hash['name'], hash['version_requirement'] 16 name = name.tr('/', '-') 17 d[name] = conditions 18 @conditions[name] << { 19 :module => mod_name, 20 :version => mod.version, 21 :dependency => conditions 22 } 23 end 24 end 25 end
get_remote_constraints(forge)
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 27 def get_remote_constraints(forge) 28 @remote = Hash.new { |h,k| h[k] = { } } 29 @urls = {} 30 @versions = Hash.new { |h,k| h[k] = [] } 31 32 Puppet.notice _("Downloading from %{uri} ...") % { uri: forge.uri } 33 author, modname = Puppet::ModuleTool.username_and_modname_from(@module_name) 34 info = forge.remote_dependency_info(author, modname, @options[:version]) 35 info.each do |pair| 36 mod_name, releases = pair 37 mod_name = mod_name.tr('/', '-') 38 releases.each do |rel| 39 semver = SemanticPuppet::Version.parse(rel['version']) rescue SemanticPuppet::Version::MIN 40 @versions[mod_name] << { :vstring => rel['version'], :semver => semver } 41 @versions[mod_name].sort! { |a, b| a[:semver] <=> b[:semver] } 42 @urls["#{mod_name}@#{rel['version']}"] = rel['file'] 43 d = @remote["#{mod_name}@#{rel['version']}"] 44 (rel['dependencies'] || []).each do |name, conditions| 45 d[name.tr('/', '-')] = conditions 46 end 47 end 48 end 49 end
implicit_version(mod)
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 51 def implicit_version(mod) 52 return :latest if @conditions[mod].empty? 53 if @conditions[mod].all? { |c| c[:queued] || c[:module] == :you } 54 return :latest 55 end 56 return :best 57 end
resolve_constraints(dependencies, source = [{:name => :you}], seen = {}, action = @action)
click to toggle source
# File lib/puppet/module_tool/shared_behaviors.rb 67 def resolve_constraints(dependencies, source = [{:name => :you}], seen = {}, action = @action) 68 dependencies = dependencies.map do |mod, range| 69 source.last[:dependency] = range 70 71 @conditions[mod] << { 72 :module => source.last[:name], 73 :version => source.last[:version], 74 :dependency => range, 75 :queued => true 76 } 77 78 if forced? 79 range = Puppet::Module.parse_range(@version) rescue Puppet::Module.parse_range('>= 0.0.0') 80 else 81 range = (@conditions[mod]).map do |r| 82 Puppet::Module.parse_range(r[:dependency]) rescue Puppet::Module.parse_range('>= 0.0.0') 83 end.inject(&:&) 84 end 85 86 if @action == :install && seen.include?(mod) 87 next if range === seen[mod][:semver] 88 89 req_module = @module_name 90 req_versions = @versions["#{@module_name}"].map { |v| v[:semver] } 91 raise InvalidDependencyCycleError, 92 :module_name => mod, 93 :source => (source + [{ :name => mod, :version => source.last[:dependency] }]), 94 :requested_module => req_module, 95 :requested_version => @version || annotated_version(req_module, req_versions), 96 :conditions => @conditions 97 end 98 99 if !(forced? || @installed[mod].empty? || source.last[:name] == :you) 100 next if range === SemanticPuppet::Version.parse(@installed[mod].first.version) 101 action = :upgrade 102 elsif @installed[mod].empty? 103 action = :install 104 end 105 106 if action == :upgrade 107 @conditions.each { |_, conds| conds.delete_if { |c| c[:module] == mod } } 108 end 109 110 versions = @versions["#{mod}"].select { |h| range === h[:semver] } 111 valid_versions = versions.select { |x| x[:semver].special == '' } 112 valid_versions = versions if valid_versions.empty? 113 114 version = valid_versions.last 115 unless version 116 req_module = @module_name 117 req_versions = @versions["#{@module_name}"].map { |v| v[:semver] } 118 raise NoVersionsSatisfyError, 119 :requested_name => req_module, 120 :requested_version => @version || annotated_version(req_module, req_versions), 121 :installed_version => @installed[@module_name].empty? ? nil : @installed[@module_name].first.version, 122 :dependency_name => mod, 123 :conditions => @conditions[mod], 124 :action => @action 125 end 126 127 seen[mod] = version 128 129 { 130 :module => mod, 131 :version => version, 132 :action => action, 133 :previous_version => @installed[mod].empty? ? nil : @installed[mod].first.version, 134 :file => @urls["#{mod}@#{version[:vstring]}"], 135 :path => action == :install ? @options[:target_dir] : (@installed[mod].empty? ? @options[:target_dir] : @installed[mod].first.modulepath), 136 :dependencies => [] 137 } 138 end.compact 139 dependencies.each do |mod| 140 deps = @remote["#{mod[:module]}@#{mod[:version][:vstring]}"].sort_by(&:first) 141 mod[:dependencies] = resolve_constraints(deps, source + [{ :name => mod[:module], :version => mod[:version][:vstring] }], seen, :install) 142 end unless @ignore_dependencies 143 return dependencies 144 end