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