Hello community, here is the log from the commit of package autoyast2 for openSUSE:Factory checked in at 2020-08-01 12:31:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/autoyast2 (Old) and /work/SRC/openSUSE:Factory/.autoyast2.new.3592 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "autoyast2" Sat Aug 1 12:31:42 2020 rev:285 rq:823700 version:4.3.32 Changes: -------- --- /work/SRC/openSUSE:Factory/autoyast2/autoyast2.changes 2020-07-30 10:01:44.431279972 +0200 +++ /work/SRC/openSUSE:Factory/.autoyast2.new.3592/autoyast2.changes 2020-08-01 12:32:00.206503178 +0200 @@ -1,0 +2,13 @@ +Thu Jul 30 14:00:17 UTC 2020 - Knut Anderssen <kanderssen@suse.com> + +- Do not report profile validation errors multiple times if the + errors are the same already reported and accepted (bsc#1173091) +- 4.3.32 + +------------------------------------------------------------------- +Thu Jul 30 13:31:01 CEST 2020 - schubi@suse.de + +- Adapted doc: Calling of post-partitioning scripts moved from + dropped inst_autoimage to inst_kickoff (bsc#1140711). + +------------------------------------------------------------------- Old: ---- autoyast2-4.3.31.tar.bz2 New: ---- autoyast2-4.3.32.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ autoyast2.spec ++++++ --- /var/tmp/diff_new_pack.lf2Tdo/_old 2020-08-01 12:32:01.182504091 +0200 +++ /var/tmp/diff_new_pack.lf2Tdo/_new 2020-08-01 12:32:01.186504095 +0200 @@ -22,7 +22,7 @@ %endif Name: autoyast2 -Version: 4.3.31 +Version: 4.3.32 Release: 0 Summary: YaST2 - Automated Installation License: GPL-2.0-only ++++++ autoyast2-4.3.31.tar.bz2 -> autoyast2-4.3.32.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/package/autoyast2.changes new/autoyast2-4.3.32/package/autoyast2.changes --- old/autoyast2-4.3.31/package/autoyast2.changes 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/package/autoyast2.changes 2020-07-31 10:35:35.000000000 +0200 @@ -1,4 +1,17 @@ ------------------------------------------------------------------- +Thu Jul 30 14:00:17 UTC 2020 - Knut Anderssen <kanderssen@suse.com> + +- Do not report profile validation errors multiple times if the + errors are the same already reported and accepted (bsc#1173091) +- 4.3.32 + +------------------------------------------------------------------- +Thu Jul 30 13:31:01 CEST 2020 - schubi@suse.de + +- Adapted doc: Calling of post-partitioning scripts moved from + dropped inst_autoimage to inst_kickoff (bsc#1140711). + +------------------------------------------------------------------- Mon Jul 27 17:01:01 CEST 2020 - schubi@suse.de - Removed "image" section from "software" section (bsc#1140711). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/package/autoyast2.spec new/autoyast2-4.3.32/package/autoyast2.spec --- old/autoyast2-4.3.31/package/autoyast2.spec 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/package/autoyast2.spec 2020-07-31 10:35:35.000000000 +0200 @@ -22,7 +22,7 @@ %endif Name: autoyast2 -Version: 4.3.31 +Version: 4.3.32 Release: 0 Summary: YaST2 - Automated Installation License: GPL-2.0-only diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/src/lib/autoinstall/autosetup_helpers.rb new/autoyast2-4.3.32/src/lib/autoinstall/autosetup_helpers.rb --- old/autoyast2-4.3.31/src/lib/autoinstall/autosetup_helpers.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/src/lib/autoinstall/autosetup_helpers.rb 2020-07-31 10:35:35.000000000 +0200 @@ -56,7 +56,7 @@ return :not_found end - return :abort unless Y2Autoinstallation::XmlChecks.valid_modified_profile? + return :abort unless profile_checker.valid_modified_profile? if !Yast::Profile.ReadXML(Yast::AutoinstConfig.modified_profile) || Yast::Profile.current == {} @@ -193,6 +193,10 @@ Yast::Profile.remove_sections("language") if Yast::Profile.current.key?("language") end + def profile_checker + Y2Autoinstallation::XmlChecks.instance + end + private def utf8_supported? diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/src/lib/autoinstall/xml_checks.rb new/autoyast2-4.3.32/src/lib/autoinstall/xml_checks.rb --- old/autoyast2-4.3.31/src/lib/autoinstall/xml_checks.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/src/lib/autoinstall/xml_checks.rb 2020-07-31 10:35:35.000000000 +0200 @@ -22,6 +22,7 @@ require "yast" require "autoinstall/xml_validator" require "yast2/popup" +require "yaml" Yast.import "AutoinstConfig" Yast.import "Report" @@ -31,19 +32,28 @@ # for not well formed or invalid documents. It is possible to continue # anyway and ignore the found problems at your risk. class XmlChecks - extend Yast::Logger - extend Yast::I18n - textdomain "autoinst" + include Singleton + include Yast::Logger + include Yast::I18n # paths to the default AutoYaST schema files PROFILE_SCHEMA = "/usr/share/YaST2/schema/autoyast/rng/profile.rng".freeze RULES_SCHEMA = "/usr/share/YaST2/schema/autoyast/rng/rules.rng".freeze CLASSES_SCHEMA = "/usr/share/YaST2/schema/autoyast/rng/classes-use.rng".freeze + ERRORS_PATH = "/var/lib/YaST2/xml_checks_errors".freeze + + # Constructor + def initialize + textdomain "autoinst" + + @reported_errors = errors_from_file + end + # Is the file a valid AutoYaST XML profile? # @param file [String] pahth to the classes file # @return [Boolean] true if valid, false otherwise - def self.valid_profile?(file = Yast::AutoinstConfig.xml_tmpfile) + def valid_profile?(file = Yast::AutoinstConfig.xml_tmpfile) # TRANSLATORS: Error message msg = _("The AutoYaST profile is not a valid XML document.") check(file, PROFILE_SCHEMA, msg) @@ -51,7 +61,7 @@ # Is the file a valid AutoYaST XML profile? # @return [Boolean] true if valid, false otherwise - def self.valid_modified_profile? + def valid_modified_profile? # TRANSLATORS: Error message msg = _("The AutoYaST pre-script generated an invalid XML document.") check(Yast::AutoinstConfig.modified_profile, PROFILE_SCHEMA, msg) @@ -59,7 +69,7 @@ # Is the file a valid AutoYaST rules file? # @return [Boolean] true if valid, false otherwise - def self.valid_rules? + def valid_rules? # TRANSLATORS: Error message msg = _("The AutoYaST rules file is not a valid XML document.") check(Yast::AutoinstConfig.local_rules_file, RULES_SCHEMA, msg) @@ -68,7 +78,7 @@ # Is the file a valid AutoYaST class file? # @param file [String] path to the classes file # @return [Boolean] true if valid, false otherwise - def self.valid_classes?(file) + def valid_classes?(file) # TRANSLATORS: Error message msg = _("The AutoYaST class file is not a valid XML document.") check(file, RULES_SCHEMA, msg) @@ -79,9 +89,9 @@ # @param schema [String] path to the RNG schema # @param msg [String] title displayed in the popup when validation fails # @return [Boolean] true if valid, false otherwise - def self.check(file, schema, msg) + def check(file, schema, msg) validator = XmlValidator.new(file, schema) - return true if validator.valid? + return true if validator.valid? || !new_errors?(validator.errors) if ENV["YAST_SKIP_XML_VALIDATION"] == "1" log.warn "Skipping invalid XML!" @@ -94,17 +104,62 @@ buttons: :continue_cancel, focus: :cancel) == :continue - log.warn "Skipping invalid XML on user request!" if ret + if ret + log.warn "Skipping invalid XML on user request and storing validation errors!" + store_errors(validator.errors) + end ret end + private + + # Convenience method to check whether the list of validation errors have + # been already reported and accepted by the user or not. + # + # @param errors [Array<String>] list of validation errors + # @return [Boolean] whether the validation errors are new or not + def new_errors?(errors) + return true if (reported_errors || []).empty? + + !reported_errors.include?(digest_hash(errors)) + end + + # Convenience method to save to a file the hash sum of the already + # reported errors + # + # @param errors [Array<String>] list of validation errors + def store_errors(errors) + @reported_errors << digest_hash(errors) + + File.write(ERRORS_PATH, reported_errors.to_yaml) + end + + # Convenience method to obtain the digest hash for the given errors + # + # @param errors [Array<String>] list of validation errors + def digest_hash(errors) + Digest::MD5.hexdigest(errors.to_yaml) + end + + # Convenience method to load the errors reported from a file + def errors_from_file + return [] unless File.exist?(ERRORS_PATH) + + YAML.safe_load(File.read(ERRORS_PATH)) + end + + # @return [Array<String>] array with the reported errors hash sums + def reported_errors + @reported_errors ||= [] + end + # an internal helper for building the error message # @param msg [String] title text # @param errors [Array<String>] list of validation errors # @param file [String] path to the XML file (only the base name is displayed) # @param schema [String] path to the RNG schema - def self.message(msg, errors, file, schema) + def message(msg, errors, file, schema) xml_file = File.basename(file) jing_command = "jing #{schema} #{xml_file}" xmllint_command = "xmllint --noout --relaxng #{schema} #{xml_file}" @@ -122,7 +177,5 @@ " %{jing}<br>" \ " %{xmllint}"), jing: jing_command, xmllint: xmllint_command) + "</p>" end - - private_class_method :message end end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/src/modules/AutoInstallRules.rb new/autoyast2-4.3.32/src/modules/AutoInstallRules.rb --- old/autoyast2-4.3.31/src/modules/AutoInstallRules.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/src/modules/AutoInstallRules.rb 2020-07-31 10:35:35.000000000 +0200 @@ -899,7 +899,7 @@ log.info("Working on file: #{file}") current_profile = File.join(AutoinstConfig.local_rules_location, file) - if !Y2Autoinstallation::XmlChecks.valid_profile?(current_profile) + if !Y2Autoinstallation::XmlChecks.instance.valid_profile?(current_profile) error = true next end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/src/modules/AutoinstClass.rb new/autoyast2-4.3.32/src/modules/AutoinstClass.rb --- old/autoyast2-4.3.31/src/modules/AutoinstClass.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/src/modules/AutoinstClass.rb 2020-07-31 10:35:35.000000000 +0200 @@ -52,7 +52,7 @@ # Reads classes def Read if SCR.Read(path(".target.size"), @classPath) != -1 && - Y2Autoinstallation::XmlChecks.valid_classes?(@classPath) + Y2Autoinstallation::XmlChecks.instance.valid_classes?(@classPath) begin classes_map = XML.XMLToYCPFile(@classPath) @Classes = (classes_map && classes_map["classes"]) || [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/src/modules/AutoinstScripts.rb new/autoyast2-4.3.32/src/modules/AutoinstScripts.rb --- old/autoyast2-4.3.31/src/modules/AutoinstScripts.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/src/modules/AutoinstScripts.rb 2020-07-31 10:35:35.000000000 +0200 @@ -31,8 +31,7 @@ # directory. # # #### Post Partitioning Scripts - # Runs after partitioning from {Yast::InstAutoimageClient} unconditionaly even when images is - # not used. + # Runs after partitioning from {Yast::InstKickoffClient} # class AutoinstScriptsClass < Module include Yast::Logger diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/src/modules/ProfileLocation.rb new/autoyast2-4.3.32/src/modules/ProfileLocation.rb --- old/autoyast2-4.3.31/src/modules/ProfileLocation.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/src/modules/ProfileLocation.rb 2020-07-31 10:35:35.000000000 +0200 @@ -30,6 +30,10 @@ ProfileLocation() end + def profile_checker + Y2Autoinstallation::XmlChecks.instance + end + # Constructor # @return [void] def ProfileLocation @@ -176,7 +180,7 @@ ) end - return false if !is_directory && !Y2Autoinstallation::XmlChecks.valid_profile? + return false if !is_directory && !profile_checker.valid_profile? ret = if is_directory Get( @@ -204,7 +208,7 @@ if AutoInstallRules.userrules Builtins.y2milestone("Reading Rules File") # display an error when the rules file is not valid and return false - return false unless Y2Autoinstallation::XmlChecks.valid_rules? + return false unless profile_checker.valid_rules? AutoInstallRules.Read # returns false if no rules have matched @@ -232,7 +236,7 @@ if process_rules rulesret = AutoInstallRules.Process(AutoinstConfig.xml_tmpfile) # validate the profile - return false if rulesret && !Y2Autoinstallation::XmlChecks.valid_profile? + return false if rulesret && !profile_checker.valid_profile? Builtins.y2milestone("rulesret=%1", rulesret) return rulesret diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/test/AutoInstallRules_test.rb new/autoyast2-4.3.32/test/AutoInstallRules_test.rb --- old/autoyast2-4.3.31/test/AutoInstallRules_test.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/test/AutoInstallRules_test.rb 2020-07-31 10:35:35.000000000 +0200 @@ -6,10 +6,11 @@ describe "Yast::AutoInstallRules" do subject { Yast::AutoInstallRules } + let(:profile_checker) { Y2Autoinstallation::XmlChecks.instance } before do Y2Storage::StorageManager.create_test_instance - allow(Y2Autoinstallation::XmlChecks).to receive(:valid_profile?).and_return(true) + allow(profile_checker).to receive(:valid_profile?).and_return(true) end let(:root_path) { File.expand_path("..", __dir__) } @@ -328,7 +329,7 @@ context "when a profile is not valid" do it "returns false" do subject.CreateFile("first.xml") - expect(Y2Autoinstallation::XmlChecks).to receive(:valid_profile?) + expect(profile_checker).to receive(:valid_profile?) .and_return(false) expect(subject.Merge(result_path)).to eq(false) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/test/AutoinstClass_test.rb new/autoyast2-4.3.32/test/AutoinstClass_test.rb --- old/autoyast2-4.3.31/test/AutoinstClass_test.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/test/AutoinstClass_test.rb 2020-07-31 10:35:35.000000000 +0200 @@ -16,7 +16,7 @@ before(:each) do subject.class_dir = CLASS_DIR - allow(Y2Autoinstallation::XmlChecks).to receive(:valid_classes?).and_return(true) + allow(Y2Autoinstallation::XmlChecks.instance).to receive(:valid_classes?).and_return(true) end describe "#Read" do @@ -65,7 +65,7 @@ before(:each) do allow(Yast::SCR).to receive(:Read).and_call_original allow(Yast::SCR).to receive(:Read).with(Yast::Path.new(".xml"), CLASS_PATH).and_return(nil) - expect(Y2Autoinstallation::XmlChecks).to receive(:valid_classes?).and_return(false) + expect(Y2Autoinstallation::XmlChecks.instance).to receive(:valid_classes?).and_return(false) end it "set Classes to []" do diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/test/lib/autosetup_helpers_test.rb new/autoyast2-4.3.32/test/lib/autosetup_helpers_test.rb --- old/autoyast2-4.3.31/test/lib/autosetup_helpers_test.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/test/lib/autosetup_helpers_test.rb 2020-07-31 10:35:35.000000000 +0200 @@ -34,7 +34,8 @@ let(:profile_dir_path) { File.join(TESTS_PATH, "tmp") } before do - allow(Y2Autoinstallation::XmlChecks).to receive(:valid_modified_profile?).and_return(true) + allow(Y2Autoinstallation::XmlChecks.instance) + .to receive(:valid_modified_profile?).and_return(true) end describe "#probe_storage" do @@ -213,7 +214,7 @@ context "when the modified profile is not valid" do before do - expect(Y2Autoinstallation::XmlChecks).to receive(:valid_modified_profile?) + expect(Y2Autoinstallation::XmlChecks.instance).to receive(:valid_modified_profile?) .and_return(false) end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/test/lib/clients/inst_autoinit_test.rb new/autoyast2-4.3.32/test/lib/clients/inst_autoinit_test.rb --- old/autoyast2-4.3.31/test/lib/clients/inst_autoinit_test.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/test/lib/clients/inst_autoinit_test.rb 2020-07-31 10:35:35.000000000 +0200 @@ -27,6 +27,7 @@ allow(Yast::WFM).to receive(:CallFunction).and_return(true) # can easily ends up in endless loop allow(subject).to receive(:ProfileSourceDialog).and_return("") + allow(subject).to receive(:autoinit_scripts).and_return(:ok) allow(Yast::Linuxrc).to receive(:useiscsi).and_return(false) allow(Yast::Linuxrc).to receive(:InstallInf).and_return(nil) allow(Yast::ProfileLocation).to receive(:Process).and_return(true) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/autoyast2-4.3.31/test/lib/xml_checks_test.rb new/autoyast2-4.3.32/test/lib/xml_checks_test.rb --- old/autoyast2-4.3.31/test/lib/xml_checks_test.rb 2020-07-29 18:30:30.000000000 +0200 +++ new/autoyast2-4.3.32/test/lib/xml_checks_test.rb 2020-07-31 10:35:35.000000000 +0200 @@ -4,25 +4,132 @@ require "autoinstall/xml_checks" describe Y2Autoinstallation::XmlChecks do + let(:subject) { described_class.instance } + let(:errors_path) { File.join(FIXTURES_PATH, "xml_checks_errors") } before do + stub_const("Y2Autoinstallation::XmlChecks::ERRORS_PATH", errors_path) # mock the popup to avoid accidentally displaying a popup in tests allow(Yast2::Popup).to receive(:show) end describe ".valid_profile?" do + let(:valid) { true } + + before do + allow(subject).to receive(:check).and_return(valid) + end + + it "checks whether a given profile is valid or not" do + expect(subject).to receive(:check) + + subject.valid_profile? + end + + context "when a valid profile is used" do + it "returns true" do + expect(subject.valid_profile?).to eql(true) + end + end + + context "when an invalid profile is used" do + let(:valid) { false } + + it "returns false" do + expect(subject.valid_profile?).to eql(false) + end + end + end + + describe ".check" do + let(:xml_name) { "foo.xml" } + let(:schema_name) { "bar.rng" } + let(:xml) { Pathname.new(xml_name) } + let(:schema) { Pathname.new(schema_name) } + let(:valid) { true } + let(:errors) { ["ERROR"] } + let(:validator) do + instance_double(Y2Autoinstallation::XmlValidator, valid?: valid, errors: errors) + end + + after do + File.delete errors_path if File.exist?(errors_path) + end + before do - expect_any_instance_of(Y2Autoinstallation::XmlValidator).to receive(:valid?) - .and_return(valid) + allow(Y2Autoinstallation::XmlValidator).to receive(:new).and_return(validator) + reset_singleton(Y2Autoinstallation::XmlChecks) end - context "valid profile" do - let(:valid) { true } + context "when the profile is a valid one" do + it "returns true" do + expect(subject.check(xml, schema, "title")).to eq(true) + end end - context "invalid profile" do + context "when the profile is an invalid one" do let(:valid) { false } + let(:popup_selection) { :continue } + before do + allow(Yast2::Popup).to receive(:show).and_return(popup_selection) + end + + context "and it is the first time that the errors have been reported" do + it "returns true if the user skipped the validation" do + allow(ENV).to receive(:"[]").with("YAST_SKIP_XML_VALIDATION").and_return("1") + + expect(Yast2::Popup).to_not receive(:show) + expect(subject.check(xml, schema, "title")).to eql(true) + end + + it "shows a popup" do + expect(Yast2::Popup).to receive(:show) + + subject.check(xml, schema, "title") + end + + context "if the user continues with the errors reported" do + it "stores the errors reported" do + expect { subject.check(xml, schema, "title") } + .to change { File.exist?(errors_path) }.from(false).to(true) + end + + it "returns true" do + expect(subject.check(xml, schema, "title")).to eql(true) + end + end + + context "if the user cancels" do + let(:popup_selection) { :cancel } + + it "does not stores them" do + expect(subject).to_not receive(:store_errors) + + subject.check(xml, schema, "title") + end + + it "returns false" do + expect(subject.check(xml, schema, "title")).to eql(false) + end + end + end + + context "and the same errors were already reported" do + before do + subject.check(xml, schema, "title") + end + + it "does not show any popup" do + expect(Yast2::Popup).to_not receive(:show) + + subject.check(xml, schema, "title") + end + + it "returns true" do + expect(subject.check(xml, schema, "title")).to eql(true) + end + end end end end