Module: PuppetX::AugeasprovidersGrub::Util

Defined in:
lib/puppetx/augeasproviders_grub/util.rb

Overview

None of these methods perform direct catalogue manipulation; they are focused on idempotent transformation of data so that providers can make consistent comparisons and updates.

Class Method Summary collapse

Class Method Details

.grub2_cfgString

Return the contents of the GRUB2 configuration on the system. Raise an error if not found.

Returns:

  • (String)

    The contents of the GRUB2 configuration on the system.



202
203
204
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 202

def self.grub2_cfg
  File.read(grub2_cfg_path)
end

.grub2_cfg_pathString

Return the location of the first discovered GRUB2 configuration.

Returns:

  • (String)

    The full path to the GRUB2 configuration file.

Raises:

  • (Puppet::Error)

    if no path is found



190
191
192
193
194
195
196
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 190

def self.grub2_cfg_path
  paths = grub2_cfg_paths

  raise Puppet::Error, 'Could not find a GRUB2 configuration on the system' if paths.empty?

  paths.first
end

.grub2_cfg_pathsArray[String]

Return the location of all valid GRUB2 configurations on the system.

Returns:

  • (Array[String])

    Paths to all system GRUB2 configuration files.

Raises:

  • (Puppet::Error)

    if no path is found



153
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
183
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 153

def self.grub2_cfg_paths
  paths = [
    '/etc/grub2.cfg',
    '/etc/grub2-efi.cfg',
    "/boot/efi/EFI/#{os_name.downcase}/grub.cfg",
    '/boot/grub2/grub.cfg',
    '/boot/grub/grub.cfg',
  ]

  valid_paths = paths.map do |path|
    real_path = nil

    if File.readable?(path) && !File.directory?(path)
      real_path = File.realpath(path)

      # Exclude stub files which include main config (e.g. Debian OS family)
      File.foreach(real_path) do |line|
        if line.match(%r{^configfile}s)
          real_path = nil
          break
        end
      end
    end

    real_path
  end.compact.uniq

  raise(%(No grub configuration found at '#{paths.join("', '")}')) if valid_paths.empty?

  valid_paths
end

.grub2_mkconfig(mkconfig_output, configs = grub2_cfg_paths) ⇒ Array[String]

Run grub2-mkconfig on all passed configurations

Parameters:

  • mkconfig_output (String)

    The output of grub2-mkconfig

  • configs (Array[String]) (defaults to: grub2_cfg_paths)

    The output target paths

Returns:

  • (Array[String])

    Updated paths

Raises:

  • (Puppet::Error)

    if an empty string is passed as the file content



217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 217

def self.grub2_mkconfig(mkconfig_output, configs = grub2_cfg_paths)
  raise('No output from grub2-mkconfig') if mkconfig_output.strip.empty?

  configs.each do |config_path|
    File.open(config_path, 'w') do |fh|
      fh.puts(mkconfig_output)
      fh.flush
    end
  end

  configs
end

.munge_grubby_value(value, flavor, grubby_info) ⇒ Object

Take care of copying ‘:default:’ values and ensure that the leading ‘boot’ entries are stripped off of passed entries.



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 118

def self.munge_grubby_value(value, flavor, grubby_info)
  if value == ':default:'
    raise Puppet::Error, "No default GRUB information found for `#{flavor}`" if grubby_info.empty? || !grubby_info[flavor]

    value = grubby_info[flavor]

    # In some cases, /boot gets shoved on by GRUB and we can't compare againt
    # that.
    value = value.split('/')
    value.delete_at(1) if value[1] == 'boot'

    value = value.join('/')
  end

  value
end

.munge_options(system_opts, new_opts, default_opts = []) ⇒ Array

Return a merge of the system options and the new options.

The following format is supported for the new options ‘:defaults:’ => Copy defaults from the default GRUB entry ‘:preserve:’ => Preserve all existing options (if present)

‘:defaults:’ and ‘:preserve:’ are mutually exclusive!

All of the options below supersede any items affected by the above

