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

View File

@ -270,7 +270,12 @@ impl APTRepository {
} }
/// Checks if the repository is the one referenced by the handle. /// 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 (package_type, handle_uris, component) = handle.info(product);
let mut found_uri = false; let mut found_uri = false;
@ -281,7 +286,11 @@ impl APTRepository {
found_uri = found_uri || handle_uris.iter().any(|handle_uri| handle_uri == uri); 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 /// 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::config::APTConfig;
use proxmox_apt::repositories::{ use proxmox_apt::repositories::{
check_repositories, standard_repositories, APTRepositoryFile, APTRepositoryHandle, check_repositories, get_current_release_codename, standard_repositories, APTRepositoryFile,
APTRepositoryInfo, APTStandardRepository, APTRepositoryHandle, APTRepositoryInfo, APTStandardRepository,
}; };
#[test] #[test]
@ -337,7 +337,7 @@ fn test_standard_repositories() -> Result<(), Error> {
let mut file = APTRepositoryFile::new(&absolute_suite_list)?.unwrap(); let mut file = APTRepositoryFile::new(&absolute_suite_list)?.unwrap();
file.parse()?; file.parse()?;
let std_repos = standard_repositories("pve", &vec![file]); let std_repos = standard_repositories(&vec![file], "pve", "bullseye");
assert_eq!(std_repos, expected); assert_eq!(std_repos, expected);
@ -347,14 +347,14 @@ fn test_standard_repositories() -> Result<(), Error> {
let file_vec = vec![file]; 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]); assert_eq!(&std_repos, &expected[0..=2]);
expected[0].status = Some(false); expected[0].status = Some(false);
expected[1].status = Some(true); 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); assert_eq!(std_repos, expected);
@ -368,9 +368,18 @@ fn test_standard_repositories() -> Result<(), Error> {
expected[1].status = Some(true); expected[1].status = Some(true);
expected[2].status = Some(false); 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); assert_eq!(std_repos, expected);
Ok(()) Ok(())
} }
#[test]
fn test_get_current_release_codename() -> Result<(), Error> {
let codename = get_current_release_codename()?;
assert_eq!(&codename, "bullseye");
Ok(())
}