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

yast / yast-bootloader / 12048550996

27 Nov 2024 10:37AM UTC coverage: 87.484% (+0.1%) from 87.378%
12048550996

Pull #708

github

schubi2
cleanup
Pull Request #708: Supporting Grub2-BLS

210 of 240 new or added lines in 13 files covered. (87.5%)

88 existing lines in 7 files now uncovered.

3362 of 3843 relevant lines covered (87.48%)

13.0 hits per line

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

92.52
/src/lib/bootloader/systemdboot.rb
1
# frozen_string_literal: true
2

3
require "fileutils"
1✔
4
require "yast"
1✔
5
require "bootloader/sysconfig"
1✔
6
require "bootloader/cpu_mitigations"
1✔
7
require "bootloader/bls"
1✔
8
require "cfa/grub2/default"
1✔
9

10
Yast.import "Report"
1✔
11
Yast.import "Arch"
1✔
12
Yast.import "ProductFeatures"
1✔
13
Yast.import "BootStorage"
1✔
14
Yast.import "Stage"
1✔
15

16
module Bootloader
1✔
17
  # Represents systemd bootloader with efi target
18
  class SystemdBoot < BootloaderBase
1✔
19
    include Yast::Logger
1✔
20
    include Yast::I18n
1✔
21

22
    CMDLINE = "/etc/kernel/cmdline"
1✔
23

24
    # @!attribute menu_timeout
25
    #   @return [Integer] menu timeout
26
    attr_accessor :menu_timeout
1✔
27

28
    # @!attribute secure_boot
29
    #   @return [Boolean] current secure boot setting
30
    attr_accessor :secure_boot
1✔
31

32
    def initialize
1✔
33
      super
65✔
34

35
      textdomain "bootloader"
65✔
36
      # For kernel parameters we are using the same data structure
37
      # like grub2 in order to be compatible with all calls.
38
      @kernel_container = ::CFA::Grub2::Default.new
65✔
39
      @explicit_cpu_mitigations = false
65✔
40
    end
41

42
    def kernel_params
1✔
43
      @kernel_container.kernel_params
31✔
44
    end
45

46
    # rubocop:disable Metrics/AbcSize
47
    def merge(other)
1✔
48
      log.info "merging: timeout: #{menu_timeout}=>#{other.menu_timeout}"
1✔
49
      log.info "         secure_boot: #{secure_boot}=>#{other.secure_boot}"
1✔
50
      log.info "         mitigations: #{cpu_mitigations.to_human_string}=>" \
1✔
51
               "#{other.cpu_mitigations.to_human_string}"
52
      log.info "         kernel_params: #{kernel_params.serialize}=>" \
1✔
53
               "#{other.kernel_params.serialize}"
54
      super
1✔
55
      self.menu_timeout = other.menu_timeout unless other.menu_timeout.nil?
1✔
56
      self.secure_boot = other.secure_boot unless other.secure_boot.nil?
1✔
57

58
      kernel_serialize = kernel_params.serialize
1✔
59
      # handle specially noresume as it should lead to remove all other resume
60
      kernel_serialize.gsub!(/resume=\S+/, "") if other.kernel_params.parameter("noresume")
1✔
61

62
      # prevent double cpu_mitigations params
63
      kernel_serialize.gsub!(/mitigations=\S+/, "") if other.kernel_params.parameter("mitigations")
1✔
64

65
      new_kernel_params = "#{kernel_serialize} #{other.kernel_params.serialize}"
1✔
66
      # deduplicate identicatel parameter. Keep always the last one ( so reverse is needed ).
67
      new_params = new_kernel_params.split.reverse.uniq.reverse.join(" ")
1✔
68

69
      @kernel_container.kernel_params.replace(new_params)
1✔
70

71
      # explicitly set mitigations means overwrite of our
72
      self.cpu_mitigations = other.cpu_mitigations if other.explicit_cpu_mitigations
1✔
73

74
      log.info "merging result: timeout: #{menu_timeout}"
1✔
75
      log.info "                secure_boot: #{secure_boot}"
1✔
76
      log.info "                mitigations: #{cpu_mitigations.to_human_string}"
1✔
77
      log.info "                kernel_params: #{kernel_params.serialize}"
1✔
78
    end
79
    # rubocop:enable Metrics/AbcSize
80

81
    def cpu_mitigations
1✔
82
      CpuMitigations.from_kernel_params(kernel_params)
6✔
83
    end
84

85
    def explicit_cpu_mitigations
1✔
86
      @explicit_cpu_mitigations ? cpu_mitigations : nil
1✔
87
    end
88

