Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions doc/questions.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,16 @@ Sensitive answers or params will be replaced, so the user has to explicitly spec
| class | description | possible answers | available data | notes |
|--- |--- |--- |--- |--- |
| `autoyast.unsupported` | When there are unsupported elements in an AutoYaST profile | `Abort` `Continue` | `planned` elements to be supported in the future, `unsupported` unsupported elements | |
| `software.medium_error` | When there is issue with access to medium | `Retry` `Skip` | `url` with url where failed access happen | |
| `software.unsigned_file` | When file from repository is not digitally signed. If it should be used | `Yes` `No` | `filename` with name of file | |
| `load.retry` | When loading the config at autoinstallation time | `Yes` `No` | | |
| `registration.certificate` | Self-signed certificate encountered | `Trust` `Reject` | `url` `issuer_name` `issuer_date` `expiration_date` `sha1_fingerprint` `sha256_fingerprint` | |
| `software.digest.no_digest` | desc | `Yes` `No` | - | |
| `software.import_gpg` | When signature is sign with unknown GPG key | `Trust` `Skip` | `id` of key `name` of key and `fingerprint` of key | |
| `software.package_error.install_error` | When there is issue with installing a downloaded package | `Retry` `Continue` | `package` | |
| `software.package_error.medium_error` | When there is issue with access to medium | `Retry` `Continue` | `url` with url where failed access happen | |
| `software.package_error.provide_error` | Package download failed | `Retry` `Continue` | `package`: name, `error_code`: `IO_ERROR` or `INVALID` | |
| `software.script_problem` | Problem running a package script | `Retry` `Continue` | `details`: description | |
| `software.unknown_gpg` | Use a file signed with an unknown GPG key | `Yes` `No` | `id` of key, `filename` | |
| `software.unsigned_file` | When file from repository is not digitally signed. If it should be used | `Yes` `No` | `filename` with name of file | |
| `storage.activate_multipath` | When it looks like system has multipath and if it should be activated | `yes` `no` | | Here it is used lower case. It should be unified. |
| `storage.commit_error` | When some storage actions failed and if it should continue | `yes` `no` | | Also here it is lowercase |
| `storage.luks_activation` | When LUKS encrypted device is detected and it needs password to probe it | `skip` `decrypt` | `device` name, `label` of device, `size` of device and `attempt` the number of attempt | Answer contain additional field password that has to be filled if answer is `decrypt`. Attempt data can be used to limit passing wrong password. |
Expand Down
2 changes: 2 additions & 0 deletions rust/agama-autoinstall/src/questions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ impl UserQuestions {
id: None,
class: "load.retry".to_string(),
text: text.to_string(),
// FIXME: translate
options: vec!["Yes".to_string(), "No".to_string()],
option_labels: vec!["Yes".to_string(), "No".to_string()],
default_option: "No".to_string(),
data: Default::default(),
};
Expand Down
4 changes: 4 additions & 0 deletions rust/agama-lib/src/proxies/questions/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

