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
