standard repos: add suite parameter for stricter detection

Require that the suite matches too when detecting standard
repositories, since no or invalid updates will be obtained when the
suite is wrong. Thus, it should not be considered to be the same
repository.

Add the parameter for get_standard_repository too, so that the two
related calls have more similar parameters, and the detection of the
current release code name can be done once in the caller once.

This also will fix an issue with the front-end, where adding a
standard repository would end up just enabling an already present
repository with the wrong suite.

Reported-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
Signed-off-by: Fabian Ebner <f.ebner@proxmox.com>
This commit is contained in:
Fabian Ebner 2021-07-29 14:25:48 +02:00 committed by Thomas Lamprecht
parent 68064f65bc
commit f48c12b00a
3 changed files with 36 additions and 18 deletions

View File

@ -12,7 +12,7 @@ mod file;
pub use file::{APTRepositoryFile, APTRepositoryFileError, APTRepositoryInfo};
mod release;
use release::get_current_release_codename;
pub use release::get_current_release_codename;
mod standard;
pub use standard::{APTRepositoryHandle, APTStandardRepository};
@ -60,24 +60,24 @@ pub fn check_repositories(files: &[APTRepositoryFile]) -> Result<Vec<APTReposito
Ok(infos)
}
/// Get the repository associated to the handle and the path where its usually configured.
/// Get the repository associated to the handle and the path where it is usually configured.
pub fn get_standard_repository(
handle: APTRepositoryHandle,
product: &str,
) -> Result<(APTRepository, String), Error> {
let suite = get_current_release_codename()?;
suite: &str,
) -> (APTRepository, String) {
let repo = handle.to_repository(product, &suite);
let path = handle.path(product);
Ok((repo, path))
(repo, path)
}
/// Return handles for standard Proxmox repositories and whether their status, where
/// None means not configured, and Some(bool) indicates enabled or disabled
/// Return handles for standard Proxmox repositories and their status, where
/// `None` means not configured, and `Some(bool)` indicates enabled or disabled.
pub fn standard_repositories(
product: &str,
files: &[APTRepositoryFile],
product: &str,
suite: &str,
) -> Vec<APTStandardRepository> {
let mut result = vec![
APTStandardRepository::from(APTRepositoryHandle::Enterprise),
@ -101,7 +101,7 @@ pub fn standard_repositories(
continue;
}
if repo.is_referenced_repository(entry.handle, product) {
if repo.is_referenced_repository(entry.handle, product, suite) {
entry.status = Some(repo.enabled);
}
}

View File

@ -270,7 +270,12 @@ impl APTRepository {
}
/// Checks if the repository is the one referenced by the handle.
pub fn is_referenced_repository(&self, handle: APTRepositoryHandle, product: &str) -> bool {
pub fn is_referenced_repository(
&self,
handle: APTRepositoryHandle,
product: &str,
suite: &str,
) -> bool {
let (package_type, handle_uris, component) = handle.info(product);
let mut found_uri = false;
@ -281,7 +286,11 @@ impl APTRepository {
found_uri = found_uri || handle_uris.iter().any(|handle_uri| handle_uri == uri);
}
self.types.contains(&package_type) && found_uri && self.components.contains(&component)
self.types.contains(&package_type)
&& found_uri
// using contains would require a &String
&& self.suites.iter().any(|self_suite| self_suite == suite)
&& self.components.contains(&component)
}
/// Check if a variant of the given suite is configured in this repository

View File

@ -5,8 +5,8 @@ use anyhow::{bail, format_err, Error};
use proxmox_apt::config::APTConfig;
use proxmox_apt::repositories::{
check_repositories, standard_repositories, APTRepositoryFile, APTRepositoryHandle,
APTRepositoryInfo, APTStandardRepository,
check_repositories, get_current_release_codename, standard_repositories, APTRepositoryFile,
APTRepositoryHandle, APTRepositoryInfo, APTStandardRepository,
};
#[test]
@ -337,7 +337,7 @@ fn test_standard_repositories() -> Result<(), Error> {
let mut file = APTRepositoryFile::new(&absolute_suite_list)?.unwrap();
file.parse()?;
let std_repos = standard_repositories("pve", &vec![file]);
let std_repos = standard_repositories(&vec![file], "pve", "bullseye");
assert_eq!(std_repos, expected);
@ -347,14 +347,14 @@ fn test_standard_repositories() -> Result<(), Error> {
let file_vec = vec![file];
let std_repos = standard_repositories("pbs", &file_vec);
let std_repos = standard_repositories(&file_vec, "pbs", "bullseye");
assert_eq!(&std_repos, &expected[0..=2]);
expected[0].status = Some(false);
expected[1].status = Some(true);
let std_repos = standard_repositories("pve", &file_vec);
let std_repos = standard_repositories(&file_vec, "pve", "bullseye");
assert_eq!(std_repos, expected);
@ -368,9 +368,18 @@ fn test_standard_repositories() -> Result<(), Error> {
expected[1].status = Some(true);
expected[2].status = Some(false);
let std_repos = standard_repositories("pve", &file_vec);
let std_repos = standard_repositories(&file_vec, "pve", "bullseye");
assert_eq!(std_repos, expected);
Ok(())
}
#[test]
fn test_get_current_release_codename() -> Result<(), Error> {
let codename = get_current_release_codename()?;
assert_eq!(&codename, "bullseye");
Ok(())
}