Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Алексей Шабалин 2022-10-03 16:56:25 +03:00
commit 40eaa21b04
19 changed files with 447 additions and 307 deletions

View File

@ -20,6 +20,14 @@ define package_template
>Proxmox/Lib/$(1).pm
endef
define upload_template
cd build; \
dcmd --deb lib$(1)-rs-perl*.changes \
| grep -v '.changes$$' \
| tar -cf "$@.tar" -T-; \
cat "$@.tar" | ssh -X repoman@repo.proxmox.com upload --product $(2) --dist bullseye
endef
.PHONY: all
all:
ifeq ($(BUILD_TARGET), pve)
@ -41,7 +49,10 @@ pve pmg:
gen:
$(call package_template,PMG,pmg_rs)
$(call package_template,PVE,pve_rs)
perl ./scripts/genpackage.pl Common Proxmox::RS::CalendarEvent
perl ./scripts/genpackage.pl Common \
Proxmox::RS::APT::Repositories \
Proxmox::RS::CalendarEvent \
Proxmox::RS::Subscription
perl ./scripts/genpackage.pl PVE \
PVE::RS::APT::Repositories \
PVE::RS::OpenId \
@ -85,14 +96,17 @@ common-deb: build
cd ./build/common-pkg && dpkg-buildpackage -b -uc -us
touch $@
%-upload: %-deb
cd build; \
dcmd --deb lib$*-rs-perl*.changes \
| grep -v '.changes$$' \
| tar -cf "$@.tar" -T-; \
cat "$@.tar" | ssh -X repoman@repo.proxmox.com upload --product $* --dist bullseye
pve-upload: pve-deb
$(call upload_template,pve,pve)
pmg-upload: pmg-deb
$(call upload_template,pmg,pmg)
# need to put into variable to ensure comma isn't interpreted as param separator on call
common_target=pve,pmg
common-upload: common-deb
$(call upload_template,proxmox,$(common_target))
.PHONY: clean
clean:
cargo clean
rm -rf ./build ./PVE ./PMG ./pve-deb ./pmg-deb
rm -rf ./build ./PVE ./PMG ./pve-deb ./pmg-deb ./common-deb

View File

@ -35,7 +35,7 @@ BEGIN {
push @ISA, $base;
} else {
eval { require Proxmox::Lib::PVE and push @ISA, 'Proxmox::Lib::PVE'; };
eval { require Proxmox::Lib::PMG and push @ISA, 'Proxmox::Lib::PVE'; } if $@;
eval { require Proxmox::Lib::PMG and push @ISA, 'Proxmox::Lib::PMG'; } if $@;
die $@ if $@;
}
}

View File

@ -1,3 +1,27 @@
libproxmox-rs-perl (0.2.1) bullseye; urgency=medium
* update to proxmox-subscription 0.3 / proxmox-http 0.7
-- Proxmox Support Team <support@proxmox.com> Wed, 7 Sep 2022 11:53:10 +0200
libproxmox-rs-perl (0.2.0) bullseye; urgency=medium
* add Proxmox::RS::Subscription
-- Proxmox Support Team <support@proxmox.com> Thu, 21 Jul 2022 15:01:29 +0200
libproxmox-rs-perl (0.1.2) bullseye; urgency=medium
* add common apt module
-- Proxmox Support Team <support@proxmox.com> Fri, 08 Jul 2022 14:50:18 +0200
libproxmox-rs-perl (0.1.1) bullseye; urgency=medium
* rebuild to record break/replace for libpve-rs-perl (<< 0.6.0)
-- Proxmox Support Team <support@proxmox.com> Tue, 10 May 2022 07:12:11 +0200
libproxmox-rs-perl (0.1.0) bullseye; urgency=medium
* initial release

View File

@ -12,11 +12,17 @@ Rules-Requires-Root: no
Package: libproxmox-rs-perl
Architecture: any
# always bump both versioned Depends and Breaks, otherwise systems with both
# libpmg-rs-perl and libpve-rs-perl might load an outdated lib and break
Depends:
${misc:Depends},
${perl:Depends},
${shlibs:Depends},
libpve-rs-perl (>= 0.6.0) | libpmg-rs-perl (>= 0.5.0),
libpve-rs-perl (>= 0.7.2) | libpmg-rs-perl (>= 0.6.2),
Breaks:
libpve-rs-perl (<< 0.7.2),
libpmg-rs-perl (<< 0.6.2),
Replaces: libpve-rs-perl (<< 0.6.0)
Description: PVE/PMG common parts which have been ported to Rust - Perl packages
Contains the perl side of modules provided by the libraries of both libpve-rs-perl and
libpmg-rs-perl, loading whichever is available.

1
common/src/apt/mod.rs Normal file
View File

@ -0,0 +1 @@
pub mod repositories;

View File

@ -0,0 +1,170 @@
#[perlmod::package(name = "Proxmox::RS::APT::Repositories")]
pub mod export {
use std::convert::TryInto;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use proxmox_apt::repositories::{
APTRepositoryFile, APTRepositoryFileError, APTRepositoryHandle, APTRepositoryInfo,
APTStandardRepository,
};
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// Result for the repositories() function
pub struct RepositoriesResult {
/// Successfully parsed files.
pub files: Vec<APTRepositoryFile>,
/// Errors for files that could not be parsed or read.
pub errors: Vec<APTRepositoryFileError>,
/// Common digest for successfully parsed files.
pub digest: String,
/// Additional information/warnings about repositories.
pub infos: Vec<APTRepositoryInfo>,
/// Standard repositories and their configuration status.
pub standard_repos: Vec<APTStandardRepository>,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// For changing an existing repository.
pub struct ChangeProperties {
/// Whether the repository should be enabled or not.
pub enabled: Option<bool>,
}
/// Get information about configured repositories and standard repositories for `product`.
#[export]
pub fn repositories(product: &str) -> Result<RepositoriesResult, Error> {
let (files, errors, digest) = proxmox_apt::repositories::repositories()?;
let digest = hex::encode(&digest);
let suite = proxmox_apt::repositories::get_current_release_codename()?;
let infos = proxmox_apt::repositories::check_repositories(&files, suite);
let standard_repos =
proxmox_apt::repositories::standard_repositories(&files, product, suite);
Ok(RepositoriesResult {
files,
errors,
digest,
infos,
standard_repos,
})
}
/// Add the repository identified by the `handle` and `product`.
/// If the repository is already configured, it will be set to enabled.
///
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn add_repository(handle: &str, product: &str, digest: Option<&str>) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
let handle: APTRepositoryHandle = handle.try_into()?;
let suite = proxmox_apt::repositories::get_current_release_codename()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
// check if it's already configured first
for file in files.iter_mut() {
for repo in file.repositories.iter_mut() {
if repo.is_referenced_repository(handle, product, &suite.to_string()) {
if repo.enabled {
return Ok(());
}
repo.set_enabled(true);
file.write()?;
return Ok(());
}
}
}
let (repo, path) =
proxmox_apt::repositories::get_standard_repository(handle, product, suite);
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!(
"unable to parse existing file {} - {}",
error.path,
error.error,
);
}
if let Some(file) = files
.iter_mut()
.find(|file| file.path.as_ref() == Some(&path))
{
file.repositories.push(repo);
file.write()?;
} else {
let mut file = match APTRepositoryFile::new(&path)? {
Some(file) => file,
None => bail!("invalid path - {}", path),
};
file.repositories.push(repo);
file.write()?;
}
Ok(())
}
/// Change the properties of the specified repository.
///
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn change_repository(
path: &str,
index: usize,
options: ChangeProperties,
digest: Option<&str>,
) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!("unable to parse file {} - {}", error.path, error.error);
}
if let Some(file) = files
.iter_mut()
.find(|file| file.path.as_ref() == Some(&path.to_string()))
{
if let Some(repo) = file.repositories.get_mut(index) {
if let Some(enabled) = options.enabled {
repo.set_enabled(enabled);
}
file.write()?;
} else {
bail!("invalid index - {}", index);
}
} else {
bail!("invalid path - {}", path);
}
Ok(())
}
}

View File

@ -1 +1,3 @@
pub mod apt;
mod calendar_event;
mod subscription;

100
common/src/subscription.rs Normal file
View File

@ -0,0 +1,100 @@
#[perlmod::package(name = "Proxmox::RS::Subscription")]
mod export {
use anyhow::{bail, format_err, Error};
use proxmox_subscription::SubscriptionInfo;
use proxmox_sys::fs::CreateOptions;
use proxmox_http::ProxyConfig;
use proxmox_http::HttpOptions;
use proxmox_http::client::sync::Client;
#[export]
fn read_subscription(path: String) -> Result<Option<SubscriptionInfo>, Error> {
proxmox_subscription::files::read_subscription(
path.as_str(),
&[proxmox_subscription::files::DEFAULT_SIGNING_KEY],
)
}
#[export]
fn write_subscription(
path: String,
apt_path: String,
url: &str,
info: SubscriptionInfo,
) -> Result<(), Error> {
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0640);
let www_data = nix::unistd::Group::from_name("www-data")?
.ok_or(format_err!("no 'www-data' group found!"))?
.gid;
let opts = CreateOptions::new()
.perm(mode)
.owner(nix::unistd::ROOT)
.group(www_data);
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
let apt_opts = CreateOptions::new().perm(mode).owner(nix::unistd::ROOT);
proxmox_subscription::files::write_subscription(path, opts, &info).and_then(|_| {
proxmox_subscription::files::update_apt_auth(
apt_path,
apt_opts,
url,
info.key,
info.serverid,
)
})
}
#[export]
fn delete_subscription(path: String, apt_path: String, url: &str) -> Result<(), Error> {
let mode = nix::sys::stat::Mode::from_bits_truncate(0o0600);
let apt_opts = CreateOptions::new().perm(mode).owner(nix::unistd::ROOT);
proxmox_subscription::files::delete_subscription(path).and_then(|_| {
proxmox_subscription::files::update_apt_auth(apt_path, apt_opts, url, None, None)
})
}
#[export]
fn check_subscription(
key: String,
server_id: String,
product_url: String,
user_agent: String,
proxy: Option<String>,
) -> Result<SubscriptionInfo, Error> {
let proxy_config = match proxy {
Some(url) => Some(ProxyConfig::parse_proxy_url(&url)?),
None => None,
};
let options = HttpOptions { proxy_config, user_agent: Some(user_agent) , ..Default::default() };
let client = Client::new(options);
proxmox_subscription::check::check_subscription(key, server_id, product_url, client)
}
#[export]
fn check_server_id(mut info: SubscriptionInfo) -> SubscriptionInfo {
info.check_server_id();
info
}
#[export]
fn check_age(mut info: SubscriptionInfo, re_check: bool) -> SubscriptionInfo {
info.check_age(re_check);
info
}
#[export]
fn check_signature(mut info: SubscriptionInfo) -> Result<SubscriptionInfo, Error> {
if !info.is_signed() {
bail!("SubscriptionInfo is not signed!");
}
info.check_signature(&[proxmox_subscription::files::DEFAULT_SIGNING_KEY]);
Ok(info)
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "pmg-rs"
version = "0.5.0"
version = "0.6.2"
authors = [
"Proxmox Support Team <support@proxmox.com>",
"Wolfgang Bumiller <w.bumiller@proxmox.com>",
@ -21,8 +21,10 @@ crate-type = [ "cdylib" ]
[dependencies]
anyhow = "1.0"
hex = "0.4"
http = "0.2.7"
libc = "0.2"
nix = "0.19"
nix = "0.24"
openssl = "0.10.40"
serde = "1.0"
serde_bytes = "0.11.3"
serde_json = "1.0"
@ -31,6 +33,9 @@ url = "2"
perlmod = { version = "0.13", features = [ "exporter" ] }
proxmox-acme-rs = { version = "0.4", features = ["client"] }
proxmox-apt = "0.8.0"
proxmox-tfa = { version = "2", features = ["api"] }
proxmox-time = "1.1.2"
proxmox-apt = "0.9"
proxmox-http = { version = "0.7", features = ["client-sync", "client-trait"] }
proxmox-subscription = "0.3"
proxmox-sys = "0.4"
proxmox-tfa = { version = "2.1", features = ["api"] }
proxmox-time = "1.1.3"

View File

@ -1,3 +1,31 @@
libpmg-rs-perl (0.6.2) bullseye; urgency=medium
* update to proxmox-subscription 0.3 / proxmox-http 0.7
-- Proxmox Support Team <support@proxmox.com> Wed, 7 Sep 2022 11:54:26 +0200
libpmg-rs-perl (0.6.1) bullseye; urgency=medium
* add 'allow-subdomains' property to webauthn config
-- Proxmox Support Team <support@proxmox.com> Mon, 25 Jul 2022 13:45:39 +0200
libpmg-rs-perl (0.6.0) bullseye; urgency=medium
* add Proxmox::RS::Subscription support
* bump proxmox-http to 0.6.4 to fix an issue with proxy authorization
-- Proxmox Support Team <support@proxmox.com> Thu, 21 Jul 2022 14:57:21 +0200
libpmg-rs-perl (0.5.2) bullseye; urgency=medium
* add common apt module
* update nix to 0.24
-- Proxmox Support Team <support@proxmox.com> Fri, 08 Jul 2022 14:48:58 +0200
libpmg-rs-perl (0.5.1) bullseye; urgency=medium
* install missing PMG.pm file

View File

@ -10,15 +10,22 @@ Build-Depends:
libstd-rust-dev <!nocheck>,
librust-anyhow-1+default-dev,
librust-hex-0.4+default-dev,
librust-http-0.2+default-dev (>= 0.2.7-~~),
librust-libc-0.2+default-dev,
librust-nix-0.19+default-dev,
librust-nix-0.24+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.40-~~),
librust-perlmod-0.13+default-dev,
librust-perlmod-0.13+exporter-dev,
librust-proxmox-acme-rs-0.4+client-dev,
librust-proxmox-acme-rs-0.4+default-dev,
librust-proxmox-apt-0.8+default-dev,
librust-proxmox-tfa-2+api-dev,
librust-proxmox-tfa-2+default-dev,
librust-proxmox-apt-0.9+default-dev,
librust-proxmox-http-0.7+client-sync-dev,
librust-proxmox-http-0.7+client-trait-dev,
librust-proxmox-http-0.7+default-dev,
librust-proxmox-subscription-0.3+default-dev,
librust-proxmox-sys-0.4+default-dev,
librust-proxmox-tfa-2+api-dev (>= 2.1-~~),
librust-proxmox-tfa-2+default-dev (>= 2.1-~~),
librust-proxmox-time-1+default-dev (>= 1.1.3-~~),
librust-serde-1+default-dev,
librust-serde-bytes-0.11+default-dev (>= 0.11.3-~~),

View File

@ -1,61 +1,13 @@
#[perlmod::package(name = "PMG::RS::APT::Repositories")]
mod export {
use std::convert::TryInto;
use anyhow::Error;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use proxmox_apt::repositories::{
APTRepositoryFile, APTRepositoryFileError, APTRepositoryHandle, APTRepositoryInfo,
APTStandardRepository,
};
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// Result for the repositories() function
pub struct RepositoriesResult {
/// Successfully parsed files.
pub files: Vec<APTRepositoryFile>,
/// Errors for files that could not be parsed or read.
pub errors: Vec<APTRepositoryFileError>,
/// Common digest for successfully parsed files.
pub digest: String,
/// Additional information/warnings about repositories.
pub infos: Vec<APTRepositoryInfo>,
/// Standard repositories and their configuration status.
pub standard_repos: Vec<APTStandardRepository>,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// For changing an existing repository.
pub struct ChangeProperties {
/// Whether the repository should be enabled or not.
pub enabled: Option<bool>,
}
use crate::common::apt::repositories::export as common;
/// Get information about configured and standard repositories.
#[export]
pub fn repositories() -> Result<RepositoriesResult, Error> {
let (files, errors, digest) = proxmox_apt::repositories::repositories()?;
let digest = hex::encode(&digest);
let suite = proxmox_apt::repositories::get_current_release_codename()?;
let infos = proxmox_apt::repositories::check_repositories(&files, suite);
let standard_repos = proxmox_apt::repositories::standard_repositories(&files, "pmg", suite);
Ok(RepositoriesResult {
files,
errors,
digest,
infos,
standard_repos,
})
pub fn repositories() -> Result<common::RepositoriesResult, Error> {
common::repositories("pmg")
}
/// Add the repository identified by the `handle`.
@ -64,60 +16,7 @@ mod export {
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn add_repository(handle: &str, digest: Option<&str>) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
let handle: APTRepositoryHandle = handle.try_into()?;
let suite = proxmox_apt::repositories::get_current_release_codename()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
// check if it's already configured first
for file in files.iter_mut() {
for repo in file.repositories.iter_mut() {
if repo.is_referenced_repository(handle, "pmg", &suite.to_string()) {
if repo.enabled {
return Ok(());
}
repo.set_enabled(true);
file.write()?;
return Ok(());
}
}
}
let (repo, path) = proxmox_apt::repositories::get_standard_repository(handle, "pmg", suite);
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!(
"unable to parse existing file {} - {}",
error.path,
error.error,
);
}
if let Some(file) = files.iter_mut().find(|file| file.path == path) {
file.repositories.push(repo);
file.write()?;
} else {
let mut file = match APTRepositoryFile::new(&path)? {
Some(file) => file,
None => bail!("invalid path - {}", path),
};
file.repositories.push(repo);
file.write()?;
}
Ok(())
common::add_repository(handle, "pmg", digest)
}
/// Change the properties of the specified repository.
@ -127,36 +26,9 @@ mod export {
pub fn change_repository(
path: &str,
index: usize,
options: ChangeProperties,
options: common::ChangeProperties,
digest: Option<&str>,
) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!("unable to parse file {} - {}", error.path, error.error);
}
if let Some(file) = files.iter_mut().find(|file| file.path == path) {
if let Some(repo) = file.repositories.get_mut(index) {
if let Some(enabled) = options.enabled {
repo.set_enabled(enabled);
}
file.write()?;
} else {
bail!("invalid index - {}", index);
}
} else {
bail!("invalid path - {}", path);
}
Ok(())
common::change_repository(path, index, options, digest)
}
}

View File

@ -382,7 +382,7 @@ pub(crate) fn mkdir<P: AsRef<Path>>(path: P, mode: libc::mode_t) -> Result<(), E
let path = path.as_ref();
match nix::unistd::mkdir(path, unsafe { Mode::from_bits_unchecked(mode) }) {
Ok(()) => Ok(()),
Err(nix::Error::Sys(Errno::EEXIST)) => Ok(()),
Err(Errno::EEXIST) => Ok(()),
Err(err) => bail!("failed to create directory {:?}: {}", path, err),
}
}