‘entry(=.*)?’ => Ensure that ‘entry` exists *as entered*; replaces all

other options with the same name

‘!entry(=.*)? => Add this option to the end of the arguments,

preserving any other options of the same name

‘-:entry’ => Ensure that all instances of ‘entry` do not exist ’-:entry=foo’ => Ensure that only instances of ‘entry` with value `foo` do not exist

Parameters:

  • system_opts (Array)

    the current system options for this entry

  • new_opts (Array)

    the new options for this entry

  • default_opts (Array) (defaults to: [])

    the default entry options (if applicable)

Returns:

  • (Array)

    a merged/manipulated array of options



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
107
108
109
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 41

def self.munge_options(system_opts, new_opts, default_opts = [])
  sys_opts = Array(system_opts).flatten.map(&:strip)
  opts     = Array(new_opts).flatten.map(&:strip)
  def_opts = Array(default_opts).flatten.map(&:strip)

  result_opts = []
  result_opts = def_opts.dup if opts.delete(':defaults:')

  if opts.delete(':preserve:')
    # Need to remove any result opts that are being preserved
    sys_opts_keys = sys_opts.map { |x| x.split('=').first.strip }

    result_opts.delete_if do |x|
      key = x.split('=').first.strip

      sys_opts_keys.include?(key)
    end

    result_opts += sys_opts
  end

  # Get rid of everything with a '-:'
  discards = Array(opts.grep(%r{^-:}).map { |x| x[2..-1] })
  opts.delete_if { |x| x =~ %r{^-:} }

  result_opts.delete_if do |x|
    discards.index do |d|
      (d == x) || (d == x.split('=').first)
    end
  end

  # Prepare to append everything with a '!:'
  appends = Array(opts.grep(%r{^!:}).map { |x| x[2..-1] })
  opts.delete_if { |x| x =~ %r{^!:} }

  # We only want to append items that aren't in the list already
  appends.delete_if { |x| result_opts.include?(x) }

  # Replace these items in place if possible
  tmp_results = []
  new_results = []

  opts.each do |opt|
    key = opt.split('=').first

    old_entry = result_opts.index { |x| x.split('=').first == key }

    if old_entry
      # Replace the first instance of a given item with the matching option.
      tmp_results[old_entry] = opt
      result_opts.map! { |x| nil if x.split('=').first == key }
    else
      # Keep track of everything that we aren't replacing
      new_results << opt
    end
  end

  # Copy in all of the remaining options in place
  result_opts.each_index do |i|
    tmp_results[i] = result_opts[i] if result_opts[i]
  end

  # Ensure that we're not duplicating arguments
  (tmp_results.compact + new_results + appends)
    .flatten
    .join(' ')
    .scan(%r{\S+=(?:(?:".+?")|(?:\S+))|\S+})
    .uniq
end

.munged_options(old_opts, new_opts, default_kernel, default_kernel_opts, prepend_kernel_path = false) ⇒ Array[String]

Return a list of options that have the kernel path prepended and are formatted with all processing arguments handled.

Parameters:

  • old_opts (Array[String])

    An array of all old options

  • new_opts (Array[String])

    An array of all new options

  • default_kernel (String)

    The default kernel

  • default_kernel_opts (Array[String])

    The default kernel options

  • prepend_kernel_path (Boolean) (defaults to: false)

    If true, add the kernel itself to the default kernel options

Returns:

  • (Array[String])

    An Array of processed options



239
240
241
242
243
244
245
246
247
248
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 239

def self.munged_options(old_opts, new_opts, default_kernel, default_kernel_opts, prepend_kernel_path = false)
  # You need to prepend the kernel path for the defaults if you're trying to
  # format for `module` lines.

  default_kernel_opts = Array(default_kernel_opts)

  default_kernel_opts = Array(default_kernel) + default_kernel_opts if default_kernel && prepend_kernel_path

  munge_options(old_opts, new_opts, default_kernel_opts)
end

.os_nameString

Return the name of the current operating system or an empty string if not found.

Returns:

  • (String)

    The current operating system name



139
140
141
142
143
144
145
146
# File 'lib/puppetx/augeasproviders_grub/util.rb', line 139

def self.os_name
  # The usual fact
  (Facter.value(:os) && Facter.value(:os)['name']) ||
    # Legacy support
    Facter.value(:operatingsystem) ||
    # Fallback
    ''
end