Skip to content

Commit

Permalink
Merge pull request #490 from yast/add-minimalistic-libzypp-config-master
Browse files Browse the repository at this point in the history
Add minimalistic libzypp config master
  • Loading branch information
imobachgs committed Jan 16, 2017
2 parents d00adca + 9d6387b commit 5601ef0
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 22 deletions.
4 changes: 4 additions & 0 deletions doc/control-file.md
Expand Up @@ -554,6 +554,10 @@ This is a list of supported entries in *software*:
- *clone\_install\_recommended\_default* - Default entry for
"install_recommended" in created AutoYaST configuration file.

- *minimalistic_libzypp_config* - adjust the libzypp configuration
to reduce the amount of packages to install: only required
packages are considered, no documentation and no multiversion.

Additionally, you can configure how updating of packages should be
performed. The following options are available:

Expand Down
8 changes: 8 additions & 0 deletions package/yast2-installation.changes
@@ -1,3 +1,11 @@
-------------------------------------------------------------------
Mon Jan 16 12:17:38 UTC 2017 - mfilka@suse.com

- fate#321739
- Made user's interaction possible in case of error in read-only
proposal.
- 3.2.14

-------------------------------------------------------------------
Thu Jan 5 13:16:08 CET 2017 - schubi@suse.de

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


Name: yast2-installation
Version: 3.2.13
Version: 3.2.14
Release: 0

BuildRoot: %{_tmppath}/%{name}-%{version}-build
Expand Down
19 changes: 14 additions & 5 deletions src/lib/installation/proposal_runner.rb
Expand Up @@ -365,6 +365,15 @@ def submod_ask_user(input)
workflow_sequence
end

# Checks if given proposal map contains an error report
#
# @param [Hash] proposal map as returned by make_proposal
# @return [Boolean] true if the map reports an issue in proposal
# @see ProposalClient#make_proposal
def proposal_failed?(proposal)
proposal && [:blocker, :fatal, :error].include?(proposal["warning_level"])
end

def make_proposal(force_reset, language_changed)
tab_to_switch = 999
current_tab_affected = false
Expand Down Expand Up @@ -404,14 +413,14 @@ def make_proposal(force_reset, language_changed)
make_proposal_callback = proc do |submod, prop_map|
submodule_nr += 1
Yast::UI.ChangeWidget(Id("pb_ip"), :Value, submodule_nr)
prop = html_header(submod)
force_rw = proposal_failed?(prop_map) && @store.soft_read_only?(submod)
prop = html_header(submod, force_rw: force_rw)

# check if it is needed to switch to another tab
# because of an error
if Yast::Builtins.haskey(@mod2tab, submod)
log.info "Mod2Tab: '#{@mod2tab[submod]}'"
warn_level = prop_map["warning_level"]
if [:blocker, :fatal, :error].include?(warn_level)
if proposal_failed?(prop_map)
# bugzilla #237291
# always switch to more detailed tab only
# value 999 means to keep current tab, in case of error,
Expand Down Expand Up @@ -803,11 +812,11 @@ def assign_next_button
# Get the header for the specific proposal module
# @param submod [String] the proposal module name
# @return [String] richtext string with the proposal header
def html_header(submod)
def html_header(submod, force_rw: false)
title = @store.title_for(submod)

# do not add a link if the module is read-only or link is already included
heading = if @store.read_only?(submod) || title.include?("<a")
heading = if (!force_rw && @store.read_only?(submod)) || title.include?("<a")
title
else
Yast::HTML.Link(title, @store.id_for(submod))
Expand Down
54 changes: 48 additions & 6 deletions src/lib/installation/proposal_store.rb
Expand Up @@ -250,12 +250,40 @@ def title_for(client)
title.gsub(/<a.*?>(.*?)<\/a>/, "\\1")
end

# Returns the read-only flag
# Checks if the client's proposal is configured as "hard" or "soft" read-only
#
# @param [String] client
# @return [String] a title provided by the description API
# "hard" read-only means that the proposal is always read-only
# "soft" read-only means that the proposal is made changeable when an error
#
# @return [Boolean] true if client is "hard" or "soft" read-only
# @see soft_read_only
# @see hard_read_only
def read_only?(client)
read_only_proposals.include?(client)
hard_read_only?(client) || soft_read_only?(client)
end

# Checks if the client's proposal is configured as "hard" read-only
#
# "hard" read-only means that the proposal is always read-only
# "soft" read-only means that the proposal is made changeable when an error
# in proposal is detected.
#
# @param [String] client
# @return [Boolean] if the client is marked as "hard" read only
def hard_read_only?(client)
read_only_proposals[:hard].include?(client)
end

# Checks if the client's proposal is configured as "soft" read-only
#
# "hard" read-only means that the proposal is always read-only
# "soft" read-only means that the proposal is made changeable when an error
# in proposal is detected.
#
# @param [String] client
# @return [Boolean] if the client is marked as "soft" read only
def soft_read_only?(client)
read_only_proposals[:soft].include?(client)
end

