Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package agama for openSUSE:Factory checked 
in at 2025-07-31 17:45:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/agama (Old)
 and      /work/SRC/openSUSE:Factory/.agama.new.1944 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "agama"

Thu Jul 31 17:45:20 2025 rev:25 rq:1295725 version:0

Changes:
--------
--- /work/SRC/openSUSE:Factory/agama/agama.changes      2025-07-23 
16:39:28.806289929 +0200
+++ /work/SRC/openSUSE:Factory/.agama.new.1944/agama.changes    2025-07-31 
17:45:46.731102429 +0200
@@ -1,0 +2,18 @@
+Thu Jul 24 13:19:52 UTC 2025 - Imobach Gonzalez Sosa <[email protected]>
+
+- Introduce inst.auto_insecure and inst.script_insecure to disable
+  SSL checks for inst.auto and inst.script (bsc#1246836).
+
+-------------------------------------------------------------------
+Wed Jul 23 14:48:53 UTC 2025 - Ladislav Slezák <[email protected]>
+
+- Added "--insecure" option to "agama config load" and
+  "agama config generate" commands (related to bsc#1246836)
+
+-------------------------------------------------------------------
+Wed Jul 23 11:37:04 UTC 2025 - Knut Anderssen <[email protected]>
+
+- Fix CLI connection update when using an special character in
+  the connection ID (bsc#1246930, gh#agama-project/agama#2605).
+
+-------------------------------------------------------------------
@@ -15,2 +33,2 @@
-- Add support for an inst.script that allows to run an arbitrary
-  script (bsc#1246702, gh#agama-project/agama#2589).
+- Add support for an inst.script option that allows to run an
+  arbitrary script (bsc#1246702, gh#agama-project/agama#2589).
@@ -47 +64,0 @@
-

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ agama.obscpio ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/Cargo.lock new/agama/Cargo.lock
--- old/agama/Cargo.lock        2025-07-22 16:19:39.000000000 +0200
+++ new/agama/Cargo.lock        2025-07-25 11:45:56.000000000 +0200
@@ -72,6 +72,7 @@
  "jsonschema",
  "jsonwebtoken",
  "log",
+ "percent-encoding",
  "regex",
  "reqwest",
  "serde",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/auto_loader.rs 
new/agama/agama-autoinstall/src/auto_loader.rs
--- old/agama/agama-autoinstall/src/auto_loader.rs      2025-07-22 
16:19:39.000000000 +0200
+++ new/agama/agama-autoinstall/src/auto_loader.rs      2025-07-25 
11:45:56.000000000 +0200
@@ -18,14 +18,8 @@
 // To contact SUSE LLC about this file by physical or electronic mail, you may
 // find current contact information at www.suse.com.
 
-use crate::ConfigLoader;
-use agama_lib::{
-    http::BaseHTTPClient,
-    questions::{
-        http_client::HTTPClient as QuestionsHTTPClient,
-        model::{GenericQuestion, Question},
-    },
-};
+use crate::{ConfigLoader, UserQuestions};
+use agama_lib::http::BaseHTTPClient;
 use anyhow::anyhow;
 
 /// List of pre-defined locations for profiles.
@@ -45,16 +39,20 @@
 ///
 /// Check the [Self::load] description for further information.
 pub struct ConfigAutoLoader {
-    questions: QuestionsHTTPClient,
+    questions: UserQuestions,
+    insecure: bool,
 }
 
 impl ConfigAutoLoader {
     /// Builds a new loader.
     ///
     /// * `http`: base client to connect to Agama.
-    pub fn new(http: BaseHTTPClient) -> anyhow::Result<Self> {
-        let questions = QuestionsHTTPClient::new(http)?;
-        Ok(Self { questions })
+    /// * `insecure`: whether to skip SSL cert checks.
+    pub fn new(http: BaseHTTPClient, insecure: bool) -> anyhow::Result<Self> {
+        Ok(Self {
+            questions: UserQuestions::new(http),
+            insecure,
+        })
     }
 
     /// Loads the configuration for the unattended installation.
@@ -66,7 +64,7 @@
     ///
     /// See [Self::load] for further information.
     pub async fn load(&self, urls: &Vec<String>) -> anyhow::Result<()> {
-        let loader = ConfigLoader::default();
+        let loader = ConfigLoader::new(self.insecure);
         if urls.is_empty() {
             self.load_predefined_config(loader).await
         } else {
@@ -103,31 +101,13 @@
         Err(anyhow!("No configuration was found"))
     }
 
-    /// Asks the user whether to retry loading the profile.
     async fn should_retry(&self, url: &str) -> anyhow::Result<bool> {
-        let text = format!(
+        let msg = format!(
             r#"
                 It was not possible to load the configuration from {url}.
-                It was unreachable or invalid. Do you want to try again?"
+                It was unreachable or invalid. Do you want to try again?
                 "#
         );
-        let generic = GenericQuestion {
-            id: None,
-            class: "config.load_error".to_string(),
-            text,
-            options: vec!["Yes".to_string(), "No".to_string()],
-            default_option: "No".to_string(),
-            data: Default::default(),
-        };
-        let question = Question {
-            generic,
-            with_password: None,
-        };
-        let question = self.questions.create_question(&question).await?;
-        let answer = self
-            .questions
-            .get_answer(question.generic.id.unwrap())
-            .await?;
-        Ok(answer.generic.answer == "Yes")
+        self.questions.should_retry(&msg).await
     }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/kernel_cmdline.rs 
new/agama/agama-autoinstall/src/kernel_cmdline.rs
--- old/agama/agama-autoinstall/src/kernel_cmdline.rs   2025-07-22 
16:19:39.000000000 +0200
+++ new/agama/agama-autoinstall/src/kernel_cmdline.rs   2025-07-25 
11:45:56.000000000 +0200
@@ -63,6 +63,12 @@
     pub fn get(&self, name: &str) -> Vec<String> {
         self.0.get(name).cloned().unwrap_or(vec![])
     }
+
+    /// Returns the last value for the argument
+    pub fn get_last(&self, name: &str) -> Option<String> {
+        let values = self.0.get(name)?;
+        values.last().cloned()
+    }
 }
 
 #[cfg(test)]
@@ -81,4 +87,12 @@
         assert_eq!(args.get("rd.neednet"), vec!["1".to_string()]);
         assert!(args.get("unknown").is_empty());
     }
+
+    #[test]
+    fn test_cmdline_args_last() {
+        let args_str = r"inst.auto_insecure=1 inst.auto_insecure=0";
+        let args = KernelCmdline::parse_str(args_str);
+
+        assert_eq!(args.get_last("inst.auto_insecure"), Some("0".to_string()));
+    }
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/lib.rs 
new/agama/agama-autoinstall/src/lib.rs
--- old/agama/agama-autoinstall/src/lib.rs      2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-autoinstall/src/lib.rs      2025-07-25 11:45:56.000000000 
+0200
@@ -17,25 +17,6 @@
 //
 // To contact SUSE LLC about this file by physical or electronic mail, you may
 // find current contact information at www.suse.com.
-// Copyright (c) [2025] SUSE LLC
-//
-// All Rights Reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License as published by the Free
-// Software Foundation; either version 2 of the License, or (at your option)
-// any later version.
-//
-// 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.
 
 mod kernel_cmdline;
 pub use kernel_cmdline::KernelCmdline;
@@ -48,3 +29,6 @@
 
 mod scripts;
 pub use scripts::ScriptsRunner;
+
+mod questions;
+pub use questions::UserQuestions;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/loader.rs 
new/agama/agama-autoinstall/src/loader.rs
--- old/agama/agama-autoinstall/src/loader.rs   2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-autoinstall/src/loader.rs   2025-07-25 11:45:56.000000000 
+0200
@@ -29,27 +29,40 @@
 /// It relies on Agama's command-line to generate and load the new
 /// configuration. In the future, it could rely directly on Agama libraries
 /// instead of the command-line.
-#[derive(Default)]
-pub struct ConfigLoader;
+pub struct ConfigLoader {
+    insecure: bool,
+}
 
 impl ConfigLoader {
+    pub fn new(insecure: bool) -> Self {
+        Self { insecure }
+    }
+
     /// Loads the configuration from the given URL.
     pub async fn load(&self, url: &str) -> anyhow::Result<()> {
+        let mut generate_args = vec!["config", "generate", url];
+        if self.insecure {
+            generate_args.insert(0, "--insecure");
+        }
+
         let generate_cmd = std::process::Command::new("agama")
             .env("YAST_SKIP_PROFILE_FETCH_ERROR", "1")
             .env("YAST_SKIP_XML_VALIDATION", "1")
-            .args(["config", "generate", url])
+            .args(generate_args)
             .output()?;
 
         if !generate_cmd.status.success() {
-            return Err(anyhow!(
-                "Could not run generate the configuration: {:?}",
-                generate_cmd.stderr,
-            ));
+            let message = String::from_utf8_lossy(&generate_cmd.stderr);
+            return Err(anyhow!("Could not generate the configuration: {}", 
message));
+        }
+
+        let mut load_args = vec!["config", "load"];
+        if self.insecure {
+            load_args.insert(0, "--insecure");
         }
 
         let child = std::process::Command::new("agama")
-            .args(["config", "load"])
+            .args(load_args)
             .stdin(Stdio::piped())
             .stdout(Stdio::piped())
             .stderr(Stdio::piped())
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/main.rs 
new/agama/agama-autoinstall/src/main.rs
--- old/agama/agama-autoinstall/src/main.rs     2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-autoinstall/src/main.rs     2025-07-25 11:45:56.000000000 
+0200
@@ -36,23 +36,29 @@
     Ok(BaseHTTPClient::new(API_URL)?.authenticated(&token)?)
 }
 
+pub fn insecure_from(cmdline: &KernelCmdline, key: &str) -> bool {
+    let value = cmdline.get_last(key);
+    Some("1".to_string()) == value
+}
+
 #[tokio::main]
 async fn main() -> anyhow::Result<()> {
     let args = KernelCmdline::parse_file(CMDLINE_FILE)?;
     let http = build_base_client()?;
     let manager_client = ManagerHTTPClient::new(http.clone());
-    let loader = ConfigAutoLoader::new(http.clone())?;
 
     let scripts = args.get("inst.script");
-    // TODO: add support to disable SSL checks.
-    let mut runner = ScriptsRunner::new("/run/agama/inst-scripts", false);
+    let script_insecure = insecure_from(&args, "inst.script_insecure");
+    let mut runner = ScriptsRunner::new(http.clone(), 
"/run/agama/inst-scripts", script_insecure);
     for url in scripts {
         println!("Running script from {}", &url);
-        if let Err(error) = runner.run(&url) {
+        if let Err(error) = runner.run(&url).await {
             eprintln!("Error running the script from {url}: {}", error);
         }
     }
 
+    let auto_insecure = insecure_from(&args, "inst.auto_insecure");
+    let loader = ConfigAutoLoader::new(http.clone(), auto_insecure)?;
     let urls = args.get("inst.auto");
     if let Err(error) = loader.load(&urls).await {
         eprintln!("Skipping the auto-installation: {error}");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/questions.rs 
new/agama/agama-autoinstall/src/questions.rs
--- old/agama/agama-autoinstall/src/questions.rs        1970-01-01 
01:00:00.000000000 +0100
+++ new/agama/agama-autoinstall/src/questions.rs        2025-07-25 
11:45:56.000000000 +0200
@@ -0,0 +1,63 @@
+// Copyright (c) [2025] SUSE LLC
+//
+// All Rights Reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 of the License, or (at your option)
+// any later version.
+//
+// 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.
+
+//! This module offers a mechanism to ask questions to users.
+
+use agama_lib::{
+    http::BaseHTTPClient,
+    questions::{
+        http_client::HTTPClient as QuestionsHTTPClient,
+        model::{GenericQuestion, Question},
+    },
+};
+
+pub struct UserQuestions {
+    questions: QuestionsHTTPClient,
+}
+
+impl UserQuestions {
+    pub fn new(client: BaseHTTPClient) -> Self {
+        Self {
+            questions: QuestionsHTTPClient::new(client),
+        }
+    }
+
+    /// Asks the user whether to retry loading the profile.
+    pub async fn should_retry(&self, text: &str) -> anyhow::Result<bool> {
+        let generic = GenericQuestion {
+            id: None,
+            class: "load.retry".to_string(),
+            text: text.to_string(),
+            options: vec!["Yes".to_string(), "No".to_string()],
+            default_option: "No".to_string(),
+            data: Default::default(),
+        };
+        let question = Question {
+            generic,
+            with_password: None,
+        };
+        let question = self.questions.create_question(&question).await?;
+        let answer = self
+            .questions
+            .get_answer(question.generic.id.unwrap())
+            .await?;
+        Ok(answer.generic.answer == "Yes")
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-autoinstall/src/scripts.rs 
new/agama/agama-autoinstall/src/scripts.rs
--- old/agama/agama-autoinstall/src/scripts.rs  2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-autoinstall/src/scripts.rs  2025-07-25 11:45:56.000000000 
+0200
@@ -26,12 +26,16 @@
     process::Output,
 };
 
-use agama_lib::utils::Transfer;
+use agama_lib::{http::BaseHTTPClient, utils::Transfer};
+use anyhow::anyhow;
 use url::Url;
 
+use crate::UserQuestions;
+
 /// Downloads and runs user-defined scripts for inst.script.
 pub struct ScriptsRunner {
     pub path: PathBuf,
+    questions: UserQuestions,
     insecure: bool,
     idx: usize,
 }
@@ -39,11 +43,13 @@
 impl ScriptsRunner {
     /// Creates a new scripts runner.
     ///
-    /// * path: working directory for the runner.
-    /// * insecure: whether to check certificates when downloading scripts.
-    pub fn new<P: AsRef<Path>>(path: P, insecure: bool) -> Self {
+    /// * `http`: base client to connect to Agama.
+    /// * `path`: working directory for the runner.
+    /// * `insecure`: whether to check certificates when downloading scripts.
+    pub fn new<P: AsRef<Path>>(http: BaseHTTPClient, path: P, insecure: bool) 
-> Self {
         Self {
             path: path.as_ref().to_path_buf(),
+            questions: UserQuestions::new(http),
             insecure,
             idx: 0,
         }
@@ -55,13 +61,13 @@
     /// It saves the stdout, stderr and exit code to separate files.
     ///
     /// * url: script URL, supporting agama-specific schemes.
-    pub fn run(&mut self, url: &str) -> anyhow::Result<()> {
+    pub async fn run(&mut self, url: &str) -> anyhow::Result<()> {
         create_dir_all(&self.path)?;
 
         let file_name = self.file_name_for(&url)?;
 
         let path = self.path.join(&file_name);
-        self.save_script(url, &path)?;
+        self.save_script(url, &path).await?;
 
         let output = std::process::Command::new(&path).output()?;
         self.save_logs(&path, output)?;
@@ -89,9 +95,14 @@
             .unwrap_or(unnamed))
     }
 
-    fn save_script(&self, url: &str, path: &PathBuf) -> anyhow::Result<()> {
+    async fn save_script(&self, url: &str, path: &PathBuf) -> 
anyhow::Result<()> {
         let mut file = Self::create_file(&path, 0o700)?;
-        Transfer::get(url, &mut file, self.insecure)?;
+        while let Err(error) = Transfer::get(url, &mut file, self.insecure) {
+            if !self.should_retry(&url).await? {
+                println!("Could not load configuration from {url}");
+                return Err(anyhow!(error));
+            }
+        }
         Ok(())
     }
 
@@ -122,11 +133,22 @@
             .mode(perms)
             .open(path)
     }
+
+    async fn should_retry(&self, url: &str) -> anyhow::Result<bool> {
+        let msg = format!(
+            r#"
+                It was not possible to load the script from {url}. Do you want 
to try again?
+                "#
+        );
+        self.questions.should_retry(&msg).await
+    }
 }
 
 #[cfg(test)]
 mod tests {
     use super::ScriptsRunner;
+    use agama_lib::http::BaseHTTPClient;
+    use tokio::test;
 
     fn script_path(name: &str) -> String {
         let current = std::env::current_dir().unwrap();
@@ -135,14 +157,15 @@
 
     fn script_runner() -> ScriptsRunner {
         let dir = tempfile::tempdir().unwrap();
-        ScriptsRunner::new(dir.path(), false)
+        let http = BaseHTTPClient::new("http://localhost";).unwrap();
+        ScriptsRunner::new(http, dir.path(), false)
     }
 
     #[test]
-    fn test_run_script() {
+    async fn test_run_script() {
         let url = script_path("success.sh");
         let mut runner = script_runner();
-        runner.run(&url).unwrap();
+        runner.run(&url).await.unwrap();
 
         let contents = 
std::fs::read_to_string(runner.path().join("1-success.stdout")).unwrap();
         assert_eq!(&contents, "SUCCESS\n");
@@ -151,10 +174,10 @@
     }
 
     #[test]
-    fn test_run_script_failed() {
+    async fn test_run_script_failed() {
         let url = script_path("error.sh");
         let mut runner = script_runner();
-        runner.run(&url).unwrap();
+        runner.run(&url).await.unwrap();
 
         let contents = 
std::fs::read_to_string(runner.path().join("1-error.stderr")).unwrap();
         assert_eq!(&contents, "ERROR\n");
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-cli/src/cli_input.rs 
new/agama/agama-cli/src/cli_input.rs
--- old/agama/agama-cli/src/cli_input.rs        2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-cli/src/cli_input.rs        2025-07-25 11:45:56.000000000 
+0200
@@ -120,7 +120,7 @@
     // Does it belong here?
     // vs the downloading code in web ProfileQuery::retrieve_profile
     // put it in agama-lib?
-    pub fn read_to_string(self) -> anyhow::Result<String> {
+    pub fn read_to_string(self, insecure: bool) -> anyhow::Result<String> {
         match self {
             Self::Full(s) => Ok(s),
             Self::Stdin => Self::stdin_to_string().map_err(|e| e.into()),
@@ -131,7 +131,7 @@
             }
             Self::Url(url_string) => {
                 let mut bytebuf = Vec::new();
-                Transfer::get(&url_string, &mut bytebuf, false)
+                Transfer::get(&url_string, &mut bytebuf, insecure)
                     .context(format!("Retrieving data from URL {}", 
url_string))?;
                 let s = String::from_utf8(bytebuf)
                     .context(format!("Invalid UTF-8 data at URL {}", 
url_string))?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-cli/src/commands.rs 
new/agama/agama-cli/src/commands.rs
--- old/agama/agama-cli/src/commands.rs 2025-07-22 16:19:39.000000000 +0200
+++ new/agama/agama-cli/src/commands.rs 2025-07-25 11:45:56.000000000 +0200
@@ -104,9 +104,6 @@
         url: String,
         /// File name
         destination: PathBuf,
-        /// Disables SSL verification for HTTPS downloads
-        #[arg(short, long)]
-        insecure: bool,
     },
     /// Finish the installation.
     Finish {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-cli/src/config.rs 
new/agama/agama-cli/src/config.rs
--- old/agama/agama-cli/src/config.rs   2025-07-22 16:19:39.000000000 +0200
+++ new/agama/agama-cli/src/config.rs   2025-07-25 11:45:56.000000000 +0200
@@ -30,7 +30,7 @@
 use fluent_uri::Uri;
 use tempfile::Builder;
 
-use crate::{cli_input::CliInput, cli_output::CliOutput, show_progress};
+use crate::{cli_input::CliInput, cli_output::CliOutput, show_progress, 
GlobalOpts};
 
 const DEFAULT_EDITOR: &str = "/usr/bin/vi";
 
@@ -99,6 +99,7 @@
     http_client: BaseHTTPClient,
     monitor: MonitorClient,
     subcommand: ConfigCommands,
+    opts: GlobalOpts,
 ) -> anyhow::Result<()> {
     let store = SettingsStore::new(http_client.clone()).await?;
 
@@ -116,7 +117,7 @@
         }
         ConfigCommands::Load { url_or_path } => {
             let url_or_path = url_or_path.unwrap_or(CliInput::Stdin);
-            let contents = url_or_path.read_to_string()?;
+            let contents = url_or_path.read_to_string(opts.insecure)?;
             // FIXME: invalid profile still gets loaded
             validate(&http_client, CliInput::Full(contents.clone())).await?;
             let result = InstallSettings::from_json(&contents, 
&InstallationContext::from_env()?)?;
@@ -130,7 +131,7 @@
         ConfigCommands::Generate { url_or_path } => {
             let url_or_path = url_or_path.unwrap_or(CliInput::Stdin);
 
-            generate(&http_client, url_or_path).await
+            generate(&http_client, url_or_path, opts.insecure).await
         }
         ConfigCommands::Edit { editor } => {
             let model = store.load().await?;
@@ -197,13 +198,20 @@
     path.ends_with(".xml") || path.ends_with(".erb") || path.ends_with('/')
 }
 
-async fn generate(client: &BaseHTTPClient, url_or_path: CliInput) -> 
anyhow::Result<()> {
+async fn generate(
+    client: &BaseHTTPClient,
+    url_or_path: CliInput,
+    insecure: bool,
+) -> anyhow::Result<()> {
     let context = match &url_or_path {
         CliInput::Stdin | CliInput::Full(_) => 
InstallationContext::from_env()?,
         CliInput::Url(url_str) => InstallationContext::from_url_str(url_str)?,
         CliInput::Path(pathbuf) => 
InstallationContext::from_file(pathbuf.as_path())?,
     };
 
+    // the AutoYaST profile is always downloaded insecurely
+    // 
(https://github.com/yast/yast-installation/blob/960c66658ab317007d2e241aab7b224657970bf9/src/lib/transfer/file_from_url.rb#L188)
+    // we can ignore the insecure option value in that case
     let profile_json = if is_autoyast(&url_or_path) {
         // AutoYaST specific download and convert to JSON
         let config_string = match url_or_path {
@@ -221,7 +229,7 @@
         };
         config_string
     } else {
-        from_json_or_jsonnet(client, url_or_path).await?
+        from_json_or_jsonnet(client, url_or_path, insecure).await?
     };
 
     let validity = validate_client(client, 
CliInput::Full(profile_json.clone())).await?;
@@ -279,8 +287,9 @@
 async fn from_json_or_jsonnet(
     client: &BaseHTTPClient,
     url_or_path: CliInput,
+    insecure: bool,
 ) -> anyhow::Result<String> {
-    let any_profile = url_or_path.read_to_string()?;
+    let any_profile = url_or_path.read_to_string(insecure)?;
 
     match FileFormat::from_string(&any_profile) {
         FileFormat::Jsonnet => {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-cli/src/lib.rs 
new/agama/agama-cli/src/lib.rs
--- old/agama/agama-cli/src/lib.rs      2025-07-22 16:19:39.000000000 +0200
+++ new/agama/agama-cli/src/lib.rs      2025-07-25 11:45:56.000000000 +0200
@@ -60,7 +60,7 @@
 use url::Url;
 
 /// Agama's CLI global options
-#[derive(Args)]
+#[derive(Args, Clone)]
 pub struct GlobalOpts {
     #[clap(long, default_value = "http://localhost";)]
     /// URI pointing to Agama's remote host.
@@ -288,12 +288,12 @@
 }
 
 pub async fn run_command(cli: Cli) -> anyhow::Result<()> {
-    let api_url = api_url(cli.opts.host)?;
+    let api_url = api_url(cli.opts.clone().host)?;
 
     match cli.command {
         Commands::Config(subcommand) => {
             let (client, monitor) = build_clients(api_url, 
cli.opts.insecure).await?;
-            run_config_cmd(client, monitor, subcommand).await?
+            run_config_cmd(client, monitor, subcommand, cli.opts).await?
         }
         Commands::Probe => {
             let (client, monitor) = build_clients(api_url, 
cli.opts.insecure).await?;
@@ -322,11 +322,9 @@
             let client = build_http_client(api_url, cli.opts.insecure, 
true).await?;
             run_logs_cmd(client, subcommand).await?
         }
-        Commands::Download {
-            url,
-            destination,
-            insecure,
-        } => download_file(&url, &destination, insecure)?,
+        Commands::Download { url, destination } => {
+            download_file(&url, &destination, cli.opts.insecure)?
+        }
         Commands::Auth(subcommand) => {
             let client = build_http_client(api_url, cli.opts.insecure, 
false).await?;
             run_auth_cmd(client, subcommand).await?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-cli/src/questions.rs 
new/agama/agama-cli/src/questions.rs
--- old/agama/agama-cli/src/questions.rs        2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-cli/src/questions.rs        2025-07-25 11:45:56.000000000 
+0200
@@ -77,7 +77,7 @@
 }
 
 async fn list_questions(client: BaseHTTPClient) -> anyhow::Result<()> {
-    let client = HTTPClient::new(client)?;
+    let client = HTTPClient::new(client);
     let questions = client.list_questions().await?;
     // FIXME: if performance is bad, we can skip converting json from http to 
struct and then
     // serialize it, but it won't be pretty string
@@ -87,7 +87,7 @@
 }
 
 async fn ask_question(client: BaseHTTPClient) -> anyhow::Result<()> {
-    let client = HTTPClient::new(client)?;
+    let client = HTTPClient::new(client);
     let question = serde_json::from_reader(std::io::stdin())?;
 
     let created_question = client.create_question(&question).await?;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-lib/Cargo.toml 
new/agama/agama-lib/Cargo.toml
--- old/agama/agama-lib/Cargo.toml      2025-07-22 16:19:39.000000000 +0200
+++ new/agama/agama-lib/Cargo.toml      2025-07-25 11:45:56.000000000 +0200
@@ -44,6 +44,7 @@
 fluent-uri = { version = "0.3.2", features = ["serde"] }
 tokio-tungstenite = { version = "0.26.2", features = ["native-tls"] }
 tokio-native-tls = "0.3.1"
+percent-encoding = "2.3.1"
 
 [dev-dependencies]
 httpmock = "0.7.0"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-lib/src/network/client.rs 
new/agama/agama-lib/src/network/client.rs
--- old/agama/agama-lib/src/network/client.rs   2025-07-22 16:19:39.000000000 
+0200
+++ new/agama/agama-lib/src/network/client.rs   2025-07-25 11:45:56.000000000 
+0200
@@ -20,6 +20,7 @@
 
 use super::{settings::NetworkConnection, types::Device};
 use crate::http::{BaseHTTPClient, BaseHTTPClientError};
+use crate::utils::url::encode;
 
 #[derive(Debug, thiserror::Error)]
 pub enum NetworkClientError {
@@ -56,9 +57,10 @@
 
     /// Returns an array of network connections
     pub async fn connection(&self, id: &str) -> Result<NetworkConnection, 
NetworkClientError> {
+        let encoded_id = encode(id);
         let json = self
             .client
-            
.get::<NetworkConnection>(format!("/network/connections/{id}").as_str())
+            
.get::<NetworkConnection>(format!("/network/connections/{encoded_id}").as_str())
             .await?;
 
         Ok(json)
@@ -70,10 +72,11 @@
         connection: NetworkConnection,
     ) -> Result<(), NetworkClientError> {
         let id = connection.id.clone();
+        let encoded_id = encode(id.as_str());
         let response = self.connection(id.as_str()).await;
 
         if response.is_ok() {
-            let path = format!("/network/connections/{id}");
+            let path = format!("/network/connections/{encoded_id}");
             self.client.put_void(path.as_str(), &connection).await?
         } else {
             self.client
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-lib/src/questions/http_client.rs 
new/agama/agama-lib/src/questions/http_client.rs
--- old/agama/agama-lib/src/questions/http_client.rs    2025-07-22 
16:19:39.000000000 +0200
+++ new/agama/agama-lib/src/questions/http_client.rs    2025-07-25 
11:45:56.000000000 +0200
@@ -38,8 +38,8 @@
 }
 
 impl HTTPClient {
-    pub fn new(client: BaseHTTPClient) -> Result<Self, 
QuestionsHTTPClientError> {
-        Ok(Self { client })
+    pub fn new(client: BaseHTTPClient) -> Self {
+        Self { client }
     }
 
     pub async fn list_questions(&self) -> Result<Vec<model::Question>, 
QuestionsHTTPClientError> {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-lib/src/utils/url.rs 
new/agama/agama-lib/src/utils/url.rs
--- old/agama/agama-lib/src/utils/url.rs        1970-01-01 01:00:00.000000000 
+0100
+++ new/agama/agama-lib/src/utils/url.rs        2025-07-25 11:45:56.000000000 
+0200
@@ -0,0 +1,38 @@
+// Copyright (c) [2025] SUSE LLC
+//
+// All Rights Reserved.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 2 of the License, or (at your option)
+// any later version.
+//
+// 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.
+
+use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
+
+pub fn encode(value: &str) -> String {
+    utf8_percent_encode(value, NON_ALPHANUMERIC).to_string()
+}
+
+#[cfg(test)]
+mod tests {
+
+    use super::encode;
+
+    #[test]
+    fn test_encode_value() {
+        let id = "Wired #1";
+        let encoded_id = encode(id);
+        assert_eq!(encoded_id, "Wired%20%231");
+    }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/agama-lib/src/utils.rs 
new/agama/agama-lib/src/utils.rs
--- old/agama/agama-lib/src/utils.rs    2025-07-22 16:19:39.000000000 +0200
+++ new/agama/agama-lib/src/utils.rs    2025-07-25 11:45:56.000000000 +0200
@@ -22,6 +22,7 @@
 
 mod file_format;
 mod transfer;
+pub mod url;
 
 pub use file_format::*;
 pub use transfer::*;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/agama/package/agama.changes 
new/agama/package/agama.changes
--- old/agama/package/agama.changes     2025-07-22 16:19:39.000000000 +0200
+++ new/agama/package/agama.changes     2025-07-25 11:45:56.000000000 +0200
@@ -1,4 +1,22 @@
 -------------------------------------------------------------------
+Thu Jul 24 13:19:52 UTC 2025 - Imobach Gonzalez Sosa <[email protected]>
+
+- Introduce inst.auto_insecure and inst.script_insecure to disable
+  SSL checks for inst.auto and inst.script (bsc#1246836).
+
+-------------------------------------------------------------------
+Wed Jul 23 14:48:53 UTC 2025 - Ladislav Slezák <[email protected]>
+
+- Added "--insecure" option to "agama config load" and
+  "agama config generate" commands (related to bsc#1246836)
+
+-------------------------------------------------------------------
+Wed Jul 23 11:37:04 UTC 2025 - Knut Anderssen <[email protected]>
+
+- Fix CLI connection update when using an special character in
+  the connection ID (bsc#1246930, gh#agama-project/agama#2605).
+
+-------------------------------------------------------------------
 Tue Jul 22 07:53:34 UTC 2025 - Martin Vidner <[email protected]>
 
 - fix .changes errors reported by obs-service-source_validator
@@ -12,8 +30,8 @@
 -------------------------------------------------------------------
 Mon Jul 21 14:35:57 UTC 2025 - Imobach Gonzalez Sosa <[email protected]>
 
-- Add support for an inst.script that allows to run an arbitrary
-  script (bsc#1246702, gh#agama-project/agama#2589).
+- Add support for an inst.script option that allows to run an
+  arbitrary script (bsc#1246702, gh#agama-project/agama#2589).
 
 -------------------------------------------------------------------
 Mon Jul 21 14:17:25 UTC 2025 - Josef Reidinger <[email protected]>
@@ -45,7 +63,6 @@
   providing better error report when product selection have to be
   done before or in the same profile (bsc#1246601)
 
-
 -------------------------------------------------------------------
 Wed Jul 16 15:37:34 UTC 2025 - Imobach Gonzalez Sosa <[email protected]>
 

++++++ agama.obsinfo ++++++
--- /var/tmp/diff_new_pack.Pk75wl/_old  2025-07-31 17:45:48.451173919 +0200
+++ /var/tmp/diff_new_pack.Pk75wl/_new  2025-07-31 17:45:48.455174086 +0200
@@ -1,5 +1,5 @@
 name: agama
-version: 17+6.d4475d531
-mtime: 1753193979
-commit: d4475d5315694348044627fdeabd0853b401b5af
+version: 17+45.62ec01ba4
+mtime: 1753436756
+commit: 62ec01ba4fad2b975b69bfcab9641645b3c97804
 

++++++ vendor.tar.zst ++++++
/work/SRC/openSUSE:Factory/agama/vendor.tar.zst 
/work/SRC/openSUSE:Factory/.agama.new.1944/vendor.tar.zst differ: char 7, line 1

Reply via email to