Skip to content

Commit

Permalink
Add support to specify new system roles through add-ons
Browse files Browse the repository at this point in the history
  • Loading branch information
imobachgs committed Mar 8, 2017
1 parent c2949be commit b5dc2ee
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 0 deletions.
31 changes: 31 additions & 0 deletions library/control/src/modules/ProductControl.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@

module Yast
class ProductControlClass < Module
include Yast::Logger

# Product control system roles key
# @return [String] System roles
SYSTEM_ROLES_KEY = "system_roles".freeze

def main
Yast.import "UI"
textdomain "base"
Expand Down Expand Up @@ -67,6 +73,9 @@ def main
# modules to be offered to clone configuration at the end of installation
@clone_modules = []

# roles
@system_roles = []

# additional workflow parameters
# workflow doesn't only match mode and stage but also these params
# bnc #427002
Expand Down Expand Up @@ -293,6 +302,7 @@ def ReadControlFile(controlfile)
@proposals = Ops.get_list(@productControl, "proposals", [])
@inst_finish = Ops.get_list(@productControl, "inst_finish_stages", [])
@clone_modules = Ops.get_list(@productControl, "clone_modules", [])
@system_roles = @productControl.fetch(SYSTEM_ROLES_KEY, [])

Builtins.foreach(
["software", "globals", "network", "partitioning", "texts"]
Expand Down Expand Up @@ -1591,11 +1601,31 @@ def ResetAdditionalWorkflowParams
nil
end

# Add new system roles
#
# For the time being, roles are inserted at the beginning of the
# roles list.
#
# @example Adding a simple role
# ProductControl.system_roles #=> []
# ProductControl.add_system_roles([{"id" => "new_role"}]) #=> [{"id" => "new_role"}]
# ProductControl.system_roles #=> [{"id" => "new_role"}]
#
# @param [Array<Hash>] new_roles Roles to add
# @return [Array<Hash>,false] All existing roles or false if roles were not
# added
def add_system_roles(new_roles)
log.info "Adding roles to product control: #{new_roles.inspect}"
return false unless new_roles.all? { |r| r.key?("id") }
system_roles.unshift(*new_roles)
end

publish variable: :productControl, type: "map"
publish variable: :workflows, type: "list <map>"
publish variable: :proposals, type: "list <map>"
publish variable: :inst_finish, type: "list <map <string, any>>"
publish variable: :clone_modules, type: "list <string>"
publish variable: :system_roles, type: "list <map>"
publish variable: :custom_control_file, type: "string"
publish variable: :y2update_control_file, type: "string"
publish variable: :default_control_file, type: "string"
Expand Down Expand Up @@ -1647,6 +1677,7 @@ def ResetAdditionalWorkflowParams
publish function: :ProductControl, type: "void ()"
publish function: :SetAdditionalWorkflowParams, type: "void (map <string, any>)"
publish function: :ResetAdditionalWorkflowParams, type: "void ()"
publish function: :merge_roles, type: "void (list <map>)"
end

ProductControl = ProductControlClass.new
Expand Down
16 changes: 16 additions & 0 deletions library/control/src/modules/WorkflowManager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ def main
@wkf_initial_proposals = []
@wkf_initial_inst_finish = []
@wkf_initial_clone_modules = []
@wkf_initial_roles = []

@wkf_initial_product_features = {}

Expand Down Expand Up @@ -152,6 +153,7 @@ def SetBaseWorkflow(force)
@wkf_initial_proposals = deep_copy(ProductControl.proposals)
@wkf_initial_inst_finish = deep_copy(ProductControl.inst_finish)
@wkf_initial_clone_modules = deep_copy(ProductControl.clone_modules)
@wkf_initial_system_roles = deep_copy(ProductControl.system_roles)

@additional_finish_steps_before_chroot = []
@additional_finish_steps_after_chroot = []
Expand Down Expand Up @@ -295,6 +297,7 @@ def FillUpInitialWorkflowSettings
ProductControl.proposals = deep_copy(@wkf_initial_proposals)
ProductControl.inst_finish = deep_copy(@wkf_initial_inst_finish)
ProductControl.clone_modules = deep_copy(@wkf_initial_clone_modules)
ProductControl.system_roles = deep_copy(@wkf_initial_system_roles)

@additional_finish_steps_before_chroot = []
@additional_finish_steps_after_chroot = []
Expand Down Expand Up @@ -1232,6 +1235,11 @@ def IntegrateWorkflow(filename)
return false
end

if !add_system_roles(update_file.fetch("system_roles", []))
Builtins.y2error("Failed to add roles")
return false
end

true
end

Expand Down Expand Up @@ -1360,6 +1368,7 @@ def HaveAdditionalWorkflows
# "proposals" : ...
# "inst_finish" : ...
# "clone_modules" : ...
# "system_roles" : ...
# "unmerged_changes" : ...
# ];
def DumpCurrentSettings
Expand All @@ -1368,10 +1377,17 @@ def DumpCurrentSettings
"proposals" => ProductControl.proposals,
"inst_finish" => ProductControl.inst_finish,
"clone_modules" => ProductControl.clone_modules,
"system_roles" => ProductControl.system_roles,
"unmerged_changes" => @unmerged_changes
}
end

# Add system roles
def add_system_roles(new_roles)
return false unless new_roles.empty? || ProductControl.add_system_roles(new_roles)
true
end

