From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id A057F60BFF for ; Fri, 14 Aug 2020 12:03:40 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8BA5220668 for ; Fri, 14 Aug 2020 12:03:10 +0200 (CEST) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [212.186.127.180]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 270952065B for ; Fri, 14 Aug 2020 12:03:09 +0200 (CEST) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id E9F7F44606 for ; Fri, 14 Aug 2020 12:03:08 +0200 (CEST) From: Dominik Csapak To: pbs-devel@lists.proxmox.com Date: Fri, 14 Aug 2020 12:03:08 +0200 Message-Id: <20200814100308.10005-1-d.csapak@proxmox.com> X-Mailer: git-send-email 2.20.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 AWL -0.050 Adjusted score from AWL reputation of From: address KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment KAM_LAZY_DOMAIN_SECURITY 1 Sending domain does not have any anti-forgery methods NO_DNS_FOR_FROM 0.379 Envelope sender has no MX or A DNS records RCVD_IN_DNSWL_MED -2.3 Sender listed at https://www.dnswl.org/, medium trust SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_NONE 0.001 SPF: sender does not publish an SPF Record URIBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to URIBL was blocked. See http://wiki.apache.org/spamassassin/DnsBlocklists#dnsbl-block for more information. [services.rs] Subject: [pbs-devel] [PATCH proxmox-backup v2] api2/node/services: turn service api calls into workers X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 14 Aug 2020 10:03:40 -0000 to be in line with pve/pmg and be able to show the progress in the gui Signed-off-by: Dominik Csapak --- changes from v1: * use Userid struct instead of strings * rebase on master src/api2/node/services.rs | 67 +++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 21 deletions(-) diff --git a/src/api2/node/services.rs b/src/api2/node/services.rs index 923252cd..849bead7 100644 --- a/src/api2/node/services.rs +++ b/src/api2/node/services.rs @@ -4,12 +4,13 @@ use anyhow::{bail, Error}; use serde_json::{json, Value}; use proxmox::{sortable, identity, list_subdirs_api_method}; -use proxmox::api::{api, Router, Permission}; +use proxmox::api::{api, Router, Permission, RpcEnvironment}; use proxmox::api::router::SubdirMap; use proxmox::api::schema::*; use crate::api2::types::*; use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_SYS_MODIFY}; +use crate::server::WorkerTask; static SERVICE_NAME_LIST: [&str; 7] = [ "proxmox-backup", @@ -181,31 +182,43 @@ fn get_service_state( Ok(json_service_state(&service, status)) } -fn run_service_command(service: &str, cmd: &str) -> Result { +fn run_service_command(service: &str, cmd: &str, userid: Userid) -> Result { - // fixme: run background worker (fork_worker) ??? + let workerid = format!("srv{}", &cmd); let cmd = match cmd { - "start"|"stop"|"restart"=> cmd, - "reload" => "try-reload-or-restart", // some services do not implement reload + "start"|"stop"|"restart"=> cmd.to_string(), + "reload" => "try-reload-or-restart".to_string(), // some services do not implement reload _ => bail!("unknown service command '{}'", cmd), }; + let service = service.to_string(); - if service == "proxmox-backup" && cmd == "stop" { - bail!("invalid service cmd '{} {}' cannot stop essential service!", service, cmd); - } + let upid = WorkerTask::new_thread( + &workerid, + Some(service.clone()), + userid, + false, + move |_worker| { - let real_service_name = real_service_name(service); + if service == "proxmox-backup" && cmd == "stop" { + bail!("invalid service cmd '{} {}' cannot stop essential service!", service, cmd); + } - let status = Command::new("systemctl") - .args(&[cmd, real_service_name]) - .status()?; + let real_service_name = real_service_name(&service); - if !status.success() { - bail!("systemctl {} failed with {}", cmd, status); - } + let status = Command::new("systemctl") + .args(&[&cmd, real_service_name]) + .status()?; + + if !status.success() { + bail!("systemctl {} failed with {}", cmd, status); + } - Ok(Value::Null) + Ok(()) + } + )?; + + Ok(upid.into()) } #[api( @@ -228,11 +241,14 @@ fn run_service_command(service: &str, cmd: &str) -> Result { fn start_service( service: String, _param: Value, + rpcenv: &mut dyn RpcEnvironment, ) -> Result { + let userid: Userid = rpcenv.get_user().unwrap().parse()?; + log::info!("starting service {}", service); - run_service_command(&service, "start") + run_service_command(&service, "start", userid) } #[api( @@ -255,11 +271,14 @@ fn start_service( fn stop_service( service: String, _param: Value, + rpcenv: &mut dyn RpcEnvironment, ) -> Result { + let userid: Userid = rpcenv.get_user().unwrap().parse()?; + log::info!("stopping service {}", service); - run_service_command(&service, "stop") + run_service_command(&service, "stop", userid) } #[api( @@ -282,15 +301,18 @@ fn stop_service( fn restart_service( service: String, _param: Value, + rpcenv: &mut dyn RpcEnvironment, ) -> Result { + let userid: Userid = rpcenv.get_user().unwrap().parse()?; + log::info!("re-starting service {}", service); if &service == "proxmox-backup-proxy" { // special case, avoid aborting running tasks - run_service_command(&service, "reload") + run_service_command(&service, "reload", userid) } else { - run_service_command(&service, "restart") + run_service_command(&service, "restart", userid) } } @@ -314,11 +336,14 @@ fn restart_service( fn reload_service( service: String, _param: Value, + rpcenv: &mut dyn RpcEnvironment, ) -> Result { + let userid: Userid = rpcenv.get_user().unwrap().parse()?; + log::info!("reloading service {}", service); - run_service_command(&service, "reload") + run_service_command(&service, "reload", userid) } -- 2.20.1