Skip to content

Commit

Permalink
[service] Export a separate product object
Browse files Browse the repository at this point in the history
  • Loading branch information
joseivanlopez committed Oct 19, 2023
1 parent 254dfe4 commit 6c6cba2
Show file tree
Hide file tree
Showing 7 changed files with 346 additions and 226 deletions.
12 changes: 9 additions & 3 deletions service/lib/agama/dbus/clients/software.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ def initialize
@dbus_object = service["/org/opensuse/Agama/Software1"]
@dbus_object.introspect

@dbus_product = service["/org/opensuse/Agama/Software1/Product"]
@dbus_product.introspect

@dbus_proposal = service["/org/opensuse/Agama/Software1/Proposal"]
@dbus_proposal.introspect
end
Expand All @@ -55,7 +58,7 @@ def service_name
#
# @return [Array<Array<String, String>>] name and display name of each product
def available_products
dbus_object["org.opensuse.Agama.Software1"]["AvailableProducts"].map do |l|
dbus_product["org.opensuse.Agama.Software1.Product"]["AvailableProducts"].map do |l|
l[0..1]
end
end
Expand All @@ -64,7 +67,7 @@ def available_products
#
# @return [String, nil] name of the product
def selected_product
product = dbus_object["org.opensuse.Agama.Software1"]["SelectedProduct"]
product = dbus_product["org.opensuse.Agama.Software1.Product"]["SelectedProduct"]
return nil if product.empty?

product
Expand All @@ -74,7 +77,7 @@ def selected_product
#
# @param name [String]
def select_product(name)
dbus_object.SelectProduct(name)
dbus_product.SelectProduct(name)
end

# Starts the probing process
Expand Down Expand Up @@ -180,6 +183,9 @@ def on_product_selected(&block)
# @return [::DBus::Object]
attr_reader :dbus_object

# @return [::DBus::Object]
attr_reader :dbus_product

# @return [::DBus::Object]
attr_reader :dbus_proposal
end
Expand Down
24 changes: 16 additions & 8 deletions service/lib/agama/dbus/clients/with_issues.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,25 @@ module WithIssues
ISSUES_IFACE = "org.opensuse.Agama1.Issues"
private_constant :ISSUES_IFACE

# Returns the issues
# Returns issues from all objects that implement the issues interface.
#
# @return [Array<Issue>]
def issues
objects_with_issues_interface.map { |o| issues_from(o) }.flatten
end

# Determines whether there are errors
#
# @return [Boolean]
def errors?
issues.any?(&:error?)
end

def objects_with_issues_interface
service.root.descendant_objects.select { |o| o.interfaces.include?(ISSUES_IFACE) }
end

def issues_from(dbus_object)
sources = [nil, Issue::Source::SYSTEM, Issue::Source::CONFIG]
severities = [Issue::Severity::WARN, Issue::Severity::ERROR]

Expand All @@ -42,13 +57,6 @@ def issues
severity: severities[dbus_issue[3]])
end
end

# Determines whether there are errors
#
# @return [Boolean]
def errors?
issues.any?(&:error?)
end
end
end
end
3 changes: 2 additions & 1 deletion service/lib/agama/dbus/software.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# frozen_string_literal: true

# Copyright (c) [2022] SUSE LLC
# Copyright (c) [2022-2023] SUSE LLC
#
# All Rights Reserved.
#
Expand Down Expand Up @@ -28,4 +28,5 @@ module Software
end

require "agama/dbus/software/manager"
require "agama/dbus/software/product"
require "agama/dbus/software/proposal"
201 changes: 1 addition & 200 deletions service/lib/agama/dbus/software/manager.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@
# find current contact information at www.suse.com.

require "dbus"
require "suse/connect"
require "agama/dbus/base_object"
require "agama/dbus/clients/locale"
require "agama/dbus/clients/network"
require "agama/dbus/interfaces/issues"
require "agama/dbus/interfaces/progress"
require "agama/dbus/interfaces/service_status"
require "agama/dbus/with_service_status"
require "agama/registration"

module Agama
module DBus
Expand Down Expand Up @@ -56,7 +54,7 @@ def initialize(backend, logger)
@selected_patterns = {}
end

# List of issues, see {DBus::Interfaces::Issues}
# List of software related issues, see {DBus::Interfaces::Issues}
#
# @return [Array<Agama::Issue>]
def issues
Expand All @@ -67,23 +65,6 @@ def issues
private_constant :SOFTWARE_INTERFACE

dbus_interface SOFTWARE_INTERFACE do
dbus_reader :available_products, "a(ssa{sv})"

dbus_reader :selected_product, "s"

dbus_method :SelectProduct, "in id:s, out result:(us)" do |id|
logger.info "Selecting product #{id}"

code, description = select_product(id)

if code == 0
dbus_properties_changed(SOFTWARE_INTERFACE, { "SelectedProduct" => id }, [])
dbus_properties_changed(REGISTRATION_INTERFACE, { "Requirement" => requirement }, [])
end

[[code, description]]
end