# Calls client('AskUser'), to change a setting interactively (if link is the
Expand Down Expand Up @@ -297,16 +325,30 @@ def client_for_link(link)
matching_client.first
end

# Reads read-only proposals from the control file
#
# @return [Hash] map with keys :hard and :soft. Values are names
# of proposals with "hard" or "soft" read_only flag set.
def read_only_proposals
return @read_only_proposals if @read_only_proposals

@read_only_proposals = []
@read_only_proposals = { hard: [], soft: [] }

properties.fetch("proposal_modules", []).each do |proposal|
next unless proposal["read_only"]

name = full_module_name(proposal["name"])
@read_only_proposals << name

ro_type = proposal["read_only"]

case ro_type
when "hard"
@read_only_proposals[:hard] << name
when "soft"
@read_only_proposals[:soft] << name
else
log.info("Uknown value for read_only node: #{ro_type}")
end
end

log.info "Found read-only proposals: #{@read_only_proposals}"
Expand Down
60 changes: 60 additions & 0 deletions test/proposal_runner_test.rb
Expand Up @@ -75,6 +75,29 @@ class C < ::Installation::ProposalStore; end
expect(subject.run).to eq :auto
end

describe "#html_header" do
it "returns clickable header when forced" do
allow(Yast::GetInstArgs).to receive(:proposal).and_return("software")

expect_any_instance_of(::Installation::ProposalRunner)
.to receive(:submod_descriptions_and_build_menu)
.and_return(false)
expect_any_instance_of(::Installation::ProposalStore)
.to receive(:title_for)
.and_return("Software")
expect_any_instance_of(::Installation::ProposalStore)
.to receive(:id_for)
.and_return("software")
expect_any_instance_of(::Installation::ProposalStore)
.not_to receive(:read_only?)

# initialization of internal state
expect(subject.run).to eq :auto

expect(subject.send(:html_header, "software", force_rw: true)).to eql Yast::HTML.Heading(Yast::HTML.Link("Software", "software"))
end
end

context "when proposal contains tabs" do
let(:properties) do
PROPERTIES.merge(
Expand Down Expand Up @@ -126,6 +149,43 @@ class C < ::Installation::ProposalStore; end
expect(subject.run).to eq(:next)
end
end

context "and it enables soft r/o proposal in case of error" do
PROPERTIES = {
"enable_skip" => "no",
"label" => "Installation Settings",
"mode" => "autoinstallation",
"name" => "initial",
"stage" => "initial",
"unique_id" => "auto_inst_proposal",
"proposal_modules" => [
{ "name" => "software", "presentation_order" => "15", "read_only" => "soft" }
]
}.freeze
let(:proposals) { [["software_proposal", 15]] }

it "makes a proposal" do
allow(subject)
.to receive(:html_header)
.with("software_proposal")
.and_call_original

# we need ProposalStore#make_proposal to call the callback
allow(Yast::WFM)
.to receive(:CallFunction)
.and_return(
"preformated_proposal" => "",
"warning_level" => :error
)

expect(subject)
.to receive(:html_header)
.with("software_proposal", force_rw: true)
.at_least(:once)
.and_call_original
expect(subject.run).to eq(:next)
end
end
end
end
end
47 changes: 37 additions & 10 deletions test/proposal_store_test.rb
Expand Up @@ -568,24 +568,51 @@ def mock_properties(data = {})
# Proposals need to be cached first
subject.make_proposals

expect(subject).to receive(:read_only?).with("proposal_a").and_return(true)
allow(Yast::Report).to receive(:Warning)
end

it "displays a warning" do
expect(Yast::Report).to receive(:Warning)
context "in case of hard read only proposal" do
before do
expect(subject).to receive(:hard_read_only?).with("proposal_a").and_return(true)
end

subject.handle_link("proposal_a")
end
it "displays a warning" do
expect(Yast::Report).to receive(:Warning)

subject.handle_link("proposal_a")
end

it "does not run the proposal client" do
expect(Yast::WFM).to_not receive(:CallFunction)
it "does not run the proposal client" do
expect(Yast::WFM).to_not receive(:CallFunction)

subject.handle_link("proposal_a")
subject.handle_link("proposal_a")
end

it "returns nil" do
expect(subject.handle_link("proposal_a")).to eq(nil)
end
end

it "returns nil" do
expect(subject.handle_link("proposal_a")).to eq(nil)
context "in case of soft read only proposal" do
before do
expect(subject).to receive(:soft_read_only?).with("proposal_a").and_return(true)
end

it "displays a warning" do
expect(Yast::Report).to receive(:Warning)

subject.handle_link("proposal_a")
end

it "does not run the proposal client" do
expect(Yast::WFM).to_not receive(:CallFunction)

subject.handle_link("proposal_a")
end

it "returns nil" do
expect(subject.handle_link("proposal_a")).to eq(nil)
end
end
end
end
Expand Down

0 comments on commit 5601ef0

Please sign in to comment.