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 20 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 34 fn from_path(path: &str) -> Result<usize, ParseError> 35 where 36 Self: Sized; 37 38 fn as_any(&self) -> &dyn Any; 39 40 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 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 设置值 60 fn set_unit_base(&mut self, unit_base: BaseUnit); 61 62 /// # 获取UnitType 63 /// 64 /// ## return UnitType 65 fn unit_type(&self) -> UnitType; 66 67 fn unit_base(&self) -> &BaseUnit; 68 69 fn unit_base_mut(&mut self) -> &mut BaseUnit; 70 71 fn unit_id(&self) -> usize; 72 73 /// ## Unit的工作逻辑 74 /// 75 /// ### return OK(())/Err 76 fn run(&mut self) -> Result<(), RuntimeError>; 77 78 /// ## 设置unit_id 79 /// 80 /// ### return OK(())/Err 81 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)需要重写此函数 90 fn after_exit(&mut self, _exit_status: ExitStatus) { 91 unimplemented!() 92 } 93 94 /// ## 初始化Unit内任务的一些参数,各个Unit所需处理的不相同,故放在总的Unit trait 95 fn init(&mut self) {} 96 97 /// ## Unit的显式退出逻辑 98 fn exit(&mut self); 99 100 fn set_unit_name(&mut self, name: String) { 101 self.unit_base_mut().unit_name = name; 102 } 103 104 /// ## Unit重启逻辑 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 { 124 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 { 158 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 { 189 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 { 233 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 { 249 pub fn set_state(&mut self, state: UnitState) { 250 self.state = state; 251 } 252 253 pub fn set_unit_type(&mut self, utype: UnitType) { 254 self.unit_type = utype; 255 } 256 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 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 273 pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> { 274 return Ok(()); 275 } 276 277 pub fn unit_part(&self) -> &UnitPart { 278 &self.unit_part 279 } 280 281 pub fn mut_unit_part(&mut self) -> &mut UnitPart { 282 &mut self.unit_part 283 } 284 285 pub fn install_part(&self) -> &InstallPart { 286 &self.install_part 287 } 288 289 pub fn state(&self) -> &UnitState { 290 &self.state 291 } 292 293 pub fn unit_type(&self) -> &UnitType { 294 &self.unit_type 295 } 296 297 pub fn set_id(&mut self, id: usize) { 298 self.unit_id = id; 299 } 300 301 pub fn unit_name(&self) -> String { 302 self.unit_name.clone() 303 } 304 305 /// ## Unit基本格式化信息 306 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 { 356 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 { 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 456 pub fn description(&self) -> &str { 457 &self.description 458 } 459 460 pub fn documentation(&self) -> &[Url] { 461 &self.documentation 462 } 463 464 pub fn requires(&self) -> &[usize] { 465 &self.requires 466 } 467 468 pub fn wants(&self) -> &[usize] { 469 &self.wants 470 } 471 472 pub fn after(&self) -> &[usize] { 473 &self.after 474 } 475 476 pub fn before(&self) -> &[usize] { 477 &self.before 478 } 479 480 pub fn binds_to(&self) -> &[usize] { 481 &self.binds_to 482 } 483 484 pub fn part_of(&self) -> &[usize] { 485 &self.part_of 486 } 487 488 pub fn on_failure(&self) -> &[usize] { 489 &self.on_failure 490 } 491 492 pub fn conflicts(&self) -> &[usize] { 493 &self.conflicts 494 } 495 496 pub fn be_binded_by(&self) -> &[usize] { 497 &self.be_binded_by 498 } 499 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 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 { 523 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 { 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 571 pub fn wanted_by(&self) -> &[usize] { 572 &self.wanted_by 573 } 574 575 pub fn requires_by(&self) -> &[usize] { 576 &self.requires_by 577 } 578 579 pub fn also(&self) -> &[usize] { 580 &self.also 581 } 582 583 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