Skip to content

Commit

Permalink
Merge 769c883 into 0ef75a5
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Oct 4, 2018
2 parents 0ef75a5 + 769c883 commit c877279
Show file tree
Hide file tree
Showing 9 changed files with 304 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/lib/y2partitioner/actions/create_partition_table.rb
Expand Up @@ -21,7 +21,7 @@

require "yast"
require "y2partitioner/device_graphs"
require "y2partitioner/dialogs"
require "y2partitioner/dialogs/partition_table_type"
require "y2partitioner/confirm_recursive_delete"

Yast.import "Label"
Expand Down
99 changes: 99 additions & 0 deletions src/lib/y2partitioner/actions/delete_bcache.rb
@@ -0,0 +1,99 @@
# encoding: utf-8

# Copyright (c) [2018] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "yast"
require "y2partitioner/actions/delete_device"

module Y2Partitioner
module Actions
# Action for deleting a Bcache
#
# @see DeleteDevice
class DeleteBcache < DeleteDevice
def initialize(*args)
super
textdomain "storage"
end

private

# Deletes the indicated Bcache (see {DeleteDevice#device})
def delete
log.info "deleting bcache raid #{device}"
device_graph.remove_bcache(device)
end

# Confirmation before performing the delete action
#
# @return [Boolean]
def confirm
if device.partitions.any?
confirm_for_partitions
elsif single_bcache_cset?
confirm_bcache
else
super
end
end

# Confirmation when the device contains partitions
#
# @see ConfirmRecursiveDelete#confirm_recursive_delete
#
# @return [Boolean]
def confirm_for_partitions
confirm_recursive_delete(
device,
_("Confirm Deleting Bcache with its Devices"),
bcache_cset_note + format(_("The selected Bcache has associated devices.\n" \
"To keep the system in a consistent state, the following\n" \
"associated devices will be deleted:")),
# TRANSLATORS: bcache is the name of the bcache to be deleted (e.g., /dev/bcache0)
format(_("Delete bcache \"%{bcache}\" and the affected devices?"), bcache: device.name)
)
end

# notes that also bcache cset will be deleted
def bcache_cset_note
# no note if there is no bcache cset associated or if cset is shared by more devices
return "" unless single_bcache_cset?

_("The selected Bcache is only user of the caching set. The caching set will be also deleted.") +
"\n"
end

# Checks if there is only single bcache cset used by this bcache, so it will be delited
def single_bcache_cset?
device.bcache_cset && device.bcache_cset.bcaches.size == 1
end

# Confirmation when the device does not contain partitions,
# but result in deleting also bcache_cset
def confirm_bcache
# TRANSLATORS %s is the name of the device to be deleted (e.g., /dev/bcache0)
message = format(_("Really delete %s?"), device.name)

result = Yast2::Popup.show(bcache_cset_note + message, buttons: :yes_no)
result == :yes
end
end
end
end
3 changes: 2 additions & 1 deletion src/lib/y2partitioner/widgets/device_buttons_set.rb
Expand Up @@ -132,7 +132,8 @@ def software_raid_buttons
def bcache_buttons
[
BcacheModifyButton.new(device),
PartitionsButton.new(device, pager)
PartitionsButton.new(device, pager),
DeviceDeleteButton.new(pager: pager, device: device)
]
end

Expand Down
28 changes: 17 additions & 11 deletions src/lib/y2partitioner/widgets/device_delete_button.rb
Expand Up @@ -21,6 +21,7 @@

require "yast"
require "y2partitioner/widgets/device_button"
require "y2partitioner/actions/delete_bcache"
require "y2partitioner/actions/delete_disk_device"
require "y2partitioner/actions/delete_partition"
require "y2partitioner/actions/delete_lvm_vg"
Expand All @@ -44,28 +45,33 @@ def label

private

DEVICE_MAPPING = {
disk_device: Actions::DeleteDiskDevice,
partition: Actions::DeletePartition,
lvm_vg: Actions::DeleteLvmVg,
lvm_lv: Actions::DeleteLvmLv,
md: Actions::DeleteMd,
bcache: Actions::DeleteBcache
}
private_constant :DEVICE_MAPPING

