Skip to content

Commit

Permalink
add support for adding bcache
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Sep 27, 2018
1 parent eda441a commit ad0ea07
Show file tree
Hide file tree
Showing 13 changed files with 612 additions and 3 deletions.
85 changes: 85 additions & 0 deletions src/lib/y2partitioner/actions/add_bcache.rb
@@ -0,0 +1,85 @@
# 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/dialogs/bcache"
require "y2partitioner/device_graphs"

Yast.import "Popup"

module Y2Partitioner
module Actions
# Action following click on Add Bcache button.
class AddBcache
# Runs dialogs for adding bcache and also modify device graph if user confirm that dialog.
def run
dialog = Dialogs::Bcache.new(device_graph, usable_blk_devices,
usable_blk_devices + existing_caches)

create_device(dialog) if dialog.run == :next
:finish
end

private

# Creates device according to user input to dialog.
# @return [void]
def create_device(dialog)
backing = dialog.backing_device
raise "Invalid result #{dialog.inspect}. Backing not found." unless backing

caching = dialog.caching_device
raise "Invalid result #{dialog.inspect}. Caching not found." unless caching

bcache = backing.create_bcache(Y2Storage::Bcache.find_free_name(device_graph))

if !caching.is?(:bcache_cset)
caching.remove_descendants
caching = caching.create_bcache_cset
end

bcache.attach_bcache_cset(caching)
end

# Device graph on which action operates
# @return [Y2Storage::Devicegraph]
def device_graph
DeviceGraphs.instance.current
end

# returns block devices that can be used for backing or caching device
# @return [Array<Y2Storage::BlkDevice>]
def usable_blk_devices
device_graph.blk_devices.select do |dev|
dev.component_of.empty? &&
(dev.filesystem.nil? || dev.filesystem.mount_point.nil?) &&
(!dev.respond_to?(:partitions) || dev.partitions.empty?)
end
end

# returns existing caches for bcache.
# @return [Array<Y2Storage::BcacheCset>]
def existing_caches
device_graph.bcache_csets
end
end
end
end
200 changes: 200 additions & 0 deletions src/lib/y2partitioner/dialogs/bcache.rb
@@ -0,0 +1,200 @@
# 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 "yast2/popup"
require "cwm/common_widgets"
require "y2partitioner/dialogs/base"

module Y2Partitioner
module Dialogs
# Form to set the backing and caching device for bcache.
# Part of {Actions::AddBcache}.
class Bcache < Base
# @param device_graph [Y2Storage::DeviceGraph] graph on which it operates
# @param suitable_backing [Array<Y2Storage::BlkDevice>] devices that can be used for backing
# @param suitable_caching [Array<Y2Storage::BlkDevice,Y2Storage::BcacheCset>]
# devices that can be used for caching
# @param device [Y2Storage::Bcache] device if already exists or nil for newly created one.
def initialize(device_graph, suitable_backing, suitable_caching, device = nil)
textdomain "storage"
@caching = CachingDevice.new(device_graph, device, suitable_caching)
@backing = BackingDevice.new(device_graph, device, suitable_backing, @caching)
@device_graph = device_graph
end

# @macro seeDialog
def title
_("Bcache Device")
end

# @macro seeDialog
def contents
VBox(
HBox(
@backing,
HSpacing(1),
@caching
),
VSpacing(1)
)
end

# Selected caching device. Undefined if result of dialog is not `:next`
# @return [Y2Storage::BlkDevice, Y2Storage::BcacheCset]
def caching_device
@caching.result
end

# Selected backing device. Undefined if result of dialog is not `:next`
# @return [Y2Storage::BlkDevice]
def backing_device
@backing.result
end

# Widget to select the backing device
class BackingDevice < CWM::ComboBox
def initialize(device_graph, device, devices, caching)
textdomain "storage"
@device = device
@devices = devices
@device_graph = device_graph
@caching = caching
end

# @macro seeAbstractWidget
def label
_("Backing Device")
end

# @macro seeItemsSelection
def items
@devices.map do |dev|
[dev.sid.to_s, dev.name]
end
end

# @macro seeAbstractWidget
def help
# TRANSLATORS: %s stands for name of option
format(_(
"<b>%s</b> is device that will be used as backing device for bcache." \
"It will define available space of bcache. " \
"Device will be reformatted so any previous content will be wiped out."
), label)
end

# @macro seeAbstractWidget
def init
return unless @device

self.value = @device.sid.to_s
end

# @macro seeAbstractWidget
def store
val = value
@result = @device_graph.find_device(val.to_i)
end

# @macro seeAbstractWidget
def validate
log.info "selected value #{value.inspect}"
# value can be empty string if there is no items
if value.nil? || value.empty?
Yast2::Popup.show(
_("Empty backing device is not yet supported"),
headline: _("Cannot Create Bcache")
)
return false
elsif value == @caching.value
Yast2::Popup.show(
_("Backing and Caching device cannot be identical."),
headline: _("Cannot Create Bcache")
)
return false
else
true
end
end

