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 #[derive(Clone, Copy, Debug, PartialEq)] 109 pub enum UnitState { 110 Enabled, 111 Disabled, 112 Static, 113 Masked, 114 } 115 116 //Unit类型 117 #[derive(Clone, Copy, PartialEq, Debug)] 118 pub enum UnitType { 119 Automount, 120 Device, 121 Mount, 122 Path, 123 Scope, 124 Service, 125 Slice, 126 Snapshot, 127 Socket, 128 Swap, 129 Target, 130 Timer, 131 Unknown, 132 } 133 134 //记录unit文件基本信息,这个结构体里面的信息是所有Unit文件都可以有的属性 135 #[derive(Debug, Clone)] 136 pub struct BaseUnit { 137 unit_part: UnitPart, 138 install_part: InstallPart, 139 state: UnitState, 140 unit_type: UnitType, 141 unit_id: usize, 142 } 143 144 impl Default for BaseUnit { 145 fn default() -> Self { 146 BaseUnit { 147 unit_part: UnitPart::default(), 148 install_part: InstallPart::default(), 149 state: UnitState::Disabled, 150 unit_type: UnitType::Unknown, 151 unit_id: 0, 152 } 153 } 154 } 155 156 impl BaseUnit { 157 pub fn set_state(&mut self, state: UnitState) { 158 self.state = state; 159 } 160 161 pub fn set_unit_type(&mut self, utype: UnitType) { 162 self.unit_type = utype; 163 } 164 165 pub fn set_unit_part_attr( 166 &mut self, 167 attr_type: &BaseUnitAttr, 168 val: &str, 169 ) -> Result<(), ParseError> { 170 return self.unit_part.set_attr(attr_type, val); 171 } 172 173 pub fn set_install_part_attr( 174 &mut self, 175 attr_type: &InstallUnitAttr, 176 val: &str, 177 ) -> Result<(), ParseError> { 178 return self.install_part.set_attr(attr_type, val); 179 } 180 181 pub fn parse_and_set_attribute(&self) -> Result<(), ParseError> { 182 return Ok(()); 183 } 184 185 pub fn unit_part(&self) -> &UnitPart { 186 &self.unit_part 187 } 188 189 pub fn mut_unit_part(&mut self) -> &mut UnitPart { 190 &mut self.unit_part 191 } 192 193 pub fn install_part(&self) -> &InstallPart { 194 &self.install_part 195 } 196 197 pub fn state(&self) -> &UnitState { 198 &self.state 199 } 200 201 pub fn unit_type(&self) -> &UnitType { 202 &self.unit_type 203 } 204 205 pub fn set_id(&mut self, id: usize) { 206 self.unit_id = id; 207 } 208 } 209 210 #[derive(Default, Debug, Clone)] 211 pub struct Url { 212 pub url_string: String, // pub protocol: String, 213 // pub host: String, 214 // pub port: Option<u16>, 215 // pub path: String, 216 // pub query: Option<String>, 217 // pub fragment: Option<String>, 218 } 219 220 //对应Unit文件的Unit段 221 #[derive(Debug, Clone)] 222 pub struct UnitPart { 223 // Unit描述 224 description: String, 225 // Unit文档 226 documentation: Vec<Url>, 227 // 依赖项,同时与当前Unit启动,任意一个失败,终止该Unit的启动 228 requires: Vec<usize>, 229 // 依赖项,同时与当前Unit启动,不需要考虑其成功与否 230 wants: Vec<usize>, 231 // 该Unit在下列Units启动完成之后才能启动 232 after: Vec<usize>, 233 // after相反的语义 234 before: Vec<usize>, 235 // 与requires类似,但是这些模块任意一个意外结束或者重启时,该Unit也会终止或重启 236 binds_to: Vec<usize>, 237 // 与binds_to类似,但是不会随着当前Unit启动而启动 238 part_of: Vec<usize>, 239 // 启动失败时,需启动的项 240 on_failure: Vec<usize>, 241 // 与当前Unit冲突项 242 conflicts: Vec<usize>, 243 // 与当前Unit绑定的项,当前Unit失败或者重启时这些项也会跟着终止或重启 244 be_binded_by: Vec<usize>, 245 } 246 247 impl Default for UnitPart { 248 fn default() -> Self { 249 UnitPart { 250 description: String::new(), 251 documentation: Vec::new(), 252 requires: Vec::new(), 253 wants: Vec::new(), 254 after: Vec::new(), 255 before: Vec::new(), 256 binds_to: Vec::new(), 257 part_of: Vec::new(), 258 on_failure: Vec::new(), 259 conflicts: Vec::new(), 260 be_binded_by: Vec::new(), 261 } 262 } 263 } 264 265 impl UnitPart { 266 pub fn set_attr(&mut self, attr: &BaseUnitAttr, val: &str) -> Result<(), ParseError> { 267 match attr { 268 BaseUnitAttr::None => { 269 return Err(ParseError::new( 270 ParseErrorType::ESyntaxError, 271 String::new(), 272 0, 273 )); 274 } 275 BaseUnitAttr::Description => self.description = String::from(val), 276 BaseUnitAttr::Documentation => { 277 self.documentation.extend(UnitParseUtil::parse_url(val)?) 278 } 279 BaseUnitAttr::Requires => { 280 let units = val.split_whitespace().collect::<Vec<&str>>(); 281 //TODO:目前先加入requires列表,可能会出现循环依赖问题,后续应解决循环依赖问题 282 for unit_path in units { 283 self.requires 284 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 285 } 286 } 287 BaseUnitAttr::Wants => { 288 let units = val.split_whitespace().collect::<Vec<&str>>(); 289 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 290 for unit_path in units { 291 self.wants 292 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 293 } 294 } 295 BaseUnitAttr::After => { 296 let units = val.split_whitespace().collect::<Vec<&str>>(); 297 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 298 for unit_path in units { 299 self.after 300 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 301 } 302 } 303 BaseUnitAttr::Before => { 304 let units = val.split_whitespace().collect::<Vec<&str>>(); 305 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 306 for unit_path in units { 307 self.before 308 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 309 } 310 } 311 BaseUnitAttr::BindsTo => { 312 let units = val.split_whitespace().collect::<Vec<&str>>(); 313 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 314 for unit_path in units { 315 self.binds_to 316 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 317 } 318 } 319 BaseUnitAttr::PartOf => { 320 let units = val.split_whitespace().collect::<Vec<&str>>(); 321 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 322 for unit_path in units { 323 self.part_of 324 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 325 } 326 } 327 BaseUnitAttr::OnFailure => { 328 let units = val.split_whitespace().collect::<Vec<&str>>(); 329 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 330 for unit_path in units { 331 self.on_failure 332 .push(UnitParseUtil::parse_unit_no_type(unit_path)?); 333 } 334 } 335 BaseUnitAttr::Conflicts => { 336 let units = val.split_whitespace().collect::<Vec<&str>>(); 337 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 338 for unit_path in units { 339 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?; 340 self.conflicts.push(unit); 341 } 342 } 343 } 344 return Ok(()); 345 } 346 347 pub fn description(&self) -> &str { 348 &self.description 349 } 350 351 pub fn documentation(&self) -> &[Url] { 352 &self.documentation 353 } 354 355 pub fn requires(&self) -> &[usize] { 356 &self.requires 357 } 358 359 pub fn wants(&self) -> &[usize] { 360 &self.wants 361 } 362 363 pub fn after(&self) -> &[usize] { 364 &self.after 365 } 366 367 pub fn before(&self) -> &[usize] { 368 &self.before 369 } 370 371 pub fn binds_to(&self) -> &[usize] { 372 &self.binds_to 373 } 374 375 pub fn part_of(&self) -> &[usize] { 376 &self.part_of 377 } 378 379 pub fn on_failure(&self) -> &[usize] { 380 &self.on_failure 381 } 382 383 pub fn conflicts(&self) -> &[usize] { 384 &self.conflicts 385 } 386 387 pub fn be_binded_by(&self) -> &[usize] { 388 &self.be_binded_by 389 } 390 391 pub fn push_be_binded_by(&mut self, id: usize) { 392 if !self.be_binded_by.contains(&id) { 393 self.be_binded_by.push(id); 394 } 395 } 396 397 pub fn push_after_unit(&mut self, id: usize) { 398 if !self.after.contains(&id) { 399 self.after.push(id); 400 } 401 } 402 } 403 404 //对应Unit文件的Install段 405 #[derive(Debug, Clone)] 406 pub struct InstallPart { 407 wanted_by: Vec<usize>, 408 requires_by: Vec<usize>, 409 also: Vec<usize>, 410 alias: String, 411 } 412 413 impl Default for InstallPart { 414 fn default() -> Self { 415 InstallPart { 416 wanted_by: Vec::new(), 417 requires_by: Vec::new(), 418 also: Vec::new(), 419 alias: String::new(), 420 } 421 } 422 } 423 424 impl InstallPart { 425 pub fn set_attr(&mut self, attr: &InstallUnitAttr, val: &str) -> Result<(), ParseError> { 426 match attr { 427 InstallUnitAttr::RequiredBy => { 428 let units = val.split_whitespace().collect::<Vec<&str>>(); 429 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 430 for unit_path in units { 431 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?; 432 self.requires_by.push(unit); 433 } 434 } 435 InstallUnitAttr::Also => { 436 let units = val.split_whitespace().collect::<Vec<&str>>(); 437 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 438 for unit_path in units { 439 let unit = UnitParseUtil::parse_unit_no_type(unit_path)?; 440 self.also.push(unit); 441 } 442 } 443 InstallUnitAttr::WantedBy => { 444 let units = val.split_whitespace().collect::<Vec<&str>>(); 445 //TODO:目前先加入列表,可能会出现循环依赖问题,后续应解决循环依赖问题 446 for unit_path in units { 447 let unit = UnitParseUtil::parse_unit::<TargetUnit>(unit_path)?; 448 self.wanted_by.push(unit); 449 } 450 } 451 InstallUnitAttr::Alias => { 452 self.alias = String::from(val); 453 } 454 InstallUnitAttr::None => { 455 return Err(ParseError::new(ParseErrorType::EINVAL, String::new(), 0)); 456 } 457 } 458 return Ok(()); 459 } 460 461 pub fn wanted_by(&self) -> &[usize] { 462 &self.wanted_by 463 } 464 465 pub fn requires_by(&self) -> &[usize] { 466 &self.requires_by 467 } 468 469 pub fn also(&self) -> &[usize] { 470 &self.also 471 } 472 473 pub fn alias(&self) -> &str { 474 &self.alias 475 } 476 } 477 //对应Unit文件的各种属性 478 pub enum BaseUnitAttr { 479 None, 480 481 //Unit段 482 //描述该Unit文件的信息 483 Description, 484 //指定服务文档 485 Documentation, 486 //依赖的其它 Unit 列表 487 Requires, 488 //这个 Unit 启动时,触发启动列出的每个 Unit 模块,而不去考虑这些模板启动是否成功 489 Wants, 490 //后面列出的所有模块全部启动完成以后,才会启动当前的服务 491 After, 492 //在启动指定的任务一个模块之间,都会首先确证当前服务已经运行 493 Before, 494 //这些Unit启动失败时该任务失败,都成功时该任务成功,在这些模板中有任意一个出现意外结束或重启时,这个服务也会跟着终止或重启 495 BindsTo, 496 //仅在列出的任务模块失败或重启时,终止或重启当前服务,而不会随列出模板的启动而启动 497 PartOf, 498 //当这个模板启动失败时,就会自动启动列出的每个模块 499 OnFailure, 500 //与这个模块有冲突的模块,如果列出的模块中有已经在运行的,这个服务就不能启动,反之亦然 501 Conflicts, 502 } 503 504 pub enum InstallUnitAttr { 505 None, 506 //Install段 507 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .wants 后缀构成的子目录中 508 WantedBy, 509 //依赖当前服务的模块。当前 Unit 激活时(enable)符号链接会放入 /etc/systemd/system 目录下面以 <Target 名> + .required 后缀构成的子目录中 510 RequiredBy, 511 //当前 Unit enable/disable 时,同时 enable/disable 的其他 Unit 512 Also, 513 //别名 514 Alias, 515 } 516