View File

@ -1,6 +1,6 @@
[package]
name = "pve-rs"
version = "0.6.1"
version = "0.7.2"
authors = ["Proxmox Support Team <support@proxmox.com>"]
edition = "2018"
license = "AGPL-3"
@ -19,8 +19,10 @@ anyhow = "1.0"
base32 = "0.4"
base64 = "0.13"
hex = "0.4"
http = "0.2.7"
libc = "0.2"
nix = "0.19"
nix = "0.24"
openssl = "0.10.40"
serde = "1.0"
serde_bytes = "0.11"
serde_json = "1.0"
@ -28,7 +30,10 @@ url = "2"
perlmod = { version = "0.13", features = [ "exporter" ] }
proxmox-apt = "0.8"
proxmox-apt = "0.9"
proxmox-http = { version = "0.7", features = ["client-sync", "client-trait"] }
proxmox-openid = "0.9.5"
proxmox-tfa = { version = "2", features = ["api"] }
proxmox-time = "1.1.2"
proxmox-subscription = "0.3"
proxmox-sys = "0.4"
proxmox-tfa = { version = "2.1", features = ["api"] }
proxmox-time = "1.1.3"

View File

@ -1,3 +1,33 @@
libpve-rs-perl (0.7.2) bullseye; urgency=medium
* update to proxmox-subscription 0.3 / proxmox-http 0.7
-- Proxmox Support Team <support@proxmox.com> Wed, 7 Sep 2022 11:56:38 +0200
libpve-rs-perl (0.7.1) bullseye; urgency=medium
* add 'allow-subdomains' property to webauthn config
-- Proxmox Support Team <support@proxmox.com> Mon, 25 Jul 2022 13:45:11 +0200
libpve-rs-perl (0.7.0) bullseye; urgency=medium
* add Proxmox::RS::Subscription support
* bump proxmox-http to 0.6.4 to fix an issue with proxy authorization
* adapt to changes in proxmox-apt
-- Proxmox Support Team <support@proxmox.com> Thu, 21 Jul 2022 14:56:12 +0200
libpve-rs-perl (0.6.2) bullseye; urgency=medium
* add common apt module
* update nix to 0.24
-- Proxmox Support Team <support@proxmox.com> Fri, 08 Jul 2022 14:48:21 +0200
libpve-rs-perl (0.6.1) bullseye; urgency=medium
* update OpenID connect proxmox integration dependency to fix Azure AD