# Returns the proper Actions class to perform the delete action
#
# @see Actions::DeleteBcache
# @see Actions::DeleteDevice
# @see Actions::DeleteDiskDevice
# @see Actions::DeletePartition
# @see Actions::DeleteLvmVg
# @see Actions::DeleteLvmLv
# @see Actions::DeleteMd
#
# @return [Actions::DeleteDevice]
# @return [Actions::DeleteDevice,nil] returns nil if action is not yet implemented
def actions_class
if device.is?(:disk_device)
Actions::DeleteDiskDevice
elsif device.is?(:partition)
Actions::DeletePartition
elsif device.is?(:lvm_vg)
Actions::DeleteLvmVg
elsif device.is?(:lvm_lv)
Actions::DeleteLvmLv
elsif device.is?(:md)
Actions::DeleteMd
DEVICE_MAPPING.each_pair do |type, result|
return result if device.is?(type)
end

nil
end
end
end
Expand Down
16 changes: 16 additions & 0 deletions src/lib/y2storage/devicegraph.rb
Expand Up @@ -380,6 +380,22 @@ def free_spaces
disk_devices.reduce([]) { |sum, disk| sum + disk.free_spaces }
end

# Removes a bcache and all its descendants
#
# It also removes bcache_cset if it is not used by any other bcache device.
#
# @see #remove_with_dependants
#
# @param bcache [Bcache]
#
# @raise [ArgumentError] if the bcache does not exist in the devicegraph
def remove_bcache(bcache)
raise(ArgumentError, "Incorrect device #{bcache.inspect}") unless bcache && bcache.is?(:bcache)
bcache_cset = bcache.bcache_cset
remove_with_dependants(bcache)
remove_with_dependants(bcache_cset) if bcache_cset && bcache_cset.bcaches.empty?
end

# Removes a Md raid and all its descendants
#
# It also removes other devices that may have become useless, like the
Expand Down
104 changes: 104 additions & 0 deletions test/y2partitioner/actions/delete_bcache_test.rb
@@ -0,0 +1,104 @@
#!/usr/bin/env rspec
# encoding: utf-8

# Copyright (c) [2018] SUSE LLC
#
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of version 2 of the GNU General Public License as published
# by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
# more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, contact SUSE LLC.
#
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com

require_relative "../test_helper"

require "cwm/rspec"
require "y2partitioner/actions/delete_bcache"

describe Y2Partitioner::Actions::DeleteBcache do
before do
devicegraph_stub(scenario)
end

subject { described_class.new(device) }

let(:scenario) { "bcache1.xml" }

let(:device) { Y2Storage::BlkDevice.find_by_name(device_graph, device_name) }

let(:device_name) { "/dev/bcache1" }

let(:device_graph) { Y2Partitioner::DeviceGraphs.instance.current }

describe "#run" do
before do
allow(Yast2::Popup).to receive(:show).and_return(accept)
end

let(:accept) { nil }

context "when deleting a bcache without associated devices" do
let(:device_name) { "/dev/bcache1" }

it "shows a confirm message" do
expect(Yast2::Popup).to receive(:show)
subject.run
end

it "adds note that also cset will be deleted if the bcache is only user of it" do
device_graph.remove_bcache(Y2Storage::BlkDevice.find_by_name(device_graph, "/dev/bcache2"))
device_graph.remove_bcache(Y2Storage::BlkDevice.find_by_name(device_graph, "/dev/bcache0"))

expect(Yast2::Popup).to receive(:show).with(/user of the caching set/, anything)
subject.run
end
end

context "when deleting a bcache with associated devices" do
let(:device_name) { "/dev/bcache2" }

it "shows a specific confirm message for recursive delete" do
expect(subject).to receive(:confirm_recursive_delete)
.and_call_original

subject.run
end
end