89
    def cpu_mitigations=(value)
1✔
UNCOV
90
      log.info "set mitigations to #{value.to_human_string}"
×
UNCOV
91
      @explicit_cpu_mitigations = true
×
UNCOV
92
      value.modify_kernel_params(kernel_params)
×
93
    end
94

95
    def read
1✔
96
      super
3✔
97

98
      self.menu_timeout = Bls.menu_timeout
3✔
99
      self.secure_boot = Systeminfo.secure_boot_active?
3✔
100

101
      lines = ""
3✔
102
      filename = File.join(Yast::Installation.destdir, CMDLINE)
3✔
103
      if File.exist?(filename)
3✔
104
        File.open(filename).each do |line|
3✔
105
          lines = + line
3✔
106
        end
107
      end
108
      @kernel_container.kernel_params.replace(lines)
3✔
109
    end
110

111
    # Write bootloader settings to disk
112
    def write(etc_only: false)
1✔
113
      super
4✔
114
      log.info("Writing settings...")
4✔
115
      Bls.install_bootloader if Yast::Stage.initial # while new installation only (currently)
4✔
116
      write_kernel_parameter
4✔
117
      Bls.create_menu_entries
4✔
118
      Bls.write_menu_timeout(menu_timeout)
4✔
119

120
      true
4✔
121
    end
122

123
    def propose
1✔
124
      super
3✔
125
      log.info("Propose settings...")
3✔
126
      if @kernel_container.kernel_params.empty?
3✔
127
        kernel_line = Yast::BootArch.DefaultKernelParams(Yast::BootStorage.propose_resume)
3✔
128
        @kernel_container.kernel_params.replace(kernel_line)
3✔
129
      end
130
      self.menu_timeout = Yast::ProductFeatures.GetIntegerFeature("globals", "boot_timeout").to_i
3✔
131
      self.secure_boot = Systeminfo.secure_boot_supported?
3✔
132
    end
133

134
    # Secure boot setting shown in summary screen.
135
    # sdbootutil intialize secure boot if shim has been installed.
136
    #
137
    # @return [String]
138
    def secure_boot_summary
1✔
139
      link = if secure_boot
2✔
UNCOV
140
        "<a href=\"disable_secure_boot\">(#{_("disable")})</a>"
×
141
      else
142
        "<a href=\"enable_secure_boot\">(#{_("enable")})</a>"
2✔
143
      end
144

145
      "#{_("Secure Boot:")} #{status_string(secure_boot)} #{link}"
2✔
146
    end
147

148
    # Display bootloader summary
149
    # @return a list of summary lines
150
    def summary(*)
1✔
151
      result = [
152
        Yast::Builtins.sformat(
2✔
153
          _("Boot Loader Type: %1"),
154
          "Systemd Boot"
155
        )
156
      ]
157
      result << secure_boot_summary if Systeminfo.secure_boot_available?(name)
2✔
158
      result
2✔
159
    end
160

161
    def name
1✔
162
      "systemd-boot"
11✔
163
    end
164

165
    def packages
1✔
166
      res = super
1✔
167
      res << "sdbootutil" << "systemd-boot"
1✔
168

169
      case Yast::Arch.architecture
1✔
170
      when "x86_64"
171
        res << "shim" if secure_boot
1✔
172
      else
UNCOV
173
        log.warn "Unknown architecture #{Yast::Arch.architecture} for systemdboot"
×
174
      end
175

176
      res
1✔
177
    end
178

179
    def delete
1✔
180
      log.warn("is currently not supported")
15✔
181
    end
182

183
    # overwrite BootloaderBase version to save secure boot
184
    def write_sysconfig(prewrite: false)
1✔
UNCOV
185
      sysconfig = Bootloader::Sysconfig.new(bootloader: name,
×
186
        secure_boot: secure_boot, trusted_boot: false,
187
        update_nvram: false)
UNCOV
188
      prewrite ? sysconfig.pre_write : sysconfig.write
×
189
    end
190

191
  private
1✔
192

193
    def write_kernel_parameter
1✔
194
      # writing kernel parameter to /etc/kernel/cmdline
195
      File.open(File.join(Yast::Installation.destdir, CMDLINE), "w+") do |fw|
4✔
196
        if Yast::Stage.initial # while new installation only
4✔
197
          fw.puts("root=#{Yast::BootStorage.root_partitions.first.name} #{kernel_params.serialize}")
4✔
198
        else # root entry is already available
199
          fw.puts(kernel_params.serialize)
×
200
        end
201
      end
202
    end
203
  end
204
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

© 2025 Coveralls, Inc