Skip to content

Commit

Permalink
Merge pull request #26 from yast/new_dbus_service
Browse files Browse the repository at this point in the history
initial new dbus service code
  • Loading branch information
jreidinger committed Feb 17, 2022
2 parents da843aa + fab6792 commit 6218249
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 131 deletions.
3 changes: 2 additions & 1 deletion yastd/Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ GEM
racc (1.6.0)
rake (13.0.6)
ruby-augeas (0.5.0)
ruby-dbus (0.16.0)
ruby-dbus (0.17.0)
rexml

PLATFORMS
ruby
Expand Down
2 changes: 1 addition & 1 deletion yastd/d-installer.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,5 @@ Gem::Specification.new do |spec|
spec.add_dependency "fast_gettext", "~> 2.2.0"
spec.add_dependency "nokogiri", "~> 1.13.1"
spec.add_dependency "rexml", "~> 3.2.5"
spec.add_dependency "ruby-dbus", "~> 0.16.0"
spec.add_dependency "ruby-dbus", "~> 0.17.0"
end
158 changes: 31 additions & 127 deletions yastd/lib/yast2/dbus/installer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,163 +23,67 @@

module Yast2
module DBus
# YaST D-Bus object (/org/opensuse/YaST/Installer)
# YaST D-Bus object (/org/opensuse/YaST/Installer1)
#
# @see https://rubygems.org/gems/ruby-dbus
class Installer < ::DBus::Object
attr_reader :installer, :logger

PROPERTY_INTERFACE = "org.freedesktop.DBus.Properties"
INSTALLER_INTERFACE = "org.opensuse.YaST.Installer"

# @param installer [Yast2::Installer] YaST installer instance
# @param args [Array<Object>] ::DBus::Object arguments
def initialize(installer, logger, *args)
@installer = installer
@logger = logger

installer.on_status_change do |status|
self.StatusChanged(status.id)
end
@available_languages = installer.languages.map { |k,v| [k, v.first, {}] }
@logger.debug "Available languages #{@available_languages.inspect}"
@available_base_products = installer.products

installer.dbus_obj = self

super(*args)
end

dbus_interface INSTALLER_INTERFACE do
dbus_method :GetLanguages, "out langs:a{sas}" do
logger.info "GetLanguages"

[installer.languages]
end

dbus_method :GetProducts, "out products:aa{ss}" do
logger.info "GetProducts"

products = installer.products.map do |product|
{ "name" => product.name, "display_name" => product.display_name }
end
[products]
end

dbus_method :GetStorage, "out proposal:aa{ss}" do
logger.info "GetStorage"

proposal = installer.storage_proposal.filesystems.map do |fs|
blk_device = fs.blk_devices.first
{
"mount" => fs.mount_point&.path,
"device" => blk_device.name,
"type" => fs.type&.to_s,
"size" => blk_device.size.to_i.to_s
}
end
[proposal]
end

dbus_method :GetDisks, "out disks:aa{ss}" do
logger.info "GetDisks"

disks = installer.disks.map do |disk|
{
"name" => disk.name,
"model" => disk.model,
"size" => disk.size.to_human_string
}
end
LANGUAGE_INTERFACE = "org.opensuse.YaST.Installer1.Language"
dbus_interface LANGUAGE_INTERFACE do
dbus_attr_reader :available_languages, "a(ssa{sv})"
attr_writer :available_languages
dbus_watcher :available_languages

[disks]
def marked_for_install
# TODO: change when installer support multiple target languages
[installer.language]
end

dbus_method :Probe, "out result:b" do
logger.info "Probe"
Thread.new { installer.probe }
true
end
dbus_reader :marked_for_install, "as"

dbus_method :Start, "out result:b" do
logger.info "Start"
Thread.new { installer.install }
true
end
dbus_method :ToInstall, "in LangIDs:as" do |lang_ids|
logger.info "ToInstall #{lang_ids.inspect}"

# FIXME: should we merge progress and status?
# TODO: return the id and the name
dbus_method :GetStatus, "out status:n" do
installer.status.id
# TODO: adapt installer API to allow more languages to install
installer.language = lang_ids.first
self[DBus::PROPERTY_INTERFACE].PropertiesChanged(LANGUAGE_INTERFACE, {"MarkedForInstall" => lang_ids}, [])
end

