xref: /DragonReach/src/executor/service_executor/mod.rs (revision e5a8055aa517085cf10def70e7fddab4ec87fd13)
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