Class: Chef::Provider::ZypperRepository

Inherits:
Chef::Provider show all
Defined in:
lib/chef/provider/zypper_repository.rb

Instance Attribute Summary

Attributes inherited from Chef::Provider

#action, #after_resource, #current_resource, #logger, #new_resource, #run_context

Instance Method Summary collapse

Methods inherited from Chef::Provider

action, action_description, action_descriptions, #action_nothing, #check_resource_semantics!, #cleanup_after_converge, #compile_and_converge_action, #converge_by, #converge_if_changed, #cookbook_name, #define_resource_requirements, #description, #events, include_resource_dsl?, include_resource_dsl_module, #initialize, #introduced, #load_after_resource, #node, #process_resource_requirements, provides, provides?, #recipe_name, #requirements, #resource_collection, #resource_updated?, #run_action, #set_updated_status, supports?, use, use_inline_resources, #validate_required_properties!, #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::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::Secret

#default_secret_config, #default_secret_service, #secret, #with_secret_config, #with_secret_service

Methods included from DSL::RenderHelpers

#render_json, #render_toml, #render_yaml

Methods included from DSL::ReaderHelpers

#parse_file, #parse_json, #parse_toml, #parse_yaml

Methods included from DSL::Powershell

#ps_credential

Methods included from DSL::RegistryHelper

#registry_data_exists?, #registry_get_subkeys, #registry_get_values, #registry_has_subkeys?, #registry_key_exists?, #registry_value_exists?

Methods included from DSL::ChefVault

#chef_vault, #chef_vault_item, #chef_vault_item_for_environment

Methods included from DSL::DataQuery

#data_bag, #data_bag_item, #search, #tagged?

Methods included from EncryptedDataBagItem::CheckEncrypted

#encrypted?

Methods included from DSL::PlatformIntrospection

#older_than_win_2012_or_8?, #platform?, #platform_family?, #value_for_platform, #value_for_platform_family

Methods included from DSL::Recipe

#exec, #have_resource_class_for?, #resource_class_for

Methods included from DSL::Definitions

add_definition, #evaluate_resource_definition, #has_resource_definition?

Methods included from DSL::Resources

add_resource_dsl, remove_resource_dsl

Methods included from DSL::Cheffish

load_cheffish

Methods included from DSL::RebootPending

#reboot_pending?

Methods included from DSL::IncludeRecipe

#include_recipe, #load_recipe

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!, #resources, #with_run_context

Methods included from DSL::Compliance

#include_input, #include_profile, #include_waiver

Constructor Details

This class inherits a constructor from Chef::Provider

Instance Method Details

#escaped_repo_nameString

zypper repos are allowed to have spaces in the names

Returns:

  • (String)

    escaped repo string



70
71
72
# File 'lib/chef/provider/zypper_repository.rb', line 70

def escaped_repo_name
  @escaped_repo_name ||= Shellwords.escape(new_resource.repo_name)
end

#gpg_versionGem::Version

the version of gpg installed on the system

Returns:

  • (Gem::Version)

    the version of GPG



112
113
114
115
116
117
118
# File 'lib/chef/provider/zypper_repository.rb', line 112

def gpg_version
  so = shell_out!("gpg --version")
  # matches 2.0 and 2.2 versions from SLES 12 and 15: https://rubular.com/r/e6D0WfGK6SXvUp
  version = /gpg \(GnuPG\)\s*(.*)/.match(so.stdout)[1]
  logger.trace("GPG package version is #{version}")
  Gem::Version.new(version)
end

#has_cookbook_file?(fn) ⇒ Boolean

determine if a cookbook file is available in the run

Parameters:

  • fn (String)

    the path to the template file

Returns:

  • (Boolean)

    cookbook file exists or doesn't



86
87
88
# File 'lib/chef/provider/zypper_repository.rb', line 86

def has_cookbook_file?(fn)
  run_context.has_cookbook_file_in_cookbook?(new_resource.cookbook, fn)
end

#install_gpg_keys(uris) ⇒ Object

install the provided gpg keys

Parameters:

  • uris (String)

    the uri of the local or remote gpg key



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
# File 'lib/chef/provider/zypper_repository.rb', line 155