View File

@ -11,14 +11,21 @@ Build-Depends:
librust-base32-0.4+default-dev,
librust-base64-0.13+default-dev,
librust-hex-0.4+default-dev,
librust-http-0.2+default-dev (>= 0.2.7-~~),
librust-libc-0.2+default-dev,
librust-nix-0.19+default-dev,
librust-nix-0.24+default-dev,
librust-openssl-0.10+default-dev (>= 0.10.40-~~),
librust-perlmod-0.13+default-dev,
librust-perlmod-0.13+exporter-dev,
librust-proxmox-apt-0.8+default-dev,
librust-proxmox-apt-0.9+default-dev,
librust-proxmox-http-0.7+client-sync-dev,
librust-proxmox-http-0.7+client-trait-dev,
librust-proxmox-http-0.7+default-dev,
librust-proxmox-openid-0.9+default-dev (>= 0.9.5-~~),
librust-proxmox-tfa-2+api-dev,
librust-proxmox-tfa-2+default-dev,
librust-proxmox-subscription-0.3+default-dev,
librust-proxmox-sys-0.4+default-dev,
librust-proxmox-tfa-2+api-dev (>= 2.1-~~),
librust-proxmox-tfa-2+default-dev (>= 2.1-~~),
librust-proxmox-time-1+default-dev (>= 1.1.3-~~),
librust-serde-1+default-dev,
librust-serde-bytes-0.11+default-dev,

