Skip to content
Merged
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
39 changes: 37 additions & 2 deletions rust/agama-software/src/callbacks/commit_download.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use std::{ffi::OsStr, path::Path};

use agama_utils::{
actor::Handler,
api::question::QuestionSpec,
api::{question::QuestionSpec, Scope},
progress,
question::{self},
};
Expand Down Expand Up @@ -29,7 +31,6 @@ impl CommitDownload {

impl Callback for CommitDownload {
fn start_preload(&self) {
// TODO: report progress that we start preloading packages
tracing::info!("Start preload");
}

Expand Down Expand Up @@ -97,4 +98,38 @@ impl Callback for CommitDownload {

None
}

fn finish_preload(
&self,
_url: String,
local_path: String,
error: zypp_agama::callbacks::pkg_download::PreloadError,
error_details: String,
) {
let file = Path::new(&local_path);
let file_str = file
.file_name()
.and_then(OsStr::to_str)
.unwrap_or("package");

if error == zypp_agama::callbacks::pkg_download::PreloadError::NoError {
let msg = format!("Finished downloading {}", file_str);
// just ignore issues with reporting progress
let _ = self
.progress
.cast(progress::message::NextWithStep::new(Scope::Software, &msg));
} else {
let labels = [gettext("Ok")];
let actions = [("Ok", labels[0].as_str())];
let question =
QuestionSpec::new(&error_details, "software.package_error.preload_error")
.with_actions(&actions)
.with_data(&[
("package", file_str),
("error_code", error.to_string().as_str()),
]);
// answer can be only OK so ignore it
let _ = ask_software_question(&self.questions, question);
}
}
}
9 changes: 6 additions & 3 deletions rust/agama-software/src/callbacks/install.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use agama_utils::{
actor::Handler,
api::question::QuestionSpec,
api::{question::QuestionSpec, Scope},
progress,
question::{self},
};
Expand Down Expand Up @@ -30,7 +30,11 @@ impl Install {
impl install::Callback for Install {
fn package_start(&self, package_name: String) {
tracing::info!("Installing package {}", package_name);
// TODO: report progress
let msg = format!("Installing {}", package_name);
// just ignore issues with reporting progress
let _ = self
.progress
.cast(progress::message::NextWithStep::new(Scope::Software, &msg));
}

fn package_problem(
Expand Down Expand Up @@ -104,6 +108,5 @@ impl install::Callback for Install {

fn package_finish(&self, package_name: String) {
tracing::info!("Finished installing package {}", package_name);
// TODO: report progress
}
}
42 changes: 25 additions & 17 deletions rust/agama-software/src/zypp_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use crate::{
callbacks,
model::state::{self, SoftwareState},
state::ResolvableSelection,
Resolvable, ResolvableType,
ResolvableType,
};

const GPG_KEYS: &str = "/usr/lib/rpm/gnupg/keys/gpg-*";
Expand Down Expand Up @@ -179,18 +179,8 @@ impl ZyppServer {
self.system_info(product_spec, tx, zypp)?;
}
SoftwareAction::Install(tx, progress, question) => {
let mut download_callback =
callbacks::CommitDownload::new(progress.clone(), question.clone());
let mut install_callback =
callbacks::Install::new(progress.clone(), question.clone());
let mut security_callback = callbacks::Security::new(question);
tx.send(self.install(
zypp,
&mut download_callback,
&mut install_callback,
&mut security_callback,
))
.map_err(|_| ZyppDispatchError::ResponseChannelClosed)?;
tx.send(self.install(zypp, progress, question))
.map_err(|_| ZyppDispatchError::ResponseChannelClosed)?;
}
SoftwareAction::Finish(tx) => {
self.finish(zypp, tx)?;
Expand All @@ -206,14 +196,32 @@ impl ZyppServer {
fn install(
&self,
zypp: &zypp_agama::Zypp,
download_callback: &mut callbacks::CommitDownload,
install_callback: &mut callbacks::Install,
security_callback: &mut callbacks::Security,
progress: Handler<progress::Service>,
question: Handler<question::Service>,
) -> ZyppServerResult<bool> {
let mut download_callback =
callbacks::CommitDownload::new(progress.clone(), question.clone());
let mut install_callback = callbacks::Install::new(progress.clone(), question.clone());
let mut security_callback = callbacks::Security::new(question);

let packages_count = zypp.packages_count();
// use packages count *2 as we need to download package and also install it
let steps = (packages_count * 2) as usize;
let _ = progress.cast(progress::message::Start::new(
Scope::Software,
steps,
"Starting packages installation",
));

let target = "/mnt";
zypp.switch_target(target)?;
let result = zypp.commit(download_callback, install_callback, security_callback)?;
let result = zypp.commit(
&mut download_callback,
&mut install_callback,
&mut security_callback,
)?;
tracing::info!("libzypp commit ends with {}", result);
let _ = progress.cast(progress::message::Finish::new(Scope::Software));
Ok(result)
}

Expand Down
14 changes: 14 additions & 0 deletions rust/zypp-agama/src/callbacks/pkg_download.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ impl From<zypp_agama_sys::GPGCheckPackageResult> for GPGCheckResult {
}
}

#[derive(Debug, PartialEq, Eq)]
pub enum PreloadError {
NoError,
NotFound, // the requested Url was not found
Expand All @@ -97,6 +98,19 @@ impl From<zypp_agama_sys::DownloadResolvableFileError> for PreloadError {
}
}

impl Display for PreloadError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let str = match self {
PreloadError::NoError => "NoError",
PreloadError::NotFound => "NotFound",
PreloadError::IO => "IO",
PreloadError::AccessDenied => "AccessDenied",
PreloadError::Error => "Error",
};
write!(f, "{}", str)
}
}

/// Callbacks for the download phase of a zypp commit.
///
/// This trait provides hooks into the package download process, which consists of two main phases:
Expand Down
4 changes: 4 additions & 0 deletions rust/zypp-agama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,10 @@ impl Zypp {
}
}

pub fn packages_count(&self) -> u32 {
unsafe { zypp_agama_sys::packages_to_install(self.ptr) }
}

pub fn list_repositories(&self) -> ZyppResult<Vec<Repository>> {
let mut repos_v = vec![];

Expand Down
5 changes: 5 additions & 0 deletions rust/zypp-agama/zypp-agama-sys/c-layer/include/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ void resolvable_unselect(struct Zypp *zypp, const char *name,
/// Note: this also resets the user locks ("taboo" or "keep installed")
void resolvable_reset_all(struct Zypp *_zypp) noexcept;

/// @brief Amount of packages selected for installation
/// @param _zypp see \ref init_target
/// @return count of packages
unsigned packages_to_install(struct Zypp *_zypp) noexcept;

struct PatternNames {
/// names of patterns
const char *const *const names;
Expand Down
9 changes: 8 additions & 1 deletion rust/zypp-agama/zypp-agama-sys/c-layer/lib.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ void switch_target(struct Zypp *zypp, const char *root,
false /* rebuild rpmdb: no */);

// switch cache for repositories, otherwise we run out of space in tmpfs
// see https://github.com/yast/yast-pkg-bindings/blob/853496f527543e6d51730fd7e3126ad94b13c303/src/PkgFunctions.cc#L496
// see
// https://github.com/yast/yast-pkg-bindings/blob/853496f527543e6d51730fd7e3126ad94b13c303/src/PkgFunctions.cc#L496
zypp::RepoManagerOptions repo_options(root);
zypp::Pathname packages_prefix = repo_options.repoPackagesCachePath;

Expand Down Expand Up @@ -467,6 +468,12 @@ bool is_local_url(const char *url, struct Status *status) noexcept {
}
}

unsigned packages_to_install(struct Zypp *zypp) noexcept {
return zypp::ResPool::instance()
.byStatus(&zypp::ResStatus::isToBeInstalled)
.size();
}

static bool package_check(Zypp *zypp, const char *tag, bool selected,
Status *status) noexcept {
try {
Expand Down
2 changes: 2 additions & 0 deletions rust/zypp-agama/zypp-agama-sys/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,8 @@ unsafe extern "C" {
);
#[doc = " Reset status of all resolvables, unselects selected packages, patterns...\n Note: this also resets the user locks (\"taboo\" or \"keep installed\")"]
pub fn resolvable_reset_all(_zypp: *mut Zypp);
#[doc = " @brief Amount of packages selected for installation\n @param _zypp see \\ref init_target\n @return count of packages"]
pub fn packages_to_install(_zypp: *mut Zypp) -> ::std::os::raw::c_uint;
#[doc = " Get Pattern details.\n Unknown patterns are simply omitted from the result. Match by\n PatternInfo.name, not by index."]
pub fn get_patterns_info(
_zypp: *mut Zypp,
Expand Down
Loading