//! # D-Bus interface proxy for: `org.opensuse.Agama1.Questions`
//!
//! FIXME, regenerate this
//!
//! This code was generated by `zbus-xmlgen` `5.0.0` from D-Bus introspection data.
//! Source: `org.opensuse.Agama1.Questions.bus.xml`.
//!
Expand Down Expand Up @@ -64,6 +66,7 @@ pub trait Questions {
class: &str,
text: &str,
options: &[&str],
option_labels: &[&str],
default_option: &str,
data: std::collections::HashMap<&str, &str>,
) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
Expand All @@ -74,6 +77,7 @@ pub trait Questions {
class: &str,
text: &str,
options: &[&str],
option_labels: &[&str],
default_option: &str,
data: std::collections::HashMap<&str, &str>,
) -> zbus::Result<zbus::zvariant::OwnedObjectPath>;
Expand Down
7 changes: 6 additions & 1 deletion rust/agama-lib/src/questions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ pub struct GenericQuestion {
pub class: String,
/// Textual representation of question. Expected to be read by people
pub text: String,
/// possible answers for question
/// possible answers for question. answer and default_option will be one of these.
pub options: Vec<String>,
/// displayed (translated) labels for the options.
pub option_labels: Vec<String>,
/// default answer. Can be used as hint or preselection and it is used as answer for unattended questions.
pub default_option: String,
/// additional data to help identify questions. Useful for automatic answers. It is question specific.
Expand All @@ -59,6 +61,7 @@ impl GenericQuestion {
class: String,
text: String,
options: Vec<String>,
option_labels: Vec<String>,
default_option: String,
data: HashMap<String, String>,
) -> Self {
Expand All @@ -67,6 +70,7 @@ impl GenericQuestion {
class,
text,
options,
option_labels,
default_option,
data,
answer: String::from(""),
Expand All @@ -86,6 +90,7 @@ impl GenericQuestion {
/// "test_class".to_string(),
/// "Really?".to_string(),
/// vec!["Yes".to_string(), "No".to_string()],
/// vec!["Ano".to_string(), "Ne".to_string()],
/// "No".to_string(),
/// HashMap::new()
/// );
Expand Down
19 changes: 19 additions & 0 deletions rust/agama-lib/src/questions/answers/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ mod tests {
class: "without_data".to_string(),
text: "JFYI we will kill all bugs during installation.".to_string(),
options: vec!["Ok".to_string(), "Cancel".to_string()],
option_labels: vec!["Oukej".to_string(), "Zrušit".to_string()],
default_option: "Cancel".to_string(),
data: HashMap::new(),
answer: "".to_string(),
Expand All @@ -192,6 +193,7 @@ mod tests {
class: "non-existing".to_string(),
text: "Hard question?".to_string(),
options: vec!["Ok".to_string(), "Cancel".to_string()],
option_labels: vec!["Oukej".to_string(), "Zrušit".to_string()],
default_option: "Cancel".to_string(),
data: HashMap::new(),
answer: "".to_string(),
Expand All @@ -207,6 +209,7 @@ mod tests {
class: "without_data".to_string(),
text: "Please provide password for dooms day.".to_string(),
options: vec!["Ok".to_string(), "Cancel".to_string()],
option_labels: vec!["Oukej".to_string(), "Zrušit".to_string()],
default_option: "Cancel".to_string(),
data: HashMap::new(),
answer: "".to_string(),
Expand All @@ -229,6 +232,11 @@ mod tests {
class: "with_data".to_string(),
text: "Hard question?".to_string(),
options: vec!["Ok2".to_string(), "Maybe".to_string(), "Cancel".to_string()],
option_labels: vec![
"Oukej2".to_string(),
"Možná".to_string(),
"Zrušit".to_string(),
],
default_option: "Cancel".to_string(),
data: HashMap::from([
("data1".to_string(), "value1".to_string()),
Expand All @@ -248,6 +256,11 @@ mod tests {
class: "with_data".to_string(),
text: "Hard question?".to_string(),
options: vec!["Ok2".to_string(), "Maybe".to_string(), "Cancel".to_string()],
option_labels: vec![
"Oukej2".to_string(),
"Možná".to_string(),
"Zrušit".to_string(),
],
default_option: "Cancel".to_string(),
data: HashMap::from([
("data1".to_string(), "another_value1".to_string()),
Expand All @@ -267,6 +280,11 @@ mod tests {
class: "with_data".to_string(),
text: "Hard question?".to_string(),
options: vec!["Ok2".to_string(), "Maybe".to_string(), "Cancel".to_string()],
option_labels: vec![
"Oukej2".to_string(),
"Možná".to_string(),
"Zrušit".to_string(),
],
default_option: "Cancel".to_string(),
data: HashMap::from([
("data1".to_string(), "different value".to_string()),
Expand Down Expand Up @@ -295,6 +313,7 @@ mod tests {
class: "without_data".to_string(),
text: "JFYI we will kill all bugs during installation.".to_string(),
options: vec!["Ok".to_string(), "Cancel".to_string()],
option_labels: vec!["Oukej".to_string(), "Zrušit".to_string()],
default_option: "Cancel".to_string(),
data: HashMap::new(),
answer: "".to_string(),
Expand Down
6 changes: 5 additions & 1 deletion rust/agama-lib/src/questions/http_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ mod test {
"class": "foo",
"text": "Shape",
"options": ["bouba","kiki"],
"optionLabels": ["buba","kyky"],
"defaultOption": "bouba",
"data": { "a": "A" }
},
Expand All @@ -153,6 +154,7 @@ mod test {
class: "foo".to_owned(),
text: "Shape".to_owned(),
options: vec!["bouba".to_owned(), "kiki".to_owned()],
option_labels: vec!["buba".to_owned(), "kyky".to_owned()],
default_option: "bouba".to_owned(),
data: HashMap::from([("a".to_owned(), "A".to_owned())]),
},
Expand All @@ -173,7 +175,7 @@ mod test {
.path("/api/questions")
.header("content-type", "application/json")
.body(
r#"{"generic":{"id":null,"class":"fiction.hamlet","text":"To be or not to be","options":["to be","not to be"],"defaultOption":"to be","data":{"a":"A"}},"withPassword":null}"#
r#"{"generic":{"id":null,"class":"fiction.hamlet","text":"To be or not to be","options":["to be","not to be"],"optionLabels":["být","nebýt"],"defaultOption":"to be","data":{"a":"A"}},"withPassword":null}"#
);
then.status(200)
.header("content-type", "application/json")
Expand All @@ -184,6 +186,7 @@ mod test {
"class": "fiction.hamlet",
"text": "To be or not to be",
"options": ["to be","not to be"],
"optionLabels": ["být","nebýt"],
"defaultOption": "to be",
"data": { "a": "A" }
},
Expand All @@ -199,6 +202,7 @@ mod test {
class: "fiction.hamlet".to_owned(),
text: "To be or not to be".to_owned(),
options: vec!["to be".to_owned(), "not to be".to_owned()],
option_labels: vec!["být".to_owned(), "nebýt".to_owned()],
default_option: "to be".to_owned(),
data: HashMap::from([("a".to_owned(), "A".to_owned())]),
},
Expand Down
1 change: 1 addition & 0 deletions rust/agama-lib/src/questions/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pub struct GenericQuestion {
pub class: String,
pub text: String,
pub options: Vec<String>,
pub option_labels: Vec<String>,
pub default_option: String,
pub data: HashMap<String, String>,
}
Expand Down
11 changes: 11 additions & 0 deletions rust/agama-server/src/questions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,11 @@ impl GenericQuestionObject {
self.0.options.to_owned()
}

#[zbus(property)]
pub fn option_labels(&self) -> Vec<String> {
self.0.option_labels.to_owned()
}

#[zbus(property)]
pub fn default_option(&self) -> &str {
self.0.default_option.as_str()
Expand Down Expand Up @@ -116,18 +121,21 @@ impl Questions {
class: &str,
text: &str,
options: Vec<&str>,
option_labels: Vec<&str>,
default_option: &str,
data: HashMap<String, String>,
) -> zbus::fdo::Result<ObjectPath> {
tracing::info!("Creating new question with text: {}.", text);
let id = self.last_id;
self.last_id += 1; // TODO use some thread safety
let options = options.iter().map(|o| o.to_string()).collect();
let option_labels = option_labels.iter().map(|o| o.to_string()).collect();
let mut question = questions::GenericQuestion::new(
id,
class.to_string(),
text.to_string(),
options,
option_labels,
default_option.to_string(),
data,
);
Expand All @@ -149,6 +157,7 @@ impl Questions {
class: &str,
text: &str,
options: Vec<&str>,
option_labels: Vec<&str>,
default_option: &str,
data: HashMap<String, String>,
) -> zbus::fdo::Result<ObjectPath> {
Expand All @@ -157,11 +166,13 @@ impl Questions {
self.last_id += 1; // TODO use some thread safety
// TODO: share code better
let options = options.iter().map(|o| o.to_string()).collect();
let option_labels = option_labels.iter().map(|o| o.to_string()).collect();
let base = questions::GenericQuestion::new(
id,
class.to_string(),
text.to_string(),
options,
option_labels,
default_option.to_string(),
data,
);
Expand Down
4 changes: 4 additions & 0 deletions rust/agama-server/src/questions/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ impl QuestionsClient<'_> {
// TODO: ugly API is caused by dbus method to create question. It can be changed in future as DBus is internal only API
let generic = &question.generic;
let options: Vec<&str> = generic.options.iter().map(String::as_ref).collect();
let option_labels: Vec<&str> = generic.option_labels.iter().map(String::as_ref).collect();
let data: HashMap<&str, &str> = generic
.data
.iter()
Expand All @@ -104,6 +105,7 @@ impl QuestionsClient<'_> {
&generic.class,
&generic.text,
&options,
&option_labels,
&generic.default_option,
data,
)
Expand All @@ -115,6 +117,7 @@ impl QuestionsClient<'_> {
&generic.class,
&generic.text,
&options,
&option_labels,
&generic.default_option,
data,
)
Expand Down Expand Up @@ -164,6 +167,7 @@ impl QuestionsClient<'_> {
class: get_property(properties, "Class")?,
text: get_property(properties, "Text")?,
options: get_property(properties, "Options")?,
option_labels: get_property(properties, "OptionLabels")?,
default_option: get_property(properties, "DefaultOption")?,
data: get_property(properties, "Data")?,
},
Expand Down
3 changes: 2 additions & 1 deletion service/.rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ Metrics/ParameterLists:
- lib/agama/software/repository.rb

Metrics/ClassLength:
Max: 300
# lib/agama/registration.rb is the outlier that should be split up
Max: 306
16 changes: 13 additions & 3 deletions service/lib/agama/autoyast/profile_reporter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,32 @@ def report(elements)
question = Agama::Question.new(
qclass: "autoyast.unsupported",
text: message,
options: [:Continue, :Abort],
default_option: :Continue,
options: [continue_id.to_sym, abort_id.to_sym],
default_option: continue_id.to_sym,
data: {
"planned" => planned.map(&:key).join(","),
"unsupported" => unsupported.map(&:key).join(",")
}
)

questions_client.ask(question) do |question_client|
question_client.answer == :Continue
question_client.answer == continue_id.to_sym
end
end

private

attr_reader :questions_client, :logger

def continue_id
# TRANSLATORS: button label
N_("Continue")
end

def abort_id
# TRANSLATORS: button label
N_("Abort")
end
end
end
end
2 changes: 2 additions & 0 deletions service/lib/agama/dbus/clients/question.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ module Agama
module DBus
module Clients
# D-Bus client for asking a question.
# Actually, this class is used only to retrieve the answer to an asked question.
# To _ask_ one, see {Questions.ask}.
class Question < Base
WITH_PASSWORD_IFACE = "org.opensuse.Agama1.Questions.WithPassword"
private_constant :WITH_PASSWORD_IFACE
Expand Down
2 changes: 2 additions & 0 deletions service/lib/agama/dbus/clients/questions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ def add_generic_question(question)
question.qclass,
question.text,
question.options.map(&:to_s),
question.option_labels,
question.default_option.to_s,
question.data
)
Expand All @@ -146,6 +147,7 @@ def add_question_with_password(question)
question.qclass,
question.text,
question.options.map(&:to_s),
question.option_labels,
question.default_option.to_s,
question.data
)
Expand Down
Loading
Loading