publish variable: :additional_finish_steps_before_chroot, type: "list <string>"
publish variable: :additional_finish_steps_after_chroot, type: "list <string>"
publish variable: :additional_finish_steps_before_umount, type: "list <string>"
Expand Down
171 changes: 171 additions & 0 deletions library/control/test/workflow_manager_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,175 @@
end
end
end

describe "#IntegrateWorkflow" do
let(:installation_updated) { true }
let(:product_info_updated) { true }
let(:new_proposals_added) { true }
let(:workflows_replaced) { true }
let(:inst_finish_updated) { true }
let(:filename) { "installation.xml" }

let(:proposal) do
{ "name" => "testing", "mode" => "installation", "proposal_modules" => ["prop1"] }
end

let(:workflow) do
{ "mode" => "installation", "modules" => ["mod1"] }
end

let(:additional_role) do
{ "id" => "additional_role" }
end

let(:control) do
{
"display_name" => "new workflow",
"proposals" => [proposal],
"workflows" => [workflow],
"textdomain" => "control",
"system_roles" => [additional_role],
"update" => {
"inst_finish" => { "before_chroot" => ["before_chroot_1"] }
}
}
end

before do
allow(Yast::XML).to receive(:XMLToYCPFile).with(filename).and_return(control)
allow(subject).to receive(:UpdateInstallation).and_return(installation_updated)
allow(subject).to receive(:UpdateProductInfo).and_return(product_info_updated)
allow(subject).to receive(:AddNewProposals).and_return(new_proposals_added)
allow(subject).to receive(:Replaceworkflows).and_return(workflows_replaced)
allow(subject).to receive(:UpdateInstFinish).and_return(inst_finish_updated)
Yast::ProductControl.system_roles = []
end

it "updates the installation" do
expect(subject).to receive(:UpdateInstallation)
.with(control["update"], "new workflow", "control").and_return(true)
expect(subject.IntegrateWorkflow(filename)).to eq(true)
end

it "updates the product info" do
expect(subject).to receive(:UpdateProductInfo)
.with(control, filename).and_return(true)
expect(subject.IntegrateWorkflow(filename)).to eq(true)
end

it "adds new proposals" do
expect(subject).to receive(:AddNewProposals)
.with(control["proposals"]).and_return(true)
expect(subject.IntegrateWorkflow(filename)).to eq(true)
end

it "adds inst_finish steps" do
expect(subject).to receive(:UpdateInstFinish)
.with(control["update"]["inst_finish"])
expect(subject.IntegrateWorkflow(filename)).to eq(true)
end

it "adds roles" do
expect(subject.IntegrateWorkflow(filename)).to eq(true)
expect(Yast::ProductControl.system_roles).to eq([additional_role])
end

context "when fails to update the installation" do
let(:installation_updated) { false }

it "logs the error and returns false" do
expect(Yast::Builtins).to receive(:y2error)
.with(/to update installation/)
expect(subject.IntegrateWorkflow(filename)).to eq(false)
end
end

context "when fails to update the product info" do
let(:product_info_updated) { false }

it "logs the error and returns false" do
expect(Yast::Builtins).to receive(:y2error)
.with(/to set product options/)
expect(subject.IntegrateWorkflow(filename)).to eq(false)
end
end

context "when fails to add new proposals" do
let(:new_proposals_added) { false }

it "logs the error and returns false" do
expect(Yast::Builtins).to receive(:y2error)
.with(/to add new proposals/)
expect(subject.IntegrateWorkflow(filename)).to eq(false)
end
end

context "when fails to replace workflows" do
let(:workflows_replaced) { false }

it "logs the error and returns false" do
expect(Yast::Builtins).to receive(:y2error)
.with(/to replace workflows/)
expect(subject.IntegrateWorkflow(filename)).to eq(false)
end
end

context "when fails to update inst_finish" do
let(:inst_finish_updated) { false }

it "logs the error and returns false" do
expect(Yast::Builtins).to receive(:y2error)
.with(/inst_finish steps failed/)
expect(subject.IntegrateWorkflow(filename)).to eq(false)
end
end

context "when fails to add roles" do
let(:additional_role) { { "identifier" => "not a valid role" } }

it "logs the error and returns false" do
expect(Yast::Builtins).to receive(:y2error)
.with(/to add roles/)
expect(subject.IntegrateWorkflow(filename)).to eq(false)
end
end
end

describe "#DumpCurrentSettings" do
let(:settings) do
{
workflows: ["workflow_1"],
proposals: ["proposal_1"],
system_roles: ["system_role_1"],
clone_modules: ["lan"],
inst_finish: { "before_chroot" => ["before_chroot_1"] }
}
end

before do
settings.each do |key, value|
allow(Yast::ProductControl).to receive(key).and_return(value)
end
end

it "returns workflows" do
expect(subject.DumpCurrentSettings["workflows"]).to eq(settings[:workflows])
end

it "returns proposals" do
expect(subject.DumpCurrentSettings["proposals"]).to eq(settings[:proposals])
end

it "returns inst_finish" do
expect(subject.DumpCurrentSettings["inst_finish"]).to eq(settings[:inst_finish])
end

it "returns system_roles" do
expect(subject.DumpCurrentSettings["system_roles"]).to eq(settings[:system_roles])
end

it "returns unmerged_changes" do
expect(subject.DumpCurrentSettings["unmerged_changes"]).to eq(false)
end
end
end

0 comments on commit b5dc2ee

Please sign in to comment.