Hello community, here is the log from the commit of package yast2-add-on for openSUSE:Factory checked in at 2018-04-26 13:28:36 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/yast2-add-on (Old) and /work/SRC/openSUSE:Factory/.yast2-add-on.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "yast2-add-on" Thu Apr 26 13:28:36 2018 rev:91 rq:596189 version:4.0.8 Changes: -------- --- /work/SRC/openSUSE:Factory/yast2-add-on/yast2-add-on.changes 2018-03-26 12:15:41.307677387 +0200 +++ /work/SRC/openSUSE:Factory/.yast2-add-on.new/yast2-add-on.changes 2018-04-26 13:28:37.844745684 +0200 @@ -1,0 +2,7 @@ +Thu Apr 12 06:44:36 UTC 2018 - [email protected] + +- Allow the user to change the CD/DVD when using addon=dvd:/// + (bsc#1082789). +- 4.0.8 + +------------------------------------------------------------------- Old: ---- yast2-add-on-4.0.7.tar.bz2 New: ---- yast2-add-on-4.0.8.tar.bz2 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ yast2-add-on.spec ++++++ --- /var/tmp/diff_new_pack.Qaa1MX/_old 2018-04-26 13:28:38.748712576 +0200 +++ /var/tmp/diff_new_pack.Qaa1MX/_new 2018-04-26 13:28:38.748712576 +0200 @@ -17,7 +17,7 @@ Name: yast2-add-on -Version: 4.0.7 +Version: 4.0.8 Release: 0 Summary: YaST2 - Add-On media installation code License: GPL-2.0 @@ -62,6 +62,9 @@ %defattr(-,root,root) %dir %{yast_yncludedir}/add-on %{yast_yncludedir}/add-on/* +%dir %{yast_libdir}/add-on +%dir %{yast_libdir}/add-on/clients +%{yast_libdir}/add-on/clients/*.rb %{yast_clientdir}/add-on.rb %{yast_clientdir}/add-on_*.rb %{yast_clientdir}/inst_add-on*.rb ++++++ yast2-add-on-4.0.7.tar.bz2 -> yast2-add-on-4.0.8.tar.bz2 ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-add-on-4.0.7/package/yast2-add-on.changes new/yast2-add-on-4.0.8/package/yast2-add-on.changes --- old/yast2-add-on-4.0.7/package/yast2-add-on.changes 2018-03-22 14:52:06.000000000 +0100 +++ new/yast2-add-on-4.0.8/package/yast2-add-on.changes 2018-04-13 09:23:34.000000000 +0200 @@ -1,4 +1,11 @@ ------------------------------------------------------------------- +Thu Apr 12 06:44:36 UTC 2018 - [email protected] + +- Allow the user to change the CD/DVD when using addon=dvd:/// + (bsc#1082789). +- 4.0.8 + +------------------------------------------------------------------- Thu Mar 22 13:24:31 CET 2018 - [email protected] - AutoYaST: Reporting missing AY configuration file entries. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-add-on-4.0.7/package/yast2-add-on.spec new/yast2-add-on-4.0.8/package/yast2-add-on.spec --- old/yast2-add-on-4.0.7/package/yast2-add-on.spec 2018-03-22 14:52:06.000000000 +0100 +++ new/yast2-add-on-4.0.8/package/yast2-add-on.spec 2018-04-13 09:23:34.000000000 +0200 @@ -17,7 +17,7 @@ Name: yast2-add-on -Version: 4.0.7 +Version: 4.0.8 Release: 0 Summary: YaST2 - Add-On media installation code License: GPL-2.0 @@ -62,6 +62,9 @@ %defattr(-,root,root) %dir %{yast_yncludedir}/add-on %{yast_yncludedir}/add-on/* +%dir %{yast_libdir}/add-on +%dir %{yast_libdir}/add-on/clients +%{yast_libdir}/add-on/clients/*.rb %{yast_clientdir}/add-on.rb %{yast_clientdir}/add-on_*.rb %{yast_clientdir}/inst_add-on*.rb diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-add-on-4.0.7/src/clients/inst_add-on.rb new/yast2-add-on-4.0.8/src/clients/inst_add-on.rb --- old/yast2-add-on-4.0.7/src/clients/inst_add-on.rb 2018-03-22 14:52:06.000000000 +0100 +++ new/yast2-add-on-4.0.8/src/clients/inst_add-on.rb 2018-04-13 09:23:34.000000000 +0200 @@ -1,167 +1,3 @@ -# encoding: utf-8 - -# File: clients/inst_add-on.ycp -# Package: yast2-add-on -# Summary: Select add-on products for installation -# Authors: Jiri Srain <[email protected]> -# - -require "tempfile" - -module Yast - # @note This client should not be called from other clients directly - # via WFM.call (only from the control.xml file), it can restart the workflow - # from the next step and return to the caller AFTER the complete workflow - # is finished (or aborted) - class InstAddOnClient < Client - include Yast::Logger - - def main - Yast.import "UI" - Yast.import "Pkg" - textdomain "add-on" - - Yast.import "AddOnProduct" - Yast.import "GetInstArgs" - Yast.import "Packages" - Yast.import "PackageCallbacks" - Yast.import "Popup" - Yast.import "ProductControl" - Yast.import "Report" - Yast.import "Wizard" - Yast.import "Label" - Yast.import "Installation" - Yast.import "Linuxrc" - Yast.import "String" - Yast.import "URL" - - Yast.include self, "add-on/add-on-workflow.rb" - Yast.include self, "packager/repositories_include.rb" - - if AddOnProduct.skip_add_ons - Builtins.y2milestone("Skipping add-ons (as requested before)") - return :auto - end - - @argmap = GetInstArgs.argmap - - Packages.SelectProduct - - PackageCallbacks.SetMediaCallbacks - - # add add-ons specified on the kernel command line - addon_opt = Linuxrc.InstallInf("addon") - - # the "addon" boot option is present - if addon_opt != nil - missing_addons = addon_opt.split(",") - current_addons - - # add the add-ons just once, skip adding if all add-ons are - # already present (handle going back and forth properly) - if missing_addons.empty? - log.info("All kernel cmdline addons already present") - else - # do not reveal the URL passwords in the log - missing_addons_log = missing_addons.map { |a| URL.HidePassword(a) } - log.info("Adding extra add-ons from kernel cmdline: #{missing_addons_log}") - - # network setup is needed when installing from a local medium (DVD) with remote Add-ons - ret = NetworkSetupForAddons(missing_addons) - return ret if Builtins.contains([:back, :abort], ret) - - plaindir, download, name, alias_ = false, true, "", "" - missing_addons.each do |url| - sources_before = Pkg.SourceGetCurrent(false) - Builtins.y2milestone("Sources before adding new one: %1", sources_before) - - createSourceImpl(url, plaindir, download, name, alias_) - - activate_addon_changes(sources_before) - end - InstallProduct() - end - end - - # the module was started because of the kernel command line option - # so finish it after adding the add-ons, no UI is actually needed - return :auto if Installation.add_on_selected == false - - @ret = RunAddOnMainDialog( - GetInstArgs.enable_back, - GetInstArgs.enable_next, - true, - Label.BackButton, - Label.NextButton, - Label.AbortButton, - true - ) - - if @ret == :next - # be careful when calling this client from other modules, this will - # start the workflow from the next step and THEN return back - # to the caller - @ret = ProductControl.RunFrom( - Ops.add(ProductControl.CurrentStep, 1), - true - ) - @ret = :finish if @ret == :next - end - - @ret - - # EOF - end - - # Ask to user to configure network for installing remote addons. - # User is aske when there is a remote add-on found and the network - # is not running yet. - # - # @param addon_urls list of URLs - # @return symbol user input result (`next, `back or `abort) - def NetworkSetupForAddons(addon_urls) - addon_urls = deep_copy(addon_urls) - # protocols locally available (no network needed) - local_protocols = ["cd", "dvd", "hd"] - - # is this CD/DVD/HDD installation? - if Builtins.contains( - local_protocols, - Builtins.tolower(Linuxrc.InstallInf("InstMode")) - ) - # is there any remote addon requiring network setup? - network_needed = false - Builtins.foreach(addon_urls) do |url| - # is it a remote protocol? - if !Builtins.contains( - local_protocols, - Builtins.tolower(Ops.get_string(URL.Parse(url), "scheme", "")) - ) - network_needed = true - raise Break - end - end - - - if network_needed - # check and setup network - ret = Convert.to_symbol(WFM.CallFunction("inst_network_check", [])) - Builtins.y2milestone("inst_network_check ret: %1", ret) - - return ret if Builtins.contains([:back, :abort], ret) - end - end - - :next - end - - # get the URLs of the all present add-ons - # @return [Array<String>] list of URLs (empty list if no add-on defined) - def current_addons - AddOnProduct.add_on_products.map do |addon| - Pkg.SourceURL(addon["media"]) - end - end - end -end +require "add-on/clients/inst_add-on" Yast::InstAddOnClient.new.main diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-add-on-4.0.7/src/lib/add-on/clients/inst_add-on.rb new/yast2-add-on-4.0.8/src/lib/add-on/clients/inst_add-on.rb --- old/yast2-add-on-4.0.7/src/lib/add-on/clients/inst_add-on.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-add-on-4.0.8/src/lib/add-on/clients/inst_add-on.rb 2018-04-13 09:23:34.000000000 +0200 @@ -0,0 +1,212 @@ +# encoding: utf-8 + +# File: clients/inst_add-on.ycp +# Package: yast2-add-on +# Summary: Select add-on products for installation +# Authors: Jiri Srain <[email protected]> +# + +require "tempfile" + +module Yast + # @note This client should not be called from other clients directly + # via WFM.call (only from the control.xml file), it can restart the workflow + # from the next step and return to the caller AFTER the complete workflow + # is finished (or aborted) + class InstAddOnClient < Client + include Yast::Logger + + def main + Yast.import "UI" + Yast.import "Pkg" + textdomain "add-on" + + Yast.import "AddOnProduct" + Yast.import "GetInstArgs" + Yast.import "Packages" + Yast.import "PackageCallbacks" + Yast.import "Popup" + Yast.import "ProductControl" + Yast.import "Report" + Yast.import "Wizard" + Yast.import "Label" + Yast.import "Installation" + Yast.import "Linuxrc" + Yast.import "String" + Yast.import "URL" + + Yast.include self, "add-on/add-on-workflow.rb" + Yast.include self, "packager/repositories_include.rb" + + if AddOnProduct.skip_add_ons + Builtins.y2milestone("Skipping add-ons (as requested before)") + return :auto + end + + @argmap = GetInstArgs.argmap + + Packages.SelectProduct + + PackageCallbacks.SetMediaCallbacks + + # add add-ons specified on the kernel command line + addon_opt = Linuxrc.InstallInf("addon") + + # the "addon" boot option is present + if addon_opt != nil + missing_addons = addon_opt.split(",") - current_addons + + # add the add-ons just once, skip adding if all add-ons are + # already present (handle going back and forth properly) + if missing_addons.empty? + log.info("All kernel cmdline addons already present") + else + # do not reveal the URL passwords in the log + missing_addons_log = missing_addons.map { |a| URL.HidePassword(a) } + log.info("Adding extra add-ons from kernel cmdline: #{missing_addons_log}") + + # network setup is needed when installing from a local medium (DVD) with remote Add-ons + ret = NetworkSetupForAddons(missing_addons) + return ret if Builtins.contains([:back, :abort], ret) + + plaindir, download, name, alias_ = false, true, "", "" + missing_addons.each do |url| + sources_before = Pkg.SourceGetCurrent(false) + Builtins.y2milestone("Sources before adding new one: %1", sources_before) + + next if instsys_dvd?(url) && !AddOnProduct.AskForCD(url, name) + createSourceImpl(url, plaindir, download, name, alias_) + + activate_addon_changes(sources_before) + end + InstallProduct() + end + end + + # the module was started because of the kernel command line option + # so finish it after adding the add-ons, no UI is actually needed + return :auto if Installation.add_on_selected == false + + @ret = RunAddOnMainDialog( + GetInstArgs.enable_back, + GetInstArgs.enable_next, + true, + Label.BackButton, + Label.NextButton, + Label.AbortButton, + true + ) + + if @ret == :next + # be careful when calling this client from other modules, this will + # start the workflow from the next step and THEN return back + # to the caller + @ret = ProductControl.RunFrom( + Ops.add(ProductControl.CurrentStep, 1), + true + ) + @ret = :finish if @ret == :next + end + + @ret + + # EOF + end + + # Ask to user to configure network for installing remote addons. + # User is aske when there is a remote add-on found and the network + # is not running yet. + # + # @param addon_urls list of URLs + # @return symbol user input result (`next, `back or `abort) + def NetworkSetupForAddons(addon_urls) + addon_urls = deep_copy(addon_urls) + # protocols locally available (no network needed) + local_protocols = ["cd", "dvd", "hd"] + + # is this CD/DVD/HDD installation? + if Builtins.contains( + local_protocols, + Builtins.tolower(Linuxrc.InstallInf("InstMode")) + ) + # is there any remote addon requiring network setup? + network_needed = false + Builtins.foreach(addon_urls) do |url| + # is it a remote protocol? + if !Builtins.contains( + local_protocols, + Builtins.tolower(Ops.get_string(URL.Parse(url), "scheme", "")) + ) + network_needed = true + raise Break + end + end + + + if network_needed + # check and setup network + ret = Convert.to_symbol(WFM.CallFunction("inst_network_check", [])) + Builtins.y2milestone("inst_network_check ret: %1", ret) + + return ret if Builtins.contains([:back, :abort], ret) + end + end + + :next + end + + # get the URLs of the all present add-ons + # @return [Array<String>] list of URLs (empty list if no add-on defined) + def current_addons + AddOnProduct.add_on_products.map do |addon| + Pkg.SourceURL(addon["media"]) + end + end + + # URL schemas to be considered as CD/DVD + DVD_SCHEMES = ["cd", "dvd"].freeze + + # Determine whether the URL points to the installation CD/DVD + # + # @param url [String] Add-on URL + # @return [Boolean] true if it points to the installation CD/DVD + def instsys_dvd?(url) + scheme = URL.Parse(url)["scheme"] + return false unless DVD_SCHEMES.include?(scheme.downcase) + + addon_devices = devices_from_url(url) + addon_devices.include?(instsys_device) + end + + # instsys device + # + # @return [String] instsys device; nil if the device could not be + # determined (for instance, when using a network based installation media) + def instsys_device + return @instsys_device if @instsys_device + @instsys_device = devices_from_url(InstURL.installInf2Url).first + end + + # Real device from an URL + # + # Symbolic links are resolved, so real devices are returned. + # + # @param url [String] URL + # @return [Array<String>] Paths to the devices. If no valid devices are found, + # it will return an empty array. + def devices_from_url(url) + parsed = URL.Parse(url) + params = URL.MakeMapFromParams(parsed["query"]) + return [] unless params["devices"] + devices = params["devices"].split(",") # MakeMapFromParams unescapes %2C + + devices.each_with_object([]) do |device, all| + begin + # File.realpath resolves symlinks (e.g. /dev/by-* to real devices like /dev/srX) + all << File.realpath(device) + rescue Errno::ENOENT + end + end + end + end +end diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/yast2-add-on-4.0.7/test/y2add_on/clients/inst_add-on_test.rb new/yast2-add-on-4.0.8/test/y2add_on/clients/inst_add-on_test.rb --- old/yast2-add-on-4.0.7/test/y2add_on/clients/inst_add-on_test.rb 1970-01-01 01:00:00.000000000 +0100 +++ new/yast2-add-on-4.0.8/test/y2add_on/clients/inst_add-on_test.rb 2018-04-13 09:23:34.000000000 +0200 @@ -0,0 +1,169 @@ +require_relative "../../test_helper" +require "add-on/clients/inst_add-on" + +Yast.import "Packages" +Yast.import "Linuxrc" +Yast.import "Installation" +Yast.import "AddOnProduct" + +describe Yast::InstAddOnClient do + describe "#main" do + let(:addons) { "dvd:///?devices=/dev/sr0" } + let(:inst_url) { "dvd:///?devices=/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00001" } + let(:skip_add_ons) { false } + let(:add_on_selected) { false } + + before do + allow(Yast::Packages).to receive(:SelectProduct) + allow(Yast::Linuxrc).to receive(:InstallInf).with("addon").and_return(addons) + allow(subject).to receive(:NetworkSetupForAddons).and_return(:next) + allow(subject).to receive(:InstallProduct) + allow(Yast::AddOnProduct).to receive(:skip_add_ons).and_return(skip_add_ons) + allow(Yast::Installation).to receive(:add_on_selected).and_return(add_on_selected) + allow(Yast::InstURL).to receive(:installInf2Url).and_return(inst_url) + allow(subject).to receive(:RunAddOnMainDialog).and_return(:next) + end + + context "when add-on products selection should be skipped" do + let(:skip_add_ons) { true } + + it "returns :auto" do + expect(subject.main).to eq(:auto) + end + end + + context "when no add-ons are given" do + let(:addons) { nil } + + it "returns :next" do + expect(subject.main).to eq(:auto) + end + end + + context "when an add-on is given" do + let(:addons) { "dvd:///?devices=/dev/sr0" } + let(:instsys_realpath) { "/dev/sr0" } + + before do + allow(File).to receive(:realpath).with("/dev/sr0").and_return("/dev/sr0") + allow(File).to receive(:realpath).with("/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00001") + .and_return(instsys_realpath) + allow(subject).to receive(:createSourceImpl) + end + + context "and it is using the same CD/DVD than instsys" do + let(:accept_dialog) { true } + + before do + allow(Yast::AddOnProduct).to receive(:AskForCD).and_return(accept_dialog) + end + + it "asks the user to change the media" do + expect(Yast::AddOnProduct).to receive(:AskForCD).with(addons, "") + .and_return(true) + subject.main + end + + it "adds the given add-on" do + expect(subject).to receive(:createSourceImpl).with(addons, *any_args) + subject.main + end + + context "and the user rejects the dialog" do + let(:accept_dialog) { false } + + it "does not add the add-on" do + expect(subject).to_not receive(:createSourceImpl) + subject.main + end + end + end + + context "and it is using a different CD/DVD than instsys" do + let(:instsys_realpath) { "/dev/sr1" } + + it "does not ask the user to change the media" do + expect(Yast::AddOnProduct).to_not receive(:AskForCD) + subject.main + end + + it "adds the given add-on" do + expect(subject).to receive(:createSourceImpl).with(addons, *any_args) + subject.main + end + end + + context "and the device does not exist" do + before do + allow(File).to receive(:realpath).with("/dev/sr0").and_raise(Errno::ENOENT) + end + + it "does not ask the user to change the media" do + expect(Yast::AddOnProduct).to_not receive(:AskForCD) + subject.main + end + end + + context "and it is not using a CD/DVD" do + let(:addons) { "http://example.net/add-on" } + + it "does not ask the user to change the media" do + expect(Yast::AddOnProduct).to_not receive(:AskForCD) + subject.main + end + + it "adds the given add-on" do + expect(subject).to receive(:createSourceImpl).with(addons, *any_args) + subject.main + end + end + + context "and it is not installing from a CD/DVD" do + let(:inst_url) { "http://example.net/sle/DVD1" } + + it "does not ask the user to change the media" do + expect(Yast::AddOnProduct).to_not receive(:AskForCD) + subject.main + end + + it "adds the given add-on" do + expect(subject).to receive(:createSourceImpl).with(addons, *any_args) + subject.main + end + end + + context "when a list of devices is given for an add-on" do + let(:addons) { "dvd:///?devices=/dev/sr0%2C/dev/sr1" } + let(:instsys_realpath) { "/dev/sr1" } + + before do + allow(File).to receive(:realpath).with("/dev/sr1").and_return("/dev/sr1") + end + + context "and some device matches the instsys media" do + it "asks the user to change the media" do + expect(Yast::AddOnProduct).to receive(:AskForCD).with(addons, "") + .and_return(true) + subject.main + end + end + + context "and none of the device matches the instsys media" do + let(:instsys_realpath) { "/dev/sr2" } + + it "does not ask the user to change the media" do + expect(Yast::AddOnProduct).to_not receive(:AskForCD) + subject.main + end + end + end + end + + context "when UI is actually needed" do + let(:add_on_selected) { true } + + it "runs add-on main dialog" + it "starts workflow" + end + end +end
