mirror of
				https://git.proxmox.com/git/proxmox-backup
				synced 2025-11-02 15:18:42 +00:00 
			
		
		
		
	api2/node/services.rs: start services api
This commit is contained in:
		
							parent
							
								
									0f253593c6
								
							
						
					
					
						commit
						d2ab5f19e2
					
				@ -6,6 +6,7 @@ mod time;
 | 
			
		||||
mod network;
 | 
			
		||||
mod dns;
 | 
			
		||||
mod syslog;
 | 
			
		||||
mod services;
 | 
			
		||||
 | 
			
		||||
pub fn router() -> Router {
 | 
			
		||||
 | 
			
		||||
@ -19,6 +20,7 @@ pub fn router() -> Router {
 | 
			
		||||
            ObjectSchema::new("Directory index.")))
 | 
			
		||||
        .subdir("dns", dns::router())
 | 
			
		||||
        .subdir("network", network::router())
 | 
			
		||||
        .subdir("services", services::router())
 | 
			
		||||
        .subdir("syslog", syslog::router())
 | 
			
		||||
        .subdir("time", time::router());
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										119
									
								
								src/api2/node/services.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										119
									
								
								src/api2/node/services.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,119 @@
 | 
			
		||||
use failure::*;
 | 
			
		||||
 | 
			
		||||
use crate::tools;
 | 
			
		||||
use crate::api::schema::*;
 | 
			
		||||
use crate::api::router::*;
 | 
			
		||||
use serde_json::{json, Value};
 | 
			
		||||
 | 
			
		||||
use std::sync::Arc;
 | 
			
		||||
use lazy_static::lazy_static;
 | 
			
		||||
use crate::tools::common_regex;
 | 
			
		||||
use std::process::{Command, Stdio};
 | 
			
		||||
 | 
			
		||||
static SERVICE_NAME_LIST: [&str; 6] = [
 | 
			
		||||
    "proxmox-backup",
 | 
			
		||||
    "sshd",
 | 
			
		||||
    "syslog",
 | 
			
		||||
    "cron",
 | 
			
		||||
    "postfix",
 | 
			
		||||
    "systemd-timesyncd",
 | 
			
		||||
];
 | 
			
		||||
 | 
			
		||||
fn get_full_service_state(service: &str) -> Result<Value, Error> {
 | 
			
		||||
 | 
			
		||||
    let mut real_service_name = service;
 | 
			
		||||
 | 
			
		||||
    // since postfix package 3.1.0-3.1 the postfix unit is only here
 | 
			
		||||
    // to manage subinstances, of which the default is called "-".
 | 
			
		||||
    // This is where we look for the daemon status
 | 
			
		||||
 | 
			
		||||
    if service == "postfix" { real_service_name = "postfix@-"; }
 | 
			
		||||
 | 
			
		||||
    let mut child = Command::new("/bin/systemctl")
 | 
			
		||||
        .args(&["show", real_service_name])
 | 
			
		||||
        .stdout(Stdio::piped())
 | 
			
		||||
        .spawn()?;
 | 
			
		||||
 | 
			
		||||
    use std::io::{BufRead,BufReader};
 | 
			
		||||
 | 
			
		||||
    let mut result = json!({});
 | 
			
		||||
 | 
			
		||||
    if let Some(ref mut stdout) = child.stdout {
 | 
			
		||||
        for line in BufReader::new(stdout).lines() {
 | 
			
		||||
            match line {
 | 
			
		||||
                Ok(line) => {
 | 
			
		||||
                    let mut iter = line.splitn(2, '=');
 | 
			
		||||
                    let key = iter.next();
 | 
			
		||||
                    let value = iter.next();
 | 
			
		||||
                    if let (Some(key), Some(value)) = (key, value) {
 | 
			
		||||
                        result[key] = Value::from(value);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Err(err) => {
 | 
			
		||||
                    log::error!("reading service config failed: {}", err);
 | 
			
		||||
                    let _ = child.kill();
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let status = child.wait().unwrap();
 | 
			
		||||
    if !status.success() {
 | 
			
		||||
        bail!("systemctl show failed with {}", status);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(result)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn list_services(
 | 
			
		||||
    param: Value,
 | 
			
		||||
    _info: &ApiMethod,
 | 
			
		||||
    rpcenv: &mut RpcEnvironment,
 | 
			
		||||
) -> Result<Value, Error> {
 | 
			
		||||
 | 
			
		||||
    let mut list = vec![];
 | 
			
		||||
 | 
			
		||||
    for service in &SERVICE_NAME_LIST {
 | 
			
		||||
        match get_full_service_state(service) {
 | 
			
		||||
            Ok(status) => {
 | 
			
		||||
                if let Some(desc) = status["Description"].as_str() {
 | 
			
		||||
                    let name = status["Name"].as_str().unwrap_or(service);
 | 
			
		||||
                    let state = status["SubState"].as_str().unwrap_or("unknown");
 | 
			
		||||
                    list.push(json!({
 | 
			
		||||
                        "service": service,
 | 
			
		||||
                        "name": name,
 | 
			
		||||
                        "desc": desc,
 | 
			
		||||
                        "state": state,
 | 
			
		||||
                    }));
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            Err(err) => log::error!("{}", err),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(Value::from(list))
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn router() -> Router {
 | 
			
		||||
 | 
			
		||||
    let route = Router::new()
 | 
			
		||||
        .get(
 | 
			
		||||
            ApiMethod::new(
 | 
			
		||||
                list_services,
 | 
			
		||||
                ObjectSchema::new("Service list.")
 | 
			
		||||
            ).returns(
 | 
			
		||||
                ArraySchema::new(
 | 
			
		||||
                    "Returns a list of systemd services.",
 | 
			
		||||
                    ObjectSchema::new("Service details.")
 | 
			
		||||
                        .required("service", StringSchema::new("Service ID."))
 | 
			
		||||
                        .required("name", StringSchema::new("systemd service name."))
 | 
			
		||||
                        .required("desc", StringSchema::new("systemd service description."))
 | 
			
		||||
                        .required("state", StringSchema::new("systemd service 'SubState'."))
 | 
			
		||||
                        .into()
 | 
			
		||||
                )
 | 
			
		||||
            )
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    route
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user