xref: /DragonReach/src/unit/mod.rs (revision e5a8055aa517085cf10def70e7fddab4ec87fd13)
1 use crate::error::parse_error::ParseError;
2 use crate::error::parse_error::ParseErrorType;
3 use crate::error::runtime_error::RuntimeError;
4 use crate::error::runtime_error::RuntimeErrorType;
5 use crate::parse::parse_util::UnitParseUtil;
6 use crate::parse::Segment;
7 
8 #[cfg(target_os = "dragonos")]
9 use drstd as std;
10 use hashbrown::HashMap;
11 
12 use std::any::Any;
13 use std::default::Default;
14 use std::fmt::Debug;
15 use std::result::Result;
16 use std::result::Result::Err;
17 use std::result::Result::Ok;
18 use std::string::String;
19 use std::sync::atomic::AtomicUsize;
20 use std::sync::atomic::Ordering;
21 use std::sync::Arc;
22 use std::vec::Vec;
23 
24 pub mod service;
25 pub mod target;
26 
27 use self::target::TargetUnit;
28 use lazy_static::lazy_static;
29 
30 pub fn generate_unit_id() -> usize {
31     static UNIT_ID: AtomicUsize = AtomicUsize::new(1);
32     return UNIT_ID.fetch_add(1, Ordering::SeqCst);
33 }
34 
35 //所有可解析的Unit都应该实现该trait
36 pub trait Unit: Sync + Send + Debug {
37     /// @brief 从文件获取到Unit,该函数是解析Unit文件的入口函数
38     ///
39     /// 从path解析Unit属性
40     ///
41     /// @param path 需解析的文件
42     ///
43     /// @return 解析成功则返回对应Unit的Arc指针,否则返回Err
44     fn from_path(path: &str) -> Result<Arc<Self>, ParseError>
45     where
46         Self: Sized;
47 
48     fn as_any(&self) -> &dyn Any;
49 
50     /// @brief 设置Unit属性
51     ///
52     /// 设置对应Unit属性
53     ///
54     /// @param segment  属性段类型
55     ///
56     /// @param attr     属性名
57     ///
58     /// @param val      属性值
59     ///
60     /// @return 设置成功则返回Ok(()),否则返回Err
61     fn set_attr(&mut self, segment: Segment, attr: &str, val: &str) -> Result<(), ParseError>;
62 
63     /// # 设置每个Unit都应该有的属性
64     ///
65     /// 设置BaseUnit
66     ///
67     /// ## param unit_base  设置值
68     fn set_unit_base(&mut self, unit_base: BaseUnit);
69 
70     /// # 获取UnitType
71     ///
72     /// ## return UnitType
73     fn unit_type(&self) -> UnitType;
74 
75     fn unit_base(&self) -> &BaseUnit;
76 
77     fn mut_unit_base(&mut self) -> &mut BaseUnit;
78 
79     fn unit_id(&self) -> usize;
80 
81     /// ## Unit的工作逻辑
82     ///
83     /// ### return OK(())/Err
84     fn run(&self) -> Result<(), RuntimeError>;
85 
86     /// ## 设置unit_id
87     ///
88     /// ### return OK(())/Err
89     fn set_unit_id(&mut self) {
90         self.mut_unit_base().set_id(generate_unit_id());
91     }
92 }
93 
94 pub struct Downcast;
95 impl Downcast {
96     fn downcast<T: Unit + Clone + 'static>(unit: Arc<dyn Unit>) -> Result<Arc<T>,RuntimeError> {
97         let any = unit.as_any();
98         let unit = match any.downcast_ref::<T>(){
99             Some(v) => v,
100             None => {
101                 return Err(RuntimeError::new(RuntimeErrorType::DatabaseError));
102             }
103         };
104 
105         return Ok(Arc::new(unit.clone()));
106     }
107 }
108 
109 //Unit状态
110 #[derive(Clone, Copy, Debug,PartialEq)]
111 pub enum UnitState {
112     Enabled,
113     Disabled,
114     Static,
115     Masked,
116 }
117 
118 //Unit类型
119 #[derive(Clone, Copy, PartialEq, Debug)]
120 pub enum UnitType {
121     Automount,
122     Device,
123     Mount,
124     Path,
125     Scope,
126     Service,
127     Slice,
128     Snapshot,
129     Socket,
130     Swap,
131     Target,
132     Timer,
133     Unknown,
134 }
135 
136 //记录unit文件基本信息,这个结构体里面的信息是所有Unit文件都可以有的属性
137 #[derive(Debug, Clone)]
138 pub struct BaseUnit {
139     unit_part: UnitPart,
140     install_part: InstallPart,
141     state: UnitState,
142     unit_type: UnitType,
143     unit_id: usize,
144 }
145 
146 impl Default for BaseUnit {
147     fn default() -> Self {
148         BaseUnit {
149             unit_part: UnitPart::default(),
150             install_part: InstallPart::default(),
151             state: UnitState::Disabled,
152             unit_type: UnitType::Unknown,
153             unit_id: 0,
154         }
155     }
156 }
157 
158 impl BaseUnit {
159     pub fn set_state(&mut self, state: UnitState) {
160         self.state = state;
161     }
162 
163     pub fn set_unit_type(&mut self, utype: UnitType) {
164         self.unit_type = utype;
165     }
166 
167     pub fn set_unit_part_attr(
168         &mut self,
169         attr_type: &BaseUnitAttr,
170         val: &str,
171     ) -> Result<(), ParseError> {
172         return self.unit_part.set_attr(attr_type, val);
173     }
174 
175     pub fn set_install_part_attr(
176         &mut self,
177         attr_type: &InstallUnitAttr,
178         val: &str,
179     ) -> Result<(), ParseError> {
180         return self.install_part.set_attr(attr_type, val);
181     }
182 
183     pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> {
184         return Ok(());
185     }
186 
187     pub fn unit_part(&self) -> &UnitPart {
188         &self.unit_part
189     }
190 
191     pub fn install_part(&self) -> &InstallPart {
192         &self.install_part
193     }
194 
195     pub fn state(&self) -> &UnitState {
196         &self.state
197     }
198 
199     pub fn unit_type(&self) -> &UnitType {
200         &self.unit_type
201     }
202 
203     pub fn set_id(&mut self, id: usize) {
204         self.unit_id = id;
205     }
206 }
207 
208 #[derive(Default, Debug, Clone)]
209 pub struct Url {
210     pub url_string: String, // pub protocol: String,
211                             // pub host: String,
212                             // pub port: Option<u16>,
213                             // pub path: String,
214                             // pub query: Option<String>,
215                             // pub fragment: Option<String>,
216 }
217 
218 //对应Unit文件的Unit段
219 #[derive(Debug, Clone)]
220 pub struct UnitPart {
221     description: String,
222     documentation: Vec<Url>,
223     requires: Vec<Arc<dyn Unit>>,
224     wants: Vec<Arc<dyn Unit>>,
225     after: Vec<Arc<dyn Unit>>,
226     before: Vec<Arc<dyn Unit>>,
227     binds_to: Vec<Arc<dyn Unit>>,
228     part_of: Vec<Arc<dyn Unit>>,
229     on_failure: Vec<Arc<dyn Unit>>,
230     conflicts: Vec<Arc<dyn Unit>>,
231 }
232 
233 impl Default for UnitPart {
234     fn default() -> Self {
235         UnitPart {
236             description: String::new(),
237             documentation: Vec::new(),
238             requires: Vec::new(),
239             wants: Vec::new(),
240             after: Vec::new(),
241             before: Vec::new(),
242             binds_to: Vec::new(),
243             part_of: Vec::new(),
244             on_failure: Vec::new(),
245             conflicts: Vec::new(),
246         }
247     }
248 }
249 
250 impl UnitPart {
251     pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> {
252         match attr {
253             BaseUnitAttr::None => {
254                 return Err(ParseError::new(
255                     ParseErrorType::ESyntaxError,
256                     String::new(),
257                     0,
258                 ));
259             }
260             BaseUnitAttr::Description => self.description = String::from(val),
261             BaseUnitAttr::Documentation => {
262                 self.documentation.extend(UnitParseUtil::parse_url(val)?)
263             }
264             BaseUnitAttr::Requires => {
265                 let units = val.split_whitespace().collect::<Vec<&str>>();
266                 //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题
267                 for unit_path in units {
268                     self.requires
269                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
270                 }
271             }
272             BaseUnitAttr::Wants => {
273                 let units = val.split_whitespace().collect::<Vec<&str>>();
274                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
275                 for unit_path in units {
276                     self.wants
277                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
278                 }
279             }
280             BaseUnitAttr::After => {
281                 let units = val.split_whitespace().collect::<Vec<&str>>();
282                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
283                 for unit_path in units {
284                     self.after
285                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
286                 }
287             }
288             BaseUnitAttr::Before => {
289                 let units = val.split_whitespace().collect::<Vec<&str>>();
290                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
291                 for unit_path in units {
292                     self.before
293                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
294                 }
295             }
296             BaseUnitAttr::BindsTo => {
297                 let units = val.split_whitespace().collect::<Vec<&str>>();
298                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
299                 for unit_path in units {
300                     self.binds_to
301                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
302                 }
303             }
304             BaseUnitAttr::PartOf => {
305                 let units = val.split_whitespace().collect::<Vec<&str>>();
306                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
307                 for unit_path in units {
308                     self.part_of
309                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
310                 }
311             }
312             BaseUnitAttr::OnFailure => {
313                 let units = val.split_whitespace().collect::<Vec<&str>>();
314                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
315                 for unit_path in units {
316                     self.on_failure
317                         .push(UnitParseUtil::parse_unit_no_type(unit_path)?);
318                 }
319             }
320             BaseUnitAttr::Conflicts => {
321                 let units = val.split_whitespace().collect::<Vec<&str>>();
322                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
323                 for unit_path in units {
324                     let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
325                     self.conflicts.push(unit);
326                 }
327             }
328         }
329         return Ok(());
330     }
331 
332     pub fn description(&self) -> &str {
333         &self.description
334     }
335 
336     pub fn documentation(&self) -> &[Url] {
337         &self.documentation
338     }
339 
340     pub fn requires(&self) -> &[Arc<dyn Unit>] {
341         &self.requires
342     }
343 
344     pub fn wants(&self) -> &[Arc<dyn Unit>] {
345         &self.wants
346     }
347 
348     pub fn after(&self) -> &[Arc<dyn Unit>] {
349         &self.after
350     }
351 
352     pub fn before(&self) -> &[Arc<dyn Unit>] {
353         &self.before
354     }
355 
356     pub fn binds_to(&self) -> &[Arc<dyn Unit>] {
357         &self.binds_to
358     }
359 
360     pub fn part_of(&self) -> &[Arc<dyn Unit>] {
361         &self.part_of
362     }
363 
364     pub fn on_failure(&self) -> &[Arc<dyn Unit>] {
365         &self.on_failure
366     }
367 
368     pub fn conflicts(&self) -> &[Arc<dyn Unit>] {
369         &self.conflicts
370     }
371 }
372 
373 //对应Unit文件的Install段
374 #[derive(Debug, Clone)]
375 pub struct InstallPart {
376     wanted_by: Vec<Arc<TargetUnit>>,
377     requires_by: Vec<Arc<TargetUnit>>,
378     also: Vec<Arc<dyn Unit>>,
379     alias: String,
380 }
381 
382 impl Default for InstallPart {
383     fn default() -> Self {
384         InstallPart {
385             wanted_by: Vec::new(),
386             requires_by: Vec::new(),
387             also: Vec::new(),
388             alias: String::new(),
389         }
390     }
391 }
392 
393 impl InstallPart {
394     pub fn set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError> {
395         match attr {
396             InstallUnitAttr::RequiredBy => {
397                 let units = val.split_whitespace().collect::<Vec<&str>>();
398                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
399                 for unit_path in units {
400                     let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
401                     self.requires_by.push(unit);
402                 }
403             }
404             InstallUnitAttr::Also => {
405                 let units = val.split_whitespace().collect::<Vec<&str>>();
406                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
407                 for unit_path in units {
408                     let unit = UnitParseUtil::parse_unit_no_type(unit_path)?;
409                     self.also.push(unit);
410                 }
411             }
412             InstallUnitAttr::WantedBy => {
413                 let units = val.split_whitespace().collect::<Vec<&str>>();
414                 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题
415                 for unit_path in units {
416                     let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?;
417                     self.wanted_by.push(unit);
418                 }
419             }
420             InstallUnitAttr::Alias => {
421                 self.alias = String::from(val);
422             }
423             InstallUnitAttr::None => {
424                 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0));
425             }
426         }
427         return Ok(());
428     }
429 
430     pub fn wanted_by(&self) -> &[Arc<TargetUnit>] {
431         &self.wanted_by
432     }
433 
434     pub fn requires_by(&self) -> &[Arc<TargetUnit>] {
435         &self.requires_by
436     }
437 
438     pub fn also(&self) -> &[Arc<dyn Unit>] {
439         &self.also
440     }
441 
442     pub fn alias(&self) -> &str {
443         &self.alias
444     }
445 }
446 //对应Unit文件的各种属性
447 pub enum BaseUnitAttr {
448     None,
449 
450     //Unit段
451     //描述该Unit文件的信息
452     Description,
453     //指定服务文档
454     Documentation,
455     //依赖的其它 Unit 列表
456     Requires,
457     //这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模板启动是否成功
458     Wants,
459     //后面列出的所有模块全部启动完成以后,才会启动当前的服务
460     After,
461     //在启动指定的任务一个模块之间,都会首先确证当前服务已经运行
462     Before,
463     //这些Unit启动失败时该任务失败,都成功时该任务成功,在这些模板中有任意一个出现意外结束或重启时,这个服务也会跟着终止或重启
464     BindsTo,
465     //仅在列出的任务模块失败或重启时,终止或重启当前服务,而不会随列出模板的启动而启动
466     PartOf,
467     //当这个模板启动失败时,就会自动启动列出的每个模块
468     OnFailure,
469     //与这个模块有冲突的模块,如果列出的模块中有已经在运行的,这个服务就不能启动,反之亦然
470     Conflicts,
471 }
472 
473 pub enum InstallUnitAttr {
474     None,
475     //Install段
476     //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .wants 后缀构成的子目录中
477     WantedBy,
478     //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .required 后缀构成的子目录中
479     RequiredBy,
480     //当前 Unit enable/disable 时,同时 enable/disable 的其他 Unit
481     Also,
482     //别名
483     Alias,
484 }
485