1 use std::any::Any;
2 use std::fmt::Debug;
3 use std::sync::atomic::AtomicUsize;
4 use std::sync::atomic::Ordering;
5
6 use crate::error::parse_error::ParseError;
7 use crate::error::parse_error::ParseErrorType;
8 use crate::error::runtime_error::RuntimeError;
9
10 use crate::executor::ExitStatus;
11 use crate::parse::parse_util::UnitParseUtil;
12 use crate::parse::Segment;
13
14 pub mod service;
15 pub mod target;
16 pub mod timer;
17
18 use self::target::TargetUnit;
19
generate_unit_id() -> usize20 pub fn generate_unit_id() -> usize {
21 static UNIT_ID: AtomicUsize = AtomicUsize::new(1);
22 return UNIT_ID.fetch_add(1, Ordering::SeqCst);
23 }
24
25 //所有可解析的Unit都应该实现该trait
26 pub trait Unit: Sync + Send + Debug {
27 /// @brief 从文件获取到Unit,该函数是解析Unit文件的入口函数
28 ///
29 /// 从path解析Unit属性
30 ///
31 /// @param path 需解析的文件
32 ///
33 /// @return 解析成功则返回对应Unit的id,否则返回Err
from_path(path: &str) -> Result<usize, ParseError> where Self: Sized34 fn from_path(path: &str) -> Result<usize, ParseError>
35 where
36 Self: Sized;
37
as_any(&self) -> &dyn Any38 fn as_any(&self) -> &dyn Any;
39
as_mut_any(&mut self) -> &mut dyn Any40 fn as_mut_any(&mut self) -> &mut dyn Any;
41
42 /// @brief 设置Unit属性
43 ///
44 /// 设置对应Unit属性
45 ///
46 /// @param segment 属性段类型
47 ///
48 /// @param attr 属性名
49 ///
50 /// @param val 属性值
51 ///
52 /// @return 设置成功则返回Ok(()),否则返回Err
set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError>53 fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError>;
54
55 /// # 设置每个Unit都应该有的属性
56 ///
57 /// 设置BaseUnit
58 ///
59 /// ## param unit_base 设置值
set_unit_base(&mut self, unit_base: BaseUnit)60 fn set_unit_base(&mut self, unit_base: BaseUnit);
61
62 /// # 获取UnitType
63 ///
64 /// ## return UnitType
unit_type(&self) -> UnitType65 fn unit_type(&self) -> UnitType;
66
unit_base(&self) -> &BaseUnit67 fn unit_base(&self) -> &BaseUnit;
68
unit_base_mut(&mut self) -> &mut BaseUnit69 fn unit_base_mut(&mut self) -> &mut BaseUnit;
70
unit_id(&self) -> usize71 fn unit_id(&self) -> usize;
72
73 /// ## Unit的工作逻辑
74 ///
75 /// ### return OK(())/Err
run(&mut self) -> Result<(), RuntimeError>76 fn run(&mut self) -> Result<(), RuntimeError>;
77
78 /// ## 设置unit_id
79 ///
80 /// ### return OK(())/Err
set_unit_id(&mut self) -> usize81 fn set_unit_id(&mut self) -> usize {
82 let ret = generate_unit_id();
83 self.unit_base_mut().set_id(ret);
84 ret
85 }
86
87 /// ## Unit退出后逻辑
88 ///
89 /// 一般只有可运行的Unit(如Service)需要重写此函数
after_exit(&mut self, _exit_status: ExitStatus)90 fn after_exit(&mut self, _exit_status: ExitStatus) {
91 unimplemented!()
92 }
93
94 /// ## 初始化Unit内任务的一些参数,各个Unit所需处理的不相同,故放在总的Unit trait
init(&mut self)95 fn init(&mut self) {}
96
97 /// ## Unit的显式退出逻辑
exit(&mut self)98 fn exit(&mut self);
99
set_unit_name(&mut self, name: String)100 fn set_unit_name(&mut self, name: String) {
101 self.unit_base_mut().unit_name = name;
102 }
103
104 /// ## Unit重启逻辑
restart(&mut self) -> Result<(), RuntimeError>105 fn restart(&mut self) -> Result<(), RuntimeError> {
106 unimplemented!()
107 }
108 }
109
110 //Unit状态
111 #[allow(dead_code)]
112 #[derive(Clone, Copy, Debug, PartialEq)]
113 pub enum UnitState {
114 Active,
115 Inactive,
116 Activating,
117 Deactivating,
118 Failed,
119 Reloading,
120 Maintenance,
121 }
122
123 impl ToString for UnitState {
to_string(&self) -> String124 fn to_string(&self) -> String {
125 match *self {
126 UnitState::Active => "active".to_string(),
127 UnitState::Inactive => "inactive".to_string(),
128 UnitState::Activating => "activeting".to_string(),
129 UnitState::Deactivating => "deactivating".to_string(),
130 UnitState::Failed => "failed".to_string(),
131 UnitState::Reloading => "reloading".to_string(),
132 UnitState::Maintenance => "maintenance".to_string(),
133 }
134 }
135 }
136
137 #[allow(dead_code)]
138 #[derive(Clone, Copy, Debug, PartialEq)]
139 pub enum UnitSubState {
140 Running,
141 Waiting,
142 StartPre,
143 StartPost,
144 StopSigterm,
145 StopSigkill,
146 StopFinalSigterm,
147 StopFinalSigkill,
148 Dead,
149 AutoRestart,
150 Failed,
151 Activating,
152 Deactivating,
153 Plugged,
154 Unknown,
155 }
156
157 impl ToString for UnitSubState {
to_string(&self) -> String158 fn to_string(&self) -> String {
159 match *self {
160 UnitSubState::Running => "running".to_string(),
161 UnitSubState::Waiting => "waiting".to_string(),
162 UnitSubState::StartPre => "start-pre".to_string(),
163 UnitSubState::StartPost => "start-post".to_string(),
164 UnitSubState::StopSigterm => "stop-sigterm".to_string(),
165 UnitSubState::StopSigkill => "stop-sigkill".to_string(),
166 UnitSubState::StopFinalSigterm => "stop-final-sigterm".to_string(),
167 UnitSubState::StopFinalSigkill => "stop-final-sigkill".to_string(),
168 UnitSubState::Dead => "dead".to_string(),
169 UnitSubState::AutoRestart => "auto-restart".to_string(),
170 UnitSubState::Failed => "failed".to_string(),
171 UnitSubState::Activating => "activating".to_string(),
172 UnitSubState::Deactivating => "deactivating".to_string(),
173 UnitSubState::Plugged => "plugged".to_string(),
174 UnitSubState::Unknown => "unknown".to_string(),
175 }
176 }
177 }
178
179 #[allow(dead_code)]
180 #[derive(Clone, Copy, Debug, PartialEq)]
181 pub enum LoadState {
182 Loaded,
183 NotFound,
184 Error,
185 Masked,
186 }
187
188 impl ToString for LoadState {
to_string(&self) -> String189 fn to_string(&self) -> String {
190 match *self {
191 LoadState::Loaded => "loaded".to_string(),
192 LoadState::NotFound => "not found".to_string(),
193 LoadState::Error => "error".to_string(),
194 LoadState::Masked => "maksed".to_string(),
195 }
196 }
197 }
198
199 //Unit类型
200 #[allow(dead_code)]
201 #[derive(Clone, Copy, PartialEq, Debug)]
202 pub enum UnitType {
203 Automount,
204 Device,
205 Mount,
206 Path,
207 Scope,
208 Service,
209 Slice,
210 Snapshot,
211 Socket,
212 Swap,
213 Target,
214 Timer,
215 Unknown,
216 }
217
218 //记录unit文件基本信息,这个结构体里面的信息是所有Unit文件都可以有的属性
219 #[allow(dead_code)]
220 #[derive(Debug, Clone)]
221 pub struct BaseUnit {
222 unit_name: String,
223 unit_part: UnitPart,
224 install_part: InstallPart,
225 state: UnitState,
226 sub_state: UnitSubState,
227 load_state: LoadState,
228 unit_type: UnitType,
229 unit_id: usize,
230 }
231
232 impl Default for BaseUnit {
default() -> Self233 fn default() -> Self {
234 BaseUnit {
235 unit_name: String::new(),
236 unit_part: UnitPart::default(),
237 install_part: InstallPart::default(),
238 state: UnitState::Inactive,
239 sub_state: UnitSubState::Unknown,
240 load_state: LoadState::Loaded,
241 unit_type: UnitType::Unknown,
242 unit_id: 0,
243 }
244 }
245 }
246
247 #[allow(dead_code)]
248 impl BaseUnit {
set_state(&mut self, state: UnitState)249 pub fn set_state(&mut self, state: UnitState) {
250 self.state = state;
251 }
252
set_unit_type(&mut self, utype: UnitType)253 pub fn set_unit_type(&mut self, utype: UnitType) {
254 self.unit_type = utype;
255 }
256
set_unit_part_attr( &mut self, attr_type: &BaseUnitAttr, val: &str, ) -> Result<(), ParseError>257 pub fn set_unit_part_attr(
258 &mut self,
259 attr_type: &BaseUnitAttr,
260 val: &str,
261 ) -> Result<(), ParseError> {
262 return self.unit_part.set_attr(attr_type, val);
263 }
264
set_install_part_attr( &mut self, attr_type: &InstallUnitAttr, val: &str, ) -> Result<(), ParseError>265 pub fn set_install_part_attr(
266 &mut self,
267 attr_type: &InstallUnitAttr,
268 val: &str,
269 ) -> Result<(), ParseError> {
270 return self.install_part.set_attr(attr_type, val);
271 }
272
parse_and_set_attribute(&self) -> Result<(), ParseError>273 pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> {
274 return Ok(());
275 }
276
unit_part(&self) -> &UnitPart277 pub fn unit_part(&self) -> &UnitPart {
278 &self.unit_part
279 }
280
mut_unit_part(&mut self) -> &mut UnitPart281 pub fn mut_unit_part(&mut self) -> &mut UnitPart {
282 &mut self.unit_part
283 }
284
install_part(&self) -> &InstallPart285 pub fn install_part(&self) -> &InstallPart {
286 &self.install_part
287 }
288
state(&self) -> &UnitState289 pub fn state(&self) -> &UnitState {
290 &self.state
291 }
292
unit_type(&self) -> &UnitType293 pub fn unit_type(&self) -> &UnitType {
294 &self.unit_type
295 }
296
set_id(&mut self, id: usize)297 pub fn set_id(&mut self, id: usize) {
298 self.unit_id = id;
299 }
300
unit_name(&self) -> String301 pub fn unit_name(&self) -> String {
302 self.unit_name.clone()
303 }
304
305 /// ## Unit基本格式化信息
unit_info(&self) -> String306 pub fn unit_info(&self) -> String {
307 format!(
308 "{}\t\t\t{}\t\t{}\t\t{}\t\t{}",
309 self.unit_name,
310 self.load_state.to_string(),
311 self.state.to_string(),
312 self.sub_state.to_string(),
313 self.unit_part.description
314 )
315 }
316 }
317
318 #[derive(Default, Debug, Clone)]
319 pub struct Url {
320 pub url_string: String, // pub protocol: String,
321 // pub host: String,
322 // pub port: Option<u16>,
323 // pub path: String,
324 // pub query: Option<String>,
325 // pub fragment: Option<String>,
326 }
327
328 //对应Unit文件的Unit段
329 #[derive(Debug, Clone)]
330 pub struct UnitPart {
331 // Unit描述
332 description: String,
333 // Unit文档
334 documentation: Vec<Url>,
335 // 依赖项,同时与当前Unit启动,任意一个失败,终止该Unit的启动
336 requires: Vec<usize>,
337 // 依赖项,同时与当前Unit启动,不需要考虑其成功与否
338 wants: Vec<usize>,
339 // 该Unit在下列Units启动完成之后才能启动
340 after: Vec<usize>,
341 // after相反的语义
342 before: Vec<usize>,
343 // 与requires类似,但是这些模块任意一个意外结束或者重启时,该Unit也会终止或重启
344 binds_to: Vec<usize>,
345 // 与binds_to类似,但是不会随着当前Unit启动而启动
346 part_of: Vec<usize>,
347 // 启动失败时,需启动的项
348 on_failure: Vec<usize>,
349 // 与当前Unit冲突项
350 conflicts: Vec<usize>,
351 // 与当前Unit绑定的项,当前Unit失败或者重启时这些项也会跟着终止或重启
352 be_binded_by: Vec<usize>,
353 }
354
355 impl Default for UnitPart {
default() -> Self356 fn default() -> Self {
357 UnitPart {
358 description: String::new(),
359 documentation: Vec::new(),
360 requires: Vec::new(),
361 wants: Vec::new(),
362 after: Vec::new(),
363 before: Vec::new(),
364 binds_to: Vec::new(),
365 part_of: Vec::new(),
366 on_failure: Vec::new(),
367 conflicts: Vec::new(),
368 be_binded_by: Vec::new(),
369 }
370 }
371 }
372
373 #[allow(dead_code)]
374 impl UnitPart {
set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError>375 pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> {
376 match attr {
377 BaseUnitAttr::None => {
378 return Err(ParseError::new(
379 ParseErrorType::ESyntaxError,
380 String::new(),
381 0,
382 ));
383 }
384 BaseUnitAttr::Description => self.description = String::from(val),
385 BaseUnitAttr::Documentation => {
386 self.documentation.extend(UnitParseUtil::parse_url(val)?)
387 }
388 BaseUnitAttr::Requires => {
389 let units = val.split_whitespace().collect::<Vec<&str>>();
390 //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题
391 for unit_path in units {
392 self.requires
393 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
394 }
395 }
396 BaseUnitAttr::Wants => {
397 let units = val.split_whitespace().collect::<Vec<&str>>();
398 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
399 for unit_path in units {
400 self.wants
401 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
402 }
403 }
404 BaseUnitAttr::After => {
405 let units = val.split_whitespace().collect::<Vec<&str>>();
406 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
407 for unit_path in units {
408 self.after
409 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
410 }
411 }
412 BaseUnitAttr::Before => {
413 let units = val.split_whitespace().collect::<Vec<&str>>();
414 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
415 for unit_path in units {
416 self.before
417 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
418 }
419 }
420 BaseUnitAttr::BindsTo => {
421 let units = val.split_whitespace().collect::<Vec<&str>>();
422 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
423 for unit_path in units {
424 self.binds_to
425 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
426 }
427 }
428 BaseUnitAttr::PartOf => {
429 let units = val.split_whitespace().collect::<Vec<&str>>();
430 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
431 for unit_path in units {
432 self.part_of
433 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
434 }
435 }
436 BaseUnitAttr::OnFailure => {
437 let units = val.split_whitespace().collect::<Vec<&str>>();
438 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
439 for unit_path in units {
440 self.on_failure
441 .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
442 }
443 }
444 BaseUnitAttr::Conflicts => {
445 let units = val.split_whitespace().collect::<Vec<&str>>();
446 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
447 for unit_path in units {
448 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
449 self.conflicts.push(unit);
450 }
451 }
452 }
453 return Ok(());
454 }
455
description(&self) -> &str456 pub fn description(&self) -> &str {
457 &self.description
458 }
459
documentation(&self) -> &[Url]460 pub fn documentation(&self) -> &[Url] {
461 &self.documentation
462 }
463
requires(&self) -> &[usize]464 pub fn requires(&self) -> &[usize] {
465 &self.requires
466 }
467
wants(&self) -> &[usize]468 pub fn wants(&self) -> &[usize] {
469 &self.wants
470 }
471
after(&self) -> &[usize]472 pub fn after(&self) -> &[usize] {
473 &self.after
474 }
475
before(&self) -> &[usize]476 pub fn before(&self) -> &[usize] {
477 &self.before
478 }
479
binds_to(&self) -> &[usize]480 pub fn binds_to(&self) -> &[usize] {
481 &self.binds_to
482 }
483
part_of(&self) -> &[usize]484 pub fn part_of(&self) -> &[usize] {
485 &self.part_of
486 }
487
on_failure(&self) -> &[usize]488 pub fn on_failure(&self) -> &[usize] {
489 &self.on_failure
490 }
491
conflicts(&self) -> &[usize]492 pub fn conflicts(&self) -> &[usize] {
493 &self.conflicts
494 }
495
be_binded_by(&self) -> &[usize]496 pub fn be_binded_by(&self) -> &[usize] {
497 &self.be_binded_by
498 }
499
push_be_binded_by(&mut self, id: usize)500 pub fn push_be_binded_by(&mut self, id: usize) {
501 if !self.be_binded_by.contains(&id) {
502 self.be_binded_by.push(id);
503 }
504 }
505
push_after_unit(&mut self, id: usize)506 pub fn push_after_unit(&mut self, id: usize) {
507 if !self.after.contains(&id) {
508 self.after.push(id);
509 }
510 }
511 }
512
513 //对应Unit文件的Install段
514 #[derive(Debug, Clone)]
515 pub struct InstallPart {
516 wanted_by: Vec<usize>,
517 requires_by: Vec<usize>,
518 also: Vec<usize>,
519 alias: String,
520 }
521
522 impl Default for InstallPart {
default() -> Self523 fn default() -> Self {
524 InstallPart {
525 wanted_by: Vec::new(),
526 requires_by: Vec::new(),
527 also: Vec::new(),
528 alias: String::new(),
529 }
530 }
531 }
532
533 #[allow(dead_code)]
534 impl InstallPart {
set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError>535 pub fn set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError> {
536 match attr {
537 InstallUnitAttr::RequiredBy => {
538 let units = val.split_whitespace().collect::<Vec<&str>>();
539 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
540 for unit_path in units {
541 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
542 self.requires_by.push(unit);
543 }
544 }
545 InstallUnitAttr::Also => {
546 let units = val.split_whitespace().collect::<Vec<&str>>();
547 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
548 for unit_path in units {
549 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
550 self.also.push(unit);
551 }
552 }
553 InstallUnitAttr::WantedBy => {
554 let units = val.split_whitespace().collect::<Vec<&str>>();
555 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
556 for unit_path in units {
557 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
558 self.wanted_by.push(unit);
559 }
560 }
561 InstallUnitAttr::Alias => {
562 self.alias = String::from(val);
563 }
564 InstallUnitAttr::None => {
565 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
566 }
567 }
568 return Ok(());
569 }
570
wanted_by(&self) -> &[usize]571 pub fn wanted_by(&self) -> &[usize] {
572 &self.wanted_by
573 }
574
requires_by(&self) -> &[usize]575 pub fn requires_by(&self) -> &[usize] {
576 &self.requires_by
577 }
578
also(&self) -> &[usize]579 pub fn also(&self) -> &[usize] {
580 &self.also
581 }
582
alias(&self) -> &str583 pub fn alias(&self) -> &str {
584 &self.alias
585 }
586 }
587 //对应Unit文件的各种属性
588 #[allow(dead_code)]
589 pub enum BaseUnitAttr {
590 None,
591
592 //Unit段
593 //描述该Unit文件的信息
594 Description,
595 //指定服务文档
596 Documentation,
597 //依赖的其它 Unit 列表
598 Requires,
599 //这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模板启动是否成功
600 Wants,
601 //后面列出的所有模块全部启动完成以后,才会启动当前的服务
602 After,
603 //在启动指定的任务一个模块之间,都会首先确证当前服务已经运行
604 Before,
605 //这些Unit启动失败时该任务失败,都成功时该任务成功,在这些模板中有任意一个出现意外结束或重启时,这个服务也会跟着终止或重启
606 BindsTo,
607 //仅在列出的任务模块失败或重启时,终止或重启当前服务,而不会随列出模板的启动而启动
608 PartOf,
609 //当这个模板启动失败时,就会自动启动列出的每个模块
610 OnFailure,
611 //与这个模块有冲突的模块,如果列出的模块中有已经在运行的,这个服务就不能启动,反之亦然
612 Conflicts,
613 }
614
615 #[allow(dead_code)]
616 pub enum InstallUnitAttr {
617 None,
618 //Install段
619 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .wants 后缀构成的子目录中
620 WantedBy,
621 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .required 后缀构成的子目录中
622 RequiredBy,
623 //当前 Unit enable/disable 时,同时 enable/disable 的其他 Unit
624 Also,
625 //别名
626 Alias,
627 }
628