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

yast / yast-bootloader / 22092103015

17 Feb 2026 09:00AM UTC coverage: 86.728% (-0.04%) from 86.771%
22092103015

push

github

schubi2
test

0 of 5 new or added lines in 1 file covered. (0.0%)

1 existing line in 1 file now uncovered.

3496 of 4031 relevant lines covered (86.73%)

12.79 hits per line

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

65.63
/src/lib/bootloader/bootloader_factory.rb
1
# frozen_string_literal: true
2

3
require "yast"
1✔
4
require "bootloader/sysconfig"
1✔
5
require "bootloader/none_bootloader"
1✔
6
require "bootloader/grub2"
1✔
7
require "bootloader/grub2efi"
1✔
8
require "bootloader/grub2bls"
1✔
9
require "bootloader/systemdboot"
1✔
10
require "bootloader/exceptions"
1✔
11
require "y2storage/disk_analyzer"
1✔
12

13
Yast.import "Arch"
1✔
14
Yast.import "Mode"
1✔
15
Yast.import "ProductFeatures"
1✔
16

17
module Bootloader
1✔
18
  # Factory to get instance of bootloader
19
  class BootloaderFactory
1✔
20
    SUPPORTED_BOOTLOADERS = [
1✔
21
      "none", # allows user to manage bootloader itself
22
      "grub2",
23
      "grub2-efi"
24
    ].freeze
25

26
    # Keyword used in autoyast for default bootloader used for given system.
27
    DEFAULT_KEYWORD = "default"
1✔
28
    SYSTEMDBOOT = "systemd-boot"
1✔
29
    GRUB2BLS = "grub2-bls"
1✔
30

31
    class << self
1✔
32
      include Yast::Logger
1✔
33

34
      attr_writer :current
1✔
35

36
      def proposed
1✔
37
        bootloader_by_name(proposed_name)
×
38
      end
39

40
      def system
1✔
41
        sysconfig_name = Sysconfig.from_system.bootloader
21✔
42
        return nil unless sysconfig_name
21✔
43

44
        bootloader_by_name(sysconfig_name)
2✔
45
      end
46

47
      def current
1✔
48
        @current ||= (system || proposed)
456✔
49
      end
50

51
      def current_name=(name)
1✔
52
        @current = bootloader_by_name(name)
246✔
53
      end
54

55
      def clear_cache
1✔
56
        @cached_bootloaders = nil
221✔
57
      end
58

59
      def supported_names
1✔
60
        if Yast::Mode.config
18✔
61
          # default means bootloader use what it think is the best
62
          result = BootloaderFactory::SUPPORTED_BOOTLOADERS.clone
×
63
          result << GRUB2BLS if use_grub2_bls?
×
64
          result << SYSTEMDBOOT if use_systemd_boot?
×
65
          result << DEFAULT_KEYWORD
×
66
          return result
×
67
        end
68

69
        begin
70
          system_bl = system.name
18✔
71
        # rescue exception if system one is not support
72
        rescue StandardError
73
          system_bl = nil
18✔
74
        end
75
        ret = system_bl ? [system.name] : [] # use current as first
18✔
76
        # grub2 everywhere except aarch64 or riscv64
77
        ret << "grub2" unless Systeminfo.efi_mandatory?
18✔
78
        ret << "grub2-efi" if Systeminfo.efi_supported?
18✔
79
        ret << GRUB2BLS if use_grub2_bls?
18✔
80
        ret << SYSTEMDBOOT if use_systemd_boot?
18✔
81
        ret << "none"
18✔
82
        # avoid double entry for selected one
83
        ret.uniq
18✔
84
      end
85

86
      # rubocop:disable Metrics/CyclomaticComplexity
87
      def bootloader_by_name(name)
1✔
88
        # needed to be able to store settings when moving between bootloaders
89
        @cached_bootloaders ||= {}
267✔
90
        case name
267✔
91
        when "grub2"
92
          @cached_bootloaders["grub2"] ||= Grub2.new
181✔
93
        when "grub2-efi"
94
          @cached_bootloaders["grub2-efi"] ||= Grub2EFI.new
12✔
95
        when "systemd-boot"
96
          @cached_bootloaders["systemd-boot"] ||= SystemdBoot.new
60✔
97
        when "grub2-bls"
98
          @cached_bootloaders["grub2-bls"] ||= Grub2Bls.new
4✔
99
        when "none"
100
          @cached_bootloaders["none"] ||= NoneBootloader.new
8✔
101
        when String
102
          raise UnsupportedBootloader, name
1✔
103
        else
104
          log.error "Factory receive nil name"
1✔
105

106
          nil # in other cases it means that read failed
1✔
107
        end
108
      end
109
    # rubocop:enable Metrics/CyclomaticComplexity
110

111
    private
1✔
112

113
      def use_systemd_boot?
1✔
114
        # only these architectures are supported.
