Class: Installation::AutoinstProfile::SectionWithAttributes

Inherits:
Object
  • Object
show all
Includes:
Yast::Logger
Defined in:
library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb

Overview

Abstract base class to be used when dealing with AutoYaST profiles

Motivation

Historically, AutoYaST has used hash objects to handle the profile data. The import method expects to receive a hash with the profile content while the export method returns a hash. For simple cases, it is just fine. However, for complex scenarios (like storage or networking settings), using a hash can be somewhat limiting.

Features

This class offers a starting point for a better API when working with AutoYaST profiles, abstracting some details. The idea is that by creating a derived class and specifying the known profile elements (attributes) you get a basic class that you can extend to offer a convenient API.

These classes would be responsible for:

Scope

Validation or setting default values is out of the scope of these classes, as it belongs to the code which imports the profile data. However, nothing is set in stone and we could change this decision in the future if needed.

Limitations

This class only handles scalar data types. If you need to deal with arrays, you must extend your derived class. The reason is that, usually, those arrays are composed of other sections like partitions, network interfaces, etc. Take into account that you will need to write code import and export those structures. Check the partitions and network interfaces examples to find out the details.

Examples

Examples:

Custom section definition

class SignatureHandlingSection < SectionWithAttributes
  class << self
    def attributes
     [
       { name: :accept_file_without_checksum },
       { name: :accept_usigned_file }
     ]
    end
  end
end

Importing a section from the profile

def import(settings)
  section = SignatureHandlingSection.new_from_hashes(settings)
  # Do whatever you need to do with the section content.
end

Exporting the values from the system

def export
  section = SignatureHandlingSection.new_from_system(signature_handling)
  section.to_hashes
end

Adding a query API method

class SignatureHandlingSection < SectionWithAttributes
  # Omiting attributes definition for simplicity reasons.

  # Determines whether the signature checking is completely disabled
  #
  # @return [Boolean]
  def disabled?
    accept_file_without_checksum && accept_unsigned_file
  end
end

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(parent = nil) ⇒ SectionWithAttributes

Constructor

Parameters:


172
173
174
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 172

def initialize(parent = nil)
  @parent = parent
end

Instance Attribute Details

#parent#parent, #section_name (readonly)

This value only makes sense when new_from_hashes is used.

Returns:


167
168
169
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 167

def parent
  @parent
end

Class Method Details

.attributesArray<Hash>

Description of the attributes in the section.

To be defined by each subclass. Each entry contains a hash with the mandatory key :name and an optional key :xml_name.

Returns:

  • (Array<Hash>)

129
130
131
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 129

def attributes
  []
end

.define_attr_accessorsObject (protected)

Macro used in the subclasses to define accessors for all the attributes defined by attributes


157
158
159
160
161
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 157

def define_attr_accessors
  attributes.each do |attrib|
    attr_accessor attrib[:name]
  end
end

.new_from_hashes(hash, parent = nil) ⇒ SectionWithAttributes

Creates an instance based on the profile representation used by the AutoYaST modules (nested arrays and hashes).

This method provides no extra validation, type conversion or initialization to default values. Those responsibilities belong to the AutoYaST modules. The hash is expected to be valid and contain the relevant information. Attributes are set to nil for missing keys and for blank values.

Parameters:

  • hash (Hash)

    content of the corresponding section of the profile. Each element of the hash corresponds to one of the attributes defined in the section.

  • parent (#parent, #section_name) (defaults to: nil)

    parent section

Returns:


147
148
149
150
151
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 147

def new_from_hashes(hash, parent = nil)
  result = new(parent)
  result.init_from_hashes(hash)
  result
end

Instance Method Details

#attrib_key(attrib) ⇒ Object (protected)


233
234
235
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 233

def attrib_key(attrib)
  (attrib[:xml_name] || attrib[:name]).to_s
end

#attrib_name(key) ⇒ Object (protected)


250
251
252
253
254
255
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 250

def attrib_name(key)
  attrib = attributes.detect { |a| a[:xml_name] == key.to_sym || a[:name] == key.to_sym }
  return nil unless attrib

  attrib[:name]
end

#attrib_scalar(element) ⇒ Object (protected)


246
247
248
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 246

def attrib_scalar(element)
  element.respond_to?(:to_hashes) ? element.to_hashes : element
end

#attrib_skip?(value) ⇒ Boolean (protected)

Whether an attribute must be skipped during import/export.

Returns:

  • (Boolean)

    true is the value is blank


229
230
231
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 229

def attrib_skip?(value)
  value.nil? || value == [] || value == ""
end

#attrib_value(attrib) ⇒ Object (protected)


237
238
239
240
241
242
243
244
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 237

def attrib_value(attrib)
  value = send(attrib[:name])
  if value.is_a?(Array)
    value.map { |v| attrib_scalar(v) }
  else
    attrib_scalar(value)
  end
end

#attributesObject (protected)


222
223
224
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 222

def attributes
  self.class.attributes
end

#init_from_hashes(hash) ⇒ Object

Method used by new_from_hashes to populate the attributes.

By default, it simply assigns the non-empty hash values to the corresponding attributes, logging unknown keys. The subclass is expected to refine this behavior if needed.

Parameters:


183
184
185
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 183

def init_from_hashes(hash)
  init_scalars_from_hash(hash)
end

#init_scalars_from_hash(hash) ⇒ Object (protected)


257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 257

def init_scalars_from_hash(hash)
  hash.each_pair do |key, value|
    name = attrib_name(key)

    if name.nil?
      log.warn "Attribute #{key} not recognized by #{self.class}. Check the XML schema."
      next
    end

    # This method only reads scalar values
    next if value.is_a?(Array) || value.is_a?(Hash)

    if attrib_skip?(value)
      log.debug "Ignored blank value (#{value}) for #{key}"
      next
    end

    send(:"#{name}=", value)
  end
end

#section_nameString

Returns the section name

In some cases, the section name does not match with the XML name and this method should be redefined.

Examples:

section = PartitioningSection.new
section.section_name #=> "partitioning"

Returns:

  • (String)

    Section name


213
214
215
216
217
218
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 213

def section_name
  klass_name = self.class.name.split("::").last
  klass_name
    .gsub(/([a-z])([A-Z])/, "\\1_\\2").downcase
    .chomp("_section")
end

#to_hashesHash

Content of the section in the format used by the AutoYaST modules (nested arrays and hashes).

Returns:

  • (Hash)

    each element of the hash corresponds to one of the attributes defined in the section. Blank attributes are not included.


193
194
195
196
197
198
199
200
201
# File 'library/general/src/lib/installation/autoinst_profile/section_with_attributes.rb', line 193

def to_hashes
  attributes.each_with_object({}) do |attrib, result|
    value = attrib_value(attrib)
    next if attrib_skip?(value)

    key = attrib_key(attrib)
    result[key] = value
  end
end