Class: Chef::Provider::AptRepository
- Inherits:
-
Chef::Provider
- Object
- Chef::Provider
- Chef::Provider::AptRepository
- Extended by:
- Mixin::Which
- Includes:
- Mixin::ShellOut
- Defined in:
- lib/chef/provider/apt_repository.rb
Constant Summary collapse
- LIST_APT_KEYS =
"apt-key list".freeze
- LIST_APT_KEY_FINGERPRINTS =
"apt-key adv --list-public-keys --with-fingerprint --with-colons".freeze
Instance Attribute Summary
Attributes inherited from Chef::Provider
#action, #current_resource, #new_resource, #recipe_name, #run_context
Instance Method Summary collapse
- #build_repo(uri, distribution, components, trusted, arch, add_src = false) ⇒ Object
- #cookbook_name ⇒ Object
- #extract_fingerprints_from_cmd(cmd) ⇒ Object
- #has_cookbook_file?(fn) ⇒ Boolean
- #install_key_from_keyserver(key = new_resource.key, keyserver = new_resource.keyserver) ⇒ Object
- #install_key_from_uri ⇒ Object
- #install_ppa_key(owner, repo) ⇒ Object
- #is_key_id?(id) ⇒ Boolean
- #is_ppa_url?(url) ⇒ Boolean
- #key_is_valid?(cmd, key) ⇒ Boolean
- #load_current_resource ⇒ Object
- #make_ppa_url(ppa) ⇒ Object
- #no_new_keys?(file) ⇒ Boolean
Methods included from Mixin::Which
Methods included from Mixin::ShellOut
#a_to_s, #clean_array, #shell_out, #shell_out!, #shell_out_compact, #shell_out_compact!, #shell_out_compact_timeout, #shell_out_compact_timeout!, #shell_out_with_systems_locale, #shell_out_with_systems_locale!
Methods included from Mixin::PathSanity
#enforce_path_sanity, #sanitized_path
Methods inherited from Chef::Provider
action, #action_nothing, #check_resource_semantics!, #cleanup_after_converge, #compile_and_converge_action, #converge_by, #converge_if_changed, #define_resource_requirements, #events, include_resource_dsl?, include_resource_dsl_module, #initialize, #node, #process_resource_requirements, provides, provides?, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, use_inline_resources, #whyrun_mode?, #whyrun_supported?
Methods included from Mixin::Provides
#provided_as, #provides, #provides?
Methods included from Mixin::DescendantsTracker
#descendants, descendants, #direct_descendants, direct_descendants, #find_descendants_by_name, find_descendants_by_name, #inherited, store_inherited
Methods included from Mixin::LazyModuleInclude
#descendants, #include, #included
Methods included from Mixin::NotifyingBlock
#notifying_block, #subcontext_block
Methods included from DSL::DeclareResource
#build_resource, #declare_resource, #delete_resource, #delete_resource!, #edit_resource, #edit_resource!, #find_resource, #find_resource!, #with_run_context
Methods included from Mixin::PowershellOut
#powershell_out, #powershell_out!
Methods included from Mixin::WindowsArchitectureHelper
#assert_valid_windows_architecture!, #disable_wow64_file_redirection, #forced_32bit_override_required?, #is_i386_process_on_x86_64_windows?, #node_supports_windows_architecture?, #node_windows_architecture, #restore_wow64_file_redirection, #valid_windows_architecture?, #with_os_architecture, #wow64_architecture_override_required?, #wow64_directory
Methods included from DSL::PlatformIntrospection
#docker?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family
Constructor Details
This class inherits a constructor from Chef::Provider
Instance Method Details
#build_repo(uri, distribution, components, trusted, arch, add_src = false) ⇒ Object
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/chef/provider/apt_repository.rb', line 232 def build_repo(uri, distribution, components, trusted, arch, add_src = false) uri = make_ppa_url(uri) if is_ppa_url?(uri) uri = '"' + uri + '"' unless uri.start_with?("'", '"') components = Array(components).join(" ") = [] << "arch=#{arch}" if arch << "trusted=yes" if trusted optstr = unless .empty? "[" + .join(" ") + "]" end info = [ optstr, uri, distribution, components ].compact.join(" ") repo = "deb #{info}\n" repo << "deb-src #{info}\n" if add_src repo end |
#cookbook_name ⇒ Object
138 139 140 |
# File 'lib/chef/provider/apt_repository.rb', line 138 def cookbook_name new_resource.cookbook || new_resource.cookbook_name end |
#extract_fingerprints_from_cmd(cmd) ⇒ Object
111 112 113 114 115 116 117 118 119 |
# File 'lib/chef/provider/apt_repository.rb', line 111 def extract_fingerprints_from_cmd(cmd) so = shell_out(cmd) so.run_command so.stdout.split(/\n/).map do |t| if z = t.match(/^fpr:+([0-9A-F]+):/) z[1].split.join end end.compact end |
#has_cookbook_file?(fn) ⇒ Boolean
142 143 144 |
# File 'lib/chef/provider/apt_repository.rb', line 142 def has_cookbook_file?(fn) run_context.has_cookbook_file_in_cookbook?(cookbook_name, fn) end |
#install_key_from_keyserver(key = new_resource.key, keyserver = new_resource.keyserver) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/chef/provider/apt_repository.rb', line 184 def install_key_from_keyserver(key = new_resource.key, keyserver = new_resource.keyserver) cmd = "apt-key adv --recv" cmd << " --keyserver-options http-proxy=#{new_resource.key_proxy}" if new_resource.key_proxy cmd << " --keyserver " cmd << if keyserver.start_with?("hkp://") keyserver else "hkp://#{keyserver}:80" end cmd << " #{key}" declare_resource(:execute, "install-key #{key}") do command cmd sensitive new_resource.sensitive not_if do present = extract_fingerprints_from_cmd(LIST_APT_KEY_FINGERPRINTS).any? do |fp| fp.end_with? key.upcase end present && key_is_valid?(LIST_APT_KEYS, key.upcase) end notifies :run, "execute[apt-cache gencaches]", :immediately end raise "The key #{key} is invalid and cannot be used to verify an apt repository." unless key_is_valid?(LIST_APT_KEYS, key.upcase) end |
#install_key_from_uri ⇒ Object
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 |
# File 'lib/chef/provider/apt_repository.rb', line 154 def install_key_from_uri key_name = new_resource.key.gsub(/[^0-9A-Za-z\-]/, "_") cached_keyfile = ::File.join(Chef::Config[:file_cache_path], key_name) type = if new_resource.key.start_with?("http") :remote_file elsif has_cookbook_file?(new_resource.key) :cookbook_file else raise Chef::Exceptions::FileNotFound, "Cannot locate key file" end declare_resource(type, cached_keyfile) do source new_resource.key mode "0644" sensitive new_resource.sensitive action :create end raise "The key #{cached_keyfile} is invalid and cannot be used to verify an apt repository." unless key_is_valid?("gpg #{cached_keyfile}", "") declare_resource(:execute, "apt-key add #{cached_keyfile}") do sensitive new_resource.sensitive action :run not_if do no_new_keys?(cached_keyfile) end notifies :run, "execute[apt-cache gencaches]", :immediately end end |
#install_ppa_key(owner, repo) ⇒ Object
211 212 213 214 215 216 217 |
# File 'lib/chef/provider/apt_repository.rb', line 211 def install_ppa_key(owner, repo) url = "https://launchpad.net/api/1.0/~#{owner}/+archive/#{repo}" key_id = Chef::HTTP::Simple.new(url).get("signing_key_fingerprint").delete('"') install_key_from_keyserver(key_id, "keyserver.ubuntu.com") rescue Net::HTTPServerException => e raise "Could not access Launchpad ppa API: #{e.message}" end |
#is_key_id?(id) ⇒ Boolean
106 107 108 109 |
# File 'lib/chef/provider/apt_repository.rb', line 106 def is_key_id?(id) id = id[2..-1] if id.start_with?("0x") id =~ /^\h+$/ && [8, 16, 40].include?(id.length) end |
#is_ppa_url?(url) ⇒ Boolean
219 220 221 |
# File 'lib/chef/provider/apt_repository.rb', line 219 def is_ppa_url?(url) url.start_with?("ppa:") end |
#key_is_valid?(cmd, key) ⇒ Boolean
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/chef/provider/apt_repository.rb', line 121 def key_is_valid?(cmd, key) valid = true so = shell_out(cmd) so.run_command so.stdout.split(/\n/).map do |t| if t =~ %r{^\/#{key}.*\[expired: .*\]$} Chef::Log.debug "Found expired key: #{t}" valid = false break end end Chef::Log.debug "key #{key} #{valid ? "is valid" : "is not valid"}" valid end |
#load_current_resource ⇒ Object
39 40 |
# File 'lib/chef/provider/apt_repository.rb', line 39 def load_current_resource end |
#make_ppa_url(ppa) ⇒ Object
223 224 225 226 227 228 229 230 |
# File 'lib/chef/provider/apt_repository.rb', line 223 def make_ppa_url(ppa) return unless is_ppa_url?(ppa) owner, repo = ppa[4..-1].split("/") repo ||= "ppa" install_ppa_key(owner, repo) "http://ppa.launchpad.net/#{owner}/#{repo}/ubuntu" end |
#no_new_keys?(file) ⇒ Boolean
146 147 148 149 150 151 152 |
# File 'lib/chef/provider/apt_repository.rb', line 146 def no_new_keys?(file) # Now we are using the option --with-colons that works across old os versions # as well as the latest (16.10). This for both `apt-key` and `gpg` commands installed_keys = extract_fingerprints_from_cmd(LIST_APT_KEY_FINGERPRINTS) proposed_keys = extract_fingerprints_from_cmd("gpg --with-fingerprint --with-colons #{file}") (installed_keys & proposed_keys).sort == proposed_keys.sort end |