(ALT) Proper default repo's checks and creation
This commit is contained in:
@ -392,15 +392,19 @@ pub enum APTRepositoryHandle {
|
||||
CephSquidNoSubscription,
|
||||
/// Ceph Squid test repository.
|
||||
CephSquidTest,
|
||||
/// Debug info
|
||||
#[serde(rename = "debuginfo")]
|
||||
DebugInfo,
|
||||
/// Classic
|
||||
#[serde(rename = "classic")]
|
||||
Classic,
|
||||
/// GOST crypto
|
||||
#[serde(rename = "gostcrypto")]
|
||||
GostCrypto,
|
||||
|
||||
/// Classic (for host's architecture)
|
||||
#[serde(rename = "classic_arch_specific")]
|
||||
ClassicArchSpecific,
|
||||
/// Classic (for any architecture)
|
||||
#[serde(rename = "classic_noarch")]
|
||||
ClassicNoArch,
|
||||
/// GOST crypto (for host's architecture)
|
||||
#[serde(rename = "gostcrypto_arch_specific")]
|
||||
GostCryptoArchSpecific,
|
||||
/// GOST crypto (for any architecture)
|
||||
#[serde(rename = "gostcrypto_noarch")]
|
||||
GostCryptoNoArch
|
||||
}
|
||||
|
||||
serde_plain::derive_display_from_serialize!(APTRepositoryHandle);
|
||||
|
@ -2,10 +2,10 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{format_err, Error};
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
use crate::repositories::release::ALTBranchID;
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
use crate::repositories::release::DebianCodename;
|
||||
#[cfg(feature = "alt-linux")]
|
||||
use crate::repositories::release::{get_rpm_arch_name, ALTBranchID};
|
||||
use proxmox_apt_api_types::{
|
||||
APTRepository, APTRepositoryFile, APTRepositoryFileError, APTRepositoryFileType,
|
||||
APTRepositoryInfo, APTRepositoryPackageType,
|
||||
@ -301,11 +301,24 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
if !repo.types.contains(&APTRepositoryPackageType::Deb) {
|
||||
continue;
|
||||
}
|
||||
let mut add_info = |kind: &str, message| {
|
||||
infos.push(APTRepositoryInfo {
|
||||
path: path.clone(),
|
||||
index: n,
|
||||
property: Some("Suites".to_string()),
|
||||
kind: kind.to_string(),
|
||||
message,
|
||||
})
|
||||
};
|
||||
#[cfg(feature = "alt-linux")]
|
||||
if !repo.types.contains(&APTRepositoryPackageType::Rpm) {
|
||||
add_info(
|
||||
"warning",
|
||||
"Unsupported repo packages type. Alt only have RPMs!".to_string(),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
let is_security_repo = repo.uris.iter().any(|uri| {
|
||||
let uri = uri.trim_end_matches('/');
|
||||
@ -316,7 +329,7 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
"http://security.debian.org" | "https://security.debian.org",
|
||||
)
|
||||
});
|
||||
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
let require_suffix = match is_security_repo {
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
@ -325,16 +338,6 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
false => None,
|
||||
};
|
||||
|
||||
let mut add_info = |kind: &str, message| {
|
||||
infos.push(APTRepositoryInfo {
|
||||
path: path.clone(),
|
||||
index: n,
|
||||
property: Some("Suites".to_string()),
|
||||
kind: kind.to_string(),
|
||||
message,
|
||||
})
|
||||
};
|
||||
|
||||
let message_old = |suite| format!("old suite '{}' configured!", suite);
|
||||
let message_new =
|
||||
|suite| format!("suite '{}' should not be used in production!", suite);
|
||||
@ -344,16 +347,10 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
for suite in repo.suites.iter() {
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
let (base_suite, suffix) = suite_variant(suite);
|
||||
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
let (base_suite, arch) = suite_arch(suite);
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
if base_suite.to_lowercase().contains("sisyphus") {
|
||||
add_info("warning", message_new("Sisyphus"))
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
match base_suite {
|
||||
"oldoldstable" | "oldstable" => {
|
||||
@ -373,14 +370,13 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
Ok(codename) => codename,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
let codename: ALTBranchID = match base_suite.try_into() {
|
||||
let codename: ALTBranchID = match base_suite.to_lowercase()[..].try_into() {
|
||||
Ok(codename) => codename,
|
||||
Err(_) => continue,
|
||||
};
|
||||
|
||||
|
||||
if codename < current_codename {
|
||||
add_info("warning", message_old(base_suite));
|
||||
}
|
||||
@ -389,10 +385,20 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
if codename > current_codename {
|
||||
add_info("warning", message_new(base_suite));
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
if arch.is_empty() {
|
||||
add_info("warning", "repo suite should contain architecture".to_string())
|
||||
add_info(
|
||||
"warning",
|
||||
"repo suite should contain architecture!".to_string(),
|
||||
)
|
||||
} else if let Ok(proper_arch) = get_rpm_arch_name() {
|
||||
if !arch.contains(&proper_arch) && arch != "noarch" {
|
||||
add_info(
|
||||
"warning",
|
||||
"Incorrent architecture name in repo suite!".to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
@ -447,7 +453,6 @@ impl APTRepositoryFileImpl for APTRepositoryFile {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
/// Splits the suite into its base part and variant.
|
||||
/// Does not expect the base part to contain either `-` or `/`.
|
||||
@ -462,7 +467,7 @@ fn suite_variant(suite: &str) -> (&str, &str) {
|
||||
/// Splits the suite into its branch part and arch.
|
||||
/// Does not expect the base part to contain either `-` or `/`.
|
||||
fn suite_arch(mut suite: &str) -> (&str, &str) {
|
||||
if suite.starts_with("ports/") {
|
||||
if suite.starts_with("ports/") {
|
||||
// Alt's suites approach is unsystematic :(
|
||||
suite = suite.strip_prefix("ports/").unwrap();
|
||||
|
||||
@ -470,7 +475,7 @@ fn suite_arch(mut suite: &str) -> (&str, &str) {
|
||||
// Cut off needless part
|
||||
Some(index) => &suite[index + 1..],
|
||||
None => suite,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
match suite.rfind('/') {
|
||||
@ -480,10 +485,10 @@ fn suite_arch(mut suite: &str) -> (&str, &str) {
|
||||
// Cut off needless '/branch' part
|
||||
Some(index) => &branch_part[0..index],
|
||||
None => branch_part,
|
||||
};
|
||||
};
|
||||
let arch_part = &suite[n + 1..];
|
||||
return (branch_part, arch_part)
|
||||
},
|
||||
None => (suite, "")
|
||||
return (branch_part, arch_part);
|
||||
}
|
||||
None => (suite, ""),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -106,9 +106,10 @@ pub fn standard_repositories(
|
||||
];
|
||||
#[cfg(feature = "alt-linux")]
|
||||
let mut result = vec![
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::Classic),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::DebugInfo),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::GostCrypto),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::ClassicArchSpecific),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::ClassicNoArch),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::GostCryptoArchSpecific),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::GostCryptoNoArch),
|
||||
];
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
|
@ -1,7 +1,11 @@
|
||||
use std::fmt::Display;
|
||||
use std::io::{BufRead, BufReader};
|
||||
|
||||
use anyhow::{bail, format_err, Error};
|
||||
use anyhow::{anyhow, bail, format_err, Error};
|
||||
#[cfg(feature = "alt-linux")]
|
||||
use std::process::Command;
|
||||
#[cfg(feature = "alt-linux")]
|
||||
use std::sync::OnceLock;
|
||||
|
||||
/// The code names of Debian releases. Does not include `sid`.
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
@ -193,4 +197,28 @@ pub fn get_current_release_branch_id() -> Result<ALTBranchID, Error> {
|
||||
}
|
||||
|
||||
bail!("unable to parse ALT branch ID from '/etc/os-release'");
|
||||
}
|
||||
}
|
||||
|
||||
// This static value is computed only once.
|
||||
#[cfg(feature = "alt-linux")]
|
||||
static RPM_ARCH: OnceLock<Option<String>> = OnceLock::new();
|
||||
|
||||
/// Read the architecture name
|
||||
#[cfg(feature = "alt-linux")]
|
||||
pub fn get_rpm_arch_name() -> Result<String, Error> {
|
||||
RPM_ARCH
|
||||
.get_or_init(|| {
|
||||
let output = Command::new("rpm")
|
||||
.args(&["--eval", "%{_arch}"])
|
||||
.output()
|
||||
.ok()?;
|
||||
if output.status.success() {
|
||||
let arch = String::from_utf8(output.stdout).ok()?;
|
||||
Some(arch.trim().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.clone()
|
||||
.ok_or(anyhow!("Failed to execute rpm command"))
|
||||
}
|
||||
|
@ -157,11 +157,14 @@ impl APTRepositoryImpl for APTRepository {
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
{
|
||||
// ALT's suites looks like `Sisyphus/noarch` or `p11/branch/x86_64`
|
||||
let proper_suite = handle.proper_suite(suite);
|
||||
self.types.contains(&package_type)
|
||||
&& found_uri
|
||||
// ALT's suites looks like `Sisyphus/noarch`
|
||||
&& self.suites.iter().any(|self_suite| self_suite.to_lowercase().starts_with(suite))
|
||||
&& found_component
|
||||
&& self
|
||||
.suites
|
||||
.iter()
|
||||
.any(|self_suite| *self_suite == proper_suite)
|
||||
&& found_component
|
||||
}
|
||||
}
|
||||
|
||||
@ -172,13 +175,14 @@ impl APTRepositoryImpl for APTRepository {
|
||||
if host == "proxmox.com" || host.ends_with(".proxmox.com") {
|
||||
return Some("Proxmox".to_string());
|
||||
}
|
||||
|
||||
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
if host == "debian.org" || host.ends_with(".debian.org") {
|
||||
return Some("Debian".to_string());
|
||||
}
|
||||
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
// In ALT we mark everything with 'badge' for now
|
||||
if !host.is_empty() {
|
||||
return Some("ALT Linux Team".to_string());
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
#[cfg(feature = "alt-linux")]
|
||||
use crate::repositories::release::{get_rpm_arch_name, ALTBranchID};
|
||||
use proxmox_apt_api_types::{
|
||||
APTRepository, APTRepositoryFileType, APTRepositoryHandle, APTRepositoryPackageType,
|
||||
APTStandardRepository,
|
||||
};
|
||||
|
||||
pub trait APTStandardRepositoryImpl {
|
||||
fn from_handle(handle: APTRepositoryHandle) -> APTStandardRepository;
|
||||
}
|
||||
@ -25,6 +26,13 @@ pub trait APTRepositoryHandleImpl {
|
||||
fn name(self) -> String;
|
||||
/// Get the standard file path for the repository referenced by the handle.
|
||||
fn path(self, product: &str) -> String;
|
||||
|
||||
/// Get the arch-suffix for the repository referenced by the handle.
|
||||
#[cfg(feature = "alt-linux")]
|
||||
fn arch_suite_suffix(self) -> String;
|
||||
/// Get proper suite for given branch
|
||||
#[cfg(feature = "alt-linux")]
|
||||
fn proper_suite(self, branch: &str) -> String;
|
||||
/// Get package type, possible URIs and the component associated with the handle.
|
||||
///
|
||||
/// The first URI is the preferred one.
|
||||
@ -86,15 +94,21 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
"This repository contains the Ceph Squid packages before they are moved to the \
|
||||
main repository."
|
||||
}
|
||||
APTRepositoryHandle::Classic => {
|
||||
"The repository contains binary executables and libraries."
|
||||
|
||||
APTRepositoryHandle::ClassicArchSpecific => {
|
||||
"The repository contains binary executables and libraries, \
|
||||
specific for node's architecture."
|
||||
}
|
||||
APTRepositoryHandle::DebugInfo => {
|
||||
"The repository contains debugging information for binary \
|
||||
executables and libraries."
|
||||
}
|
||||
APTRepositoryHandle::GostCrypto => {
|
||||
APTRepositoryHandle::ClassicNoArch => {
|
||||
"The repository contains binary executables and libraries \
|
||||
that are architecture-independent."
|
||||
}
|
||||
APTRepositoryHandle::GostCryptoArchSpecific => {
|
||||
"The repository contains binary executables and libraries \
|
||||
with GOST cryptography, specific for node's architecture."
|
||||
}
|
||||
APTRepositoryHandle::GostCryptoNoArch => {
|
||||
"The repository contains architecture-independent executables and libraries \
|
||||
with GOST cryptography."
|
||||
}
|
||||
}
|
||||
@ -116,9 +130,10 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
APTRepositoryHandle::CephSquidNoSubscription => "Ceph Squid No-Subscription",
|
||||
APTRepositoryHandle::CephSquidTest => "Ceph Squid Test",
|
||||
|
||||
APTRepositoryHandle::Classic => "classic",
|
||||
APTRepositoryHandle::DebugInfo => "debuginfo",
|
||||
APTRepositoryHandle::GostCrypto => "gostcrypto",
|
||||
APTRepositoryHandle::ClassicArchSpecific => "Classic (architecture-dependent)",
|
||||
APTRepositoryHandle::ClassicNoArch => "Classic (architecture-independent)",
|
||||
APTRepositoryHandle::GostCryptoArchSpecific => "GostCrypto (architecture-dependent)",
|
||||
APTRepositoryHandle::GostCryptoNoArch => "GostCrypto (architecture-independent)",
|
||||
}
|
||||
.to_string()
|
||||
}
|
||||
@ -139,9 +154,10 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
| APTRepositoryHandle::CephSquidEnterprise
|
||||
| APTRepositoryHandle::CephSquidNoSubscription
|
||||
| APTRepositoryHandle::CephSquidTest => "/etc/apt/sources.list.d/ceph.list".to_string(),
|
||||
APTRepositoryHandle::Classic
|
||||
| APTRepositoryHandle::DebugInfo
|
||||
| APTRepositoryHandle::GostCrypto => "/etc/apt/sources.list".to_string(),
|
||||
APTRepositoryHandle::ClassicArchSpecific
|
||||
| APTRepositoryHandle::ClassicNoArch
|
||||
| APTRepositoryHandle::GostCryptoArchSpecific
|
||||
| APTRepositoryHandle::GostCryptoNoArch => "/etc/apt/sources.list".to_string(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -225,7 +241,7 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
vec!["http://download.proxmox.com/debian/ceph-squid".to_string()],
|
||||
"test".to_string(),
|
||||
),
|
||||
APTRepositoryHandle::Classic => (
|
||||
APTRepositoryHandle::ClassicArchSpecific | APTRepositoryHandle::ClassicNoArch => (
|
||||
APTRepositoryPackageType::Rpm,
|
||||
vec![
|
||||
"http://ftp.altlinux.org/pub/distributions/ALTLinux".to_string(),
|
||||
@ -234,16 +250,13 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
],
|
||||
"classic".to_string(),
|
||||
),
|
||||
APTRepositoryHandle::DebugInfo => (
|
||||
APTRepositoryPackageType::Rpm,
|
||||
vec!["http://ftp.altlinux.org/pub/distributions/ALTLinux".to_string()],
|
||||
"debuginfo".to_string(),
|
||||
),
|
||||
APTRepositoryHandle::GostCrypto => (
|
||||
APTRepositoryPackageType::Rpm,
|
||||
vec!["http://ftp.altlinux.org/pub/distributions/ALTLinux".to_string()],
|
||||
"gostcrypto".to_string(),
|
||||
),
|
||||
APTRepositoryHandle::GostCryptoArchSpecific | APTRepositoryHandle::GostCryptoNoArch => {
|
||||
(
|
||||
APTRepositoryPackageType::Rpm,
|
||||
vec!["http://ftp.altlinux.org/pub/distributions/ALTLinux".to_string()],
|
||||
"gostcrypto".to_string(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,7 +266,10 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
APTRepository {
|
||||
types: vec![package_type],
|
||||
uris: vec![uris.into_iter().next().unwrap()],
|
||||
#[cfg(not(feature = "alt-linux"))]
|
||||
suites: vec![suite.to_string()],
|
||||
#[cfg(feature = "alt-linux")]
|
||||
suites: vec![self.proper_suite(suite)],
|
||||
components: vec![component],
|
||||
options: vec![],
|
||||
comment: String::new(),
|
||||
@ -261,4 +277,29 @@ impl APTRepositoryHandleImpl for APTRepositoryHandle {
|
||||
enabled: true,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
fn arch_suite_suffix(self) -> String {
|
||||
match self {
|
||||
APTRepositoryHandle::ClassicArchSpecific
|
||||
| APTRepositoryHandle::GostCryptoArchSpecific => {
|
||||
get_rpm_arch_name().unwrap_or("noarch".to_string())
|
||||
}
|
||||
APTRepositoryHandle::ClassicNoArch | APTRepositoryHandle::GostCryptoNoArch => {
|
||||
"noarch".to_string()
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "alt-linux")]
|
||||
fn proper_suite(self, branch: &str) -> String {
|
||||
let branch_id: ALTBranchID = branch.try_into().unwrap_or(ALTBranchID::Sisyphus);
|
||||
match branch_id {
|
||||
ALTBranchID::Sisyphus => {
|
||||
format!("Sisyphus/{}", self.arch_suite_suffix())
|
||||
}
|
||||
_ => format!("{}/branch/{}", branch, self.arch_suite_suffix()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -770,7 +770,6 @@ fn test_standard_repositories() -> Result<(), Error> {
|
||||
|
||||
let mut expected = vec![
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::Classic),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::DebugInfo),
|
||||
APTStandardRepository::from_handle(APTRepositoryHandle::GostCrypto),
|
||||
];
|
||||
|
||||
|
Reference in New Issue
Block a user