• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

yast / yast-bootloader / 14857311768

06 May 2025 10:23AM UTC coverage: 87.382% (-0.04%) from 87.417%
14857311768

Pull #716

github

schubi2
added alias for Agama
Pull Request #716: Unifying Bootloader Options for systemd-boot and grub2-bls

93 of 120 new or added lines in 10 files covered. (77.5%)

6 existing lines in 1 file now uncovered.

3435 of 3931 relevant lines covered (87.38%)

12.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.82
/src/lib/bootloader/generic_widgets.rb
1
# frozen_string_literal: true
2

3
require "yast"
1✔
4

5
require "bootloader/bootloader_factory"
1✔
6
require "bootloader/cpu_mitigations"
1✔
7

8
require "cwm/widget"
1✔
9

10
Yast.import "UI"
1✔
11
Yast.import "Popup"
1✔
12

13
module Bootloader
1✔
14
  # Widget to switch between all supported bootloaders
15
  class LoaderTypeWidget < CWM::ComboBox
1✔
16
    def initialize
1✔
17
      textdomain "bootloader"
8✔
18

19
      super
8✔
20
    end
21

22
    def label
1✔
23
      textdomain "bootloader"
1✔
24

25
      _("&Boot Loader")
1✔
26
    end
27

28
    def init
1✔
29
      self.value = BootloaderFactory.current.name
×
30
    end
31

32
    def opt
1✔
33
      [:notify]
2✔
34
    end
35

36
    def items
1✔
37
      BootloaderFactory.supported_names.map do |name|
2✔
38
        [name, localized_names(name)]
10✔
39
      end
40
    end
41

42
    def localized_names(name)
1✔
43
      names = {
44
        "grub2"        => _("GRUB2"),
10✔
45
        "grub2-efi"    => _("GRUB2 for EFI"),
46
        # Translators: Using Boot Loader Specification (BLS) snippets.
47
        "grub2-bls"    => _("GRUB2 with BLS"),
48
        "systemd-boot" => _("Systemd Boot"),
49
        # Translators: option in combo box when bootloader is not managed by yast2
50
        "none"         => _("Not Managed"),
51
        "default"      => _("Default")
52
      }
53

54
      names[name] or raise "Unknown supported bootloader '#{name}'"
10✔
55
    end
56

57
    def handle
1✔
58
      old_bl = BootloaderFactory.current.name
1✔
59
      new_bl = value
1✔
60

61
      return nil if old_bl == new_bl
1✔
62

63
      if new_bl == "none"
1✔
64
        # popup - Continue/Cancel
65
        popup_msg = _(
×
66
          "\n" \
67
          "If you do not install any boot loader, the system\n" \
68
          "might not start.\n" \
69
          "\n" \
70
          "Proceed?\n"
71
        )
72

73
        return :redraw if !Yast::Popup.ContinueCancel(popup_msg)
×
74
      end
75

76
      if !Yast::Stage.initial && ["systemd-boot", "grub2-bls"].include?(old_bl)
1✔
77
        Yast::Popup.Warning(format(_(
×
78
        "Switching from %s to another bootloader\n" \
79
        "is currently not supported.\n"
80
      ), old_bl))
81
        return :redraw
×
82
      end
83

84
      if !Yast::Stage.initial && ["systemd-boot", "grub2-bls"].include?(new_bl)
1✔
85
        Yast::Popup.Warning(format(_(
×
86
        "Switching to bootloader %s \n" \
87
        "is currently not supported.\n"
88
      ), new_bl))
89
        return :redraw
×
90
      end
91

92
      BootloaderFactory.current_name = new_bl
1✔
93
      BootloaderFactory.current.propose
1✔
94

95
      :redraw
1✔
96
    end
97

98
    def help
1✔
99
      _(
1✔
100
        "<p><b>Boot Loader</b>\n" \
101
        "specifies which boot loader to install. Can be also set to <tt>None</tt> " \
102
        "which means that the boot loader configuration is not managed by YaST and also " \
103
        "the kernel post install script does not update the boot loader configuration."
104
      )
105
    end
106
  end
107

108
  # represent choosing default section to boot
109
  class DefaultSectionWidget < CWM::ComboBox
1✔
110
    def initialize
1✔
111
      textdomain "bootloader"
7✔
112

113
      super
7✔
114
    end
115

116
    def label
1✔
117
      _("&Default Boot Section")
1✔
118
    end
119

120
    def help
1✔
121
      _(
1✔
122
        "<p><b>Default Boot Section</b> selects the default section for booting.\n" \
123
        " If sections are not generated yet ( e.g. during installation) \n" \
124
        "then the box is empty and the default is picked by grub2 itself.</p>\n"
125
      )
126
    end
127

128
    def init
1✔
129
      self.value = Bootloader::BootloaderFactory.current.sections.default
1✔
130
    end
131

132
    def items
1✔
133
      Bootloader::BootloaderFactory.current.sections.all.map do |section|
1✔
134
        [section, section]
2✔
135
      end
136
    end
137

138
    def store
1✔
139
      Bootloader::BootloaderFactory.current.sections.default = value
1✔
140
    end
141
  end
142

143
  # Represents switcher for secure boot on EFI
144
  class SecureBootWidget < CWM::CheckBox
1✔
145
    def initialize
1✔
146
      textdomain "bootloader"
5✔
147

148
      super
5✔
149
    end
150

151
    def label
1✔
152
      _("&Secure Boot Support")
1✔
153
    end
154

155
    def help
1✔
156
      if Yast::Arch.s390
1✔
NEW
157
        _(
×
158
          "<p><b>Secure Boot Support</b> if checked enables Secure Boot support.<br>" \
159
          "This does not turn on secure booting. " \
160
          "It only switches to the new secure-boot enabled boot data format. " \
161
          "Note that this new format works only on z15 or later and "\
162
          "only for some disk types. " \
163
          "For more details see the requirements at  " \
164
          "https://www.ibm.com/docs/en/linux-on-systems?topic=introduction-requirements</p>"
165
        )
166
      else
167
        _(
1✔
168
          "<p><b>Secure Boot Support</b> if checked enables Secure Boot support.<br>" \
169
          "This does not turn on secure booting. " \
170
          "It only sets up the boot loader in a way that supports secure booting. " \
171
          "You still have to enable Secure Boot in the UEFI Firmware.</p> "
172
        )
173
      end
174
    end
175

176
    def init
1✔
177
      self.value = Bootloader::BootloaderFactory.current.secure_boot
1✔
178
    end
179

180
    def store
1✔
181
      Bootloader::BootloaderFactory.current.secure_boot = value
1✔
182
    end
183

184
    def validate
1✔
NEW
185
      return true if Yast::Mode.config ||
×
186
        !Yast::Arch.s390 ||
187
        !value ||
188
        value == Systeminfo.secure_boot_active?
189

NEW
190
      Yast::Popup.ContinueCancel(
×
191
        # text is identical like one in proposal client. Keep in sync!
192
        # TRANSLATORS: IPL stands for Initial Program Load, IBM speak for system boot
193
        _(
194
          "Secure boot IPL has the following minimum system requirements,\n" \
195
          "depending on the boot device to be IPLed:\n" \
196
          "NVMe disk: IBM LinuxONE III or newer.\n" \
197
          "FC-attached SCSI disk: IBM LinuxONE III, IBM z15 or newer.\n" \
198
          "ECKD DASD with CDL layout: IBM z16, LinuxONE 4 or newer.\n" \
199
          "If these requirements are not met, the system can be IPLed in non-secure mode only."
200
        )
201
      )
202
    end
203
  end
204

205
  # Represents decision if smt is enabled
206
  class CpuMitigationsWidget < CWM::ComboBox
1✔
207
    def initialize
1✔
208
      textdomain "bootloader"
22✔
209

210
      super
22✔
211
    end
212

213
    def label
1✔
214
      _("CPU Mitigations")
4✔
215
    end
216

217
    def items
1✔
218
      ::Bootloader::CpuMitigations::ALL.map do |m|
4✔
219
        [m.value.to_s, m.to_human_string]
16✔
220
      end
221
    end
222

223
    def help
1✔
224
      _(
4✔
225
        "<p><b>CPU Mitigations</b><br>\n" \
226
        "The option selects which default settings should be used for CPU \n" \
227
        "side channels mitigations. A highlevel description is on our Technical Information \n" \
228
        "Document TID 7023836. Following options are available:<ul>\n" \
229
        "<li><b>Auto</b>: This option enables all the mitigations needed for your CPU model. \n" \
230
        "This setting can impact performance to some degree, depending on CPU model and \n" \
231
        "workload. It provides all security mitigations, but it does not protect against \n" \
232
        "cross-CPU thread attacks.</li>\n" \
233
        "<li><b>Auto + No SMT</b>: This option enables all the above mitigations in \n" \
234
        "\"Auto\", and also disables Simultaneous Multithreading to avoid \n" \
235
        "side channel attacks across multiple CPU threads. This setting can \n" \
236
        "further impact performance, depending on your \n" \
237
        "workload. This setting provides the full set of available security mitigations.</li>\n" \
238
        "<li><b>Off</b>: All CPU Mitigations are disabled. This setting has no performance \n" \
239
        "impact, but side channel attacks against your CPU are possible, depending on CPU \n" \
240
        "model.</li>\n" \
241
        "<li><b>Manual</b>: This setting does not specify a mitigation level and leaves \n" \
242
        "this to be the kernel default. The administrator can add other mitigations options \n" \
243
        "in the <i>kernel command line</i> widget.\n" \
244
        "All CPU mitigation specific options can be set manually.</li></ul></p>"
245
      )
246
    end
247

248
    def init
1✔
249
      if Bootloader::BootloaderFactory.current.respond_to?(:cpu_mitigations)
2✔
250
        self.value = Bootloader::BootloaderFactory.current.cpu_mitigations.value.to_s
×
251
      else
252
        disable
2✔
253
      end
254
    end
255

256
    def store
1✔
257
      return unless enabled?
2✔
258

259
      Bootloader::BootloaderFactory.current.cpu_mitigations =
×
260
        ::Bootloader::CpuMitigations.new(value.to_sym)
261
    end
262
  end
263

264
  # Represents Protective MBR action
265
  class PMBRWidget < CWM::ComboBox
1✔
266
    def initialize
1✔
267
      textdomain "bootloader"
5✔
268

269
      super
5✔
270
    end
271

272
    def label
1✔
273
      _("&Protective MBR flag")
×
274
    end
275

276
    def help
1✔
277
      _(
×
278
        "<p><b>Protective MBR flag</b> is expert only settings, that is needed " \
279
        "only on exotic hardware. For details see Protective MBR in GPT disks. " \
280
        "Do not touch if you are not sure.</p>"
281
      )
282
    end
283

284
    def init
1✔
285
      current_bl = ::Bootloader::BootloaderFactory.current
1✔
286
      if current_bl.respond_to?(:pmbr_action)
1✔
287
        self.value = current_bl.pmbr_action
1✔
288
      else
289
        log.error("Bootloader #{current_bl} does not support PMBR.")
×
290
        disable
×
291
      end
292
    end
293

294
    def items
1✔
295
      [
296
        # TRANSLATORS: set flag on disk
297
        [:add, _("set")],
1✔
298
        # TRANSLATORS: remove flag from disk
299
        [:remove, _("remove")],
300
        # TRANSLATORS: do not change flag on disk
301
        [:nothing, _("do not change")]
302
      ]
303
    end
304

305
    def store
1✔
306
      current_bl = ::Bootloader::BootloaderFactory.current
1✔
307
      if current_bl.respond_to?(:pmbr_action)
1✔
308
        current_bl.pmbr_action = value
1✔
309
      else
310
        log.error("Bootloader #{current_bl} does not support PMBR.")
×
311
      end
312
    end
313
  end
314

315
  # represents kernel command line
316
  class KernelAppendWidget < CWM::InputField
1✔
317
    def initialize
1✔
318
      textdomain "bootloader"
10✔
319

320
      super
10✔
321
    end
322

323
    def label
1✔
324
      _("O&ptional Kernel Command Line Parameter")
2✔
325
    end
326

327
    def help
1✔
328
      _(
2✔
329
        "<p><b>Optional Kernel Command Line Parameter</b> lets you define " \
330
        "additional parameters to pass to the kernel.</p>"
331
      )
332
    end
333

334
    def init
1✔
335
      current_bl = ::Bootloader::BootloaderFactory.current
2✔
336
      case current_bl
2✔
337
      when ::Bootloader::SystemdBoot
338
        self.value = current_bl.kernel_params.serialize.gsub(/mitigations=\S+/, "")
1✔
339
      when ::Bootloader::Grub2Base
340
        self.value = current_bl.grub_default.kernel_params.serialize.gsub(/mitigations=\S+/, "")
1✔
341
      else
342
        disable
×
343
      end
344
    end
345

346
    def store
1✔
347
      return unless enabled?
2✔
348

349
      current_bl = ::Bootloader::BootloaderFactory.current
2✔
350
      case current_bl
2✔
351
      when ::Bootloader::SystemdBoot
352
        current_bl.kernel_params.replace(value)
1✔
353
      when ::Bootloader::Grub2Base
354
        current_bl.grub_default.kernel_params.replace(value)
1✔
355
      else
356
        log.error("Bootloader type #{current_bl} not found.")
×
357
      end
358
    end
359
  end
360
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc