1 use crate::error::parse_error::ParseError; 2 use crate::error::parse_error::ParseErrorType; 3 use crate::error::runtime_error::RuntimeError; 4 5 use crate::executor::ExitStatus; 6 use crate::parse::parse_util::UnitParseUtil; 7 use crate::parse::Segment; 8 9 use std::any::Any; 10 use std::default::Default; 11 use std::fmt::Debug; 12 use std::marker::{Send, Sized, Sync}; 13 14 use std::result::Result; 15 use std::result::Result::Err; 16 use std::result::Result::Ok; 17 use std::string::String; 18 use std::sync::atomic::AtomicUsize; 19 use std::sync::atomic::Ordering; 20 21 use std::vec::Vec; 22 23 pub mod service; 24 pub mod target; 25 26 use self::target::TargetUnit; 27 28 pub fn generate_unit_id() -> usize { 29 static UNIT_ID: AtomicUsize = AtomicUsize::new(1); 30 return UNIT_ID.fetch_add(1, Ordering::SeqCst); 31 } 32 33 //所有可解析的Unit都应该实现该trait 34 pub trait Unit: Sync + Send + Debug { 35 /// @brief 从文件获取到Unit,该函数是解析Unit文件的入口函数 36 /// 37 /// 从path解析Unit属性 38 /// 39 /// @param path 需解析的文件 40 /// 41 /// @return 解析成功则返回对应Unit的id,否则返回Err 42 fn from_path(path: &str) -> Result<usize, ParseError> 43 where 44 Self: Sized; 45 46 fn as_any(&self) -> &dyn Any; 47 48 fn as_mut_any(&mut self) -> &mut 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(&mut self) -> Result<(), RuntimeError>; 85 86 /// ## 设置unit_id 87 /// 88 /// ### return OK(())/Err 89 fn set_unit_id(&mut self) -> usize { 90 let ret = generate_unit_id(); 91 self.mut_unit_base().set_id(ret); 92 ret 93 } 94 95 /// ## Unit退出后逻辑 96 /// 97 /// 一般只有可运行的Unit(如Service)需要重写此函数 98 fn after_exit(&mut self, _exit_status: ExitStatus) {} 99 100 /// ## 初始化Unit内任务的一些参数,各个Unit所需处理的不相同,故放在总的Unit trait 101 fn init(&mut self) {} 102 103 /// ## Unit的显式退出逻辑 104 fn exit(&mut self); 105 } 106 107 //Unit状态 108 #[allow(dead_code)] 109 #[derive(Clone, Copy, Debug, PartialEq)] 110 pub enum UnitState { 111 Enabled, 112 Disabled, 113 Static, 114 Masked, 115 } 116 117 //Unit类型 118 #[allow(dead_code)] 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 #[allow(dead_code)] 159 impl BaseUnit { 160 pub fn set_state(&mut self, state: UnitState) { 161 self.state = state; 162 } 163 164 pub fn set_unit_type(&mut self, utype: UnitType) { 165 self.unit_type = utype; 166 } 167 168 pub fn set_unit_part_attr( 169 &mut self, 170 attr_type: &BaseUnitAttr, 171 val: &str, 172 ) -> Result<(), ParseError> { 173 return self.unit_part.set_attr(attr_type, val); 174 } 175 176 pub fn set_install_part_attr( 177 &mut self, 178 attr_type: &InstallUnitAttr, 179 val: &str, 180 ) -> Result<(), ParseError> { 181 return self.install_part.set_attr(attr_type, val); 182 } 183 184 pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> { 185 return Ok(()); 186 } 187 188 pub fn unit_part(&self) -> &UnitPart { 189 &self.unit_part 190 } 191 192 pub fn mut_unit_part(&mut self) -> &mut UnitPart { 193 &mut self.unit_part 194 } 195 196 pub fn install_part(&self) -> &InstallPart { 197 &self.install_part 198 } 199 200 pub fn state(&self) -> &UnitState { 201 &self.state 202 } 203 204 pub fn unit_type(&self) -> &UnitType { 205 &self.unit_type 206 } 207 208 pub fn set_id(&mut self, id: usize) { 209 self.unit_id = id; 210 } 211 } 212 213 #[derive(Default, Debug, Clone)] 214 pub struct Url { 215 pub url_string: String, // pub protocol: String, 216 // pub host: String, 217 // pub port: Option<u16>, 218 // pub path: String, 219 // pub query: Option<String>, 220 // pub fragment: Option<String>, 221 } 222 223 //对应Unit文件的Unit段 224 #[derive(Debug, Clone)] 225 pub struct UnitPart { 226 // Unit描述 227 description: String, 228 // Unit文档 229 documentation: Vec<Url>, 230 // 依赖项,同时与当前Unit启动,任意一个失败,终止该Unit的启动 231 requires: Vec<usize>, 232 // 依赖项,同时与当前Unit启动,不需要考虑其成功与否 233 wants: Vec<usize>, 234 // 该Unit在下列Units启动完成之后才能启动 235 after: Vec<usize>, 236 // after相反的语义 237 before: Vec<usize>, 238 // 与requires类似,但是这些模块任意一个意外结束或者重启时,该Unit也会终止或重启 239 binds_to: Vec<usize>, 240 // 与binds_to类似,但是不会随着当前Unit启动而启动 241 part_of: Vec<usize>, 242 // 启动失败时,需启动的项 243 on_failure: Vec<usize>, 244 // 与当前Unit冲突项 245 conflicts: Vec<usize>, 246 // 与当前Unit绑定的项,当前Unit失败或者重启时这些项也会跟着终止或重启 247 be_binded_by: Vec<usize>, 248 } 249 250 impl Default for UnitPart { 251 fn default() -> Self { 252 UnitPart { 253 description: String::new(), 254 documentation: Vec::new(), 255 requires: Vec::new(), 256 wants: Vec::new(), 257 after: Vec::new(), 258 before: Vec::new(), 259 binds_to: Vec::new(), 260 part_of: Vec::new(), 261 on_failure: Vec::new(), 262 conflicts: Vec::new(), 263 be_binded_by: Vec::new(), 264 } 265 } 266 } 267 268 #[allow(dead_code)] 269 impl UnitPart { 270 pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> { 271 match attr { 272 BaseUnitAttr::None => { 273 return Err(ParseError::new( 274 ParseErrorType::ESyntaxError, 275 String::new(), 276 0, 277 )); 278 } 279 BaseUnitAttr::Description => self.description = String::from(val), 280 BaseUnitAttr::Documentation => { 281 self.documentation.extend(UnitParseUtil::parse_url(val)?) 282 } 283 BaseUnitAttr::Requires => { 284 let units = val.split_whitespace().collect::<Vec<&str>>(); 285 //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题 286 for unit_path in units { 287 self.requires 288 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 289 } 290 } 291 BaseUnitAttr::Wants => { 292 let units = val.split_whitespace().collect::<Vec<&str>>(); 293 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 294 for unit_path in units { 295 self.wants 296 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 297 } 298 } 299 BaseUnitAttr::After => { 300 let units = val.split_whitespace().collect::<Vec<&str>>(); 301 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 302 for unit_path in units { 303 self.after 304 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 305 } 306 } 307 BaseUnitAttr::Before => { 308 let units = val.split_whitespace().collect::<Vec<&str>>(); 309 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 310 for unit_path in units { 311 self.before 312 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 313 } 314 } 315 BaseUnitAttr::BindsTo => { 316 let units = val.split_whitespace().collect::<Vec<&str>>(); 317 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 318 for unit_path in units { 319 self.binds_to 320 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 321 } 322 } 323 BaseUnitAttr::PartOf => { 324 let units = val.split_whitespace().collect::<Vec<&str>>(); 325 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 326 for unit_path in units { 327 self.part_of 328 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 329 } 330 } 331 BaseUnitAttr::OnFailure => { 332 let units = val.split_whitespace().collect::<Vec<&str>>(); 333 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 334 for unit_path in units { 335 self.on_failure 336 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 337 } 338 } 339 BaseUnitAttr::Conflicts => { 340 let units = val.split_whitespace().collect::<Vec<&str>>(); 341 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 342 for unit_path in units { 343 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?; 344 self.conflicts.push(unit); 345 } 346 } 347 } 348 return Ok(()); 349 } 350 351 pub fn description(&self) -> &str { 352 &self.description 353 } 354 355 pub fn documentation(&self) -> &[Url] { 356 &self.documentation 357 } 358 359 pub fn requires(&self) -> &[usize] { 360 &self.requires 361 } 362 363 pub fn wants(&self) -> &[usize] { 364 &self.wants 365 } 366 367 pub fn after(&self) -> &[usize] { 368 &self.after 369 } 370 371 pub fn before(&self) -> &[usize] { 372 &self.before 373 } 374 375 pub fn binds_to(&self) -> &[usize] { 376 &self.binds_to 377 } 378 379 pub fn part_of(&self) -> &[usize] { 380 &self.part_of 381 } 382 383 pub fn on_failure(&self) -> &[usize] { 384 &self.on_failure 385 } 386 387 pub fn conflicts(&self) -> &[usize] { 388 &self.conflicts 389 } 390 391 pub fn be_binded_by(&self) -> &[usize] { 392 &self.be_binded_by 393 } 394 395 pub fn push_be_binded_by(&mut self, id: usize) { 396 if !self.be_binded_by.contains(&id) { 397 self.be_binded_by.push(id); 398 } 399 } 400 401 pub fn push_after_unit(&mut self, id: usize) { 402 if !self.after.contains(&id) { 403 self.after.push(id); 404 } 405 } 406 } 407 408 //对应Unit文件的Install段 409 #[derive(Debug, Clone)] 410 pub struct InstallPart { 411 wanted_by: Vec<usize>, 412 requires_by: Vec<usize>, 413 also: Vec<usize>, 414 alias: String, 415 } 416 417 impl Default for InstallPart { 418 fn default() -> Self { 419 InstallPart { 420 wanted_by: Vec::new(), 421 requires_by: Vec::new(), 422 also: Vec::new(), 423 alias: String::new(), 424 } 425 } 426 } 427 428 #[allow(dead_code)] 429 impl InstallPart { 430 pub fn set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError> { 431 match attr { 432 InstallUnitAttr::RequiredBy => { 433 let units = val.split_whitespace().collect::<Vec<&str>>(); 434 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 435 for unit_path in units { 436 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?; 437 self.requires_by.push(unit); 438 } 439 } 440 InstallUnitAttr::Also => { 441 let units = val.split_whitespace().collect::<Vec<&str>>(); 442 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 443 for unit_path in units { 444 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?; 445 self.also.push(unit); 446 } 447 } 448 InstallUnitAttr::WantedBy => { 449 let units = val.split_whitespace().collect::<Vec<&str>>(); 450 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 451 for unit_path in units { 452 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?; 453 self.wanted_by.push(unit); 454 } 455 } 456 InstallUnitAttr::Alias => { 457 self.alias = String::from(val); 458 } 459 InstallUnitAttr::None => { 460 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 461 } 462 } 463 return Ok(()); 464 } 465 466 pub fn wanted_by(&self) -> &[usize] { 467 &self.wanted_by 468 } 469 470 pub fn requires_by(&self) -> &[usize] { 471 &self.requires_by 472 } 473 474 pub fn also(&self) -> &[usize] { 475 &self.also 476 } 477 478 pub fn alias(&self) -> &str { 479 &self.alias 480 } 481 } 482 //对应Unit文件的各种属性 483 #[allow(dead_code)] 484 pub enum BaseUnitAttr { 485 None, 486 487 //Unit段 488 //描述该Unit文件的信息 489 Description, 490 //指定服务文档 491 Documentation, 492 //依赖的其它 Unit 列表 493 Requires, 494 //这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模板启动是否成功 495 Wants, 496 //后面列出的所有模块全部启动完成以后,才会启动当前的服务 497 After, 498 //在启动指定的任务一个模块之间,都会首先确证当前服务已经运行 499 Before, 500 //这些Unit启动失败时该任务失败,都成功时该任务成功,在这些模板中有任意一个出现意外结束或重启时,这个服务也会跟着终止或重启 501 BindsTo, 502 //仅在列出的任务模块失败或重启时,终止或重启当前服务,而不会随列出模板的启动而启动 503 PartOf, 504 //当这个模板启动失败时,就会自动启动列出的每个模块 505 OnFailure, 506 //与这个模块有冲突的模块,如果列出的模块中有已经在运行的,这个服务就不能启动,反之亦然 507 Conflicts, 508 } 509 510 #[allow(dead_code)] 511 pub enum InstallUnitAttr { 512 None, 513 //Install段 514 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .wants 后缀构成的子目录中 515 WantedBy, 516 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .required 后缀构成的子目录中 517 RequiredBy, 518 //当前 Unit enable/disable 时,同时 enable/disable 的其他 Unit 519 Also, 520 //别名 521 Alias, 522 } 523