Skip to content

Commit

Permalink
Merge d83b506 into f8d2764
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Sep 12, 2022
2 parents f8d2764 + d83b506 commit b7cee0e
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 31 deletions.
6 changes: 6 additions & 0 deletions package/yast2-bootloader.changes
@@ -1,3 +1,9 @@
-------------------------------------------------------------------
Mon Sep 12 10:04:01 UTC 2022 - Josef Reidinger <jreidinger@suse.com>

- Allow bootloader to run on transactional systems (bsc#1128853)
- 4.5.4

-------------------------------------------------------------------
Thu Aug 11 13:04:27 UTC 2022 - Steffen Winterfeldt <snwint@suse.com>

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-bootloader.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2-bootloader
Version: 4.5.3
Version: 4.5.4
Release: 0
Summary: YaST2 - Bootloader Configuration
License: GPL-2.0-or-later
Expand Down
4 changes: 3 additions & 1 deletion src/lib/bootloader/bootloader_base.rb
Expand Up @@ -36,7 +36,9 @@ def prepare
end

# writes configuration to target disk
def write; end
# @param etc_only [Boolean] true on transactional systems
# because /boot is read-only there
def write(etc_only: false); end

# reads configuration from target disk
def read
Expand Down
8 changes: 4 additions & 4 deletions src/lib/bootloader/grub2.rb
Expand Up @@ -53,18 +53,18 @@ def read

# Write bootloader settings to disk
# @return [Boolean] true on success
def write
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
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)
unless Yast::Arch.board_powernv
if !Yast::Arch.board_powernv && !etc_only
failed = @grub_install.execute(
devices: stage1.devices, secure_boot: secure_boot, trusted_boot: trusted_boot,
update_nvram: update_nvram
Expand All @@ -74,7 +74,7 @@ def 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
MBRUpdate.new.run(stage1) if !Yast::Arch.s390 && !Yast::Arch.board_powernv && !etc_only
end

def propose
Expand Down
4 changes: 3 additions & 1 deletion src/lib/bootloader/grub2base.rb
Expand Up @@ -134,13 +134,15 @@ def read
self.update_nvram = Systeminfo.update_nvram_active?
end

def write
def write(etc_only: false)
super

log.info "writing /etc/default/grub #{grub_default.inspect}"
grub_default.save
@sections.write
@password.write
return if etc_only

Yast::Execute.on_target("/usr/sbin/grub2-mkconfig", "-o", "/boot/grub2/grub.cfg",
env: systemwide_locale)
end
Expand Down
37 changes: 21 additions & 16 deletions src/lib/bootloader/grub2efi.rb
Expand Up @@ -23,28 +23,17 @@ def initialize
end

# Write bootloader settings to disk
def write
def write(etc_only: false)
# super have to called as first as grub install require some config written in ancestor
super

if pmbr_action
fs = filesystems
efi_partition = fs.find { |f| f.mount_path == "/boot/efi" }
efi_partition ||= fs.find { |f| f.mount_path == "/boot" }
efi_partition ||= fs.find { |f| f.mount_path == "/" }
pmbr_write if pmbr_action

raise "could not find boot partiton" unless efi_partition

disks = Yast::BootStorage.stage1_disks_for(efi_partition)
# set only gpt disks
disks.select! { |disk| disk.gpt? }

pmbr_setup(*disks.map(&:name))
unless etc_only
@grub_install.execute(secure_boot: secure_boot, trusted_boot: trusted_boot,
update_nvram: update_nvram)
end

@grub_install.execute(secure_boot: secure_boot, trusted_boot: trusted_boot,
update_nvram: update_nvram)

true
end

Expand Down Expand Up @@ -120,5 +109,21 @@ def filesystems
staging = Y2Storage::StorageManager.instance.staging
staging.filesystems
end

# write pmbr flags
def pmbr_write
fs = filesystems
efi_partition = fs.find { |f| f.mount_path == "/boot/efi" }
efi_partition ||= fs.find { |f| f.mount_path == "/boot" }
efi_partition ||= fs.find { |f| f.mount_path == "/" }

raise "could not find boot partiton" unless efi_partition

disks = Yast::BootStorage.stage1_disks_for(efi_partition)
# set only gpt disks
disks.select! { |disk| disk.gpt? }

pmbr_setup(*disks.map(&:name))
end
end
end
15 changes: 11 additions & 4 deletions src/modules/Bootloader.rb
Expand Up @@ -25,15 +25,16 @@
require "installation/autoinst_issues/invalid_value"
require "cfa/matcher"

Yast.import "UI"
Yast.import "Arch"
Yast.import "BootStorage"
Yast.import "Initrd"
Yast.import "Installation"
Yast.import "Mode"
Yast.import "Package"
Yast.import "Progress"
Yast.import "Report"
Yast.import "Stage"
Yast.import "Installation"
Yast.import "UI"

module Yast
class BootloaderClass < Module
Expand Down Expand Up @@ -273,16 +274,22 @@ def Write
end
Progress.set(progress_state)

transactional = Package.IsTransactionalSystem

# Create initrd
Progress.NextStage
Progress.Title(titles[1]) unless Mode.normal

write_initrd || log.error("Error occurred while creating initrd")
write_initrd || log.error("Error occurred while creating initrd") if !transactional

# Save boot loader configuration
Progress.NextStage
Progress.Title(titles[2]) unless Mode.normal
::Bootloader::BootloaderFactory.current.write
::Bootloader::BootloaderFactory.current.write(etc_only: transactional)
if transactional
# all writing to target is done in specific transactional command
Yast::Execute.on_target!("transactional-update", "--continue", "bootloader")
end

true
end
Expand Down
6 changes: 5 additions & 1 deletion test/grub2_efi_test.rb
Expand Up @@ -44,7 +44,7 @@
subject.write
end

it "calls grub2-install with respective boot flags configuration" do
it "calls grub2-install with respective boot flags configuration on non-transactional systems" do
# This test fails (only!) in Travis with
# Failure/Error: subject.write Storage::Exception: Storage::Exception
grub_install = double(Bootloader::GrubInstall)
Expand All @@ -56,6 +56,10 @@
subject.update_nvram = false

subject.write

expect(grub_install).to_not receive(:execute)

subject.write(etc_only: true)
end

end
Expand Down
18 changes: 15 additions & 3 deletions test/grub2_test.rb
Expand Up @@ -55,12 +55,16 @@
allow(Yast::BootStorage).to receive(:gpt_disks).and_return(["/dev/sdb"])
end

it "writes stage1 location" do
it "writes stage1 location on non-transactional systems" do
stage1 = double(Bootloader::Stage1, devices: [], generic_mbr?: false)
expect(stage1).to receive(:write)
allow(Bootloader::Stage1).to receive(:new).and_return(stage1)

subject.write

expect(stage1).to_not receive(:write)

subject.write(etc_only: true)
end

it "changes pmbr flag as specified in pmbr_action for all boot devices with gpt label" do
Expand All @@ -75,7 +79,7 @@
subject.write
end

it "runs grub2-install for all configured stage1 locations" do
it "runs grub2-install for all configured stage1 locations on non-transactional systems" do
stage1 = double(Bootloader::Stage1, devices: ["/dev/sda", "/dev/sdb1"], generic_mbr?: false, write: nil)
allow(Bootloader::Stage1).to receive(:new).and_return(stage1)

Expand All @@ -86,6 +90,10 @@

subject.trusted_boot = false
subject.write

expect(grub2_install).to_not receive(:execute)

subject.write(etc_only: true)
end

context "on s390" do
Expand All @@ -105,12 +113,16 @@
allow(Yast::Arch).to receive(:architecture).and_return("x86_64")
end

it "runs mbr update for configured stage1 flags" do
it "runs mbr update for configured stage1 flags on non-transactional systems" do
mbr_update = double(Bootloader::MBRUpdate)
expect(mbr_update).to receive(:run)
expect(Bootloader::MBRUpdate).to receive(:new).and_return(mbr_update)

subject.write

expect(mbr_update).to_not receive(:run)

subject.write(etc_only: true)
end
end
end
Expand Down
17 changes: 17 additions & 0 deletions test/grub2base_test.rb
Expand Up @@ -115,6 +115,23 @@

subject.write
end

it "writes password" do
password = instance_double(Bootloader::GRUB2Pwd)
expect(Bootloader::GRUB2Pwd).to receive(:new).and_return(password)
subject.define_singleton_method(:name) { "grub2base" }

expect(password).to receive(:write)

subject.write
end

it "calls grub2-mkconfig in non-transactional system" do
expect(Yast::Execute).to receive(:on_target).with(/grub2-mkconfig/, any_args)
subject.write
expect(Yast::Execute).to_not receive(:on_target)
subject.write(etc_only: true)
end
end

describe "#propose" do
Expand Down

0 comments on commit b7cee0e

Please sign in to comment.