Skip to content

Commit

Permalink
merged with sles12-sp2
Browse files Browse the repository at this point in the history
  • Loading branch information
schubi2 committed Mar 8, 2017
1 parent 17d980f commit fdcc9b1
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 15 deletions.
13 changes: 13 additions & 0 deletions package/yast2-packager.changes
@@ -1,3 +1,16 @@
-------------------------------------------------------------------
Tue Mar 7 09:37:15 CET 2017 - schubi@suse.de

- Product selection: Do not reinstall already installed products
or products which are already included in another product.

Fixes SLES4SAP autoupgrade with SUSE Manager repositories.
These repositories contain SLES_SAP and SLES product. SLES
product will not be installed because SLES_SAP already includes
the SLES product.
(bnc#1014861)
- 3.2.17

-------------------------------------------------------------------
Wed Feb 8 14:40:29 UTC 2017 - jreidinger@suse.com

Expand Down
2 changes: 1 addition & 1 deletion package/yast2-packager.spec
Expand Up @@ -17,7 +17,7 @@


Name: yast2-packager
Version: 3.2.16
Version: 3.2.17
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down
58 changes: 44 additions & 14 deletions src/modules/Packages.rb
Expand Up @@ -31,6 +31,15 @@ class PackagesClass < Module
# Graphical packages for VNC installation
GRAPHIC_PACKAGES = [ "xorg-x11-server", "xorg-x11-server-glx", "libusb", "yast2-x11" ]

# Some products are already be "included" in other products. So they MUST
# not be installed anymore because the other product has a conflict to
# that one.
PRODUCT_CONFLICTS = {
# SLES_SAP contains "Conflicts: sles-release". So SLES will not be installed.
# see https://build.suse.de/package/view_file/SUSE:SLE-12-SP2:GA/_product/SLES_SAP-release.spec?expand=1
"SLES_SAP" => [ "SLES" ]
}

def main
Yast.import "UI"
Yast.import "Pkg"
Expand Down Expand Up @@ -1961,33 +1970,46 @@ def SelectProduct
Initialize(true)

if Stage.cont
Builtins.y2milestone("Second stage - skipping product selection")
log.info("Second stage - skipping product selection")
return true
end

products = Pkg.ResolvableProperties("", :product, "")

if Builtins.size(products) == 0
Builtins.y2milestone("No product found on media")
if !products || products.empty?
log.info("No product found on media")
return true
end

selected_products = Builtins.filter(products) do |p|
Ops.get(p, "status") == :selected
end
# no product selected -> select them all
ret = true
if Builtins.size(selected_products) == 0
Builtins.y2milestone("No product selected so far...")
Builtins.foreach(products) do |p|
product_name = Ops.get_string(p, "name", "")
if !Builtins.regexpmatch(product_name, "-migration$")
Builtins.y2milestone("Selecting product %1", product_name)
ret = Pkg.ResolvableInstall(product_name, :product) && ret
unless products.any? { |p| p["status"] == :selected }
log.info("No product selected so far...")
selected_products = []
products.each do |p|
product_name = p["name"] || ""
if product_name.match(/-migration$/)
log.info("Ignoring migration product: #{product_name}")
elsif p["status"] == :installed
log.info("Ignoring already installed product: #{product_name}")
else
Builtins.y2milestone("Ignoring migration product: %1", product_name)
log.info("Selecting product #{product_name}")
selected_products << product_name
end
end

# Due selecting all available products there can be products which
# are conflicting.
# E.g products are already be "included" by other products. So they MUST
# not be installed anymore.
selected_products.reject! do |product1|
selected_products.any? do |product2|
conflicts = product_conflicts?(product1, product2)
log.info("Product #{product1} conflicts with #{product2} and will not be installed.") if conflicts
conflicts
end
end
ret = selected_products.all? { |name| Pkg.ResolvableInstall(name, :product) }
end

ret
Expand Down Expand Up @@ -2719,6 +2741,14 @@ def format_missing_resolvables(type, list)
_("These items (%{type}) need to be selected to install: %{list}") % {type: type, list: list}
end
end

# Checking if product2 has a conflict to product1
#
# @return [Boolean] true if there are conflicts
def product_conflicts?(product1, product2)
return false unless PRODUCT_CONFLICTS[product2]
PRODUCT_CONFLICTS[product2].include?(product1)
end
end

Packages = PackagesClass.new
Expand Down
81 changes: 81 additions & 0 deletions test/packages_test.rb
Expand Up @@ -1084,4 +1084,85 @@ def product(properties = {})
end
end
end

describe "#SelectProduct" do
before do
allow(subject).to receive(:Initialize).with(true)
end

context "when it is called in continue stage" do
before do
allow(Yast::Stage).to receive(:cont).and_return(true)
end

it "does not install any product" do
expect(Yast::Pkg).not_to receive(:ResolvableInstall)
subject.SelectProduct
end
end

context "when it is called in NOT continue stage" do
before do
allow(Yast::Stage).to receive(:cont).and_return(false)
end

context "when one or more products have already been selected for installation" do
before do
allow(Yast::Pkg).to receive(:ResolvableProperties).and_return(
[product("name" => "p1", "status" => :selected), product("name" => "p2")]
)
end

it "does not install any additional product" do
expect(Yast::Pkg).not_to receive(:ResolvableInstall)
subject.SelectProduct
end
end

context "when no installable product has been found" do
before do
allow(Yast::Pkg).to receive(:ResolvableProperties).and_return([])
end

it "does not install any product" do
expect(Yast::Pkg).not_to receive(:ResolvableInstall)
subject.SelectProduct
end
end

context "when installable and installed products have been found" do
before do
allow(Yast::Pkg).to receive(:ResolvableProperties).and_return(
[ product("name" => "installed_product", "status" => :installed),
product("name" => "p1"),
product("name" => "p2")
]
)
end

it "does not install already installed products" do
expect(Yast::Pkg).not_to receive(:ResolvableInstall).with("installed_product", :product)
expect(Yast::Pkg).to receive(:ResolvableInstall).with("p1", :product).and_return(true)
expect(Yast::Pkg).to receive(:ResolvableInstall).with("p2", :product).and_return(true)
subject.SelectProduct
end
end

context "when conflicting products should be installed (SLES/SLES_SAP)" do
before do
allow(Yast::Pkg).to receive(:ResolvableProperties).and_return(
[ product("name" => "SLES"),
product("name" => "SLES_SAP")
]
)
end

it "does not install SLES product" do
expect(Yast::Pkg).not_to receive(:ResolvableInstall).with("SLES", :product)
expect(Yast::Pkg).to receive(:ResolvableInstall).with("SLES_SAP", :product).and_return(true)
subject.SelectProduct
end
end
end
end
end

0 comments on commit fdcc9b1

Please sign in to comment.