use anyhow::{Error}; use serde_json::{json, Value}; use proxmox::api::{api, cli::*}; use pbs_client::display_task_log; use pbs_tools::percent_encoding::percent_encode_component; use pbs_tools::json::required_string_param; use pbs_api_types::UPID; use crate::{ REPO_URL_SCHEMA, extract_repository_from_value, complete_repository, connect, }; #[api( input: { properties: { repository: { schema: REPO_URL_SCHEMA, optional: true, }, limit: { description: "The maximal number of tasks to list.", type: Integer, optional: true, minimum: 1, maximum: 1000, default: 50, }, "output-format": { schema: OUTPUT_FORMAT, optional: true, }, all: { type: Boolean, description: "Also list stopped tasks.", optional: true, }, } } )] /// List running server tasks for this repo user async fn task_list(param: Value) -> Result { let output_format = get_output_format(¶m); let repo = extract_repository_from_value(¶m)?; let client = connect(&repo)?; let limit = param["limit"].as_u64().unwrap_or(50) as usize; let running = !param["all"].as_bool().unwrap_or(false); let args = json!({ "running": running, "start": 0, "limit": limit, "userfilter": repo.auth_id(), "store": repo.store(), }); let mut result = client.get("api2/json/nodes/localhost/tasks", Some(args)).await?; let mut data = result["data"].take(); let return_type = &proxmox_backup::api2::node::tasks::API_METHOD_LIST_TASKS.returns; use pbs_tools::format::{render_epoch, render_task_status}; let options = default_table_format_options() .column(ColumnConfig::new("starttime").right_align(false).renderer(render_epoch)) .column(ColumnConfig::new("endtime").right_align(false).renderer(render_epoch)) .column(ColumnConfig::new("upid")) .column(ColumnConfig::new("status").renderer(render_task_status)); format_and_print_result_full(&mut data, return_type, &output_format, &options); Ok(Value::Null) } #[api( input: { properties: { repository: { schema: REPO_URL_SCHEMA, optional: true, }, upid: { type: UPID, }, } } )] /// Display the task log. async fn task_log(param: Value) -> Result { let repo = extract_repository_from_value(¶m)?; let upid = required_string_param(¶m, "upid")?; let mut client = connect(&repo)?; display_task_log(&mut client, upid, true).await?; Ok(Value::Null) } #[api( input: { properties: { repository: { schema: REPO_URL_SCHEMA, optional: true, }, upid: { type: UPID, }, } } )] /// Try to stop a specific task. async fn task_stop(param: Value) -> Result { let repo = extract_repository_from_value(¶m)?; let upid_str = required_string_param(¶m, "upid")?; let mut client = connect(&repo)?; let path = format!("api2/json/nodes/localhost/tasks/{}", percent_encode_component(upid_str)); let _ = client.delete(&path, None).await?; Ok(Value::Null) } pub fn task_mgmt_cli() -> CliCommandMap { let task_list_cmd_def = CliCommand::new(&API_METHOD_TASK_LIST) .completion_cb("repository", complete_repository); let task_log_cmd_def = CliCommand::new(&API_METHOD_TASK_LOG) .arg_param(&["upid"]); let task_stop_cmd_def = CliCommand::new(&API_METHOD_TASK_STOP) .arg_param(&["upid"]); CliCommandMap::new() .insert("log", task_log_cmd_def) .insert("list", task_list_cmd_def) .insert("stop", task_stop_cmd_def) }