# value of result hash is category, description, icon, summary and order
dbus_method :ListPatterns, "in Filtered:b, out Result:a{s(sssss)}" do |filtered|
[
Expand Down Expand Up @@ -129,41 +110,6 @@ def issues
dbus_method(:Finish) { finish }
end

def available_products
backend.products.map do |product|
[product.id, product.display_name, { "description" => product.description }]
end
end

# Returns the selected base product
#
# @return [String] Product ID or an empty string if no product is selected
def selected_product
backend.product&.id || ""
end

# Selects a product.
#
# @param id [String] Product id.
# @return [Array(Integer, String)] Result code and a description.
# Possible result codes:
# 0: success
# 1: already selected
# 2: deregister first
# 3: unknown product
def select_product(id)
if backend.product&.id == id
[1, "Product is already selected"]
elsif backend.registration.reg_code
[2, "Current product must be deregistered first"]
else
backend.select_product(id)
[0, ""]
end
rescue ArgumentError
[3, "Unknown product"]
end

def probe
busy_while { backend.probe }
end
Expand All @@ -182,103 +128,6 @@ def finish
busy_while { backend.finish }
end

REGISTRATION_INTERFACE = "org.opensuse.Agama1.Registration"
private_constant :REGISTRATION_INTERFACE

dbus_interface REGISTRATION_INTERFACE do
dbus_reader(:reg_code, "s")

dbus_reader(:email, "s")

dbus_reader(:requirement, "u")

dbus_method(:Register, "in reg_code:s, in options:a{sv}, out result:(us)") do |*args|
[register(args[0], email: args[1]["Email"])]
end

dbus_method(:Deregister, "out result:(us)") { [deregister] }
end

def reg_code
backend.registration.reg_code || ""
end

def email
backend.registration.email || ""
end

# Registration requirement.
#
# @return [Integer] Possible values:
# 0: not required
# 1: optional
# 2: mandatory
def requirement
case backend.registration.requirement
when Agama::Registration::Requirement::MANDATORY
2
when Agama::Registration::Requirement::OPTIONAL
1
else
0
end
end

# Tries to register with the given registration code.
#
# @param reg_code [String]
# @param email [String, nil]
#
# @return [Array(Integer, String)] Result code and a description.
# Possible result codes:
# 0: success
# 1: missing product
# 2: already registered
# 3: network error
# 4: timeout error
# 5: api error
# 6: missing credentials
# 7: incorrect credentials
# 8: invalid certificate
# 9: internal error (e.g., parsing json data)
def register(reg_code, email: nil)
if !backend.product
[1, "Product not selected yet"]
elsif backend.registration.reg_code
[2, "Product already registered"]
else
connect_result(first_error_code: 3) do
backend.registration.register(reg_code, email: email)
end
end
end

# Tries to deregister.
#
# @return [Array(Integer, String)] Result code and a description.
# Possible result codes:
# 0: success
# 1: missing product
# 2: not registered yet
# 3: network error
# 4: timeout error
# 5: api error
# 6: missing credentials
# 7: incorrect credentials
# 8: invalid certificate
# 9: internal error (e.g., parsing json data)
def deregister
if !backend.product
[1, "Product not selected yet"]
elsif !backend.registration.reg_code
[2, "Product not registered yet"]
else
connect_result(first_error_code: 3) do
backend.registration.deregister
end
end
end

private

# @return [Agama::Software]
Expand All @@ -300,8 +149,6 @@ def register_callbacks
self.selected_patterns = compute_patterns
end

backend.registration.on_change { registration_properties_changed }

backend.on_issues_change { issues_properties_changed }
end

Expand All @@ -315,52 +162,6 @@ def compute_patterns

patterns
end

def registration_properties_changed
dbus_properties_changed(REGISTRATION_INTERFACE,
interfaces_and_properties[REGISTRATION_INTERFACE], [])
end

# Result from calling to SUSE connect.
#
# @raise [Exception] if an unexpected error is found.
#
# @return [Array(Integer, String)] List including a result code and a description
# (e.g., [1, "Connection to registration server failed (network error)"]).
def connect_result(first_error_code: 1, &block)
block.call
[0, ""]
rescue SocketError => e
connect_result_from_error(e, first_error_code, "network error")
rescue Timeout::Error => e
connect_result_from_error(e, first_error_code + 1, "timeout")
rescue SUSE::Connect::ApiError => e
connect_result_from_error(e, first_error_code + 2)
rescue SUSE::Connect::MissingSccCredentialsFile => e
connect_result_from_error(e, first_error_code + 3, "missing credentials")
rescue SUSE::Connect::MalformedSccCredentialsFile => e
connect_result_from_error(e, first_error_code + 4, "incorrect credentials")
rescue OpenSSL::SSL::SSLError => e
connect_result_from_error(e, first_error_code + 5, "invalid certificate")
rescue JSON::ParserError => e
connect_result_from_error(e, first_error_code + 6)
end

# Generates a result from a given error.
#
# @param error [Exception]
# @param error_code [Integer]
# @param details [String, nil]
#
# @return [Array(Integer, String)] List including an error code and a description.
def connect_result_from_error(error, error_code, details = nil)
logger.error("Error connecting to registration server: #{error}")

description = "Connection to registration server failed"
description += " (#{details})" if details

[error_code, description]
end
end
end
end
Expand Down
Loading

0 comments on commit 6c6cba2

Please sign in to comment.