nomad_client_rs/extensions/
mod.rsuse serde::{Deserialize, Serialize};
use crate::models::alloc_file_info::AllocFileInfo;
use crate::models::event::{Event, EventPayload};
use crate::models::{TaskEvent, TaskState};
impl AllocFileInfo {
pub fn is_empty(&self) -> bool {
self.size.map_or(false, |value| value <= 1)
}
}
impl Event {
pub fn get_alloc_id(&self) -> Option<String> {
if let Some(payload) = &self.payload {
match payload {
EventPayload::Allocation(allocation) => {
allocation.job_id.as_ref().map(|job_id| job_id.to_string())
}
_ => None,
};
}
None
}
}
impl TaskState {
pub fn last_exit_code(&self) -> Option<i32> {
match &self.events {
Some(events) => {
for event in events.iter().rev() {
match event.exit_code() {
Some(exit_code) => return Some(exit_code),
None => continue,
}
}
}
None => return None,
}
None
}
pub fn first_exit_code(&self) -> Option<i32> {
match &self.events {
Some(events) => {
for event in events {
match event.exit_code() {
Some(exit_code) => return Some(exit_code),
None => continue,
}
}
}
None => return None,
}
None
}
}
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub enum TaskStates {
#[default]
None,
#[serde(rename = "pending")]
Pending,
#[serde(rename = "running")]
Running,
#[serde(rename = "dead")]
Dead,
}
impl TaskEvent {
pub fn exit_code(&self) -> Option<i32> {
if let Some(Ok(exit_code)) = self
.details
.as_ref()?
.get("exit_code")
.map(|s| s.parse::<i32>())
{
return Some(exit_code);
}
None
}
pub fn driver_message(&self) -> Option<String> {
self.details
.as_ref()?
.get("driver_message")
.map(|s| s.into())
}
pub fn restart_reason(&self) -> Option<String> {
self.details
.as_ref()?
.get("restart_reason")
.map(|s| s.into())
}
pub fn kill_reason(&self) -> Option<String> {
self.details.as_ref()?.get("kill_reason").map(|s| s.into())
}
pub fn has_error(&self) -> bool {
if let Some(details) = &self.details {
for key in error_keys() {
if details.contains_key(key) {
return true;
}
}
}
false
}
pub fn error(&self, error_key: &str) -> Option<String> {
self.details.as_ref()?.get(error_key).map(|s| s.into())
}
pub fn all_errors(&self) -> Option<Vec<(&str, String)>> {
let mut errors: Vec<(&str, String)> = Vec::new();
for key in error_keys() {
match self.details.as_ref()?.get(key) {
Some(error) => errors.push((key, error.into())),
None => continue,
}
}
if errors.is_empty() {
None
} else {
Some(errors)
}
}
}
pub fn error_keys() -> Vec<&'static str> {
vec![
"validation_error",
"kill_error",
"setup_error",
"driver_error",
"download_error",
"vault_renewal_error",
]
}