Class: Bootloader::Grub2

Inherits:
Grub2Base show all
Defined in:
src/lib/bootloader/grub2.rb

Overview

Represents non-EFI variant of GRUB2

Instance Attribute Summary collapse

Attributes inherited from Grub2Base

#console, #grub_default, #password, #pmbr_action, #sections, #secure_boot, #stage1, #trusted_boot, #update_nvram

Instance Method Summary collapse

Methods inherited from Grub2Base

#cpu_mitigations, #cpu_mitigations=, #disable_serial_console, #enable_serial_console, #explicit_cpu_mitigations, #include_os_prober_package?, #pmbr_setup, #serial_console?

Methods inherited from BootloaderBase

#prepare, #proposed?, #read?

Constructor Details

#initializeGrub2

Returns a new instance of Grub2.



21
22
23
24
25
26
27
28
# File 'src/lib/bootloader/grub2.rb', line 21

def initialize
  super

  textdomain "bootloader"
  @stage1 = Stage1.new
  @grub_install = GrubInstall.new(efi: false)
  @device_map = DeviceMap.new
end

Instance Attribute Details

#device_mapObject (readonly)

Returns the value of attribute device_map.



19
20
21
# File 'src/lib/bootloader/grub2.rb', line 19

def device_map
  @device_map
end

Instance Method Details

#merge(other) ⇒ Object



94
95
96
97
98
99
100
# File 'src/lib/bootloader/grub2.rb', line 94

def merge(other)
  super

  @device_map = other.device_map if !other.device_map.empty?

  stage1.merge(other.stage1)
end

#nameObject



135
136
137
# File 'src/lib/bootloader/grub2.rb', line 135

def name
  "grub2"
end

#packagesObject



139
140
141
142
143
144
145
# File 'src/lib/bootloader/grub2.rb', line 139

def packages
  res = super
  res << "grub2"
  res << "syslinux" if include_syslinux_package?
  res << "trustedgrub2" << "trustedgrub2-i386-pc" if include_trustedgrub2_packages?
  res
end

#proposeObject



83
84
85
86
87
88
89
90
91
92
# File 'src/lib/bootloader/grub2.rb', line 83

def propose
  super

  stage1.propose
  # for GPT add protective MBR flag otherwise some systems won't
  # boot, safer option for legacy booting (bnc#872054)
  self.pmbr_action = :add
  log.info "proposed pmbr_action #{pmbr_action}."
  device_map.propose if Yast::Arch.x86_64 || Yast::Arch.i386
end

#readObject

Read settings from disk, overwritting already set values



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'src/lib/bootloader/grub2.rb', line 31

def read
  super

  begin
    stage1.read
  rescue Errno::ENOENT
    # grub_installdevice is not part of grub2 rpm, so it doesn't need to exist.
    # In such case ignore exception and use empty @stage1
    log.info "grub_installdevice does not exist. Using empty one."
    @stage1 = Stage1.new
  end

  begin
    # device map is needed only for legacy boot on intel
    device_map.read if Yast::Arch.x86_64 || Yast::Arch.i386
  rescue Errno::ENOENT
    # device map is only optional part of grub2, so it doesn't need to exist.
    # In such case ignore exception and use empty device map
    log.info "grub2/device.map does not exist. Using empty one."
    @device_map = DeviceMap.new
  end
end

#summary(simple_mode: false) ⇒ Object

Display bootloader summary

Returns:

  • a list of summary lines



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'src/lib/bootloader/grub2.rb', line 104

def summary(simple_mode: false)
  result = [
    Yast::Builtins.sformat(
      _("Boot Loader Type: %1"),
      "GRUB2"
    )
  ]

  result.concat(boot_flags_summary)

  locations_val = locations
  if !locations_val.empty?
    result << format(
      _("Write Boot Code To: %s"),
      locations_val.join(", ")
    )
  end

  # it is necessary different summary for autoyast and installation
  # other mode than autoyast on running system
  # both ppc and s390 have special devices for stage1 so it do not make sense
  # allow change of location to MBR or boot partition (bnc#879107)
  no_location = simple_mode || Yast::Arch.ppc || Yast::Arch.s390 || Yast::Mode.config
  result << url_location_summary unless no_location

  order_sum = disk_order_summary
  result << order_sum unless order_sum.empty?

  result
end

#write(etc_only: false) ⇒ Boolean

Write bootloader settings to disk

Returns:

  • (Boolean)

    true on success



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
# File 'src/lib/bootloader/grub2.rb', line 56

def write(etc_only: false)
  # super have to called as first as grub install require some config writen in ancestor
  super

  device_map.write if (Yast::Arch.x86_64 || Yast::Arch.i386) && !etc_only

  # TODO: own class handling PBMR
  # set it only for gpt disk bsc#1008092
  pmbr_setup(*::Yast::BootStorage.gpt_disks(stage1.devices))

  # powernv must not call grub2-install (bnc#970582)
  if !Yast::Arch.board_powernv
    if !etc_only
      failed = @grub_install.execute(
        devices: stage1.devices, secure_boot: secure_boot, trusted_boot: trusted_boot,
        update_nvram: update_nvram
      )
      failed.each { |f| stage1.remove_device(f) }
    end
    # write stage1 location
    stage1.write
  end
  # Do some mbr activations ( s390 do not have mbr nor boot flag on its disks )
  # powernv do not have prep partition, so we do not have any partition to activate (bnc#970582)
  MBRUpdate.new.run(stage1) if !Yast::Arch.s390 && !Yast::Arch.board_powernv && !etc_only
end

#write_sysconfig(prewrite: false) ⇒ Object

FIXME: refactor with injection like super(prewrite: prewrite, sysconfig = ...) overwrite BootloaderBase version to save trusted boot



149
150
151
152
153
154
155
# File 'src/lib/bootloader/grub2.rb', line 149

def write_sysconfig(prewrite: false)
  sysconfig = Bootloader::Sysconfig.new(
    bootloader: name, secure_boot: secure_boot, trusted_boot: trusted_boot,
    update_nvram: update_nvram
  )
  prewrite ? sysconfig.pre_write : sysconfig.write
end