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 pbs_api_types::{Authid, NODE_SCHEMA, SERVICE_ID_SCHEMA, PRIV_SYS_AUDIT, PRIV_SYS_MODIFY};
+
+use crate::server::WorkerTask;
static SERVICE_NAME_LIST: [&str; 7] = [
"proxmox-backup",
"systemd-timesyncd",
];
-fn real_service_name(service: &str) -> &str {
+pub fn real_service_name(service: &str) -> &str {
// since postfix package 3.1.0-3.1 the postfix unit is only here
// to manage subinstances, of which the default is called "-".
let real_service_name = real_service_name(service);
- let mut child = Command::new("/bin/systemctl")
+ let mut child = Command::new("systemctl")
.args(&["show", real_service_name])
.stdout(Stdio::piped())
.spawn()?;
Ok(json_service_state(&service, status))
}
-fn run_service_command(service: &str, cmd: &str) -> Result<Value, Error> {
+fn run_service_command(service: &str, cmd: &str, auth_id: Authid) -> Result<Value, Error> {
- // fixme: run background worker (fork_worker) ???
+ let workerid = format!("srv{}", &cmd);
- match cmd {
- "start"|"stop"|"restart"|"reload" => {},
+ let cmd = match cmd {
+ "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();
+
+ let upid = WorkerTask::new_thread(
+ &workerid,
+ Some(service.clone()),
+ auth_id,
+ false,
+ move |_worker| {
+
+ if service == "proxmox-backup" && cmd == "stop" {
+ bail!("invalid service cmd '{} {}' cannot stop essential service!", service, cmd);
+ }
- if service == "proxmox-backup" && cmd != "restart" {
- bail!("invalid service cmd '{} {}'", service, cmd);
- }
+ let real_service_name = real_service_name(&service);
- let real_service_name = real_service_name(service);
+ let status = Command::new("systemctl")
+ .args(&[&cmd, real_service_name])
+ .status()?;
- let status = Command::new("/bin/systemctl")
- .args(&[cmd, real_service_name])
- .status()?;
+ if !status.success() {
+ bail!("systemctl {} failed with {}", cmd, status);
+ }
- if !status.success() {
- bail!("systemctl {} failed with {}", cmd, status);
- }
+ Ok(())
+ }
+ )?;
- Ok(Value::Null)
+ Ok(upid.into())
}
#[api(
fn start_service(
service: String,
_param: Value,
+ rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+
log::info!("starting service {}", service);
- run_service_command(&service, "start")
+ run_service_command(&service, "start", auth_id)
}
#[api(
fn stop_service(
service: String,
_param: Value,
+ rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+
log::info!("stopping service {}", service);
- run_service_command(&service, "stop")
+ run_service_command(&service, "stop", auth_id)
}
#[api(
fn restart_service(
service: String,
_param: Value,
+ rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().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", auth_id)
} else {
- run_service_command(&service, "restart")
+ run_service_command(&service, "restart", auth_id)
}
}
fn reload_service(
service: String,
_param: Value,
+ rpcenv: &mut dyn RpcEnvironment,
) -> Result<Value, Error> {
+ let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?;
+
log::info!("reloading service {}", service);
- run_service_command(&service, "reload")
+ run_service_command(&service, "reload", auth_id)
}
-
-const SERVICE_ID_SCHEMA: Schema = StringSchema::new("Service ID.")
- .max_length(256)
- .schema();
-
#[sortable]
const SERVICE_SUBDIRS: SubdirMap = &sorted!([
(