Skip to content

Commit

Permalink
service: Avoid updating D-Bus nodes of devices tree
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Mar 6, 2024
1 parent 26fb99d commit 36ff75a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 18 deletions.
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
21 changes: 15 additions & 6 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 intefaces 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,17 +61,17 @@ 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.
Expand Down
6 changes: 0 additions & 6 deletions service/test/agama/dbus/storage/device_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -181,12 +181,6 @@
context "if the given device has the same sid" do
let(:new_device) { devicegraph.find_by_name("/dev/sda") }

it "sets the new device" do
subject.storage_device = new_device

expect(subject.storage_device).to equal(new_device)
end

it "emits a properties changed signal for each interface" do
subject.interfaces_and_properties.each_key do |interface|
expect(subject).to receive(:dbus_properties_changed).with(interface, anything, anything)
Expand Down

0 comments on commit 36ff75a

Please sign in to comment.