dbus_signal :StatusChanged, "status:n"

# signal for installation progress
#
# parameters:
#
# - message: localized string describing current step
# - total_steps: how many steps will be done
# - current_step: current step. Always in range of 0..total_steps
# - total_substeps: total count of smaller steps done as part of big step. Can be 0, which means no substeps defined
# - current_substep: current substep. Always in range of 0..total_substeps
dbus_signal :Progress,
"message:s, total_steps:t, current_step:t, total_substeps:t, current_substep:t"
end

dbus_interface PROPERTY_INTERFACE do
dbus_method :Get, "in interface:s, in propname:s, out value:v" do |interface, propname|
logger.info "Get(#{interface}, #{propname})"

if interface != INSTALLER_INTERFACE
raise ::DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '{@path}'"
end

begin
value = installer.send(propname.downcase.to_s)
value.respond_to?(:id) ? value.id : value.to_s
rescue NoMethodError
raise ::DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' not found on object '#{@path}'"
end
end
SOFTWARE_INTERFACE = "org.opensuse.YaST.Installer1.Software"
dbus_interface SOFTWARE_INTERFACE do
dbus_attr_reader :available_base_products, "a(ssa{sv})"
attr_writer :available_base_products
dbus_watcher :available_base_products

dbus_method :Set,
"in interface:s, in propname:s, in value:v" do |interface, propname, value|
logger.info "Set(#{interface}, #{propname}, #{value})"

unless interface == INSTALLER_INTERFACE
raise ::DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end

begin
s_value = value.to_s
installer.send("#{propname.downcase}=", s_value)
self.PropertiesChanged(interface, { propname => s_value }, [])
rescue Yast2::Installer::InvalidValue
raise ::DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Value '#{value}' not valid for '#{interface}.#{propname}' on object '#{@path}'"
rescue NoMethodError
raise ::DBus.error("org.freedesktop.DBus.Error.InvalidArgs"),
"Property '#{interface}.#{propname}' not found on object '#{@path}'"
end
def selected_base_product
installer.product
end

dbus_method :GetAll, "in interface:s, out value:a{sv}" do |interface|
logger.info "GetAll(#{interface})"
dbus_reader :selected_base_product, "s"

unless interface == INSTALLER_INTERFACE
raise ::DBus.error("org.freedesktop.DBus.Error.UnknownInterface"),
"Interface '#{interface}' not found on object '#{@path}'"
end

props = installer.options.merge("status" => installer.status.id)
normalized_props = props.reduce({}) { |h, (k, v)| h.merge(k.capitalize => v) }
[normalized_props]
end
dbus_method :SelectProduct, "in ProductID:s" do |product_id|
logger.info "SelectProduct #{product_id}"

dbus_signal :PropertiesChanged,
"interface:s, changed_properties:a{sv}, invalidated_properties:as"
installer.product = product_id
self[DBus::PROPERTY_INTERFACE].PropertiesChanged(SOFTWARE_INTERFACE, {"SelectedBaseProduct" => product_id}, [])
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions yastd/lib/yast2/dbus/service.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2021] SUSE LLC
# Copyright (c) [2022] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -38,7 +38,7 @@ class Service
SERVICE_NAME = "org.opensuse.YaST"

# @return [String] D-Bus object path
OBJECT_PATH = "/org/opensuse/YaST/Installer"
OBJECT_PATH = "/org/opensuse/YaST/Installer1"

attr_reader :bus

Expand Down
2 changes: 2 additions & 0 deletions yastd/share/dbus.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
<allow send_destination="org.opensuse.YaST" />
<allow send_destination="org.opensuse.YaST"
send_interface="org.freedesktop.DBus.Introspectable"/>
<allow send_destination="org.opensuse.YaST.Installer1" />
<allow receive_sender="org.opensuse.YaST.Installer1" />
<allow send_destination="org.opensuse.YaST.Installer" />
<allow receive_sender="org.opensuse.YaST.Installer" />
</policy>
Expand Down

0 comments on commit 6218249

Please sign in to comment.