Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package yast2-storage-ng for openSUSE:Factory checked in at 2021-12-21 18:40:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-storage-ng (Old) and /work/SRC/openSUSE:Factory/.yast2-storage-ng.new.2520 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-storage-ng" Tue Dec 21 18:40:21 2021 rev:114 rq:941681 version:4.4.28 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-storage-ng/yast2-storage-ng.changes 2021-12-18 20:30:25.246248366 +0100 +++ /work/SRC/openSUSE:Factory/.yast2-storage-ng.new.2520/yast2-storage-ng.changes 2021-12-21 18:40:28.337865259 +0100 @@ -1,0 +2,7 @@ +Mon Dec 20 16:25:17 UTC 2021 - Ancor Gonzalez Sosa <an...@suse.com> + +- Partitioner: added a warning if a required mount option, eg. + _netdev, is missing in a mount point (jsc#SLE-20535). +- 4.4.28 + +------------------------------------------------------------------- Old: ---- yast2-storage-ng-4.4.27.tar.bz2 New: ---- yast2-storage-ng-4.4.28.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-storage-ng.spec ++++++ --- /var/tmp/diff_new_pack.tSD2Gx/_old 2021-12-21 18:40:28.845865716 +0100 +++ /var/tmp/diff_new_pack.tSD2Gx/_new 2021-12-21 18:40:28.849865719 +0100 @@ -17,7 +17,7 @@ Name: yast2-storage-ng -Version: 4.4.27 +Version: 4.4.28 Release: 0 Summary: YaST2 - Storage Configuration License: GPL-2.0-only OR GPL-3.0-only ++++++ yast2-storage-ng-4.4.27.tar.bz2 -> yast2-storage-ng-4.4.28.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/package/yast2-storage-ng.changes new/yast2-storage-ng-4.4.28/package/yast2-storage-ng.changes --- old/yast2-storage-ng-4.4.27/package/yast2-storage-ng.changes 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/package/yast2-storage-ng.changes 2021-12-20 17:32:39.000000000 +0100 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Mon Dec 20 16:25:17 UTC 2021 - Ancor Gonzalez Sosa <an...@suse.com> + +- Partitioner: added a warning if a required mount option, eg. + _netdev, is missing in a mount point (jsc#SLE-20535). +- 4.4.28 + +------------------------------------------------------------------- Wed Dec 15 18:48:46 UTC 2021 - David Diaz <dgonza...@suse.com> - Improve probing issues handling by raising exceptions. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/package/yast2-storage-ng.spec new/yast2-storage-ng-4.4.28/package/yast2-storage-ng.spec --- old/yast2-storage-ng-4.4.27/package/yast2-storage-ng.spec 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/package/yast2-storage-ng.spec 2021-12-20 17:32:39.000000000 +0100 @@ -16,7 +16,7 @@ # Name: yast2-storage-ng -Version: 4.4.27 +Version: 4.4.28 Release: 0 Summary: YaST2 - Storage Configuration License: GPL-2.0-only OR GPL-3.0-only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/src/lib/y2partitioner/setup_errors_presenter.rb new/yast2-storage-ng-4.4.28/src/lib/y2partitioner/setup_errors_presenter.rb --- old/yast2-storage-ng-4.4.27/src/lib/y2partitioner/setup_errors_presenter.rb 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/src/lib/y2partitioner/setup_errors_presenter.rb 2021-12-20 17:32:39.000000000 +0100 @@ -54,7 +54,7 @@ # # @return [String, nil] nil if there is no boot warning def warnings_html - warnings = [boot_warnings_html, product_warnings_html].compact + warnings = [boot_warnings_html, product_warnings_html, mount_warnings_html].compact return nil if warnings.empty? warnings.join(Yast::HTML.Newline) @@ -65,7 +65,6 @@ # @return [String, nil] nil if there is no boot warning def boot_warnings_html warnings = setup_checker.boot_warnings - # TRANSLATORS header = _("The system might not be able to boot:\n") create_html(header, warnings) @@ -76,13 +75,24 @@ # @return [String, nil] nil if there is no product warning def product_warnings_html warnings = setup_checker.product_warnings - # TRANSLATORS header = _( "The system could not work properly because the following product " \ "requirements were not fulfilled:\n" ) create_html(header, warnings) + end + + # HTML representation for warnings about the mount points + # + # @return [String, nil] nil if there is no mount warning + def mount_warnings_html + warnings = setup_checker.mount_warnings + header = _( + "The system could fail to initialize some mount point during boot:\n" + ) + + create_html(header, warnings) end # HTML representation for fatal booting errors diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/src/lib/y2storage/mount_point.rb new/yast2-storage-ng-4.4.28/src/lib/y2storage/mount_point.rb --- old/yast2-storage-ng-4.4.27/src/lib/y2storage/mount_point.rb 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/src/lib/y2storage/mount_point.rb 2021-12-20 17:32:39.000000000 +0100 @@ -166,8 +166,17 @@ # # See jsc#SLE-20535, bsc#1176140, bsc#1165937 and jsc#SLE-7687 def adjust_mount_options - self.mount_options = - mount_options + mountable.missing_mount_options - mountable.unwanted_mount_options + self.mount_options = mount_options + missing_mount_options - unwanted_mount_options + end + + # @see Mountable#missing_mount_options + def missing_mount_options + mountable.missing_mount_options + end + + # @see Mountable#unwanted_mount_options + def unwanted_mount_options + mountable.unwanted_mount_options end # @!method set_default_mount_by diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/src/lib/y2storage/setup_checker.rb new/yast2-storage-ng-4.4.28/src/lib/y2storage/setup_checker.rb --- old/yast2-storage-ng-4.4.27/src/lib/y2storage/setup_checker.rb 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/src/lib/y2storage/setup_checker.rb 2021-12-20 17:32:39.000000000 +0100 @@ -40,6 +40,8 @@ # checker = SetupChecker.new(devicegraph) # checker.valid? #=> true class SetupChecker + include Yast::I18n + # @return [Devicegraph] attr_reader :devicegraph @@ -47,6 +49,7 @@ # # @param devicegraph [Devicegraph] setup to check def initialize(devicegraph) + textdomain "storage" @devicegraph = devicegraph end @@ -71,7 +74,7 @@ # # @return [Array<SetupError>] def warnings - boot_warnings + product_warnings + boot_warnings + product_warnings + mount_warnings end # All boot errors detected in the setup @@ -93,6 +96,15 @@ @product_warnings ||= missing_product_volumes.map { |v| SetupError.new(missing_volume: v) } end + # All warnings related to the definition of the mount points in the setup + # + # This checks for example whether the mount options make sense. + # + # @return [Array<SetupError>] + def mount_warnings + devicegraph.mount_points.map { |mp| mount_warning(mp) }.compact + end + private # Mandatory product volumes that are not present in the current setup @@ -153,6 +165,31 @@ end end + # @see #mount_warnings + # + # @param mount_point [MountPoint] + # @return [SetupError, nil] + def mount_warning(mount_point) + missing = mount_point.missing_mount_options + return if missing.empty? + + # TRANSLATORS: do not translate %{opt} or %{path}. %{opt} is replaced by the name of a mount + # option in the singular sentence or a list of options separated by commas in the plural one. + # ${path} is replaced by the mount point. + msg = n_( + format( + "The fstab option %{opt} may be needed to properly mount %{path}.", + opt: missing.first, path: mount_point.path + ), + format( + "The following fstab options may be needed to propely mount %{path}: %{opt}", + opt: missing.join(","), path: mount_point.path + ), + missing.size + ) + SetupError.new(message: msg) + end + # @return [BootRequirementsChecker] shortcut for boot requirements checker # with given device graph def boot_requirements_checker diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/test/y2partitioner/setup_errors_presenter_test.rb new/yast2-storage-ng-4.4.28/test/y2partitioner/setup_errors_presenter_test.rb --- old/yast2-storage-ng-4.4.27/test/y2partitioner/setup_errors_presenter_test.rb 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/test/y2partitioner/setup_errors_presenter_test.rb 2021-12-20 17:32:39.000000000 +0100 @@ -31,6 +31,7 @@ Y2Storage::StorageManager.create_test_instance allow(setup_checker).to receive(:boot_warnings).and_return(boot_errors) allow(setup_checker).to receive(:product_warnings).and_return(product_errors) + allow(setup_checker).to receive(:mount_warnings).and_return(mount_errors) allow(setup_checker).to receive(:errors).and_return(fatal_errors) end @@ -42,10 +43,13 @@ let(:product_errors) { [] } + let(:mount_errors) { [] } + describe "#to_html" do context "when there is no error" do let(:boot_errors) { [] } let(:product_errors) { [] } + let(:mount_errors) { [] } it "returns an empty string" do expect(subject.to_html).to be_empty @@ -66,17 +70,20 @@ let(:product_error1) { instance_double(Y2Storage::SetupError, message: "product error 1") } let(:product_error2) { instance_double(Y2Storage::SetupError, message: "product error 2") } let(:product_error3) { instance_double(Y2Storage::SetupError, message: "product error 3") } + let(:mount_error1) { instance_double(Y2Storage::SetupError, message: "missing option 1") } let(:boot_errors) { [boot_error1, boot_error2] } let(:product_errors) { [product_error1, product_error2, product_error3] } + let(:mount_errors) { [mount_error1] } it "contains a message for each error" do - expect(subject.to_html.scan(/<li>/).size).to eq(5) + expect(subject.to_html.scan(/<li>/).size).to eq(6) end context "and there are boot errors" do let(:boot_errors) { [boot_error1] } let(:product_errors) { [] } + let(:mount_errors) { [] } it "contains a general error message for boot errors" do expect(subject.to_html).to match(/not be able to boot/) @@ -85,11 +92,16 @@ it "does not contain a general error message for product errors" do expect(subject.to_html).to_not match(/could not work/) end + + it "does not contain a general error message for product errors" do + expect(subject.to_html).to_not match(/mount point during boot/) + end end context "and there are product errors" do let(:boot_errors) { [] } let(:product_errors) { [product_error1] } + let(:mount_errors) { [] } it "contains a general error message for product errors" do expect(subject.to_html).to match(/could not work/) @@ -98,11 +110,34 @@ it "does not contain a general error message for boot errors" do expect(subject.to_html).to_not match(/not be able to boot/) end + + it "does not contain a general error message for mount errors" do + expect(subject.to_html).to_not match(/mount point during boot/) + end + end + + context "and there are mount errors" do + let(:boot_errors) { [] } + let(:product_errors) { [] } + let(:mount_errors) { [mount_error1] } + + it "contains a general error message for mount errors" do + expect(subject.to_html).to match(/mount point during boot/) + end + + it "does not contain a general error message for boot errors" do + expect(subject.to_html).to_not match(/not be able to boot/) + end + + it "does not contain a general error message for product errors" do + expect(subject.to_html).to_not match(/could not work/) + end end - context "and there are boot and product errors" do + context "and there are boot, product and mount errors" do let(:boot_errors) { [boot_error1] } let(:product_errors) { [product_error1] } + let(:mount_errors) { [mount_error1] } it "contains a general error message for boot errors" do expect(subject.to_html).to match(/not be able to boot/) @@ -111,6 +146,10 @@ it "contains a general error message for product errors" do expect(subject.to_html).to match(/could not work/) end + + it "contains a general error message for mount errors" do + expect(subject.to_html).to match(/mount point during boot/) + end end end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-storage-ng-4.4.27/test/y2storage/setup_checker_test.rb new/yast2-storage-ng-4.4.28/test/y2storage/setup_checker_test.rb --- old/yast2-storage-ng-4.4.27/test/y2storage/setup_checker_test.rb 2021-12-17 16:37:31.000000000 +0100 +++ new/yast2-storage-ng-4.4.28/test/y2storage/setup_checker_test.rb 2021-12-20 17:32:39.000000000 +0100 @@ -50,6 +50,11 @@ allow(Y2Storage::ProposalSettings).to receive(:new_for_current_product).and_return(settings) allow(settings).to receive(:volumes).and_return(product_volumes) + + # We have to use allow_any_instance due to the nature of libstorage-ng bindings (they return + # a different object for each query to the devicegraph) + allow_any_instance_of(Y2Storage::Filesystems::BlkFilesystem).to receive(:missing_mount_options) + .and_return(missing_root_opts) end let(:boot_checker) { instance_double(Y2Storage::BootRequirementsChecker) } @@ -62,6 +67,8 @@ let(:product_volumes) { [] } + let(:missing_root_opts) { [] } + let(:boot_error) { instance_double(Y2Storage::SetupError) } let(:root_volume) do @@ -115,6 +122,18 @@ end end + context "when there is some error in the mount options" do + before { create_root } + + let(:product_volumes) { [] } + let(:boot_warnings) { [] } + let(:missing_root_opts) { ["_netdev"] } + + it "returns false" do + expect(subject.valid?).to eq(false) + end + end + context "when there is a fatal error" do let(:fatal_errors) { [boot_error] } @@ -126,6 +145,7 @@ context "when all mandatory product volumes are present in the system and there is no boot error" do let(:product_volumes) { [root_volume, home_volume] } let(:boot_warnings) { [] } + let(:missing_root_opts) { [] } before do create_root @@ -167,7 +187,7 @@ end end - context "when there is no boot error and all mandatory product volumes are present in the system" do + context "when there is no boot error, mount options are ok and all mandatory volumes are present" do let(:boot_warnings) { [] } let(:product_volumes) { [root_volume, home_volume] } @@ -179,6 +199,16 @@ expect(subject.warnings).to be_empty end end + + context "when a mount option is missing for some mount point" do + before { create_root } + let(:boot_warnings) { [] } + let(:missing_root_opts) { ["_netdev"] } + + it "includes an error mentioning the missing option" do + expect(subject.warnings.map(&:message)).to include(an_object_matching(/_netdev/)) + end + end end describe "#boot_warnings" do @@ -274,4 +304,56 @@ end end end + + describe "#mount_warnings" do + before { create_root } + + let(:boot_error1) { instance_double(Y2Storage::SetupError) } + let(:boot_error2) { instance_double(Y2Storage::SetupError) } + let(:boot_warnings) { [boot_error1, boot_error2] } + + context "if there are no missing mount options" do + let(:missing_root_opts) { [] } + + it "returns an empty list" do + expect(subject.mount_warnings).to be_empty + end + end + + context "if there is a missing mount option for a given mount point" do + let(:missing_root_opts) { ["extra_option"] } + + it "returns a list of setup errors" do + expect(subject.product_warnings).to all(be_a(Y2Storage::SetupError)) + end + + it "does not include boot errors" do + expect(subject.product_warnings).to_not include(boot_error1, boot_error2) + end + + it "includes an error for the affected mount point and missing option" do + warning = subject.mount_warnings.first + expect(warning.message).to include "/" + expect(warning.message).to include "extra_option" + end + end + + context "if there are several missing mount options for the same mount point" do + let(:missing_root_opts) { ["one", "two"] } + + it "returns a list of setup errors" do + expect(subject.product_warnings).to all(be_a(Y2Storage::SetupError)) + end + + it "does not include boot errors" do + expect(subject.product_warnings).to_not include(boot_error1, boot_error2) + end + + it "includes an error for the affected mount point with all the missing options" do + warning = subject.mount_warnings.first + expect(warning.message).to include "/" + expect(warning.message).to include "one,two" + end + end + end end