Class: Simp::Build::ReleaseMapper

Inherits:
Object
  • Object
show all
Defined in:
lib/simp/build/release_mapper.rb

Overview

Maps a target SIMP release to the base OS ISOs required to build it.

Reads a release_mappings.yaml (from simp-core's build/distributions/<distro>/<version>/<arch>/) and matches a set of candidate ISO files against the flavors known for the target release.

Absorbed from the simp-build-helpers gem, which is no longer maintained as a separate project.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(target_release, mappings_file, do_checksums = false) ⇒ ReleaseMapper



21
22
23
24
25
26
27
28
# File 'lib/simp/build/release_mapper.rb', line 21

def initialize(target_release, mappings_file, do_checksums = false)
  @target_release   = target_release
  @mappings_file    = mappings_file
  @release_mappings = YAML.load_file(mappings_file)
  @target_data      = get_release_mappings_for_target(@target_release, @release_mappings)
  @do_checksums     = do_checksums
  @verbose          = false
end

Instance Attribute Details

#do_checksumsObject

Returns the value of attribute do_checksums.



19
20
21
# File 'lib/simp/build/release_mapper.rb', line 19

def do_checksums
  @do_checksums
end

#verboseObject

Returns the value of attribute verbose.



19
20
21
# File 'lib/simp/build/release_mapper.rb', line 19

def verbose
  @verbose
end

Instance Method Details

#autoscan_unpack_list(paths_string) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/simp/build/release_mapper.rb', line 108

def autoscan_unpack_list(paths_string)
  iso_paths = sanitize_iso_list(paths_string)

  if iso_paths.empty?
    raise SIMPBuildException,
          "ERROR: No suitable ISOs found for target release '#{@target_release}' in '#{paths_string}'.\n\n" \
          "## Recognized SIMP ISOs for '#{@target_release}':\n\n#{recognized_isos}\n\n"
  end

  unpack_files = get_flavor(iso_paths)

  if unpack_files.nil?
    raise SIMPBuildException,
          "ERROR: No flavors for target release '#{@target_release}' found in '#{paths_string}'.\n\n" \
          "## Recognized SIMP ISOs for '#{@target_release}':\n\n#{recognized_isos(detailed: true)}\n\n"
  end

  unpack_files
end

#get_flavor(isos) ⇒ Object

Given a list of isos: see if any match the complete set of ISOs for one of the target_release's flavors. If it matches, return a Hash containing the flavor and the matched ISOs. If they didn't match any known distros, return nil

Some of the isos lists might be superfluous



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/simp/build/release_mapper.rb', line 66

def get_flavor(isos)
  iso_sizes   = isos.map { |iso| [iso, File.size(iso)] }.sort.to_h
  result      = false
  result_isos = []

  @target_data['flavors'].each do |flavor, data|
    sizes = data['isos'].map { |x| x['size'] }.sort
    next unless sizes.uniq == sizes & iso_sizes.values

    matched_isos = iso_sizes.select { |_iso, size| sizes.include?(size) }.keys
    result_isos  = matched_isos

    if @do_checksums || (sizes.uniq.size != sizes.size)
      checksums = data['isos'].map { |x| x['checksum'] }

      iso_checksums = matched_isos.to_h do |iso|
        puts "=== getting checksum of '#{iso}'" if @verbose

        [iso, `sha256sum "#{iso}"`.split(%r{ +}).first]
      end

      matched_isos = iso_checksums.select { |_iso, sum| checksums.include?(sum) }

      # The checksums did not account for every ISO this flavor expects, so
      # it is not a match.  Keep looking rather than falling through and
      # reporting the flavor with an empty ISO list.
      next unless matched_isos.values.uniq.size == checksums.uniq.size

      result      = flavor
      result_isos = matched_isos.keys.dup
      break
    end

    result = flavor
    break
  end

  return nil unless result

  @target_data['flavors'][result].merge({ 'flavor' => result, 'isos' => result_isos })
end

#get_release_mappings_for_target(target_release, release_mappings) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/simp/build/release_mapper.rb', line 30

def get_release_mappings_for_target(target_release, release_mappings)
  releases    = release_mappings.fetch('simp_releases')
  target_data = releases.fetch(target_release, false)

  unless target_data
    known = releases.keys.map { |x| "  - #{x}\n" }.join

    raise SIMPBuildException,
          "'#{target_release}' is not a recognized SIMP release.\n\n" \
          "## Recognized SIMP releases:\n#{known}\n\n"
  end

  target_data
end

#sanitize_iso_list(paths_string) ⇒ Object

Given a path string of files or directories, return a list of .iso files

  • if all paths are bad, the result is an empty array
  • directories are scanned for .iso files


48
49
50
51
52
53
54
55
56
57
58
# File 'lib/simp/build/release_mapper.rb', line 48

def sanitize_iso_list(paths_string)
  paths_string.split(':').flat_map { |path|
    if File.directory?(path)
      Dir[File.join(path, '*.iso')]
    elsif File.file?(path)
      path
    else
      []
    end
  }.sort.uniq
end