# returns device selected in widget. Only when dialog succeed and store is called.
# Otherwise undefined
attr_reader :result
end

# Widget to select the caching device
class CachingDevice < CWM::ComboBox
def initialize(device_graph, device, devices)
textdomain "storage"
@device_graph = device_graph
@device = device
@devices = devices
end

# @macro seeAbstractWidget
def label
_("Caching Device")
end

# @macro seeItemsSelection
def items
@devices.map do |dev|
case dev
when Y2Storage::BcacheCset
[dev.sid.to_s, dev.display_name]
else
[dev.sid.to_s, dev.name]
end
end
end

# @macro seeAbstractWidget
def help
# TRANSLATORS: %s stands for name of option
format(_(
"<b>%s</b> is device that will be used as caching device for bcache." \
"It should be faster and usually is smaller then backing device, " \
"but it is not required. " \
"Device will be reformatted so any previous content will be wiped out."
), label)
end

# @macro seeAbstractWidget
def init
return unless @device

self.value = @device.sid.to_s
end

# @macro seeAbstractWidget
def store
val = value
@result = @device_graph.find_device(val.to_i)
end

# returns device selected in widget. Only when dialog succeed and store is called.
# Otherwise undefined
attr_reader :result
end
end
end
end
2 changes: 2 additions & 0 deletions src/lib/y2partitioner/dialogs/md.rb
Expand Up @@ -33,6 +33,8 @@
# @see http://www.rubydoc.info/github/yast/yast-yast2/CWM%2FCustomWidget:${0}
# @!macro [new] seeDialog
# @see http://www.rubydoc.info/github/yast/yast-yast2/CWM%2FDialog:${0}
# @!macro [new] seeItemsSelection
# @see http://www.rubydoc.info/github/yast/yast-yast2/CWM%2FItemsSelection:${0}

Yast.import "Popup"

Expand Down
49 changes: 49 additions & 0 deletions src/lib/y2partitioner/widgets/bcache_add_button.rb
@@ -0,0 +1,49 @@
# 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 "cwm"
require "y2partitioner/actions/add_bcache"

module Y2Partitioner
module Widgets
# Button for opening a wizard to add a new Bcache device
class BcacheAddButton < CWM::PushButton
# Constructor
def initialize
textdomain "storage"
end

# @macro seeAbstractWidget
def label
# TRANSLATORS: button label to add a new Bcache device
_("Add Bcache...")
end

# @macro seeAbstractWidget
# @see Actions::AddBcache
def handle
Actions::AddBcache.run
:redraw
end
end
end
end
4 changes: 3 additions & 1 deletion src/lib/y2partitioner/widgets/pages/bcaches.rb
Expand Up @@ -22,6 +22,7 @@
require "cwm/tree_pager"
require "y2partitioner/icons"
require "y2partitioner/widgets/configurable_blk_devices_table"
require "y2partitioner/widgets/bcache_add_button"
require "y2partitioner/device_graphs"

module Y2Partitioner
Expand Down Expand Up @@ -64,7 +65,8 @@ def contents
table,
Left(
HBox(
# TODO: buttons
BcacheAddButton.new
# TODO: other buttons
)
)
)
Expand Down
11 changes: 11 additions & 0 deletions src/lib/y2storage/bcache.rb
Expand Up @@ -33,6 +33,11 @@ class Bcache < Partitionable
# @return [BcacheCset, nil] returns associated bcache cset
storage_forward :bcache_cset, as: "BcacheCset", check_with: :has_bcache_cset

# @!method attach_bcache_cset(set)
# @param set [BcacheCset] set to attach
# @raise if attaching failed
storage_forward :attach_bcache_cset

# @!method blk_device
# @return [BlkDevice] returns a backing device for cache
storage_forward :blk_device, as: "BlkDevice"
Expand All @@ -55,6 +60,12 @@ class Bcache < Partitionable
# @return [Bcache] nil if there is no such device
storage_class_forward :find_by_name, as: "Bcache"

# @!method self.find_free_name(devicegraph)
# Returns available free name for bcache device.
# @param devicegraph [Devicegraph] in which search for free name
# @return [String] full path to new bcache device like "/dev/bcache3"
storage_class_forward :find_free_name

def inspect
"<Bcache #{name} #{bcache_cset.inspect} -> #{blk_device}>"
end
Expand Down
2 changes: 1 addition & 1 deletion src/lib/y2storage/bcache_cset.rb
Expand Up @@ -53,7 +53,7 @@ class BcacheCset < Device
storage_class_forward :all, as: "BcacheCset"

def inspect
"<BcacheCset #{uuid} #{blk_devices.inspect}>"
"<BcacheCset uuid:#{uuid} #{blk_devices.inspect}>"
end

# Gets user friendly name for caching set. It is translated and ready to show to user.
Expand Down

0 comments on commit ad0ea07

Please sign in to comment.