lib/cfa/grub2/device_map.rb
# frozen_string_literal: true
require "cfa/base_model"
require "cfa/augeas_parser"
require "cfa/placer"
require "cfa/matcher"
module CFA
module Grub2
# Represents grub device map in /boot/grub2/device_map
# for details see https://www.gnu.org/software/grub/manual/html_node/Device-map.html
# Main features:
#
# - Do not overwrite files
# - When setting value first try to just change value if key already exists
# - When grub key is not there, then add to file
# - checks and raise exception if number of mappings exceed limit 8.
# Limitation is caused by BIOS Int 13 used by grub2 for selecting boot
# device.
class DeviceMap < BaseModel
PATH = "/boot/grub2/device.map"
def initialize(file_handler: nil)
super(AugeasParser.new("device_map.lns"), PATH,
file_handler: file_handler)
end
def save
raise "Too many grub devices. Limit is 8." if grub_devices.size > 8
super
end
# @return [String] grub device name for given system device
def grub_device_for(system_dev)
matcher = Matcher.new(value_matcher: system_dev)
entry = data.select(matcher)
entry.empty? ? nil : entry.first[:key]
end
# @return [String] system device name for given grub device
def system_device_for(grub_device)
data[grub_device]
end
# Appends to configuration mapping between grub_device and system_device
# @note if mapping for given grub device is already defined, it will be
# overwritten
def add_mapping(grub_device, system_device)
generic_set(grub_device, system_device)
end
# Removes mapping for given grub device
def remove_mapping(grub_device)
data.delete(grub_device)
end
# @return [Array<String>] list of all grub devices which have mapping.
# If there is no mapping, then it return empty list.
def grub_devices
matcher = Matcher.new { |k, _v| k !~ /comment/ }
entries = data.select(matcher)
entries.map { |e| e[:key] }
end
end
end
end