diff --git a/src/cli/parser.rs b/src/cli/parser.rs index 4deaa6d..cb290c9 100644 --- a/src/cli/parser.rs +++ b/src/cli/parser.rs @@ -3106,7 +3106,10 @@ environments: "; let (_parser, result) = parse_with_contract(contract, &["apply", "--environment", "test"]); let err = result.unwrap_err(); - assert!(err.contains("{profile}"), "error names the placeholder: {err}"); + assert!( + err.contains("{profile}"), + "error names the placeholder: {err}" + ); assert!(err.contains("no profile"), "error states the cause: {err}"); } diff --git a/src/modules/services/sd_service.rs b/src/modules/services/sd_service.rs index c3e1582..3ad1796 100644 --- a/src/modules/services/sd_service.rs +++ b/src/modules/services/sd_service.rs @@ -31,6 +31,7 @@ pub struct SystemdServiceTask { pub service: String, pub enabled: Option, pub started: Option, + pub reload: Option, pub restart: Option, pub with: Option, pub and: Option, @@ -40,6 +41,7 @@ struct SystemdServiceAction { pub service: String, pub enabled: Option, pub started: Option, + pub reload: bool, pub restart: bool, } @@ -100,6 +102,12 @@ impl IsTask for SystemdServiceTask { &String::from("started"), &self.started, )?, + reload: handle.template.boolean_option_default_false( + request, + tm, + &String::from("reload"), + &self.reload, + )?, restart: handle.template.boolean_option_default_false( request, tm, @@ -142,26 +150,52 @@ impl IsAction for SystemdServiceAction { _ => {} }; - match (actual.started, self.started, self.restart) { - (_, Some(false), true) => { + match (actual.started, self.started, self.reload, self.restart) { + (_, Some(false), true, _) => { + return Err(handle.response.is_failed( + request, + &String::from("started:false and reload:true conflict"), + )); + } + (_, Some(false), _, true) => { return Err(handle.response.is_failed( request, &String::from("started:false and restart:true conflict"), )); } - (true, Some(true), true) => { + (_, _, true, true) => { + return Err(handle.response.is_failed( + request, + &String::from("reload:true and restart:true conflict"), + )); + } + (true, Some(true), true, false) => { + changes.push(Field::Reload); + } + (true, None, true, false) => { + changes.push(Field::Reload); /* a little weird, but we know what you mean */ + } + (false, None, true, false) => { + return Err(handle.response.is_failed( + request, + &String::from( + "reload:true requires the service to already be started or started:true", + ), + )); + } + (true, Some(true), false, true) => { changes.push(Field::Restart); } - (true, None, true) => { + (true, None, false, true) => { changes.push(Field::Restart); /* a little weird, but we know what you mean */ } - (false, None, true) => { + (false, None, false, true) => { changes.push(Field::Start); /* a little weird, but we know what you mean */ } - (false, Some(true), _) => { + (false, Some(true), _, _) => { changes.push(Field::Start); } - (true, Some(false), false) => { + (true, Some(false), false, false) => { changes.push(Field::Stop); } _ => {} @@ -179,6 +213,8 @@ impl IsAction for SystemdServiceAction { self.do_start(handle, request)?; } else if request.changes.contains(&Field::Stop) { self.do_stop(handle, request)?; + } else if request.changes.contains(&Field::Reload) { + self.do_reload(handle, request)?; } else if request.changes.contains(&Field::Restart) { self.do_restart(handle, request)?; } @@ -293,6 +329,15 @@ impl SystemdServiceAction { let cmd = format!("systemctl restart '{}'", self.service); handle.remote.run(request, &cmd, CheckRc::Checked) } + + pub fn do_reload( + &self, + handle: &Arc, + request: &Arc, + ) -> Result, Arc> { + let cmd = format!("systemctl reload '{}'", self.service); + handle.remote.run(request, &cmd, CheckRc::Checked) + } } /// Classify the stdout of `systemctl is-enabled ` into an [`Enablement`] diff --git a/src/tasks/fields.rs b/src/tasks/fields.rs index d5af80a..2407312 100644 --- a/src/tasks/fields.rs +++ b/src/tasks/fields.rs @@ -34,6 +34,7 @@ pub enum Field { Location, Mode, Owner, + Reload, Restart, Shell, Start, diff --git a/tests/modules/services/sd_service.rs b/tests/modules/services/sd_service.rs index 2c6ef3f..457c55f 100644 --- a/tests/modules/services/sd_service.rs +++ b/tests/modules/services/sd_service.rs @@ -8,6 +8,7 @@ fn test_systemd_service_task_basic() { service: "nginx".to_string(), enabled: None, started: None, + reload: None, restart: None, with: None, and: None, @@ -27,6 +28,7 @@ fn test_systemd_service_task_enabled_started() { service: "postgresql".to_string(), enabled: Some("yes".to_string()), started: Some("yes".to_string()), + reload: None, restart: None, with: None, and: None, @@ -45,6 +47,7 @@ fn test_systemd_service_task_restart() { service: "httpd".to_string(), enabled: None, started: None, + reload: None, restart: Some("yes".to_string()), with: None, and: None, @@ -61,6 +64,7 @@ fn test_systemd_service_task_disabled_stopped() { service: "firewalld".to_string(), enabled: Some("no".to_string()), started: Some("no".to_string()), + reload: None, restart: None, with: None, and: None, @@ -145,3 +149,23 @@ restart: "yes" assert!(task.enabled.is_none()); assert!(task.started.is_none()); } + +#[test] +fn test_systemd_service_task_reload_only() { + let yaml = r#" +name: Reload application +service: myapp +reload: "yes" +"#; + + let task: Result = serde_yaml::from_str(yaml); + assert!(task.is_ok()); + + let task = task.unwrap(); + assert_eq!(task.name, Some("Reload application".to_string())); + assert_eq!(task.service, "myapp"); + assert_eq!(task.reload, Some("yes".to_string())); + assert!(task.restart.is_none()); + assert!(task.enabled.is_none()); + assert!(task.started.is_none()); +} diff --git a/tests/tasks/fields.rs b/tests/tasks/fields.rs index 7d22cc2..c45384c 100644 --- a/tests/tasks/fields.rs +++ b/tests/tasks/fields.rs @@ -62,6 +62,7 @@ fn test_all_field_variants() { Field::Groups, Field::Mode, Field::Owner, + Field::Reload, Field::Restart, Field::Shell, Field::Start,