1 #[cfg(target_os = "dragonos")] 2 use drstd as std; 3 4 use std::{process::Command, sync::Arc}; 5 6 use crate::{ 7 error::runtime_error::{RuntimeError, RuntimeErrorType}, 8 manager::{GLOBAL_UNIT_MANAGER, RunnnigUnit}, 9 unit::{service::ServiceUnit, UnitState}, 10 }; 11 12 pub struct ServiceExecutor; 13 14 impl ServiceExecutor { 15 pub fn exec(service: &ServiceUnit) -> Result<(), RuntimeError> { 16 //处理conflict 17 let conflicts = service.unit_base().unit_part().conflicts(); 18 for u in conflicts { 19 // 如果有冲突项enable的时候,该unit不能启动 20 if *u.unit_base().state() == UnitState::Enabled { 21 eprintln!("{}: Service startup failed: conflict unit", u.unit_base().unit_part().description()); 22 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 23 } 24 } 25 26 //处理ExecStarts,执行在服务启动前执行的命令 27 let cmds = service.service_part().exec_start_pre(); 28 for cmdtask in cmds { 29 cmdtask.exec()?; 30 } 31 32 //服务的启动命令 33 let exec_start = service.service_part().exec_start(); 34 let proc = Command::new(&exec_start.path).args(&exec_start.cmd).spawn(); 35 36 match proc { 37 Ok(p) => { 38 //修改service状态 39 40 //启动成功后将Child加入全局管理的进程表 41 let mut manager_writer = GLOBAL_UNIT_MANAGER.write().unwrap(); 42 manager_writer.running_table.push(RunnnigUnit::new(p,Arc::new(service.clone()))); 43 //执行启动后命令 44 let cmds = service.service_part().exec_start_pos(); 45 for cmd in cmds { 46 cmd.exec()? 47 } 48 } 49 Err(err) => { 50 eprintln!("{}: Service startup failed: {}", exec_start.path, err); 51 return Err(RuntimeError::new(RuntimeErrorType::ExecFailed)); 52 } 53 } 54 55 Ok(()) 56 } 57 } 58