115
        Yast::ProductFeatures.GetBooleanFeature("globals", "enable_systemd_boot") &&
18✔
116
          (Yast::Arch.x86_64 ||
16✔
117
           Yast::Arch.aarch64 ||
118
           Yast::Arch.arm ||
119
           Yast::Arch.riscv64)
120
      end
121

122
      def use_grub2_bls?
1✔
123
        # only these architectures are supported.
124
        (Yast::Arch.x86_64 ||
18✔
125
         Yast::Arch.aarch64 ||
126
         Yast::Arch.arm ||
127
         Yast::Arch.riscv64)
128
      end
129

130
      def grub2_efi_installable?
1✔
131
        Systeminfo.efi_mandatory? ||
×
132
          ((Yast::Arch.x86_64 || Yast::Arch.i386) && Systeminfo.efi?)
×
133
      end
134

135
      def bls_installable?
1✔
136
        #      staging = Y2Storage::StorageManager.instance.staging
137
        #      staging.disk_devices.each_with_index do |disk, index|
138
        #        add_mapping("hd#{index}", disk.name)
139
        #      end
140
        #      Y2Storage::StorageManager.instance.system
141
        #      devicegraph.find_by_any_name
142
        #
143
        #     fs = filesystems
144
        # efi_partition = fs.find { |f| f.mount_path == "/boot/efi" }
145
        #
146
        #      disks = Yast::BootStorage.stage1_disks_for(efi_partition)
147
        # set only gpt disks
148
        #        disks.select! { |disk| disk.gpt? }
149
        #       pmbr_setup(*disks.map(&:name), action)
150
        #
151
        #        @boot_objects = Yast::BootStorage.boot_partitions
152
        #        @boot_devices = @boot_objects.map(&:name)
153
        #        Yast::BootStorage.boot_filesystem
154
        #        fs = Yast::BootStorage.boot_filesystem
155

156
        # no boot assigned
157
        #      return false unless fs
158
        #      return false unless fs.is?(:blk_filesystem)
159
        # cannot install stage one to xfs as it doesn't have reserved space (bnc#884255)
160
        #      return false if fs.type == ::Y2Storage::Filesystems::Type::XFS
161

162
        #        parts = fs.blk_devices
163

164
        #        parts.each_with_object([]) do |part, result|
165
        #          log.info("xxxxxx #{part.inspect} #{result.inspect})")
166
        #        end
167

168
        #        staging = Y2Storage::StorageManager.instance.staging
169
        #        staging.filesystems.each do |d|
170
        #          log.info("yyyyy #{d.inspect} #{d.mount_path}")
171
        #        end
172
        staging = Y2Storage::StorageManager.instance.staging
×
173
        log.info("yyyyy #{staging.inspect}")
×
174
        Y2Storage::MountPoint.all(staging).each { |m|
×
175
          log.info("  yyyyy #{m.path}")
×
176
          log.info("  yyyyy #{m.mount_by}")
×
177
        }
178
        log.info("yyyyyyyyy11 #{staging.disks.inspect}")
×
179
        log.info("yyyyyyyyy #{staging.devices.inspect}")
×
180
        log.info("yyyyyyyyy #{staging.actiongraph.print_graph}")
×
181
        log.info("yyyyyyyyy #{staging.actiongraph.commit_actions_as_strings}")
×
182
        log.info("yyyyyyyyy #{staging.actiongraph.compound_actions}")
×
183
        d_ana = Y2Storage::DiskAnalyzer.new(staging)
×
184
        d_ana.installed_systems().each { |d|
×
NEW
185
          log.info("yyyyinstalled system: #{d}")
×
186
        }
NEW
187
        d_ana.windows_partitions().each { |d|
×
NEW
188
          log.info("yyywindows system: #{d}")
×
189
        }
NEW
190
        d_ana.linux_partitions().each { |d|
×
NEW
191
          log.info("yyylinux system: #{d}")
×
192
        }        
193
        
UNCOV
194
        ((Yast::Arch.x86_64 ||
×
195
          Yast::Arch.i386 ||
196
          Yast::Arch.aarch64 ||
197
          Yast::Arch.arm ||
198
          Yast::Arch.riscv64) && Systeminfo.efi?)
199
      end
200

201
      def proposed_name
1✔
202
        preferred_bootloader = Yast::ProductFeatures.GetStringFeature("globals",
×
203
          "preferred_bootloader")
204
        if supported_names.include?(preferred_bootloader) &&
×
205
            !["grub2-efi", "systemd-boot", "grub2-bls"].include?(preferred_bootloader)
206
          return preferred_bootloader
×
207
        end
208

209
        if bls_installable? && ["systemd-boot", "grub2-bls"].include?(preferred_bootloader)
×
210
          return preferred_bootloader
×
211
        end
212

213
        return "grub2-efi" if grub2_efi_installable?
×
214

215
        "grub2" # grub2 works(c) everywhere
×
216
      end
217
    end
218
  end
219
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