View File

@ -1,61 +1,13 @@
#[perlmod::package(name = "PVE::RS::APT::Repositories", lib = "pve_rs")]
mod export {
use std::convert::TryInto;
use anyhow::Error;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
use proxmox_apt::repositories::{
APTRepositoryFile, APTRepositoryFileError, APTRepositoryHandle, APTRepositoryInfo,
APTStandardRepository,
};
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// Result for the repositories() function
pub struct RepositoriesResult {
/// Successfully parsed files.
pub files: Vec<APTRepositoryFile>,
/// Errors for files that could not be parsed or read.
pub errors: Vec<APTRepositoryFileError>,
/// Common digest for successfully parsed files.
pub digest: String,
/// Additional information/warnings about repositories.
pub infos: Vec<APTRepositoryInfo>,
/// Standard repositories and their configuration status.
pub standard_repos: Vec<APTStandardRepository>,
}
#[derive(Deserialize, Serialize)]
#[serde(rename_all = "kebab-case")]
/// For changing an existing repository.
pub struct ChangeProperties {
/// Whether the repository should be enabled or not.
pub enabled: Option<bool>,
}
use crate::common::apt::repositories::export as common;
/// Get information about configured and standard repositories.
#[export]
pub fn repositories() -> Result<RepositoriesResult, Error> {
let (files, errors, digest) = proxmox_apt::repositories::repositories()?;
let digest = hex::encode(&digest);
let suite = proxmox_apt::repositories::get_current_release_codename()?;
let infos = proxmox_apt::repositories::check_repositories(&files, suite);
let standard_repos = proxmox_apt::repositories::standard_repositories(&files, "pve", suite);
Ok(RepositoriesResult {
files,
errors,
digest,
infos,
standard_repos,
})
pub fn repositories() -> Result<common::RepositoriesResult, Error> {
common::repositories("pve")
}
/// Add the repository identified by the `handle`.
@ -64,60 +16,7 @@ mod export {
/// The `digest` parameter asserts that the configuration has not been modified.
#[export]
pub fn add_repository(handle: &str, digest: Option<&str>) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
let handle: APTRepositoryHandle = handle.try_into()?;
let suite = proxmox_apt::repositories::get_current_release_codename()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
// check if it's already configured first
for file in files.iter_mut() {
for repo in file.repositories.iter_mut() {
if repo.is_referenced_repository(handle, "pve", &suite.to_string()) {
if repo.enabled {
return Ok(());
}
repo.set_enabled(true);
file.write()?;
return Ok(());
}
}
}
let (repo, path) = proxmox_apt::repositories::get_standard_repository(handle, "pve", suite);
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!(
"unable to parse existing file {} - {}",
error.path,
error.error,
);
}
if let Some(file) = files.iter_mut().find(|file| file.path == path) {
file.repositories.push(repo);
file.write()?;
} else {
let mut file = match APTRepositoryFile::new(&path)? {
Some(file) => file,
None => bail!("invalid path - {}", path),
};
file.repositories.push(repo);
file.write()?;
}
Ok(())
common::add_repository(handle, "pve", digest)
}
/// Change the properties of the specified repository.
@ -127,36 +26,9 @@ mod export {
pub fn change_repository(
path: &str,
index: usize,
options: ChangeProperties,
options: common::ChangeProperties,
digest: Option<&str>,
) -> Result<(), Error> {
let (mut files, errors, current_digest) = proxmox_apt::repositories::repositories()?;
if let Some(digest) = digest {
let expected_digest = hex::decode(digest)?;
if expected_digest != current_digest {
bail!("detected modified configuration - file changed by other user? Try again.");
}
}
if let Some(error) = errors.iter().find(|error| error.path == path) {
bail!("unable to parse file {} - {}", error.path, error.error);
}
if let Some(file) = files.iter_mut().find(|file| file.path == path) {
if let Some(repo) = file.repositories.get_mut(index) {
if let Some(enabled) = options.enabled {
repo.set_enabled(enabled);
}
file.write()?;
} else {
bail!("invalid index - {}", index);
}
} else {
bail!("invalid path - {}", path);
}
Ok(())
common::change_repository(path, index, options, digest)
}
}

View File

@ -1,13 +1,13 @@
#[perlmod::package(name = "PVE::RS::OpenId", lib = "pve_rs")]
mod export {
use std::sync::Mutex;
use std::convert::TryFrom;
use std::sync::Mutex;
use anyhow::Error;
use perlmod::{to_value, Value};
use proxmox_openid::{OpenIdConfig, OpenIdAuthenticator, PrivateAuthState};
use proxmox_openid::{OpenIdAuthenticator, OpenIdConfig, PrivateAuthState};
const CLASSNAME: &str = "PVE::RS::OpenId";
@ -44,7 +44,6 @@ mod export {
config: OpenIdConfig,
redirect_url: &str,
) -> Result<Value, Error> {
let open_id = OpenIdAuthenticator::discover(&config, redirect_url)?;
bless(
class,
@ -60,7 +59,6 @@ mod export {
state_dir: &str,
realm: &str,
) -> Result<String, Error> {
let open_id = this.inner.lock().unwrap();
open_id.authorize_url(state_dir, realm)
}
@ -69,17 +67,16 @@ mod export {
pub fn verify_public_auth_state(
state_dir: &str,
state: &str,
) -> Result<(String, PrivateAuthState), Error> {
) -> Result<(String, PrivateAuthState), Error> {
OpenIdAuthenticator::verify_public_auth_state(state_dir, state)
}
#[export(raw_return)]
pub fn verify_authorization_code(
#[try_from_ref] this: &OpenId,
#[try_from_ref] this: &OpenId,
code: &str,
private_auth_state: PrivateAuthState,
) -> Result<Value, Error> {
let open_id = this.inner.lock().unwrap();
let claims = open_id.verify_authorization_code_simple(code, &private_auth_state)?;

View File

@ -783,7 +783,7 @@ pub(crate) fn mkdir<P: AsRef<Path>>(path: P, mode: libc::mode_t) -> Result<(), E
let path = path.as_ref();
match nix::unistd::mkdir(path, unsafe { Mode::from_bits_unchecked(mode) }) {
Ok(()) => Ok(()),
Err(nix::Error::Sys(Errno::EEXIST)) => Ok(()),
Err(Errno::EEXIST) => Ok(()),
Err(err) => bail!("failed to create directory {:?}: {}", path, err),
}
}