context "when the confirm message is not accepted" do
let(:accept) { :no }

it "does not delete the bcache" do
subject.run
expect(Y2Storage::BlkDevice.find_by_name(device_graph, device_name)).to_not be_nil
end

it "returns :back" do
expect(subject.run).to eq(:back)
end
end

context "when the confirm message is accepted" do
let(:accept) { :yes }

it "deletes the bcache" do
subject.run
expect(Y2Storage::BlkDevice.find_by_name(device_graph, device_name)).to be_nil
end

it "returns :finish" do
expect(subject.run).to eq(:finish)
end
end
end
end
3 changes: 2 additions & 1 deletion test/y2partitioner/widgets/device_buttons_set_test.rb
Expand Up @@ -108,7 +108,8 @@
expect(widgets.map(&:class)).to contain_exactly(
Y2Partitioner::Widgets::DeviceButtonsSet::ButtonsBox,
Y2Partitioner::Widgets::BcacheModifyButton,
Y2Partitioner::Widgets::PartitionsButton
Y2Partitioner::Widgets::PartitionsButton,
Y2Partitioner::Widgets::DeviceDeleteButton
)
end

Expand Down
1 change: 1 addition & 0 deletions test/y2partitioner/widgets/partition_add_button_test.rb
Expand Up @@ -24,6 +24,7 @@

require "cwm/rspec"
require "y2partitioner/widgets/partition_add_button"
require "y2partitioner/widgets/overview"

describe Y2Partitioner::Widgets::PartitionAddButton do
subject { described_class.new(device: device, pager: pager) }
Expand Down
62 changes: 62 additions & 0 deletions test/y2storage/devicegraph_test.rb
Expand Up @@ -641,6 +641,68 @@ def with_sda2_deleted(initial_graph)
end
end

describe "#remove_bcache" do
subject(:devicegraph) { Y2Storage::StorageManager.instance.staging }

before do
fake_scenario("bcache1.xml")
end

let(:bcache_name) { "/dev/bcache2" }

it "removes the given bcache device" do
bcache = Y2Storage::Bcache.find_by_name(devicegraph, bcache_name)
expect(bcache).to_not be_nil

devicegraph.remove_bcache(bcache)

bcache = Y2Storage::Bcache.find_by_name(devicegraph, bcache_name)
expect(bcache).to be_nil
end

it "removes all bcache descendants" do
bcache = Y2Storage::Bcache.find_by_name(devicegraph, bcache_name)
descendants_sid = bcache.descendants.map(&:sid)

expect(descendants_sid).to_not be_empty

devicegraph.remove_bcache(bcache)

existing_descendants = descendants_sid.map { |sid| devicegraph.find_device(sid) }.compact
expect(existing_descendants).to be_empty
end

it "removes the no longer used bcache csets" do
bcache = Y2Storage::Bcache.find_by_name(devicegraph, bcache_name)

expect(devicegraph.bcache_csets).to_not be_empty
devicegraph.remove_bcache(bcache)
# still in use
expect(devicegraph.bcache_csets).to_not be_empty
devicegraph.bcaches.each do |bcache_device|
devicegraph.remove_bcache(bcache_device)
end
expect(devicegraph.bcache_csets).to be_empty
end

context "when the bcache does not exist in the devicegraph" do
before do
Y2Storage::Bcache.create(other_devicegraph, bcache1_name)
end

let(:other_devicegraph) { devicegraph.dup }

let(:bcache1_name) { "/dev/bcache10" }

it "raises an exception and does not remove the bcache" do
bcache1 = Y2Storage::Bcache.find_by_name(other_devicegraph, bcache1_name)

expect { devicegraph.remove_bcache(bcache1) }.to raise_error(ArgumentError)
expect(Y2Storage::Bcache.find_by_name(other_devicegraph, bcache1_name)).to_not be_nil
end
end
end

describe "#remove_md" do
subject(:devicegraph) { Y2Storage::StorageManager.instance.staging }

Expand Down

0 comments on commit c877279

Please sign in to comment.