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
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<repoindex>
<repo url="http://foo.com/repo1" alias="a repository 1"/>
<repo url="http://foo.com/repo2" alias="a repository 2"/>
</repoindex>
23 changes: 23 additions & 0 deletions rust/zypp-agama/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,29 @@ impl Zypp {
}
}

pub fn add_service(&self, alias: &str, url: &str) -> ZyppResult<()> {
unsafe {
let mut status: Status = Status::default();
let status_ptr = &mut status as *mut _;
let c_alias = CString::new(alias).unwrap();
let c_url = CString::new(url).unwrap();
zypp_agama_sys::add_service(self.ptr, c_alias.as_ptr(), c_url.as_ptr(), status_ptr);

helpers::status_to_result_void(status)
}
}

pub fn refresh_service(&self, alias: &str) -> ZyppResult<()> {
unsafe {
let mut status: Status = Status::default();
let status_ptr = &mut status as *mut _;
let c_alias = CString::new(alias).unwrap();
zypp_agama_sys::refresh_service(self.ptr, c_alias.as_ptr(), status_ptr);

helpers::status_to_result_void(status)
}
}

pub fn create_repo_cache<F>(&self, alias: &str, progress: F) -> ZyppResult<()>
where
F: FnMut(i64, String) -> bool,
Expand Down
63 changes: 63 additions & 0 deletions rust/zypp-agama/tests/services.rs
Original file line number Diff line number Diff line change
@@ -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.

use std::{fs, io, path::Path};

fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
fs::create_dir_all(&dst)?;
for entry in fs::read_dir(src)? {
let entry = entry?;
let ty = entry.file_type()?;
if ty.is_dir() {
copy_dir_all(entry.path(), dst.as_ref().join(entry.file_name()))?;
} else {
fs::copy(entry.path(), dst.as_ref().join(entry.file_name()))?;
}
}
Ok(())
}

#[test]
fn test_services() {
let root_dir = env!("CARGO_MANIFEST_DIR").to_string() + "/fixtures/zypp_services_root";

let zypp_root = env!("CARGO_MANIFEST_DIR").to_string() + "/fixtures/zypp_root_tmp";
if fs::exists(&zypp_root).unwrap() {
fs::remove_dir_all(&zypp_root).unwrap();
}
fs::create_dir_all(&zypp_root).unwrap();

copy_dir_all(Path::new(&root_dir), Path::new(&zypp_root)).unwrap();

let zypp = zypp_agama::Zypp::init_target(&zypp_root, |_, _, _| {}).unwrap();

let service_url = "file:///service";
println!("{}", service_url);

zypp.add_service("test", service_url).unwrap();
zypp.refresh_service("test").unwrap();

let repos = zypp.list_repositories().unwrap();
assert!(
repos.len() == 2,
"Unexpected repos count. Repos: {:#?}",
repos
);
}
15 changes: 15 additions & 0 deletions rust/zypp-agama/zypp-agama-sys/c-layer/include/repository.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,14 @@ void remove_repository(struct Zypp *zypp, const char *alias,
struct Status *status, ZyppProgressCallback callback,
void *user_data) noexcept;

/// Adds service to repo manager
/// @param zypp see \ref init_target
/// @param alias have to be unique
/// @param url
/// @param[out] status (will overwrite existing contents)
void add_service(struct Zypp *zypp, const char *alias, const char *url,
struct Status *status) noexcept;

///
/// @param zypp see \ref init_target
/// @param alias alias of repository to refresh
Expand All @@ -77,6 +85,13 @@ void refresh_repository(struct Zypp *zypp, const char *alias,
struct DownloadProgressCallbacks *progress,
struct SecurityCallbacks *security) noexcept;

///
/// @param zypp see \ref init_target
/// @param alias alias of service to refresh
/// @param[out] status (will overwrite existing contents)
void refresh_service(struct Zypp *zypp, const char *alias,
struct Status *status) noexcept;

void build_repository_cache(struct Zypp *zypp, const char *alias,
struct Status *status,
ZyppProgressCallback callback,
Expand Down
41 changes: 40 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 @@ -424,6 +425,44 @@ bool run_solver(struct Zypp *zypp, struct Status *status) noexcept {
}
}

void add_service(struct Zypp *zypp, const char *alias, const char *url,
struct Status *status) noexcept {
if (zypp->repo_manager == NULL) {
STATUS_ERROR(status, "Internal Error: Repo manager is not initialized.");
return;
}
try {
zypp::ServiceInfo zypp_service = zypp::ServiceInfo(alias);
zypp_service.setUrl(zypp::Url(url));

zypp->repo_manager->addService(zypp_service);
STATUS_OK(status);
} catch (zypp::Exception &excpt) {
STATUS_EXCEPT(status, excpt);
}
}

void refresh_service(struct Zypp *zypp, const char *alias,
struct Status *status) noexcept {
if (zypp->repo_manager == NULL) {
STATUS_ERROR(status, "Internal Error: Repo manager is not initialized.");
return;
}
try {
zypp::ServiceInfo service = zypp->repo_manager->getService(alias);
if (service == zypp::ServiceInfo::noService) {
STATUS_ERROR(status,
"Cannot refresh service with alias %s. Service not found.",
alias);
return;
}
zypp->repo_manager->refreshService(service);
STATUS_OK(status);
} catch (zypp::Exception &excpt) {
STATUS_EXCEPT(status, excpt);
}
}

void refresh_repository(struct Zypp *zypp, const char *alias,
struct Status *status,
struct DownloadProgressCallbacks *callbacks,
Expand Down
13 changes: 13 additions & 0 deletions rust/zypp-agama/zypp-agama-sys/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -683,6 +683,13 @@ unsafe extern "C" {
callback: ZyppProgressCallback,
user_data: *mut ::std::os::raw::c_void,
);
#[doc = " Adds service to repo manager\n @param zypp see \\ref init_target\n @param alias have to be unique\n @param url\n @param[out] status (will overwrite existing contents)"]
pub fn add_service(
zypp: *mut Zypp,
alias: *const ::std::os::raw::c_char,
url: *const ::std::os::raw::c_char,
status: *mut Status,
);
#[doc = "\n @param zypp see \\ref init_target\n @param alias alias of repository to refresh\n @param[out] status (will overwrite existing contents)\n @param progress pointer to struct with callbacks or NULL if no progress is\n needed\n @param security pointer to struct with security callbacks"]
pub fn refresh_repository(
zypp: *mut Zypp,
Expand All @@ -691,6 +698,12 @@ unsafe extern "C" {
progress: *mut DownloadProgressCallbacks,
security: *mut SecurityCallbacks,
);
#[doc = "\n @param zypp see \\ref init_target\n @param alias alias of service to refresh\n @param[out] status (will overwrite existing contents)"]
pub fn refresh_service(
zypp: *mut Zypp,
alias: *const ::std::os::raw::c_char,
status: *mut Status,
);
pub fn build_repository_cache(
zypp: *mut Zypp,
alias: *const ::std::os::raw::c_char,
Expand Down
Loading