Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

web: Revamp the Storage page UI #1104

Merged
merged 30 commits into from
Mar 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
4372623
service: Export device sid in the proposal actions
joseivanlopez Mar 6, 2024
ca34978
service: Export unused slots
joseivanlopez Mar 6, 2024
02a93e9
service: Export more info about block devices
joseivanlopez Mar 6, 2024
26fb99d
service: Export LVM devices
joseivanlopez Mar 6, 2024
36ff75a
service: Avoid updating D-Bus nodes of devices tree
joseivanlopez Mar 6, 2024
fa1ace3
service: Export staging devices
joseivanlopez Mar 6, 2024
d43bb46
service: Fix rubocop config
joseivanlopez Mar 4, 2024
8128fd7
service: Fix typo
joseivanlopez Mar 6, 2024
e35d470
Extend storage D-Bus API (#1071)
joseivanlopez Mar 6, 2024
1ba7c2b
service: Add Device interface
joseivanlopez Mar 8, 2024
f94680d
service: Add Partition interface
joseivanlopez Mar 8, 2024
d2ce25e
service: Adapt Filesystem interface
joseivanlopez Mar 8, 2024
19f769a
service: Update dependency
joseivanlopez Mar 8, 2024
ba93043
service: Use display_name
joseivanlopez Mar 8, 2024
aa1e7a3
service: Add LogicalVolume interface
joseivanlopez Mar 8, 2024
64129d5
Extend storage D-Bus API (#1082)
joseivanlopez Mar 8, 2024
09f3e08
web: Adapt storage client to changes in D-Bus
joseivanlopez Mar 11, 2024
e40435c
web: Load devices in the proposal page
joseivanlopez Mar 11, 2024
380dbb6
Adapt storage client (#1079)
joseivanlopez Mar 11, 2024
8fd0ff7
Merge branch 'master' into storage-ui
joseivanlopez Mar 14, 2024
108f16d
WIP: SpacePolicy as pop-up
ancorgs Mar 12, 2024
43bf709
web: Select action according to the policy
joseivanlopez Mar 14, 2024
3af5a29
web: Do not use local storage
joseivanlopez Mar 14, 2024
ca49bc3
web: Improve table of space actions
joseivanlopez Mar 14, 2024
0574914
[web] SpacePolicy as pop-up (#1090)
ancorgs Mar 15, 2024
32c4639
web: add Result section to Storage page (#1088)
dgdavid Mar 18, 2024
613b1d0
web: Indicate size before resizing
joseivanlopez Mar 18, 2024
6480e03
Show size before resizing (#1098)
joseivanlopez Mar 18, 2024
4ddb24d
service: Changelog
joseivanlopez Mar 19, 2024
d1b2c94
web: Changelog
joseivanlopez Mar 19, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions service/lib/agama/dbus/base_tree.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2023] SUSE LLC
# Copyright (c) [2023-2024] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -47,11 +47,16 @@ def initialize(service, root_path, logger: nil)
#
# @param objects [Array]
def objects=(objects)
try_add_objects(objects)
try_update_objects(objects)
try_add_objects(objects)
try_delete_objects(objects)
end

# Unexports the current D-Bus objects of this tree.
def clean
dbus_objects.each { |o| service.unexport(o) }
end

private

# @return [::DBus::ObjectServer]
Expand Down
20 changes: 16 additions & 4 deletions service/lib/agama/dbus/storage/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,15 @@ module Storage
#
# The D-Bus object includes the required interfaces for the storage object that it represents.
class Device < BaseObject
# @return [Y2Storage::Device]
attr_reader :storage_device
# sid of the Y2Storage device.
#
# @note A Y2Storage device is a wrapper over a libstorage-ng object. If the source
# devicegraph does not exist anymore (e.g., after reprobing), then the Y2Storage device
# object cannot be used (memory error). The device sid is stored to avoid accessing to
# the old Y2Storage device when updating the represented device, see {#storage_device=}.
#
# @return [Integer]
attr_reader :sid

# Constructor
#
Expand All @@ -43,6 +50,7 @@ def initialize(storage_device, path, tree, logger: nil)
super(path, logger: logger)

@storage_device = storage_device
@sid = storage_device.sid
@tree = tree
add_interfaces
end
Expand All @@ -54,12 +62,13 @@ def initialize(storage_device, path, tree, logger: nil)
#
# @param value [Y2Storage::Device]
def storage_device=(value)
if value.sid != storage_device.sid
if value.sid != sid
raise "Cannot update the D-Bus object because the given device has a different sid: " \
"#{value} instead of #{storage_device.sid}"
"#{value} instead of #{sid}"
end

@storage_device = value
@sid = value.sid

interfaces_and_properties.each do |interface, properties|
dbus_properties_changed(interface, properties, [])
Expand All @@ -71,6 +80,9 @@ def storage_device=(value)
# @return [DevicesTree]
attr_reader :tree

# @return [Y2Storage::Device]
attr_reader :storage_device

# Adds the required interfaces according to the storage object.
def add_interfaces
interfaces = Interfaces::Device.constants
Expand Down
30 changes: 21 additions & 9 deletions service/lib/agama/dbus/storage/devices_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,19 @@ def path_for(device)
::DBus::ObjectPath.new(File.join(root_path, device.sid.to_s))
end

# Updates the D-Bus tree according to the given devicegraph
# Updates the D-Bus tree according to the given devicegraph.
#
# @note In the devices tree it is important to avoid updating D-Bus nodes. Note that an
# already exported D-Bus object could require to add or remove interfaces (e.g., an
# existing partition needs to add the Filesystem interface after formatting the
# partition). Dynamically adding or removing interfaces is not possible with ruby-dbus
# once the object is exported on D-Bus.
#
# Updating the currently exported D-Bus objects is avoided by calling to {#clean} first.
#
# @param devicegraph [Y2Storage::Devicegraph]
def update(devicegraph)
clean
self.objects = devices(devicegraph)
end

Expand All @@ -52,31 +61,34 @@ def create_dbus_object(device)
end

# @see BaseTree
# @param dbus_object [Device]
# @param device [Y2Storage::Device]
def update_dbus_object(dbus_object, device)
dbus_object.storage_device = device
#
# @note D-Bus objects representing devices cannot be safely updated, see {#update}.
def update_dbus_object(_dbus_object, _device)
nil
end

# @see BaseTree
# @param dbus_object [Device]
# @param device [Y2Storage::Device]
def dbus_object?(dbus_object, device)
dbus_object.storage_device.sid == device.sid
dbus_object.sid == device.sid
end

# Devices to be exported.
#
# Right now, only the required information for calculating a proposal is exported, that is:
# * Potential candidate devices (i.e., disk devices, MDs).
# * Partitions of the candidate devices in order to indicate how to find free space.
#
# TODO: export LVM VGs and file systems of directly formatted devices.
# * LVM volume groups and logical volumes.
#
# @param devicegraph [Y2Storage::Devicegraph]
# @return [Array<Y2Storage::Device>]
def devices(devicegraph)
devices = devicegraph.disk_devices + devicegraph.software_raids
devices = devicegraph.disk_devices +
devicegraph.software_raids +
devicegraph.lvm_vgs +
devicegraph.lvm_lvs

devices + partitions_from(devices)
end

Expand Down
4 changes: 4 additions & 0 deletions service/lib/agama/dbus/storage/interfaces/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,13 @@ module Device

require "agama/dbus/storage/interfaces/device/block"
require "agama/dbus/storage/interfaces/device/component"
require "agama/dbus/storage/interfaces/device/device"
require "agama/dbus/storage/interfaces/device/drive"
require "agama/dbus/storage/interfaces/device/filesystem"
require "agama/dbus/storage/interfaces/device/lvm_lv"
require "agama/dbus/storage/interfaces/device/lvm_vg"
require "agama/dbus/storage/interfaces/device/md"
require "agama/dbus/storage/interfaces/device/multipath"
require "agama/dbus/storage/interfaces/device/partition"
require "agama/dbus/storage/interfaces/device/partition_table"
require "agama/dbus/storage/interfaces/device/raid"
20 changes: 14 additions & 6 deletions service/lib/agama/dbus/storage/interfaces/device/block.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ def self.apply?(storage_device)
BLOCK_INTERFACE = "org.opensuse.Agama.Storage1.Block"
private_constant :BLOCK_INTERFACE

# Name of the block device
# Position of the first block of the region.
#
# @return [String] e.g., "/dev/sda"
def block_name
storage_device.name
# @return [Integer]
def block_start
storage_device.start
end

# Whether the block device is currently active
Expand All @@ -58,6 +58,13 @@ def block_active
storage_device.active?
end

# Whether the block device is encrypted.
#
# @return [Boolean]
def block_encrypted
storage_device.encrypted?
end

# Name of the udev by-id links
#
# @return [Array<String>]
Expand Down Expand Up @@ -98,9 +105,10 @@ def block_systems

def self.included(base)
base.class_eval do
dbus_interface BLOCK_INTERFACE do
dbus_reader :block_name, "s", dbus_name: "Name"
dbus_interface BLOCK_INTERFACE do
dbus_reader :block_start, "t", dbus_name: "Start"
dbus_reader :block_active, "b", dbus_name: "Active"
dbus_reader :block_encrypted, "b", dbus_name: "Encrypted"
dbus_reader :block_udev_ids, "as", dbus_name: "UdevIds"
dbus_reader :block_udev_paths, "as", dbus_name: "UdevPaths"
dbus_reader :block_size, "t", dbus_name: "Size"
Expand Down
2 changes: 2 additions & 0 deletions service/lib/agama/dbus/storage/interfaces/device/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ def self.included(base)
base.class_eval do
dbus_interface COMPONENT_INTERFACE do
dbus_reader :component_type, "s", dbus_name: "Type"
# The names are provided just in case the device is component of a device that
# is not exported yet (e.g., Bcache devices).
dbus_reader :component_device_names, "as", dbus_name: "DeviceNames"
dbus_reader :component_devices, "ao", dbus_name: "Devices"
end
Expand Down
82 changes: 82 additions & 0 deletions service/lib/agama/dbus/storage/interfaces/device/device.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# frozen_string_literal: true

# Copyright (c) [2024] 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 "dbus"
require "y2storage/device_description"

module Agama
module DBus
module Storage
module Interfaces
module Device
# Interface for a device.
#
# @note This interface is intended to be included by {Agama::DBus::Storage::Device}.
module Device
# Whether this interface should be implemented for the given device.
#
# @note All devices implement this interface.
#
# @param _storage_device [Y2Storage::Device]
# @return [Boolean]
def self.apply?(_storage_device)
true
end

DEVICE_INTERFACE = "org.opensuse.Agama.Storage1.Device"
private_constant :DEVICE_INTERFACE

# sid of the device.
#
# @return [Integer]
def device_sid
storage_device.sid
end

# Name to represent the device.
#
# @return [String] e.g., "/dev/sda".
def device_name
storage_device.display_name || ""
end

# Description of the device.
#
# @return [String] e.g., "EXT4 Partition".
def device_description
Y2Storage::DeviceDescription.new(storage_device).to_s
end

def self.included(base)
base.class_eval do
dbus_interface DEVICE_INTERFACE do
dbus_reader :device_sid, "u", dbus_name: "SID"
dbus_reader :device_name, "s", dbus_name: "Name"
dbus_reader :device_description, "s", dbus_name: "Description"
end
end
end
end
end
end
end
end
end
31 changes: 25 additions & 6 deletions service/lib/agama/dbus/storage/interfaces/device/filesystem.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# find current contact information at www.suse.com.

require "dbus"
require "y2storage/filesystem_label"

module Agama
module DBus
Expand All @@ -44,25 +45,43 @@ def self.apply?(storage_device)
FILESYSTEM_INTERFACE = "org.opensuse.Agama.Storage1.Filesystem"
private_constant :FILESYSTEM_INTERFACE

# SID of the file system.
#
# It is useful to detect whether a file system is new.
#
# @return [Integer]
def filesystem_sid
storage_device.filesystem.sid
end

# File system type.
#
# @return [String] e.g., "ext4"
def filesystem_type
storage_device.filesystem.type.to_s
end

# Whether the filesystem contains the directory layout of an ESP partition.
# Mount path of the file system.
#
# @return [Boolean]
def filesystem_efi?
storage_device.filesystem.efi?
# @return [String] Empty if not mounted.
def filesystem_mount_path
storage_device.filesystem.mount_path || ""
end

# Label of the file system.
#
# @return [String] Empty if it has no label.
def filesystem_label
Y2Storage::FilesystemLabel.new(storage_device).to_s
end

def self.included(base)
base.class_eval do
dbus_interface FILESYSTEM_INTERFACE do
dbus_interface FILESYSTEM_INTERFACE do
dbus_reader :filesystem_sid, "u", dbus_name: "SID"
dbus_reader :filesystem_type, "s", dbus_name: "Type"
dbus_reader :filesystem_efi?, "b", dbus_name: "EFI"
dbus_reader :filesystem_mount_path, "s", dbus_name: "MountPath"
dbus_reader :filesystem_label, "s", dbus_name: "Label"
end
end
end
Expand Down
Loading
Loading