gatehouse_runtime_protocol/lifecycle_v2/
readonly.rs1use super::{
5 native_image::{decode_image, image_route, ImageFacts},
6 native_info::decode_info,
7 native_status::{decode_inspect, inspect_route, InspectOutcome, State},
8 observation::INFO_ROUTE,
9 ownership::ExpectedContainer,
10 protected_context::ProtectedContext,
11};
12
13pub struct CapturedImage {
18 facts: ImageFacts,
19 image_bytes: Vec<u8>,
20 config_bytes: Vec<u8>,
21 epoch: String,
22}
23impl std::fmt::Debug for CapturedImage {
24 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
25 f.debug_struct("CapturedImage").finish_non_exhaustive()
26 }
27}
28impl CapturedImage {
29 pub fn facts(&self) -> &ImageFacts {
30 &self.facts
31 }
32 pub fn image_bytes(&self) -> &[u8] {
33 &self.image_bytes
34 }
35 pub fn config_bytes(&self) -> &[u8] {
36 &self.config_bytes
37 }
38 pub fn operator_epoch(&self) -> &str {
39 &self.epoch
40 }
41 pub fn match_context(&self, context: &ProtectedContext) -> Result<(), &'static str> {
43 let (expected, bytes) = context.snapshot()?;
44 if bytes != self.config_bytes || expected.operator_epoch != self.epoch {
45 return Err("captured image context mismatch");
46 }
47 Ok(())
48 }
49}
50
51impl ProtectedContext {
52 pub fn capture_image_for_plan<F>(&self, id: &str, get: F) -> Result<CapturedImage, &'static str>
55 where
56 F: FnMut(&str) -> Result<(u16, Vec<u8>), &'static str>,
57 {
58 let (expected, bytes) = self.snapshot()?;
59 let config_bytes = bytes.to_vec();
60 let epoch = expected.operator_epoch.clone();
61 let (facts, image_bytes) =
62 self.inspect_checked_with(&image_route(id)?, get, |route, status, bytes| {
63 Ok((
64 decode_image(id, "GET", route, status, bytes)?,
65 bytes.to_vec(),
66 ))
67 })?;
68 let captured = CapturedImage {
69 facts,
70 image_bytes,
71 config_bytes,
72 epoch,
73 };
74 captured.match_context(self)?;
75 Ok(captured)
76 }
77
78 pub fn inspect_with<F>(&self, id: &str, get: F) -> Result<InspectOutcome, &'static str>
81 where
82 F: FnMut(&str) -> Result<(u16, Vec<u8>), &'static str>,
83 {
84 self.inspect_checked_with(&inspect_route(id)?, get, |route, status, bytes| {
85 decode_inspect(id, "GET", route, status, bytes)
86 })
87 }
88 pub fn inspect_owned_with<F>(
91 &self,
92 owner: &ExpectedContainer,
93 get: F,
94 ) -> Result<State, &'static str>
95 where
96 F: FnMut(&str) -> Result<(u16, Vec<u8>), &'static str>,
97 {
98 owner.validate()?;
99 self.inspect_checked_with(&inspect_route(&owner.id)?, get, |route, status, bytes| {
100 owner.match_inspect("GET", route, status, bytes)
101 })
102 }
103 pub fn inspect_image_with<F>(&self, id: &str, get: F) -> Result<ImageFacts, &'static str>
105 where
106 F: FnMut(&str) -> Result<(u16, Vec<u8>), &'static str>,
107 {
108 self.inspect_checked_with(&image_route(id)?, get, |route, status, bytes| {
109 decode_image(id, "GET", route, status, bytes)
110 })
111 }
112 fn inspect_checked_with<F, T, D>(
113 &self,
114 route: &str,
115 mut get: F,
116 decode: D,
117 ) -> Result<T, &'static str>
118 where
119 F: FnMut(&str) -> Result<(u16, Vec<u8>), &'static str>,
120 D: FnOnce(&str, u16, &[u8]) -> Result<T, &'static str>,
121 {
122 let (expected, _) = self.snapshot()?;
123 expected.validate_local_socket_policy()?;
124 let exchange = |get: &mut F, path: &str| {
125 self.revalidate()?;
126 let response = get(path)?;
127 self.revalidate()?;
128 Ok::<_, &'static str>(response)
129 };
130 let (status, bytes) = exchange(&mut get, INFO_ROUTE)?;
131 if status != 200 {
132 return Err("initial native info unavailable");
133 }
134 let before = decode_info(&bytes, expected.observation.socket.clone())?;
135 expected.match_current_operation(expected, &before, &before)?;
136 let (status, bytes) = exchange(&mut get, route)?;
137 let result = decode(route, status, &bytes)?;
138 let (status, bytes) = exchange(&mut get, INFO_ROUTE)?;
139 if status != 200 {
140 return Err("final native info unavailable");
141 }
142 let after = decode_info(&bytes, expected.observation.socket.clone())?;
143 expected.match_current_operation(expected, &before, &after)?;
144 self.revalidate()?;
145 Ok(result)
146 }
147}