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

#grub_default, #password, #pmbr_action, #sections

Instance Method Summary (collapse)

Methods inherited from Grub2Base

#disable_serial_console, #enable_serial_console, #pmbr_setup

Methods inherited from BootloaderBase

#proposed?, #read?, #write_sysconfig

Constructor Details

- (Grub2) initialize

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

- (Object) device_map (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

- (Object) stage1 (readonly)

Returns the value of attribute stage1



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

def stage1
  @stage1
end

Instance Method Details

- (Object) merge(other)



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'src/lib/bootloader/grub2.rb', line 84

def merge(other)
  super

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

  # merge here is a bit tricky, as for stage1 does not exist `defined?`
  # because grub_installdevice contain value or not, so it is not
  # possible to recognize if chosen or just not set
  # so logic is following
  # 1) if any flag is set to true, then use it because e.g. autoyast defined flags,
  #    but devices usually not
  # 2) if there is devices specified, then set also flags to value in other
  #    as it mean, that there is enough info to decide
  log.info "stage1 to merge #{other.stage1.inspect}"

  # so first part of logic
  stage1.activate = stage1.activate? || other.stage1.activate?
  stage1.generic_mbr = stage1.generic_mbr? || other.stage1.generic_mbr?

  # use second part described above if there is some device
  replace_with(other) unless other.stage1.devices.empty?

  log.info "stage1 after merge #{stage1.inspect}"
end

- (Object) name



138
139
140
# File 'src/lib/bootloader/grub2.rb', line 138

def name
  "grub2"
end

- (Object) packages



142
143
144
145
146
147
148
149
150
151
152
153
# File 'src/lib/bootloader/grub2.rb', line 142

def packages
  res = super

  res << "grub2"

  if stage1.generic_mbr?
    # needed for generic _mbr binary files
    res << "syslinux"
  end

  res
end

- (Object) propose



74
75
76
77
78
79
80
81
82
# File 'src/lib/bootloader/grub2.rb', line 74

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 if Yast::BootStorage.gpt_boot_disk?
  device_map.propose if Yast::Arch.x86_64 || Yast::Arch.i386
end

- (Object) read(reread: false)

Read settings from disk

Parameters:

  • reread (Boolean)

    boolean true to force reread settings from system



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

def read(reread: false)
  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

- (Object) summary

Display bootloader summary

Returns:

  • a list of summary lines



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'src/lib/bootloader/grub2.rb', line 111

def summary
  result = [
    Yast::Builtins.sformat(
      _("Boot Loader Type: %1"),
      "GRUB2"
    )
  ]
  locations_val = locations
  if !locations_val.empty?
    result << Yast::Builtins.sformat(
      _("Status Location: %1"),
      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)
  result << url_location_summary if !Yast::Arch.ppc && !Yast::Arch.s390 && !Yast::Mode.config

  order_sum = disk_order_summary
  result << order_sum if order_sum

  result
end

- (Boolean) write

Write bootloader settings to disk

Returns:

  • (Boolean)

    true on success



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'src/lib/bootloader/grub2.rb', line 57

def write
  # 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
  stage1.write

  # TODO: own class handling PBMR
  pmbr_setup(*gpt_disks_devices)

  # powernv must not call grub2-install (bnc#970582)
  @grub_install.execute(devices: stage1.devices) unless Yast::Arch.board_powernv
  # 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
end