Skip to content

Commit

Permalink
service: Export LVM devices
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Mar 6, 2024
1 parent 02a93e9 commit 26fb99d
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 6 deletions.
9 changes: 6 additions & 3 deletions service/lib/agama/dbus/storage/devices_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,16 @@ def dbus_object?(dbus_object, device)
# 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
1 change: 1 addition & 0 deletions service/lib/agama/dbus/storage/interfaces/device.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module Device
require "agama/dbus/storage/interfaces/device/component"
require "agama/dbus/storage/interfaces/device/drive"
require "agama/dbus/storage/interfaces/device/filesystem"
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_table"
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
90 changes: 90 additions & 0 deletions service/lib/agama/dbus/storage/interfaces/device/lvm_vg.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
# 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"

module Agama
module DBus
module Storage
module Interfaces
module Device
# Interface for a LVM Volume Group.
#
# @note This interface is intended to be included by {Agama::DBus::Storage::Device} if
# needed.
module LvmVg
# Whether this interface should be implemented for the given device.
#
# @note LVM Volume Groups implement this interface.
#
# @param storage_device [Y2Storage::Device]
# @return [Boolean]
def self.apply?(storage_device)
storage_device.is?(:lvm_vg)
end

VOLUME_GROUP_INTERFACE = "org.opensuse.Agama.Storage1.LVM.VolumeGroup"
private_constant :VOLUME_GROUP_INTERFACE

# Name of the volume group
#
# @return [String] e.g., "/dev/mapper/vg0"
def lvm_vg_name
storage_device.name
end

# Size of the volume group in bytes
#
# @return [Integer]
def lvm_vg_size
storage_device.size.to_i
end

# D-Bus paths of the objects representing the physical volumes.
#
# @return [Array<String>]
def lvm_vg_pvs
storage_device.lvm_pvs.map { |p| tree.path_for(p.plain_blk_device) }
end

# D-Bus paths of the objects representing the logical volumes.
#
# @return [Array<String>]
def lvm_vg_lvs
storage_device.lvm_lvs.map { |l| tree.path_for(l) }
end

def self.included(base)
base.class_eval do
dbus_interface VOLUME_GROUP_INTERFACE do
dbus_reader :lvm_vg_name, "s", dbus_name: "Name"
dbus_reader :lvm_vg_size, "t", dbus_name: "Size"
dbus_reader :lvm_vg_pvs, "ao", dbus_name: "PhysicalVolumes"
dbus_reader :lvm_vg_lvs, "ao", dbus_name: "LogicalVolumes"
end
end
end
end
end
end
end
end
end
19 changes: 16 additions & 3 deletions service/test/agama/dbus/storage/device_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,20 @@
# To contact SUSE LLC about this file by physical or electronic mail, you may
# find current contact information at www.suse.com.

require "agama/dbus/storage/device"
require "agama/dbus/storage/devices_tree"
require "dbus"
require_relative "../../../test_helper"
require_relative "../../storage/storage_helpers"
require_relative "./interfaces/device/block_examples"
require_relative "./interfaces/device/component_examples"
require_relative "./interfaces/device/drive_examples"
require_relative "./interfaces/device/filesystem_examples"
require_relative "./interfaces/device/lvm_vg_examples"
require_relative "./interfaces/device/md_examples"
require_relative "./interfaces/device/multipath_examples"
require_relative "./interfaces/device/partition_table_examples"
require_relative "./interfaces/device/raid_examples"
require "agama/dbus/storage/device"
require "agama/dbus/storage/devices_tree"
require "dbus"

describe Agama::DBus::Storage::Device do
include Agama::RSpec::StorageHelpers
Expand Down Expand Up @@ -110,6 +111,16 @@
end
end

context "when the given device is a LVM volume group" do
let(:scenario) { "trivial_lvm.yml" }

let(:device) { devicegraph.find_by_name("/dev/vg0") }

it "defines the LVM.VolumeGroup interface" do
expect(subject).to include_dbus_interface("org.opensuse.Agama.Storage1.LVM.VolumeGroup")
end
end

context "when the given device has a partition table" do
let(:scenario) { "partitioned_md.yml" }

Expand Down Expand Up @@ -142,6 +153,8 @@

include_examples "Block interface"

include_examples "LVM.VolumeGroup interface"

include_examples "PartitionTable interface"

include_examples "Filesystem interface"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# 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_relative "../../../../../test_helper"

shared_examples "LVM.VolumeGroup interface" do
describe "LVM.VolumeGroup D-Bus interface" do
let(:scenario) { "trivial_lvm.yml" }

let(:device) { devicegraph.find_by_name("/dev/vg0") }

describe "#lvm_vg_name" do
it "returns the name of the volume group" do
expect(subject.lvm_vg_name).to eq("/dev/vg0")
end
end

describe "#lvm_vg_size" do
before do
allow(device).to receive(:size).and_return(size)
end

let(:size) { Y2Storage::DiskSize.new(1024) }

it "returns the size in bytes" do
expect(subject.lvm_vg_size).to eq(1024)
end
end

describe "#lvm_vg_pvs" do
it "returns the D-Bus path of the physical volumes" do
sda1 = devicegraph.find_by_name("/dev/sda1")

expect(subject.lvm_vg_pvs).to contain_exactly(tree.path_for(sda1))
end
end

describe "#lvm_vg_lvs" do
it "returns the D-Bus path of the logical volumes" do
lv1 = devicegraph.find_by_name("/dev/vg0/lv1")

expect(subject.lvm_vg_lvs).to contain_exactly(tree.path_for(lv1))
end
end
end
end
24 changes: 24 additions & 0 deletions service/test/fixtures/trivial_lvm.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
- disk:
name: /dev/sda
size: 200 GiB
partition_table: gpt
partitions:

- partition:
size: unlimited
name: /dev/sda1
id: lvm

- lvm_vg:
vg_name: vg0
lvm_pvs:
- lvm_pv:
blk_device: /dev/sda1

lvm_lvs:
- lvm_lv:
size: unlimited
lv_name: lv1
file_system: btrfs
mount_point: /

0 comments on commit 26fb99d

Please sign in to comment.