Skip to content

Commit

Permalink
adapt ruby service to new questions API
Browse files Browse the repository at this point in the history
  • Loading branch information
jreidinger committed Jun 28, 2023
1 parent 7e56e5f commit 21c64d6
Show file tree
Hide file tree
Showing 10 changed files with 126 additions and 161 deletions.
8 changes: 4 additions & 4 deletions service/lib/agama/dbus/clients/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ module DBus
module Clients
# D-Bus client for asking a question.
class Question < Base
LUKS_ACTIVATION_IFACE = "org.opensuse.Agama.Questions1.LuksActivation"
private_constant :LUKS_ACTIVATION_IFACE
WITH_PASSWORD_IFACE = "org.opensuse.Agama.Questions1.WithPassword"
private_constant :WITH_PASSWORD_IFACE

# @return [::DBus::ProxyObject]
attr_reader :dbus_object
Expand All @@ -39,9 +39,9 @@ def initialize(object_path)
@dbus_object = service[object_path]
@dbus_iface = @dbus_object["org.opensuse.Agama.Questions1.Generic"]
# one D-Bus client for all kinds of questions
return unless @dbus_object.has_iface?(LUKS_ACTIVATION_IFACE)
return unless @dbus_object.has_iface?(WITH_PASSWORD_IFACE)

@luks_iface = @dbus_object[LUKS_ACTIVATION_IFACE]
@password_iface = @dbus_object[WITH_PASSWORD_IFACE]
end

# @return [String]
Expand Down
20 changes: 13 additions & 7 deletions service/lib/agama/dbus/clients/questions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ def ask(question)
# @param question [Agama::Question]
# @return [::DBus::ObjectPath]
def add_question(question)
if question.is_a?(Agama::LuksActivationQuestion)
add_luks_activation_question(question)
if question.is_a?(Agama::QuestionWithPassword)
add_question_with_password(question)
else
add_generic_question(question)
end
Expand All @@ -129,19 +129,25 @@ def add_question(question)
# @return [::DBus::ObjectPath]
def add_generic_question(question)
@dbus_object.New(
question.qclass,
question.text,
question.options.map(&:to_s),
Array(question.default_option&.to_s)
question.default_option.to_s,
question.data
)
end