def install_gpg_keys(uris)
  if uris.empty?
    logger.debug("'gpgkey' property not provided or set. Skipping gpg key import.")
    return
  end

  # fetch each key to the cache dir either from the cookbook or by downloading it
  # and then import the key
  uris.each do |uri|
    cached_keyfile = ::File.join(Chef::Config[:file_cache_path], uri.split("/")[-1])

    declare_resource(key_type(uri), cached_keyfile) do
      source uri
      mode "0644"
      sensitive new_resource.sensitive
      action :create
    end

    execute "import gpg key from #{uri}" do
      command "/bin/rpm --import #{cached_keyfile}"
      not_if { key_installed?(cached_keyfile) }
      action :run
    end
  end
end

#key_installed?(key_path) ⇒ boolean

is the provided key already installed

Parameters:

  • key_path (String)

    the path to the key on the local filesystem

Returns:

  • (boolean)

    is the key already known by rpm



124
125
126
127
128
129
130
# File 'lib/chef/provider/zypper_repository.rb', line 124

def key_installed?(key_path)
  so = shell_out("/bin/rpm -qa gpg-pubkey*")
  # expected output & match: http://rubular.com/r/RdF7EcXEtb
  status = /gpg-pubkey-#{short_key_id(key_path)}/.match(so.stdout)
  logger.trace("GPG key at #{key_path} is known by rpm? #{status ? "true" : "false"}")
  status
end

#key_type(uri) ⇒ Symbol

Given the provided key URI determine what kind of chef resource we need to fetch the key

Parameters:

  • uri (String)

    the uri of the gpg key (local path or http URL)

Returns:

  • (Symbol)

    :remote_file or :cookbook_file

Raises:



97
98
99
100
101
102
103
104
105
106
107
# File 'lib/chef/provider/zypper_repository.rb', line 97

def key_type(uri)
  if uri.start_with?("http")
    logger.trace("Will use :remote_file resource to cache the gpg key locally")
    :remote_file
  elsif has_cookbook_file?(uri)
    logger.trace("Will use :cookbook_file resource to cache the gpg key locally")
    :cookbook_file
  else
    raise Chef::Exceptions::FileNotFound, "Cannot determine location of gpgkey. Must start with 'http' or be a file managed by #{ChefUtils::Dist::Infra::PRODUCT}."
  end
end

#load_current_resourceObject



30
# File 'lib/chef/provider/zypper_repository.rb', line 30

def load_current_resource; end

#short_key_id(key_path) ⇒ String

extract the gpg key's short key id from a local file. Learning moment: This 8 hex value ID is sometimes incorrectly called the fingerprint. The fingerprint is the full length value and googling for that will just result in sad times.

Parameters:

  • key_path (String)

    the path to the key on the local filesystem

Returns:

  • (String)

    the short key id of the key



139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/chef/provider/zypper_repository.rb', line 139

def short_key_id(key_path)
  if gpg_version >= Gem::Version.new("2.2") # SLES 15+
    so = shell_out!("gpg --import-options import-show --dry-run --import --with-colons #{key_path}")
    # expected output and match: https://rubular.com/r/uXWJo3yfkli1qA
    short_key_id = /fpr:*\h*(\h{8}):/.match(so.stdout)[1].downcase
  else # SLES 12 and earlier
    so = shell_out!("gpg --with-fingerprint #{key_path}")
    # expected output and match: http://rubular.com/r/BpfMjxySQM
    short_key_id = %r{pub\s*\S*/(\S*)}.match(so.stdout)[1].downcase
  end
  logger.trace("GPG short key ID of key at #{key_path} is #{short_key_id}")
  short_key_id
end

#template_available?(path) ⇒ Boolean

determine if a template file is available in the current run

Parameters:

  • path (String)

    the path to the template file

Returns:

  • (Boolean)

    template file exists or doesn't



78
79
80
# File 'lib/chef/provider/zypper_repository.rb', line 78

def template_available?(path)
  !path.nil? && run_context.has_template_in_cookbook?(new_resource.cookbook, path)
end