use proxmox_backup::api2::version;
use proxmox_backup::client::*;
use proxmox_backup::pxar::catalog::*;
+use proxmox_backup::config::user::complete_user_name;
use proxmox_backup::backup::{
archive_type,
decrypt_key,
result
}
-fn connect(server: &str, userid: &Userid) -> Result<HttpClient, Error> {
+fn connect(server: &str, port: u16, userid: &Userid) -> Result<HttpClient, Error> {
let fingerprint = std::env::var(ENV_VAR_PBS_FINGERPRINT).ok();
.fingerprint_cache(true)
.ticket_cache(true);
- HttpClient::new(server, userid, options)
+ HttpClient::new(server, port, userid, options)
}
async fn view_task_result(
let repo = extract_repository_from_value(¶m)?;
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/groups", repo.store());
Ok(Value::Null)
}
+#[api(
+ input: {
+ properties: {
+ repository: {
+ schema: REPO_URL_SCHEMA,
+ optional: true,
+ },
+ group: {
+ type: String,
+ description: "Backup group.",
+ },
+ "new-owner": {
+ type: Userid,
+ },
+ }
+ }
+)]
+/// Change owner of a backup group
+async fn change_backup_owner(group: String, mut param: Value) -> Result<(), Error> {
+
+ let repo = extract_repository_from_value(¶m)?;
+
+ let mut client = connect(repo.host(), repo.port(), repo.user())?;
+
+ param.as_object_mut().unwrap().remove("repository");
+
+ let group: BackupGroup = group.parse()?;
+
+ param["backup-type"] = group.backup_type().into();
+ param["backup-id"] = group.backup_id().into();
+
+ let path = format!("api2/json/admin/datastore/{}/change-owner", repo.store());
+ client.post(&path, Some(param)).await?;
+
+ record_repository(&repo);
+
+ Ok(())
+}
+
#[api(
input: {
properties: {
let output_format = get_output_format(¶m);
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
let group: Option<BackupGroup> = if let Some(path) = param["group"].as_str() {
Some(path.parse()?)
.sortby("backup-id", false)
.sortby("backup-time", false)
.column(ColumnConfig::new("backup-id").renderer(render_snapshot_path).header("snapshot"))
- .column(ColumnConfig::new("size"))
+ .column(ColumnConfig::new("size").renderer(tools::format::render_bytes_human_readable))
.column(ColumnConfig::new("files").renderer(render_files))
;
let path = tools::required_string_param(¶m, "snapshot")?;
let snapshot: BackupDir = path.parse()?;
- let mut client = connect(repo.host(), repo.user())?;
+ let mut client = connect(repo.host(), repo.port(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/snapshots", repo.store());
let repo = extract_repository_from_value(¶m)?;
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
client.login().await?;
record_repository(&repo);
let repo = extract_repository_from_value(¶m);
if let Ok(repo) = repo {
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
match client.get("api2/json/version", None).await {
Ok(mut result) => version_info["server"] = result["data"].take(),
let output_format = get_output_format(¶m);
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/files", repo.store());
let output_format = get_output_format(¶m);
- let mut client = connect(repo.host(), repo.user())?;
+ let mut client = connect(repo.host(), repo.port(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/gc", repo.store());
let backup_time = backup_time_opt.unwrap_or_else(|| epoch_i64());
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
record_repository(&repo);
println!("Starting backup: {}/{}/{}", backup_type, backup_id, BackupDir::backup_time_to_string(backup_time)?);
let archive_name = tools::required_string_param(¶m, "archive-name")?;
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
record_repository(&repo);
let snapshot = tools::required_string_param(¶m, "snapshot")?;
let snapshot: BackupDir = snapshot.parse()?;
- let mut client = connect(repo.host(), repo.user())?;
+ let mut client = connect(repo.host(), repo.port(), repo.user())?;
let (keydata, crypt_mode) = keyfile_parameters(¶m)?;
async fn prune_async(mut param: Value) -> Result<Value, Error> {
let repo = extract_repository_from_value(¶m)?;
- let mut client = connect(repo.host(), repo.user())?;
+ let mut client = connect(repo.host(), repo.port(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/prune", repo.store());
optional: true,
},
}
- }
+ },
+ returns: {
+ type: StorageStatus,
+ },
)]
/// Get repository status.
async fn status(param: Value) -> Result<Value, Error> {
let output_format = get_output_format(¶m);
- let client = connect(repo.host(), repo.user())?;
+ let client = connect(repo.host(), repo.port(), repo.user())?;
let path = format!("api2/json/admin/datastore/{}/status", repo.store());
let mut result = client.get(&path, None).await?;
- let mut data = result["data"].take();
+ let mut data = result["data"]["storage"].take();
record_repository(&repo);
.column(ColumnConfig::new("used").renderer(render_total_percentage))
.column(ColumnConfig::new("avail").renderer(render_total_percentage));
- let schema = &proxmox_backup::api2::admin::datastore::API_RETURN_SCHEMA_STATUS;
+ let schema = &API_RETURN_SCHEMA_STATUS;
format_and_print_result_full(&mut data, schema, &output_format, &options);
.fingerprint_cache(true)
.ticket_cache(true);
- let client = match HttpClient::new(repo.host(), repo.user(), options) {
+ let client = match HttpClient::new(repo.host(), repo.port(), repo.user(), options) {
Ok(v) => v,
_ => return Value::Null,
};
fn complete_archive_name(arg: &str, param: &HashMap<String, String>) -> Vec<String> {
complete_server_file_name(arg, param)
.iter()
- .map(|v| tools::format::strip_server_file_expenstion(&v))
+ .map(|v| tools::format::strip_server_file_extension(&v))
.collect()
}
pub fn complete_pxar_archive_name(arg: &str, param: &HashMap<String, String>) -> Vec<String> {
complete_server_file_name(arg, param)
.iter()
- .filter_map(|v| {
- let name = tools::format::strip_server_file_expenstion(&v);
- if name.ends_with(".pxar") {
- Some(name)
+ .filter_map(|name| {
+ if name.ends_with(".pxar.didx") {
+ Some(tools::format::strip_server_file_extension(name))
+ } else {
+ None
+ }
+ })
+ .collect()
+}
+
+pub fn complete_img_archive_name(arg: &str, param: &HashMap<String, String>) -> Vec<String> {
+ complete_server_file_name(arg, param)
+ .iter()
+ .filter_map(|name| {
+ if name.ends_with(".img.fidx") {
+ Some(tools::format::strip_server_file_extension(name))
} else {
None
}
let version_cmd_def = CliCommand::new(&API_METHOD_API_VERSION)
.completion_cb("repository", complete_repository);
+ let change_owner_cmd_def = CliCommand::new(&API_METHOD_CHANGE_BACKUP_OWNER)
+ .arg_param(&["group", "new-owner"])
+ .completion_cb("group", complete_backup_group)
+ .completion_cb("new-owner", complete_user_name)
+ .completion_cb("repository", complete_repository);
+
let cmd_def = CliCommandMap::new()
.insert("backup", backup_cmd_def)
.insert("upload-log", upload_log_cmd_def)
.insert("status", status_cmd_def)
.insert("key", key::cli())
.insert("mount", mount_cmd_def())
+ .insert("map", map_cmd_def())
+ .insert("unmap", unmap_cmd_def())
.insert("catalog", catalog_mgmt_cli())
.insert("task", task_mgmt_cli())
.insert("version", version_cmd_def)
- .insert("benchmark", benchmark_cmd_def);
+ .insert("benchmark", benchmark_cmd_def)
+ .insert("change-owner", change_owner_cmd_def);
let rpcenv = CliEnvironment::new();
run_cli_command(cmd_def, rpcenv, Some(|future| {