# Adds a question for activating LUKS
#
# @param question [Agama::LuksActivationQuestion]
# @param question [Agama::QuestionWithPassword]
# @return [::DBus::ObjectPath]
def add_luks_activation_question(question)
@dbus_object.NewLuksActivation(
question.device, question.label, question.size, question.attempt
def add_question_with_password(question)
@dbus_object.NewWithPassword(
question.qclass,
question.text,
question.options.map(&:to_s),
question.default_option.to_s,
question.data
)
end
end
Expand Down
92 changes: 0 additions & 92 deletions service/lib/agama/luks_activation_question.rb

This file was deleted.

61 changes: 15 additions & 46 deletions service/lib/agama/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,16 @@
# find current contact information at www.suse.com.

module Agama
# This class represents a question
# This class represents a question to be created
#
# Questions are used when some information needs to be asked. For example, a question could be
# created for asking whether to continue or not when an error is detected.
class Question
# Each question is identified by an unique id
# Class of the question
# Helps with identification of same type of questions
#
# @return [Integer]
attr_reader :id
# @return [String]
attr_reader :qclass

# Text of the question
#
Expand All @@ -44,58 +45,26 @@ class Question

# Default option to use as answer
#
# @return [Symbol, nil]
# @return [Symbol]
attr_reader :default_option

# Answer of the question
#
# @return [Symbol, nil] nil if the question is not answered yet
attr_reader :answer

def initialize(text, options: [], default_option: nil)
@id = IdGenerator.next
# Additional data to hold identify question or improve UI to display it
# It is tight with {qclass}.
#
# @return [Hash<String,String>]
attr_reader :data

def initialize(qclass:, text:, options:, default_option:, data: {})
@qclass = qclass
@text = text
@options = options
@default_option = default_option
end

# Answers the question with an option
#
# @raise [ArgumentError] if the given value is not a valid answer.
#
# @param value [Symbol]
def answer=(value)
raise ArgumentError, "Invalid answer. Options: #{options}" unless valid_answer?(value)

@answer = value
end

# Whether the question is already answered
#
# @return [Boolean]
def answered?
!answer.nil?
end

private

# Checks whether the given value is a valid answer
#
# @param value [Symbol]
# @return [Boolean]
def valid_answer?(value)
options.include?(value)
end

# Helper class for generating unique ids
class IdGenerator
# Generates the next id to be used
#
# @return [Integer]
def self.next
@last_id ||= 0
@last_id += 1
end
@data = data
end
end
end
28 changes: 28 additions & 0 deletions service/lib/agama/question_with_password.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# frozen_string_literal: true

# Copyright (c) [2022] 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 "agama/question"

module Agama
# This class represent a question that contain additional field to provide password
class QuestionWithPassword < Question
end
end
8 changes: 6 additions & 2 deletions service/lib/agama/software/callbacks/media.rb
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,14 @@ def setup
# @return [String]
# @see https://github.com/yast/yast-yast2/blob/19180445ab935a25edd4ae0243aa7a3bcd09c9de/library/packages/src/modules/PackageCallbacks.rb#L620
# rubocop:disable Metrics/ParameterLists
def media_change(_error_code, error, _url, _product, _current, _current_label, _wanted,
def media_change(_error_code, error, url, _product, _current, _current_label, _wanted,
_wanted_label, _double_sided, _devices, _current_device)
question = Agama::Question.new(
error, options: [:Retry, :Skip], default_option: :Retry
qclass: "software.medium_error",
text: error,
options: [:Retry, :Skip],
default_option: :Skip,
data: { "url" => url }
)
questions_client.ask(question) do |question_client|
(question_client.answer == :Retry) ? "" : "S"
Expand Down
16 changes: 14 additions & 2 deletions service/lib/agama/software/callbacks/signature.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,11 @@ def accept_unsigned_file(filename, repo_id)
)

question = Agama::Question.new(
message, options: [:Yes, :No], default_option: :No
qclass: "software.unsigned_file",
text: message,
options: [:Yes, :No],
default_option: :No,
data: { "filename" => filename }
)
questions_client.ask(question) do |question_client|
question_client.answer == :Yes
Expand All @@ -89,7 +93,15 @@ def import_gpg_key(key, _repo_id)
)

question = Agama::Question.new(
message, options: [:Trust, :Skip], default_option: :Skip
qclass: "software.import_gpg",
text: message,
options: [:Trust, :Skip],
default_option: :Skip,
data: {
"id" => key["id"],
"name" => key["name"],
"fingerprint" => fingerprint
}
)

questions_client.ask(question) do |question_client|
Expand Down
37 changes: 32 additions & 5 deletions service/lib/agama/storage/callbacks/activate_luks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,21 @@ def call(info, attempt)

# Question to ask for LUKS activation
#
# @return [LuksActivationQuestion]
# @return [QuestionWithPassword]
def question(info, attempt)
LuksActivationQuestion.new(info.device_name,
label: info.label,
size: formatted_size(info.size),
attempt: attempt)
data = {
"device" => info.device_name,
"label" => info.label,
"size" => formatted_size(info.size),
"attempt" => attempt
}
QuestionWithPassword.new(
qclass: "storage.luks_activation",
text: generate_text(data),
options: [:skip, :decrypt],
default_option: :decrypt,
data: data
)
end

# Generates a formatted representation of the size
Expand All @@ -82,6 +91,24 @@ def question(info, attempt)
def formatted_size(value)
Y2Storage::DiskSize.new(value).to_human_string
end

# Generate the text for the question
#
# @return [String]
def generate_text(data)
"The device #{device_info(data)} is encrypted."
end

# Device information to include in the question
#
# @return [String]
def device_info(data)
info = [data["device"]]
info << data["label"] unless data["label"].to_s.empty?
info << "(#{data["size"]})" unless data["size"].to_s.empty?

info.join(" ")
end
end
end
end
Expand Down
7 changes: 6 additions & 1 deletion service/lib/agama/storage/callbacks/activate_multipath.rb
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,12 @@ def question
text = "The system seems to have multipath hardware. " \
"Do you want to activate multipath?"

Question.new(text, options: [:yes, :no])
Question.new(
qclass: "storage.activate_multipath",
text: text,
options: [:yes, :no],
default_option: :yes
)
end
end
end
Expand Down
Loading

0 comments on commit 21c64d6

Please sign in to comment.