Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adapt dbus API to prepare for answers file and change use_defaults to… #669

Merged
merged 19 commits into from
Jul 26, 2023

Conversation

jreidinger
Copy link
Contributor

@jreidinger jreidinger commented Jul 19, 2023

… interactive property

Problem

We want to have support for predefined answers and it is missing.

https://trello.com/c/9plYc08k/3373-8-agama-add-support-for-unattended-questions

Solution

Adapt dbus API to allow to add such file.

Testing

  • Tested manually
  • Unit tested

Follow-ups

  • document all types of questions we have
  • some tracking/reporting feature so user can see questions that was asked/answered.

@coveralls
Copy link

coveralls commented Jul 19, 2023

Coverage Status

coverage: 72.051% (-0.1%) from 72.172% when pulling 266f3d0 on answers_support into 5d4f3b2 on master.

log::info!("set interactive to {}", value);
if value {
if !self.interactive() {
self.answer_strategies.pop();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This means that no strategies mean "no non-interactive" strategies, that is, the default strategy is interaction? Should be explicitly stated at Questions::answer_strategies declaration

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, no strategies means that user need to answer it itself. Will document it.

rust/agama-dbus-server/src/questions.rs Outdated Show resolved Hide resolved
@jreidinger jreidinger marked this pull request as ready for review July 20, 2023 20:32
}

#[test]
fn test_full_data_match() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this test does the same thing as partial_data_match. What is the point?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well, difference here is that first test match only one answer. But here data2 match one answer and data1 another. So it test if wins correct answer.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, maybe I can express it slightly better in code or comments, will try

<!--
UseDefaultAnswer:
AddAnswerFile:
@path: Local fs path to answers file in yaml format.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP: In Agama we are using both YaML and Json (jsonnet). It was already commented in some planning that we should converge to a single format if there is no reason to keep both. I would vote for using json everywhere: config file, autoinstall profile and questions answers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

luckily it is easy with abstraction library provides. It is just about different crate. So when it is unify it is fine for me to convert it.

proxy
.set_interactive(value == Modes::Interactive)
.await
.context("Failed to set default answer")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I find the error a bit misleading. What about "Failed to set the mode for answering questions".

proxy
.add_answer_file(path.as_str())
.await
.context("Failed to set default answer")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP: The same here, maybe "Failed to set default answers from answers file".

@@ -103,7 +110,17 @@ trait AnswerStrategy {
/// AnswerStrategy that provides as answer the default option.
struct DefaultAnswers;

impl DefaultAnswers {
pub fn id() -> u8 {
1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP: I think this can be a field of the struct.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reason why it is also class method is to allow detection of strategy like below that instance is DefaultAnswers

fn interactive(&self) -> bool {
let last = self.answer_strategies.last();
if let Some(real_strategy) = last {
real_strategy.id() != DefaultAnswers::id()
Copy link
Contributor

@joseivanlopez joseivanlopez Jul 26, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if I understood the idea of having more than one strategy. Is it for priorities? First from file, if no found then default, if not found then ask to user? And the mode is only considered interactive if the last assigned strategy is not DefaultAnswers. But what happens if the last strategy is answers?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reason for strategies is extensibility, which allows to add completely different source of answers from strategy like e.g. some remote server answering it.
So whole idea is to have list of strategies and the first one that can answer it, provide that answer.
Default strategy should be always able to answer, so it is reason why it is last as answer file has precedence. And also it means that it is non interactive.
If last strategy is answers and it does not provide answer to given question, it is asked user. It is general rule, if no strategy can answer, then ask user ( aka interactive mode ).

@@ -81,7 +83,12 @@ enum QuestionType {
}

/// Trait for objects that can provide answers to all kind of Question.
///
/// If not strategy is used or all defined strategies does not know answer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NP: a bit of rewording: "If no strategy is selected or the answer is unknown, then ask to the user".

pub data: Option<HashMap<String, String>>,
/// The answer text is the only mandatory part of an Answer
pub answer: String,
/// All possible mixins have to be here, so they can be specified in an Answer
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixins?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixins to Base Question like WithPassword. So it means that all possible additional data entries from additional mixins to question have to be specified in answer.

@jreidinger jreidinger merged commit 81a5d9b into master Jul 26, 2023
14 checks passed
@jreidinger jreidinger deleted the answers_support branch July 26, 2023 13:04
@imobachgs imobachgs mentioned this pull request Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants