nomad_client_rs/extensions/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
use 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",
    ]
}