From 7b61422a8555a10fe20d4310c026cb0d65a84563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ladislav=20Slez=C3=A1k?= Date: Mon, 26 Feb 2018 13:08:52 +0100 Subject: [PATCH] Install the packages needed for accessing the repositories (bsc#1063980) - Install e.g. "nfs-client" for "nfs://" repositories - Additionally evaluate also the add-on repositories, not just the base product repository - 4.0.42 --- package/yast2-packager.changes | 9 +++ package/yast2-packager.spec | 2 +- src/modules/Packages.rb | 58 +++++++++++++---- test/packages_test.rb | 115 ++++++++++++++++++++++++++++++++- 4 files changed, 169 insertions(+), 15 deletions(-) diff --git a/package/yast2-packager.changes b/package/yast2-packager.changes index 735801812..854d4f698 100644 --- a/package/yast2-packager.changes +++ b/package/yast2-packager.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Mon Feb 26 12:05:46 UTC 2018 - lslezak@suse.cz + +- Fixed installing packages needed for accessing the installation + repositories (e.g. "nfs-client" for "nfs://" repositories), + additionally evaluate also the add-on repositories, not just the + base product repository (bsc#1063980) +- 4.0.42 + ------------------------------------------------------------------- Thu Feb 22 17:17:31 CET 2018 - schubi@suse.de diff --git a/package/yast2-packager.spec b/package/yast2-packager.spec index f7381f3f9..6550d6ce7 100644 --- a/package/yast2-packager.spec +++ b/package/yast2-packager.spec @@ -17,7 +17,7 @@ Name: yast2-packager -Version: 4.0.41 +Version: 4.0.42 Release: 0 BuildRoot: %{_tmppath}/%{name}-%{version}-build diff --git a/src/modules/Packages.rb b/src/modules/Packages.rb index 08677e6fc..2c4ca832c 100644 --- a/src/modules/Packages.rb +++ b/src/modules/Packages.rb @@ -5,6 +5,7 @@ require "erb" require "fileutils" require "uri" +require "cgi" # Yast namespace module Yast @@ -1050,23 +1051,54 @@ def boardPackages # Compute packages required to access the repository # @return [Array](string) list of the required packages def sourceAccessPackages - # TODO: rather check all registered repositories... - ret = [] + packages = [] + schemes = repo_schemes - instmode = Linuxrc.InstallInf("InstMode") - Builtins.y2milestone("Installation mode: %1", instmode) + # /sbin/mount.cifs is required to mount a SMB/CIFS share + packages << "cifs-mount" if schemes.include?("smb") || schemes.include?("cifs") - if instmode == "smb" || instmode == "cifs" - # /sbin/mount.cifs is required to mount a SMB/CIFS share - ret = ["cifs-mount"] - elsif instmode == "nfs" - # portmap is required to mount an NFS export - ret = ["nfs-client"] - end + # portmap is required to mount an NFS export + packages << "nfs-client" if schemes.include?("nfs") - Builtins.y2milestone("Packages for accessing the repository: %1", ret) + log.info("Packages for accessing the repositories: #{packages.inspect}") + packages + end - deep_copy(ret) + # Return the URL schemes for the currently defined repositories (only enabled + # repositories are evaluated). For ISO repositories the base URL schema + # is returned (i.e. the location of the ISO), invalid URLs are ignored. + # @return [Array] the list of the URL schemes, empty if + # no repository is defined + def repo_schemes + schemes = [] + + # all enabled repositories + Pkg.SourceGetCurrent(true).map do |repo| + url = Pkg.SourceURL(repo) + + begin + uri = URI(url) + + # handle the ISO scheme specifically + # Note: scheme is converted to lowercase by Ruby + if uri.scheme == "iso" && uri.query + # parse the query string into a hash, extract the base URL from the query + # CGI.parse output is a hash: key => [val1, val2, ...] + params = CGI.parse(uri.query) + # expect only one "url" parameter + scheme = URI(params["url"].first).scheme if params["url"] && !params["url"].empty? + else + scheme = uri.scheme + end + + schemes << scheme if scheme && !schemes.include?(scheme) + # normally should not happen, the URLs from libzypp should be always valid + rescue URI::InvalidURIError => e + log.error(e.message) + end + end + + schemes end # Additional kernel packages from control file diff --git a/test/packages_test.rb b/test/packages_test.rb index 11f44415d..3efd68e6e 100755 --- a/test/packages_test.rb +++ b/test/packages_test.rb @@ -36,7 +36,8 @@ def load_zypp(file_name) PRODUCTS_FROM_ZYPP = load_zypp("products.yml").freeze -describe Yast::Packages do +describe "Yast::Packages" do + subject { Yast::Packages } before(:each) do log.info "--- test ---" end @@ -1496,4 +1497,116 @@ def product(properties = {}) it_behaves_like "sets priority", 0, 100 end end + + def expect_source_urls(mapping) + expect(Yast::Pkg).to receive(:SourceGetCurrent).with(true).and_return(mapping.keys) + + mapping.each do |id, url| + expect(Yast::Pkg).to receive(:SourceURL).with(id).and_return(url) + end + end + + describe "#repo_schemes" do + it "returns empty list if no repository is defined" do + expect_source_urls({}) + expect(subject.repo_schemes).to eq([]) + end + + it "returns all used schemes" do + expect_source_urls( + 0 => "http://example.com", + 1 => "https://example.com", + 2 => "ftp://example.com", + 3 => "dir:///packages", + 4 => "dvd:///" + ) + expect(subject.repo_schemes).to eq(["http", "https", "ftp", "dir", "dvd"]) + end + + it "returns unique list" do + expect_source_urls( + 0 => "http://example.com", + 1 => "http://example2.com", + 7 => "ftp://example.com", + 8 => "ftp://example2.com" + ) + expect(subject.repo_schemes).to eq(["http", "ftp"]) + end + + it "returns the scheme of the base URL for ISO scheme" do + expect_source_urls( + 0 => "iso:/subdir?iso=DVD1.iso&url=nfs://server/dir&mnt=/nfs&filesystem=udf" + ) + expect(subject.repo_schemes).to eq(["nfs"]) + end + + it "converts the scheme names to lower case" do + expect_source_urls( + 0 => "HTTP://example.com", + 8 => "FTP://example2.com" + ) + expect(subject.repo_schemes).to eq(["http", "ftp"]) + end + + it "ignores invalid URL" do + expect_source_urls(0 => ":") + expect(subject.repo_schemes).to eq([]) + end + + it "ignores incomplete ISO URL (missing 'url' parameter)" do + expect_source_urls(0 => "iso:/subdir?iso=DVD1.iso&mnt=/nfs&filesystem=udf") + expect(subject.repo_schemes).to eq([]) + end + + it "ignores incomplete ISO URL (empty 'url' parameter)" do + expect_source_urls(0 => "iso:/subdir?iso=DVD1.iso&url=&mnt=/nfs&filesystem=udf") + expect(subject.repo_schemes).to eq([]) + end + + it "ignores invalid ISO URL (invalid 'url' parameter)" do + expect_source_urls( + 0 => "iso:/subdir?iso=DVD1.iso&url=:&filesystem=udf" + ) + expect(subject.repo_schemes).to eq([]) + end + end + + describe "#sourceAccessPackages" do + it "returns empty list if no repository is defined" do + expect(subject).to receive(:repo_schemes).and_return([]) + expect(subject.sourceAccessPackages).to eq([]) + end + + # these do not need any extra package to access them + it "returns empty list for http(s), ftp, hd, cd, dvd and dir schemes" do + schemes = ["http", "https", "ftp", "hd", "cd", "dvd", "dir"] + expect(subject).to receive(:repo_schemes).and_return(schemes) + expect(subject.sourceAccessPackages).to eq([]) + end + + it "returns 'nfs-client' for nfs scheme" do + schemes = ["nfs"] + expect(subject).to receive(:repo_schemes).and_return(schemes) + expect(subject.sourceAccessPackages).to eq(["nfs-client"]) + end + + it "returns 'cifs-mount' for smb scheme" do + schemes = ["smb"] + expect(subject).to receive(:repo_schemes).and_return(schemes) + expect(subject.sourceAccessPackages).to eq(["cifs-mount"]) + end + + it "returns 'cifs-mount' for cifs scheme" do + schemes = ["cifs"] + expect(subject).to receive(:repo_schemes).and_return(schemes) + expect(subject.sourceAccessPackages).to eq(["cifs-mount"]) + end + + it "returns 'cifs-mount' and 'nfs-client' for smb and nfs schemes" do + schemes = ["cifs", "nfs"] + expect(subject).to receive(:repo_schemes).and_return(schemes) + # sort the result to make it order independent + expect(subject.sourceAccessPackages.sort).to eq(["cifs-mount", "nfs-client"]) + end + end end