From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 619941FF2D5 for ; Tue, 9 Jul 2024 08:18:19 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id D36051855B; Tue, 9 Jul 2024 08:18:39 +0200 (CEST) From: Wolfgang Bumiller To: pbs-devel@lists.proxmox.com Date: Tue, 9 Jul 2024 08:18:27 +0200 Message-Id: <20240709061832.52121-1-w.bumiller@proxmox.com> X-Mailer: git-send-email 2.39.2 MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.087 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] applied-series: [PATCH proxmox 1/6] apt-api-types: new crate X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" From: Dietmar Maurer Signed-off-by: Dietmar Maurer --- Cargo.toml | 2 + proxmox-apt-api-types/Cargo.toml | 15 + proxmox-apt-api-types/debian/changelog | 5 + proxmox-apt-api-types/debian/control | 42 ++ proxmox-apt-api-types/debian/copyright | 18 + proxmox-apt-api-types/debian/debcargo.toml | 7 + proxmox-apt-api-types/src/lib.rs | 442 +++++++++++++++++++++ 7 files changed, 531 insertions(+) create mode 100644 proxmox-apt-api-types/Cargo.toml create mode 100644 proxmox-apt-api-types/debian/changelog create mode 100644 proxmox-apt-api-types/debian/control create mode 100644 proxmox-apt-api-types/debian/copyright create mode 100644 proxmox-apt-api-types/debian/debcargo.toml create mode 100644 proxmox-apt-api-types/src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 48fa77b6..15556670 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ members = [ "proxmox-acme-api", "proxmox-api-macro", "proxmox-apt", + "proxmox-apt-api-types", "proxmox-async", "proxmox-auth-api", "proxmox-borrow", @@ -111,6 +112,7 @@ zstd = { version = "0.12", features = [ "bindgen" ] } # workspace dependencies proxmox-acme = { version = "0.5.2", path = "proxmox-acme", default-features = false } proxmox-api-macro = { version = "1.0.8", path = "proxmox-api-macro" } +proxmox-apt-api-types = { version = "1.0.0", path = "proxmox-apt-api-types" } proxmox-auth-api = { version = "0.4.0", path = "proxmox-auth-api" } proxmox-async = { version = "0.4.1", path = "proxmox-async" } proxmox-compression = { version = "0.2.0", path = "proxmox-compression" } diff --git a/proxmox-apt-api-types/Cargo.toml b/proxmox-apt-api-types/Cargo.toml new file mode 100644 index 00000000..e2ab46ad --- /dev/null +++ b/proxmox-apt-api-types/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "proxmox-apt-api-types" +version = "1.0.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +exclude.workspace = true +description = "APT API type definitions." + +[dependencies] +anyhow.workspace = true +serde = { workspace = true, features = ["derive"] } +proxmox-schema = { workspace = true, features = ["api-macro"] } +proxmox-config-digest.workspace = true diff --git a/proxmox-apt-api-types/debian/changelog b/proxmox-apt-api-types/debian/changelog new file mode 100644 index 00000000..32221867 --- /dev/null +++ b/proxmox-apt-api-types/debian/changelog @@ -0,0 +1,5 @@ +rust-proxmox-apt-api-types (1.0.0-1) bookworm; urgency=medium + + * initial release + + -- Proxmox Support Team Thu, 27 Jun 2024 13:14:23 +0200 diff --git a/proxmox-apt-api-types/debian/control b/proxmox-apt-api-types/debian/control new file mode 100644 index 00000000..708e8c4b --- /dev/null +++ b/proxmox-apt-api-types/debian/control @@ -0,0 +1,42 @@ +Source: rust-proxmox-apt-api-types +Section: rust +Priority: optional +Build-Depends: debhelper (>= 12), + dh-cargo (>= 25), + cargo:native , + rustc:native , + libstd-rust-dev , + librust-anyhow-1+default-dev , + librust-proxmox-config-digest-0.1+default-dev , + librust-proxmox-schema-3+api-macro-dev (>= 3.1.1-~~) , + librust-proxmox-schema-3+default-dev (>= 3.1.1-~~) , + librust-serde-1+default-dev , + librust-serde-1+derive-dev +Maintainer: Proxmox Support Team +Standards-Version: 4.6.2 +Vcs-Git: git://git.proxmox.com/git/proxmox-apt.git +Vcs-Browser: https://git.proxmox.com/?p=proxmox-apt.git +X-Cargo-Crate: proxmox-apt-api-types +Rules-Requires-Root: no + +Package: librust-proxmox-apt-api-types-dev +Architecture: any +Multi-Arch: same +Depends: + ${misc:Depends}, + librust-anyhow-1+default-dev, + librust-proxmox-config-digest-0.1+default-dev, + librust-proxmox-schema-3+api-macro-dev (>= 3.1.1-~~), + librust-proxmox-schema-3+default-dev (>= 3.1.1-~~), + librust-serde-1+default-dev, + librust-serde-1+derive-dev +Provides: + librust-proxmox-apt-api-types+default-dev (= ${binary:Version}), + librust-proxmox-apt-api-types-1-dev (= ${binary:Version}), + librust-proxmox-apt-api-types-1+default-dev (= ${binary:Version}), + librust-proxmox-apt-api-types-1.0-dev (= ${binary:Version}), + librust-proxmox-apt-api-types-1.0+default-dev (= ${binary:Version}), + librust-proxmox-apt-api-types-1.0.0-dev (= ${binary:Version}), + librust-proxmox-apt-api-types-1.0.0+default-dev (= ${binary:Version}) +Description: APT API type definitions - Rust source code + Source code for Debianized Rust crate "proxmox-apt-api-types" diff --git a/proxmox-apt-api-types/debian/copyright b/proxmox-apt-api-types/debian/copyright new file mode 100644 index 00000000..b227c290 --- /dev/null +++ b/proxmox-apt-api-types/debian/copyright @@ -0,0 +1,18 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ + +Files: + * +Copyright: 2019 - 2024 Proxmox Server Solutions GmbH +License: AGPL-3.0-or-later + This program is free software: you can redistribute it and/or modify it under + the terms of the GNU Affero General Public License as published by the Free + Software Foundation, either version 3 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 Affero General Public License for more + details. + . + You should have received a copy of the GNU Affero General Public License along + with this program. If not, see . diff --git a/proxmox-apt-api-types/debian/debcargo.toml b/proxmox-apt-api-types/debian/debcargo.toml new file mode 100644 index 00000000..74e38540 --- /dev/null +++ b/proxmox-apt-api-types/debian/debcargo.toml @@ -0,0 +1,7 @@ +overlay = "." +crate_src_path = ".." +maintainer = "Proxmox Support Team " + +[source] +vcs_git = "git://git.proxmox.com/git/proxmox-apt.git" +vcs_browser = "https://git.proxmox.com/?p=proxmox-apt.git" diff --git a/proxmox-apt-api-types/src/lib.rs b/proxmox-apt-api-types/src/lib.rs new file mode 100644 index 00000000..3b6ac9e4 --- /dev/null +++ b/proxmox-apt-api-types/src/lib.rs @@ -0,0 +1,442 @@ +use std::fmt::Display; + +use anyhow::{bail, Error}; +use serde::{Deserialize, Serialize}; + +use proxmox_config_digest::ConfigDigest; +use proxmox_schema::api; + +#[api] +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "lowercase")] +pub enum APTRepositoryFileType { + /// One-line-style format + List, + /// DEB822-style format + Sources, +} + +impl TryFrom<&str> for APTRepositoryFileType { + type Error = Error; + + fn try_from(file_type: &str) -> Result { + match file_type { + "list" => Ok(APTRepositoryFileType::List), + "sources" => Ok(APTRepositoryFileType::Sources), + _ => bail!("invalid file type '{file_type}'"), + } + } +} + +impl Display for APTRepositoryFileType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + APTRepositoryFileType::List => write!(f, "list"), + APTRepositoryFileType::Sources => write!(f, "sources"), + } + } +} + +#[api] +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +pub enum APTRepositoryPackageType { + /// Debian package + Deb, + /// Debian source package + DebSrc, +} + +impl TryFrom<&str> for APTRepositoryPackageType { + type Error = Error; + + fn try_from(package_type: &str) -> Result { + match package_type { + "deb" => Ok(APTRepositoryPackageType::Deb), + "deb-src" => Ok(APTRepositoryPackageType::DebSrc), + _ => bail!("invalid package type '{package_type}'"), + } + } +} + +impl Display for APTRepositoryPackageType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + APTRepositoryPackageType::Deb => write!(f, "deb"), + APTRepositoryPackageType::DebSrc => write!(f, "deb-src"), + } + } +} + +#[api( + properties: { + Key: { + description: "Option key.", + type: String, + }, + Values: { + description: "Option values.", + type: Array, + items: { + description: "Value.", + type: String, + }, + }, + }, +)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] // for consistency +/// Additional options for an APT repository. +/// Used for both single- and mutli-value options. +pub struct APTRepositoryOption { + /// Option key. + pub key: String, + /// Option value(s). + pub values: Vec, +} + +#[api( + properties: { + Types: { + description: "List of package types.", + type: Array, + items: { + type: APTRepositoryPackageType, + }, + }, + URIs: { + description: "List of repository URIs.", + type: Array, + items: { + description: "Repository URI.", + type: String, + }, + }, + Suites: { + description: "List of distributions.", + type: Array, + items: { + description: "Package distribution.", + type: String, + }, + }, + Components: { + description: "List of repository components.", + type: Array, + items: { + description: "Repository component.", + type: String, + }, + }, + Options: { + type: Array, + optional: true, + items: { + type: APTRepositoryOption, + }, + }, + Comment: { + description: "Associated comment.", + type: String, + optional: true, + }, + FileType: { + type: APTRepositoryFileType, + }, + Enabled: { + description: "Whether the repository is enabled or not.", + type: Boolean, + }, + }, +)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +/// Describes an APT repository. +pub struct APTRepository { + /// List of package types. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub types: Vec, + + /// List of repository URIs. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + #[serde(rename = "URIs")] + pub uris: Vec, + + /// List of package distributions. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub suites: Vec, + + /// List of repository components. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub components: Vec, + + /// Additional options. + #[serde(default, skip_serializing_if = "Vec::is_empty")] + pub options: Vec, + + /// Associated comment. + #[serde(default, skip_serializing_if = "String::is_empty")] + pub comment: String, + + /// Format of the defining file. + pub file_type: APTRepositoryFileType, + + /// Whether the repository is enabled or not. + pub enabled: bool, +} + +#[api( + properties: { + "file-type": { + type: APTRepositoryFileType, + }, + repositories: { + description: "List of APT repositories.", + type: Array, + items: { + type: APTRepository, + }, + }, + digest: { + type: ConfigDigest, + optional: true, + }, + }, +)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +/// Represents an abstract APT repository file. +pub struct APTRepositoryFile { + /// The path to the file. If None, `contents` must be set directly. + #[serde(skip_serializing_if = "Option::is_none")] + pub path: Option, + + /// The type of the file. + pub file_type: APTRepositoryFileType, + + /// List of repositories in the file. + pub repositories: Vec, + + /// The file content, if already parsed. + #[serde(skip_serializing_if = "Option::is_none")] + pub content: Option, + + /// Digest of the original contents. + #[serde(skip_serializing_if = "Option::is_none")] + pub digest: Option, +} + +#[api] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +/// Error type for problems with APT repository files. +pub struct APTRepositoryFileError { + /// The path to the problematic file. + pub path: String, + + /// The error message. + pub error: String, +} + +impl Display for APTRepositoryFileError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "proxmox-apt error for '{}' - {}", self.path, self.error) + } +} + +impl std::error::Error for APTRepositoryFileError { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + None + } +} + +#[api] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +/// Additional information for a repository. +pub struct APTRepositoryInfo { + /// Path to the defining file. + #[serde(default, skip_serializing_if = "String::is_empty")] + pub path: String, + + /// Index of the associated respository within the file (starting from 0). + pub index: usize, + + /// The property from which the info originates (e.g. "Suites") + #[serde(skip_serializing_if = "Option::is_none")] + pub property: Option, + + /// Info kind (e.g. "warning") + pub kind: String, + + /// Info message + pub message: String, +} + +#[api( + properties: { + handle: { + description: "Handle referencing a standard repository.", + type: String, + }, + }, +)] +#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +/// Reference to a standard repository and configuration status. +pub struct APTStandardRepository { + /// Handle referencing a standard repository. + pub handle: APTRepositoryHandle, + + /// Configuration status of the associated repository, where `None` means + /// not configured, and `Some(bool)` indicates enabled or disabled. + #[serde(skip_serializing_if = "Option::is_none")] + pub status: Option, + + /// Display name of the repository. + pub name: String, + + /// Description of the repository. + pub description: String, +} + +#[api] +#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)] +#[serde(rename_all = "kebab-case")] +/// Handles for Proxmox repositories. +pub enum APTRepositoryHandle { + /// The enterprise repository for production use. + Enterprise, + /// The repository that can be used without subscription. + NoSubscription, + /// The test repository. + Test, + /// Ceph Quincy enterprise repository. + CephQuincyEnterprise, + /// Ceph Quincy no-subscription repository. + CephQuincyNoSubscription, + /// Ceph Quincy test repository. + CephQuincyTest, + // TODO: Add separate enum for ceph releases and use something like + // `CephTest(CephReleaseCodename),` once the API macro supports it. + /// Ceph Reef enterprise repository. + CephReefEnterprise, + /// Ceph Reef no-subscription repository. + CephReefNoSubscription, + /// Ceph Reef test repository. + CephReefTest, +} + +#[api()] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "PascalCase")] +/// Describes a package for which an update is available. +pub struct APTUpdateInfo { + /// Package name + pub package: String, + /// Package title + pub title: String, + /// Package architecture + pub arch: String, + /// Human readable package description + pub description: String, + /// New version to be updated to + pub version: String, + /// Old version currently installed + pub old_version: String, + /// Package origin + pub origin: String, + /// Package priority in human-readable form + pub priority: String, + /// Package section + pub section: String, + /// Custom extra field for additional package information + #[serde(skip_serializing_if = "Option::is_none")] + pub extra_info: Option, +} + +#[api( + properties: { + notify: { + default: false, + optional: true, + }, + quiet: { + default: false, + optional: true, + }, + } +)] +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Options for APT update +pub struct APTUpdateOptions { + /// Send notification mail about new package updates available to the email + /// address configured for 'root@pam'). + pub notify: Option, + /// Only produces output suitable for logging, omitting progress indicators. + pub quiet: Option, +} + +#[api( + properties: { + files: { + type: Array, + items: { + type: APTRepositoryFile, + }, + }, + errors: { + type: Array, + items: { + type: APTRepositoryFileError, + }, + }, + infos: { + type: Array, + items: { + type: APTRepositoryInfo, + }, + }, + "standard-repos": { + type: Array, + items: { + type: APTStandardRepository, + }, + }, + digest: { + type: ConfigDigest, + }, + }, +)] +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(rename_all = "kebab-case")] +/// Result from parsing the APT repository files in /etc/apt/. +pub struct APTRepositoriesResult { + /// List of problematic files. + pub errors: Vec, + /// List of standard repositories and their configuration status. + pub standard_repos: Vec, + /// List of additional information/warnings about the repositories + pub infos: Vec, + /// List of parsed repository files. + pub files: Vec, + pub digest: ConfigDigest, +} + +#[api()] +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Options for the get changelog API. +pub struct APTGetChangelogOptions { + /// Package name to get changelog of. + pub name: String, + /// Package version to get changelog of. Omit to use candidate version. + pub version: Option, +} + +#[api()] +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Options for the change repository API call +pub struct APTChangeRepositoryOptions { + /// Whether the repository should be enabled or not. + pub enabled: Option, +} -- 2.39.2 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel