futures = "0.3"
h2 = { version = "0.3", features = [ "stream" ] }
handlebars = "3.0"
+hex = "0.4.3"
http = "0.2"
hyper = { version = "0.14", features = [ "full" ] }
lazy_static = "1.4"
pathpatterns = "0.1.2"
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
-proxmox = { version = "0.14.0", features = [ "sortable-macro", "api-macro", "cli", "router", "tfa" ] }
-proxmox-acme-rs = "0.2.1"
-proxmox-apt = "0.7.0"
+proxmox = { version = "0.14.0", features = [ "sortable-macro" ] }
proxmox-http = { version = "0.5.0", features = [ "client", "http-helpers", "websocket" ] }
-proxmox-openid = "0.7.0"
+proxmox-io = "1"
+proxmox-lang = "1"
+proxmox-router = { version = "1", features = [ "cli" ] }
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-section-config = "1"
+proxmox-tfa = { version = "1", features = [ "u2f" ] }
+proxmox-time = "1"
+proxmox-uuid = "1"
+
+proxmox-acme-rs = "0.2.1"
+proxmox-apt = "0.8.0"
+proxmox-openid = "0.8.0"
pbs-api-types = { path = "pbs-api-types" }
pbs-buildcfg = { path = "pbs-buildcfg" }
-use anyhow::{Error};
+use anyhow::Error;
// chacha20-poly1305
use anyhow::{Error};
-use proxmox::api::{*, cli::*};
+use proxmox_schema::*;
+use proxmox_router::cli::*;
#[api(
input: {
use std::io::Write;
-use anyhow::{Error};
+use anyhow::Error;
use pbs_api_types::Authid;
use pbs_client::{HttpClient, HttpClientOptions, BackupReader};
let client = HttpClient::new(host, 8007, auth_id, options)?;
- let backup_time = proxmox::tools::time::parse_rfc3339("2019-06-28T10:49:48Z")?;
+ let backup_time = proxmox_time::parse_rfc3339("2019-06-28T10:49:48Z")?;
let client = BackupReader::start(client, None, "store2", "host", "elsa", backup_time, true)
.await?;
-use anyhow::{bail, Error};
-
use std::thread;
use std::path::PathBuf;
use std::io::Write;
+use anyhow::{bail, Error};
+
// tar handle files that shrink during backup, by simply padding with zeros.
//
// this binary run multiple thread which writes some large files, then truncates
let client = HttpClient::new(host, 8007, auth_id, options)?;
- let backup_time = proxmox::tools::time::epoch_i64();
+ let backup_time = proxmox_time::epoch_i64();
let client = BackupWriter::start(client, None, datastore, "host", "speedtest", backup_time, false, true).await?;
regex = "1.2"
serde = { version = "1.0", features = ["derive"] }
+proxmox = "0.14.0"
+proxmox-lang = "1.0.0"
proxmox-schema = { version = "1.0.0", features = [ "api-macro" ] }
+proxmox-time = "1.0.0"
+proxmox-uuid = { version = "1.0.0", features = [ "serde" ] }
proxmox-rrd-api-types = { path = "../proxmox-rrd-api-types" }
proxmox-systemd = { path = "../proxmox-systemd" }
use std::str::FromStr;
-use serde::{Deserialize, Serialize};
use serde::de::{value, IntoDeserializer};
+use serde::{Deserialize, Serialize};
-use proxmox::api::api;
-use proxmox::api::schema::{
- ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
+use proxmox_lang::constnamedbitmap;
+use proxmox_schema::{
+ api, const_regex, ApiStringFormat, BooleanSchema, EnumEntry, Schema, StringSchema,
};
-use proxmox::{constnamedbitmap, const_regex};
const_regex! {
pub ACL_PATH_REGEX = concat!(r"^(?:/|", r"(?:/", PROXMOX_SAFE_ID_REGEX_STR!(), ")+", r")$");
TapeReader = ROLE_TAPE_READER,
}
-
impl FromStr for Role {
type Err = value::Error;
}
}
-pub const ACL_PATH_FORMAT: ApiStringFormat =
- ApiStringFormat::Pattern(&ACL_PATH_REGEX);
+pub const ACL_PATH_FORMAT: ApiStringFormat = ApiStringFormat::Pattern(&ACL_PATH_REGEX);
-pub const ACL_PATH_SCHEMA: Schema = StringSchema::new(
- "Access control path.")
+pub const ACL_PATH_SCHEMA: Schema = StringSchema::new("Access control path.")
.format(&ACL_PATH_FORMAT)
.min_length(1)
.max_length(128)
.schema();
-pub const ACL_PROPAGATE_SCHEMA: Schema = BooleanSchema::new(
- "Allow to propagate (inherit) permissions.")
- .default(true)
- .schema();
+pub const ACL_PROPAGATE_SCHEMA: Schema =
+ BooleanSchema::new("Allow to propagate (inherit) permissions.")
+ .default(true)
+ .schema();
-pub const ACL_UGID_TYPE_SCHEMA: Schema = StringSchema::new(
- "Type of 'ugid' property.")
+pub const ACL_UGID_TYPE_SCHEMA: Schema = StringSchema::new("Type of 'ugid' property.")
.format(&ApiStringFormat::Enum(&[
EnumEntry::new("user", "User"),
- EnumEntry::new("group", "Group")]))
+ EnumEntry::new("group", "Group"),
+ ]))
.schema();
#[api(
use anyhow::Error;
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
use pbs_tools::format::{as_fingerprint, bytes_as_fingerprint};
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
-use proxmox::api::schema::{
- ApiStringFormat, ApiType, ArraySchema, EnumEntry, IntegerSchema, ReturnType, Schema,
- StringSchema, Updater,
+use proxmox_schema::{
+ api, const_regex, ApiStringFormat, ApiType, ArraySchema, EnumEntry, IntegerSchema, ReturnType,
+ Schema, StringSchema, Updater,
};
-use proxmox::const_regex;
-
use crate::{
PROXMOX_SAFE_ID_FORMAT, SHA256_HEX_REGEX, SINGLE_LINE_COMMENT_SCHEMA, CryptMode, UPID,
Fingerprint, Userid, Authid,
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
#[api]
#[derive(Serialize, Deserialize)]
use serde::{Deserialize, Serialize};
-use proxmox::const_regex;
-
-use proxmox::api::{api, schema::*};
+use proxmox_schema::*;
use crate::{
Userid, Authid, REMOTE_ID_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
use crate::CERT_FINGERPRINT_SHA256_SCHEMA;
use serde::{Deserialize, Serialize};
use anyhow::bail;
-use proxmox::api::api;
-use proxmox::api::schema::{ApiStringFormat, ApiType, ArraySchema, Schema, StringSchema, ReturnType};
-use proxmox::const_regex;
+use proxmox_schema::{
+ api, const_regex, ApiStringFormat, ApiType, ArraySchema, Schema, StringSchema, ReturnType,
+};
use proxmox::{IPRE, IPRE_BRACKET, IPV4OCTET, IPV4RE, IPV6H16, IPV6LS32, IPV6RE};
#[rustfmt::skip]
mod user;
pub use user::*;
-pub use proxmox::api::upid::*;
+pub use proxmox_schema::upid::*;
mod crypto;
pub use crypto::{CryptMode, Fingerprint};
use serde::{Deserialize, Serialize};
-use proxmox::api::{api, schema::*};
+use proxmox_schema::*;
use crate::{
PROXMOX_SAFE_ID_REGEX,
use serde::{Deserialize, Serialize};
use super::*;
-use proxmox::api::{api, schema::*};
+use proxmox_schema::*;
pub const REMOTE_PASSWORD_SCHEMA: Schema = StringSchema::new("Password or auth token for remote host.")
.format(&PASSWORD_FORMAT)
use serde::{Deserialize, Serialize};
-use proxmox::api::{
- api,
- schema::{
- Schema,
- ApiStringFormat,
- ArraySchema,
- IntegerSchema,
- StringSchema,
- Updater,
- },
+use proxmox_schema::{
+ api, ApiStringFormat, ArraySchema, IntegerSchema, Schema, StringSchema, Updater,
};
-use crate::{
- PROXMOX_SAFE_ID_FORMAT,
- OptionalDeviceIdentification,
-};
+use crate::{OptionalDeviceIdentification, PROXMOX_SAFE_ID_FORMAT};
pub const CHANGER_NAME_SCHEMA: Schema = StringSchema::new("Tape Changer Identifier.")
.format(&PROXMOX_SAFE_ID_FORMAT)
.max_length(32)
.schema();
-pub const SCSI_CHANGER_PATH_SCHEMA: Schema = StringSchema::new(
- "Path to Linux generic SCSI device (e.g. '/dev/sg4')")
- .schema();
+pub const SCSI_CHANGER_PATH_SCHEMA: Schema =
+ StringSchema::new("Path to Linux generic SCSI device (e.g. '/dev/sg4')").schema();
pub const MEDIA_LABEL_SCHEMA: Schema = StringSchema::new("Media Label/Barcode.")
.format(&PROXMOX_SAFE_ID_FORMAT)
.schema();
pub const SLOT_ARRAY_SCHEMA: Schema = ArraySchema::new(
- "Slot list.", &IntegerSchema::new("Slot number")
- .minimum(1)
- .schema())
- .schema();
+ "Slot list.",
+ &IntegerSchema::new("Slot number").minimum(1).schema(),
+)
+.schema();
-pub const EXPORT_SLOT_LIST_SCHEMA: Schema = StringSchema::new("\
+pub const EXPORT_SLOT_LIST_SCHEMA: Schema = StringSchema::new(
+ "\
A list of slot numbers, comma separated. Those slots are reserved for
Import/Export, i.e. any media in those slots are considered to be
'offline'.
-")
+",
+)
.format(&ApiStringFormat::PropertyString(&SLOT_ARRAY_SCHEMA))
.schema();
},
},
)]
-#[derive(Serialize,Deserialize,Updater)]
+#[derive(Serialize, Deserialize, Updater)]
#[serde(rename_all = "kebab-case")]
/// SCSI tape changer
pub struct ScsiTapeChanger {
#[updater(skip)]
pub name: String,
pub path: String,
- #[serde(skip_serializing_if="Option::is_none")]
+ #[serde(skip_serializing_if = "Option::is_none")]
pub export_slots: Option<String>,
}
},
},
)]
-#[derive(Serialize,Deserialize)]
+#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Changer config with optional device identification attributes
pub struct ChangerListEntry {
}
#[api()]
-#[derive(Serialize,Deserialize)]
+#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Mtx Entry Kind
pub enum MtxEntryKind {
},
},
)]
-#[derive(Serialize,Deserialize)]
+#[derive(Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
/// Mtx Status Entry
pub struct MtxStatusEntry {
/// The ID of the slot or drive
pub entry_id: u64,
/// The media label (volume tag) if the slot/drive is full
- #[serde(skip_serializing_if="Option::is_none")]
+ #[serde(skip_serializing_if = "Option::is_none")]
pub label_text: Option<String>,
/// The slot the drive was loaded from
- #[serde(skip_serializing_if="Option::is_none")]
+ #[serde(skip_serializing_if = "Option::is_none")]
pub loaded_slot: Option<u64>,
/// The current state of the drive
- #[serde(skip_serializing_if="Option::is_none")]
+ #[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<String>,
}
use ::serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
#[api()]
#[derive(Serialize,Deserialize)]
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
-use proxmox::api::{
- api,
- schema::{Schema, IntegerSchema, StringSchema, Updater},
-};
+use proxmox_schema::{api, Schema, IntegerSchema, StringSchema, Updater};
use crate::{
PROXMOX_SAFE_ID_FORMAT,
use ::serde::{Deserialize, Serialize};
-use proxmox::{
- api::{api, schema::*},
- tools::Uuid,
-};
+use proxmox_schema::*;
+use proxmox_uuid::Uuid;
use crate::{
UUID_FORMAT,
use anyhow::{bail, Error};
-use proxmox::api::{
- schema::{
- Schema,
- StringSchema,
- ApiStringFormat,
- parse_simple_value,
- },
-};
+use proxmox_schema::{parse_simple_value, ApiStringFormat, Schema, StringSchema};
-use crate::{
- PROXMOX_SAFE_ID_FORMAT,
- CHANGER_NAME_SCHEMA,
-};
+use crate::{CHANGER_NAME_SCHEMA, PROXMOX_SAFE_ID_FORMAT};
pub const VAULT_NAME_SCHEMA: Schema = StringSchema::new("Vault name.")
.format(&PROXMOX_SAFE_ID_FORMAT)
proxmox::forward_deserialize_to_from_str!(MediaLocation);
proxmox::forward_serialize_to_display!(MediaLocation);
-impl proxmox::api::schema::ApiType for MediaLocation {
+impl proxmox_schema::ApiType for MediaLocation {
const API_SCHEMA: Schema = StringSchema::new(
- "Media location (e.g. 'offline', 'online-<changer_name>', 'vault-<vault_name>')")
- .format(&ApiStringFormat::VerifyFn(|text| {
- let location: MediaLocation = text.parse()?;
- match location {
- MediaLocation::Online(ref changer) => {
- parse_simple_value(changer, &CHANGER_NAME_SCHEMA)?;
- }
- MediaLocation::Vault(ref vault) => {
- parse_simple_value(vault, &VAULT_NAME_SCHEMA)?;
- }
- MediaLocation::Offline => { /* OK */}
+ "Media location (e.g. 'offline', 'online-<changer_name>', 'vault-<vault_name>')",
+ )
+ .format(&ApiStringFormat::VerifyFn(|text| {
+ let location: MediaLocation = text.parse()?;
+ match location {
+ MediaLocation::Online(ref changer) => {
+ parse_simple_value(changer, &CHANGER_NAME_SCHEMA)?;
}
- Ok(())
- }))
- .schema();
+ MediaLocation::Vault(ref vault) => {
+ parse_simple_value(vault, &VAULT_NAME_SCHEMA)?;
+ }
+ MediaLocation::Offline => { /* OK */ }
+ }
+ Ok(())
+ }))
+ .schema();
}
-
impl std::fmt::Display for MediaLocation {
-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
MediaLocation::Offline => {
use anyhow::Error;
use serde::{Deserialize, Serialize};
-use proxmox::api::{
- api,
- schema::{Schema, StringSchema, ApiStringFormat, Updater},
-};
+use proxmox_schema::{api, Schema, StringSchema, ApiStringFormat, Updater};
use proxmox_systemd::time::{parse_calendar_event, parse_time_span, CalendarEvent, TimeSpan};
-use ::serde::{Deserialize, Serialize};
+use serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
#[api()]
/// Media status
mod media;
pub use media::*;
-use ::serde::{Deserialize, Serialize};
+use serde::{Deserialize, Serialize};
-use proxmox::api::api;
-use proxmox::api::schema::{Schema, StringSchema, ApiStringFormat};
-use proxmox::tools::Uuid;
-
-use proxmox::const_regex;
+use proxmox_schema::{api, const_regex, Schema, StringSchema, ApiStringFormat};
+use proxmox_uuid::Uuid;
use crate::{
FINGERPRINT_SHA256_FORMAT, BACKUP_ID_SCHEMA, BACKUP_TYPE_SCHEMA,
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
-use proxmox::api::schema::{
- BooleanSchema, IntegerSchema, Schema, StringSchema, Updater,
+use proxmox_schema::{
+ api, BooleanSchema, IntegerSchema, Schema, StringSchema, Updater,
};
use super::{SINGLE_LINE_COMMENT_FORMAT, SINGLE_LINE_COMMENT_SCHEMA};
return false;
}
if let Some(expire) = self.expire {
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
if expire > 0 && expire <= now {
return false;
}
return false;
}
if let Some(expire) = self.expire {
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
if expire > 0 && expire <= now {
return false;
}
use lazy_static::lazy_static;
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
-use proxmox::api::schema::{ApiStringFormat, ApiType, Schema, StringSchema, UpdaterType};
-use proxmox::const_regex;
+use proxmox_schema::{
+ api, const_regex, ApiStringFormat, ApiType, Schema, StringSchema, UpdaterType,
+};
// we only allow a limited set of characters
// colon is not allowed, because we store usernames in
use serde::{Deserialize, Serialize};
-use proxmox::api::{api, schema::*};
-
-use proxmox::const_regex;
+use proxmox_schema::*;
const_regex! {
pub ZPOOL_NAME_REGEX = r"^[a-zA-Z][a-z0-9A-Z\-_.:]+$";
xdg = "2.2"
pathpatterns = "0.1.2"
-proxmox = { version = "0.14.0", default-features = false, features = [ "cli" ] }
+proxmox = "0.14.0"
proxmox-fuse = "0.1.1"
proxmox-http = { version = "0.5.0", features = [ "client", "http-helpers", "websocket" ] }
+proxmox-io = { version = "1", features = [ "tokio" ] }
+proxmox-lang = "1"
+proxmox-router = { version = "1", features = [ "cli" ] }
+proxmox-schema = "1"
+proxmox-time = "1"
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
pbs-api-types = { path = "../pbs-api-types" }
use anyhow::{bail, Error};
-use proxmox::api::schema::*;
+use proxmox_schema::*;
-proxmox::const_regex! {
+const_regex! {
BACKUPSPEC_REGEX = r"^([a-zA-Z0-9_-]+\.(pxar|img|conf|log)):(.+)$";
}
use nix::sys::stat::Mode;
use pathpatterns::{MatchEntry, MatchList, MatchPattern, MatchType, PatternFlag};
-use proxmox::api::api;
-use proxmox::api::cli::{self, CliCommand, CliCommandMap, CliHelper, CommandLineInterface};
use proxmox::tools::fs::{create_path, CreateOptions};
+use proxmox_router::cli::{self, CliCommand, CliCommandMap, CliHelper, CommandLineInterface};
+use proxmox_schema::api;
use pxar::{EntryKind, Metadata};
use pbs_runtime::block_in_place;
use xdg::BaseDirectories;
use proxmox::{
- api::error::HttpError,
sys::linux::tty,
tools::fs::{file_get_json, replace_file, CreateOptions},
};
+use proxmox_router::HttpError;
use proxmox_http::client::HttpsConnector;
use proxmox_http::uri::build_authority;
let mut data = file_get_json(&path, Some(json!({})))?;
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
data[server][username] = json!({ "timestamp": now, "ticket": ticket, "token": token});
// usually /run/user/<uid>/...
let path = base.place_runtime_file("tickets").ok()?;
let data = file_get_json(&path, None).ok()?;
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
let ticket_lifetime = ticket::TICKET_LIFETIME - 60;
let uinfo = data[server][userid.as_str()].as_object()?;
let timestamp = uinfo["timestamp"].as_i64()?;
use pxar::Metadata;
use pxar::encoder::{SeqWrite, LinkOffset};
-use proxmox::c_str;
use proxmox::sys::error::SysError;
use proxmox::tools::fd::RawFdNum;
-use proxmox::tools::vec;
use proxmox::tools::fd::Fd;
+use proxmox_io::vec;
+use proxmox_lang::c_str;
use pbs_datastore::catalog::BackupCatalogWriter;
use pbs_tools::{acl, fs, xattr};
use pxar::{Entry, EntryKind, Metadata};
use proxmox::c_result;
-use proxmox::tools::{
- fs::{create_path, CreateOptions},
- io::{sparse_copy, sparse_copy_async},
-};
+use proxmox::tools::fs::{create_path, CreateOptions};
+use proxmox_io::{sparse_copy, sparse_copy_async};
use pbs_tools::zip::{ZipEncoder, ZipEntry};
use futures::sink::SinkExt;
use futures::stream::{StreamExt, TryStreamExt};
-use proxmox::tools::vec;
+use proxmox_io::vec;
use pxar::accessor::{self, EntryRangeInfo, ReadAt};
use proxmox_fuse::requests::{self, FuseRequest};
}
fn format_mtime(mtime: &StatxTimestamp) -> String {
- if let Ok(s) = proxmox::tools::time::strftime_local("%Y-%m-%d %H:%M:%S", mtime.secs) {
+ if let Ok(s) = proxmox_time::strftime_local("%Y-%m-%d %H:%M:%S", mtime.secs) {
return s;
}
format!("{}.{}", mtime.secs, mtime.nanos)
use tokio::signal::unix::{signal, SignalKind};
use futures::*;
-use proxmox::api::cli::format_and_print_result;
+use proxmox_router::cli::format_and_print_result;
use pbs_tools::percent_encoding::percent_encode_component;
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::api::schema::*;
use proxmox::sys::linux::tty;
use proxmox::tools::fs::file_get_contents;
+use proxmox_schema::*;
use pbs_api_types::CryptMode;
use serde_json::{json, Value};
use xdg::BaseDirectories;
-use proxmox::{
- api::schema::*,
- api::cli::shellword_split,
- tools::fs::file_get_json,
-};
+use proxmox_schema::*;
+use proxmox_router::cli::shellword_split;
+use proxmox::tools::fs::file_get_json;
use pbs_api_types::{BACKUP_REPO_URL, Authid, UserWithTokens};
use pbs_datastore::BackupDir;
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, ReadBuf};
use tokio::net::UnixStream;
-use proxmox::api::error::HttpError;
+use proxmox_router::HttpError;
pub const DEFAULT_VSOCK_PORT: u16 = 807;
description = "Configuration file management for PBS"
[dependencies]
-libc = "0.2"
anyhow = "1.0"
+hex = "0.4.3"
lazy_static = "1.4"
-serde = { version = "1.0", features = ["derive"] }
-serde_json = "1.0"
-openssl = "0.10"
+libc = "0.2"
nix = "0.19.1"
-regex = "1.2"
once_cell = "1.3.1"
+openssl = "0.10"
+regex = "1.2"
+serde = { version = "1.0", features = ["derive"] }
+serde_json = "1.0"
-proxmox = { version = "0.14.0", default-features = false, features = [ "cli" ] }
+proxmox = "0.14.0"
+proxmox-lang = "1"
+proxmox-router = "1"
+proxmox-schema = "1"
+proxmox-section-config = "1"
+proxmox-time = "1"
pbs-api-types = { path = "../pbs-api-types" }
pbs-buildcfg = { path = "../pbs-buildcfg" }
use lazy_static::lazy_static;
-use proxmox::api::schema::{Schema, StringSchema, ApiStringFormat, ApiType};
+use proxmox_schema::{ApiStringFormat, ApiType, Schema, StringSchema};
use pbs_api_types::{Authid, Userid, Role, ROLE_NAME_NO_ACCESS};
use std::sync::{RwLock, Arc};
use anyhow::{Error, bail};
-
-use proxmox::api::section_config::SectionConfigData;
use lazy_static::lazy_static;
-use proxmox::api::UserInformation;
-use proxmox::tools::time::epoch_i64;
+
+use proxmox_router::UserInformation;
+use proxmox_section_config::SectionConfigData;
+use proxmox_time::epoch_i64;
use pbs_api_types::{Authid, Userid, User, ApiToken, ROLE_ADMIN};
use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox::api::{
- schema::{ApiType, Schema},
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use proxmox_schema::{ApiType, Schema};
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{DataStoreConfig, DATASTORE_SCHEMA};
+use std::collections::HashMap;
+
use anyhow::{Error};
use lazy_static::lazy_static;
-use std::collections::HashMap;
use serde::{Serialize, Deserialize};
-use proxmox::api::{
- api,
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use proxmox_schema::{api, ApiType, Updater, Schema};
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{REALM_ID_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA};
use crate::{open_backup_lockfile, replace_backup_config, BackupLockGuard};
},
},
)]
-#[derive(Serialize,Deserialize,Updater)]
+#[derive(Serialize, Deserialize, Updater)]
#[serde(rename_all="kebab-case")]
/// OpenID configuration properties.
pub struct OpenIdRealmConfig {
use anyhow::{bail, Error};
use lazy_static::lazy_static;
-use proxmox::{
- api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- },
- },
-};
+use proxmox_schema::*;
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use crate::{open_backup_lockfile, replace_backup_config, BackupLockGuard};
use serde::{Deserialize, Serialize};
use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
-use proxmox::try_block;
+use proxmox_lang::try_block;
use pbs_api_types::{Kdf, KeyInfo, Fingerprint};
let crypt_config = CryptConfig::new(raw_key.clone())?;
let fingerprint = Some(Fingerprint::new(crypt_config.fingerprint()));
- let created = proxmox::tools::time::epoch_i64();
+ let created = proxmox_time::epoch_i64();
Ok(Self {
kdf: None,
created,
enc_data.extend_from_slice(&tag);
enc_data.extend_from_slice(&encrypted_key);
- let created = proxmox::tools::time::epoch_i64();
+ let created = proxmox_time::epoch_i64();
// always compute fingerprint
let crypt_config = CryptConfig::new(raw_key.clone())?;
let key = KeyConfig {
kdf: None,
- created: proxmox::tools::time::epoch_i64(),
- modified: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
+ modified: proxmox_time::epoch_i64(),
data: (0u8..32u8).collect(),
fingerprint: Some(Fingerprint::new([
14, 171, 212, 70, 11, 110, 185, 202, 52, 80, 35, 222, 226, 183, 120, 199, 144, 229, 74,
fn fingerprint_checks() -> Result<(), Error> {
let key = KeyConfig {
kdf: None,
- created: proxmox::tools::time::epoch_i64(),
- modified: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
+ modified: proxmox_time::epoch_i64(),
data: (0u8..32u8).collect(),
fingerprint: Some(Fingerprint::new([0u8; 32])), // wrong FP
hint: None,
let key = KeyConfig {
kdf: None,
- created: proxmox::tools::time::epoch_i64(),
- modified: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
+ modified: proxmox_time::epoch_i64(),
data: (0u8..32u8).collect(),
fingerprint: None,
hint: None,
//! provides a type safe interface to store [`MediaPoolConfig`],
//!
//! [MediaPoolConfig]: crate::api2::types::MediaPoolConfig
-//! [SectionConfig]: proxmox::api::section_config::SectionConfig
+//! [SectionConfig]: proxmox_section_config::SectionConfig
use std::collections::HashMap;
use anyhow::Error;
use lazy_static::lazy_static;
-use proxmox::{
- api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
- },
-};
+use proxmox_schema::*;
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{MEDIA_POOL_NAME_SCHEMA, MediaPoolConfig};
-use anyhow::{Error};
-use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox::api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use anyhow::Error;
+use lazy_static::lazy_static;
+
+use proxmox_schema::*;
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{Remote, REMOTE_ID_SCHEMA};
-use anyhow::{Error};
-use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox::api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use anyhow::Error;
+use lazy_static::lazy_static;
+
+use proxmox_schema::{ApiType, Schema};
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{JOB_ID_SCHEMA, SyncJobConfig};
use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox::api::{
- schema::{Schema, ApiType},
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use proxmox_schema::{Schema, ApiType};
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{TapeBackupJobConfig, JOB_ID_SCHEMA};
use anyhow::{bail, Error};
use lazy_static::lazy_static;
-use proxmox::api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use proxmox_schema::*;
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{
Authid, Userid, ApiToken, User,
-use anyhow::{Error};
-use lazy_static::lazy_static;
use std::collections::HashMap;
-use proxmox::api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use anyhow::Error;
+use lazy_static::lazy_static;
+
+use proxmox_schema::*;
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_api_types::{JOB_ID_SCHEMA, VerificationJobConfig};
pathpatterns = "0.1.2"
pxar = "0.10.1"
-proxmox = { version = "0.14.0", default-features = false, features = [ "api-macro" ] }
+proxmox = "0.14.0"
+proxmox-io = "1"
+proxmox-lang = "1"
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-time = "1"
+proxmox-uuid = "1"
pbs-api-types = { path = "../pbs-api-types" }
pbs-tools = { path = "../pbs-tools" }
}
}
- let timestamp = proxmox::tools::time::parse_rfc3339(backup_time)?;
+ let timestamp = proxmox_time::parse_rfc3339(backup_time)?;
if let Some(last_timestamp) = last {
if timestamp > last_timestamp {
last = Some(timestamp);
V: Into<String>,
{
let backup_time_string = backup_time_string.into();
- let backup_time = proxmox::tools::time::parse_rfc3339(&backup_time_string)?;
+ let backup_time = proxmox_time::parse_rfc3339(&backup_time_string)?;
let group = BackupGroup::new(backup_type.into(), backup_id.into());
Ok(Self {
group,
pub fn backup_time_to_string(backup_time: i64) -> Result<String, Error> {
// fixme: can this fail? (avoid unwrap)
- proxmox::tools::time::epoch_to_rfc3339_utc(backup_time)
+ Ok(proxmox_time::epoch_to_rfc3339_utc(backup_time)?)
}
}
use serde::{Deserialize, Serialize};
use pathpatterns::{MatchList, MatchType};
-use proxmox::api::api;
-use proxmox::tools::io::ReadExt;
+
+use proxmox_io::ReadExt;
+use proxmox_schema::api;
use crate::file_formats::PROXMOX_CATALOG_FILE_MAGIC_1_0;
}
CatalogEntryType::File => {
let mut mtime_string = mtime.to_string();
- if let Ok(s) = proxmox::tools::time::strftime_local("%FT%TZ", mtime as i64) {
+ if let Ok(s) = proxmox_time::strftime_local("%FT%TZ", mtime as i64) {
mtime_string = s;
}
use anyhow::{bail, Error};
use openssl::symm::{decrypt_aead, Mode};
-use proxmox::tools::io::{ReadExt, WriteExt};
+use proxmox_io::{ReadExt, WriteExt};
use pbs_tools::crypt_config::CryptConfig;
use pbs_api_types::CryptMode;
/// accessor to crc32 checksum
pub fn crc(&self) -> u32 {
- let crc_o = proxmox::offsetof!(DataBlobHeader, crc);
+ let crc_o = proxmox_lang::offsetof!(DataBlobHeader, crc);
u32::from_le_bytes(self.raw_data[crc_o..crc_o+4].try_into().unwrap())
}
// set the CRC checksum field
pub fn set_crc(&mut self, crc: u32) {
- let crc_o = proxmox::offsetof!(DataBlobHeader, crc);
+ let crc_o = proxmox_lang::offsetof!(DataBlobHeader, crc);
self.raw_data[crc_o..crc_o+4].copy_from_slice(&crc.to_le_bytes());
}
use std::sync::Arc;
use anyhow::{bail, format_err, Error};
-use proxmox::tools::io::ReadExt;
+
+use proxmox_io::ReadExt;
use pbs_tools::crypt_config::CryptConfig;
-use anyhow::Error;
-use proxmox::tools::io::WriteExt;
use std::io::{Seek, SeekFrom, Write};
use std::sync::Arc;
+use anyhow::Error;
+
+use proxmox_io::WriteExt;
+
use pbs_tools::crypt_config::CryptConfig;
use crate::checksum_writer::ChecksumWriter;
// writer" information and thus no safe atime cutoff
let _exclusive_lock = self.chunk_store.try_exclusive_lock()?;
- let phase1_start_time = proxmox::tools::time::epoch_i64();
+ let phase1_start_time = proxmox_time::epoch_i64();
let oldest_writer = self.chunk_store.oldest_writer().unwrap_or(phase1_start_time);
let mut gc_status = GarbageCollectionStatus::default();
path.push(backup_dir.relative_path());
path.push(filename);
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut file = std::fs::File::open(&path)?;
DataBlob::load_from_reader(&mut file)
}).map_err(|err| format_err!("unable to load blob '{:?}' - {}", path, err))
let (chunk_path, digest_str) = self.chunk_store.chunk_path(digest);
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut file = std::fs::File::open(&chunk_path)?;
DataBlob::load_from_reader(&mut file)
}).map_err(|err| format_err!(
use anyhow::{bail, format_err, Error};
-use proxmox::tools::io::ReadExt;
-use proxmox::tools::uuid::Uuid;
use proxmox::tools::mmap::Mmap;
+use proxmox_io::ReadExt;
+use proxmox_uuid::Uuid;
use pxar::accessor::{MaybeReady, ReadAt, ReadAtOperation};
use pbs_tools::lru_cache::LruCache;
pub index_csum: [u8; 32],
reserved: [u8; 4032], // overall size is one page (4096 bytes)
}
-proxmox::static_assert_size!(DynamicIndexHeader, 4096);
+proxmox_lang::static_assert_size!(DynamicIndexHeader, 4096);
// TODO: Once non-Copy unions are stabilized, use:
// union DynamicIndexHeader {
// reserved: [u8; 4096],
bail!("got unknown magic number");
}
- let ctime = proxmox::tools::time::epoch_i64();
+ let ctime = proxmox_time::epoch_i64();
let index_size = stat.st_size as usize - header_size;
let index_count = index_size / 40;
let mut writer = BufWriter::with_capacity(1024 * 1024, file);
- let ctime = proxmox::tools::time::epoch_i64();
+ let ctime = proxmox_time::epoch_i64();
let uuid = Uuid::generate();
self.writer.flush()?;
- let csum_offset = proxmox::offsetof!(DynamicIndexHeader, index_csum);
+ let csum_offset = proxmox_lang::offsetof!(DynamicIndexHeader, index_csum);
self.writer.seek(SeekFrom::Start(csum_offset as u64))?;
let csum = self.csum.take().unwrap();
use pbs_tools::process_locker::ProcessLockSharedGuard;
-use proxmox::tools::io::ReadExt;
-use proxmox::tools::Uuid;
+use proxmox_io::ReadExt;
+use proxmox_uuid::Uuid;
use crate::chunk_stat::ChunkStat;
use crate::chunk_store::ChunkStore;
pub chunk_size: u64,
reserved: [u8; 4016], // overall size is one page (4096 bytes)
}
-proxmox::static_assert_size!(FixedIndexHeader, 4096);
+proxmox_lang::static_assert_size!(FixedIndexHeader, 4096);
// split image into fixed size chunks
println!("ChunkSize: {}", self.chunk_size);
let mut ctime_str = self.ctime.to_string();
- if let Ok(s) = proxmox::tools::time::strftime_local("%c", self.ctime) {
+ if let Ok(s) = proxmox_time::strftime_local("%c", self.ctime) {
ctime_str = s;
}
panic!("got unexpected header size");
}
- let ctime = proxmox::tools::time::epoch_i64();
+ let ctime = proxmox_time::epoch_i64();
let uuid = Uuid::generate();
self.unmap()?;
- let csum_offset = proxmox::offsetof!(FixedIndexHeader, index_csum);
+ let csum_offset = proxmox_lang::offsetof!(FixedIndexHeader, index_csum);
self.file.seek(SeekFrom::Start(csum_offset as u64))?;
self.file.write_all(&index_csum)?;
self.file.flush()?;
use anyhow::{bail, format_err, Error};
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
use pbs_config::key_config::KeyConfig;
})?;
}
- use proxmox::tools::time::strftime_local;
+ use proxmox_time::strftime_local;
if let Some(keep_hourly) = options.keep_hourly {
mark_selections(&mut mark, &list, keep_hourly as usize, |info| {
- strftime_local("%Y/%m/%d/%H", info.backup_dir.backup_time())
+ strftime_local("%Y/%m/%d/%H", info.backup_dir.backup_time()).map_err(Error::from)
})?;
}
if let Some(keep_daily) = options.keep_daily {
mark_selections(&mut mark, &list, keep_daily as usize, |info| {
- strftime_local("%Y/%m/%d", info.backup_dir.backup_time())
+ strftime_local("%Y/%m/%d", info.backup_dir.backup_time()).map_err(Error::from)
})?;
}
mark_selections(&mut mark, &list, keep_weekly as usize, |info| {
// Note: Use iso-week year/week here. This year number
// might not match the calendar year number.
- strftime_local("%G/%V", info.backup_dir.backup_time())
+ strftime_local("%G/%V", info.backup_dir.backup_time()).map_err(Error::from)
})?;
}
if let Some(keep_monthly) = options.keep_monthly {
mark_selections(&mut mark, &list, keep_monthly as usize, |info| {
- strftime_local("%Y/%m", info.backup_dir.backup_time())
+ strftime_local("%Y/%m", info.backup_dir.backup_time()).map_err(Error::from)
})?;
}
if let Some(keep_yearly) = options.keep_yearly {
mark_selections(&mut mark, &list, keep_yearly as usize, |info| {
- strftime_local("%Y", info.backup_dir.backup_time())
+ strftime_local("%Y", info.backup_dir.backup_time()).map_err(Error::from)
})?;
}
type Item = Result<[u8; 32], Error>;
fn next(&mut self) -> Option<Self::Item> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
loop {
if self.current_index.is_none() {
if let Some(filename) = self.todo_list.pop() {
regex = "1.2"
tokio = { version = "1.6", features = [] }
-proxmox = "0.14.0"
+proxmox-time = "1"
proxmox-fuse = "0.1.1"
pbs-tools = { path = "../pbs-tools" }
//! Map a raw data reader as a loop device via FUSE
-use anyhow::{Error, format_err, bail};
+use anyhow::{bail, format_err, Error};
+use std::collections::HashMap;
use std::ffi::OsStr;
-use std::path::{Path, PathBuf};
-use std::fs::{File, remove_file, read_to_string, OpenOptions};
-use std::io::SeekFrom;
+use std::fs::{read_to_string, remove_file, File, OpenOptions};
use std::io::prelude::*;
-use std::collections::HashMap;
+use std::io::SeekFrom;
+use std::path::{Path, PathBuf};
-use nix::unistd::Pid;
use nix::sys::signal::{self, Signal};
+use nix::unistd::Pid;
+use regex::Regex;
-use tokio::io::{AsyncRead, AsyncSeek, AsyncReadExt, AsyncSeekExt};
+use futures::channel::mpsc::{Receiver, Sender};
use futures::stream::{StreamExt, TryStreamExt};
-use futures::channel::mpsc::{Sender, Receiver};
+use tokio::io::{AsyncRead, AsyncReadExt, AsyncSeek, AsyncSeekExt};
-use proxmox::const_regex;
-use proxmox::tools::time;
-use proxmox_fuse::{*, requests::FuseRequest};
use super::loopdev;
+use proxmox_fuse::{requests::FuseRequest, *};
+use proxmox_time::epoch_i64;
const RUN_DIR: &str = "/run/pbs-loopdev";
-const_regex! {
- pub LOOPDEV_REGEX = r"^loop\d+$";
+lazy_static::lazy_static! {
+ static ref LOOPDEV_REGEX: Regex = Regex::new(r"^loop\d+$").unwrap();
}
/// Represents an ongoing FUSE-session that has been mapped onto a loop device.
}
impl<R: AsyncRead + AsyncSeek + Unpin> FuseLoopSession<R> {
-
/// Prepare for mapping the given reader as a block device node at
/// /dev/loopN. Creates a temporary file for FUSE and a PID file for unmap.
- pub async fn map_loop<P: AsRef<str>>(size: u64, mut reader: R, name: P, options: &OsStr)
- -> Result<Self, Error>
- {
+ pub async fn map_loop<P: AsRef<str>>(
+ size: u64,
+ mut reader: R,
+ name: P,
+ options: &OsStr,
+ ) -> Result<Self, Error> {
// attempt a single read to check if the reader is configured correctly
let _ = reader.read_u8().await?;
cleanup_unused_run_files(Some(name.as_ref().to_owned()));
match OpenOptions::new().write(true).create_new(true).open(&path) {
- Ok(_) => { /* file created, continue on */ },
+ Ok(_) => { /* file created, continue on */ }
Err(e) => {
if e.kind() == std::io::ErrorKind::AlreadyExists {
bail!("the given archive is already mapped, cannot map twice");
} else {
bail!("error while creating backing file ({:?}) - {}", &path, e);
}
- },
+ }
}
let session = Fuse::builder("pbs-block-dev")?
.build()?
.mount(&path)?;
- let loopdev_path = loopdev::get_or_create_free_dev().map_err(|err| {
- format_err!("loop-control GET_FREE failed - {}", err)
- })?;
+ let loopdev_path = loopdev::get_or_create_free_dev()
+ .map_err(|err| format_err!("loop-control GET_FREE failed - {}", err))?;
// write pidfile so unmap can later send us a signal to exit
Self::write_pidfile(&pid_path)?;
mut startup_chan: Sender<Result<(), Error>>,
abort_chan: Receiver<()>,
) -> Result<(), Error> {
-
if self.session.is_none() {
panic!("internal error: fuse_loop::main called before ::map_loop");
}
let (loopdev_path, fuse_path) = (self.loopdev_path.clone(), self.fuse_path.clone());
tokio::task::spawn_blocking(move || {
if let Err(err) = loopdev::assign(loopdev_path, fuse_path) {
- let _ = startup_chan.try_send(Err(format_err!("error while assigning loop device - {}", err)));
+ let _ = startup_chan.try_send(Err(format_err!(
+ "error while assigning loop device - {}",
+ err
+ )));
} else {
// device is assigned successfully, which means not only is the
// loopdev ready, but FUSE is also okay, since the assignment
}
});
- let (loopdev_path, fuse_path, pid_path) =
- (self.loopdev_path.clone(), self.fuse_path.clone(), self.pid_path.clone());
+ let (loopdev_path, fuse_path, pid_path) = (
+ self.loopdev_path.clone(),
+ self.fuse_path.clone(),
+ self.pid_path.clone(),
+ );
let cleanup = |session: futures::stream::Fuse<Fuse>| {
// only warn for errors on cleanup, if these fail nothing is lost
if let Err(err) = loopdev::unassign(&loopdev_path) {
eprintln!(
"cleanup: warning: could not unassign file {} from loop device {} - {}",
- &fuse_path,
- &loopdev_path,
- err,
+ &fuse_path, &loopdev_path, err,
);
}
if let Err(err) = remove_file(&fuse_path) {
eprintln!(
"cleanup: warning: could not remove temporary file {} - {}",
- &fuse_path,
- err,
+ &fuse_path, err,
);
}
if let Err(err) = remove_file(&pid_path) {
eprintln!(
"cleanup: warning: could not remove PID file {} - {}",
- &pid_path,
- err,
+ &pid_path, err,
);
}
};
loop {
- tokio::select!{
+ tokio::select! {
_ = abort_chan.next() => {
// aborted, do cleanup and exit
break;
pub fn cleanup_unused_run_files(filter_name: Option<String>) {
if let Ok(maps) = find_all_mappings() {
for (name, loopdev) in maps {
- if loopdev.is_none() &&
- (filter_name.is_none() || &name == filter_name.as_ref().unwrap())
+ if loopdev.is_none()
+ && (filter_name.is_none() || &name == filter_name.as_ref().unwrap())
{
let mut path = PathBuf::from(RUN_DIR);
path.push(&name);
}
fn get_backing_file(loopdev: &str) -> Result<String, Error> {
- let num = loopdev.split_at(9).1.parse::<u8>().map_err(|err|
- format_err!("malformed loopdev path, does not end with valid number - {}", err))?;
+ let num = loopdev.split_at(9).1.parse::<u8>().map_err(|err| {
+ format_err!(
+ "malformed loopdev path, does not end with valid number - {}",
+ err
+ )
+ })?;
- let block_path = PathBuf::from(format!("/sys/devices/virtual/block/loop{}/loop/backing_file", num));
+ let block_path = PathBuf::from(format!(
+ "/sys/devices/virtual/block/loop{}/loop/backing_file",
+ num
+ ));
let backing_file = read_to_string(block_path).map_err(|err| {
if err.kind() == std::io::ErrorKind::NotFound {
format_err!("nothing mapped to {}", loopdev)
// call in broken state: we found the mapping, but the client is already dead,
// only thing to do is clean up what we can
-fn emerg_cleanup (loopdev: Option<&str>, mut backing_file: PathBuf) {
+fn emerg_cleanup(loopdev: Option<&str>, mut backing_file: PathBuf) {
eprintln!(
"warning: found mapping with dead process ({:?}), attempting cleanup",
&backing_file
}
format_err!("error reading pidfile {:?}: {}", &pid_path, err)
})?;
- let pid = pid_str.parse::<i32>().map_err(|err|
- format_err!("malformed PID ({}) in pidfile - {}", pid_str, err))?;
+ let pid = pid_str
+ .parse::<i32>()
+ .map_err(|err| format_err!("malformed PID ({}) in pidfile - {}", pid_str, err))?;
let pid = Pid::from_raw(pid);
// send SIGINT to trigger cleanup and exit in target process
match signal::kill(pid, Signal::SIGINT) {
- Ok(()) => {},
+ Ok(()) => {}
Err(nix::Error::Sys(nix::errno::Errno::ESRCH)) => {
emerg_cleanup(loopdev, backing_file.to_owned());
return Ok(());
- },
+ }
Err(e) => return Err(e.into()),
}
// block until unmap is complete or timeout
- let start = time::epoch_i64();
+ let start = epoch_i64();
loop {
match signal::kill(pid, None) {
Ok(_) => {
// 10 second timeout, then assume failure
- if (time::epoch_i64() - start) > 10 {
+ if (epoch_i64() - start) > 10 {
return Err(format_err!("timed out waiting for PID '{}' to exit", &pid));
}
std::thread::sleep(std::time::Duration::from_millis(100));
- },
+ }
Err(nix::Error::Sys(nix::errno::Errno::ESRCH)) => {
break;
- },
+ }
Err(e) => return Err(e.into()),
}
}
let loopdev = format!("/dev/{}", ent.file_name().to_string_lossy());
if let Ok(file) = get_backing_file(&loopdev) {
// insert filename only, strip RUN_DIR/
- loopmap.insert(file[RUN_DIR.len()+1..].to_owned(), loopdev);
+ loopmap.insert(file[RUN_DIR.len() + 1..].to_owned(), loopdev);
}
}
}
- Ok(pbs_tools::fs::read_subdir(libc::AT_FDCWD, Path::new(RUN_DIR))?
- .filter_map(move |ent| {
+ Ok(
+ pbs_tools::fs::read_subdir(libc::AT_FDCWD, Path::new(RUN_DIR))?.filter_map(move |ent| {
match ent {
Ok(ent) => {
let file = ent.file_name().to_string_lossy();
let loopdev = loopmap.get(file.as_ref()).map(String::to_owned);
Some((file.into_owned(), loopdev))
}
- },
+ }
Err(_) => None,
}
- }))
+ }),
+ )
}
/// Try and unmap a running proxmox-backup-client instance from the given
regex = "1.2"
udev = ">= 0.3, <0.5"
-proxmox = { version = "0.14.0", default-features = false, features = [] }
+proxmox = "0.14.0"
+proxmox-io = "1"
+proxmox-lang = "1"
+# api-macro is only used by the binaries, so maybe we should split them out
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-time = "1"
+proxmox-uuid = "1"
+
+# router::cli is only used by binaries, so maybe we should split them out
+proxmox-router = "1"
pbs-api-types = { path = "../pbs-api-types" }
pbs-tools = { path = "../pbs-tools" }
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- schema::{
- Schema,
- IntegerSchema,
- StringSchema,
- ArraySchema,
- },
- RpcEnvironment,
- },
-};
+use proxmox_schema::{api, ArraySchema, IntegerSchema, Schema, StringSchema};
+use proxmox_router::cli::*;
+use proxmox_router::RpcEnvironment;
use pbs_api_types::{
LTO_DRIVE_PATH_SCHEMA, DRIVE_NAME_SCHEMA, LtoTapeDrive,
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- },
-};
+use proxmox_schema::api;
+use proxmox_router::cli::*;
+use proxmox_router::RpcEnvironment;
use pbs_config::drive::complete_changer_name;
use pbs_api_types::{
let output_format = get_output_format(¶m);
- let result: Result<_, Error> = proxmox::try_block!({
+ let result: Result<_, Error> = proxmox_lang::try_block!({
let mut file = get_changer_handle(¶m)?;
let info = scsi_inquiry(&mut file)?;
Ok(info)
let output_format = get_output_format(¶m);
- let result: Result<_, Error> = proxmox::try_block!({
+ let result: Result<_, Error> = proxmox_lang::try_block!({
let mut file = get_changer_handle(¶m)?;
let status = sg_pt_changer::read_element_status(&mut file)?;
Ok(status)
-use proxmox::tools::vec;
+use proxmox_io::vec;
use crate::{
TapeWrite,
use std::io::Read;
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use crate::{BlockRead, BlockReadError, PROXMOX_TAPE_BLOCK_SIZE};
use serde::{Serialize, Deserialize};
use serde_json::Value;
-use proxmox::tools::Uuid;
-use proxmox::api::schema::parse_property_string;
+use proxmox_schema::parse_property_string;
+use proxmox_uuid::Uuid;
use pbs_api_types::{ScsiTapeChanger, SLOT_ARRAY_SCHEMA};
/// Create a new instance with autogenerated Uuid
pub fn new(content_magic: [u8; 8], size: u32) -> Self {
- let uuid = *proxmox::tools::uuid::Uuid::generate()
+ let uuid = *Uuid::generate()
.into_inner();
Self {
magic: PROXMOX_BACKUP_CONTENT_HEADER_MAGIC_1_0,
content_magic,
uuid,
- ctime: proxmox::tools::time::epoch_i64(),
+ ctime: proxmox_time::epoch_i64(),
size,
part_number: 0,
reserved_0: 0,
use anyhow::{bail, format_err, Error};
use endian_trait::Endian;
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use pbs_api_types::ScsiTapeChanger;
let data = execute_scsi_command(&mut sg_raw, &cmd, "read element address assignment", true)?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut reader = &data[..];
let page: AddressAssignmentPage = unsafe { reader.read_be_value()? };
start_element_address: u16,
) -> Result<DecodedStatusPage, Error> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut result = DecodedStatusPage {
last_element_address: None,
mod report_density;
pub use report_density::*;
-use proxmox::{
- sys::error::SysResult,
- tools::io::{ReadExt, WriteExt},
-};
+use proxmox::sys::error::SysResult;
+use proxmox_io::{ReadExt, WriteExt};
use pbs_api_types::{MamAttribute, Lp17VolumeStatistics, LtoDriveAndMediaStatus};
let data = sg_raw.do_command(&cmd)
.map_err(|err| format_err!("read position failed - {}", err))?;
- let page = proxmox::try_block!({
+ let page = proxmox_lang::try_block!({
if data.len() != expected_size {
bail!("got unexpected data len ({} != {}", data.len(), expected_size);
}
let (head, block_descriptor, page): (_,_, MediumConfigurationModePage)
= scsi_mode_sense(&mut self.file, false, 0x1d, 0)?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
if (page.page_code & 0b0011_1111) != 0x1d {
bail!("wrong page code {}", page.page_code);
}
let (head, block_descriptor, page): (_,_, DataCompressionModePage)
= scsi_mode_sense(&mut self.file, false, 0x0f, 0)?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
if (page.page_code & 0b0011_1111) != 0x0f {
bail!("wrong page code {}", page.page_code);
}
use anyhow::{bail, format_err, Error};
use endian_trait::Endian;
-use proxmox::tools::io::{ReadExt, WriteExt};
+use proxmox_io::{ReadExt, WriteExt};
use crate::sgutils2::{SgRaw, alloc_page_aligned_buffer};
// Returns the algorythm_index for AES-CGM
fn decode_spin_data_encryption_caps(data: &[u8]) -> Result<u8, Error> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut reader = &data[..];
let _page: SspDataEncryptionCapabilityPage = unsafe { reader.read_be_value()? };
fn decode_spin_data_encryption_status(data: &[u8]) -> Result<DataEncryptionStatus, Error> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut reader = &data[..];
let page: SspDataEncryptionStatusPage = unsafe { reader.read_be_value()? };
use anyhow::{bail, format_err, Error};
use endian_trait::Endian;
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use pbs_api_types::MamAttribute;
let mon: i32 = date_str[4..6].parse()?;
let mday: i32 = date_str[6..8].parse()?;
- use proxmox::tools::time::TmEditor;
+ use proxmox_time::TmEditor;
let mut t = TmEditor::new(true);
t.set_year(year)?;
t.set_mon(mon)?;
use endian_trait::Endian;
use std::os::unix::io::AsRawFd;
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use crate::sgutils2::SgRaw;
let mut max_density = 0u8;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut reader = &data[..];
let page_len: u16 = unsafe { reader.read_be_value()? };
use anyhow::{bail, format_err, Error};
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use crate::sgutils2::SgRaw;
fn decode_tape_alert_flags(data: &[u8]) -> Result<TapeAlertFlags, Error> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
if !((data[0] & 0x7f) == 0x12 && data[1] == 0) {
bail!("invalid response");
}
use anyhow::{bail, format_err, Error};
use endian_trait::Endian;
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use pbs_api_types::Lp17VolumeStatistics;
Ok(value)
};
- proxmox::try_block!({
+ proxmox_lang::try_block!({
if !((data[0] & 0x7f) == 0x17 && data[1] == 0) {
bail!("invalid response");
}
//!
//! The SCSI Commands Reference Manual also contains some useful information.
+use std::ffi::CStr;
use std::os::unix::io::AsRawFd;
use std::ptr::NonNull;
use anyhow::{bail, format_err, Error};
use endian_trait::Endian;
-use serde::{Deserialize, Serialize};
use libc::{c_char, c_int};
-use std::ffi::CStr;
+use serde::{Deserialize, Serialize};
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
#[derive(thiserror::Error, Debug)]
pub struct SenseInfo {
)
};
- proxmox::try_block!({
+ proxmox_lang::try_block!({
if res.is_null() { // just to be safe
bail!("unexpected NULL ptr");
}
let data = sg_raw.do_command(&cmd)
.map_err(|err| format_err!("SCSI inquiry failed - {}", err))?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut reader = &data[..];
let page: InquiryPage = unsafe { reader.read_be_value()? };
let data = sg_raw.do_command(&cmd)
.map_err(|err| format_err!("mode sense failed - {}", err))?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut reader = &data[..];
let head: ModeParameterHeader = unsafe { reader.read_be_value()? };
let data = sg_raw.do_command(&cmd)
.map_err(|err| format_err!("request sense failed - {}", err))?;
- let sense = proxmox::try_block!({
+ let sense = proxmox_lang::try_block!({
let data_len = data.len();
if data_len < std::mem::size_of::<RequestSenseFixed>() {
flate2 = "1.0"
foreign-types = "0.3"
futures = "0.3"
-hex = "0.4"
+hex = "0.4.3"
lazy_static = "1.4"
libc = "0.2"
log = "0.4"
zstd = { version = "0.6", features = [ "bindgen" ] }
proxmox = { version = "0.14.0", default-features = false, features = [ "tokio" ] }
-proxmox-io = { version = "1.0.0" }
-proxmox-lang = { version = "1.0.0" }
-proxmox-time = { version = "1.0.0" }
+proxmox-io = { version = "1", features = [ "tokio" ] }
+proxmox-lang = { version = "1" }
+proxmox-time = { version = "1" }
pbs-buildcfg = { path = "../pbs-buildcfg" }
pbs-runtime = { path = "../pbs-runtime" }
bail!("failed to parse ASN1 time");
}
let mut c_tm = unsafe { c_tm.assume_init() };
- proxmox::tools::time::timegm(&mut c_tm)
+ Ok(proxmox_time::timegm(&mut c_tm)?)
}
pub struct CertInfo {
pub fn fingerprint(&self) -> Result<String, Error> {
let fp = self.x509.digest(openssl::hash::MessageDigest::sha256())?;
- let fp_string = proxmox::tools::digest_to_hex(&fp);
- let fp_string = fp_string.as_bytes().chunks(2).map(|v| std::str::from_utf8(v).unwrap())
- .collect::<Vec<&str>>().join(":");
- Ok(fp_string)
+ Ok(hex::encode(&fp)
+ .as_bytes()
+ .chunks(2)
+ .map(|v| std::str::from_utf8(v).unwrap())
+ .collect::<Vec<&str>>().join(":"))
}
pub fn public_key(&self) -> Result<PKey<Public>, Error> {
use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt};
use proxmox::io_format_err;
-use proxmox::tools::byte_buffer::ByteBuffer;
+use proxmox_io::ByteBuffer;
const BUFFER_SIZE: usize = 8192;
if value.is_null() { return Ok(String::new()); }
let text = match value.as_i64() {
Some(epoch) => {
- if let Ok(epoch_string) = proxmox::tools::time::strftime_local("%c", epoch as i64) {
+ if let Ok(epoch_string) = proxmox_time::strftime_local("%c", epoch as i64) {
epoch_string
} else {
epoch.to_string()
}
pub fn as_fingerprint(bytes: &[u8]) -> String {
- proxmox::tools::digest_to_hex(bytes)
+ hex::encode(bytes)
.as_bytes()
.chunks(2)
- .map(|v| std::str::from_utf8(v).unwrap())
+ .map(|v| unsafe { std::str::from_utf8_unchecked(v) }) // it's a hex string
.collect::<Vec<&str>>().join(":")
}
pub mod bytes_as_fingerprint {
+ use std::mem::MaybeUninit;
+
use serde::{Deserialize, Serializer, Deserializer};
pub fn serialize<S>(
where
D: Deserializer<'de>,
{
+ // TODO: more efficiently implement with a Visitor implementing visit_str using split() and
+ // hex::decode by-byte
let mut s = String::deserialize(deserializer)?;
s.retain(|c| c != ':');
- proxmox::tools::hex_to_digest(&s).map_err(serde::de::Error::custom)
+ let mut out = MaybeUninit::<[u8; 32]>::uninit();
+ hex::decode_to_slice(s.as_bytes(), unsafe { &mut (*out.as_mut_ptr())[..] })
+ .map_err(serde::de::Error::custom)?;
+ Ok(unsafe { out.assume_init() })
}
}
use anyhow::Error;
+use proxmox_io::vec;
+
/// Calculate the sha256sum from a readable object.
pub fn sha256(file: &mut dyn Read) -> Result<([u8; 32], u64), Error> {
let mut hasher = openssl::sha::Sha256::new();
- let mut buffer = proxmox::tools::vec::undefined(256 * 1024);
+ let mut buffer = vec::undefined(256 * 1024);
let mut size: u64 = 0;
loop {
use futures::stream::Stream;
use proxmox::io_format_err;
-use proxmox::tools::byte_buffer::ByteBuffer;
use proxmox::sys::error::io_err_other;
+use proxmox_io::ByteBuffer;
use pbs_runtime::block_in_place;
Ok(Self {
prefix: Cow::Borrowed(prefix),
data: data.to_string(),
- time: proxmox::tools::time::epoch_i64(),
+ time: proxmox_time::epoch_i64(),
signature: None,
_type_marker: PhantomData,
})
None => bail!("invalid ticket without signature"),
};
- let age = proxmox::tools::time::epoch_i64() - self.time;
+ let age = proxmox_time::epoch_i64() - self.time;
if age < time_frame.start {
bail!("invalid ticket - timestamp newer than expected");
}
false
});
simple_test(&key, None, |t| {
- t.change_time(proxmox::tools::time::epoch_i64() + 0x1000_0000);
+ t.change_time(proxmox_time::epoch_i64() + 0x1000_0000);
false
});
}
use nix::errno::Errno;
-use proxmox::c_str;
-use proxmox::tools::vec;
+use proxmox_io::vec;
+use proxmox_lang::c_str;
/// `"security.capability"` as a CStr to avoid typos.
///
use nix::errno::Errno;
- use proxmox::c_str;
+ use proxmox_lang::c_str;
#[test]
fn test_fsetxattr_fgetxattr() {
use tokio::io::{AsyncRead, AsyncWrite, AsyncWriteExt, ReadBuf};
use crc32fast::Hasher;
-use proxmox::tools::time::gmtime;
+use proxmox_time::gmtime;
use crate::compression::{DeflateEncoder, Level};
pathpatterns = "0.1.2"
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
-proxmox = { version = "0.14.0", features = [ "sortable-macro", "api-macro", "cli", "router" ] }
+proxmox = { version = "0.14.0", features = [ "sortable-macro" ] }
+proxmox-router = { version = "1", features = [ "cli" ] }
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-time = "1"
pbs-api-types = { path = "../pbs-api-types" }
pbs-buildcfg = { path = "../pbs-buildcfg" }
use serde_json::Value;
use serde::Serialize;
-use proxmox::api::{ApiMethod, RpcEnvironment};
-use proxmox::api::{
- api,
+use proxmox_schema::{api, ApiType, ReturnType};
+use proxmox_router::{
cli::{
OUTPUT_FORMAT,
ColumnConfig,
format_and_print_result_full,
default_table_format_options,
},
- router::ReturnType,
- schema::ApiType,
+ ApiMethod,
+ RpcEnvironment,
};
use pbs_tools::crypt_config::CryptConfig;
verbose: bool,
) -> Result<(), Error> {
- let backup_time = proxmox::tools::time::epoch_i64();
+ let backup_time = proxmox_time::epoch_i64();
let client = connect(&repo)?;
record_repository(&repo);
use anyhow::{Error};
-use proxmox::api::format::*;
-use proxmox::api::cli::*;
+use proxmox_router::cli::*;
+use proxmox_schema::format::*;
use pbs_client::catalog_shell::catalog_shell_cli;
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::api::{api, cli::*};
+use proxmox_schema::api;
+use proxmox_router::cli::*;
use pbs_client::tools::key_source::get_encryption_key_password;
use pbs_client::{BackupReader, RemoteChunkReader};
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::api::api;
-use proxmox::api::cli::{
+use proxmox::sys::linux::tty;
+use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
+use proxmox_router::cli::{
format_and_print_result_full, get_output_format, CliCommand, CliCommandMap, ColumnConfig,
OUTPUT_FORMAT,
};
-use proxmox::api::router::ReturnType;
-use proxmox::api::schema::ApiType;
-use proxmox::sys::linux::tty;
-use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
+use proxmox_schema::{api, ApiType, ReturnType};
use pbs_api_types::{RsaPubKeyInfo, PASSWORD_HINT_SCHEMA, Kdf, KeyInfo};
use pbs_config::key_config::{KeyConfig, rsa_decrypt_key_config};
let mut info: KeyInfo = (&config).into();
info.path = Some(format!("{:?}", path));
- let options = proxmox::api::cli::default_table_format_options()
+ let options = proxmox_router::cli::default_table_format_options()
.column(ColumnConfig::new("path"))
.column(ColumnConfig::new("kdf"))
.column(ColumnConfig::new("created").renderer(pbs_tools::format::render_epoch))
let mut info = RsaPubKeyInfo::try_from(rsa)?;
info.path = Some(path.display().to_string());
- let options = proxmox::api::cli::default_table_format_options()
+ let options = proxmox_router::cli::default_table_format_options()
.column(ColumnConfig::new("path"))
.column(ColumnConfig::new("modulus"))
.column(ColumnConfig::new("exponent"))
use xdg::BaseDirectories;
use pathpatterns::{MatchEntry, MatchType, PatternFlag};
-use proxmox::{
- tools::{
- time::{strftime_local, epoch_i64},
- fs::{file_get_json, replace_file, CreateOptions, image_size},
- },
- api::{
- api,
- ApiMethod,
- RpcEnvironment,
- cli::*,
- },
-};
+use proxmox::tools::fs::{file_get_json, replace_file, CreateOptions, image_size};
+use proxmox_router::{ApiMethod, RpcEnvironment, cli::*};
+use proxmox_schema::api;
+use proxmox_time::{strftime_local, epoch_i64};
use pxar::accessor::{MaybeReady, ReadAt, ReadAtOperation};
use pbs_api_types::{
use tokio::signal::unix::{signal, SignalKind};
use proxmox::{sortable, identity};
-use proxmox::api::{ApiHandler, ApiMethod, RpcEnvironment, schema::*, cli::*};
use proxmox::tools::fd::Fd;
+use proxmox_router::{ApiHandler, ApiMethod, RpcEnvironment, cli::*};
+use proxmox_schema::*;
use pbs_tools::crypt_config::CryptConfig;
use pbs_config::key_config::load_and_decrypt_key;
use anyhow::Error;
use serde_json::{json, Value};
-use proxmox::{
- api::{api, cli::*},
- tools::fs::file_get_contents,
-};
+use proxmox::tools::fs::file_get_contents;
+use proxmox_router::cli::*;
+use proxmox_schema::api;
use pbs_tools::crypt_config::CryptConfig;
use pbs_config::key_config::decrypt_key;
use anyhow::{Error};
use serde_json::{json, Value};
-use proxmox::api::{api, cli::*};
+use proxmox_schema::api;
+use proxmox_router::cli::*;
use pbs_client::display_task_log;
use pbs_tools::percent_encoding::percent_encode_component;
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
-proxmox = { version = "0.14.0", features = [ "api-macro", "cli" ] }
+proxmox = { version = "0.14.0" }
+proxmox-lang = "1"
+proxmox-router = { version = "1", features = [ "cli" ] }
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-time = "1"
+proxmox-uuid = "1"
pbs-api-types = { path = "../pbs-api-types" }
pbs-buildcfg = { path = "../pbs-buildcfg" }
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
-use proxmox::api::{api, cli::*};
+use proxmox_router::cli::*;
+use proxmox_schema::api;
use pbs_client::BackupRepository;
use pbs_datastore::backup_info::BackupDir;
}
fn new_ticket() -> String {
- proxmox::tools::Uuid::generate().to_string()
+ proxmox_uuid::Uuid::generate().to_string()
}
async fn ensure_running(details: &SnapRestoreDetails) -> Result<VsockClient, Error> {
use anyhow::{bail, format_err, Error};
use serde_json::{json, Value};
-use proxmox::api::{
- api,
- cli::{
- default_table_format_options, format_and_print_result_full, get_output_format,
- run_cli_command, CliCommand, CliCommandMap, CliEnvironment, ColumnConfig, OUTPUT_FORMAT,
- },
-};
use proxmox::tools::fs::{create_path, CreateOptions};
+use proxmox_router::cli::{
+ default_table_format_options, format_and_print_result_full, get_output_format,
+ run_cli_command, CliCommand, CliCommandMap, CliEnvironment, ColumnConfig, OUTPUT_FORMAT,
+};
+use proxmox_schema::api;
use pxar::accessor::aio::Accessor;
use pxar::decoder::aio::Decoder;
fn create_restore_log_dir() -> Result<String, Error> {
let logpath = format!("{}/file-restore", pbs_buildcfg::PROXMOX_BACKUP_LOG_DIR);
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let backup_user = backup_user()?;
let opts = CreateOptions::new()
.owner(backup_user.uid)
// preface log file with start timestamp so one can see how long QEMU took to start
writeln!(logfd, "[{}] PBS file restore VM log", {
- let now = proxmox::tools::time::epoch_i64();
- proxmox::tools::time::epoch_to_rfc3339(now)?
+ let now = proxmox_time::epoch_i64();
+ proxmox_time::epoch_to_rfc3339(now)?
},)?;
let base_args = [
# for example
[dev-dependencies]
-proxmox = { version = "0.14.0", features = ["router","api-macro"] }
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
tokio = { version = "1.6", features = [ "rt-multi-thread", "signal", "process" ] }
[dependencies]
tower-service = "0.3.0"
url = "2.1"
-proxmox = { version = "0.14.0", features = [ "router"] }
+proxmox = "0.14.0"
+proxmox-io = "1"
+proxmox-lang = "1"
+proxmox-router = "1"
+proxmox-schema = { version = "1", features = [ "api-macro", "upid-api-impl" ] }
+proxmox-time = "1"
# fixme: remove this dependency (pbs_tools::broadcast_future)
pbs-tools = { path = "../pbs-tools" }
use http::request::Parts;
use http::HeaderMap;
-use proxmox::api::{api, router::SubdirMap, Router, RpcEnvironmentType, UserInformation};
-use proxmox::list_subdirs_api_method;
+use proxmox_schema::api;
+use proxmox_router::{list_subdirs_api_method, SubdirMap, Router, RpcEnvironmentType, UserInformation};
+
use proxmox_rest_server::{ServerAdapter, ApiConfig, AuthError, RestServer, RestEnvironment};
// Create a Dummy User information system
use handlebars::Handlebars;
use serde::Serialize;
-use proxmox::api::{ApiMethod, Router, RpcEnvironmentType, UserInformation};
use proxmox::tools::fs::{create_path, CreateOptions};
+use proxmox_router::{ApiMethod, Router, RpcEnvironmentType, UserInformation};
use crate::{ServerAdapter, AuthError, FileLogger, FileLogOptions, CommandSocket, RestEnvironment};
use futures::future::{self, Either};
use nix::unistd::{fork, ForkResult};
-use proxmox::tools::io::{ReadExt, WriteExt};
use proxmox::tools::fd::Fd;
+use proxmox_io::{ReadExt, WriteExt};
use pbs_tools::fd::fd_change_cloexec;
use serde_json::{json, Value};
-use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
+use proxmox_router::{RpcEnvironment, RpcEnvironmentType};
use crate::ApiConfig;
}
let line = if self.options.prefix_time {
- let now = proxmox::tools::time::epoch_i64();
- let rfc3339 = match proxmox::tools::time::epoch_to_rfc3339(now) {
+ let now = proxmox_time::epoch_i64();
+ let rfc3339 = match proxmox_time::epoch_to_rfc3339(now) {
Ok(rfc3339) => rfc3339,
Err(_) => "1970-01-01T00:00:00Z".into(), // for safety, should really not happen!
};
use hyper::{Body, Response, StatusCode};
use hyper::header;
-use proxmox::api::{HttpError, schema::ParameterError, RpcEnvironment};
+use proxmox_router::{HttpError, RpcEnvironment};
+use proxmox_schema::ParameterError;
/// Extension to set error message for server side logging
pub(crate) struct ErrorMessageExtension(pub String);
use futures::*;
use hyper::{Body, Request, Response, StatusCode};
-use proxmox::api::{ApiResponseFuture, HttpError, Router, RpcEnvironment};
-use proxmox::http_err;
+use proxmox_router::{ApiResponseFuture, HttpError, Router, RpcEnvironment};
+use proxmox_router::http_err;
use crate::{normalize_uri_path, WorkerTask};
use crate::formatter::*;
use proxmox::tools::fd::Fd;
use proxmox::sys::linux::procfs::PidStat;
-use proxmox::api::UserInformation;
use proxmox::tools::fs::CreateOptions;
+use proxmox_router::UserInformation;
mod compression;
pub use compression::*;
use url::form_urlencoded;
use tower_service::Service;
-use proxmox::api::schema::{
- parse_parameter_strings, parse_simple_value, verify_json_object, ObjectSchemaType,
- ParameterSchema,
-};
-use proxmox::api::{
+use proxmox_router::{
check_api_permission, ApiHandler, ApiMethod, HttpError, Permission, RpcEnvironment,
RpcEnvironmentType, UserInformation,
};
-use proxmox::http_err;
+use proxmox_router::http_err;
+use proxmox_schema::{
+ parse_parameter_strings, parse_simple_value, verify_json_object, ObjectSchemaType,
+ ParameterSchema,
+};
use pbs_tools::compression::{DeflateEncoder, Level};
use pbs_tools::stream::AsyncReaderStream;
Some(AuthStringExtension(auth_id)) => auth_id.clone(),
None => "-".to_string(),
};
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
// time format which apache/nginx use (by default), copied from pve-http-server
- let datetime = proxmox::tools::time::strftime_local("%d/%m/%Y:%H:%M:%S %z", now)
+ let datetime = proxmox_time::strftime_local("%d/%m/%Y:%H:%M:%S %z", now)
.unwrap_or_else(|_| "-".to_string());
logfile.lock().unwrap().log(format!(
use once_cell::sync::OnceCell;
use proxmox::sys::linux::procfs;
-use proxmox::try_block;
use proxmox::tools::fs::{create_path, replace_file, atomic_open_or_create_file, CreateOptions};
-use proxmox::api::upid::UPID;
+use proxmox_lang::try_block;
+use proxmox_schema::upid::UPID;
use pbs_tools::task::WorkerTaskContext;
use pbs_tools::logrotate::{LogRotate, LogRotateFiles};
if !worker_is_active_local(&info.upid) {
// println!("Detected stopped task '{}'", &info.upid_str);
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
let status = upid_read_status(&info.upid).unwrap_or(TaskState::Unknown { endtime: now });
finish_list.push(TaskListInfo {
upid: info.upid,
let mut iter = last_line.splitn(2, ": ");
if let Some(time_str) = iter.next() {
- if let Ok(endtime) = proxmox::tools::time::parse_rfc3339(time_str) {
+ if let Ok(endtime) = proxmox_time::parse_rfc3339(time_str) {
// set the endtime even if we cannot parse the state
status = TaskState::Unknown { endtime };
if let Some(rest) = iter.next().and_then(|rest| rest.strip_prefix("TASK ")) {
pub fn create_state(&self, result: &Result<(), Error>) -> TaskState {
let warn_count = self.data.lock().unwrap().warn_count;
- let endtime = proxmox::tools::time::epoch_i64();
+ let endtime = proxmox_time::epoch_i64();
if let Err(err) = result {
TaskState::Error { message: err.to_string(), endtime }
pathpatterns = "0.1.2"
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
-proxmox = { version = "0.14.0", features = [ "router", "sortable-macro" ] }
+proxmox = { version = "0.14.0", features = [ "sortable-macro" ] }
+proxmox-router = { version = "1", features = [ "cli" ] }
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-time = "1"
pbs-api-types = { path = "../pbs-api-types" }
pbs-runtime = { path = "../pbs-runtime" }
use tokio::sync::mpsc;
use tokio_stream::wrappers::ReceiverStream;
-use proxmox::api::RpcEnvironmentType;
+use proxmox_router::RpcEnvironmentType;
use pbs_client::DEFAULT_VSOCK_PORT;
use proxmox_rest_server::{ApiConfig, RestServer};
use tokio::sync::Semaphore;
use pathpatterns::{MatchEntry, MatchPattern, MatchType, Pattern};
-use proxmox::api::{
- api, schema::*, ApiHandler, ApiMethod, ApiResponseFuture, Permission, Router, RpcEnvironment,
- SubdirMap,
+use proxmox::{identity, sortable};
+use proxmox_router::{
+ list_subdirs_api_method,
+ ApiHandler, ApiMethod, ApiResponseFuture, Permission, Router, RpcEnvironment, SubdirMap,
};
-use proxmox::{identity, list_subdirs_api_method, sortable};
+use proxmox_schema::*;
use pbs_api_types::file_restore::RestoreDaemonStatus;
use pbs_client::pxar::{create_archive, Flags, PxarCreateOptions, ENCODER_MAX_ENTRIES};
use http::request::Parts;
use http::HeaderMap;
-use proxmox::api::UserInformation;
+use proxmox_router::UserInformation;
use proxmox_rest_server::{ServerAdapter, AuthError, RestEnvironment};
use lazy_static::lazy_static;
use log::{info, warn};
-use proxmox::const_regex;
use proxmox::tools::fs;
+use proxmox_schema::const_regex;
use pbs_api_types::BLOCKDEVICE_NAME_REGEX;
use pbs_tools::run_command;
//! Tokio-based watchdog that shuts down the VM if not pinged for TIMEOUT
use std::sync::atomic::{AtomicI64, Ordering};
-use proxmox::tools::time::epoch_i64;
+use proxmox_time::epoch_i64;
const TIMEOUT: i64 = 600; // seconds
static TRIGGERED: AtomicI64 = AtomicI64::new(0);
[dependencies]
-serde = { version = "1.0", features = [] }
-proxmox = { version = "0.14.0", features = ["api-macro"] }
+serde = { version = "1.0", features = ["derive"] }
+proxmox-schema = { version = "1", features = ["api-macro"] }
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
+
+use proxmox_schema::api;
#[api()]
#[derive(Copy, Clone, Serialize, Deserialize)]
bitflags = "1.2.1"
log = "0.4"
-proxmox = { version = "0.14.0", features = ["api-macro"] }
+proxmox = { version = "0.14.0" }
+proxmox-time = "1"
proxmox-rrd-api-types = { path = "../proxmox-rrd-api-types" }
create_path(path.parent().unwrap(), Some(self.dir_options.clone()), Some(self.file_options.clone()))?;
let mut map = self.cache.write().unwrap();
- let now = proxmox::tools::time::epoch_f64();
+ let now = proxmox_time::epoch_f64();
if let Some(rrd) = map.get_mut(rel_path) {
rrd.update(now, value);
lazy_static = "1.4"
nom = "5.1"
-proxmox = { version = "0.14.0", default-features = false }
+proxmox-time = "1"
+proxmox-lang = "1"
-#pbs-tools = { path = "../pbs-tools" }
+[dev-dependencies]
+proxmox = "0.14.0"
use anyhow::Error;
use bitflags::bitflags;
-use proxmox::tools::time::TmEditor;
+use proxmox_time::TmEditor;
pub use super::parse_time::*;
use anyhow::bail;
use super::*;
- use proxmox::tools::time::*;
+ //use proxmox_time::*;
fn test_event(v: &'static str) -> Result<(), Error> {
match parse_calendar_event(v) {
if next == expect {
println!("next {:?} => {}", event, next);
} else {
- bail!("next {:?} failed\nnext: {:?}\nexpect: {:?}",
- event, gmtime(next), gmtime(expect));
+ bail!(
+ "next {:?} failed\nnext: {:?}\nexpect: {:?}",
+ event,
+ proxmox_time::gmtime(next),
+ proxmox_time::gmtime(expect),
+ );
}
}
Ok(None) => bail!("next {:?} failed to find a timestamp", event),
.output()
.map_err(|err| format_err!("failed to execute {:?} - {}", command, err))?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
if !output.status.success() {
match output.status.code() {
Some(code) => {
tokio = { version = "1.6", features = [ "rt", "rt-multi-thread" ] }
pathpatterns = "0.1.2"
-proxmox = { version = "0.14.0", default-features = false, features = [] }
+proxmox = "0.14.0"
+proxmox-schema = { version = "1", features = [ "api-macro" ] }
+proxmox-router = "1"
pxar = { version = "0.10.1", features = [ "tokio-io" ] }
pbs-client = { path = "../pbs-client" }
use pathpatterns::{MatchEntry, MatchType, PatternFlag};
use pbs_client::pxar::{fuse, format_single_line_entry, ENCODER_MAX_ENTRIES, Flags, PxarExtractOptions};
-use proxmox::api::cli::*;
-use proxmox::api::api;
+use proxmox_schema::api;
+use proxmox_router::cli::*;
fn extract_archive_from_reader<R: std::io::Read>(
reader: &mut R,
use anyhow::{bail, Error};
-use proxmox::api::{api, Router, RpcEnvironment, Permission};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, AclListItem, Role,
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{REALM_ID_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA};
use std::collections::HashMap;
use std::collections::HashSet;
-use proxmox::api::router::{Router, SubdirMap};
-use proxmox::api::{api, Permission, RpcEnvironment};
-use proxmox::{http_err, list_subdirs_api_method};
use proxmox::{identity, sortable};
+use proxmox_router::{
+ http_err, list_subdirs_api_method, Router, RpcEnvironment, SubdirMap, Permission,
+};
+use proxmox_schema::api;
use pbs_api_types::{
Userid, Authid, PASSWORD_SCHEMA, ACL_PATH_SCHEMA,
use serde_json::{json, Value};
-use proxmox::api::router::{Router, SubdirMap};
-use proxmox::api::{api, Permission, RpcEnvironment};
-use proxmox::{http_err, list_subdirs_api_method, identity, sortable};
+use proxmox::{identity, sortable};
+use proxmox_router::{
+ http_err, list_subdirs_api_method, Router, RpcEnvironment, SubdirMap, Permission,
+};
+use proxmox_schema::api;
use proxmox_openid::{OpenIdAuthenticator, OpenIdConfig};
let mut tested_username = None;
- let result = proxmox::try_block!({
+ let result = proxmox_lang::try_block!({
let (realm, private_auth_state) =
OpenIdAuthenticator::verify_public_auth_state(PROXMOX_BACKUP_RUN_DIR_M!(), &state)?;
use serde_json::{json, Value};
-use proxmox::api::{api, Permission};
-use proxmox::api::router::Router;
+use proxmox_router::{Permission, Router};
+use proxmox_schema::api;
use pbs_api_types::{Role, SINGLE_LINE_COMMENT_SCHEMA, PRIVILEGES};
use pbs_config::acl::ROLE_NAMES;
use anyhow::{bail, format_err, Error};
use serde::{Deserialize, Serialize};
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
-use proxmox::tools::tfa::totp::Totp;
-use proxmox::{http_bail, http_err};
+use proxmox_router::{http_bail, http_err, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
+use proxmox_tfa::totp::Totp;
use pbs_api_types::{Authid, Userid, User, PASSWORD_SCHEMA, PRIV_PERMISSIONS_MODIFY, PRIV_SYS_AUDIT};
use serde_json::{json, Value};
use std::collections::HashMap;
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
-use proxmox::api::router::SubdirMap;
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, SubdirMap, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
PROXMOX_CONFIG_DIGEST_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA, Authid,
bail!("token '{}' for user '{}' already exists.", token_name.as_str(), userid);
}
- let secret = format!("{:x}", proxmox::tools::uuid::Uuid::generate());
+ let secret = format!("{:x}", proxmox_uuid::Uuid::generate());
token_shadow::set_secret(&tokenid, &secret)?;
let token = ApiToken {
use serde_json::{json, Value};
use tokio_stream::wrappers::ReceiverStream;
-use proxmox::api::{
- api, ApiResponseFuture, ApiHandler, ApiMethod, Router,
- RpcEnvironment, RpcEnvironmentType, Permission
-};
-use proxmox::api::router::SubdirMap;
-use proxmox::api::schema::*;
+use proxmox::{identity, sortable};
use proxmox::tools::fs::{
file_read_firstline, file_read_optional_string, replace_file, CreateOptions,
};
-use proxmox::{http_err, identity, list_subdirs_api_method, sortable};
+use proxmox_router::{
+ list_subdirs_api_method, http_err, ApiResponseFuture, ApiHandler, ApiMethod, Router,
+ RpcEnvironment, RpcEnvironmentType, SubdirMap, Permission,
+};
+use proxmox_schema::*;
use pxar::accessor::aio::Accessor;
use pxar::EntryKind;
//! Backup Server Administration
-use proxmox::api::router::{Router, SubdirMap};
-use proxmox::list_subdirs_api_method;
+use proxmox_router::{Router, SubdirMap};
+use proxmox_router::list_subdirs_api_method;
pub mod datastore;
pub mod sync;
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment, RpcEnvironmentType};
-use proxmox::api::router::SubdirMap;
-use proxmox::{list_subdirs_api_method, sortable};
+use proxmox::sortable;
+use proxmox_router::{
+ list_subdirs_api_method, ApiMethod, Router, RpcEnvironment, RpcEnvironmentType, SubdirMap,
+ Permission,
+};
+use proxmox_schema::api;
use pbs_api_types::{DATASTORE_SCHEMA, JOB_ID_SCHEMA, Authid, SyncJobConfig, SyncJobStatus};
use pbs_config::sync;
use anyhow::{format_err, Error};
use serde_json::Value;
-use proxmox::api::router::SubdirMap;
-use proxmox::{list_subdirs_api_method, sortable};
-use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment, RpcEnvironmentType};
+use proxmox::sortable;
+use proxmox_router::{
+ list_subdirs_api_method, ApiMethod, Router, RpcEnvironment, RpcEnvironmentType, SubdirMap,
+ Permission,
+};
+use proxmox_schema::api;
use pbs_api_types::{
VerificationJobConfig, VerificationJobStatus, JOB_ID_SCHEMA, Authid,
use proxmox::tools::digest_to_hex;
use proxmox::tools::fs::{replace_file, CreateOptions};
-use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
+use proxmox_router::{RpcEnvironment, RpcEnvironmentType};
use pbs_datastore::{DataStore, DataBlob};
use pbs_datastore::backup_info::{BackupDir, BackupInfo};
use hyper::{Body, Response, Request, StatusCode};
use serde_json::{json, Value};
-use proxmox::{sortable, identity, list_subdirs_api_method};
-use proxmox::api::{ApiResponseFuture, ApiHandler, ApiMethod, Router, RpcEnvironment, Permission};
-use proxmox::api::router::SubdirMap;
-use proxmox::api::schema::*;
+use proxmox::{sortable, identity};
+use proxmox_router::list_subdirs_api_method;
+use proxmox_router::{
+ ApiResponseFuture, ApiHandler, ApiMethod, Router, RpcEnvironment, SubdirMap, Permission,
+};
+use proxmox_schema::*;
use pbs_api_types::{
Authid, VerifyState, SnapshotVerifyState,
use serde_json::{json, Value};
use proxmox::{sortable, identity};
-use proxmox::api::{ApiResponseFuture, ApiHandler, ApiMethod, RpcEnvironment};
-use proxmox::api::schema::*;
+use proxmox_router::{ApiResponseFuture, ApiHandler, ApiMethod, RpcEnvironment};
+use proxmox_schema::*;
use pbs_datastore::{DataStore, DataBlob};
use pbs_datastore::file_formats::{DataBlobHeader, EncryptedDataBlobHeader};
break format_err!("uploaded chunk has unexpected size.");
}
- let (is_duplicate, compressed_size) = match proxmox::try_block! {
+ let (is_duplicate, compressed_size) = match proxmox_lang::try_block! {
let mut chunk = DataBlob::from_raw(raw_data)?;
pbs_runtime::block_in_place(|| {
-use proxmox::api::{Router, SubdirMap};
-use proxmox::list_subdirs_api_method;
+use proxmox_router::{Router, SubdirMap};
+use proxmox_router::list_subdirs_api_method;
use proxmox::{identity, sortable};
pub mod tfa;
use serde_json::Value;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
PROXMOX_CONFIG_DIGEST_SCHEMA, REALM_ID_SCHEMA, PRIV_SYS_AUDIT, PRIV_REALM_ALLOCATE,
use anyhow::Error;
-use proxmox::api::{api, Permission, Router, RpcEnvironment, SubdirMap};
-use proxmox::list_subdirs_api_method;
+use proxmox_router::{Router, RpcEnvironment, Permission, SubdirMap};
+use proxmox_schema::api;
+use proxmox_router::list_subdirs_api_method;
use pbs_api_types::PROXMOX_CONFIG_DIGEST_SCHEMA;
use serde::{Deserialize, Serialize};
use serde_json::{json, Value};
-use proxmox::api::router::SubdirMap;
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
-use proxmox::http_bail;
-use proxmox::list_subdirs_api_method;
+use proxmox_router::{
+ http_bail, list_subdirs_api_method, Permission, Router, SubdirMap, RpcEnvironment,
+};
+use proxmox_schema::api;
use proxmox_acme_rs::account::AccountData as AcmeAccountData;
use proxmox_acme_rs::Account;
use ::serde::{Deserialize, Serialize};
use serde_json::Value;
-use proxmox::api::{
- api,
- Router,
- RpcEnvironment,
- Permission,
- schema::parse_property_string,
-};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::{api, parse_property_string};
use pbs_api_types::{
Authid, ScsiTapeChanger, ScsiTapeChangerUpdater, LtoTapeDrive,
use serde_json::Value;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Router, RpcEnvironment, RpcEnvironmentType, Permission};
-use proxmox::api::section_config::SectionConfigData;
-use proxmox::api::schema::{ApiType, parse_property_string};
+use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
+use proxmox_schema::{api, ApiType, parse_property_string};
+use proxmox_section_config::SectionConfigData;
use pbs_datastore::chunk_store::ChunkStore;
use pbs_config::BackupLockGuard;
use ::serde::{Deserialize, Serialize};
use serde_json::Value;
-use proxmox::api::{api, Router, RpcEnvironment, Permission};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, LtoTapeDrive, LtoTapeDriveUpdater, ScsiTapeChanger,
use anyhow::{bail, Error};
use ::serde::{Deserialize, Serialize};
-use proxmox::{
- api::{
- api,
- Router,
- RpcEnvironment,
- Permission,
- },
-};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, MediaPoolConfig, MediaPoolConfigUpdater, MEDIA_POOL_NAME_SCHEMA,
//! Backup Server Configuration
-use proxmox::api::router::{Router, SubdirMap};
-use proxmox::list_subdirs_api_method;
+use proxmox_router::{Router, SubdirMap};
+use proxmox_router::list_subdirs_api_method;
pub mod access;
pub mod acme;
use serde_json::Value;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
-use proxmox::http_err;
+use proxmox_router::{http_err, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_client::{HttpClient, HttpClientOptions};
use pbs_api_types::{
use serde_json::Value;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, SyncJobConfig, SyncJobConfigUpdater, JOB_ID_SCHEMA, PROXMOX_CONFIG_DIGEST_SCHEMA,
use serde_json::Value;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Router, RpcEnvironment, Permission};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, TapeBackupJobConfig, TapeBackupJobConfigUpdater,
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- ApiMethod,
- Router,
- RpcEnvironment,
- Permission,
- },
-};
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Fingerprint, KeyInfo, Kdf,
use serde_json::Value;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, VerificationJobConfig, VerificationJobConfigUpdater, JOB_ID_SCHEMA,
use futures::stream::TryStreamExt;
use hyper::{Body, Response, StatusCode, header};
-use proxmox::http_bail;
+use proxmox_router::http_bail;
pub async fn create_download_response(path: PathBuf) -> Result<Response<Body>, Error> {
let file = match tokio::fs::File::open(path.clone()).await {
pub mod tape;
pub mod helpers;
-use proxmox::api::router::SubdirMap;
-use proxmox::api::Router;
-use proxmox::list_subdirs_api_method;
+use proxmox_router::{list_subdirs_api_method, Router, SubdirMap};
const SUBDIRS: SubdirMap = &[
("access", &access::ROUTER),
use serde_json::{json, Value};
use std::collections::HashMap;
-use proxmox::list_subdirs_api_method;
-use proxmox::api::{api, RpcEnvironment, RpcEnvironmentType, Permission};
-use proxmox::api::router::{Router, SubdirMap};
use proxmox::tools::fs::{replace_file, CreateOptions};
+use proxmox_router::{
+ list_subdirs_api_method, RpcEnvironment, RpcEnvironmentType, Permission, Router, SubdirMap
+};
+use proxmox_schema::api;
use proxmox_apt::repositories::{
APTRepositoryFile, APTRepositoryFileError, APTRepositoryHandle, APTRepositoryInfo,
use openssl::x509::X509;
use serde::{Deserialize, Serialize};
-use proxmox::api::router::SubdirMap;
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
-use proxmox::list_subdirs_api_method;
+use proxmox_router::SubdirMap;
+use proxmox_router::{Permission, Router, RpcEnvironment};
+use proxmox_router::list_subdirs_api_method;
+use proxmox_schema::api;
use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_MODIFY};
use pbs_buildcfg::configdir;
/// Check whether the current certificate expires within the next 30 days.
pub fn cert_expires_soon() -> Result<bool, Error> {
let cert = pem_to_cert_info(get_certificate_pem()?.as_bytes())?;
- cert.is_expired_after_epoch(proxmox::tools::time::epoch_i64() + 30 * 24 * 60 * 60)
+ cert.is_expired_after_epoch(proxmox_time::epoch_i64() + 30 * 24 * 60 * 60)
.map_err(|err| format_err!("Failed to check certificate expiration date: {}", err))
}
use anyhow::Error;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Permission, Router, RpcEnvironment};
+use proxmox_router::{Permission, Router, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
use serde_json::json;
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, Permission, RpcEnvironment, RpcEnvironmentType};
-use proxmox::api::section_config::SectionConfigData;
-use proxmox::api::router::Router;
+use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
+use proxmox_schema::api;
+use proxmox_section_config::SectionConfigData;
use pbs_api_types::{
DataStoreConfig, NODE_SCHEMA, BLOCKDEVICE_NAME_SCHEMA,
use anyhow::{bail, Error};
use serde_json::{json, Value};
-use proxmox::api::{api, Permission, RpcEnvironment, RpcEnvironmentType};
-use proxmox::api::router::{Router, SubdirMap};
use proxmox::{sortable, identity};
-use proxmox::{list_subdirs_api_method};
+use proxmox_router::{
+ list_subdirs_api_method, Router, RpcEnvironment, RpcEnvironmentType, SubdirMap, Permission,
+};
+use proxmox_schema::api;
use pbs_api_types::{
UPID_SCHEMA, NODE_SCHEMA, BLOCKDEVICE_NAME_SCHEMA,
use anyhow::{bail, Error};
use serde_json::{json, Value};
-use proxmox::api::{
- api, Permission, RpcEnvironment, RpcEnvironmentType,
- schema::parse_property_string,
-};
-use proxmox::api::router::Router;
+use proxmox_router::{Router, RpcEnvironment, RpcEnvironmentType, Permission};
+use proxmox_schema::{api, parse_property_string};
use pbs_api_types::{
ZpoolListItem, ZfsRaidLevel, ZfsCompressionType, DataStoreConfig,
use serde_json::{json, Value};
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
use proxmox::{IPRE, IPV4RE, IPV6RE, IPV4OCTET, IPV6H16, IPV6LS32};
use serde_json::{json, Value};
use std::io::{BufRead,BufReader};
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_AUDIT};
use serde_json::{json, Value};
use tokio::io::{AsyncBufReadExt, BufReader};
-use proxmox::api::router::{Router, SubdirMap};
-use proxmox::api::{
- api, schema::*, ApiHandler, ApiMethod, ApiResponseFuture, Permission, RpcEnvironment,
-};
-use proxmox::list_subdirs_api_method;
use proxmox::{identity, sortable};
+use proxmox_router::{
+ ApiHandler, ApiMethod, ApiResponseFuture, Permission, RpcEnvironment, Router, SubdirMap,
+};
+use proxmox_schema::*;
+use proxmox_router::list_subdirs_api_method;
use proxmox_http::websocket::WebSocket;
use proxmox_rest_server::WorkerTask;
use serde_json::{Value, to_value};
use ::serde::{Deserialize, Serialize};
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
-use proxmox::api::schema::parse_property_string;
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::{api, parse_property_string};
use pbs_api_types::{
Authid, Interface, NetworkInterfaceType, LinuxBondMode, NetworkConfigMethod, BondXmitHashPolicy,
use anyhow::Error;
-use proxmox::api::{api, ApiMethod, Permission, Router, RpcEnvironment};
use serde_json::{json, Value};
+use proxmox_router::{ApiMethod, Permission, Router, RpcEnvironment};
+use proxmox_schema::api;
+
use pbs_api_types::{NODE_SCHEMA, PRIV_SYS_AUDIT};
use crate::server::generate_report;
use anyhow::Error;
use serde_json::{Value, json};
-use proxmox::api::{api, Permission, Router};
+use proxmox_router::{Permission, Router};
+use proxmox_schema::api;
use pbs_api_types::{
NODE_SCHEMA, RRDMode, RRDTimeFrameResolution, PRIV_SYS_AUDIT,
) -> Result<Value, Error> {
let mut result = Vec::new();
- let now = proxmox::tools::time::epoch_f64();
+ let now = proxmox_time::epoch_f64();
for name in list {
let (start, reso, list) = match RRD_CACHE.extract_cached_data(basedir, name, now, timeframe, cf) {
use anyhow::{bail, Error};
use serde_json::{json, Value};
-use proxmox::{sortable, identity, list_subdirs_api_method};
-use proxmox::api::{api, Router, Permission, RpcEnvironment};
-use proxmox::api::router::SubdirMap;
+use proxmox::{sortable, identity};
+use proxmox_router::{list_subdirs_api_method, Router, Permission, RpcEnvironment, SubdirMap};
+use proxmox_schema::api;
use pbs_api_types::{Authid, NODE_SCHEMA, SERVICE_ID_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
use proxmox::sys::linux::procfs;
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{NODE_SCHEMA, NodePowerCommand, PRIV_SYS_AUDIT, PRIV_SYS_POWER_MANAGEMENT};
use anyhow::{Error, format_err, bail};
use serde_json::Value;
-use proxmox::api::{api, Router, RpcEnvironment, Permission};
+use proxmox_router::{Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{
NODE_SCHEMA, SUBSCRIPTION_KEY_SCHEMA, Authid,
};
if !force && info.status == SubscriptionStatus::ACTIVE {
- let age = proxmox::tools::time::epoch_i64() - info.checktime.unwrap_or(i64::MAX);
+ let age = proxmox_time::epoch_i64() - info.checktime.unwrap_or(i64::MAX);
if age < subscription::MAX_LOCAL_KEY_AGE {
return Ok(());
}
use anyhow::{Error};
use serde_json::{json, Value};
-use proxmox::api::{api, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
use pbs_api_types::{NODE_SCHEMA, SYSTEMD_DATETIME_FORMAT, PRIV_SYS_AUDIT};
use anyhow::{bail, Error};
use serde_json::{json, Value};
-use proxmox::api::{api, Router, RpcEnvironment, Permission};
-use proxmox::api::router::SubdirMap;
-use proxmox::{identity, list_subdirs_api_method, sortable};
+use proxmox::{identity, sortable};
+use proxmox_router::{list_subdirs_api_method, Router, RpcEnvironment, Permission, SubdirMap};
+use proxmox_schema::api;
use pbs_api_types::{
Userid, Authid, Tokenname, TaskListItem, TaskStateType, UPID,
use anyhow::{bail, format_err, Error};
use serde_json::{json, Value};
-use proxmox::api::{api, Router, Permission};
use proxmox::tools::fs::{file_read_firstline, replace_file, CreateOptions};
+use proxmox_router::{Router, Permission};
+use proxmox_schema::api;
use pbs_api_types::{NODE_SCHEMA, TIME_ZONE_SCHEMA, PRIV_SYS_MODIFY};
)]
/// Read server time and time zone settings.
fn get_time(_param: Value) -> Result<Value, Error> {
- let time = proxmox::tools::time::epoch_i64();
- let tm = proxmox::tools::time::localtime(time)?;
+ let time = proxmox_time::epoch_i64();
+ let tm = proxmox_time::localtime(time)?;
let offset = tm.tm_gmtoff;
let localtime = time + offset;
use anyhow::{Error};
use serde_json::{json, Value};
-use proxmox::api::{api, Router, Permission};
+use proxmox_router::{Router, Permission};
+use proxmox_schema::api;
#[api(
returns: {
use anyhow::{format_err, Error};
use futures::{select, future::FutureExt};
-use proxmox::api::api;
-use proxmox::api::{ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::api;
+use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission};
use pbs_client::{HttpClient, BackupRepository};
use pbs_api_types::{
use serde_json::{json, Value};
-use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
+use proxmox_router::{RpcEnvironment, RpcEnvironmentType};
use pbs_datastore::backup_info::BackupDir;
use pbs_datastore::DataStore;
use hyper::{Body, Response, Request, StatusCode};
use serde_json::Value;
-use proxmox::{
- http_err,
- sortable,
- identity,
- list_subdirs_api_method,
- api::{
- ApiResponseFuture,
- ApiHandler,
- ApiMethod,
- Router,
- RpcEnvironment,
- Permission,
- router::SubdirMap,
- schema::{
- ObjectSchema,
- BooleanSchema,
- },
- },
+use proxmox::{identity, sortable};
+use proxmox_router::{
+ http_err, list_subdirs_api_method, ApiHandler, ApiMethod, ApiResponseFuture, Permission,
+ Router, RpcEnvironment, SubdirMap,
};
+use proxmox_schema::{BooleanSchema, ObjectSchema};
use pbs_api_types::{
Authid, DATASTORE_SCHEMA, BACKUP_TYPE_SCHEMA, BACKUP_TIME_SCHEMA, BACKUP_ID_SCHEMA,
//! Datastote status
-use proxmox::list_subdirs_api_method;
-
use anyhow::{Error};
use serde_json::{json, Value};
-use proxmox::api::{
- api,
+use proxmox_schema::api;
+use proxmox_router::{
ApiMethod,
Permission,
Router,
RpcEnvironment,
SubdirMap,
};
+use proxmox_router::list_subdirs_api_method;
use pbs_api_types::{
Authid, DATASTORE_SCHEMA, RRDMode, RRDTimeFrameResolution,
});
let rrd_dir = format!("datastore/{}", store);
- let now = proxmox::tools::time::epoch_f64();
+ let now = proxmox_time::epoch_f64();
let get_rrd = |what: &str| RRD_CACHE.extract_cached_data(
&rrd_dir,
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::{
- try_block,
- api::{
- api,
- RpcEnvironment,
- RpcEnvironmentType,
- Router,
- Permission,
- },
-};
+use proxmox_lang::try_block;
+use proxmox_router::{Permission, Router, RpcEnvironment, RpcEnvironmentType};
+use proxmox_schema::api;
use pbs_api_types::{
Authid, Userid, TapeBackupJobConfig, TapeBackupJobSetup, TapeBackupJobStatus, MediaPoolConfig,
let mut list = Vec::new();
let status_path = Path::new(TAPE_STATUS_DIR);
- let current_time = proxmox::tools::time::epoch_i64();
+ let current_time = proxmox_time::epoch_i64();
for job in job_list_iter {
let privs = user_info.lookup_privs(&auth_id, &["tape", "job", &job.id]);
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, Router, SubdirMap, RpcEnvironment, Permission};
-use proxmox::list_subdirs_api_method;
+use proxmox_schema::api;
+use proxmox_router::{list_subdirs_api_method, Permission, Router, RpcEnvironment, SubdirMap};
use pbs_api_types::{
Authid, ChangerListEntry, LtoTapeDrive, MtxEntryKind, MtxStatusEntry, ScsiTapeChanger,
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::{
- sortable,
- identity,
- list_subdirs_api_method,
- tools::Uuid,
- api::{
- api,
- section_config::SectionConfigData,
- RpcEnvironment,
- RpcEnvironmentType,
- Permission,
- Router,
- SubdirMap,
- },
+use proxmox::{sortable, identity};
+use proxmox_router::{
+ list_subdirs_api_method, Permission, Router, RpcEnvironment, RpcEnvironmentType, SubdirMap,
};
+use proxmox_schema::api;
+use proxmox_section_config::SectionConfigData;
+use proxmox_uuid::Uuid;
use pbs_api_types::{
UPID_SCHEMA, CHANGER_NAME_SCHEMA, DRIVE_NAME_SCHEMA, MEDIA_LABEL_SCHEMA, MEDIA_POOL_NAME_SCHEMA,
}
}
- let ctime = proxmox::tools::time::epoch_i64();
+ let ctime = proxmox_time::epoch_i64();
let label = MediaLabel {
label_text: label_text.to_string(),
uuid: Uuid::generate(),
}
}
- let ctime = proxmox::tools::time::epoch_i64();
+ let ctime = proxmox_time::epoch_i64();
let label = MediaLabel {
label_text: label_text.to_string(),
uuid: Uuid::generate(),
use anyhow::{bail, format_err, Error};
-use proxmox::{
- api::{api, Router, SubdirMap, RpcEnvironment, Permission},
- list_subdirs_api_method,
- tools::Uuid,
-};
+use proxmox_router::{list_subdirs_api_method, Router, SubdirMap, RpcEnvironment, Permission};
+use proxmox_schema::api;
+use proxmox_uuid::Uuid;
use pbs_datastore::backup_info::BackupDir;
use pbs_api_types::{
let changer_name = None; // assume standalone drive
let mut pool = MediaPool::with_config(status_path, &config, changer_name, true)?;
- let current_time = proxmox::tools::time::epoch_i64();
+ let current_time = proxmox_time::epoch_i64();
// Call start_write_session, so that we show the same status a
// backup job would see.
use anyhow::Error;
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- router::SubdirMap,
- Router,
- },
- list_subdirs_api_method,
-};
+use proxmox_schema::api;
+use proxmox_router::{list_subdirs_api_method, Router, SubdirMap};
use pbs_api_types::TapeDeviceInfo;
use pbs_tape::linux_list_drives::{lto_tape_device_list, linux_tape_changer_list};
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- RpcEnvironment,
- RpcEnvironmentType,
- Router,
- Permission,
- schema::parse_property_string,
- section_config::SectionConfigData,
- },
- tools::{
- Uuid,
- io::ReadExt,
- fs::{
- replace_file,
- CreateOptions,
- },
- },
-};
+use proxmox::tools::fs::{replace_file, CreateOptions};
+use proxmox_io::ReadExt;
+use proxmox_router::{Permission, Router, RpcEnvironment, RpcEnvironmentType};
+use proxmox_schema::{api, parse_property_string};
+use proxmox_section_config::SectionConfigData;
+use proxmox_uuid::Uuid;
use pbs_api_types::{
Authid, Userid, CryptMode,
let mut snapshot_file_hash: BTreeMap<Uuid, Vec<u64>> = BTreeMap::new();
let mut snapshot_locks = HashMap::new();
- let res = proxmox::try_block!({
+ let res = proxmox_lang::try_block!({
// assemble snapshot files/locks
for store_snapshot in snapshots.iter() {
let mut split = store_snapshot.splitn(2, ':');
"Phase 3: copy snapshots from temp dir to datastores"
);
for (store_snapshot, _lock) in snapshot_locks.into_iter() {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut split = store_snapshot.splitn(2, ':');
let source_datastore = split
.next()
use serde::{Deserialize, Serialize};
use serde_json::Value;
-use proxmox::api::{api, schema::{ApiType, Schema, StringSchema, ApiStringFormat}};
+use proxmox_schema::{api, ApiType, Schema, StringSchema, ApiStringFormat};
use pbs_api_types::{
DNS_ALIAS_FORMAT, DNS_NAME_FORMAT, PROXMOX_SAFE_ID_FORMAT,
pub url: &'static str,
}
-proxmox::api_string_type! {
+proxmox_schema::api_string_type! {
#[api(format: &PROXMOX_SAFE_ID_FORMAT)]
/// ACME account name.
#[derive(Clone, Eq, PartialEq, Hash, Deserialize, Serialize)]
use anyhow::bail;
use serde::{Deserialize, Serialize};
-use proxmox::api::{api, schema::*};
+use proxmox_schema::*;
use pbs_api_types::StorageStatus;
use anyhow::{Error};
use serde_json::{json, Value};
-use proxmox::api::{ApiHandler, ApiMethod, Router, RpcEnvironment, Permission};
-use proxmox::api::schema::ObjectSchema;
+use proxmox_router::{ApiHandler, ApiMethod, Router, RpcEnvironment, Permission};
+use proxmox_schema::ObjectSchema;
fn get_version(
_param: Value,
use openssl::sha;
use proxmox::tools::fs::{file_get_contents, replace_file, CreateOptions};
-use proxmox::try_block;
+use proxmox_lang::try_block;
use pbs_buildcfg::configdir;
use pbs_api_types::Userid;
userid: &Userid,
) -> String {
- let epoch = proxmox::tools::time::epoch_i64();
+ let epoch = proxmox_time::epoch_i64();
let digest = compute_csrf_secret_digest(epoch, secret, userid);
bail!("invalid signature.");
}
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
let age = now - ttime;
if age < min_age {
let mut verify_result = VerifyState::Ok;
for info in manifest.files() {
- let result = proxmox::try_block!({
+ let result = proxmox_lang::try_block!({
task_log!(verify_worker.worker, " check {}", info.filename);
match archive_type(&info.filename)? {
ArchiveType::FixedIndex => verify_fixed_index(verify_worker, &backup_dir, info),
match outdated_after {
None => false, // never re-verify if ignored and no max age
Some(max_age) => {
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
let days_since_last_verify = (now - last_verify.upid.starttime) / 86400;
days_since_last_verify > max_age
use anyhow::{bail, Error};
use serde_json::{json, Value};
-use proxmox::{
- api::{
- schema::{
- ApiType,
- Schema,
- ObjectSchemaType,
- ApiStringFormat,
- },
- router::{
- ApiAccess,
- },
- format::{
- dump_enum_properties,
- dump_section_config,
- get_property_string_type_text,
- },
- ApiMethod,
- ApiHandler,
- Router,
- SubRoute,
- Permission,
- },
-};
+use proxmox_router::{ApiAccess, ApiHandler, ApiMethod, Permission, Router, SubRoute};
+use proxmox_schema::format::{dump_enum_properties, get_property_string_type_text};
+use proxmox_schema::{ApiStringFormat, ApiType, ObjectSchemaType, Schema};
+use proxmox_section_config::dump_section_config;
use pbs_api_types::PRIVILEGES;
use hyper::{Body, Method, StatusCode};
use http::HeaderMap;
-use proxmox::try_block;
-use proxmox::api::RpcEnvironmentType;
+use proxmox_lang::try_block;
+use proxmox_router::{RpcEnvironmentType, UserInformation};
use proxmox::tools::fs::CreateOptions;
-use proxmox::api::UserInformation;
use proxmox_rest_server::{daemon, AuthError, ApiConfig, RestServer, RestEnvironment, ServerAdapter};
-use proxmox::api::{
+use proxmox_router::{
cli::{run_cli_command, CliCommandMap, CliEnvironment},
RpcEnvironment,
};
use anyhow::{format_err, Error};
use serde_json::{json, Value};
-use proxmox::api::{api, cli::*, RpcEnvironment};
use proxmox::tools::fs::CreateOptions;
+use proxmox_router::{cli::*, RpcEnvironment};
+use proxmox_schema::api;
use pbs_client::{display_task_log, view_task_result};
use pbs_tools::percent_encoding::percent_encode_component;
let mut list = Vec::new();
- let _ = proxmox::try_block!({
+ let _ = proxmox_lang::try_block!({
let remote = param.get("remote").ok_or_else(|| format_err!("no remote"))?;
let data = pbs_runtime::block_on(async move {
use serde_json::{json, Value};
use http::{Method, HeaderMap};
-use proxmox::try_block;
-use proxmox::api::{RpcEnvironment, RpcEnvironmentType, UserInformation};
use proxmox::sys::linux::socket::set_tcp_keepalive;
use proxmox::tools::fs::CreateOptions;
+use proxmox_lang::try_block;
+use proxmox_router::{RpcEnvironment, RpcEnvironmentType, UserInformation};
use pbs_tools::{task_log, task_warn};
use pbs_datastore::DataStore;
}
};
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
if next > now { continue; }
}
};
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
next <= now
}
use anyhow::Error;
use serde_json::json;
-use proxmox::api::{cli::*, RpcEnvironment, ApiHandler};
use proxmox::tools::fs::CreateOptions;
+use proxmox_router::{cli::*, RpcEnvironment, ApiHandler};
use proxmox_backup::api2;
use proxmox_backup::tools::subscription;
use anyhow::{format_err, Error};
use serde_json::{json, Value};
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- section_config::SectionConfigData,
- },
- tools::{
- time::strftime_local,
- io::ReadExt,
- },
-};
+use proxmox_io::ReadExt;
+use proxmox_router::RpcEnvironment;
+use proxmox_router::cli::*;
+use proxmox_schema::api;
+use proxmox_section_config::SectionConfigData;
+use proxmox_time::strftime_local;
use pbs_client::view_task_result;
use pbs_tools::format::{
use std::collections::HashMap;
-use proxmox::api::{
- api,
- cli::*,
- format::DocumentationFormat,
- schema::{parse_parameter_strings, ApiType, ParameterSchema, Schema},
- ApiHandler, ApiMethod, RpcEnvironment, SubRoute,
-};
+use proxmox_router::{cli::*, ApiHandler, ApiMethod, RpcEnvironment, SubRoute};
+use proxmox_schema::{api, parse_parameter_strings, ApiType, ParameterSchema, Schema};
+use proxmox_schema::format::DocumentationFormat;
use pbs_api_types::{PROXMOX_UPID_REGEX, UPID};
use pbs_client::view_task_result;
capabilities: String,
}
-const LS_SCHEMA: &proxmox::api::schema::Schema =
- &proxmox::api::schema::ArraySchema::new("List of child links", &ApiDirEntry::API_SCHEMA)
+const LS_SCHEMA: &proxmox_schema::Schema =
+ &proxmox_schema::ArraySchema::new("List of child links", &ApiDirEntry::API_SCHEMA)
.schema();
async fn get_api_children(
format_and_print_result_full(
&mut serde_json::to_value(res)?,
- &proxmox::api::schema::ReturnType {
+ &proxmox_schema::ReturnType {
optional: false,
schema: &LS_SCHEMA,
},
use serde_json::{json, Value};
use walkdir::WalkDir;
-use proxmox::api::cli::{
+use proxmox_router::cli::{
format_and_print_result, get_output_format, CliCommand, CliCommandMap, CommandLineInterface,
+ OUTPUT_FORMAT,
};
-use proxmox::api::{api, cli::*};
+use proxmox_schema::api;
use pbs_tools::cli::outfile_or_stdout;
use pbs_tools::crypt_config::CryptConfig;
};
let mut ctime_str = index.index_ctime().to_string();
- if let Ok(s) = proxmox::tools::time::strftime_local("%c", index.index_ctime()) {
+ if let Ok(s) = proxmox_time::strftime_local("%c", index.index_ctime()) {
ctime_str = s;
}
use anyhow::{bail, format_err, Error};
use serde_json::Value;
-use proxmox::api::api;
-use proxmox::api::cli::{CliCommand, CliCommandMap, CommandLineInterface};
use proxmox::tools::digest_to_hex;
+use proxmox_router::cli::{CliCommand, CliCommandMap, CommandLineInterface};
+use proxmox_schema::api;
use pbs_tools::crypt_config::CryptConfig;
use pbs_datastore::dynamic_index::DynamicIndexReader;
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use proxmox_backup::api2;
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::api::{api, cli::*, ApiHandler, RpcEnvironment};
use proxmox::tools::fs::file_get_contents;
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use proxmox_backup::acme::AcmeClient;
use proxmox_backup::api2;
use anyhow::{bail, Error};
-use proxmox::api::{api, cli::*};
+use proxmox_router::cli::*;
+use proxmox_schema::api;
use proxmox_backup::config;
use proxmox_backup::auth_helpers::*;
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_client::view_task_result;
use pbs_api_types::{DataStoreConfig, DATASTORE_SCHEMA};
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::{
DISK_LIST_SCHEMA, ZFS_ASHIFT_SCHEMA, ZfsRaidLevel, ZfsCompressionType,
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use proxmox_backup::api2;
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use proxmox_backup::api2;
-use proxmox::api::{api, cli::*, ApiHandler, RpcEnvironment};
use anyhow::Error;
use serde_json::Value;
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
+
use proxmox_backup::api2;
#[api(
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::REALM_ID_SCHEMA;
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::REMOTE_ID_SCHEMA;
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use proxmox_backup::api2;
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::JOB_ID_SCHEMA;
use std::collections::HashMap;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::{ACL_PATH_SCHEMA, Authid, Userid};
let text = match value.as_i64() {
Some(epoch) if epoch == 0 => never,
Some(epoch) => {
- if let Ok(epoch_string) = proxmox::tools::time::strftime_local("%c", epoch as i64) {
+ if let Ok(epoch_string) = proxmox_time::strftime_local("%c", epoch as i64) {
epoch_string
} else {
epoch.to_string()
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::JOB_ID_SCHEMA;
use anyhow::Error;
use serde_json::Value;
-use proxmox::api::{api, cli::*, RpcEnvironment, ApiHandler};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::JOB_ID_SCHEMA;
use pbs_client::view_task_result;
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- ApiHandler,
- section_config::SectionConfigData,
- },
-};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
+use proxmox_section_config::SectionConfigData;
use pbs_config::drive::{
complete_drive_name,
use anyhow::Error;
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- ApiHandler,
- },
-};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::DRIVE_NAME_SCHEMA;
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- ApiHandler,
- },
- sys::linux::tty,
-};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
+use proxmox::sys::linux::tty;
use pbs_api_types::{
Fingerprint, Kdf, DRIVE_NAME_SCHEMA, TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
_ => unreachable!(),
};
- let options = proxmox::api::cli::default_table_format_options()
+ let options = proxmox_router::cli::default_table_format_options()
.column(ColumnConfig::new("kdf"))
.column(ColumnConfig::new("created").renderer(pbs_tools::format::render_epoch))
.column(ColumnConfig::new("modified").renderer(pbs_tools::format::render_epoch))
use anyhow::{Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- ApiHandler,
- },
-};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::{
MEDIA_POOL_NAME_SCHEMA, CHANGER_NAME_SCHEMA, MediaStatus, MediaListEntry,
use anyhow::{Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- ApiHandler,
- },
-};
+use proxmox_router::{cli::*, ApiHandler, RpcEnvironment};
+use proxmox_schema::api;
use pbs_api_types::MEDIA_POOL_NAME_SCHEMA;
use pbs_config::media_pool::complete_pool_name;
use anyhow::{bail, Error};
use serde_json::Value;
-use proxmox::{
- api::{
- api,
- cli::*,
- RpcEnvironment,
- },
- tools::Uuid,
-};
+use proxmox_router::{cli::*, RpcEnvironment};
+use proxmox_schema::api;
+use proxmox_uuid::Uuid;
use pbs_api_types::{
Fingerprint, LTO_DRIVE_PATH_SCHEMA, DRIVE_NAME_SCHEMA, TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
param: Value,
) -> Result<(), Error> {
- let result = proxmox::try_block!({
+ let result = proxmox_lang::try_block!({
let mut handle = get_tape_handle(¶m)?;
match (fingerprint, uuid) {
use serde::{Deserialize, Serialize};
use serde_json::Value;
-use proxmox::api::{
- api,
- schema::*,
- section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin},
-};
+use proxmox_schema::{api, ApiType, Schema, StringSchema, Updater};
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use pbs_config::{open_backup_lockfile, BackupLockGuard};
use pbs_api_types::PROXMOX_SAFE_ID_FORMAT;
use openssl::x509::{X509Builder};
use openssl::pkey::PKey;
-use proxmox::try_block;
+use proxmox_lang::try_block;
use pbs_buildcfg::{self, configdir};
// we try to generate an unique 'subject' to avoid browser problems
//(reused serial numbers, ..)
- let uuid = proxmox::tools::uuid::Uuid::generate();
+ let uuid = proxmox_uuid::Uuid::generate();
let mut subject_name = openssl::x509::X509NameBuilder::new()?;
subject_name.append_entry_by_text("O", "Proxmox Backup Server")?;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
-use proxmox::api::api;
-use proxmox::api::schema::{ApiStringFormat, ApiType, Updater};
+use proxmox_schema::{api, ApiStringFormat, ApiType, Updater};
use proxmox_http::ProxyConfig;
use webauthn_rs::proto::Credential as WebauthnCredential;
-use proxmox::api::api;
-use proxmox::api::schema::Updater;
use proxmox::sys::error::SysError;
use proxmox::tools::fs::CreateOptions;
-use proxmox::tools::tfa::totp::Totp;
-use proxmox::tools::tfa::u2f;
-use proxmox::tools::uuid::Uuid;
-use proxmox::tools::AsHex;
+use proxmox_schema::{api, Updater};
+use proxmox_tfa::{totp::Totp, u2f};
+use proxmox_uuid::Uuid;
use pbs_buildcfg::configdir;
use pbs_config::{open_backup_lockfile, BackupLockGuard};
}
/// Remove non-existent users.
- pub fn cleanup_users(&mut self, config: &proxmox::api::section_config::SectionConfigData) {
+ pub fn cleanup_users(&mut self, config: &proxmox_section_config::SectionConfigData) {
self.users
.retain(|user, _| config.lookup::<User>("user", user.as_str()).is_ok());
}
id: Uuid::generate().to_string(),
enable: true,
description,
- created: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
},
entry,
}
Self {
challenge,
description,
- created: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
}
}
}
state,
challenge,
description,
- created: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
}
}
}
Self {
state,
challenge,
- created: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
}
}
}
challenge: &str,
response: &str,
) -> Result<TfaEntry<u2f::Registration>, Error> {
- let expire_before = proxmox::tools::time::epoch_i64() - CHALLENGE_TIMEOUT;
+ let expire_before = proxmox_time::epoch_i64() - CHALLENGE_TIMEOUT;
let index = self
.inner
response: webauthn_rs::proto::RegisterPublicKeyCredential,
existing_registrations: &[TfaEntry<WebauthnCredential>],
) -> Result<TfaEntry<WebauthnCredential>, Error> {
- let expire_before = proxmox::tools::time::epoch_i64() - CHALLENGE_TIMEOUT;
+ let expire_before = proxmox_time::epoch_i64() - CHALLENGE_TIMEOUT;
let index = self
.inner
mut webauthn: Webauthn<WebauthnConfig>,
mut response: Value,
) -> Result<(), Error> {
- let expire_before = proxmox::tools::time::epoch_i64() - CHALLENGE_TIMEOUT;
+ let expire_before = proxmox_time::epoch_i64() - CHALLENGE_TIMEOUT;
let challenge = match response
.as_object_mut()
proxmox::sys::linux::fill_with_random_data(&mut secret)?;
let mut this = Self {
- secret: AsHex(&secret).to_string(),
+ secret: hex::encode(&secret).to_string(),
entries: Vec::with_capacity(10),
- created: proxmox::tools::time::epoch_i64(),
+ created: proxmox_time::epoch_i64(),
};
let mut original = Vec::new();
let mut key_data = [0u8; 80]; // 10 keys of 12 bytes
proxmox::sys::linux::fill_with_random_data(&mut key_data)?;
for b in key_data.chunks(8) {
+ // unwrap: encoding hex bytes to fixed sized arrays
let entry = format!(
- "{}-{}-{}-{}",
- AsHex(&b[0..2]),
- AsHex(&b[2..4]),
- AsHex(&b[4..6]),
- AsHex(&b[6..8]),
+ "{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}-{:02x}{:02x}",
+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
);
-
this.entries.push(Some(this.hash(entry.as_bytes())?));
original.push(entry);
}
.sign_oneshot_to_vec(data)
.map_err(|err| format_err!("error calculating hmac: {}", err))?;
- Ok(AsHex(&hmac).to_string())
+ Ok(hex::encode(&hmac))
}
/// Iterator over available keys.
D: Deserializer<'de>,
T: Deserialize<'de> + IsExpired,
{
- let expire_before = proxmox::tools::time::epoch_i64() - CHALLENGE_TIMEOUT;
+ let expire_before = proxmox_time::epoch_i64() - CHALLENGE_TIMEOUT;
Ok(
deserializer.deserialize_seq(crate::tools::serde_filter::FilteredVecVisitor::new(
"a challenge entry",
use anyhow::format_err;
-use proxmox::api::UserInformation;
+use proxmox_router::UserInformation;
use pbs_tools::ticket::{self, Ticket};
use pbs_config::{token_shadow, CachedUserInfo};
use handlebars::{Handlebars, Helper, Context, RenderError, RenderContext, Output, HelperResult, TemplateError};
use proxmox::tools::email::sendmail;
-use proxmox::api::schema::{ApiType, parse_property_string};
-use proxmox::try_block;
+use proxmox_lang::try_block;
+use proxmox_schema::{parse_property_string, ApiType};
use pbs_tools::format::HumanByte;
use pbs_api_types::{
Ok(job) => job,
Err(_) => return Ok(()), // was locked (running), so do not update
};
- let time = proxmox::tools::time::epoch_i64();
+ let time = proxmox_time::epoch_i64();
job.state = match JobState::load(jobtype, jobname)? {
JobState::Created { .. } => JobState::Created { time },
}
} else {
Ok(JobState::Created {
- time: proxmox::tools::time::epoch_i64() - 30,
+ time: proxmox_time::epoch_i64() - 30,
})
}
}
jobtype: jobtype.to_string(),
jobname: jobname.to_string(),
state: JobState::Created {
- time: proxmox::tools::time::epoch_i64(),
+ time: proxmox_time::epoch_i64(),
},
_lock,
})
use anyhow::{bail, format_err, Error};
use serde_json::json;
+use http::StatusCode;
-use proxmox::api::error::{HttpError, StatusCode};
+use proxmox_router::HttpError;
use pbs_api_types::{Authid, SnapshotListItem, GroupListItem};
use pbs_datastore::{DataStore, BackupInfo, BackupDir, BackupGroup, StoreProgress};
let tmp_manifest_blob = DataBlob::load_from_reader(&mut tmp_manifest_file)?;
if manifest_name.exists() {
- let manifest_blob = proxmox::try_block!({
+ let manifest_blob = proxmox_lang::try_block!({
let mut manifest_file = std::fs::File::open(&manifest_name).map_err(|err| {
format_err!(
"unable to open local manifest {:?} - {}",
fn affected(&self) -> Result<String, Error> {
match self.count {
0 => Ok(String::new()),
- 1 => proxmox::tools::time::epoch_to_rfc3339_utc(self.oldest),
+ 1 => Ok(proxmox_time::epoch_to_rfc3339_utc(self.oldest)?),
_ => {
Ok(format!(
"{} .. {}",
- proxmox::tools::time::epoch_to_rfc3339_utc(self.oldest)?,
- proxmox::tools::time::epoch_to_rfc3339_utc(self.newest)?,
+ proxmox_time::epoch_to_rfc3339_utc(self.oldest)?,
+ proxmox_time::epoch_to_rfc3339_utc(self.newest)?,
))
}
}
}
if delete {
- let result: Result<(), Error> = proxmox::try_block!({
+ let result: Result<(), Error> = proxmox_lang::try_block!({
let local_groups = BackupInfo::list_backup_groups(&tgt_store.base_path())?;
for local_group in local_groups {
if new_groups.contains(&local_group) {
use anyhow::{bail, Error};
-use proxmox::tools::Uuid;
-use proxmox::api::section_config::SectionConfigData;
+use proxmox_section_config::SectionConfigData;
+use proxmox_uuid::Uuid;
use pbs_api_types::{VirtualTapeDrive, ScsiTapeChanger};
use pbs_tape::{ElementStatus, MtxStatus};
use anyhow::{bail, format_err, Error};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use pbs_api_types::{
Fingerprint, MamAttribute, LtoDriveAndMediaStatus, LtoTapeDrive, Lp17VolumeStatistics,
/// - for autoloader only, try to reload ejected tapes
pub fn open_lto_tape_drive(config: &LtoTapeDrive) -> Result<LtoTapeHandle, Error> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let file = open_lto_tape_device(&config.path)?;
let mut handle = LtoTapeHandle::new(file)?;
use std::path::PathBuf;
use anyhow::{bail, format_err, Error};
-use ::serde::{Deserialize};
+use serde::Deserialize;
use serde_json::Value;
use nix::fcntl::OFlag;
use nix::sys::stat::Mode;
use proxmox::{
tools::{
- Uuid,
- io::ReadExt,
fs::{
lock_file,
atomic_open_or_create_file,
CreateOptions,
}
},
- api::section_config::SectionConfigData,
};
+use proxmox_io::ReadExt;
+use proxmox_section_config::SectionConfigData;
+use proxmox_uuid::Uuid;
use pbs_api_types::{VirtualTapeDrive, LtoTapeDrive, Fingerprint};
use pbs_config::key_config::KeyConfig;
MediaId,
), Error> {
- let check_label = |handle: &mut dyn TapeDriver, uuid: &proxmox::tools::Uuid| {
+ let check_label = |handle: &mut dyn TapeDriver, uuid: &proxmox_uuid::Uuid| {
if let Ok((Some(media_id), _)) = handle.read_label() {
task_log!(
worker,
/// This needs to lock the drive
pub fn open_virtual_tape_drive(config: &VirtualTapeDrive) -> Result<VirtualTapeHandle, Error> {
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let mut lock_path = std::path::PathBuf::from(&config.path);
lock_path.push(".drive.lck");
use std::fs::File;
use std::io::Read;
-use proxmox::{
- sys::error::SysError,
- tools::Uuid,
-};
+use proxmox::sys::error::SysError;
+use proxmox_uuid::Uuid;
use pbs_tape::{
PROXMOX_TAPE_BLOCK_SIZE,
return Ok(None);
}
- let mut file_copy_buffer = proxmox::tools::vec::undefined(PROXMOX_TAPE_BLOCK_SIZE);
+ let mut file_copy_buffer = proxmox_io::vec::undefined(PROXMOX_TAPE_BLOCK_SIZE);
- let result: Result<(), std::io::Error> = proxmox::try_block!({
+ let result: Result<(), std::io::Error> = proxmox_lang::try_block!({
let file_size = file.metadata()?.len();
let mut remaining = file_size;
use anyhow::{bail, Error};
use endian_trait::Endian;
-use proxmox::tools::{
- Uuid,
- io::ReadExt,
-};
+use proxmox_io::ReadExt;
+use proxmox_uuid::Uuid;
use pbs_datastore::DataBlob;
use pbs_tape::{
use endian_trait::Endian;
use serde::{Deserialize, Serialize};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use pbs_api_types::Fingerprint;
use anyhow::{bail, Error};
-use proxmox::tools::io::ReadExt;
+use proxmox_io::ReadExt;
use pbs_tape::{TapeRead, MediaContentHeader};
let mut reader = (self.next_reader_fn)()
.map_err(|err| proxmox::io_format_err!("multi-volume next failed: {}", err))?;
- proxmox::try_block!({
+ proxmox_lang::try_block!({
let part_header: MediaContentHeader = unsafe { reader.read_le_value()? };
self.reader = Some(reader);
use anyhow::Error;
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use pbs_tape::{TapeWrite, MediaContentHeader};
use std::pin::Pin;
use std::task::{Context, Poll};
-use proxmox::{
- sys::error::SysError,
- tools::Uuid,
-};
+use proxmox::sys::error::SysError;
+use proxmox_uuid::Uuid;
use pbs_tape::{
PROXMOX_TAPE_BLOCK_SIZE,
let root_metadata = pxar::Metadata::dir_builder(0o0664).build();
- let mut file_copy_buffer = proxmox::tools::vec::undefined(PROXMOX_TAPE_BLOCK_SIZE);
+ let mut file_copy_buffer = proxmox_io::vec::undefined(PROXMOX_TAPE_BLOCK_SIZE);
- let result: Result<(), std::io::Error> = proxmox::try_block!({
+ let result: Result<(), std::io::Error> = proxmox_lang::try_block!({
let leom = writer.write_header(&header, &header_data)?;
if leom {
use serde::{Serialize, Deserialize};
use serde_json::json;
-use proxmox::tools::{
- Uuid,
- fs::{
- replace_file,
- file_get_json,
- CreateOptions,
- },
-};
+use proxmox::tools::fs::{replace_file, file_get_json, CreateOptions};
+use proxmox_uuid::Uuid;
use proxmox_systemd::time::compute_next_event;
use pbs_config::BackupLockGuard;
if let Some(ctime) = self.media_set_start_time(media_set_uuid) {
let mut template = template.unwrap_or_else(|| String::from("%c"));
template = template.replace("%id%", &media_set_uuid.to_string());
- proxmox::tools::time::strftime_local(&template, ctime)
+ Ok(proxmox_time::strftime_local(&template, ctime)?)
} else {
// We don't know the set start time, so we cannot use the template
Ok(media_set_uuid.to_string())
use pbs_tools::fs::read_subdir;
use pbs_datastore::backup_info::BackupDir;
-use proxmox::tools::{
- Uuid,
- fs::{
- fchown,
- create_path,
- CreateOptions,
- },
- io::{
- WriteExt,
- ReadExt,
- },
+use proxmox::tools::fs::{
+ fchown,
+ create_path,
+ CreateOptions,
};
+use proxmox_io::{WriteExt, ReadExt};
+use proxmox_uuid::Uuid;
use crate::{
tape::{
let path = Self::catalog_path(base_path, uuid);
- let me = proxmox::try_block!({
+ let me = proxmox_lang::try_block!({
Self::create_basedir(base_path)?;
let tmp_path = Self::tmp_catalog_path(base_path, uuid);
- let me = proxmox::try_block!({
+ let me = proxmox_lang::try_block!({
let file = Self::create_temporary_database_file(base_path, uuid)?;
let pending = &self.pending;
// Note: lock file, to get a consistent view with load_catalog
nix::fcntl::flock(file.as_raw_fd(), nix::fcntl::FlockArg::LockExclusive)?;
- let result: Result<(), Error> = proxmox::try_block!({
+ let result: Result<(), Error> = proxmox_lang::try_block!({
file.write_all(pending)?;
file.flush()?;
file.sync_data()?;
use anyhow::{bail, Error};
use serde::{Deserialize, Serialize};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use pbs_api_types::{
Fingerprint, MediaStatus, MediaLocation, MediaSetPolicy, RetentionPolicy,
use anyhow::{bail, Error};
use serde::{Serialize, Deserialize};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
/// MediaSet - Ordered group of media
#[derive(Debug, Serialize, Deserialize)]
use anyhow::{bail, Error};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use crate::{
tape::{
use anyhow::{bail, Error};
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use pbs_tools::{task_log, task_warn};
use pbs_config::tape_encryption_keys::load_key_configs;
force_media_set: bool,
) -> Result<Self, Error> {
- let current_time = proxmox::tools::time::epoch_i64();
+ let current_time = proxmox_time::epoch_i64();
let new_media_set_reason = pool.start_write_session(current_time, force_media_set)?;
if let Some(reason) = new_media_set_reason {
None => None,
};
- let current_time = proxmox::tools::time::epoch_i64();
+ let current_time = proxmox_time::epoch_i64();
let media_uuid = self.pool.alloc_writable_media(current_time)?;
let media = self.pool.lookup_media(&media_uuid).unwrap();
let datastore_name = snapshot_reader.datastore_name();
- let result: Result<(), Error> = proxmox::try_block!({
+ let result: Result<(), Error> = proxmox_lang::try_block!({
let mut chunk_iter = snapshot_reader.chunk_iterator()?;
use std::path::PathBuf;
use anyhow::Error;
-use proxmox::tools::{
- Uuid,
-};
+use proxmox_uuid::Uuid;
use pbs_api_types::{MediaStatus, MediaSetPolicy, RetentionPolicy};
use std::path::PathBuf;
use anyhow::Error;
-use proxmox::tools::Uuid;
+use proxmox_uuid::Uuid;
use pbs_api_types::{RetentionPolicy, MediaSetPolicy};
use std::path::PathBuf;
use anyhow::{bail, Error};
-use proxmox::tools::{
- Uuid,
-};
+use proxmox_uuid::Uuid;
use pbs_api_types::{MediaLocation, MediaStatus};
use anyhow::{Error, bail, format_err};
use apt_pkg_native::Cache;
-use proxmox::const_regex;
use proxmox::tools::fs::{file_read_optional_string, replace_file, CreateOptions};
+use proxmox_schema::const_regex;
use pbs_api_types::APTUpdateInfo;
use serde::{Deserialize, Serialize};
use serde_json::Value;
-use proxmox::api::schema::{
+use proxmox_schema::{
parse_property_string, parse_simple_value, verify_json_object, ObjectSchemaType, Schema,
};
#[test]
fn test() {
- use proxmox::api::schema::ApiType;
+ use proxmox_schema::ApiType;
// let's just reuse some schema we actually have available:
use crate::config::node::NodeConfig;
use proxmox::sys::error::io_err_other;
use proxmox::sys::linux::procfs::{MountInfo, mountinfo::Device};
use proxmox::{io_bail, io_format_err};
-use proxmox::api::api;
+use proxmox_schema::api;
use pbs_api_types::{BLOCKDEVICE_NAME_REGEX, StorageStatus};
use anyhow::{bail, Error};
use ::serde::{Deserialize, Serialize};
-use proxmox::api::api;
+use proxmox_schema::api;
#[api()]
#[derive(Debug, Serialize, Deserialize)]
/// where
/// D: Deserializer<'de>,
/// {
-/// let expire_before = proxmox::tools::time::epoch_i64() - CHALLENGE_TIMEOUT;
+/// let expire_before = proxmox_time::epoch_i64() - CHALLENGE_TIMEOUT;
///
/// Ok(deserializer.deserialize_seq(
/// FilteredVecVisitor::new(
use serde::{Deserialize, Serialize};
use serde_json::json;
-use proxmox::api::api;
+use proxmox_schema::api;
use proxmox::tools::fs::{replace_file, CreateOptions};
use proxmox_http::client::SimpleHttp;
/// queries the up to date subscription status and parses the response
pub fn check_subscription(key: String, server_id: String) -> Result<SubscriptionInfo, Error> {
- let now = proxmox::tools::time::epoch_i64();
+ let now = proxmox_time::epoch_i64();
let (response, challenge) = pbs_runtime::block_on(register_subscription(&key, &server_id, now))
.map_err(|err| format_err!("Error checking subscription: {}", err))?;
}));
}
- let age = proxmox::tools::time::epoch_i64() - info.checktime.unwrap_or(0);
+ let age = proxmox_time::epoch_i64() - info.checktime.unwrap_or(0);
if age < -5400 { // allow some delta for DST changes or time syncs, 1.5h
return Ok(Some( SubscriptionInfo {
status: SubscriptionStatus::INVALID,
use super::types::*;
-use proxmox::api::{
- schema::*,
- section_config::{
- SectionConfig,
- SectionConfigData,
- SectionConfigPlugin,
- }
-};
+use proxmox_schema::*;
+use proxmox_section_config::{SectionConfig, SectionConfigData, SectionConfigPlugin};
use proxmox::tools::{fs::replace_file, fs::CreateOptions};
use serde::{Serialize, Deserialize};
-use proxmox::api::{ api, schema::* };
+use proxmox_schema::*;
use pbs_api_types::SINGLE_LINE_COMMENT_FORMAT;
pub const SYSTEMD_SECTION_NAME_SCHEMA: Schema = StringSchema::new(
-use anyhow::{bail, Error};
use std::sync::Arc;
use std::io::Cursor;
use std::io::{Read, Write, Seek, SeekFrom };
+
+use anyhow::{bail, Error};
use lazy_static::lazy_static;
use pbs_tools::crypt_config::CryptConfig;
use std::process::Command;
-use anyhow::{Error};
+use anyhow::Error;
use pbs_client::pxar::*;
-use anyhow::{Error};
use std::path::PathBuf;
+use anyhow::Error;
+
use pbs_api_types::PruneOptions;
use pbs_datastore::manifest::MANIFEST_BLOB_NAME;
use pbs_datastore::prune::compute_prune_info;
use anyhow::{bail, format_err, Error};
+use proxmox_schema::*;
+use proxmox_router::{ApiMethod, Permission, Router, SubdirMap, SubRoute};
+
use proxmox_backup::api2;
-use proxmox::api::*;
-use proxmox::api::schema::*;
// Simply test if api lookup tables inside Routers and Schemas are
// correctly sorted.
extern crate tokio;
extern crate nix;
-use proxmox::try_block;
use proxmox::tools::fs::CreateOptions;
+use proxmox_lang::try_block;
use pbs_api_types::{Authid, UPID};
use pbs_tools::{task_log, task::WorkerTaskContext};