diff --git a/.travis.yml b/.travis.yml index 7496edc84..b3406ef28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,4 @@ script: # the "storage-ng-travis-ruby" script is included in the base yastdevel/storage-ng image # see https://github.com/yast/docker-storage-ng/blob/master/storage-ng-travis-ruby - docker run -it -e TRAVIS=1 -e TRAVIS_JOB_ID="$TRAVIS_JOB_ID" yast-bootloader-image storage-ng-travis-ruby + - docker run -it yast-bootloader-image rake check:doc diff --git a/Dockerfile b/Dockerfile index 73b0be3ee..053b8e5e5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,2 @@ FROM yastdevel/storage-ng COPY . /usr/src/app - diff --git a/Rakefile b/Rakefile index 08b80f200..8f9b22677 100644 --- a/Rakefile +++ b/Rakefile @@ -8,4 +8,7 @@ Yast::Tasks.configuration do |conf| conf.obs_project = "YaST:storage-ng" # Make sure 'rake osc:sr' fails conf.obs_sr_project = nil + # TODO: improve it, at least do not get worse + # TODO: remove condition when new packaging tasks are accepted to factory + conf.documentation_minimal = 50 if conf.respond_to?(:documentation_minimal=) end diff --git a/package/yast2-bootloader.changes b/package/yast2-bootloader.changes index 87499752d..b260be3c1 100644 --- a/package/yast2-bootloader.changes +++ b/package/yast2-bootloader.changes @@ -1,3 +1,14 @@ +------------------------------------------------------------------- +Fri Apr 21 11:28:29 UTC 2017 - jreidinger@suse.com + +- storage-ng: use new wrapper API +- 3.3.7 + +------------------------------------------------------------------- +Thu Apr 13 13:34:12 UTC 2017 - jreidinger@suse.com + +- Add possibility to use trusted boot for EFI (FATE#315831) + ------------------------------------------------------------------- Tue Mar 28 13:32:23 UTC 2017 - jreidinger@suse.com @@ -5,12 +16,32 @@ Tue Mar 28 13:32:23 UTC 2017 - jreidinger@suse.com partition - 3.3.6 +------------------------------------------------------------------- +Fri Mar 24 14:17:00 UTC 2017 - jreidinger@suse.com + +- Report user friendly message when no root partition is detected + instead of internal error. (bsc#1029293) + ------------------------------------------------------------------- Fri Mar 3 15:33:11 CET 2017 - snwint@suse.de - storage-ng: avoid call to old libstorage - 3.3.5 +------------------------------------------------------------------- +Wed Mar 1 17:42:18 UTC 2017 - jreidinger@suse.com + +- provide more helpful error message when invalid arguments for + serial console are provided (bsc#1012383) + +------------------------------------------------------------------- +Wed Mar 1 16:42:18 UTC 2017 - jreidinger@suse.com + +- propose for xen hypervisor vga parameter if framebuffer is used + ( should fix issue with text only environment when fbdev driver + is used ) + (FATE#322200) + ------------------------------------------------------------------- Thu Feb 16 14:47:03 UTC 2017 - ancor@suse.com diff --git a/package/yast2-bootloader.spec b/package/yast2-bootloader.spec index 012dbb747..0d1f5f971 100644 --- a/package/yast2-bootloader.spec +++ b/package/yast2-bootloader.spec @@ -17,7 +17,7 @@ Name: yast2-bootloader -Version: 3.3.6 +Version: 3.3.7 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build diff --git a/src/lib/bootloader/autoyast_converter.rb b/src/lib/bootloader/autoyast_converter.rb index ab578ad68..e2918845d 100644 --- a/src/lib/bootloader/autoyast_converter.rb +++ b/src/lib/bootloader/autoyast_converter.rb @@ -125,10 +125,10 @@ def import_device_map(data, bootloader) end STAGE1_DEVICES_MAPPING = { - "boot_root" => :RootPartitionDevice, - "boot_boot" => :BootPartitionDevice, + "boot_root" => :root_partition, + "boot_boot" => :boot_partition, "boot_mbr" => :mbr_disk, - "boot_extended" => :ExtendedPartitionDevice + "boot_extended" => :extended_partition }.freeze def import_stage1(data, bootloader) return unless bootloader.name == "grub2" @@ -153,13 +153,13 @@ def import_stage1_devices(data, stage1) # extended partion maybe do not exists, so report it to user if (data["global"]["boot_extended"] == "true" || data["location"] == "extended") && - Yast::BootStorage.ExtendedPartitionDevice.nil? + Yast::BootStorage.extended_partition.nil? raise "boot_extended used in autoyast profile, but there is no extended partition" end STAGE1_DEVICES_MAPPING.each do |key, device| if data["global"][key] == "true" || data["boot_#{key}"] - stage1.add_udev_device(Yast::BootStorage.public_send(device)) + stage1.add_udev_device(Yast::BootStorage.public_send(device).name) end end diff --git a/src/lib/bootloader/boot_record_backup.rb b/src/lib/bootloader/boot_record_backup.rb index b692a0b18..7c3b1e2c5 100644 --- a/src/lib/bootloader/boot_record_backup.rb +++ b/src/lib/bootloader/boot_record_backup.rb @@ -50,7 +50,7 @@ def write # special backup only if device is mbr disk Yast.import "BootStorage" - return if device != Yast::BootStorage.mbr_disk + return if device != Yast::BootStorage.mbr_disk.name copy_br(device, "/boot/backup_mbr") end diff --git a/src/lib/bootloader/config_dialog.rb b/src/lib/bootloader/config_dialog.rb index 0250cf43f..0d702c152 100644 --- a/src/lib/bootloader/config_dialog.rb +++ b/src/lib/bootloader/config_dialog.rb @@ -44,7 +44,7 @@ def guarded_run # F#300779 - Install diskless client (NFS-root) # additional warning that root partition is nfs type -> bootloader will not be installed - device = Yast::BootStorage.disk_with_boot_partition + device = Yast::BootStorage.disk_with_boot_partition.name if device == "/dev/nfs" && Yast::Mode.installation Yast::Popup.Message( diff --git a/src/lib/bootloader/device_map.rb b/src/lib/bootloader/device_map.rb index a54926e91..924ad445f 100644 --- a/src/lib/bootloader/device_map.rb +++ b/src/lib/bootloader/device_map.rb @@ -13,7 +13,6 @@ module Bootloader class DeviceMap extend Forwardable include Yast::Logger - using Y2Storage::Refinements::DevicegraphLists def_delegators :@model, :grub_device_for, :system_device_for, :grub_devices, :add_mapping, :remove_mapping @@ -120,7 +119,7 @@ def order_boot_device # want to modify its MBR. So we get disk of such partition and change order to add it # to top of device map. For details see bnc#887808,bnc#880439 boot_disk = Yast::BootStorage.disk_with_boot_partition - priority_disks = ::Bootloader::Stage1Device.new(boot_disk).real_devices + priority_disks = ::Bootloader::Stage1Device.new(boot_disk.name).real_devices # if none of priority disk is hd0, then choose one and assign it return if any_first_device?(priority_disks) @@ -132,7 +131,7 @@ def fill_mapping # BIOS-ID is not supported in libstorage-ng, so let's simply create a # mapping entry per disk for the time being (see commented code for the # real expected behavior) - staging = Y2Storage::StorageManager.instance.staging + staging = Y2Storage::StorageManager.instance.y2storage_staging staging.disks.each_with_index do |disk, index| add_mapping("hd#{index}", disk.name) end diff --git a/src/lib/bootloader/device_map_dialog.rb b/src/lib/bootloader/device_map_dialog.rb index 8c5f9b5e1..0a1b37163 100644 --- a/src/lib/bootloader/device_map_dialog.rb +++ b/src/lib/bootloader/device_map_dialog.rb @@ -142,7 +142,7 @@ def refresh_disks end def store_order - Yast::BootStorage.mbr_disk = disks.first + Yast::BootStorage.assign_mbr_disk_by_name(disks.first) @device_map.clear_mapping disks.each_with_index do |disk, index| diff --git a/src/lib/bootloader/exceptions.rb b/src/lib/bootloader/exceptions.rb index 16cc4cd78..454ff1a0e 100644 --- a/src/lib/bootloader/exceptions.rb +++ b/src/lib/bootloader/exceptions.rb @@ -25,4 +25,15 @@ def initialize(msg) "Please use YaST2 bootloader to fix it. Details: %s") % msg end end + + # Represents error when serial console arguments are not valid + class InvalidSerialConsoleArguments < BrokenConfiguration + MESSAGE = "Invalid serial console arguments".freeze + def initialize(msg = MESSAGE) + super + end + end + + class NoRoot < RuntimeError + end end diff --git a/src/lib/bootloader/grub2.rb b/src/lib/bootloader/grub2.rb index 96254a74e..86cc2cb0d 100644 --- a/src/lib/bootloader/grub2.rb +++ b/src/lib/bootloader/grub2.rb @@ -17,11 +17,6 @@ module Bootloader class Grub2 < Grub2Base attr_reader :stage1 attr_reader :device_map - # @return [Boolean] - attr_accessor :trusted_boot - - using Y2Storage::Refinements::DevicegraphLists - using Y2Storage::Refinements::Disk def initialize super @@ -30,7 +25,6 @@ def initialize @stage1 = Stage1.new @grub_install = GrubInstall.new(efi: false) @device_map = DeviceMap.new - @trusted_boot = false end # Read settings from disk, overwritting already set values @@ -55,8 +49,6 @@ def read log.info "grub2/device.map does not exist. Using empty one." @device_map = DeviceMap.new end - - @trusted_boot = Sysconfig.from_system.trusted_boot end # Write bootloader settings to disk @@ -89,14 +81,12 @@ def propose # 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 - @trusted_boot = false end def merge(other) super @device_map = other.device_map if !other.device_map.empty? - @trusted_boot = other.trusted_boot unless other.trusted_boot.nil? stage1.merge(other.stage1) end @@ -111,7 +101,7 @@ def summary(simple_mode: false) ), Yast::Builtins.sformat( _("Enable Trusted Boot: %1"), - @trusted_boot ? _("yes") : _("no") + trusted_boot ? _("yes") : _("no") ) ] locations_val = locations @@ -151,7 +141,7 @@ def packages end if Yast::Arch.x86_64 || Yast::Arch.i386 - res << "trustedgrub2" << "trustedgrub2-i386-pc" if @trusted_boot + res << "trustedgrub2" << "trustedgrub2-i386-pc" if trusted_boot end res @@ -160,19 +150,21 @@ def packages # FIXME: refactor with injection like super(prewrite: prewrite, sysconfig = ...) # overwrite BootloaderBase version to save trusted boot def write_sysconfig(prewrite: false) - sysconfig = Bootloader::Sysconfig.new(bootloader: name, trusted_boot: @trusted_boot) + sysconfig = Bootloader::Sysconfig.new(bootloader: name, trusted_boot: trusted_boot) prewrite ? sysconfig.pre_write : sysconfig.write end private def devicegraph - Y2Storage::StorageManager.instance.staging + Y2Storage::StorageManager.instance.y2storage_staging end def gpt_disks_devices boot_devices = stage1.devices - boot_discs = devicegraph.disks.with_name_or_partition(boot_devices) + boot_discs = devicegraph.disks.select do |disk| + boot_devices.any? { |bd| disk.name_or_partition?(bd) } + end gpt_disks = boot_discs.select { |d| d.gpt? } gpt_disks.map { |d| d.name } end @@ -196,12 +188,12 @@ def locations locations << partition_location unless partition_location.empty? if stage1.extended_partition? # TRANSLATORS: extended is here for extended partition. Keep translation short. - locations << Yast::BootStorage.ExtendedPartitionDevice + _(" (extended)") + locations << Yast::BootStorage.extended_partition.name + _(" (extended)") end if stage1.mbr? # TRANSLATORS: MBR is acronym for Master Boot Record, if nothing locally specific # is used in your language, then keep it as it is. - locations << Yast::BootStorage.mbr_disk + _(" (MBR)") + locations << Yast::BootStorage.mbr_disk.name + _(" (MBR)") end locations << stage1.custom_devices if !stage1.custom_devices.empty? @@ -211,10 +203,10 @@ def locations def boot_partition_location if Yast::BootStorage.separated_boot? if stage1.boot_partition? - return Yast::BootStorage.BootPartitionDevice + " (\"/boot\")" + return Yast::BootStorage.boot_partition.name + " (\"/boot\")" end elsif stage1.root_partition? - return Yast::BootStorage.RootPartitionDevice + " (\"/\")" + return Yast::BootStorage.root_partition.name + " (\"/\")" end "" diff --git a/src/lib/bootloader/grub2_widgets.rb b/src/lib/bootloader/grub2_widgets.rb index 528db697a..a46cb2889 100644 --- a/src/lib/bootloader/grub2_widgets.rb +++ b/src/lib/bootloader/grub2_widgets.rb @@ -2,6 +2,7 @@ require "bootloader/generic_widgets" require "bootloader/device_map_dialog" +require "bootloader/serial_console" require "cfa/matcher" Yast.import "BootStorage" @@ -297,13 +298,17 @@ def label def help # TRANSLATORS: TrustedGRUB2 is a name, don't translate it - _("
Trusted Boot will install TrustedGRUB2\n" \ - "instead of regular GRUB2.
\n" \ - "It means measuring the integrity of the boot process,\n" \ - "with the help from the hardware (a TPM, Trusted Platform Module,\n" \ - "chip).
\n" \ - "First you need to make sure Trusted Boot is enabled in the BIOS\n" \ - "setup (the setting may be named Security Chip, for example).
\n") + res = _("Trusted Boot will install TrustedGRUB2\n" \ + "instead of regular GRUB2.
\n" \ + "It means measuring the integrity of the boot process,\n" \ + "with the help from the hardware (a TPM, Trusted Platform Module,\n" \ + "chip).
\n") + if grub2.name == "grub2" + res += _("First you need to make sure Trusted Boot is enabled in the BIOS\n" \ + "setup (the setting may be named Security Chip, for example).
\n") + end + + res end def init @@ -315,7 +320,7 @@ def store end def validate - return true if Yast::Mode.config || !value + return true if Yast::Mode.config || !value || grub2.name == "grub2-efi" tpm_files = Dir.glob("/sys/**/pcrs") if !tpm_files.empty? # check for file size does not work, since FS reports it 4096 @@ -460,6 +465,22 @@ def contents ) end + def help + # Translators: do not translate the quoted parts like "unit" + _( + "When a graphical console is used it allows to use various " \ + "display resolutions. The auto option tries to find " \ + "the best one when booting starts.
\n" \ + "When a serial console is used the boot output " \ + "will be printed to a serial device like ttyS0. " \ + "At least the --unit option has to be specified, " \ + "and the complete syntax is %s. " \ + "Other parts are optional and if not set, a default is used. " \ + "NUM in commands stands for a positive number like 8. " \ + "Example parameters are serial --speed=38400 --unit=0.
" + ) % syntax + end + def init enable = grub_default.terminal == :serial Yast::UI.ChangeWidget(Id(:console_frame), :Value, enable) @@ -488,6 +509,14 @@ def validate Yast::UI.SetFocus(Id(:console_args)) return false end + if ::Bootloader::SerialConsole.load_from_console_args(console_value).nil? + # Translators: do not translate "unit" + msg = _("To enable the serial console you must provide the corresponding arguments.\n" \ + "The \"unit\" argument is required, the complete syntax is:\n%s") % syntax + Yast::Report.Error(msg) + Yast::UI.SetFocus(Id(:console_args)) + return false + end end true end @@ -533,6 +562,16 @@ def handle(event) private + # Explanation for help and error messages + def syntax + # Translators: NUM is an abbreviation for "number", + # to be substituted in a command like + # "serial --unit=NUM --speed=NUM --parity={odd|even|no} --word=NUM --stop=NUM" + # so do not use punctuation + n = _("NUM") + "serial --unit=#{n} --speed=#{n} --parity={odd|even|no} --word=#{n} --stop=#{n}" + end + def graphical_console_frame CheckBoxFrame( Id(:gfxterm_frame), @@ -568,7 +607,7 @@ def vga_modes_items @vga_modes.sort! do |a, b| res = a["width"] <=> b["width"] - res = a["height"] <=> b["height"] if res == 0 + res = a["height"] <=> b["height"] if res.zero? res end @@ -857,7 +896,11 @@ def secure_boot_widget? end def trusted_boot_widget? - (Yast::Arch.x86_64 || Yast::Arch.i386) && grub2.name == "grub2" + return false if !(Yast::Arch.x86_64 || Yast::Arch.i386) + return true if grub2.name == "grub2" + # for details about grub2 efi trusted boot support see FATE#315831 + return File.exist?("/dev/tpm0") if grub2.name == "grub2-efi" + false end def pmbr_widget? diff --git a/src/lib/bootloader/grub2base.rb b/src/lib/bootloader/grub2base.rb index 886e972af..d6c21acd0 100644 --- a/src/lib/bootloader/grub2base.rb +++ b/src/lib/bootloader/grub2base.rb @@ -3,6 +3,7 @@ require "yast2/execute" require "yast2/target_file" # adds ability to work with cfa in inst-sys require "bootloader/bootloader_base" +require "bootloader/exceptions" require "bootloader/sections" require "bootloader/grub2pwd" require "bootloader/udev_mapping" @@ -42,6 +43,9 @@ class Grub2Base < BootloaderBase attr_accessor :pmbr_action + # @return [Boolean] + attr_accessor :trusted_boot + def initialize super @@ -84,6 +88,8 @@ def read end @sections = ::Bootloader::Sections.new(grub_cfg) log.info "grub sections: #{@sections.all}" + + self.trusted_boot = Sysconfig.from_system.trusted_boot end def write @@ -117,7 +123,9 @@ def propose grub_default.generic_set("SUSE_BTRFS_SNAPSHOT_BOOTING", "true") propose_serial + propose_xen_hypervisor + self.trusted_boot = false nil end @@ -128,11 +136,13 @@ def merge(other) merge_password(other) merge_pmbr_action(other) merge_sections(other) + + self.trusted_boot = other.trusted_boot unless other.trusted_boot.nil? end def enable_serial_console(console) console = SerialConsole.load_from_console_args(console) - raise "Invalid console parameters" unless console + raise ::Bootloader::InvalidSerialConsoleArguments unless console grub_default.serial_console = console.console_args @@ -267,6 +277,14 @@ def propose_serial grub_default.serial_console = console.console_args end + def propose_xen_hypervisor + return if Dir["/dev/fb*"].empty? + + matcher = CFA::Matcher.new(key: "vga") + placer = CFA::ReplacePlacer.new(matcher) + grub_default.xen_hypervisor_params.add_parameter("vga", "gfx-1024x768x16", placer) + end + def propose_resume swap_parts = Yast::BootStorage.available_swap_partitions largest_swap_part = (swap_parts.max_by { |_part, size| size } || [""]).first diff --git a/src/lib/bootloader/grub2efi.rb b/src/lib/bootloader/grub2efi.rb index a6ff8fba2..f99f81c94 100644 --- a/src/lib/bootloader/grub2efi.rb +++ b/src/lib/bootloader/grub2efi.rb @@ -14,7 +14,6 @@ module Bootloader class Grub2EFI < Grub2Base include Yast::Logger attr_accessor :secure_boot - using Y2Storage::Refinements::DevicegraphLists def initialize super @@ -37,13 +36,15 @@ def write super if pmbr_action && Yast::BootStorage.gpt_boot_disk? - efi_partition = filesystems.with_mountpoint("/boot/efi").partitions.first - efi_partition ||= filesystems.with_mountpoint("/boot").partitions.first - efi_partition ||= filesystems.with_mountpoint("/").partitions.first + efi_partition = filesystems.find { |f| f.mountpoint == "/boot/efi" } + efi_partition ||= filesystems.find { |f| f.mountpoint == "/boot" } + efi_partition ||= filesystems.find { |f| f.mountpoint == "/" } raise "could not find boot partiton" unless efi_partition - efi_disk = efi_partition.partitionable + efi_partition = efi_partition.plain_blk_devices.first + + efi_disk = efi_partition.disk # storage-ng # rubocop:disable Style/BlockComments @@ -55,7 +56,7 @@ def write pmbr_setup(efi_disk.name) end - @grub_install.execute(secure_boot: @secure_boot) + @grub_install.execute(secure_boot: @secure_boot, trusted_boot: trusted_boot) true end @@ -88,6 +89,10 @@ def summary(*) Yast::Builtins.sformat( _("Enable Secure Boot: %1"), @secure_boot ? _("yes") : _("no") + ), + Yast::Builtins.sformat( + _("Enable Trusted Boot: %1"), + trusted_boot ? _("yes") : _("no") ) ] end @@ -118,7 +123,8 @@ def packages # overwrite BootloaderBase version to save secure boot def write_sysconfig(prewrite: false) - sysconfig = Bootloader::Sysconfig.new(bootloader: name, secure_boot: @secure_boot) + sysconfig = Bootloader::Sysconfig.new(bootloader: name, + secure_boot: @secure_boot, trusted_boot: trusted_boot) prewrite ? sysconfig.pre_write : sysconfig.write end @@ -128,7 +134,7 @@ def write_sysconfig(prewrite: false) # # @return [Y2Storage::FilesystemsList] def filesystems - staging = Y2Storage::StorageManager.instance.staging + staging = Y2Storage::StorageManager.instance.y2storage_staging staging.filesystems end end diff --git a/src/lib/bootloader/grub_install.rb b/src/lib/bootloader/grub_install.rb index 4478943f4..c921d906c 100644 --- a/src/lib/bootloader/grub_install.rb +++ b/src/lib/bootloader/grub_install.rb @@ -12,7 +12,6 @@ def initialize(efi: false) def execute(devices: [], secure_boot: false, trusted_boot: false) raise "cannot have secure boot without efi" if secure_boot && !efi - raise "cannot have trusted boot with efi" if trusted_boot && efi cmd = basic_cmd(secure_boot, trusted_boot) @@ -37,7 +36,10 @@ def basic_cmd(secure_boot, trusted_boot) # Do skip-fs-probe to avoid error when embedding stage1 # to extended partition cmd << "--force" << "--skip-fs-probe" - cmd << "--directory=/usr/lib/trustedgrub2/#{target}" if trusted_boot + end + + if trusted_boot + cmd << (efi ? "--suse-enable-tpm" : "--directory=/usr/lib/trustedgrub2/#{target}") end cmd << "--no-nvram" << "--removable" if removable_efi? diff --git a/src/lib/bootloader/mbr_update.rb b/src/lib/bootloader/mbr_update.rb index c4b0f0137..9e62aeffc 100644 --- a/src/lib/bootloader/mbr_update.rb +++ b/src/lib/bootloader/mbr_update.rb @@ -14,8 +14,6 @@ module Bootloader # FIXME: make it single responsibility class class MBRUpdate include Yast::Logger - using Y2Storage::Refinements::DevicegraphLists - using Y2Storage::Refinements::Disk # Update contents of MBR (active partition and booting code) def run(stage1) @@ -34,11 +32,11 @@ def run(stage1) private def devicegraph - Y2Storage::StorageManager.instance.staging + Y2Storage::StorageManager.instance.y2storage_staging end def mbr_disk - @mbr_disk ||= Yast::BootStorage.mbr_disk + @mbr_disk ||= Yast::BootStorage.mbr_disk.name end def create_backups @@ -52,7 +50,7 @@ def create_backups end def gpt?(disk) - mbr_storage_object = devicegraph.disks.with(name: disk).first + mbr_storage_object = devicegraph.disks.find { |d| d.name == disk } raise "Cannot find in storage mbr disk #{disk}" unless mbr_storage_object mbr_storage_object.gpt? end @@ -182,13 +180,11 @@ def activatable_partitions(disk) # do not select swap and do not select BIOS grub partition # as it clear its special flags (bnc#894040) - devicegraph.disks.with(name: disk.name).partitions.reject do |part| - [Storage::ID_SWAP, Storage::ID_BIOS_BOOT].include?(part.id) - end + disk.partitions.reject { |p| p.id.is?(:swap, :bios_boot) } end def extended_partition(disk) - part = activatable_partitions(disk).find { |p| p.type == Storage::PartitionType_EXTENDED } + part = activatable_partitions(disk).find { |p| p.type == Y2Storage::PartitionType::EXTENDED } return nil unless part log.info "Using extended partition instead: #{part.inspect}" @@ -229,18 +225,17 @@ def partition_to_activate(loader_device) end def partition_and_disk_to_activate(dev_name) - parts = devicegraph.partitions.with(name: dev_name) - partition = parts.first - mbr_dev = parts.disks.first - - # if real_device is not a partition but a disk - if !partition - mbr_dev = devicegraph.disks.with(name: dev_name).first + device = Y2Storage::BlkDevice.find_by_name(devicegraph, dev_name) + if device.is?(:disk) + mbr_dev = device # (bnc # 337742) - Unable to boot the openSUSE (32 and 64 bits) after installation # if loader_device is disk Choose any partition which is not swap to # satisfy such bios (bnc#893449) partition = activatable_partitions(mbr_dev).first log.info "loader_device is disk device, so use its partition #{partition.inspect}" + else + partition = device + mbr_dev = device.disk end [partition, mbr_dev] end diff --git a/src/lib/bootloader/proposal_client.rb b/src/lib/bootloader/proposal_client.rb index 47f3dfe2f..5cb417ba0 100644 --- a/src/lib/bootloader/proposal_client.rb +++ b/src/lib/bootloader/proposal_client.rb @@ -1,4 +1,5 @@ require "installation/proposal_client" +require "bootloader/exceptions" require "bootloader/main_dialog" require "bootloader/bootloader_factory" @@ -35,6 +36,8 @@ def make_proposal(attrs) force_reset = attrs["force_reset"] auto_mode = Yast::Mode.autoinst || Yast::Mode.autoupgrade + Yast::BootStorage.detect_disks + if (force_reset || !Yast::Bootloader.proposed_cfg_changed) && !auto_mode # force re-calculation of bootloader proposal @@ -61,6 +64,12 @@ def make_proposal(attrs) Yast::PackagesProposal.AddResolvables("yast2-bootloader", :package, bl.packages) construct_proposal_map + rescue ::Bootloader::NoRoot + { + "label_proposal" => [], + "warning_level" => :fatal, + "warning" => _("Cannot detect device mounted as root. Please check partitioning.") + } end def ask_user(param) @@ -156,7 +165,7 @@ def construct_proposal_map # F#300779 - Install diskless client (NFS-root) # kokso: bootloader will not be installed - device = Yast::BootStorage.disk_with_boot_partition + device = Yast::BootStorage.disk_with_boot_partition.name log.info "Type of BootPartitionDevice: #{device}" if device == "/dev/nfs" log.info "Boot partition is nfs type, bootloader will not be installed." diff --git a/src/lib/bootloader/stage1.rb b/src/lib/bootloader/stage1.rb index 6a7e562bd..14d884bd9 100644 --- a/src/lib/bootloader/stage1.rb +++ b/src/lib/bootloader/stage1.rb @@ -17,7 +17,6 @@ module Bootloader class Stage1 extend Forwardable include Yast::Logger - using Y2Storage::Refinements::DevicegraphLists attr_reader :model def_delegators :@model, :generic_mbr?, :generic_mbr=, :activate?, :activate=, :devices, @@ -75,7 +74,7 @@ def clear_devices def boot_partition? if !@boot_partition_device - dev = Yast::BootStorage.BootPartitionDevice + dev = Yast::BootStorage.boot_partition.name kernel_dev = Bootloader::UdevMapping.to_kernel_device(dev) @boot_partition_device = ::Bootloader::Stage1Device.new(kernel_dev) @@ -86,7 +85,7 @@ def boot_partition? def root_partition? if !@root_partition_device - dev = Yast::BootStorage.RootPartitionDevice + dev = Yast::BootStorage.root_partition.name kernel_dev = Bootloader::UdevMapping.to_kernel_device(dev) @root_partition_device = ::Bootloader::Stage1Device.new(kernel_dev) @@ -97,7 +96,7 @@ def root_partition? def mbr? if !@mbr_device - dev = Yast::BootStorage.mbr_disk + dev = Yast::BootStorage.mbr_disk.name kernel_dev = Bootloader::UdevMapping.to_kernel_device(dev) @mbr_device = ::Bootloader::Stage1Device.new(kernel_dev) @@ -107,10 +106,10 @@ def mbr? end def extended_partition? - return false unless Yast::BootStorage.ExtendedPartitionDevice + return false unless Yast::BootStorage.extended_partition if !@extended_partition_device - dev = Yast::BootStorage.ExtendedPartitionDevice + dev = Yast::BootStorage.extended_partition.name kernel_dev = Bootloader::UdevMapping.to_kernel_device(dev) @extended_partition_device = ::Bootloader::Stage1Device.new(kernel_dev) @@ -121,13 +120,13 @@ def extended_partition? def custom_devices known_devices = [ - Yast::BootStorage.BootPartitionDevice, - Yast::BootStorage.RootPartitionDevice, + Yast::BootStorage.boot_partition, + Yast::BootStorage.root_partition, Yast::BootStorage.mbr_disk, - Yast::BootStorage.ExtendedPartitionDevice + Yast::BootStorage.extended_partition ] - known_devices.compact! - known_devices.map! { |d| Bootloader::UdevMapping.to_kernel_device(d) } + known_devices.compact! # extended partition can be nil + known_devices.map! { |d| Bootloader::UdevMapping.to_kernel_device(d.name) } devices.select do |dev| !known_devices.include?(Bootloader::UdevMapping.to_kernel_device(dev)) @@ -149,7 +148,7 @@ def available_locations case Yast::Arch.architecture when "i386", "x86_64" res = available_partitions - res[:mbr] = Yast::BootStorage.mbr_disk + res[:mbr] = Yast::BootStorage.mbr_disk.name return res else @@ -160,23 +159,20 @@ def available_locations end def can_use_boot? - partition = Yast::BootStorage.BootPartitionDevice + part = Yast::BootStorage.boot_partition - parts = partitions.with(name: partition) - - if parts.empty? - log.error "cannot find partition #{partition}" + if !part + log.error "boot partition is not assigned" return false end - log.info "Boot partition info #{parts.first.inspect}" + log.info "Boot partition info #{part.inspect}" # cannot install stage one to xfs as it doesn't have reserved space (bnc#884255) - fs = parts.filesystems.first - return false if fs && fs.type == ::Storage::FsType_XFS + return false if part.filesystem_type == ::Y2Storage::Filesystems::Type::XFS # LVM partition does not have reserved space for stage one - return false if staging.lvm_vgs.partitions.with(name: partition).any? + return false if part.lvm_pv true end @@ -216,7 +212,7 @@ def partitions end def staging - Y2Storage::StorageManager.instance.staging + Y2Storage::StorageManager.instance.y2storage_staging end def include_real_devs?(real_devs) @@ -232,13 +228,13 @@ def available_partitions res = {} if Yast::BootStorage.separated_boot? - res[:boot] = Yast::BootStorage.BootPartitionDevice + res[:boot] = Yast::BootStorage.boot_partition.name else - res[:root] = Yast::BootStorage.RootPartitionDevice + res[:root] = Yast::BootStorage.root_partition.name end if extended_partition? - res[:extended] = Yast::BootStorage.ExtendedPartitionDevice + res[:extended] = Yast::BootStorage.extended_partition.name end res diff --git a/src/lib/bootloader/stage1_device.rb b/src/lib/bootloader/stage1_device.rb index 11d85e0c0..115914f10 100644 --- a/src/lib/bootloader/stage1_device.rb +++ b/src/lib/bootloader/stage1_device.rb @@ -15,7 +15,6 @@ module Bootloader # puts dev.real_devices # => ["/dev/sda1", "/dev/sdb1"] class Stage1Device include Yast::Logger - using Y2Storage::Refinements::DevicegraphLists # @param [String] device intended location of stage1. Device here # means any name under /dev like "/dev/sda", "/dev/system/root" or @@ -40,7 +39,7 @@ def real_devices private def devicegraph - Y2Storage::StorageManager.instance.staging + Y2Storage::StorageManager.instance.y2storage_staging end # underlaying_devices without any caching @@ -57,6 +56,11 @@ def underlaying_devices_for(dev) res.uniq end + def pv_disk(vg) + pvs = usable_pvs(vg) + pvs.map { |p| p.ancestors.find { |a| a.is?(:disk) }.name } + end + # get one level of underlaying devices, so no recursion deeper def underlaying_devices_one_level(dev) # FIXME: there is nothing like this right now in libstorage-ng @@ -64,18 +68,12 @@ def underlaying_devices_one_level(dev) # revisit when such thing exist match = /^\/dev\/(\w+)$/.match(dev) if match && match[1] - vgs = devicegraph.volume_groups.with(vg_name: match[1]) - return usable_pvs(vgs).disks.map(&:name) unless vgs.empty? + vg = devicegraph.lvm_vgs.find { |v| v.vg_name == match[1] } + return pv_disk(vg) if vg end - # FIXME: there is nothing like this right now in libstorage-ng - # a_lv.name #=> "/dev/vgname/lvname" - # revisit when such thing exist - match = /^\/dev\/\w+\/(\w+)$/.match(dev) - if match && match[1] - lvs = devicegraph.logical_volumes.with(lv_name: match[1]) - return usable_pvs(lvs.vgs).map { |pv| pv.blk_device.name } unless lvs.empty? - end + lvs = devicegraph.lvm_lvs.find { |v| v.name == dev } + return usable_pvs(lvs.lvm_vg).map { |v| v.blk_device.name } if lvs && lvs.lvm_vg # TODO: storage-ng # md @@ -102,18 +100,17 @@ def underlaying_devices_one_level(dev) # # Ignores physical volumes on a whole disk. See bnc#980529 # - # @param volumes_group_list [Y2Storage::LvmVgsList] - # @return [Y2Storage::LvmPvsList] - def usable_pvs(volume_groups_list) - pvs = volume_groups_list.physical_volumes - pvs.with { |pv| !Storage.disk?(pv.blk_device) } + # @param volume_group [Y2Storage::LvmVg] + # @return [Array