1use chrono::{DateTime, Utc};
4use kube::CustomResource;
5use schemars::JsonSchema;
6use serde::{Deserialize, Serialize};
7use std::collections::BTreeMap;
8
9use crate::phase::ProcessPhase;
10
11#[derive(CustomResource, Clone, Debug, Deserialize, Serialize, JsonSchema)]
16#[kube(
17 group = "tatara.pleme.io",
18 version = "v1alpha1",
19 kind = "ProcessTable",
20 plural = "processtables",
21 shortname = "pt",
22 status = "ProcessTableStatus",
23 printcolumn = r#"{"name":"Procs","type":"integer","jsonPath":".status.processCount"}"#,
24 printcolumn = r#"{"name":"Ready","type":"integer","jsonPath":".status.readyCount"}"#,
25 printcolumn = r#"{"name":"NextPID","type":"integer","jsonPath":".spec.nextSequence"}"#,
26 printcolumn = r#"{"name":"Depth","type":"integer","jsonPath":".spec.maxDepth"}"#,
27 printcolumn = r#"{"name":"Age","type":"date","jsonPath":".metadata.creationTimestamp"}"#
28)]
29#[serde(rename_all = "camelCase")]
30pub struct ProcessTableSpec {
31 #[serde(default = "default_next_seq")]
33 pub next_sequence: u32,
34
35 #[serde(default, skip_serializing_if = "Option::is_none")]
37 pub parent_pid: Option<String>,
38
39 #[serde(default, skip_serializing_if = "Option::is_none")]
41 pub dns_domain: Option<String>,
42
43 #[serde(default, skip_serializing_if = "Option::is_none")]
45 pub dns_zone_id: Option<String>,
46
47 #[serde(default)]
49 pub max_depth: u32,
50
51 #[serde(default)]
53 pub max_children: u32,
54
55 #[serde(default = "default_sigterm_timeout")]
57 pub sigterm_timeout_seconds: u32,
58
59 #[serde(default = "default_zombie_timeout")]
61 pub zombie_timeout_seconds: u32,
62
63 #[serde(default = "default_true")]
65 pub orphan_reaping_enabled: bool,
66}
67
68fn default_next_seq() -> u32 {
69 1
70}
71fn default_sigterm_timeout() -> u32 {
72 480
73}
74fn default_zombie_timeout() -> u32 {
75 600
76}
77fn default_true() -> bool {
78 true
79}
80
81#[derive(Clone, Debug, Default, Deserialize, Serialize, JsonSchema)]
82#[serde(rename_all = "camelCase")]
83pub struct ProcessTableStatus {
84 pub process_count: u32,
85 pub ready_count: u32,
86 #[serde(default)]
87 pub processes: Vec<ProcessEntry>,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
89 pub last_reconciled: Option<DateTime<Utc>>,
90
91 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
100 pub claims: BTreeMap<String, ClaimRecord>,
101}
102
103#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema, PartialEq, Eq)]
107#[serde(rename_all = "camelCase")]
108pub struct ClaimRecord {
109 pub holder: String,
113
114 pub pid: String,
118
119 pub granted_at: DateTime<Utc>,
122
123 pub priority: i32,
127}
128
129#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
131#[serde(rename_all = "camelCase")]
132pub struct ProcessEntry {
133 pub name: String,
134 pub namespace: String,
135 pub pid: String,
136 #[serde(default, skip_serializing_if = "Option::is_none")]
137 pub parent_pid: Option<String>,
138 pub phase: ProcessPhase,
139 pub point_type: String,
141 pub substrate: String,
143 #[serde(default, skip_serializing_if = "Option::is_none")]
144 pub content_hash: Option<String>,
145 #[serde(default, skip_serializing_if = "Option::is_none")]
146 pub attestation_root: Option<String>,
147 #[serde(default, skip_serializing_if = "Option::is_none")]
148 pub last_updated: Option<DateTime<Utc>>,
149}